refactor(users): rename Prisma User model to UserDirectoryEntry #230

Merged
julien merged 1 commits from fix/rename-user-to-user-directory-entry into main 2026-05-26 12:42:24 +02:00
Owner

Summary

Mechanical refactor only, prerequisite to ADR-0026 PR 1. Renames the existing Prisma User model (the ADR-0020 user-directory cache, oid PK, written by UserDirectoryService.recordSignIn) to UserDirectoryEntry. Frees the User name for the upcoming ADR-0026 model (UUID PK, FK to Person, lastSignInAt — different semantics).

Zero behavioural change. Same columns, same indexes, same constraints, same call sites — just a different identifier on the model and the table.

What lands

File Change
apps/portal-bff/prisma/schema.prisma model Usermodel UserDirectoryEntry. @@map("users")@@map("user_directory_entries"). Comment block extended to flag the upcoming distinction from ADR-0026's new User.
apps/portal-bff/prisma/migrations/20260526200000_rename_users_to_user_directory_entries/migration.sql New. ALTER TABLE "users" RENAME TO "user_directory_entries" + ALTER INDEX renames for the PK constraint and the two named indexes (Postgres doesn't auto-rename these on table rename).
apps/portal-bff/src/users/user-directory.service.ts Two renames: the TS input interface UserDirectoryEntryRecordSignInInput (the existing name was a misnomer — it's the input to recordSignIn, not the entry itself, and would collide with the Prisma-generated UserDirectoryEntry type after the model rename). The Prisma client ref this.prisma.user.upsertthis.prisma.userDirectoryEntry.upsert.
apps/portal-bff/src/users/user-directory.service.spec.ts Imports / mock setup / fixture type updated to track the two renames.
apps/portal-bff/src/admin/admin-users-reader.service.ts this.prisma.user.{count,findMany}this.prisma.userDirectoryEntry.{count,findMany}. Prisma.UserWhereInputPrisma.UserDirectoryEntryWhereInput. Doc comments mentioning public.users updated to public.user_directory_entries. The class name AdminUsersReader, the endpoint URL /api/admin/users, the DTO AdminUserDto, and the local interface UserRow are unchanged — these are SPA/HTTP-facing identifiers, where the URL semantics ("admin user list") still hold regardless of the backing table name.
apps/portal-bff/src/admin/admin-users-reader.service.spec.ts Mock setup updated to track the Prisma client field rename.

Why two renames in one file

apps/portal-bff/src/users/user-directory.service.ts had a TypeScript interface UserDirectoryEntry carrying the input shape of recordSignIn(entry: UserDirectoryEntry). After the Prisma model rename to UserDirectoryEntry, that name would clash with the Prisma-generated row type. The fix is to rename the TS interface to its proper role — RecordSignInInput — at the same time. Net effect: clearer naming on both sides (the call-input name now describes the call, the persisted-row type name now describes the row).

Recovery procedure (for anyone with the old migration applied locally)

The new migration 20260526200000_rename_users_to_user_directory_entries is a pure ALTER TABLE ... RENAME + index renames — Prisma's migrate dev runs it forward without prompting:

cd apps/portal-bff && pnpm exec prisma migrate dev
# Should report: "Applied migration `20260526200000_rename_users_to_user_directory_entries`"

No down -v needed — existing data carries over.

Test plan

  • node scripts/check-catalogue-drift.mjs — clean (4 / 24 / 7).
  • node --test scripts/check-catalogue-drift.spec.mjs — 22 tests passing.
  • pnpm exec prettier --check clean on the touched files.
  • Sweep grep — zero leftover model User, prisma.user., Prisma.UserWhereInput, interface UserDirectoryEntry, or public.users references anywhere under apps/portal-bff/src/ or apps/portal-bff/prisma/.
  • Locally: pnpm exec prisma migrate dev applies the rename migration cleanly; pnpm exec nx test portal-bff runs the updated specs green.
  • Review focus — the two-rename rationale in user-directory.service.ts, the migration's ALTER INDEX clauses (don't forget those — ALTER TABLE ... RENAME does NOT cascade to index names in Postgres), the unchanged class/URL/DTO/local-interface identifiers in admin-users-reader.service.ts.

Why ship as a separate PR

ADR-0026 PR 1's nominal scope is Person + User + UserScope + provisioner + drift gate + PrincipalBuilder — already ~15+ files touched. Folding the rename into that PR would mix mechanical refactor with new design. Splitting keeps both PRs reviewable for what they actually do.

What's next (post-merge)

ADR-0026 PR 1Person + new User + UserScope schema + PersonAndUserProvisioner wired into SessionEstablisher + Person.source catalogue + drift-gate extension + PrincipalBuilder populating Principal.user.{id, personId} from real rows. Now unblocked.

## Summary **Mechanical refactor only**, prerequisite to ADR-0026 PR 1. Renames the existing Prisma `User` model (the ADR-0020 user-directory cache, `oid` PK, written by `UserDirectoryService.recordSignIn`) to `UserDirectoryEntry`. Frees the `User` name for the upcoming ADR-0026 model (UUID PK, FK to `Person`, `lastSignInAt` — different semantics). Zero behavioural change. Same columns, same indexes, same constraints, same call sites — just a different identifier on the model and the table. ## What lands | File | Change | | --- | --- | | `apps/portal-bff/prisma/schema.prisma` | `model User` → `model UserDirectoryEntry`. `@@map("users")` → `@@map("user_directory_entries")`. Comment block extended to flag the upcoming distinction from ADR-0026's new `User`. | | `apps/portal-bff/prisma/migrations/20260526200000_rename_users_to_user_directory_entries/migration.sql` | **New**. `ALTER TABLE "users" RENAME TO "user_directory_entries"` + `ALTER INDEX` renames for the PK constraint and the two named indexes (Postgres doesn't auto-rename these on table rename). | | `apps/portal-bff/src/users/user-directory.service.ts` | Two renames: the **TS input interface** `UserDirectoryEntry` → `RecordSignInInput` (the existing name was a misnomer — it's the input to `recordSignIn`, not the entry itself, and would collide with the Prisma-generated `UserDirectoryEntry` type after the model rename). The **Prisma client ref** `this.prisma.user.upsert` → `this.prisma.userDirectoryEntry.upsert`. | | `apps/portal-bff/src/users/user-directory.service.spec.ts` | Imports / mock setup / fixture type updated to track the two renames. | | `apps/portal-bff/src/admin/admin-users-reader.service.ts` | `this.prisma.user.{count,findMany}` → `this.prisma.userDirectoryEntry.{count,findMany}`. `Prisma.UserWhereInput` → `Prisma.UserDirectoryEntryWhereInput`. Doc comments mentioning `public.users` updated to `public.user_directory_entries`. The class name `AdminUsersReader`, the endpoint URL `/api/admin/users`, the DTO `AdminUserDto`, and the local `interface UserRow` are unchanged — these are SPA/HTTP-facing identifiers, where the URL semantics ("admin user list") still hold regardless of the backing table name. | | `apps/portal-bff/src/admin/admin-users-reader.service.spec.ts` | Mock setup updated to track the Prisma client field rename. | ## Why two renames in one file `apps/portal-bff/src/users/user-directory.service.ts` had a TypeScript `interface UserDirectoryEntry` carrying the **input shape** of `recordSignIn(entry: UserDirectoryEntry)`. After the Prisma model rename to `UserDirectoryEntry`, that name would clash with the Prisma-generated row type. The fix is to rename the TS interface to its proper role — `RecordSignInInput` — at the same time. Net effect: clearer naming on both sides (the call-input name now describes the call, the persisted-row type name now describes the row). ## Recovery procedure (for anyone with the old migration applied locally) The new migration `20260526200000_rename_users_to_user_directory_entries` is a pure `ALTER TABLE ... RENAME` + index renames — Prisma's `migrate dev` runs it forward without prompting: ```bash cd apps/portal-bff && pnpm exec prisma migrate dev # Should report: "Applied migration `20260526200000_rename_users_to_user_directory_entries`" ``` No `down -v` needed — existing data carries over. ## Test plan - [x] `node scripts/check-catalogue-drift.mjs` — clean (4 / 24 / 7). - [x] `node --test scripts/check-catalogue-drift.spec.mjs` — 22 tests passing. - [x] `pnpm exec prettier --check` clean on the touched files. - [x] Sweep grep — zero leftover `model User`, `prisma.user.`, `Prisma.UserWhereInput`, `interface UserDirectoryEntry`, or `public.users` references anywhere under `apps/portal-bff/src/` or `apps/portal-bff/prisma/`. - [ ] **Locally**: `pnpm exec prisma migrate dev` applies the rename migration cleanly; `pnpm exec nx test portal-bff` runs the updated specs green. - [ ] **Review focus** — the two-rename rationale in `user-directory.service.ts`, the migration's `ALTER INDEX` clauses (don't forget those — `ALTER TABLE ... RENAME` does NOT cascade to index names in Postgres), the unchanged class/URL/DTO/local-interface identifiers in `admin-users-reader.service.ts`. ## Why ship as a separate PR ADR-0026 PR 1's nominal scope is `Person` + `User` + `UserScope` + provisioner + drift gate + PrincipalBuilder — already ~15+ files touched. Folding the rename into that PR would mix mechanical refactor with new design. Splitting keeps both PRs reviewable for what they actually do. ## What's next (post-merge) **ADR-0026 PR 1** — `Person` + new `User` + `UserScope` schema + `PersonAndUserProvisioner` wired into `SessionEstablisher` + `Person.source` catalogue + drift-gate extension + `PrincipalBuilder` populating `Principal.user.{id, personId}` from real rows. Now unblocked.
julien added 1 commit 2026-05-26 12:39:05 +02:00
refactor(users): rename Prisma User model to UserDirectoryEntry
CI / scan (pull_request) Successful in 3m21s
CI / commits (pull_request) Successful in 4m3s
CI / check (pull_request) Failing after 4m22s
CI / a11y (pull_request) Successful in 3m33s
CI / perf (pull_request) Successful in 8m0s
8aec83f82e
Mechanical refactor, prerequisite to ADR-0026 PR 1. Frees the
`User` name for the upcoming ADR-0026 model (UUID PK + FK to
Person + lastSignInAt), which has materially different semantics
from the ADR-0020 user-directory cache.

Zero behavioural change. Same columns, same indexes, same
constraints, same call sites - just a different identifier on the
model, the table, and the corresponding Prisma client field.

Two renames in user-directory.service.ts: the Prisma model rename
collided with an existing TS interface also called
UserDirectoryEntry (which was actually the input shape of
recordSignIn). The interface gets renamed to RecordSignInInput at
the same time, which is its correct semantic name. Net effect:
clearer on both sides.

Postgres ALTER TABLE RENAME does NOT cascade to PK constraint /
index names; the migration explicitly ALTER INDEXes the three
named indexes (pkey + last_seen_at + username).

The class name AdminUsersReader, the endpoint URL /api/admin/users,
the DTO AdminUserDto and the local interface UserRow are
unchanged - these are SPA/HTTP-facing identifiers where the
"admin user list" URL semantics hold regardless of the backing
table name.
julien merged commit b84b58068a into main 2026-05-26 12:42:24 +02:00
julien deleted branch fix/rename-user-to-user-directory-entry 2026-05-26 12:42:27 +02:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: julien/apf_portal#230