131 lines
4.1 KiB
TypeScript
131 lines
4.1 KiB
TypeScript
/**
|
||
* Prisma seed – single entrypoint for all tables.
|
||
* Tool data is loaded from prisma/tools.json (generate with: npm run db:export-tools-json -- prisma/tools.json).
|
||
*
|
||
* Run: npm run db:seed (or npx prisma db seed)
|
||
*/
|
||
|
||
import { PrismaClient, AccessLevel, ProcessingType } from '@prisma/client';
|
||
import * as fs from 'fs';
|
||
import * as path from 'path';
|
||
|
||
const prisma = new PrismaClient();
|
||
|
||
/** One tool row from tools.json (matches Tool model fields) */
|
||
type ToolFromJson = {
|
||
id: string;
|
||
slug: string;
|
||
category: string;
|
||
name: string;
|
||
description: string | null;
|
||
accessLevel: string;
|
||
countsAsOperation: boolean;
|
||
dockerService: string | null;
|
||
processingType: string;
|
||
isActive: boolean;
|
||
metaTitle: string | null;
|
||
metaDescription: string | null;
|
||
nameLocalized: unknown;
|
||
descriptionLocalized: unknown;
|
||
metaTitleLocalized: unknown;
|
||
metaDescriptionLocalized: unknown;
|
||
createdAt?: string;
|
||
updatedAt?: string;
|
||
};
|
||
|
||
const DISABLED_CATEGORIES = ['video', 'audio', 'text'] as const;
|
||
|
||
async function seedTools() {
|
||
const dataPath = path.join(__dirname, 'tools.json');
|
||
if (!fs.existsSync(dataPath)) {
|
||
console.error(`\n❌ Tools data file not found: ${dataPath}`);
|
||
console.error(' Generate it with: npm run db:export-tools-json -- prisma/tools.json\n');
|
||
throw new Error('Missing prisma/tools.json');
|
||
}
|
||
|
||
const raw = fs.readFileSync(dataPath, 'utf-8');
|
||
const tools: ToolFromJson[] = JSON.parse(raw);
|
||
if (!Array.isArray(tools) || tools.length === 0) {
|
||
console.warn('\n⚠️ tools.json is empty or invalid; skipping Tool seed.\n');
|
||
return;
|
||
}
|
||
|
||
// Remove tools in disabled categories (consistency with frontend)
|
||
const disabledTools = await prisma.tool.findMany({
|
||
where: { category: { in: [...DISABLED_CATEGORIES] } },
|
||
select: { id: true },
|
||
});
|
||
if (disabledTools.length > 0) {
|
||
const toolIds = disabledTools.map((t) => t.id);
|
||
await prisma.job.deleteMany({ where: { toolId: { in: toolIds } } });
|
||
await prisma.usageLog.deleteMany({ where: { toolId: { in: toolIds } } });
|
||
const { count } = await prisma.tool.deleteMany({
|
||
where: { category: { in: [...DISABLED_CATEGORIES] } },
|
||
});
|
||
console.log(` 🗑️ Removed ${count} tool(s) from disabled categories: ${DISABLED_CATEGORIES.join(', ')}`);
|
||
}
|
||
|
||
let success = 0;
|
||
const errors: Array<{ slug: string; error: unknown }> = [];
|
||
|
||
for (const t of tools) {
|
||
const payload = {
|
||
slug: t.slug,
|
||
category: t.category,
|
||
name: t.name,
|
||
description: t.description,
|
||
accessLevel: t.accessLevel as AccessLevel,
|
||
countsAsOperation: t.countsAsOperation,
|
||
dockerService: t.dockerService,
|
||
processingType: t.processingType as ProcessingType,
|
||
isActive: t.isActive,
|
||
metaTitle: t.metaTitle,
|
||
metaDescription: t.metaDescription,
|
||
nameLocalized: t.nameLocalized ?? undefined,
|
||
descriptionLocalized: t.descriptionLocalized ?? undefined,
|
||
metaTitleLocalized: t.metaTitleLocalized ?? undefined,
|
||
metaDescriptionLocalized: t.metaDescriptionLocalized ?? undefined,
|
||
};
|
||
|
||
try {
|
||
await prisma.tool.upsert({
|
||
where: { slug: t.slug },
|
||
create: payload,
|
||
update: payload,
|
||
});
|
||
success++;
|
||
} catch (err) {
|
||
errors.push({ slug: t.slug, error: err });
|
||
}
|
||
}
|
||
|
||
console.log(` ✅ Tools: ${success} upserted`);
|
||
if (errors.length > 0) {
|
||
errors.forEach(({ slug, error }) => console.error(` ❌ ${slug}:`, error));
|
||
throw new Error(`${errors.length} tool(s) failed to seed`);
|
||
}
|
||
}
|
||
|
||
async function main() {
|
||
console.log('\n🌱 Seeding database...\n');
|
||
|
||
await seedTools();
|
||
|
||
// AppConfig (022-runtime-config): Tier 2 runtime config keys
|
||
const { seedAppConfig } = await import('../scripts/seed-app-config');
|
||
await seedAppConfig(prisma);
|
||
console.log(' ✅ AppConfig seeded.');
|
||
|
||
// Add other table seeds here if needed (e.g. reference data, feature flags).
|
||
// User, Job, Payment, etc. are not seeded in production.
|
||
|
||
console.log('\n🎉 Seed completed successfully.\n');
|
||
}
|
||
|
||
main()
|
||
.catch((e) => {
|
||
console.error('\n💥 Seed failed:\n', e);
|
||
process.exit(1);
|
||
})
|
||
.finally(() => prisma.$disconnect());
|