5.9 KiB
First Recommended Slice: EDU-P0-S1
Phase 0 static assessment generated on 2026-07-29. No build, test, application startup, PostgreSQL connection, or Flyway migration was executed during this assessment.
Provider-neutral fail-closed safe question browsing and session restoration
Rationale
The initial native-only slice was corrected because SCALAR_READ is the verified default and JavaCatalogProvider is conditional. A provider-neutral safe-content contract is the smallest observable correction that addresses both active and optional paths, avoids provider-authority assumptions, protects the dirty worktree, and covers the second fail-open path in restored sessions.
Scope
- Define and document the common option validity contract, including whether absent options are legal for each question type; invalid published question payloads must be omitted or return a controlled failure, never an apparently valid empty-options question.
- Apply and test the contract for both ScalarCatalogProvider and JavaCatalogProvider, despite SCALAR_READ being the current default, so provider mode cannot change safety behavior.
- Apply and test safe projection for single-question browsing and collection/catalog browsing paths.
- Make SessionResponseAssembler reject, mark unavailable, or otherwise fail closed on malformed persisted snapshots; do not silently convert parse failure to an empty list.
- Verify publication/status/visibility and unavailable-provider fail-closed behavior at the service boundary.
- Add cross-tenant and PUBLIC-scope negative tests, while recording that current native reads use an intentional TenantUtils.executeIgnore/manual predicate boundary.
- Separate committed behavior from dirty behavior in the implementation report; do not claim runtime verification.
- Critical files for implementation: /Users/tiku1/code/ruoyi-vue-pro/yudao-module-education/src/main/java/cn/iocoder/yudao/module/education/service/catalog/provider/JavaCatalogProvider.java; /Users/tiku1/code/ruoyi-vue-pro/yudao-module-education/src/main/java/cn/iocoder/yudao/module/education/service/catalog/ScalarCatalogProvider.java; /Users/tiku1/code/ruoyi-vue-pro/yudao-module-education/src/main/java/cn/iocoder/yudao/module/education/service/question/QuestionCatalogServiceImpl.java; /Users/tiku1/code/ruoyi-vue-pro/yudao-module-education/src/main/java/cn/iocoder/yudao/module/education/service/practice/SessionResponseAssembler.java; /Users/tiku1/code/ruoyi-vue-pro/yudao-module-education/src/test/java/cn/iocoder/yudao/module/education/service/catalog/CatalogServiceImplTest.java.
Reuse boundaries
- Reuse /Users/tiku1/code/ruoyi-vue-pro/yudao-module-education/src/main/java/cn/iocoder/yudao/module/education/service/catalog/CatalogProvider.java and existing provider selection; do not choose a new provider in this slice.
- Reuse existing safe question DTO/assembler boundaries in QuestionCatalogServiceImpl; never return DOs, answers, explanations, correctness flags, or admin metadata.
- Apply one shared, provider-neutral option validation contract at the provider-to-safe-question/session-snapshot boundary; do not duplicate divergent validation rules.
- Reuse framework TenantContextHolder and the existing explicit CatalogScopeQuery predicate. Do not broaden TenantUtils.executeIgnore or add a custom tenant bypass.
- Keep changes inside Education unless a proven public contract gap requires a minimal separately owned interface; do not alter System, Member, Scalar infrastructure, or database schema speculatively.
- Preserve and classify the existing dirty tree; implementation must be serial and must not overwrite unrelated files.
Database change
No database change for the bounded correctness slice. Do not modify V4010 or V4020. Do not promote untracked SQL during this slice. If later graph-integrity or core-loop schema work is approved, create new immutable module-owned PostgreSQL Flyway migrations under /Users/tiku1/code/ruoyi-vue-pro/yudao-module-education/src/main/resources/db/migration/education/ after schema review; never claim execution without a real PostgreSQL run.
Test plan
- Focused unit/provider contract tests for null, absent, empty, malformed, structurally invalid, blank-label, duplicate/order-invalid options, and valid question-type-specific payloads.
- Service tests proving malformed published content cannot produce a student-visible apparently valid safe question.
- Session create/restore tests proving malformed persisted snapshots fail closed and valid snapshots retain safe fields only.
- Tests for single browse, collection browse, unpublished/invisible content, unavailable provider, disabled feature, cross-tenant access, and tenant_id=0 PUBLIC scope.
- If both providers cannot yet share a concrete contract, add contract tests parameterized over each implementation and record the remaining provider decision rather than silently selecting one.
- No concurrency test is required for this read-only slice, but atomic submit-idempotency reservation and crash recovery must block the later submit slice.
- After implementation authorization only: run focused Education tests, git diff --check, and mvn -pl yudao-server -am -DskipTests clean compile; if schema files remain unchanged, do not claim Flyway execution.
Rollback
Application-level rollback is configuration/provider disablement or restoration of the prior provider behavior after review, without destructive Git or database rollback. No database rollback applies because this slice has no schema change. If malformed persisted snapshots are encountered, fail closed with a controlled unavailable/corrupt-content outcome rather than silently restoring an empty-options question.
Authorization gate
This document selects and specifies the first slice; it does not authorize broad implementation. Before editing, re-read the dirty working tree, isolate existing user changes, state the exact files to touch, and execute the slice test-first.