commit
This commit is contained in:
196
docs/sprint-6-12-employee-ownership-final-migration-review.md
Normal file
196
docs/sprint-6-12-employee-ownership-final-migration-review.md
Normal file
@@ -0,0 +1,196 @@
|
||||
# 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
|
||||
```
|
||||
Reference in New Issue
Block a user