diff --git a/prisma/seed.ts b/prisma/seed.ts index b0f9707..3fd6f7e 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -6,28 +6,19 @@ const prisma = new PrismaClient(); async function main() { console.log('Seeding database...'); - // Create default tenant - const tenant = await prisma.tenant.upsert({ - where: { slug: 'default' }, - update: {}, - create: { - name: 'Default Workspace', - slug: 'default' - } - }); - - // Map hostnames to default tenant - const hostnames = ['localhost', '127.0.0.1', 'pounce.catrenelle.com']; - for (const hostname of hostnames) { - await prisma.tenantHostname.upsert({ - where: { hostname }, - update: {}, - create: { - hostname, - tenantId: tenant.id, - isPrimary: hostname === 'localhost' + // The app auto-creates a tenant on first request, + // but the seed ensures an admin user exists. + let tenant = await prisma.tenant.findFirst(); + if (!tenant) { + tenant = await prisma.tenant.create({ + data: { + name: 'Pounce', + slug: 'default' } }); + console.log(` Created tenant: ${tenant.name} (${tenant.id})`); + } else { + console.log(` Existing tenant: ${tenant.name} (${tenant.id})`); } // Create admin user @@ -46,8 +37,6 @@ async function main() { }); console.log('Seed complete.'); - console.log(` Tenant: ${tenant.name} (${tenant.id})`); - console.log(` Hostnames: ${hostnames.join(', ')}`); console.log(' Admin: admin@example.com / admin123'); } diff --git a/src/lib/server/tenant.ts b/src/lib/server/tenant.ts index 8fa209b..c7b7d0c 100644 --- a/src/lib/server/tenant.ts +++ b/src/lib/server/tenant.ts @@ -19,23 +19,71 @@ export async function resolveTenant(hostname: string): Promise { + // Any hostname that reaches this app was pointed here via DNS, + // so it's intentional. Auto-create a tenant for it. + const slug = slugify(host); + const name = humanizeDomain(host); + + const tenant = await prisma.tenant.create({ + data: { + name, + slug, + hostnames: { + create: { hostname: host, isPrimary: true } + } + } + }); + + return { id: tenant.id, name: tenant.name, slug: tenant.slug }; +} + +function slugify(host: string): string { + return host + .replace(/[^a-zA-Z0-9]/g, '-') + .replace(/-+/g, '-') + .replace(/^-|-$/g, '') + .toLowerCase() + .slice(0, 48); +} + +function humanizeDomain(host: string): string { + // "pounce.catrenelle.com" -> "Pounce" + // "192.168.3.65" -> "Pounce" + // "localhost" -> "Pounce" + const part = host.split('.')[0]; + if (/^\d+$/.test(part) || part === 'localhost') { + return 'Pounce'; + } + return part.charAt(0).toUpperCase() + part.slice(1); +} + export function clearTenantCache() { tenantCache.clear(); }