Creating a CRM Super Admin

This commit is contained in:
2026-09-19 21:54:21 +03:30
parent ff5ad21eb9
commit b016b4754f
28 changed files with 2977 additions and 6 deletions
@@ -0,0 +1,18 @@
-- AlterTable
ALTER TABLE "Organization" ADD COLUMN IF NOT EXISTS "isActive" BOOLEAN NOT NULL DEFAULT true;
-- CreateTable
CREATE TABLE IF NOT EXISTS "PlatformAdmin" (
"id" TEXT NOT NULL,
"email" TEXT NOT NULL,
"passwordHash" TEXT NOT NULL,
"fullName" TEXT NOT NULL,
"isActive" BOOLEAN NOT NULL DEFAULT true,
"lastLoginAt" TIMESTAMP(3),
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "PlatformAdmin_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX IF NOT EXISTS "PlatformAdmin_email_key" ON "PlatformAdmin"("email");
+13
View File
@@ -147,6 +147,7 @@ model Organization {
businessField String?
baseCurrency String @default("IRR")
enabledCurrencies String[] @default(["IRR", "USD", "EUR"])
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
users User[]
@@ -278,6 +279,18 @@ model Membership {
@@index([orgRoleId])
}
/// حساب سوپرادمین پلتفرم — جدا از User سازمانی
model PlatformAdmin {
id String @id @default(cuid())
email String @unique
passwordHash String
fullName String
isActive Boolean @default(true)
lastLoginAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Company {
id String @id @default(cuid())
organizationId String
+34
View File
@@ -13,7 +13,41 @@ const DEFAULT_STAGES = [
{ name: 'از دست‌رفته', isWon: false, isLost: true },
] as const;
async function seedPlatformAdmin() {
const envEmail = (process.env.PLATFORM_ADMIN_EMAIL ?? '').trim().toLowerCase();
const envPassword = process.env.PLATFORM_ADMIN_PASSWORD ?? '';
const envName = (process.env.PLATFORM_ADMIN_NAME ?? 'سوپرادمین').trim() || 'سوپرادمین';
const isProd = process.env.NODE_ENV === 'production';
const email = envEmail || (isProd ? '' : 'platform@demo.local');
const password = envPassword || (isProd ? '' : 'demo1234');
if (!email || !password) {
console.log(
'Platform admin seed skipped (set PLATFORM_ADMIN_EMAIL and PLATFORM_ADMIN_PASSWORD)',
);
return;
}
if (password.length < 8) {
console.log('Platform admin seed skipped (password must be at least 8 chars)');
return;
}
const existing = await prisma.platformAdmin.findUnique({ where: { email } });
if (existing) {
console.log('Platform admin exists:', email);
return;
}
const passwordHash = await bcrypt.hash(password, 10);
await prisma.platformAdmin.create({
data: { email, passwordHash, fullName: envName },
});
console.log('Seeded platform admin:', email);
}
async function main() {
await seedPlatformAdmin();
const email = 'owner@demo.local';
let org = await prisma.organization.findUnique({ where: { slug: 'demo-mento' } });
if (!org) {