# 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.