Files
alla-tms/docs/sprint-6-11-identity-employee-cleanup-review.md
2026-07-16 09:53:14 +07:00

5.0 KiB

Sprint 6.11 Identity / Employee Cleanup Review

Summary

This pass moves the system closer to the target architecture where:

  • users is login identity
  • employees is employee master
  • training ownership is based on employeeId
  • user actions remain tracked separately

The work completed in this pass focuses on the highest-risk operational paths first:

  • schema support for user-to-employee mapping
  • stopping employee import from auto-creating users
  • employee-owned training records
  • employee-based employee directory
  • employee-based training matrix compliance

Migration Changes

Migration file:

  • drizzle/0010_romantic_marauders.sql

Changes included:

  • create user_employee_maps
  • make training_records.user_id nullable
  • make employee_training_targets.user_id nullable
  • add training_records.submitted_by_user_id
  • add training_records.reviewed_by_user_id
  • add unique index employee_training_targets_org_employee_year_idx
  • backfill user_employee_maps from existing users.employee_id
  • backfill submitted_by_user_id from created_by
  • backfill reviewed_by_user_id from reviewed_by

Code Changes

Identity / Mapping

  • src/db/schema.ts
  • src/features/employees/server/employee-identity-linking.ts

Added:

  • user_employee_maps
  • helper to resolve employee ids for a user
  • helper to maintain mapping during import or login linking

Employee Import

  • src/app/api/import-employees/route.ts

Changed behavior:

  • import upserts into employees
  • import upserts employee_training_targets by employeeId
  • import links existing users when employee code matches
  • import no longer auto-creates login users

Employees API

  • src/app/api/employees/route.ts
  • src/features/employees/server/employee-data.ts

Changed behavior:

  • employees API is active again
  • mode=options returns active employee options for HRD workflows

Training Records

  • src/features/training-records/api/types.ts
  • src/features/training-records/api/service.ts
  • src/features/training-records/schemas/training-record.ts
  • src/features/training-records/components/training-record-form.tsx
  • src/features/training-records/components/training-record-view-page.tsx
  • src/features/training-records/server/training-record-data.ts
  • src/app/api/training-records/route.ts
  • src/app/api/training-records/[id]/route.ts
  • src/app/api/training-records/[id]/review/route.ts
  • src/app/dashboard/training-records/[trainingRecordId]/page.tsx

Changed behavior:

  • training record create/update now uses employeeId as owner
  • submittedByUserId is written on create
  • reviewedByUserId is written on review
  • employee self-scope uses mapped employee ids
  • HRD employee selector now reads from employees

Employee Directory

  • src/features/employee-directory/server/employee-directory-data.ts
  • src/features/employee-directory/components/employee-directory-detail-page.tsx

Changed behavior:

  • directory detail reads from employees
  • training summary and transcript use training_records.employee_id

Training Targets

  • src/features/training-policy/server/employee-training-target-data.ts

Changed behavior:

  • added employee-based target resolution
  • user-based target resolution now falls through employee mapping

Training Matrix

  • src/features/training-matrix/server/training-matrix-data.ts

Changed behavior:

  • compliance calculation now uses employees
  • approved-course ownership now uses training_records.employee_id

Regression Checklist

  1. Run npm run migrate
  2. Sign in with an existing credentials user
  3. Import employee Excel with no pre-existing user account
  4. Verify employee rows are created/updated in employees
  5. Verify no new users row is auto-created from import
  6. Verify employee_training_targets rows are created using employee_id
  7. Verify existing users with matching employee code are linked in user_employee_maps
  8. As employee user with a linked employee profile, create a training record
  9. Verify training_records.employee_id is set
  10. Verify training_records.submitted_by_user_id is set
  11. Review a pending record as HRD
  12. Verify training_records.reviewed_by_user_id is set
  13. Open employee directory detail and verify totals still load
  14. Open training matrix compliance and verify rows still load

Verification

Verified in this pass:

  • npx tsc --noEmit

Known Remaining Work

This pass does not fully migrate every aggregation path yet.

Still recommended for the next pass:

  • move overview fully to employees + training_records.employee_id
  • move reports fully to employees + training_records.employee_id
  • reduce remaining dependency on users.employeeCode as compatibility fallback
  • add Keycloak runtime mapping using user_employee_maps

Risk Notes

  • some runtime paths still keep compatibility writes to legacy columns
  • users.employeeId still exists as fallback and compatibility support
  • notifications still depend on login users, so employees without user accounts will not receive login-bound notifications