From adce8fb6f501f46d6e8b76ace6e193ae7599aff5 Mon Sep 17 00:00:00 2001 From: ChickenPige0n <2336983354@qq.com> Date: Tue, 14 Jul 2026 21:20:50 +0800 Subject: [PATCH] chore: drop legacy PlatformRoleAssignment model ADR-0023 / Spec.System.PlatformAdministration pins the platform administrator as a separate identity/session/audit control plane, intentionally not modeled in alpha (ADR-0025). The legacy PlatformRoleAssignment / PlatformRole{ADMIN,TEACHER} table had no runtime reader (no guard, route, or service queried it for an authorization decision) and ADR-0023 requires it to be replaced before the platform panel ships. Drop the model, the PlatformRole enum, the User.platformRoles relation, and the migration. Stop seeding platformRoles in externalSync principal ingestion and the integration test helper. Update the doc comments on OrganizationMembership and PermissionRole to point at the platform-admin control plane instead of the dropped model. The 20260709180000_organization_tenant_root backfill only referenced PlatformRoleAssignment in a one-time INSERT...SELECT; no persistent object references it, so dropping the table is safe after that migration. --- .../migration.sql | 20 ++++++++++++ hub/prisma/schema.prisma | 31 ++++--------------- hub/src/permissions/externalSync.ts | 1 - hub/test/integration/helpers.ts | 1 - 4 files changed, 26 insertions(+), 27 deletions(-) create mode 100644 hub/prisma/migrations/20260714120000_drop_legacy_platform_role_assignment/migration.sql 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: {