Files
tabungin/apps/api/dist/seed.js
dwindown c3bc181063 feat: add admin dashboard schema and seeder
- Add Plan, Subscription, Payment, PaymentMethod, Coupon models
- Add ApiKey, Webhook models for API access
- Add AppConfig model for dynamic configuration
- Add role, suspendedAt fields to User model
- Create comprehensive seeder with:
  - Admin user (dwindi.ramadhana@gmail.com)
  - Default plans (Free, Pro Monthly, Pro Yearly)
  - Payment methods (BCA, Mandiri, GoPay)
  - App config (maintenance mode)
- Zero data loss migration strategy
2025-10-11 14:06:55 +07:00

268 lines
9.9 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const client_1 = require("@prisma/client");
const bcrypt = __importStar(require("bcrypt"));
const prisma = new client_1.PrismaClient();
const TEMP_USER_ID = process.env.TEMP_USER_ID || '16b74848-daa3-4dc9-8de2-3cf59e08f8e3';
const ADMIN_EMAIL = 'dwindi.ramadhana@gmail.com';
const ADMIN_PASSWORD = 'tabungin2k25!@#';
async function main() {
console.log('🌱 Starting seed...');
console.log('\n👤 Creating admin user...');
const passwordHash = await bcrypt.hash(ADMIN_PASSWORD, 10);
const admin = await prisma.user.upsert({
where: { email: ADMIN_EMAIL },
update: {
role: 'admin',
passwordHash,
emailVerified: true,
},
create: {
email: ADMIN_EMAIL,
passwordHash,
name: 'Dwindi Ramadhana',
role: 'admin',
emailVerified: true,
},
});
console.log('✅ Admin user created:', admin.email);
console.log('\n💰 Creating default plans...');
const freePlan = await prisma.plan.upsert({
where: { slug: 'free' },
update: {},
create: {
name: 'Free',
slug: 'free',
description: 'Perfect for getting started',
price: 0,
currency: 'IDR',
durationType: 'lifetime',
durationDays: null,
trialDays: 0,
features: {
wallets: { limit: 5, label: '5 wallets' },
goals: { limit: 3, label: '3 goals' },
team: { enabled: false, label: 'No team feature' },
api: { enabled: false, label: 'No API access' },
support: { level: 'basic', label: 'Basic support' },
export: { enabled: true, formats: ['csv'], label: 'CSV export' },
},
badge: null,
sortOrder: 1,
isActive: true,
isVisible: true,
isFeatured: false,
maxWallets: 5,
maxGoals: 3,
maxTeamMembers: 0,
apiEnabled: false,
apiRateLimit: null,
},
});
const proMonthly = await prisma.plan.upsert({
where: { slug: 'pro-monthly' },
update: {},
create: {
name: 'Pro Monthly',
slug: 'pro-monthly',
description: 'Perfect for individuals and small teams',
price: 49000,
currency: 'IDR',
durationType: 'monthly',
durationDays: 30,
trialDays: 7,
features: {
wallets: { limit: null, label: 'Unlimited wallets' },
goals: { limit: null, label: 'Unlimited goals' },
team: { enabled: true, maxMembers: 10, label: 'Team feature (10 members)' },
api: { enabled: true, rateLimit: 1000, label: 'API access (1000 req/hr)' },
support: { level: 'priority', label: 'Priority support' },
export: { enabled: true, formats: ['csv', 'excel', 'pdf'], label: 'All export formats' },
},
badge: 'Popular',
badgeColor: 'blue',
highlightColor: '#3B82F6',
sortOrder: 2,
isActive: true,
isVisible: true,
isFeatured: true,
maxWallets: null,
maxGoals: null,
maxTeamMembers: 10,
apiEnabled: true,
apiRateLimit: 1000,
},
});
const proYearly = await prisma.plan.upsert({
where: { slug: 'pro-yearly' },
update: {},
create: {
name: 'Pro Yearly',
slug: 'pro-yearly',
description: 'Best value - Save 17% with annual billing',
price: 490000,
currency: 'IDR',
durationType: 'yearly',
durationDays: 365,
trialDays: 7,
features: {
wallets: { limit: null, label: 'Unlimited wallets' },
goals: { limit: null, label: 'Unlimited goals' },
team: { enabled: true, maxMembers: 10, label: 'Team feature (10 members)' },
api: { enabled: true, rateLimit: 1000, label: 'API access (1000 req/hr)' },
support: { level: 'priority', label: 'Priority support' },
export: { enabled: true, formats: ['csv', 'excel', 'pdf'], label: 'All export formats' },
discount: { value: '17%', label: 'Save 17% (2 months free)' },
},
badge: 'Best Value',
badgeColor: 'green',
highlightColor: '#10B981',
sortOrder: 3,
isActive: true,
isVisible: true,
isFeatured: true,
maxWallets: null,
maxGoals: null,
maxTeamMembers: 10,
apiEnabled: true,
apiRateLimit: 1000,
},
});
console.log('✅ Plans created:', [freePlan.name, proMonthly.name, proYearly.name]);
console.log('\n💳 Creating default payment methods...');
const bcaMethod = await prisma.paymentMethod.upsert({
where: { id: 'bca-method' },
update: {},
create: {
id: 'bca-method',
type: 'bank_transfer',
provider: 'BCA',
accountName: 'PT Tabungin Indonesia',
accountNumber: '1234567890',
displayName: 'BCA Virtual Account',
logoUrl: '/logos/bca.png',
instructions: 'Transfer to the account above and upload proof of payment.',
isActive: true,
sortOrder: 1,
},
});
const mandiriMethod = await prisma.paymentMethod.upsert({
where: { id: 'mandiri-method' },
update: {},
create: {
id: 'mandiri-method',
type: 'bank_transfer',
provider: 'Mandiri',
accountName: 'PT Tabungin Indonesia',
accountNumber: '9876543210',
displayName: 'Mandiri Virtual Account',
logoUrl: '/logos/mandiri.png',
instructions: 'Transfer to the account above and upload proof of payment.',
isActive: true,
sortOrder: 2,
},
});
const gopayMethod = await prisma.paymentMethod.upsert({
where: { id: 'gopay-method' },
update: {},
create: {
id: 'gopay-method',
type: 'e-wallet',
provider: 'GoPay',
accountName: 'Dwindi Ramadhana',
accountNumber: '081234567890',
displayName: 'GoPay',
logoUrl: '/logos/gopay.png',
instructions: 'Send payment to the number above and upload proof.',
isActive: true,
sortOrder: 3,
},
});
console.log('✅ Payment methods created:', [bcaMethod.displayName, mandiriMethod.displayName, gopayMethod.displayName]);
console.log('\n⚙ Creating app config...');
await prisma.appConfig.upsert({
where: { key: 'MAINTENANCE_MODE' },
update: {},
create: {
key: 'MAINTENANCE_MODE',
value: 'false',
category: 'general',
label: 'Maintenance Mode',
description: 'Enable to show maintenance page to users',
type: 'boolean',
isSecret: false,
},
});
console.log('✅ App config created');
console.log('\n🔧 Creating temp user (legacy)...');
const user = await prisma.user.upsert({
where: { id: TEMP_USER_ID },
update: {},
create: {
id: TEMP_USER_ID,
email: 'temp@example.com',
},
});
const existing = await prisma.wallet.findFirst({});
if (!existing) {
await prisma.wallet.create({
data: {
userId: user.id,
kind: 'money',
name: 'Cash',
currency: 'IDR',
},
});
}
console.log('✅ Temp user created:', user.id);
console.log('\n🎉 Seed complete!');
console.log('\n📋 Summary:');
console.log(' Admin Email:', ADMIN_EMAIL);
console.log(' Admin Password:', ADMIN_PASSWORD);
console.log(' Plans:', [freePlan.name, proMonthly.name, proYearly.name].join(', '));
console.log(' Payment Methods:', [bcaMethod.displayName, mandiriMethod.displayName, gopayMethod.displayName].join(', '));
console.log('\n⚠ IMPORTANT: Change admin password after first login!');
console.log('\n🔗 Login at: http://localhost:5174/auth/login');
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
//# sourceMappingURL=seed.js.map