Edit Project dialog's Owner/Project Manager field is now a dropdown
of real users on the system instead of a text box — so the value is
a FK to a real User row rather than a hand-typed string that drifts
from the roster.
Schema:
- Project.requestorUserId (nullable FK → User) + relation
"ProjectOwner" on both sides. Migration 20260425000000_project_owner_fk.
- Existing freeform `requestor` column stays put. It's now the
FALLBACK for ingest-sourced rows where the upstream Owner name
doesn't match a user on the system yet; the UI prefers the linked
user's display name when one exists.
Plumbing:
- createProjectSchema accepts requestorUserId.
- project-service listProjects + getProject both include
requestorUser { id, name, email } so the UI doesn't need a second
round-trip.
UI:
- ProjectFormDialog swaps the Input for a Select populated by
useUsers(). "— Unassigned —" at the top clears the link. When a
project has a legacy freeform requestor and no linked user, the
dialog shows it as a hint ("Currently unlinked (from intake):
<name> — pick a user from the list to replace") so admins can
see what came in from the XLSX/webhook and bind it.
- Project detail view + list view both prefer
requestorUser.name ?? requestorUser.email ?? requestor for the
"Owner" column. Sort key on the list uses the same chain.
|
||
|---|---|---|
| .. | ||
| migrations | ||
| schema.prisma | ||
| seed-dow.ts | ||
| seed-tracker-data.ts | ||
| seed.ts | ||