Files
pn-new-crm/src/lib/db/seed-bootstrap.ts

168 lines
5.0 KiB
TypeScript
Raw Normal View History

/**
* Shared seed bootstrap: ports + system roles + super admin profile.
*
* Both the realistic seed (`seed.ts`) and the synthetic seed
* (`seed-synthetic.ts`) call into this so we don't drift on the
* permission maps or the operator account ids.
*
* Idempotent. Returns the resolved port ids so callers can chain
* per-port fixture builders.
*/
import { eq } from 'drizzle-orm';
import { db } from './index';
import { ports } from './schema/ports';
import { roles, userProfiles } from './schema/users';
import {
ALL_PERMISSIONS,
DIRECTOR_PERMISSIONS,
SALES_MANAGER_PERMISSIONS,
SALES_AGENT_PERMISSIONS,
VIEWER_PERMISSIONS,
RESIDENTIAL_PARTNER_PERMISSIONS,
} from './seed-permissions';
export interface BootstrappedPort {
id: string;
name: string;
slug: string;
}
export const PORT_DEFINITIONS: Array<{
name: string;
slug: string;
primaryColor: string;
defaultCurrency: string;
timezone: string;
}> = [
{
name: 'Port Nimara',
slug: 'port-nimara',
primaryColor: '#0F4C81',
defaultCurrency: 'USD',
timezone: 'America/Anguilla',
},
{
name: 'Port Amador',
slug: 'port-amador',
primaryColor: '#D97706',
defaultCurrency: 'USD',
timezone: 'America/Panama',
},
];
export const SUPER_ADMIN_USER_ID = 'super-admin-matt-portnimara';
export async function seedBootstrap(): Promise<BootstrappedPort[]> {
console.log('Bootstrap: ports + roles + super admin profile');
// ── Ports ──────────────────────────────────────────────────────────────────
const portIds: BootstrappedPort[] = [];
for (const def of PORT_DEFINITIONS) {
const [inserted] = await db
.insert(ports)
.values({
id: crypto.randomUUID(),
name: def.name,
slug: def.slug,
logoUrl: null,
primaryColor: def.primaryColor,
defaultCurrency: def.defaultCurrency,
timezone: def.timezone,
settings: {},
isActive: true,
})
.onConflictDoNothing()
.returning();
if (inserted) {
console.log(` Port created: ${def.name} (${inserted.id})`);
portIds.push({ id: inserted.id, name: def.name, slug: def.slug });
} else {
const [existing] = await db.select().from(ports).where(eq(ports.slug, def.slug)).limit(1);
if (existing) {
console.log(` Port exists: ${def.name} (${existing.id})`);
portIds.push({ id: existing.id, name: def.name, slug: def.slug });
}
}
}
// ── System roles ──────────────────────────────────────────────────────────
const systemRoles = [
{
id: crypto.randomUUID(),
name: 'super_admin',
description: 'Full system access. Bypasses all permission checks.',
permissions: ALL_PERMISSIONS,
isGlobal: true,
isSystem: true,
},
{
id: crypto.randomUUID(),
name: 'director',
description: 'Operational admin within assigned port(s). Can manage users and settings.',
permissions: DIRECTOR_PERMISSIONS,
isGlobal: true,
isSystem: true,
},
{
id: crypto.randomUUID(),
name: 'sales_manager',
description: 'Full sales access. Can view all reminders, assign tasks, and export reports.',
permissions: SALES_MANAGER_PERMISSIONS,
isGlobal: true,
isSystem: true,
},
{
id: crypto.randomUUID(),
name: 'sales_agent',
description:
'Standard sales role. View/create/edit clients and interests, manage own reminders.',
permissions: SALES_AGENT_PERMISSIONS,
isGlobal: true,
isSystem: true,
},
{
id: crypto.randomUUID(),
name: 'viewer',
description: 'Read-only access to all records.',
permissions: VIEWER_PERMISSIONS,
isGlobal: true,
isSystem: true,
},
{
id: crypto.randomUUID(),
name: 'residential_partner',
description:
'External partner who handles residential inquiries. Sees only the residential pages — no marina clients, yachts, berths, or financial data.',
permissions: RESIDENTIAL_PARTNER_PERMISSIONS,
isGlobal: true,
isSystem: true,
},
];
for (const role of systemRoles) {
await db.insert(roles).values(role).onConflictDoNothing();
}
console.log(` Roles ensured: ${systemRoles.map((r) => r.name).join(', ')}`);
// ── Super admin profile placeholder ───────────────────────────────────────
await db
.insert(userProfiles)
.values({
id: crypto.randomUUID(),
userId: SUPER_ADMIN_USER_ID,
displayName: 'Matt',
avatarUrl: null,
phone: null,
isSuperAdmin: true,
isActive: true,
lastLoginAt: null,
preferences: {},
})
.onConflictDoNothing();
console.log(` Super admin profile ensured (user_id: ${SUPER_ADMIN_USER_ID})`);
return portIds;
}