# Auth Refactor Implementation Plan > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. **Goal:** Refactor `modules/auth` to keep only the new standardized auth API while preserving the legacy password-login and UKey-login business rules for the four main roles. **Architecture:** Keep one canonical auth module built around four roles plus `AuthLevel`, split standardized controllers for session and admin actions, and move all old flow compatibility into the service layer instead of keeping compatibility endpoints. Preserve legacy verification order for UKey login and password-login safety checks while normalizing DTO names, entity fields, and mapper contracts. **Tech Stack:** Spring Boot, MyBatis, Flyway, Jakarta Validation, JUnit 5, Maven --- ### Task 1: Lock the domain model to four roles plus auth level **Files:** - Modify: `src/main/java/com/cisd/tms/modules/auth/enums/RoleCode.java` - Create: `src/main/java/com/cisd/tms/modules/auth/enums/AuthMethod.java` - Modify: `src/main/java/com/cisd/tms/modules/auth/enums/AuthLevel.java` - Create: `src/main/java/com/cisd/tms/modules/auth/service/AuthPolicyService.java` - Test: `src/test/java/com/cisd/tms/modules/auth/service/AuthDomainModelTest.java` **Step 1: Write the failing test** Add assertions that: - `RoleCode` only exposes `SUPER_ADMIN`, `KEY_ADMIN`, `AUDIT_ADMIN`, `OPS_ADMIN` - each role has the correct required UKey count - `PASSWORD` maps to `LIMITED` - `UKEY` maps to `FULL` **Step 2: Run test to verify it fails** Run: `mvn -q -Dtest=AuthDomainModelTest test` Expected: FAIL because role/auth-method policy is not fully modeled yet. **Step 3: Write minimal implementation** Implement: - `AuthMethod` enum - updated `RoleCode` - minimal `AuthPolicyService` helpers such as: - `requiredUkeyCount(roleCode)` - `authLevelFor(method)` **Step 4: Run test to verify it passes** Run: `mvn -q -Dtest=AuthDomainModelTest test` Expected: PASS **Step 5: Commit** ```bash git add src/main/java/com/cisd/tms/modules/auth/enums/RoleCode.java src/main/java/com/cisd/tms/modules/auth/enums/AuthMethod.java src/main/java/com/cisd/tms/modules/auth/enums/AuthLevel.java src/main/java/com/cisd/tms/modules/auth/service/AuthPolicyService.java src/test/java/com/cisd/tms/modules/auth/service/AuthDomainModelTest.java git commit -m "refactor: normalize auth role domain model" ``` ### Task 2: Normalize request and response DTOs to the new API contract **Files:** - Create: `src/main/java/com/cisd/tms/modules/auth/dto/PasswordLoginRequest.java` - Create: `src/main/java/com/cisd/tms/modules/auth/dto/UkeyLoginRequest.java` - Create: `src/main/java/com/cisd/tms/modules/auth/dto/UkeyLoginProof.java` - Create: `src/main/java/com/cisd/tms/modules/auth/dto/UkeyLoginRandomRequest.java` - Modify: `src/main/java/com/cisd/tms/modules/auth/dto/UkeyLoginRandomResponse.java` - Create: `src/main/java/com/cisd/tms/modules/auth/dto/CaptchaResponse.java` - Modify: `src/main/java/com/cisd/tms/modules/auth/dto/UkeyBindRequest.java` - Modify: `src/main/java/com/cisd/tms/modules/auth/dto/CurrentUserResponse.java` - Delete: `src/main/java/com/cisd/tms/modules/auth/dto/CompatPasswordLoginRequest.java` - Delete: `src/main/java/com/cisd/tms/modules/auth/dto/CompatUkeyLoginRequest.java` - Test: `src/test/java/com/cisd/tms/modules/auth/controller/AuthControllerTest.java` **Step 1: Write the failing test** Add controller-request binding tests covering: - `POST /api/v1/auth/password-login` - `POST /api/v1/auth/ukey-login/randoms` - `POST /api/v1/auth/ukey-login` - request validation failures for missing `roleCode`, missing captcha fields, and missing UKey proof fields **Step 2: Run test to verify it fails** Run: `mvn -q -Dtest=AuthControllerTest test` Expected: FAIL because controller methods and DTOs still use the old contract. **Step 3: Write minimal implementation** Introduce the standardized DTOs with field names: - `roleCode` - `captchaCode` - `captchaId` - `ukeyProofs` - proof fields `pubKey`, `uid`, `rid`, `serverRandom`, `issueSignature`, `loginPayload`, `loginSignature` Update `UkeyBindRequest` to include `slotNo`, `ukeySerial`, `pubKey`, `uid`, `rid`, `issuerSignature`. **Step 4: Run test to verify it passes** Run: `mvn -q -Dtest=AuthControllerTest test` Expected: PASS **Step 5: Commit** ```bash git add src/main/java/com/cisd/tms/modules/auth/dto/PasswordLoginRequest.java src/main/java/com/cisd/tms/modules/auth/dto/UkeyLoginRequest.java src/main/java/com/cisd/tms/modules/auth/dto/UkeyLoginProof.java src/main/java/com/cisd/tms/modules/auth/dto/UkeyLoginRandomRequest.java src/main/java/com/cisd/tms/modules/auth/dto/UkeyLoginRandomResponse.java src/main/java/com/cisd/tms/modules/auth/dto/CaptchaResponse.java src/main/java/com/cisd/tms/modules/auth/dto/UkeyBindRequest.java src/main/java/com/cisd/tms/modules/auth/dto/CurrentUserResponse.java src/test/java/com/cisd/tms/modules/auth/controller/AuthControllerTest.java git commit -m "refactor: standardize auth api dto contract" ``` ### Task 3: Extend persistence model for legacy UKey semantics **Files:** - Modify: `src/main/java/com/cisd/tms/modules/auth/entity/RoleUkeyBindingEntity.java` - Modify: `src/main/java/com/cisd/tms/modules/auth/entity/AuthSessionEntity.java` - Modify: `src/main/java/com/cisd/tms/modules/auth/mapper/RoleUkeyBindingMapper.java` - Modify: `src/main/java/com/cisd/tms/modules/auth/mapper/AuthSessionMapper.java` - Modify: `src/main/resources/mapper/auth/RoleUkeyBindingMapper.xml` - Modify: `src/main/resources/mapper/auth/AuthSessionMapper.xml` - Create: `src/main/resources/db/migration/V12__refactor_auth_login_model.sql` - Test: `src/test/java/com/cisd/tms/modules/auth/service/AuthServiceTest.java` **Step 1: Write the failing test** Add service-level tests asserting: - UKey binding records preserve `uid` and `rid` - sessions persist `authMethod` and `authLevel` **Step 2: Run test to verify it fails** Run: `mvn -q -Dtest=AuthServiceTest test` Expected: FAIL because entities and mappers do not yet expose the new fields. **Step 3: Write minimal implementation** Add: - `uid`, `rid` to `RoleUkeyBindingEntity` and mapper XML - `authMethod` to `AuthSessionEntity` and mapper XML - Flyway migration to add the new columns and seed/normalize existing auth rows if needed **Step 4: Run test to verify it passes** Run: `mvn -q -Dtest=AuthServiceTest test` Expected: PASS **Step 5: Commit** ```bash git add src/main/java/com/cisd/tms/modules/auth/entity/RoleUkeyBindingEntity.java src/main/java/com/cisd/tms/modules/auth/entity/AuthSessionEntity.java src/main/java/com/cisd/tms/modules/auth/mapper/RoleUkeyBindingMapper.java src/main/java/com/cisd/tms/modules/auth/mapper/AuthSessionMapper.java src/main/resources/mapper/auth/RoleUkeyBindingMapper.xml src/main/resources/mapper/auth/AuthSessionMapper.xml src/main/resources/db/migration/V12__refactor_auth_login_model.sql src/test/java/com/cisd/tms/modules/auth/service/AuthServiceTest.java git commit -m "refactor: persist normalized auth login model" ``` ### Task 4: Refactor AuthService into explicit password-login and UKey-login flows **Files:** - Modify: `src/main/java/com/cisd/tms/modules/auth/service/AuthService.java` - Modify: `src/main/java/com/cisd/tms/modules/auth/service/UkeyLoginRandomService.java` - Modify: `src/main/java/com/cisd/tms/modules/auth/service/InMemoryUkeyLoginRandomService.java` - Create: `src/main/java/com/cisd/tms/modules/auth/service/CaptchaService.java` - Create: `src/main/java/com/cisd/tms/modules/auth/service/InMemoryCaptchaService.java` - Modify: `src/test/java/com/cisd/tms/modules/auth/service/AuthServiceTest.java` **Step 1: Write the failing test** Add tests for: - password login returns `LIMITED` - UKey login returns `FULL` - wrong captcha fails password login - wrong UKey count fails UKey login - wrong auth level is stored in session if service logic is broken **Step 2: Run test to verify it fails** Run: `mvn -q -Dtest=AuthServiceTest test` Expected: FAIL because `AuthService` still uses the generic old login shape. **Step 3: Write minimal implementation** Refactor service methods to explicit operations: - `passwordLogin(PasswordLoginRequest request)` - `issueUkeyLoginRandoms(UkeyLoginRandomRequest request)` - `ukeyLogin(UkeyLoginRequest request)` - `issueCaptcha()` Preserve old business order: - password flow validates master key, captcha, password, failure count, and status - UKey flow validates count, role/rid combination, issuer signature, auth info, randoms, login signature, whitelist, master key, and role password **Step 4: Run test to verify it passes** Run: `mvn -q -Dtest=AuthServiceTest test` Expected: PASS **Step 5: Commit** ```bash git add src/main/java/com/cisd/tms/modules/auth/service/AuthService.java src/main/java/com/cisd/tms/modules/auth/service/UkeyLoginRandomService.java src/main/java/com/cisd/tms/modules/auth/service/InMemoryUkeyLoginRandomService.java src/main/java/com/cisd/tms/modules/auth/service/CaptchaService.java src/main/java/com/cisd/tms/modules/auth/service/InMemoryCaptchaService.java src/test/java/com/cisd/tms/modules/auth/service/AuthServiceTest.java git commit -m "refactor: split password and ukey auth flows" ``` ### Task 5: Refactor AuthAdminService around standardized role and UKey admin APIs **Files:** - Modify: `src/main/java/com/cisd/tms/modules/auth/service/AuthAdminService.java` - Modify: `src/main/java/com/cisd/tms/modules/auth/repository/RoleUkeyBindingRepository.java` - Modify: `src/main/java/com/cisd/tms/modules/auth/repository/impl/RoleUkeyBindingRepositoryImpl.java` - Modify: `src/test/java/com/cisd/tms/modules/auth/service/AuthAdminServiceTest.java` **Step 1: Write the failing test** Add tests covering: - `KEY_ADMIN + FULL` can enable another role - `KEY_ADMIN + FULL` can reset password - `KEY_ADMIN + FULL` can issue UKey binding sign - `KEY_ADMIN + FULL` can bind UKey with `uid/rid/issuerSignature` - `KEY_ADMIN + LIMITED` is rejected **Step 2: Run test to verify it fails** Run: `mvn -q -Dtest=AuthAdminServiceTest test` Expected: FAIL because service still reflects the old compat split. **Step 3: Write minimal implementation** Refactor admin methods so they accept: - `roleCode` - `slotNo` - `ukeySerial` - `pubKey` - `uid` - `rid` - `issuerSignature` Ensure slot validation follows role UKey counts and binding updates are overwrite-by-role-and-slot. **Step 4: Run test to verify it passes** Run: `mvn -q -Dtest=AuthAdminServiceTest test` Expected: PASS **Step 5: Commit** ```bash git add src/main/java/com/cisd/tms/modules/auth/service/AuthAdminService.java src/main/java/com/cisd/tms/modules/auth/repository/RoleUkeyBindingRepository.java src/main/java/com/cisd/tms/modules/auth/repository/impl/RoleUkeyBindingRepositoryImpl.java src/test/java/com/cisd/tms/modules/auth/service/AuthAdminServiceTest.java git commit -m "refactor: standardize auth admin role and ukey actions" ``` ### Task 6: Collapse controller layer to one standardized API surface **Files:** - Modify: `src/main/java/com/cisd/tms/modules/auth/controller/AuthController.java` - Create: `src/main/java/com/cisd/tms/modules/auth/controller/AuthAdminController.java` - Delete: `src/main/java/com/cisd/tms/modules/auth/controller/CompatAuthController.java` - Delete: `src/test/java/com/cisd/tms/modules/auth/controller/CompatAuthControllerTest.java` - Modify: `src/test/java/com/cisd/tms/modules/auth/controller/AuthControllerTest.java` **Step 1: Write the failing test** Add controller tests for: - `POST /api/v1/auth/password-login` - `POST /api/v1/auth/ukey-login/randoms` - `POST /api/v1/auth/ukey-login` - `POST /api/v1/auth/captcha` - `POST /api/v1/auth/roles/{roleCode}/enable` - `POST /api/v1/auth/roles/{roleCode}/reset-password` - `POST /api/v1/auth/roles/{roleCode}/ukeys/issue-sign` - `POST /api/v1/auth/roles/{roleCode}/ukeys/bind` **Step 2: Run test to verify it fails** Run: `mvn -q -Dtest=AuthControllerTest test` Expected: FAIL because the endpoints are still split across standard and compat controllers. **Step 3: Write minimal implementation** Keep only: - `AuthController` for session-facing endpoints - `AuthAdminController` for role/UKey admin endpoints Delete `CompatAuthController` and route all supported behavior through the new API paths. **Step 4: Run test to verify it passes** Run: `mvn -q -Dtest=AuthControllerTest test` Expected: PASS **Step 5: Commit** ```bash git add src/main/java/com/cisd/tms/modules/auth/controller/AuthController.java src/main/java/com/cisd/tms/modules/auth/controller/AuthAdminController.java src/test/java/com/cisd/tms/modules/auth/controller/AuthControllerTest.java git rm src/main/java/com/cisd/tms/modules/auth/controller/CompatAuthController.java src/test/java/com/cisd/tms/modules/auth/controller/CompatAuthControllerTest.java git commit -m "refactor: keep one standardized auth controller surface" ``` ### Task 7: Update internal authorization to use role plus auth level **Files:** - Modify: `src/main/java/com/cisd/tms/modules/auth/security/InternalAuthorizationInterceptor.java` - Modify: `src/main/java/com/cisd/tms/modules/auth/security/RequireRole.java` - Modify: `src/main/java/com/cisd/tms/modules/auth/security/RequireAuthLevel.java` - Modify: `src/test/java/com/cisd/tms/modules/auth/security/InternalAuthorizationInterceptorTest.java` **Step 1: Write the failing test** Add tests asserting: - a `LIMITED` session is denied for `FULL` endpoints - role-only mismatch is denied - `KEY_ADMIN + FULL` is accepted for admin endpoints **Step 2: Run test to verify it fails** Run: `mvn -q -Dtest=InternalAuthorizationInterceptorTest test` Expected: FAIL because endpoint requirements and session mapping still reflect the pre-refactor shape. **Step 3: Write minimal implementation** Make interceptor decisions solely from: - session `roleCode` - session `authLevel` Remove any remaining dependency on compat endpoint semantics. **Step 4: Run test to verify it passes** Run: `mvn -q -Dtest=InternalAuthorizationInterceptorTest test` Expected: PASS **Step 5: Commit** ```bash git add src/main/java/com/cisd/tms/modules/auth/security/InternalAuthorizationInterceptor.java src/main/java/com/cisd/tms/modules/auth/security/RequireRole.java src/main/java/com/cisd/tms/modules/auth/security/RequireAuthLevel.java src/test/java/com/cisd/tms/modules/auth/security/InternalAuthorizationInterceptorTest.java git commit -m "refactor: enforce auth by role and auth level" ``` ### Task 8: Remove obsolete compat code and refresh docs **Files:** - Delete: `src/main/java/com/cisd/tms/modules/auth/service/CompatAuthService.java` - Delete: `src/main/java/com/cisd/tms/modules/auth/dto/CompatPasswordLoginRequest.java` - Delete: `src/main/java/com/cisd/tms/modules/auth/dto/CompatUkeyLoginRequest.java` - Delete: `src/test/java/com/cisd/tms/modules/auth/service/CompatAuthServiceTest.java` - Modify: `docs/plans/2026-03-23-auth-role-ukey-design.md` - Modify: `docs/openapi/cisd-init.openapi.yaml` - Modify: `docs/openapi/cisd-init.openapi.json` - Test: `src/test/java/com/cisd/tms/modules/auth/controller/AuthControllerTest.java` **Step 1: Write the failing test** Add an assertion in controller-level tests or OpenAPI export verification that only the standardized endpoints remain documented. **Step 2: Run test to verify it fails** Run: `mvn -q -Dtest=AuthControllerTest test` Expected: FAIL because compat artifacts or docs are still present. **Step 3: Write minimal implementation** Remove obsolete compat classes and update documentation to describe: - four roles only - `LIMITED/FULL` - `password-login` and `ukey-login` standardized endpoints **Step 4: Run test to verify it passes** Run: `mvn -q -Dtest=AuthControllerTest test` Expected: PASS **Step 5: Commit** ```bash git rm src/main/java/com/cisd/tms/modules/auth/service/CompatAuthService.java src/main/java/com/cisd/tms/modules/auth/dto/CompatPasswordLoginRequest.java src/main/java/com/cisd/tms/modules/auth/dto/CompatUkeyLoginRequest.java src/test/java/com/cisd/tms/modules/auth/service/CompatAuthServiceTest.java git add docs/plans/2026-03-23-auth-role-ukey-design.md docs/openapi/cisd-init.openapi.yaml docs/openapi/cisd-init.openapi.json src/test/java/com/cisd/tms/modules/auth/controller/AuthControllerTest.java git commit -m "refactor: remove auth compat surface and refresh docs" ``` ### Task 9: Final verification **Files:** - Verify only **Step 1: Run focused auth test suite** Run: `mvn -q -Dtest=AuthControllerTest,AuthServiceTest,AuthAdminServiceTest,AuthDomainModelTest,InternalAuthorizationInterceptorTest test` Expected: PASS **Step 2: Run full auth package compile verification** Run: `mvn -q -DskipTests compile` Expected: PASS **Step 3: Review final behavior against design** Confirm: - only four roles remain - `password-login` issues `LIMITED` - `ukey-login` issues `FULL` - no compat controller remains - UKey binding preserves `slotNo/uid/rid/issuerSignature` **Step 4: Commit verification touch-ups if needed** ```bash git add . git commit -m "test: finalize auth refactor verification" ```