Files
course-registration/docs/superpowers/plans/2026-09-17-course-registration-implementation.md
T

3.7 KiB

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.