# User-Employee Domain Inventory

This inventory records the current implementation state for Phase 1 remediation. It is intentionally descriptive, not aspirational.

## Boundary Summary

- `users` owns authentication, session identity, active organization, permissions, notifications, and audit actors.
- `employees` owns HR master data, employee profile, training ownership, matrix targeting, and compliance subject scope.
- The current codebase still uses two linkage seams: `users.employeeId` and `user_employee_maps`.
- The effective relationship is `User 0..1 <-> 0..1 Employee`, but reconciliation is still needed.

## Inventory

| Domain | User Usage | Employee Usage | Current FK/Join | Data Owner | Issue | Required Change |
|---|---|---|---|---|---|---|
| Authentication and session | `src/auth.ts`, `src/lib/auth/session.ts`, `src/types/next-auth.d.ts` | session enrichment attaches `employeeId` | `users.employeeId`, `syncUserEmployeeLink()` | `users` for auth, `employees` for linked profile | login flow implicitly syncs employee linkage | document and later reconcile the linking source |
| User-employee linking | `users.employeeId`, `user_employee_maps.userId` | `user_employee_maps.employeeId` | direct FK plus mapping table | compatibility seam | dual source of truth risk | adopt a canonical linking strategy and enforce it with checks |
| Training records | `userId`, `submittedByUserId`, `reviewedByUserId`, `createdBy` | `employeeId` | mixed FK usage in `training_records` | split by intent | actor/owner split exists but is undocumented | preserve and codify the split |
| Training targets and policy | `employee_training_targets.userId`, creator/updater user fields | `employee_training_targets.employeeId` | unique indexes on user/year and employee/year | split by intent | two ownership axes coexist | document `employees` as canonical owner for runtime training scope |
| Training matrix | session actor only | compliance joins `employees` and `trainingRecords.employeeId` | `training-matrix-data.ts` joins | `employees` | feature relied on employee scope but page guard was missing | keep employee ownership and enforce page/API guard |
| Reports | current session user is actor | datasets scoped by employee joins | `report-data.ts` joins `employees` and `training_records` | `employees` for subject, `users` for actor | docs previously overstated employees as legacy-only | update architecture docs to reflect transitional reality |
| Overview | current session user defines access scope | KPIs and self-scope resolve through employee IDs | `overview-data.ts` employee joins | mixed | non-employee user handling is implicit | add explicit non-employee handling rules |
| Employee directory | optional user linking | employee is the primary record | `employees.id`, employee target APIs | `employees` | linkage lifecycle is not formally documented | keep employee-first workflow and document it |
| Audit and permission management | actor and target use `users` | none | `audit_logs`, `permission_audit_logs` | `users` | ownership is correct but undocumented as a rule | codify actor convention |
| Notifications | recipient uses `users.userId` | none | `notifications.userId` | `users` | no issue | keep user-only notification model |

## Confirmed Findings

- `src/db/schema.ts` still contains both `users.employeeId` and `user_employee_maps`.
- Training ownership is still employee-centric in `training-records`, `training-policy`, `training-matrix`, `reports`, and `overview`.
- Session enrichment still synchronizes user-to-employee linkage during login.
- The original audit note about `/dashboard/training-matrix/new` is outdated in the current repo state because `src/app/dashboard/training-matrix/[matrixId]/page.tsx` resolves the `new` segment dynamically.

## Immediate Remediation Direction

1. Keep actor fields on `users` and owner fields on `employees`.
2. Standardize page guards on employee-scoped management routes.
3. Treat `users.employeeId` and `user_employee_maps` as a transition seam that must be reconciled, not expanded.
4. Add automated route and architecture checks before deeper schema migration work.
