Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
[![FastAPI](https://img.shields.io/badge/FastAPI-0.140%E2%80%930.141-009688?logo=fastapi&logoColor=white)](https://fastapi.tiangolo.com/)
[![React](https://img.shields.io/badge/React-19-61DAFB?logo=react&logoColor=white)](https://react.dev/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![Tests](https://img.shields.io/badge/Tests-102%20vitest%20%7C%20142%20SQL%20assertions-brightgreen)](#test-suite)
[![Tests](https://img.shields.io/badge/Tests-139%20vitest%20%7C%20142%20SQL%20assertions-brightgreen)](#test-suite)

---

Expand Down Expand Up @@ -38,10 +38,16 @@
`API_KEY` is for scripts and services only; the browser never holds it. The
API refuses to start outside `dev` without `API_KEY`. Requests that use the
key reach the default schemas, not any tenant's.
Users change their own password from the header; a tenant admin can reset
members of their own tenant only. A user who belongs to more than one tenant
can be reset only by an operator with `scripts/reset_password.py` (#117).
- **Upload failure reasons:** the per-row reasons and step log for an upload
are kept in the uploading browser's Import history, not on the server; the
server keeps only the counts. Server-side storage is planned for M3 (#107).
- **Rate limiting:** in-process only, so it suits a single API instance.
- **Frontend audit page:** shows this browser's local import history, not the
server audit log (see the naming note under Frontend Features).
- **Offline install:** procedure in `docs/offline-install.md`, rehearsed with networking off. The clean-VM dry run (#60) is still to do.
- **Offline install:** procedure in `docs/offline-install.md`, rehearsed with networking off. The clean-VM dry run (#60) is still to do. It targets Ubuntu 24.04 only; an offline container bundle for Windows, macOS and Linux is tracked as #128 (BR-38).

## For Reviewers

Expand Down Expand Up @@ -103,7 +109,7 @@ PostgreDataMigrationAppWithCSVLoader/
│ │ ├── export.ts ← CSV / XLSX / PDF export
│ │ ├── mapping-templates.ts ← saved column mapping templates
│ │ └── csv-preview.ts ← CSV parsing utilities
│ ├── src/__tests__/ ← 102 vitest tests
│ ├── src/__tests__/ ← 139 vitest tests
│ ├── .env.local ← VITE_API_BASE (not committed)
│ └── package.json
│
Expand Down Expand Up @@ -242,7 +248,7 @@ python -m pytest tests\test_te_loader_integration.py -v
python -m pytest tests\environments\ -v
```

### Frontend tests (102 vitest)
### Frontend tests (139 vitest)

```powershell
cd csv-table-hub-main
Expand Down
8 changes: 6 additions & 2 deletions docs/VCRM.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ Added by ART Milestone 0 (#53) and approved by the product owner on 2026-10-26.
| **BR-35** | Audit events shall be append-only at database level; reports shall be filterable; exports shall neutralise spreadsheet formula injection. | ART v2, D7 |
| **BR-36** | Users shall authenticate; access shall be role-based; no tenant shall read or affect another tenant's data. | ART v2, D1, ADR-0003, decision 6 |
| **BR-37** | Data shall stay inside the deployment boundary, with no runtime external services, and the stack shall install offline. | ART v2, D6, decision 7 |
| **BR-38** | The platform shall install and run without internet access on Windows, macOS and Linux hosts that have a container runtime (Docker or Podman) installed. | Product owner, 27 Oct 2026; #128 |

### Out of scope (recorded for completeness)

Expand Down Expand Up @@ -135,7 +136,7 @@ The `input_data/` loader has its own implicit requirements — verified end-to-e
| BR-D4 | Duplicate primary keys in source are reported, not silently dropped | 4 (duplicate detection) | ✅ |
| BR-D5 | Loaded data is browsable (sample peek) | 1 (sample rows) | ✅ |

### ART extension traceability (BR-23 to BR-37)
### ART extension and later requirements, traceability (BR-23 to BR-38)

Status as assessed on 2026-10-26 at `main` 032b522. None of these is "Verified" until a test run proves it (D5).

Expand All @@ -156,6 +157,7 @@ Status as assessed on 2026-10-26 at `main` 032b522. None of these is "Verified"
| BR-35 | ⚠️ Partial | Export formula injection neutralised (M1: #86, `export.test.ts`); audit table still plain, no actor, no filters | DB negative tests + unit | M1, M3, M7 |
| BR-36 | ⚠️ Partial | Done in M2:<br>• local accounts with lockout (#98, #103)<br>• OIDC (#105)<br>• per-tenant schemas, T&E tables included (#100, #104)<br>• role matrix in `docs/ROLES.md` (#101)<br><br>Tests: `tests/test_accounts.py`, `test_tenant_isolation.py`, `test_roles.py`, `test_oidc.py`, `test_password_reset.py`. Each failed with its control removed.<br>• frontend sign-in; the browser no longer holds the shared key (#115)<br>• password change, admin reset and break-glass reset (#117; `tests/test_password_reset.py`)<br><br>Open: the shared key still grants non-tenant access to scripts and services; security review (#112); real-IdP OIDC check (#113) | Cross-tenant negative tests; role matrix tests | M2 |
| BR-37 | ⚠️ Partial | No external calls found; no automated check; no offline doc (#60) | Egress-blocked run + offline dry run | M7 |
| BR-38 | ❌ Not started | No container bundle for the application yet (`infra/Dockerfile` is the schema and evals runner only) | Offline smoke test 7/7 on Windows, macOS and Linux | #128 |

---

Expand All @@ -178,9 +180,11 @@ Status as assessed on 2026-10-26 at `main` 032b522. None of these is "Verified"
|--------|-------|-------------|
| ✅ Verified | 19 | BR-01, BR-03, BR-04, BR-05, BR-06, BR-07, BR-08, BR-09, BR-10, BR-11, BR-12, BR-13, BR-14, BR-15, BR-16, BR-17, BR-18, BR-19, BR-20 |
| ⚠️ Partial | 11 | BR-23, BR-25, BR-28, BR-29, BR-30, BR-31, BR-33, BR-34, BR-35, BR-36, BR-37 (ART, added 2026-10-26) |
| ❌ Not started | 4 | BR-24, BR-26, BR-27, BR-32 (ART, added 2026-10-26) |
| ❌ Not started | 5 | BR-24, BR-26, BR-27, BR-32 (ART, added 2026-10-26); BR-38 (added 2026-10-27) |
| ⏸ Deferred by decision | 3 | BR-02, BR-21, BR-22 |

**Headline (2026-10-27):** with BR-38 added (cross-platform offline install, #128), **19 of 38 (50 %)** are verified, 3 are deferred by decision, and the other 16 are partial or not started.

**Headline (2026-10-26):** with the 15 ART requirements added, **19 of 37 (51 %)** are verified, 3 are deferred by decision, and the other 15 are partial or not started.

**Headline before ART:** **19 of 22 (86 %)** business requirements are fully verified by at least one automated test condition, up from 17 of 22 (77 %).
Expand Down
2 changes: 1 addition & 1 deletion docs/offline-install.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ Once that evidence is on #60, the README can move to the "fully offline" wording
sudo bash -c 'set -a; . /opt/te-migration/env; set +a; runuser -u te-app -- /opt/te-migration/venv/bin/python scripts/reset_password.py --username admin'
```
- **The API address is fixed at install.** It's written into the frontend files. To change it, re-run the install.
- **Ubuntu 24.04 x86_64 only.** Other operating systems need different packages and wheels.
- **Ubuntu 24.04 x86_64 only.** Other operating systems need different packages and wheels. An offline container bundle for Windows, macOS and Linux is tracked as #128 (BR-38).

## How it was rehearsed

Expand Down
Loading