docs(education): define manual collection contract
This commit is contained in:
@@ -120,6 +120,11 @@ The durable artifact classification, adoption matrix, version allocation, backfi
|
||||
11. Tenant Content Node authoring is JAVA_READ-only, current-tenant TENANT_OWNED-only, and uses `DRAFT → ACTIVE → ARCHIVED` with one CAS `authoring_version` shared by revisions and transitions.
|
||||
12. Content Node activation requires a structurally available entry and parent. Student discovery and Question Placement treat only ACTIVE nodes as available. Content Node lifecycle audit is transactional and append-only.
|
||||
13. Content Node permissions are `education:content-node:author`, `education:content-node:publish`, and `education:content-node:archive`; V4100 seeds no permission, menu, role, or role grant.
|
||||
14. The next bounded EDU-010 slice is a JAVA_READ-only current-tenant `TENANT_OWNED` Manual Question Collection attached to one existing ACTIVE, visible Content Node. Content Entry creation is excluded, so the target node and its structurally available Content Entry must be pre-provisioned.
|
||||
15. A Manual Question Collection uses `DRAFT → ACTIVE → ARCHIVED` with one optimistic authoring version. Only DRAFT metadata and membership may change; ACTIVE collection content and membership are immutable, and ARCHIVED is terminal.
|
||||
16. Membership is an ordered replace-all command available only in DRAFT. Every member must be a current-tenant `TENANT_OWNED` PUBLISHED Question, and duplicate Question IDs are rejected rather than collapsed or upserted.
|
||||
17. Activation exposes the collection route only when the collection and its existing Content Node are available. Archiving closes only collection-route discovery; it does not alter direct Question visibility or historical Practice Question Snapshots.
|
||||
18. `access_rules` is descriptive reserved metadata in this slice, not entitlement enforcement. PUBLIC Question curation, dynamic filters, paid/private access, Category, Practice Blueprint, and Content Entry creation are excluded.
|
||||
|
||||
**Permission and data-scope matrix:**
|
||||
|
||||
@@ -140,17 +145,17 @@ V4080/V4090 conditionally seed the five Education permissions (`education:capabi
|
||||
|
||||
**ADR:** `docs/adr/0001-native-question-authoring-authority.md`.
|
||||
|
||||
The accepted Manual Question Collection slice does not warrant a separate ADR: it applies the already-recorded native-authority, tenant-ownership, lifecycle, optimistic-concurrency, route-gating, and snapshot-preservation decisions to one narrower aggregate, without adding a hard-to-reverse architectural trade-off.
|
||||
|
||||
## 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.
|
||||
2. Whether untracked /Users/tiku1/code/ruoyi-vue-pro/sql/postgresql/education files are intended for promotion into Flyway or are design/manual artifacts.
|
||||
3. Whether V4010/V4020 or any manual core-loop DDL has ever run successfully in PostgreSQL; no runtime migration evidence exists.
|
||||
4. Which Auth/Profile/extended Learning semantics are replaced by Member/System/Infra versus Education-owned, including vocabulary, leaderboard, stats, trend, feedback, exam dates, notifications, points, and badges.
|
||||
5. Whether tenant appearance, domains, payment accounts, auth providers, secrets, activation codes, coupons, integrations, marketing, public-bank grants, and sync are in scope or explicitly retired.
|
||||
6. Whether legacy assets are migrated, re-uploaded, re-scanned, or retired, and who owns ClamAV/scanner integration.
|
||||
7. Which legacy RLS, triggers, functions, grants, seeds, queue leases, retry behavior, and operational semantics are contractual and need Java/constraint/event/job reproduction.
|
||||
8. Whether the ten required Phase 0 artifacts must be committed files or may remain in reviewed scratch form during discovery.
|
||||
9. Whether a future System-owned immutable Tenant Code or signed bootstrap locator is required beyond the accepted public-handle/existence-disclosure contract.
|
||||
1. Which Auth/Profile/extended Learning semantics are replaced by Member/System/Infra versus Education-owned, including vocabulary, leaderboard, stats, trend, feedback, exam dates, notifications, points, and badges.
|
||||
2. Whether tenant appearance, domains, payment accounts, auth providers, secrets, activation codes, coupons, integrations, marketing, public-bank grants, and sync are in scope or explicitly retired.
|
||||
3. Whether legacy assets are migrated, re-uploaded, re-scanned, or retired, and who owns ClamAV/scanner integration.
|
||||
4. Which legacy RLS, triggers, functions, grants, seeds, queue leases, retry behavior, and operational semantics are contractual and need Java/constraint/event/job reproduction.
|
||||
5. Whether the ten required Phase 0 artifacts must be committed files or may remain in reviewed scratch form during discovery.
|
||||
6. Whether a future System-owned immutable Tenant Code or signed bootstrap locator is required beyond the accepted public-handle/existence-disclosure contract.
|
||||
7. Which shared environments already carry V4010/V4020 or manual equivalents and what explicit baseline/adoption record each requires. The root `sql/postgresql/education/` classification and the module-owned Flyway authority are resolved; disposable PostgreSQL execution evidence exists, but no shared-environment migration is claimed.
|
||||
|
||||
## Decision rule
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# EDU-010 — Tenant content publication and graph integrity
|
||||
|
||||
- **Status:** in progress — catalog graph-integrity, JAVA_READ tenant-question lifecycle, Question Placement, and tenant Content Node lifecycle slices are delivered; category, collection, and blueprint authoring remain
|
||||
- **Status:** in progress — catalog graph-integrity, JAVA_READ tenant-question lifecycle, Question Placement, and tenant Content Node lifecycle slices are delivered; the Manual Question Collection slice is contract-ready but not implemented; category and blueprint authoring remain
|
||||
- **Type:** implementation program
|
||||
- **Phase:** 3
|
||||
- **Blockers:** EDU-004 ✓ (done), EDU-009 ✓ (done), provider-authority decision ✓ (resolved 2026-07-30, see decisions.md), PUBLIC graph-semantics decision ✓ (resolved 2026-07-30, see decisions.md)
|
||||
@@ -28,6 +28,11 @@ Authorized tenant administrators can author, classify, publish, archive, and ret
|
||||
- [x] Publication is transactional and auditable.
|
||||
- [x] Tenant Question Placement is permission-separated, tenant-safe, optimistic, and frozen after publication.
|
||||
- [x] Database graph-integrity changes use `flyway-postgresql` and forward migrations V4070/V4090.
|
||||
- [x] The next Manual Question Collection bounded contract, exclusions, pre-provisioning constraint, and readiness gates are explicit before implementation.
|
||||
- [ ] A current-tenant `TENANT_OWNED` Manual Question Collection can be authored only in `JAVA_READ` on an existing ACTIVE, visible Content Node.
|
||||
- [ ] Collection lifecycle is `DRAFT → ACTIVE → ARCHIVED` with one optimistic authoring version; ACTIVE content/membership is immutable and archive is terminal.
|
||||
- [ ] DRAFT membership is ordered replace-all, accepts only current-tenant `TENANT_OWNED` PUBLISHED Questions, and rejects duplicates.
|
||||
- [ ] Collection archive gates only collection-route discovery while direct Question visibility and historical Practice snapshots remain unchanged.
|
||||
|
||||
## Delivery progress — graph-integrity slice (2026-07-30)
|
||||
|
||||
@@ -98,6 +103,35 @@ Delivered:
|
||||
- Activation/archive append an actor/version/status audit in the same transaction. V4100 makes that audit append-only and uses a deferred constraint trigger to reject lifecycle changes without the matching audit.
|
||||
- Student catalog discovery and Question Placement continue to require `is_active=true`; V4100 constrains that flag to `publication_status='ACTIVE'`, so drafts/archives cannot appear or accept placement.
|
||||
|
||||
## Next slice — Manual Question Collection bounded contract (accepted 2026-07-31)
|
||||
|
||||
This section records domain and readiness decisions only. No production Java, SQL, Flyway migration, permission seed, or runtime behavior is delivered by this documentation step.
|
||||
|
||||
Accepted boundary:
|
||||
|
||||
1. Native authority only: every collection command is available only in `JAVA_READ`; unsupported modes must fail before persistence access.
|
||||
2. Tenant ownership only: tenant APIs manage current-tenant `TENANT_OWNED` collections. PUBLIC Questions, PUBLIC collection curation, and platform-curator workflows are excluded.
|
||||
3. Placement boundary: a collection belongs to one existing ACTIVE, visible Content Node. Content Entry creation is excluded, so that node and its structurally available Content Entry must already be provisioned before collection authoring.
|
||||
4. Manual assembly only: membership is an explicit ordered list, not a dynamic filter, Category result, Question Bank query, node-descendant query, or Practice Blueprint.
|
||||
5. Lifecycle and concurrency: collections move only `DRAFT → ACTIVE → ARCHIVED`. One optimistic authoring version covers accepted draft revisions, ordered membership replacement, activation, and archive. ACTIVE collection fields and membership are immutable; ARCHIVED is terminal.
|
||||
6. Membership replacement: only a DRAFT collection accepts an ordered replace-all membership command. Every member must be a current-tenant `TENANT_OWNED` PUBLISHED Question. Duplicate Question IDs are a request conflict and are not deduplicated or upserted.
|
||||
7. Visibility: an ACTIVE collection may be discovered only through its available Content Node. Archive closes collection listing and collection-question discovery, but does not archive member Questions, change their direct visibility, or invalidate immutable Practice Question Snapshots already captured.
|
||||
8. Access metadata: `access_rules` remains descriptive reserved metadata. This slice does not interpret it as paid, private, member, SVIP, quota, or other entitlement enforcement.
|
||||
9. Explicit exclusions: dynamic filters, paid/private access, Category CRUD, Practice Blueprint authoring, Content Entry creation, PUBLIC content/curation, Retire, and legacy section/score/required membership extensions.
|
||||
|
||||
### Readiness and implementation gates
|
||||
|
||||
- [x] Current target evidence identifies `education_question_collection_question` as the sole collection-membership fact, with tenant-scoped duplicate prevention and deterministic membership order.
|
||||
- [x] Legacy evidence confirms manual collections, transactional replace-all membership, server-derived counts, active-parent route gating, and an independent `DRAFT/ACTIVE/ARCHIVED` lifecycle; richer dynamic/filter and per-member scoring semantics are deliberately excluded.
|
||||
- [x] Provider-neutral option safety is already resolved by EDU-001 and `QuestionContentSafety`; it is not an EDU-010 blocker.
|
||||
- [x] Root Education SQL is already classified as non-operational manual/design history by EDU-005; module-owned PostgreSQL Flyway remains authoritative. Shared-environment adoption inventory remains an operational rollout gate, not an unresolved schema-owner decision.
|
||||
- [ ] Before implementation, allocate the next project-wide Flyway version through `flyway-postgresql` and design forward adoption from the current boolean collection availability fields.
|
||||
- [ ] Make collection listing and collection-question reads validate collection lifecycle and Content Node availability at the route boundary; the current Java collection-question read loads membership without first proving the parent collection is available.
|
||||
- [ ] Define separate collection author/publish/archive permissions, tenant-bound command requests, lifecycle audit, CAS conflict errors, server-derived `question_count`, and transaction boundaries.
|
||||
- [ ] Add focused service, method-security, and real-PostgreSQL tests for provider fail-before-Mapper behavior, cross-tenant/PUBLIC rejection, duplicate membership, stale versions, ACTIVE immutability, terminal archive, route gating, direct Question visibility, and snapshot preservation.
|
||||
|
||||
No new ADR is added: this bounded slice consistently applies the existing native-authority and lifecycle decisions and does not introduce a separate hard-to-reverse architectural trade-off.
|
||||
|
||||
## Verification evidence (2026-07-30)
|
||||
|
||||
- `mvn -pl yudao-module-education clean test` with the five `EDU_TEST_POSTGRES_*` variables pointed at the local Docker PostgreSQL: **502 tests passed**, including 20 Flyway migration tests and nine lifecycle/placement PostgreSQL integration tests. V4090 was actually executed in disposable PostgreSQL schemas.
|
||||
|
||||
Reference in New Issue
Block a user