Skip to content

Commit 045ea34

Browse files
authored
feat: (PBAC) Add db seed (calcom#22704)
* add a seed for pbac * remove readme * add team feature * add seed script to json * log seed detials
1 parent 3228d8d commit 045ea34

5 files changed

Lines changed: 878 additions & 3 deletions

File tree

packages/prisma/cleanup-pbac.ts

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#!/usr/bin/env tsx
2+
3+
/**
4+
* Cleanup script to remove PBAC demo organization and related data
5+
* Run with: npx tsx packages/prisma/cleanup-pbac.ts
6+
*/
7+
import prisma from ".";
8+
9+
async function cleanupPBACOrganization() {
10+
console.log("🧹 Cleaning up PBAC Demo Organization...");
11+
12+
try {
13+
// Find the organization
14+
const organization = await prisma.team.findFirst({
15+
where: {
16+
slug: "pbac-demo-org",
17+
isOrganization: true,
18+
},
19+
include: {
20+
members: true,
21+
roles: true,
22+
children: true, // teams within the organization
23+
},
24+
});
25+
26+
if (!organization) {
27+
console.log("ℹ️ PBAC Demo Organization not found, nothing to clean up");
28+
return;
29+
}
30+
31+
console.log(`Found organization: ${organization.name} (ID: ${organization.id})`);
32+
33+
// Delete users created for PBAC demo
34+
const pbacUserEmails = [
35+
"owner@pbac-demo.com",
36+
"events@pbac-demo.com",
37+
"analytics@pbac-demo.com",
38+
"coordinator@pbac-demo.com",
39+
"support@pbac-demo.com",
40+
];
41+
42+
const pbacUsers = await prisma.user.findMany({
43+
where: {
44+
email: { in: pbacUserEmails },
45+
},
46+
});
47+
48+
console.log(`Found ${pbacUsers.length} PBAC users to delete`);
49+
50+
// Delete users (this will cascade delete memberships, profiles, etc.)
51+
for (const user of pbacUsers) {
52+
await prisma.user.delete({
53+
where: { id: user.id },
54+
});
55+
console.log(` ✅ Deleted user: ${user.email}`);
56+
}
57+
58+
// Delete custom roles (this will cascade delete permissions)
59+
for (const role of organization.roles) {
60+
await prisma.role.delete({
61+
where: { id: role.id },
62+
});
63+
console.log(` ✅ Deleted role: ${role.name}`);
64+
}
65+
66+
// Delete child teams
67+
for (const team of organization.children) {
68+
await prisma.team.delete({
69+
where: { id: team.id },
70+
});
71+
console.log(` ✅ Deleted team: ${team.name}`);
72+
}
73+
74+
// Delete the organization (this will cascade delete organization settings)
75+
await prisma.team.delete({
76+
where: { id: organization.id },
77+
});
78+
79+
console.log(` ✅ Deleted organization: ${organization.name}`);
80+
81+
// Clean up any temp org redirects
82+
await prisma.tempOrgRedirect.deleteMany({
83+
where: {
84+
OR: [
85+
{ from: { in: ["owner", "events", "analytics", "coordinator", "support"] } },
86+
{ toUrl: { contains: "pbac-demo-org" } },
87+
],
88+
},
89+
});
90+
91+
console.log(" ✅ Cleaned up temp org redirects");
92+
93+
console.log("\n🎉 PBAC Demo Organization cleanup completed successfully!");
94+
} catch (error) {
95+
console.error("❌ Error during cleanup:", error);
96+
throw error;
97+
} finally {
98+
await prisma.$disconnect();
99+
}
100+
}
101+
102+
cleanupPBACOrganization()
103+
.then(() => {
104+
console.log("✅ Cleanup completed!");
105+
process.exit(0);
106+
})
107+
.catch((error) => {
108+
console.error("❌ Cleanup failed:", error);
109+
process.exit(1);
110+
});

packages/prisma/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
"post-install": "yarn generate-schemas",
1919
"seed-app-store": "ts-node --transpile-only ./seed-app-store.ts",
2020
"delete-app": "ts-node --transpile-only ./delete-app.ts",
21-
"seed-insights": "ts-node --transpile-only ./seed-insights.ts"
21+
"seed-insights": "ts-node --transpile-only ./seed-insights.ts",
22+
"seed-pbac": "ts-node --transpile-only ./seed-pbac-organization.ts"
2223
},
2324
"devDependencies": {
2425
"@faker-js/faker": "9.2.0",

packages/prisma/seed-pbac-only.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/usr/bin/env tsx
2+
3+
/**
4+
* Standalone script to create a PBAC-enabled organization with custom roles
5+
* Run with: npx tsx packages/prisma/seed-pbac-only.ts
6+
*/
7+
import { createPBACOrganization } from "./seed-pbac-organization";
8+
9+
async function main() {
10+
console.log("🚀 Starting PBAC organization seed...");
11+
12+
try {
13+
const result = await createPBACOrganization();
14+
15+
console.log("\n🎉 PBAC Organization created successfully!");
16+
console.log("\n📋 Summary:");
17+
console.log(`Organization: ${result.organization.name} (${result.organization.slug})`);
18+
console.log(`Custom Roles: ${Object.keys(result.customRoles).length}`);
19+
console.log(`Users: ${result.users.length}`);
20+
console.log(`Team: ${result.team?.name || "None"} (${result.team?.slug || "N/A"})`);
21+
22+
console.log("\n🔐 Login Credentials:");
23+
result.users.forEach(({ user, role, customRole }) => {
24+
const roleText = customRole ? `${role} + ${customRole}` : role;
25+
console.log(` - ${user.name}: ${user.email} / password (${roleText})`);
26+
});
27+
28+
console.log(`\n🌐 Access URLs:`);
29+
console.log(`Organization: ${process.env.NEXT_PUBLIC_WEBAPP_URL}/org/${result.organization.slug}`);
30+
if (result.team) {
31+
console.log(`Team: ${process.env.NEXT_PUBLIC_WEBAPP_URL}/team/${result.team.slug}`);
32+
}
33+
} catch (error) {
34+
console.error("❌ Error creating PBAC organization:", error);
35+
process.exit(1);
36+
}
37+
}
38+
39+
main()
40+
.then(() => {
41+
console.log("\n✅ Seed completed successfully!");
42+
process.exit(0);
43+
})
44+
.catch((error) => {
45+
console.error("❌ Seed failed:", error);
46+
process.exit(1);
47+
});

0 commit comments

Comments
 (0)