Initial AI manga platform

This commit is contained in:
www
2026-06-15 17:45:28 +08:00
commit 7a8191650f
267 changed files with 105987 additions and 0 deletions
+147
View File
@@ -0,0 +1,147 @@
import { PrismaClient } from '@prisma/client';
import { hash } from 'bcryptjs';
import { DEFAULT_AI_ROUTER_CONFIG } from '../src/ai-router/ai-router.types';
const prisma = new PrismaClient();
const mockProviders = [
['TextProvider', 'mock-text', 'Mock Text Provider', 'mock-text-v1'],
['NovelProvider', 'mock-novel', 'Mock Novel Provider', 'mock-novel-v1'],
['ImageProvider', 'mock-image', 'Mock Image Provider', 'mock-image-v1'],
['VideoProvider', 'mock-video', 'Mock Video Provider', 'mock-video-v1'],
['VoiceProvider', 'mock-voice', 'Mock Voice Provider', 'mock-voice-v1'],
['LipSyncProvider', 'mock-lipsync', 'Mock Lip Sync Provider', 'mock-lipsync-v1'],
['ModerationProvider', 'mock-moderation', 'Mock Moderation Provider', 'mock-moderation-v1'],
['QualityCheckProvider', 'mock-qc', 'Mock Quality Check Provider', 'mock-qc-v1'],
['FileParseProvider', 'mock-file-parse', 'Mock File Parse Provider', 'mock-file-parse-v1'],
['EmbeddingProvider', 'mock-embedding', 'Mock Embedding Provider', 'mock-embedding-v1']
] as const;
async function main() {
const adminPassword = process.env.SEED_ADMIN_PASSWORD || 'Admin123!';
const adminPasswordHash = await hash(adminPassword, 12);
const admin = await prisma.user.upsert({
where: { email: 'admin@example.com' },
update: {
password_hash: adminPasswordHash,
role: 'admin',
status: 'active'
},
create: {
email: 'admin@example.com',
password_hash: adminPasswordHash,
nickname: 'System Admin',
role: 'admin',
status: 'active'
}
});
for (const [providerType, providerCode, displayName, modelName] of mockProviders) {
const isEnabled = providerCode !== 'mock-lipsync';
await prisma.providerConfig.upsert({
where: {
provider_type_provider_code: {
provider_type: providerType,
provider_code: providerCode
}
},
update: {
display_name: displayName,
mode: 'mock',
model_name: modelName,
is_enabled: isEnabled,
priority: 100,
rate_limit_json: {
rpm: 120,
concurrency: 8
},
cost_rule_json: {
flat_cost: 0,
unit: 'mock'
}
},
create: {
provider_type: providerType,
provider_code: providerCode,
display_name: displayName,
mode: 'mock',
model_name: modelName,
is_enabled: isEnabled,
priority: 100,
config_json: {
note: 'Used until the MVP flow is complete.'
},
rate_limit_json: {
rpm: 120,
concurrency: 8
},
cost_rule_json: {
flat_cost: 0,
unit: 'mock'
}
}
});
}
await prisma.systemConfig.upsert({
where: { config_key: 'system_a.current_stage' },
update: {
config_value: {
stage: 'stage-02-database-schema'
}
},
create: {
config_key: 'system_a.current_stage',
config_value: {
stage: 'stage-02-database-schema'
},
description: 'Tracks current System A development stage.'
}
});
await prisma.systemConfig.upsert({
where: { config_key: 'security.api_crypto_enabled' },
update: {},
create: {
config_key: 'security.api_crypto_enabled',
config_value: {
enabled: false
},
description: 'Controls frontend/backend API payload encryption. Default off for testing; enable manually in production.',
is_public: true
}
});
await prisma.systemConfig.upsert({
where: { config_key: 'ai.router.v1' },
update: {},
create: {
config_key: 'ai.router.v1',
config_value: DEFAULT_AI_ROUTER_CONFIG,
description: 'AI Router V1 route config for automatic provider selection by language, shot score and budget.',
is_public: false
}
});
await prisma.quotaAccount.upsert({
where: { user_id: admin.id },
update: {},
create: {
user_id: admin.id,
total_quota: 100,
available_quota: 100,
status: 'active'
}
});
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (error) => {
console.error(error);
await prisma.$disconnect();
process.exit(1);
});