Implementados 4 módulos con agent swarm: 1. MERCADOPAGO INTEGRADO - SDK oficial de MercadoPago - Crear preferencias de pago - Webhooks para notificaciones - Reembolsos y cancelaciones - Estados: PENDING, PROCESSING, COMPLETED, REFUNDED 2. SISTEMA DE BONOS Y PACKS - Pack 5, Pack 10, Pack Mensual - Compra online con MP - Uso FIFO automático - Control de expiración - Aplicación en reservas 3. SUSCRIPCIONES/MEMBRESÍAS - Planes: Básico, Premium, Anual VIP - Beneficios: descuentos, reservas gratis, prioridad - Cobro recurrente vía MP - Estados: ACTIVE, PAUSED, CANCELLED - Aplicación automática en reservas 4. CLASES CON PROFESORES - Registro de coaches con verificación - Tipos: Individual, Grupal, Clínica - Horarios y disponibilidad - Reservas con pago integrado - Sistema de reseñas Endpoints nuevos: - /payments/* - Pagos MercadoPago - /bonus-packs/*, /bonuses/* - Bonos - /subscription-plans/*, /subscriptions/* - Suscripciones - /coaches/* - Profesores - /classes/*, /class-enrollments/* - Clases Variables de entorno: - MERCADOPAGO_ACCESS_TOKEN - MERCADOPAGO_PUBLIC_KEY - MERCADOPAGO_WEBHOOK_SECRET Datos de prueba: - 3 Bonus Packs - 3 Planes de suscripción - 1 Coach verificado (admin) - 3 Clases disponibles
160 lines
5.0 KiB
TypeScript
160 lines
5.0 KiB
TypeScript
import { PrismaClient } from '@prisma/client';
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
async function main() {
|
|
console.log('🌱 Seeding Fase 4 - Pagos y Monetización...\n');
|
|
|
|
const admin = await prisma.user.findUnique({ where: { email: 'admin@padel.com' } });
|
|
const user = await prisma.user.findUnique({ where: { email: 'user@padel.com' } });
|
|
|
|
if (!admin || !user) {
|
|
console.log('❌ Usuarios no encontrados. Ejecuta seed.ts primero.');
|
|
return;
|
|
}
|
|
|
|
// Crear Bonus Packs
|
|
const bonusPacks = [
|
|
{ name: 'Pack 5 Clases', bookings: 5, price: 9000, validity: 90 },
|
|
{ name: 'Pack 10 Clases', bookings: 10, price: 16000, validity: 180 },
|
|
{ name: 'Pack Mensual', bookings: 30, price: 40000, validity: 30 },
|
|
];
|
|
|
|
for (const pack of bonusPacks) {
|
|
await prisma.bonusPack.upsert({
|
|
where: { id: `bonus-${pack.bookings}` },
|
|
update: {},
|
|
create: {
|
|
id: `bonus-${pack.bookings}`,
|
|
name: pack.name,
|
|
description: `${pack.bookings} reservas de 1 hora cada una`,
|
|
numberOfBookings: pack.bookings,
|
|
price: pack.price,
|
|
validityDays: pack.validity,
|
|
isActive: true,
|
|
},
|
|
});
|
|
console.log(`✅ Bonus Pack creado: ${pack.name}`);
|
|
}
|
|
|
|
// Crear planes de suscripción
|
|
const plans = [
|
|
{
|
|
name: 'Básico',
|
|
type: 'MONTHLY',
|
|
price: 15000,
|
|
benefits: { discountPercentage: 10, freeBookingsPerMonth: 2, priorityBooking: false, tournamentDiscount: 5 },
|
|
desc: '10% off en reservas, 2 reservas gratis/mes'
|
|
},
|
|
{
|
|
name: 'Premium',
|
|
type: 'MONTHLY',
|
|
price: 25000,
|
|
benefits: { discountPercentage: 20, freeBookingsPerMonth: 5, priorityBooking: true, tournamentDiscount: 10 },
|
|
desc: '20% off en reservas, 5 reservas gratis/mes, prioridad'
|
|
},
|
|
{
|
|
name: 'Anual VIP',
|
|
type: 'YEARLY',
|
|
price: 250000,
|
|
benefits: { discountPercentage: 30, freeBookingsPerMonth: 10, priorityBooking: true, tournamentDiscount: 15 },
|
|
desc: '30% off en reservas, 10 reservas gratis/mes'
|
|
},
|
|
];
|
|
|
|
for (const plan of plans) {
|
|
await prisma.subscriptionPlan.upsert({
|
|
where: { id: `plan-${plan.name.toLowerCase().replace(/ /g, '-')}` },
|
|
update: {},
|
|
create: {
|
|
id: `plan-${plan.name.toLowerCase().replace(/ /g, '-')}`,
|
|
name: plan.name,
|
|
description: plan.desc,
|
|
type: plan.type,
|
|
price: plan.price,
|
|
benefits: JSON.stringify(plan.benefits),
|
|
features: JSON.stringify([`${plan.benefits.discountPercentage}% descuento`, `${plan.benefits.freeBookingsPerMonth} reservas gratis`, plan.benefits.priorityBooking ? 'Prioridad de reserva' : 'Sin prioridad']),
|
|
isActive: true,
|
|
},
|
|
});
|
|
console.log(`✅ Plan de suscripción creado: ${plan.name}`);
|
|
}
|
|
|
|
// Registrar usuario como coach
|
|
const coach = await prisma.coach.upsert({
|
|
where: { id: 'coach-1' },
|
|
update: {},
|
|
create: {
|
|
id: 'coach-1',
|
|
userId: admin.id,
|
|
bio: 'Profesor de pádel con 10 años de experiencia. Especialista en técnica y táctica.',
|
|
specialties: JSON.stringify(['Técnica', 'Táctica', 'Volea', 'Smash']),
|
|
certifications: 'Entrenador Nacional Nivel 3',
|
|
yearsExperience: 10,
|
|
hourlyRate: 5000,
|
|
isActive: true,
|
|
isVerified: true,
|
|
},
|
|
});
|
|
console.log(`✅ Coach creado: ${coach.id}`);
|
|
|
|
// Crear disponibilidad del coach
|
|
for (let day = 1; day <= 5; day++) { // Lunes a Viernes
|
|
await prisma.coachAvailability.upsert({
|
|
where: { id: `avail-${coach.id}-${day}` },
|
|
update: {},
|
|
create: {
|
|
id: `avail-${coach.id}-${day}`,
|
|
coachId: coach.id,
|
|
dayOfWeek: day,
|
|
startTime: '09:00',
|
|
endTime: '18:00',
|
|
isAvailable: true,
|
|
},
|
|
});
|
|
}
|
|
console.log('✅ Disponibilidad del coach creada');
|
|
|
|
// Crear clases
|
|
const classes = [
|
|
{ name: 'Clase Individual', type: 'INDIVIDUAL', max: 1, price: 5000, duration: 60 },
|
|
{ name: 'Clase en Pareja', type: 'GROUP', max: 2, price: 3500, duration: 60 },
|
|
{ name: 'Clínica de Volea', type: 'CLINIC', max: 8, price: 2000, duration: 90 },
|
|
];
|
|
|
|
for (const cls of classes) {
|
|
await prisma.class.upsert({
|
|
where: { id: `class-${cls.name.toLowerCase().replace(/ /g, '-')}` },
|
|
update: {},
|
|
create: {
|
|
id: `class-${cls.name.toLowerCase().replace(/ /g, '-')}`,
|
|
coachId: coach.id,
|
|
title: cls.name,
|
|
description: `Clase especializada de ${cls.name.toLowerCase()}`,
|
|
type: cls.type,
|
|
maxStudents: cls.max,
|
|
price: cls.price,
|
|
duration: cls.duration,
|
|
isActive: true,
|
|
},
|
|
});
|
|
console.log(`✅ Clase creada: ${cls.name}`);
|
|
}
|
|
|
|
console.log('\n🎾 Fase 4 seed completado!');
|
|
console.log('\nDatos creados:');
|
|
console.log(` - 3 Bonus Packs`);
|
|
console.log(` - 3 Planes de suscripción`);
|
|
console.log(` - 1 Coach verificado`);
|
|
console.log(` - 3 Clases disponibles`);
|
|
}
|
|
|
|
main()
|
|
.catch((e) => {
|
|
console.error(e);
|
|
process.exit(1);
|
|
})
|
|
.finally(async () => {
|
|
await prisma.$disconnect();
|
|
});
|