Fix dev seed for single-company schema, sync RBAC on startup

- Remove all company_id references from dev-seed.ts (removed in 0021)
- seedPermissions now syncs role-permission assignments for system roles
  when new permissions are added (e.g., vault.view assigned to admin)
- Fix enum migration: use text cast workaround for PostgreSQL's
  "unsafe use of new enum value" error on fresh DB creation
This commit is contained in:
Ryan Moon
2026-03-30 07:10:20 -05:00
parent e346e072b8
commit 328b4a1f7b
4 changed files with 50 additions and 27 deletions

View File

@@ -7,15 +7,40 @@ import { ForbiddenError } from '../lib/errors.js'
import { withPagination, withSort, buildSearchCondition, paginatedResponse } from '../utils/pagination.js'
export const RbacService = {
/** Seed system permissions (global, run once) */
/** Seed system permissions and sync role assignments for any new permissions */
async seedPermissions(db: PostgresJsDatabase<any>) {
const existing = await db.select({ slug: permissions.slug }).from(permissions)
const existingSlugs = new Set(existing.map((p) => p.slug))
const toInsert = SYSTEM_PERMISSIONS.filter((p) => !existingSlugs.has(p.slug))
if (toInsert.length === 0) return
if (toInsert.length > 0) {
await db.insert(permissions).values(toInsert)
}
await db.insert(permissions).values(toInsert)
// Sync system role permission assignments — ensures new permissions
// (e.g., vault.view) get assigned to existing roles on restart
const allPerms = await db.select().from(permissions)
const permMap = new Map(allPerms.map((p) => [p.slug, p.id]))
const systemRoles = await db.select().from(roles).where(eq(roles.isSystem, true))
for (const role of systemRoles) {
const roleDef = DEFAULT_ROLES.find((r) => r.slug === role.slug)
if (!roleDef) continue
const existingAssignments = await db.select({ permissionId: rolePermissions.permissionId })
.from(rolePermissions).where(eq(rolePermissions.roleId, role.id))
const assignedPermIds = new Set(existingAssignments.map((a) => a.permissionId))
const missingPermIds = roleDef.permissions
.map((slug) => permMap.get(slug))
.filter((id): id is string => id !== undefined && !assignedPermIds.has(id))
if (missingPermIds.length > 0) {
await db.insert(rolePermissions).values(
missingPermIds.map((permissionId) => ({ roleId: role.id, permissionId })),
)
}
}
},
/** Seed default roles */