65 lines
3.7 KiB
Markdown
65 lines
3.7 KiB
Markdown
# Course Registration Implementation Plan
|
|
|
|
> **For agentic workers:** Implement task-by-task with test-first verification for behavior changes.
|
|
|
|
**Goal:** Implement the Requirements.md course-registration API, concurrency rules, query APIs, seed data, OpenAPI/Postman assets, environment profiles, and Docker Compose while leaving k6 for a later phase.
|
|
|
|
**Architecture:** Keep transaction/lock orchestration in application services, isolate deterministic registration rules in a validator/schedule checker, use JPA repositories for fixed User -> Lesson pessimistic locking, and separate lesson query concerns from registration mutation concerns. Use bulk schedule/enrollment queries to avoid per-row N+1 behavior.
|
|
|
|
**Tech Stack:** Java 21, Spring Boot 4.1.1, Spring Data JPA, H2 local/test, PostgreSQL dev/prod, springdoc-openapi 3.x, JUnit 5.
|
|
|
|
**Spec:** `docs/Requirements.md`
|
|
|
|
## Global Constraints
|
|
|
|
- No master-data CRUD APIs.
|
|
- No update-registration API; section changes are cancel + re-register.
|
|
- No authentication/JWT in this scope.
|
|
- Lock order is always User -> Lesson.
|
|
- Registration rejection order is R1 through R8 exactly as specified.
|
|
- Cancellation rejection order is C1 through C4.
|
|
- k6 is explicitly deferred.
|
|
- Existing tracked `.env` is not read, printed, or rewritten; provide `.env.example` separately.
|
|
|
|
---
|
|
|
|
### Task 1: Normalize persistence model and restore a compilable baseline
|
|
- Modify BaseEntity/BaseCreateEntity/BaseTimeZoneEntity, Semester, Subject, Lesson, LessonSchedule, UserLesson.
|
|
- Remove composite UserLessonId usage and use String UUID surrogate IDs.
|
|
- Add domain integrity checks for capacity, credit, schedule range, and semester ranges.
|
|
- Add repository types needed by the new model.
|
|
- Verify `compileJava` before adding behavior.
|
|
|
|
### Task 2: Add registration rule tests and implementation
|
|
- Add tests for period boundaries, grade/role, duplicate lesson/subject, schedule overlap boundaries, credit boundary, and capacity boundary.
|
|
- Implement RegistrationErrorCode, RegistrationException, ScheduleConflictChecker, and RegistrationValidator.
|
|
- Run targeted unit tests red -> green.
|
|
|
|
### Task 3: Implement transaction and locking flow
|
|
- Add User and Lesson pessimistic lock repository methods with 3s lock hints.
|
|
- Implement CourseRegistrationService register/cancel/list using fixed User -> Lesson lock ordering.
|
|
- Add integration tests for success/cancel/re-register and core rejection paths.
|
|
- Add concurrency tests for capacity, same-student credit, schedule, and duplicate requests.
|
|
|
|
### Task 4: Implement HTTP API and lesson queries
|
|
- Add typed DTO records and validation.
|
|
- Add registration controller POST/GET/DELETE endpoints.
|
|
- Add LessonQueryService and LessonController list/detail endpoints.
|
|
- Bulk load schedules and enrollment counts for paged lesson results.
|
|
- Add common error response and controller advice.
|
|
|
|
### Task 5: Seed data and runtime profiles
|
|
- Replace DataSeeder with deterministic, idempotent scenario-oriented local/dev seed data controlled by `app.seed.enabled`.
|
|
- Split shared/local/dev/prod config; local H2, dev PostgreSQL update, prod PostgreSQL validate.
|
|
- Provide Clock bean for deterministic service tests.
|
|
|
|
### Task 6: Swagger, Postman, Docker
|
|
- Upgrade springdoc to Boot-4-compatible 3.x and configure OpenAPI metadata.
|
|
- Add Postman collection plus local/dev environments using deterministic seed IDs.
|
|
- Add Actuator health, Dockerfile, `.dockerignore`, `.env.example`, and docker-compose with PostgreSQL + app health checks.
|
|
|
|
### Task 7: Final verification
|
|
- Run full `./gradlew test` and `./gradlew build` as managed tasks.
|
|
- Validate Docker Compose config when Docker Compose is available.
|
|
- Inspect git diff/status and report implemented scope and any remaining environmental limitations.
|