Add CEO-safe company portability flows

Expose CEO-scoped import/export preview and apply routes, keep safe imports non-destructive, add export preview-first UI behavior, and document the new portability workflows.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
dotta
2026-03-18 21:54:10 -05:00
parent 685c7549e1
commit 51ca713181
18 changed files with 1166 additions and 96 deletions

View File

@@ -83,6 +83,20 @@ export function accessService(db: Db) {
.orderBy(sql`${companyMemberships.createdAt} desc`);
}
async function listActiveUserMemberships(companyId: string) {
return db
.select()
.from(companyMemberships)
.where(
and(
eq(companyMemberships.companyId, companyId),
eq(companyMemberships.principalType, "user"),
eq(companyMemberships.status, "active"),
),
)
.orderBy(sql`${companyMemberships.createdAt} asc`);
}
async function setMemberPermissions(
companyId: string,
memberId: string,
@@ -251,6 +265,20 @@ export function accessService(db: Db) {
});
}
async function copyActiveUserMemberships(sourceCompanyId: string, targetCompanyId: string) {
const sourceMemberships = await listActiveUserMemberships(sourceCompanyId);
for (const membership of sourceMemberships) {
await ensureMembership(
targetCompanyId,
"user",
membership.principalId,
membership.membershipRole,
"active",
);
}
return sourceMemberships;
}
return {
isInstanceAdmin,
canUser,
@@ -258,6 +286,8 @@ export function accessService(db: Db) {
getMembership,
ensureMembership,
listMembers,
listActiveUserMemberships,
copyActiveUserMemberships,
setMemberPermissions,
promoteInstanceAdmin,
demoteInstanceAdmin,