Commit Graph

2 Commits (5865aafe06fb505c96ab2702a1cb5607b044fe12)

Author SHA1 Message Date
Thomas Joise 5865aafe06 fix(employees): purge sessions on password reset; reject empty patches and duplicate emails cleanly
Review findings on the Phase 1-2 employee slice:

- setEmployeePassword now deletes the employee's sessions in the same
  transaction — resetting a suspected-compromised password must not leave
  the attacker's existing 14-day bearer token valid (deactivateEmployee
  already did this; the reset path is the natural lockout action).
- updateEmployee throws 'Nothing to update' when the patch resolves to
  zero recognized fields, instead of returning 200 and writing a no-op
  before==after audit row; PATCH /employees/:id with {} or wrongly-typed
  fields now 400s.
- createEmployee pre-checks UNIQUE(email) inside the transaction and
  throws 'Email already in use' instead of surfacing the raw
  engine-specific 'UNIQUE constraint failed: staff_user.email' text
  (would differ on Postgres, the locked production engine — D15).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
5 days ago
Thomas Joise d4388c4f63 feat(employees): management surface — /employees API routes + owner-only Employees page
Phase 2 of the quote-to-close funnel slice. Six /employees routes in
apps/hq/src/api.ts (GET requireAuth for the picker; POST/PATCH/deactivate/
reactivate/password owner-only, acting as the signed-in user); Employees
page (table + add/edit/reset-password forms, email immutable on edit,
count shown, no truncation); owner-only nav item beside Document Template;
typed client fns in hq-web api.ts. 6 new route tests (192 total).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
5 days ago