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