feat(teams): add Team entity foundation (Slice 1/2) #4

Closed
aferrer wants to merge 0 commits from feature/add-teams-slice-1 into feature/add-teams
Owner

Summary

Adds the Team entity and the management tab on /people without touching the existing Person.department / PersonDepartment enum. This is Slice 1 of 2 in the add-teams chained PR. Slice 2 will cut over Person to use Person.teamId and drop the enum.

What's in

  • Team Prisma model (id, name, createdAt, updatedAt) + additive Person.teamId FK column.
  • Migration that creates the Team table, adds a case-insensitive unique index on lower("name"), and adds the Person.teamId column. Does not drop the PersonDepartment enum or Person.department column.
  • Team Zod schemas (src/schemas/team.schema.ts) with trim().min(1).max(80) validation.
  • TeamService (findAll, findById, findByNameCaseInsensitive, create, update, delete — hard delete).
  • TeamUseCases (list/create/update/delete) with preflight uniqueness checks and P2002 mapping.
  • Server Actions createTeamAction, updateTeamAction, deleteTeamAction, listTeamsAction (ADMIN-gated for write; list open to any authenticated user for the picker).
  • Tab UI on /people?tab=teams with TeamsTab, TeamListTable, TeamCreateForm, TeamEditForm components.
  • i18n keys under inventory.teams.* in both en.ts and es.ts.
  • Unit tests for the schema and integration tests for the use-cases.

What's out (Slice 2)

  • Replacing Person.department with Person.teamId in person forms, list cells, detail views, and person use-cases.
  • Removing the PersonDepartment enum and the Person.department column.
  • Removing the inventory.people.departments i18n keys.
  • Updating person-related tests, e2e, and the import flow.

Hard delete decision

Team uses hard delete (no deletedAt). FK onDelete: SetNull on Person.teamId handles the cascade automatically. If a team is deleted, all linked persons are automatically unassigned.

PR chain

  • Tracker: feature/add-teams (this PR's base)
  • This PR: feature/add-teams-slice-1
  • Next PR (Slice 2): will target feature/add-teams-slice-1

Verification

  • bun run test:unit
  • bun run test:integration
  • bunx tsc --noEmit
  • bunx prisma validate
  • bunx biome check .

Diff: ~1,214 insertions, 1 deletion across 22 files.

Related

  • Proposal: openspec/changes/add-teams/proposal.md
  • Specs: openspec/changes/add-teams/specs/team-management.md, openspec/changes/add-teams/specs/person-team.md
  • Design: openspec/changes/add-teams/design.md
  • Tasks: openspec/changes/add-teams/tasks.md
## Summary Adds the `Team` entity and the management tab on `/people` without touching the existing `Person.department` / `PersonDepartment` enum. This is **Slice 1 of 2** in the `add-teams` chained PR. Slice 2 will cut over Person to use `Person.teamId` and drop the enum. ## What's in - `Team` Prisma model (id, name, createdAt, updatedAt) + additive `Person.teamId` FK column. - Migration that creates the `Team` table, adds a case-insensitive unique index on `lower("name")`, and adds the `Person.teamId` column. Does **not** drop the `PersonDepartment` enum or `Person.department` column. - Team Zod schemas (`src/schemas/team.schema.ts`) with `trim().min(1).max(80)` validation. - `TeamService` (findAll, findById, findByNameCaseInsensitive, create, update, delete — hard delete). - `TeamUseCases` (list/create/update/delete) with preflight uniqueness checks and `P2002` mapping. - Server Actions `createTeamAction`, `updateTeamAction`, `deleteTeamAction`, `listTeamsAction` (ADMIN-gated for write; list open to any authenticated user for the picker). - Tab UI on `/people?tab=teams` with `TeamsTab`, `TeamListTable`, `TeamCreateForm`, `TeamEditForm` components. - i18n keys under `inventory.teams.*` in both `en.ts` and `es.ts`. - Unit tests for the schema and integration tests for the use-cases. ## What's out (Slice 2) - Replacing `Person.department` with `Person.teamId` in person forms, list cells, detail views, and person use-cases. - Removing the `PersonDepartment` enum and the `Person.department` column. - Removing the `inventory.people.departments` i18n keys. - Updating person-related tests, e2e, and the import flow. ## Hard delete decision Team uses **hard delete** (no `deletedAt`). FK `onDelete: SetNull` on `Person.teamId` handles the cascade automatically. If a team is deleted, all linked persons are automatically unassigned. ## PR chain - Tracker: `feature/add-teams` (this PR's base) - This PR: `feature/add-teams-slice-1` - Next PR (Slice 2): will target `feature/add-teams-slice-1` ## Verification - ✅ `bun run test:unit` - ✅ `bun run test:integration` - ✅ `bunx tsc --noEmit` - ✅ `bunx prisma validate` - ✅ `bunx biome check .` Diff: ~1,214 insertions, 1 deletion across 22 files. ## Related - Proposal: `openspec/changes/add-teams/proposal.md` - Specs: `openspec/changes/add-teams/specs/team-management.md`, `openspec/changes/add-teams/specs/person-team.md` - Design: `openspec/changes/add-teams/design.md` - Tasks: `openspec/changes/add-teams/tasks.md`
aferrer closed this pull request 2026-06-26 00:29:01 +00:00

Pull request closed

Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: aferrer/stock-manager#4