generated from fahricansecer/boilerplate-be
291 lines
10 KiB
TypeScript
291 lines
10 KiB
TypeScript
import { PrismaClient } from '@prisma/client';
|
||
import * as bcrypt from 'bcrypt';
|
||
|
||
const prisma = new PrismaClient();
|
||
|
||
async function main() {
|
||
console.log('🌱 ContentGen AI — Seed Data Yükleniyor...\n');
|
||
|
||
// ── 1. Roller ──────────────────────────────────────────────────────
|
||
console.log('👤 Roller oluşturuluyor...');
|
||
|
||
const adminRole = await prisma.role.upsert({
|
||
where: { name: 'admin' },
|
||
update: {},
|
||
create: {
|
||
name: 'admin',
|
||
description: 'Tam yetkili yönetici — sınırsız erişim',
|
||
isSystem: true,
|
||
},
|
||
});
|
||
|
||
const userRole = await prisma.role.upsert({
|
||
where: { name: 'user' },
|
||
update: {},
|
||
create: {
|
||
name: 'user',
|
||
description: 'Standart kullanıcı rolü',
|
||
isSystem: true,
|
||
},
|
||
});
|
||
|
||
console.log(` ✅ admin (${adminRole.id})`);
|
||
console.log(` ✅ user (${userRole.id})`);
|
||
|
||
// ── 2. İzinler ─────────────────────────────────────────────────────
|
||
console.log('\n🔑 İzinler oluşturuluyor...');
|
||
|
||
const permissionDefs = [
|
||
// Projects
|
||
{ name: 'projects:create', resource: 'projects', action: 'create', description: 'Proje oluşturabilir' },
|
||
{ name: 'projects:read', resource: 'projects', action: 'read', description: 'Projeleri görüntüleyebilir' },
|
||
{ name: 'projects:update', resource: 'projects', action: 'update', description: 'Proje düzenleyebilir' },
|
||
{ name: 'projects:delete', resource: 'projects', action: 'delete', description: 'Proje silebilir' },
|
||
// Templates
|
||
{ name: 'templates:read', resource: 'templates', action: 'read', description: 'Şablonları görüntüleyebilir' },
|
||
{ name: 'templates:create', resource: 'templates', action: 'create', description: 'Şablon oluşturabilir' },
|
||
{ name: 'templates:manage', resource: 'templates', action: 'manage', description: 'Şablonları yönetebilir' },
|
||
// Billing
|
||
{ name: 'billing:read', resource: 'billing', action: 'read', description: 'Fatura bilgilerini görüntüleyebilir' },
|
||
{ name: 'billing:manage', resource: 'billing', action: 'manage', description: 'Abonelik ve ödeme yönetimi' },
|
||
// Admin
|
||
{ name: 'admin:access', resource: 'admin', action: 'access', description: 'Admin paneline erişebilir' },
|
||
{ name: 'admin:users', resource: 'admin', action: 'users', description: 'Kullanıcıları yönetebilir' },
|
||
{ name: 'admin:system', resource: 'admin', action: 'system', description: 'Sistem ayarlarını yönetebilir' },
|
||
// Notifications
|
||
{ name: 'notifications:read', resource: 'notifications', action: 'read', description: 'Bildirimleri görüntüleyebilir' },
|
||
{ name: 'notifications:manage', resource: 'notifications', action: 'manage', description: 'Bildirimleri yönetebilir' },
|
||
];
|
||
|
||
const permissions: Record<string, any> = {};
|
||
for (const perm of permissionDefs) {
|
||
const p = await prisma.permission.upsert({
|
||
where: { resource_action: { resource: perm.resource, action: perm.action } },
|
||
update: { description: perm.description },
|
||
create: perm,
|
||
});
|
||
permissions[perm.name] = p;
|
||
console.log(` ✅ ${perm.name}`);
|
||
}
|
||
|
||
// ── 3. Rol-İzin Eşlemeleri ─────────────────────────────────────────
|
||
console.log('\n🔗 Rol-İzin eşlemeleri oluşturuluyor...');
|
||
|
||
// Admin: Tüm izinler
|
||
for (const perm of Object.values(permissions)) {
|
||
await prisma.rolePermission.upsert({
|
||
where: { roleId_permissionId: { roleId: adminRole.id, permissionId: perm.id } },
|
||
update: {},
|
||
create: { roleId: adminRole.id, permissionId: perm.id },
|
||
});
|
||
}
|
||
console.log(` ✅ admin → ${Object.keys(permissions).length} izin`);
|
||
|
||
// User: Temel izinler
|
||
const userPermNames = [
|
||
'projects:create', 'projects:read', 'projects:update', 'projects:delete',
|
||
'templates:read', 'billing:read', 'billing:manage', 'notifications:read',
|
||
];
|
||
for (const permName of userPermNames) {
|
||
const perm = permissions[permName];
|
||
if (perm) {
|
||
await prisma.rolePermission.upsert({
|
||
where: { roleId_permissionId: { roleId: userRole.id, permissionId: perm.id } },
|
||
update: {},
|
||
create: { roleId: userRole.id, permissionId: perm.id },
|
||
});
|
||
}
|
||
}
|
||
console.log(` ✅ user → ${userPermNames.length} izin`);
|
||
|
||
// ── 4. Planlar ─────────────────────────────────────────────────────
|
||
console.log('\n💳 Planlar oluşturuluyor...');
|
||
|
||
const plans = [
|
||
{
|
||
name: 'free',
|
||
displayName: 'Free',
|
||
description: 'Başlangıç planı — temel video üretimi',
|
||
monthlyPrice: 0,
|
||
yearlyPrice: 0,
|
||
currency: 'usd',
|
||
monthlyCredits: 3,
|
||
maxDuration: 30,
|
||
maxResolution: '720p',
|
||
maxProjects: 5,
|
||
sortOrder: 0,
|
||
features: {
|
||
templates: true,
|
||
priorityQueue: false,
|
||
customBranding: false,
|
||
apiAccess: false,
|
||
analytics: false,
|
||
support: 'community',
|
||
},
|
||
},
|
||
{
|
||
name: 'pro',
|
||
displayName: 'Pro',
|
||
description: 'Profesyonel içerik üreticileri için — gelişmiş özellikler',
|
||
monthlyPrice: 1900, // $19.00
|
||
yearlyPrice: 19000, // $190.00 (yıllık ~%17 indirim)
|
||
currency: 'usd',
|
||
monthlyCredits: 25,
|
||
maxDuration: 120,
|
||
maxResolution: '1080p',
|
||
maxProjects: 50,
|
||
sortOrder: 1,
|
||
features: {
|
||
templates: true,
|
||
priorityQueue: true,
|
||
customBranding: true,
|
||
apiAccess: false,
|
||
analytics: true,
|
||
support: 'email',
|
||
},
|
||
},
|
||
{
|
||
name: 'business',
|
||
displayName: 'Business',
|
||
description: 'Ajanslar ve ekipler için — sınırsız üretim kapasitesi',
|
||
monthlyPrice: 4900, // $49.00
|
||
yearlyPrice: 49000, // $490.00 (yıllık ~%17 indirim)
|
||
currency: 'usd',
|
||
monthlyCredits: 100,
|
||
maxDuration: 300,
|
||
maxResolution: '4k',
|
||
maxProjects: 500,
|
||
sortOrder: 2,
|
||
features: {
|
||
templates: true,
|
||
priorityQueue: true,
|
||
customBranding: true,
|
||
apiAccess: true,
|
||
analytics: true,
|
||
support: 'priority',
|
||
},
|
||
},
|
||
];
|
||
|
||
for (const plan of plans) {
|
||
await prisma.plan.upsert({
|
||
where: { name: plan.name },
|
||
update: {
|
||
displayName: plan.displayName,
|
||
description: plan.description,
|
||
monthlyPrice: plan.monthlyPrice,
|
||
yearlyPrice: plan.yearlyPrice,
|
||
monthlyCredits: plan.monthlyCredits,
|
||
maxDuration: plan.maxDuration,
|
||
maxResolution: plan.maxResolution,
|
||
maxProjects: plan.maxProjects,
|
||
features: plan.features,
|
||
sortOrder: plan.sortOrder,
|
||
},
|
||
create: plan,
|
||
});
|
||
console.log(` ✅ ${plan.displayName} — ${plan.monthlyCredits} kredi/ay, $${(plan.monthlyPrice / 100).toFixed(0)}/ay`);
|
||
}
|
||
|
||
// ── 5. Admin Kullanıcı — haruncan@gmail.com ────────────────────────
|
||
console.log('\n👑 Admin kullanıcı oluşturuluyor...');
|
||
|
||
const adminPassword = await bcrypt.hash('Admin123!', 12);
|
||
const adminEmail = 'haruncan@gmail.com';
|
||
|
||
const adminUser = await prisma.user.upsert({
|
||
where: { email: adminEmail },
|
||
update: {},
|
||
create: {
|
||
email: adminEmail,
|
||
password: adminPassword,
|
||
firstName: 'Harun',
|
||
lastName: 'Can',
|
||
isActive: true,
|
||
roles: {
|
||
create: {
|
||
roleId: adminRole.id,
|
||
},
|
||
},
|
||
},
|
||
});
|
||
|
||
console.log(` ✅ ${adminEmail} (${adminUser.id})`);
|
||
|
||
// Admin kullanıcıya sınırsız kredi ver (999999 başlangıç kredisi)
|
||
const existingGrant = await prisma.creditTransaction.findFirst({
|
||
where: { userId: adminUser.id, type: 'grant', description: 'Admin başlangıç kredisi' },
|
||
});
|
||
|
||
if (!existingGrant) {
|
||
await prisma.creditTransaction.create({
|
||
data: {
|
||
userId: adminUser.id,
|
||
amount: 999999,
|
||
type: 'grant',
|
||
description: 'Admin başlangıç kredisi — sınırsız',
|
||
balanceAfter: 999999,
|
||
},
|
||
});
|
||
console.log(' ✅ 999.999 kredi yüklendi (sınırsız)');
|
||
} else {
|
||
console.log(' ⏭️ Kredi zaten mevcut');
|
||
}
|
||
|
||
// Admin kullanıcıya Business planına aktif abonelik oluştur
|
||
const businessPlan = await prisma.plan.findUnique({ where: { name: 'business' } });
|
||
if (businessPlan) {
|
||
const existingSub = await prisma.subscription.findFirst({
|
||
where: { userId: adminUser.id, status: 'active' },
|
||
});
|
||
if (!existingSub) {
|
||
await prisma.subscription.create({
|
||
data: {
|
||
userId: adminUser.id,
|
||
planId: businessPlan.id,
|
||
status: 'active',
|
||
currentPeriodStart: new Date(),
|
||
currentPeriodEnd: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000), // 1 yıl
|
||
},
|
||
});
|
||
console.log(' ✅ Business plan aboneliği oluşturuldu (sınırsız)');
|
||
} else {
|
||
console.log(' ⏭️ Aktif abonelik zaten mevcut');
|
||
}
|
||
}
|
||
|
||
// Admin tercihlerini oluştur
|
||
await prisma.userPreference.upsert({
|
||
where: { userId: adminUser.id },
|
||
update: {},
|
||
create: {
|
||
userId: adminUser.id,
|
||
defaultLanguage: 'tr',
|
||
defaultVideoStyle: 'CINEMATIC',
|
||
defaultDuration: 60,
|
||
theme: 'dark',
|
||
emailNotifications: true,
|
||
pushNotifications: true,
|
||
},
|
||
});
|
||
console.log(' ✅ Kullanıcı tercihleri ayarlandı');
|
||
|
||
// ── Özet ────────────────────────────────────────────────────────────
|
||
console.log('\n═══════════════════════════════════════════════════════════');
|
||
console.log('🎉 Seed data başarıyla yüklendi!');
|
||
console.log(` 📁 Roller: ${2}`);
|
||
console.log(` 🔑 İzinler: ${Object.keys(permissions).length}`);
|
||
console.log(` 💳 Planlar: ${plans.length}`);
|
||
console.log(` 👤 Admin: ${adminEmail}`);
|
||
console.log('═══════════════════════════════════════════════════════════\n');
|
||
}
|
||
|
||
main()
|
||
.catch((e) => {
|
||
console.error('❌ Seed hatası:', e);
|
||
process.exit(1);
|
||
})
|
||
.finally(async () => {
|
||
await prisma.$disconnect();
|
||
});
|