feat(education): add native question publication lifecycle
This commit is contained in:
@@ -29,7 +29,7 @@ The durable artifact classification, adoption matrix, version allocation, backfi
|
||||
3. V4030 owns the final Practice core-loop schema, including sessions/questions, reports/details, wrong questions, favorites, and unified `education_idempotency`. Fresh schema does not create legacy answer/submit idempotency tables.
|
||||
4. Existing manually bootstrapped databases require explicit schema comparison and adoption. A verified V4020-equivalent catalog may use an environment-specific 4020 baseline; incompatible environments require a higher-version correction, never falsified history.
|
||||
5. Legacy idempotency data is backfilled into the unified table before any later forward cleanup. Legacy tables are preserved during initial adoption.
|
||||
6. The Education capability menu seed is a separate conditional V4040 owner only if the administrator endpoint remains approved; role assignment is not seeded.
|
||||
6. The earlier V4040 capability-seed plan was superseded after V4040 was allocated to the submit-claim lease. V4080 conditionally seeds the approved capability plus question author/publish/archive permissions when `system_menu` exists; role assignment is not seeded.
|
||||
7. Docker/manual SQL initialization and MySQL rollback runbooks must be removed from active operations when EDU-006 lands. EDU-016's temporary test bridge becomes Flyway-driven after equivalence is proven.
|
||||
8. The inspected local disposable `postgresdb` had no Flyway history and no Education tables. EDU-005 ran no migration and makes no migration-success claim.
|
||||
|
||||
@@ -102,6 +102,34 @@ The durable artifact classification, adoption matrix, version allocation, backfi
|
||||
|
||||
**Evidence:** Schema graph analysis of V4020 (11 catalog tables, all single-column FKs, no composite tenant enforcement), legacy RLS/trigger audit (Supabase RLS + staged composite FK migration), current CHECK constraints provide row-level but not cross-row enforcement.
|
||||
|
||||
### Native question authoring authority and lifecycle (resolved 2026-07-30)
|
||||
|
||||
**Decision:** Local tenant question authoring is available only under explicit `JAVA_READ` authority and fails before persistence access in `SCALAR_READ`. New questions are `DRAFT`; the current command surface permits only `DRAFT → PUBLISHED → ARCHIVED`, with no restore or retire command.
|
||||
|
||||
**Rules:**
|
||||
1. Create, publish, and archive are explicit commands with separate System RBAC permissions; clients cannot submit tenant, scope, lifecycle, or actor fields.
|
||||
2. Tenant authoring always creates `TENANT_OWNED` content for the current framework tenant. PUBLIC/platform-curator authoring is not part of this slice.
|
||||
3. Question Content Versions are immutable. Publication changes lifecycle state for the current version and never changes `tenant_id`, `scope`, or content version.
|
||||
4. Education appends a lifecycle audit in the same transaction as each state transition. The asynchronous platform operation log remains supplementary, not proof of atomic publication.
|
||||
5. Direct question visibility follows the question's Publication State. Entry, node, and collection availability gates their own discovery routes and does not mutate the question lifecycle or historical practice snapshots.
|
||||
6. Historical `HIDDEN`, `INACTIVE`, and `PUBLISHED/is_published=false` rows map to `ARCHIVED`; historical `DRAFT` rows become non-published; only consistent published rows remain `PUBLISHED`.
|
||||
7. V4080 adds Question Version → Question as the twentieth guarded catalog edge. A version must have exactly the same tenant and scope as its question, and the version table becomes the twelfth catalog table whose ownership cannot change after insert.
|
||||
|
||||
**Permission and data-scope matrix:**
|
||||
|
||||
| Actor capability | Permission | Allowed rows | Data scope |
|
||||
|---|---|---|---|
|
||||
| Author | `education:question:author` | Create current-tenant `TENANT_OWNED` drafts | Current tenant; no request-supplied owner or tenant |
|
||||
| Publisher | `education:question:publish` | Current-tenant `TENANT_OWNED` drafts | Tenant-wide shared catalog asset; department/self DataPermission does not expand access |
|
||||
| Archiver | `education:question:archive` | Current-tenant `TENANT_OWNED` published questions | Tenant-wide shared catalog asset; department/self DataPermission does not expand access |
|
||||
| Platform curator | none in this slice | No PUBLIC or tenant-owned writes through these endpoints | Fail closed |
|
||||
|
||||
V4080 conditionally seeds the four Education permissions (`education:capability` plus author/publish/archive) when the adopted platform schema contains `system_menu`. It fails when a fixed ID is already occupied by a different permission and deliberately does not assign the permissions to any role.
|
||||
|
||||
**Rationale:** A successful PostgreSQL write while Scalar remains authoritative would be student-invisible. Department/self DataPermission has no truthful meaning for tenant-wide shared catalog rows without a separate ownership model, so action permissions plus framework tenant isolation are explicit rather than applying a misleading annotation.
|
||||
|
||||
**ADR:** `docs/adr/0001-native-question-authoring-authority.md`.
|
||||
|
||||
## Unresolved decisions
|
||||
|
||||
1. The valid option schema for each question type, including whether absent options are legal; whether malformed published content is omitted or produces a controlled source failure.
|
||||
|
||||
Reference in New Issue
Block a user