From 443ed2281ccc547f4a922db394cacdd26710a4b2 Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Sat, 28 Feb 2026 11:19:51 -0600 Subject: [PATCH] feat(api): add MS21 user fields for admin, local auth, and invitations Co-Authored-By: Claude Opus 4.6 --- apps/api/prisma/schema.prisma | 8 ++++++++ .../settings/workspaces/[id]/page.tsx | 18 ++++++++++++++++++ .../workspaces/[id]/teams/[teamId]/page.tsx | 12 ++++++++++++ .../components/workspace/MemberList.test.tsx | 12 ++++++++++++ apps/web/src/lib/api/teams.ts | 12 ++++++++++++ packages/shared/src/types/database.types.ts | 6 ++++++ 6 files changed, 68 insertions(+) diff --git a/apps/api/prisma/schema.prisma b/apps/api/prisma/schema.prisma index 35d474b..b63af21 100644 --- a/apps/api/prisma/schema.prisma +++ b/apps/api/prisma/schema.prisma @@ -227,6 +227,14 @@ model User { createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz + // MS21: Admin, local auth, and invitation fields + deactivatedAt DateTime? @map("deactivated_at") @db.Timestamptz + isLocalAuth Boolean @default(false) @map("is_local_auth") + passwordHash String? @map("password_hash") + invitedBy String? @map("invited_by") @db.Uuid + invitationToken String? @unique @map("invitation_token") + invitedAt DateTime? @map("invited_at") @db.Timestamptz + // Relations ownedWorkspaces Workspace[] @relation("WorkspaceOwner") workspaceMemberships WorkspaceMember[] diff --git a/apps/web/src/app/(authenticated)/settings/workspaces/[id]/page.tsx b/apps/web/src/app/(authenticated)/settings/workspaces/[id]/page.tsx index a6b78ef..79dcca8 100644 --- a/apps/web/src/app/(authenticated)/settings/workspaces/[id]/page.tsx +++ b/apps/web/src/app/(authenticated)/settings/workspaces/[id]/page.tsx @@ -39,6 +39,12 @@ const mockMembers: WorkspaceMemberWithUser[] = [ image: null, authProviderId: null, preferences: {}, + deactivatedAt: null, + isLocalAuth: false, + passwordHash: null, + invitedBy: null, + invitationToken: null, + invitedAt: null, createdAt: new Date("2024-01-15"), updatedAt: new Date("2024-01-15"), }, @@ -56,6 +62,12 @@ const mockMembers: WorkspaceMemberWithUser[] = [ image: null, authProviderId: null, preferences: {}, + deactivatedAt: null, + isLocalAuth: false, + passwordHash: null, + invitedBy: null, + invitationToken: null, + invitedAt: null, createdAt: new Date("2024-01-16"), updatedAt: new Date("2024-01-16"), }, @@ -73,6 +85,12 @@ const mockMembers: WorkspaceMemberWithUser[] = [ image: null, authProviderId: null, preferences: {}, + deactivatedAt: null, + isLocalAuth: false, + passwordHash: null, + invitedBy: null, + invitationToken: null, + invitedAt: null, createdAt: new Date("2024-01-17"), updatedAt: new Date("2024-01-17"), }, diff --git a/apps/web/src/app/settings/workspaces/[id]/teams/[teamId]/page.tsx b/apps/web/src/app/settings/workspaces/[id]/teams/[teamId]/page.tsx index 564d797..e0c1af9 100644 --- a/apps/web/src/app/settings/workspaces/[id]/teams/[teamId]/page.tsx +++ b/apps/web/src/app/settings/workspaces/[id]/teams/[teamId]/page.tsx @@ -21,6 +21,12 @@ const mockAvailableUsers: User[] = [ image: null, authProviderId: null, preferences: {}, + deactivatedAt: null, + isLocalAuth: false, + passwordHash: null, + invitedBy: null, + invitationToken: null, + invitedAt: null, createdAt: new Date("2026-01-17"), updatedAt: new Date("2026-01-17"), }, @@ -32,6 +38,12 @@ const mockAvailableUsers: User[] = [ image: null, authProviderId: null, preferences: {}, + deactivatedAt: null, + isLocalAuth: false, + passwordHash: null, + invitedBy: null, + invitationToken: null, + invitedAt: null, createdAt: new Date("2026-01-18"), updatedAt: new Date("2026-01-18"), }, diff --git a/apps/web/src/components/workspace/MemberList.test.tsx b/apps/web/src/components/workspace/MemberList.test.tsx index cb2fe8b..98071d7 100644 --- a/apps/web/src/components/workspace/MemberList.test.tsx +++ b/apps/web/src/components/workspace/MemberList.test.tsx @@ -20,6 +20,12 @@ const makeMember = ( image: null, authProviderId: `auth-${overrides.userId}`, preferences: {}, + deactivatedAt: null, + isLocalAuth: false, + passwordHash: null, + invitedBy: null, + invitationToken: null, + invitedAt: null, createdAt: new Date("2025-01-01"), updatedAt: new Date("2025-01-01"), }, @@ -62,6 +68,12 @@ describe("MemberList", (): void => { image: null, authProviderId: "auth-2", preferences: {}, + deactivatedAt: null, + isLocalAuth: false, + passwordHash: null, + invitedBy: null, + invitationToken: null, + invitedAt: null, createdAt: new Date("2025-01-01"), updatedAt: new Date("2025-01-01"), }, diff --git a/apps/web/src/lib/api/teams.ts b/apps/web/src/lib/api/teams.ts index f756f44..18e4dc8 100644 --- a/apps/web/src/lib/api/teams.ts +++ b/apps/web/src/lib/api/teams.ts @@ -178,6 +178,12 @@ export const mockTeamWithMembers: TeamWithMembers = { image: null, authProviderId: null, preferences: {}, + deactivatedAt: null, + isLocalAuth: false, + passwordHash: null, + invitedBy: null, + invitationToken: null, + invitedAt: null, createdAt: new Date("2026-01-15"), updatedAt: new Date("2026-01-15"), }, @@ -195,6 +201,12 @@ export const mockTeamWithMembers: TeamWithMembers = { image: null, authProviderId: null, preferences: {}, + deactivatedAt: null, + isLocalAuth: false, + passwordHash: null, + invitedBy: null, + invitationToken: null, + invitedAt: null, createdAt: new Date("2026-01-16"), updatedAt: new Date("2026-01-16"), }, diff --git a/packages/shared/src/types/database.types.ts b/packages/shared/src/types/database.types.ts index dd76bfc..4906232 100644 --- a/packages/shared/src/types/database.types.ts +++ b/packages/shared/src/types/database.types.ts @@ -27,6 +27,12 @@ export interface User extends BaseEntity { image: string | null; authProviderId: string | null; preferences: Record; + deactivatedAt: Date | null; + isLocalAuth: boolean; + passwordHash: string | null; + invitedBy: string | null; + invitationToken: string | null; + invitedAt: Date | null; } /**