diff --git a/hub/prisma/migrations/20260714120000_drop_legacy_platform_role_assignment/migration.sql b/hub/prisma/migrations/20260714120000_drop_legacy_platform_role_assignment/migration.sql new file mode 100644 index 0000000..ed23cb6 --- /dev/null +++ b/hub/prisma/migrations/20260714120000_drop_legacy_platform_role_assignment/migration.sql @@ -0,0 +1,20 @@ +-- ADR-0023 rejected the legacy `PlatformRoleAssignment` / `PlatformRole`{ADMIN,TEACHER} +-- model: the platform administration control plane is a separate identity/session/ +-- audit surface (see `Spec.System.PlatformAdministration`), intentionally not built +-- in alpha (ADR-0025, `hub/deploy/README.md`). The legacy table has no runtime +-- reader — no guard, route, or service queries it for an authorization decision — +-- and ADR-0023 requires it to be migrated/replaced before the platform panel ships. +-- Drop the table, the `User.platformRoles` relation, and the enum. + +-- DropForeignKey +ALTER TABLE "PlatformRoleAssignment" DROP CONSTRAINT "PlatformRoleAssignment_userId_fkey"; + +-- DropIndex +DROP INDEX IF EXISTS "PlatformRoleAssignment_userId_revokedAt_idx"; +DROP INDEX IF EXISTS "PlatformRoleAssignment_role_revokedAt_idx"; + +-- DropTable +DROP TABLE IF EXISTS "PlatformRoleAssignment"; + +-- DropEnum +DROP TYPE IF EXISTS "PlatformRole"; diff --git a/hub/prisma/schema.prisma b/hub/prisma/schema.prisma index b7707e8..75ceeba 100644 --- a/hub/prisma/schema.prisma +++ b/hub/prisma/schema.prisma @@ -58,8 +58,9 @@ enum OrganizationStatus { ARCHIVED } -/// Org-scoped platform role. Distinct from project PermissionRole and from -/// global PlatformRoleAssignment, which is reserved for SaaS/platform control. +/// Org-scoped membership role. Distinct from project PermissionRole and from +/// the platform administrator surface (ADR-0023 / Spec.System.PlatformAdministration), +/// which is a separate control plane not modeled in alpha (ADR-0025). model OrganizationMembership { id String @id @default(cuid()) organizationId String @@ -170,7 +171,6 @@ model User { createdAt DateTime @default(now()) updatedAt DateTime @updatedAt - platformRoles PlatformRoleAssignment[] organizationMemberships OrganizationMembership[] createdProjects Project[] @relation("projectCreator") requestedRuns AgentRun[] @relation("runRequester") @@ -311,26 +311,6 @@ model ProviderCredentialVersion { @@index([createdByUserId]) } -/// Platform-level role (admin/teacher). Distinct from ADR-0004 PermissionRole. -/// `admin` is the only override path for force-release (spec RequiresAdmin). -model PlatformRoleAssignment { - id String @id @default(cuid()) - userId String - role PlatformRole - createdAt DateTime @default(now()) - revokedAt DateTime? - - user User @relation(fields: [userId], references: [id], onDelete: Cascade) - - @@index([userId, revokedAt]) - @@index([role, revokedAt]) -} - -enum PlatformRole { - ADMIN - TEACHER -} - /// ADR-0019: typed principals for permission grants and actor resolution. /// USER and Feishu external principals use connection-scoped opaque ids, never /// raw provider-local ids; TEAM uses Hub Team.id. @@ -647,8 +627,9 @@ model ProjectAgentLock { // --- Permission grants & settings (ADR-0004) ---------------------------- /// ADR-0004 PermissionRole: read ⊂ edit ⊂ manage (capability lattice). -/// Distinct from PlatformRole. Force-release is admin-only, outside this -/// lattice (spec RequiresAdmin). +/// Force-release is platform-admin-only, outside this lattice (spec +/// RequiresAdmin); platform admin is a separate control plane (ADR-0023), +/// not modeled in alpha (ADR-0025). enum PermissionRole { READ EDIT diff --git a/hub/src/permissions/externalSync.ts b/hub/src/permissions/externalSync.ts index 4b6db40..9b2b6e4 100644 --- a/hub/src/permissions/externalSync.ts +++ b/hub/src/permissions/externalSync.ts @@ -71,7 +71,6 @@ export async function syncExternalPrincipalMemberships( create: { feishuOpenId: item.feishuOpenId, displayName: item.displayName, - platformRoles: { create: { role: "TEACHER" } }, organizationMemberships: { create: { organizationId: input.organizationId, role: "MEMBER" } }, }, }); diff --git a/hub/test/integration/helpers.ts b/hub/test/integration/helpers.ts index e68f4b1..aca8e73 100644 --- a/hub/test/integration/helpers.ts +++ b/hub/test/integration/helpers.ts @@ -400,7 +400,6 @@ export async function seedProject( id: "u_" + projectId, feishuOpenId: principal, displayName: "Test User", - platformRoles: { create: { role: "TEACHER" } }, organizationMemberships: { create: { organizationId: DEFAULT_ORG_ID, role: "MEMBER" } }, permissionGrants: { create: {