Files
alla-tms/docs/sprint-6-12-employee-ownership-final-migration-review.md
2026-07-16 09:53:14 +07:00

197 lines
7.2 KiB
Markdown

# Sprint 6.12 Employee Ownership Final Migration Review
## 1. Summary
Sprint 6.12 completes the remaining runtime migration from user-owned training data to employee-owned training data in the main HRD paths.
Primary outcomes:
- Employee Directory now reads employee master data from `employees`.
- Dashboard overview aggregates training ownership from `training_records.employee_id`.
- Reports aggregate from `employees` and `training_records.employee_id`.
- Employee target resolution prefers `employee_training_targets.employee_id` and falls back to policy.
- Compatibility paths for login and legacy references remain intact.
## 2. Files Changed
Schema and migration:
- `src/db/schema.ts`
- `drizzle/0010_romantic_marauders.sql`
- `drizzle/meta/0010_snapshot.json`
- `drizzle/meta/_journal.json`
Employee identity and import:
- `src/features/employees/server/employee-identity-linking.ts`
- `src/features/employees/server/employee-data.ts`
- `src/app/api/import-employees/route.ts`
- `src/app/api/employees/route.ts`
Training records and ownership:
- `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`
Employee directory:
- `src/features/employee-directory/server/employee-directory-data.ts`
- `src/features/employee-directory/components/employee-directory-listing.tsx`
- `src/features/employee-directory/components/employee-directory-table.tsx`
- `src/features/employee-directory/components/employee-directory-columns.tsx`
- `src/features/employee-directory/components/employee-directory-action-menu.tsx`
- `src/features/employee-directory/components/employee-directory-detail-page.tsx`
Overview and reports:
- `src/features/overview/server/overview-data.ts`
- `src/features/reports/server/report-data.ts`
- `src/features/reports/api/types.ts`
- `src/features/training-matrix/server/training-matrix-data.ts`
- `src/features/training-matrix/api/types.ts`
Training target resolution:
- `src/features/training-policy/server/employee-training-target-data.ts`
## 3. Employee Directory Data Source Validation
Implemented:
- List page now fetches from `employeesQueryOptions(...)`, not `usersQueryOptions(...)`.
- Table row shape now uses `Employee` contracts from the employee module.
- Row action routes now use `employeeId`.
- Detail page already resolves primary data from `employees`.
- Training summary in detail page uses `training_records.employee_id = employees.id`.
Validated behavior:
- Imported employees without linked user accounts remain visible in Employee Directory.
- Department and position display come from employee relations.
- Employee code and display fields come from employee-owned data, not auth-owned user data.
## 4. Overview Migration
Updated `src/features/overview/server/overview-data.ts` to:
- resolve self scope from `user_employee_maps` through `getEmployeeIdsForUser(...)`
- resolve the primary self employee through `getPrimaryEmployeeIdForUser(...)`
- use `employees` as the employee source for admin dashboards
- use `training_records.employee_id` for all yearly aggregates
- use employee-owned target resolution through `getResolvedTrainingTargetForEmployee(...)`
- use employee-owned target maps through `getResolvedTrainingTargetsForEmployees(...)`
Result:
- employee cards now represent the mapped employee record
- HRD cards, charts, rankings, and pending counts now use employee ownership consistently
## 5. Reports Migration
Updated `src/features/reports/server/report-data.ts` to:
- scope employees through `employees` instead of membership/user joins
- aggregate transcript rows from `employees + training_records.employee_id`
- count department employees from `employees`
- aggregate annual summary from employee-owned training records
- calculate training matrix from `employees`, `training_matrices`, and `training_records.employee_id`
- keep PDF and Excel export behavior working on the migrated datasets
Also updated report API types so report row ids now use employee ids as numbers.
## 6. Target Resolution Changes
Current target priority:
1. `employee_training_targets.employee_id`
2. `training_policies`
3. default zero-value fallback if no policy exists
Compatibility retained:
- user-based target resolution still exists only for legacy callers and fallback compatibility
- new migrated paths call employee-first target resolvers
## 7. Remaining Legacy Dependencies
Still required now:
- `training_records.user_id`
- retained for compatibility, notifications, and staged migration safety
- `employee_training_targets.user_id`
- retained for compatibility with legacy target readers/import history
- `users.employee_id`
- retained as fallback when no `user_employee_maps` row exists
- `users.employee_code`
- retained for compatibility and historical link recovery
Can be migrated later:
- legacy user-based target resolver branches in `employee-training-target-data.ts`
- compatibility updates in `employee-identity-linking.ts` that still backfill `trainingRecords.userId` and `employeeTrainingTargets.userId`
- user-centric fields in the users feature that still surface employee identity for admin maintenance
Safe candidates for future cleanup after validation period:
- direct runtime reads that rely on `training_records.user_id` for ownership semantics
- fallback reads from `users.employee_id` once all active accounts have `user_employee_maps`
- fallback reads from `users.employee_code` once mapping stability is confirmed
## 8. Regression Checklist
Code-level verification completed:
- `npx tsc --noEmit`
Expected runtime validation checklist:
- Employee login
- Employee dashboard
- HRD dashboard
- Employee Directory list
- Employee Directory detail
- Employee imported without user appears in Employee Directory
- Employee transcript
- Department summary
- Annual summary
- Training matrix
- Training record create/edit
- HRD review
- Employee import
- Employee target import
## 9. Risks
- Existing databases require the new migration before the new ownership fields and map table are fully available.
- Some compatibility code still writes both employee-owned and user-owned references; that is intentional for this sprint, but it increases temporary complexity.
- If older rows lack employee linkage, self-scoped dashboards and reports will return empty data until mapping is backfilled.
## 10. Recommendation Before Sprint 7.2
- Run the new Drizzle migration in every active environment.
- Backfill and verify `user_employee_maps` coverage for all active employee users.
- Run UAT on dashboard, directory, reports, training record create/review, and import flows using real migrated data.
- Keep legacy user-owned columns for one more validation cycle, then schedule a dedicated cleanup sprint.
## Migration Commands
Run the pending migration:
```bash
npm run migrate
```
Optional validation:
```bash
npx tsc --noEmit
```