8.3 KiB
W2 Wave Review: Onboarding Checklist, Company CRUD, and Company Knowledge
Verdict
- Wave: W2
- Base:
3e7c6e7 - Head:
a5730a7 - Verdict: PASS
- Blocking findings: None
- Deferred T6 obligations: Mandatory, as listed below
Scope Reviewed
Read and cross-checked:
changes/n04-onboard/execution-contract.mdchanges/n04-onboard/specs/onboarding-checklist/spec.mdchanges/n04-onboard/specs/company-knowledge/spec.mdchanges/n04-onboard/design.md.superpowers/sdd/task-briefs/T3.md.superpowers/sdd/task-briefs/T4.md.superpowers/sdd/task-briefs/T5.md.superpowers/sdd/reviews/W2-T3.md.superpowers/sdd/reviews/W2-T4.md.superpowers/sdd/reviews/W2-T5.md
Inspected the combined diff 3e7c6e7..a5730a7, including all production additions for student checklist access, company checklist CRUD, company knowledge configuration/overview, shared error changes, and the associated service/controller tests.
Evidence
Command:
cd D:\1\zhi\zhilai\mydreamjob-server
$env:JAVA_HOME='D:\java'
$env:Path='D:\java\bin;'+$env:Path
& 'D:\maven\apache-maven-3.9.7\bin\mvn.cmd' '-Dtest=Onboarding*Test,CompanyKnowledge*Test' test
Result:
Tests run: 66, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS
Per-class results:
CompanyKnowledgeControllerTest: 8 passedCompanyKnowledgeServiceTest: 14 passedOnboardingChecklistControllerTest: 5 passedOnboardingChecklistServiceTest: 10 passedOnboardingCompanyChecklistControllerTest: 10 passedOnboardingCompanyChecklistServiceTest: 12 passedOnboardingMigrationTest: 1 passedOnboardingRepositoryIntegrationTest: 5 passedOnboardingSeedDataIntegrationTest: 1 passed
git diff --check 3e7c6e7..a5730a7 passed with no whitespace errors.
Cross-Task Integration Findings
Student checklist and company CRUD
- Company-created items use the same
onboarding_checklist_itemsidentity space and predicates consumed by the effective checklist query. OnboardingChecklistItemRepository.findEffectiveChecklistItemsreturns active STANDARD items plus active COMPANY items scoped to the requested company, with stablesortOrder ASC, id ASCordering.- Company soft deletion sets
active=false, which removes the item from the student effective checklist while preserving the row and any student progress history. - Student progress is keyed by the shared
itemId, so a company item created through T4 is addressable through T3 without a translation layer. - Cross-company ownership checks use the same
scopeType,scopeId, andcompanyIdpredicate for company listing/update/delete paths.
Company knowledge and checklist interactions
- Checklist and knowledge controllers share only the
/onboardingnamespace and API response conventions; their paths, services, tables, and ownership checks do not collide. - Company knowledge reads are scoped by
company_id; student overviews fall back toBASIC_ONLYwithout creating knowledge rows. - Review aggregation is isolated to published, approved reviews through company jobs and does not mutate checklist or review data.
Error-code consistency
The new codes are defined once and consistently mapped:
9701ONBOARDING_CHECKLIST_ITEM_NOT_FOUND-> HTTP 4049702ONBOARDING_CHECKLIST_ITEM_CONCURRENT_UPDATE-> HTTP 4099703ONBOARDING_ITEM_LIMIT_EXCEEDED-> HTTP 4099704ONBOARDING_IDEMPOTENCY_CONFLICT-> HTTP 4099705ONBOARDING_PROGRESS_CONCURRENT_UPDATE-> HTTP 4099706ONBOARDING_KNOWLEDGE_CONCURRENT_UPDATE-> HTTP 409
The shared exception-handler additions preserve the existing mappings for prior error codes.
Sensitive-field check
The W2 DTOs are whitelist-shaped. Internal fields such as ownerUserId, studentUserId, requestHash, raw idempotency keys, review hashes, moderation reasons, tokens, IP addresses, and User-Agent values are not exposed in the onboarding response DTOs. Internal repository/entity field usage is restricted to persistence and ownership logic.
Existing API semantics
The combined diff changes only shared error-code handling outside the new onboarding package. No existing company, job, offer, review, or dimension-score controller path, request contract, response contract, or authorization behavior was changed. The exception-handler edits are additive mappings for the new 97xx codes.
Non-Blocking Findings
GlobalExceptionHandler.javawas modified even though the W2 task briefs list only the onboarding files andErrorCode.javaexplicitly. The changes are additive, necessary to realize the approved 404/409 contract, and do not alter existing error mappings. Reconcile ownership and scope wording during T6/T8 so the file is not treated as an unaccounted change.- The W2 suite uses service tests and MockMvc with mocked services. It does not yet prove a database-backed end-to-end flow from COMPANY create, through STUDENT checklist read, to STUDENT completion update. T6 integration tests should close this cross-layer gap.
- Existing review coverage still lacks the exact two-review boundary, a full
HIDDEN + APPROVEDexclusion case, a 10-tag cap/quoted-JSON case, and direct MockMvc assertions for some conflict mappings. These are coverage gaps, not current W2 implementation defects. - Real MySQL 8.4 execution remains unverified; the W2 suite uses H2
MODE=MySQL. B3/T6 verification must run the approved MySQL path before the final gate. SecurityConfigcurrently relies onanyRequest().authenticated()for/onboarding/**; the explicit path matcher and complete anonymous/STUDENT/COMPANY/ADMIN matrix remain T6 work.
Mandatory T6 Obligations Carried Forward
The following must be implemented and proven by T6 before W3 can be considered complete:
Concurrent company checklist create and limit
- Fire two concurrent creates with the same company, same normalized
idempotencyKey, and same body. Assert exactly one row, both callers receive the same successful item or a safe replay, and neither receives an internal 500. - Fire two concurrent creates with the same
idempotencyKeybut different bodies. Assert exactly one row, one successful create, and one 4099704, not a unique-constraint 500. - Start with 49 active company items and concurrently create two distinct items. Assert the final active count is exactly 50, one request succeeds, one returns 409
9703, and no partial or 51st row remains. - Start with 50 active company items and assert new creates return 409
9703. Prove inactive items are excluded from the active limit and that replaying an existing idempotency key remains successful without counting as a new item. - Repeat the idempotency-key race across two companies and assert
(company_id, idempotency_key)isolation with no cross-company replay.
First progress version and first-create race
- When no
student_onboarding_progressrow exists, a request carrying a non-zeroversionmust return 4099705, including the first completion path. - Exercise simultaneous first progress creation for the same student/item. Assert one row, one safe result, and a deterministic conflict/replay mapping rather than an uncaught unique-constraint 500.
First company-knowledge upsert race
- Exercise simultaneous first knowledge upserts for the same company. Assert one row, one successful create, and a deterministic
9706or other contract-approved conflict response; do not allow an uncaught unique-constraint 500. - Confirm the same behavior through the HTTP integration tests with the final error/status mapping.
Readiness for W3/T6
The W2 implementation and review evidence are sufficient to proceed. T6 has the required service surfaces, shared error constants, ownership predicates, and test scaffolding. If a database-level lock becomes necessary to make the 50-item boundary or first-create race deterministic, update the T6 scope/contract explicitly before editing repository or migration files; do not silently widen the file scope.
Final Assessment
Verdict: PASS
W2 is spec-compliant at the service and controller contract level, passes the required evidence suite, preserves existing API semantics, maintains response-field minimization, and provides the necessary interfaces for T6. The unresolved concurrency and first-create-version behavior is correctly deferred to W3/T6 and must not be closed without the obligations above.