MCPcopy Create free account
hub / github.com/UsefulSoftwareCo/executor / purgeOrganizationData

Function purgeOrganizationData

apps/cloud/src/db/org-deletion.ts:54–95  ·  view source on GitHub ↗
(
  db: DrizzleDb,
  organizationId: string,
  deletedAt: Date,
)

Source from the content-addressed store, hash-verified

52 * nothing and keeps the first mark.
53 */
54export const purgeOrganizationData = (
55 db: DrizzleDb,
56 organizationId: string,
57 deletedAt: Date,
58): Promise<void> =>
59 db.transaction(async (tx) => {
60 // Executor tenant tables — every row is scoped by `tenant = organizationId`.
61 await tx.delete(tool).where(eq(tool.tenant, organizationId));
62 await tx.delete(definition).where(eq(definition.tenant, organizationId));
63 await tx.delete(connection).where(eq(connection.tenant, organizationId));
64 await tx.delete(integration).where(eq(integration.tenant, organizationId));
65 await tx.delete(oauth_client).where(eq(oauth_client.tenant, organizationId));
66 await tx.delete(oauth_session).where(eq(oauth_session.tenant, organizationId));
67 await tx.delete(tool_policy).where(eq(tool_policy.tenant, organizationId));
68 await tx.delete(plugin_storage).where(eq(plugin_storage.tenant, organizationId));
69 await tx.delete(subject).where(eq(subject.tenant, organizationId));
70 await tx.delete(artifact).where(eq(artifact.tenant, organizationId));
71
72 // Secrets, OAuth tokens, and cached specs live in `blob`, namespaced by
73 // owner: `o:<org>/<plugin>` (org scope) and `u:<org>:<subject>/<plugin>`
74 // (per-user scope). Match both prefixes for this org.
75 const esc = escapeLike(organizationId);
76 await tx
77 .delete(blob)
78 .where(
79 or(
80 sql`${blob.namespace} LIKE ${`o:${esc}/%`} ESCAPE '\\'`,
81 sql`${blob.namespace} LIKE ${`u:${esc}:%`} ESCAPE '\\'`,
82 ),
83 );
84
85 // Identity mirror: the memberships go, the organization row stays as a
86 // tombstone (see the header). `accounts` are intentionally left: a user
87 // may belong to other orgs.
88 await tx.delete(memberships).where(eq(memberships.organizationId, organizationId));
89 await tx
90 .update(organizations)
91 .set({
92 deletedAt: sql`coalesce(${organizations.deletedAt}, ${deletedAt.toISOString()}::timestamptz)`,
93 })
94 .where(eq(organizations.id, organizationId));
95 });

Callers 1

makeUserStoreFunction · 0.90

Calls 5

escapeLikeFunction · 0.70
transactionMethod · 0.65
deleteMethod · 0.65
setMethod · 0.65
updateMethod · 0.65

Tested by

no test coverage detected