# 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
```
