docs(adr): split ADR-0026 + propose ADR-0027 (Structure hierarchy)
CI / commits (pull_request) Successful in 3m1s
CI / check (pull_request) Successful in 3m3s
CI / scan (pull_request) Successful in 3m12s
CI / a11y (pull_request) Successful in 3m1s
Docs site / build (pull_request) Successful in 3m16s
CI / perf (pull_request) Successful in 5m59s
CI / commits (pull_request) Successful in 3m1s
CI / check (pull_request) Successful in 3m3s
CI / scan (pull_request) Successful in 3m12s
CI / a11y (pull_request) Successful in 3m1s
Docs site / build (pull_request) Successful in 3m16s
CI / perf (pull_request) Successful in 5m59s
Cascade + acteurs_plus source-of-truth audit caught the original ADR-0026 draft pinning Etablissement.finess as PK while >=30% of APF's real structure inventory has no FINESS (antennes, dispositifs, entreprises adaptees, mouvement, administratif, siege). Narrow ADR-0026 to identity only (Person + User + UserScope). Drop Person.email unique (two distinct humans can share an email) and drop email-based dedup from the v1 provisioner lifecycle - entraOid is the only natural key trusted in v1. New ADR-0027 owns the organisational hierarchy: cascade-aligned Structure with kind discriminator + nullable FINESS / SIRET / codePaie + internal code PK that doubles as FINESS for medico-social structures. Pole / Service / arbitrary nesting / per-source enrichment deferred to ADR-0028 (sync), renumbered from the prior ADR-0027 placeholder. Both ADRs stay proposed pending review.
This commit is contained in:
@@ -60,7 +60,7 @@ The structural, security, observability, and quality choices are recorded as ADR
|
||||
|
||||
The Nx workspace is **scaffolded and operational**. The three apps (`portal-shell`, `portal-admin`, `portal-bff`) and the seven lib roots (`libs/feature/auth`, `libs/shared/auth`, `libs/shared/charts`, `libs/shared/state`, `libs/shared/tokens`, `libs/shared/ui`, `libs/shared/util`) are in place; CI runs `format:check / lint / test / build` plus the ADR-0025 catalogue-drift gate on every PR.
|
||||
|
||||
ADRs 0001 → 0025 are accepted and cover the structural, security, observability, quality, i18n, admin-app, docs-site, charts, AI-relay, and authorization choices. **Shipped on `main`:**
|
||||
ADRs 0001 → 0025 are accepted and cover the structural, security, observability, quality, i18n, admin-app, docs-site, charts, AI-relay, and authorization choices. ADR-0026 (portal-side identity model — `Person` + `User` + `UserScope`) and ADR-0027 (portal-side organisational hierarchy — `Structure` with kind discriminator + nullable FINESS / SIRET, cascade-aligned) are proposed; together they unlock the ADR-0025 stubs (`Principal.user.{id, personId}` placeholders, `StubScopeResolver`'s `unrestricted` blanket return). **Shipped on `main`:**
|
||||
|
||||
- **Phase-1 foundation** — Nx workspace, Angular `portal-shell`, NestJS `portal-bff`, Prisma + Postgres, Pino + OpenTelemetry, Husky/lint-staged/commitlint, Gitea Actions CI.
|
||||
- **Phase-2 auth + audit + security** — OIDC Auth Code + PKCE via MSAL Node, Redis sessions with AES-256-GCM at rest, idle 30 min sliding + absolute 12 h hard ceiling, RP-initiated logout, double-submit CSRF, `audit.events` append-only schema with role-based grants, helmet + env-driven CORS allowlist + rate limiting + structured error envelope (see [ADR-0021](docs/decisions/0021-phase-2-security-baseline.md)).
|
||||
@@ -74,7 +74,7 @@ ADRs 0001 → 0025 are accepted and cover the structural, security, observabilit
|
||||
|
||||
- `DownstreamApiClient` + OBO ([ADR-0014](docs/decisions/0014-downstream-api-access-obo-pattern.md)) — module scaffolded (`obo.strategy`, `signed-assertion.strategy`, JWKS publisher, encrypted token cache); no v1 consumer yet. Wires in when the first business route needs an Entra-protected API.
|
||||
- `@RequireMfa()` step-up consumer routes ([ADR-0011](docs/decisions/0011-mfa-enforcement-entra-conditional-access.md)) — guard + decorator shipped; awaiting first sensitive route that needs explicit freshness enforcement beyond the Conditional Access baseline.
|
||||
- **`@RequireScope` Prisma-backed resolver + first consumer surface** — `StubScopeResolver` returns `unrestricted` for everyone in v1 per [ADR-0025](docs/decisions/0025-authorization-model-privileges-roles-scopes.md) §331. The real implementation lands with ADR-0026 (proposed: `Person` golden record + portal-side `User` + `user_scopes` table); the first scope-aware route surface follows in the same PR family.
|
||||
- **`@RequireScope` Prisma-backed resolver + first consumer surface** — `StubScopeResolver` returns `unrestricted` for everyone in v1 per [ADR-0025](docs/decisions/0025-authorization-model-privileges-roles-scopes.md) §331. Real implementation lands across [ADR-0026](docs/decisions/0026-person-user-portal-data-model.md) (proposed: `Person` + `User` + `UserScope`) and [ADR-0027](docs/decisions/0027-portal-side-organisational-hierarchy.md) (proposed: `Region` / `Delegation` / `Structure` with `kind` discriminator + nullable FINESS / SIRET). Sequencing: ADR-0026 PR 1 + ADR-0027 PR 1 ship schema in parallel; ADR-0026 PR 2 then lands the `PrismaScopeResolver` + admin scope-seeding UI + test-tenant seed (which references ADR-0027's `Structure.code` values). The follow-up [ADR-0028](#) covers Pléiades / Acteurs+ / cascade syncs + facet schemas.
|
||||
- **Proto-drift CI gate for the AI relay** ([ADR-0024](docs/decisions/0024-ai-service-relay-grpc-sse-bridge.md)) — asserts the vendored `apf-ai-service` proto files stay in lockstep with the upstream contract.
|
||||
- **Admin app — CMS & menu management** ([ADR-0020](docs/decisions/0020-portal-admin-app.md)) — multilingual static-page editor + navigation menu builder. The user-list + audit-log-viewer modules already exist; the CMS/menu pair is the remaining v1 module scope.
|
||||
- **Strategic security baseline ADR** — separate from the implementation-level [ADR-0021](docs/decisions/0021-phase-2-security-baseline.md). Remains **paused** awaiting RSSI input on the OWASP ASVS reference level and adjacent frameworks (HDS, GDPR, possibly NIS 2). When it lands it will either confirm 0021 or supersede pieces of it.
|
||||
|
||||
Reference in New Issue
Block a user