feat: update seed data for Cabo Pickleball Club

- Organization: Cabo Pickleball Club, Mazatlan timezone
- Single site: Corridor Courts, Cabo San Lucas
- 6 outdoor courts at 300 MXN/person
- Admin: ivan@horuxfin.com
- 5 membership plans: Day Pass, 10-Day, 10-Morning, Monthly, Family
- Pickleball products replacing padel items

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Ivan
2026-03-01 21:29:16 +00:00
parent d3419a8cc5
commit 25b1495bb0

View File

@@ -40,12 +40,12 @@ async function main() {
const organization = await prisma.organization.create({ const organization = await prisma.organization.create({
data: { data: {
name: 'SmashPoint Demo', name: 'Cabo Pickleball Club',
slug: 'smashpoint-demo', slug: 'cabo-pickleball-club',
settings: { settings: {
currency: 'MXN', currency: 'MXN',
timezone: 'America/Mexico_City', timezone: 'America/Mazatlan',
language: 'es', language: 'en',
}, },
}, },
}); });
@@ -56,39 +56,19 @@ async function main() {
// ============================================================================= // =============================================================================
// SITES // SITES
// ============================================================================= // =============================================================================
console.log('Creating sites...'); console.log('Creating site...');
const sitesData = [ const sitesData = [
{ {
name: 'Sede Norte', name: 'Corridor Courts',
slug: 'sede-norte', slug: 'corridor-courts',
address: 'Av. Universidad 1000, Col. Del Valle', address: 'Corridor area, Cabo San Lucas, BCS',
phone: '+52 55 1234 5678', phone: '+52-624-151-5455',
email: 'norte@smashpoint.com', email: 'topdogcabo@yahoo.com',
timezone: 'America/Mexico_City', timezone: 'America/Mazatlan',
openTime: '07:00', openTime: '07:00',
closeTime: '23:00',
},
{
name: 'Sede Sur',
slug: 'sede-sur',
address: 'Av. Insurgentes 2000, Col. Roma',
phone: '+52 55 2345 6789',
email: 'sur@smashpoint.com',
timezone: 'America/Mexico_City',
openTime: '08:00',
closeTime: '22:00', closeTime: '22:00',
}, },
{
name: 'Sede Centro',
slug: 'sede-centro',
address: 'Calle Reforma 500, Centro Historico',
phone: '+52 55 3456 7890',
email: 'centro@smashpoint.com',
timezone: 'America/Mexico_City',
openTime: '06:00',
closeTime: '24:00',
},
]; ];
const sites = await Promise.all( const sites = await Promise.all(
@@ -107,44 +87,27 @@ async function main() {
console.log(''); console.log('');
// ============================================================================= // =============================================================================
// COURTS (2 per site) // COURTS (6 outdoor courts)
// ============================================================================= // =============================================================================
console.log('Creating courts...'); console.log('Creating courts...');
const courts: { id: string; name: string; siteId: string }[] = []; const courts: { id: string; name: string; siteId: string }[] = [];
for (const site of sites) { for (let i = 1; i <= 6; i++) {
const courtData = [ const created = await prisma.court.create({
{ data: {
name: 'Cancha 1', siteId: sites[0].id,
type: CourtType.INDOOR, name: `Court ${i}`,
type: CourtType.OUTDOOR,
status: CourtStatus.AVAILABLE, status: CourtStatus.AVAILABLE,
pricePerHour: 350, pricePerHour: 300,
description: 'Cancha techada con iluminacion LED', description: 'Outdoor court with night lighting',
features: ['Iluminacion LED', 'Techada', 'Cristal panoramico'], features: ['Night lighting', 'Court dividers'],
displayOrder: 1, displayOrder: i,
}, },
{ });
name: 'Cancha 2', courts.push(created);
type: CourtType.INDOOR, console.log(` Created court: ${created.name}`);
status: CourtStatus.AVAILABLE,
pricePerHour: 450,
description: 'Cancha premium con aire acondicionado',
features: ['Iluminacion LED', 'Techada', 'Aire acondicionado', 'Cristal panoramico', 'Premium'],
displayOrder: 2,
},
];
for (const court of courtData) {
const created = await prisma.court.create({
data: {
siteId: site.id,
...court,
},
});
courts.push(created);
console.log(` Created court: ${site.name} - ${created.name}`);
}
} }
console.log(''); console.log('');
@@ -152,17 +115,17 @@ async function main() {
// ============================================================================= // =============================================================================
// ADMIN USER (SUPER_ADMIN) // ADMIN USER (SUPER_ADMIN)
// ============================================================================= // =============================================================================
console.log('Creating admin users...'); console.log('Creating admin user...');
const hashedPassword = await bcrypt.hash('admin123', 10); const hashedPassword = await bcrypt.hash('Aasi940812', 10);
const adminUser = await prisma.user.create({ const adminUser = await prisma.user.create({
data: { data: {
organizationId: organization.id, organizationId: organization.id,
email: 'admin@smashpoint.com', email: 'ivan@horuxfin.com',
password: hashedPassword, password: hashedPassword,
firstName: 'Administrador', firstName: 'Ivan',
lastName: 'Sistema', lastName: 'Admin',
role: UserRole.SUPER_ADMIN, role: UserRole.SUPER_ADMIN,
phone: '+52 55 9999 0000', phone: '+52 55 9999 0000',
siteIds: sites.map(s => s.id), siteIds: sites.map(s => s.id),
@@ -171,41 +134,6 @@ async function main() {
console.log(` Created super admin: ${adminUser.email}`); console.log(` Created super admin: ${adminUser.email}`);
// =============================================================================
// SITE ADMINS (one per site)
// =============================================================================
const siteAdminsData = [
{ email: 'norte@smashpoint.com', firstName: 'Carlos', lastName: 'Rodriguez', site: sites[0] },
{ email: 'sur@smashpoint.com', firstName: 'Maria', lastName: 'Gonzalez', site: sites[1] },
{ email: 'centro@smashpoint.com', firstName: 'Luis', lastName: 'Hernandez', site: sites[2] },
];
for (const adminData of siteAdminsData) {
const siteAdmin = await prisma.user.create({
data: {
organizationId: organization.id,
email: adminData.email,
password: hashedPassword,
firstName: adminData.firstName,
lastName: adminData.lastName,
role: UserRole.SITE_ADMIN,
siteIds: [adminData.site.id],
},
});
// Connect user to site
await prisma.site.update({
where: { id: adminData.site.id },
data: {
users: {
connect: { id: siteAdmin.id },
},
},
});
console.log(` Created site admin: ${siteAdmin.email} (${adminData.site.name})`);
}
console.log(''); console.log('');
// ============================================================================= // =============================================================================
@@ -214,10 +142,10 @@ async function main() {
console.log('Creating product categories...'); console.log('Creating product categories...');
const categoriesData = [ const categoriesData = [
{ name: 'Bebidas', description: 'Bebidas y refrescos', displayOrder: 1 }, { name: 'Drinks', description: 'Beverages and refreshments', displayOrder: 1 },
{ name: 'Snacks', description: 'Botanas y snacks', displayOrder: 2 }, { name: 'Snacks', description: 'Snacks and light food', displayOrder: 2 },
{ name: 'Equipamiento', description: 'Equipo y accesorios de padel', displayOrder: 3 }, { name: 'Equipment', description: 'Pickleball equipment and accessories', displayOrder: 3 },
{ name: 'Alquiler', description: 'Articulos en renta', displayOrder: 4 }, { name: 'Rental', description: 'Rental items', displayOrder: 4 },
]; ];
const categories: { id: string; name: string }[] = []; const categories: { id: string; name: string }[] = [];
@@ -236,28 +164,24 @@ async function main() {
console.log(''); console.log('');
// ============================================================================= // =============================================================================
// PRODUCTS (for organization, shown in Sede Norte initially) // PRODUCTS
// ============================================================================= // =============================================================================
console.log('Creating products...'); console.log('Creating products...');
const bebidasCategory = categories.find(c => c.name === 'Bebidas'); const drinksCategory = categories.find(c => c.name === 'Drinks');
const snacksCategory = categories.find(c => c.name === 'Snacks'); const snacksCategory = categories.find(c => c.name === 'Snacks');
const equipamientoCategory = categories.find(c => c.name === 'Equipamiento'); const equipmentCategory = categories.find(c => c.name === 'Equipment');
const alquilerCategory = categories.find(c => c.name === 'Alquiler'); const rentalCategory = categories.find(c => c.name === 'Rental');
const productsData = [ const productsData = [
// Bebidas { name: 'Water', description: 'Natural water 600ml', price: 20, costPrice: 8, stock: 100, categoryId: drinksCategory?.id, sku: 'DRK-001' },
{ name: 'Agua', description: 'Agua natural 600ml', price: 20, costPrice: 8, stock: 100, categoryId: bebidasCategory?.id, sku: 'BEB-001' }, { name: 'Gatorade', description: 'Sports drink 500ml', price: 35, costPrice: 18, stock: 50, categoryId: drinksCategory?.id, sku: 'DRK-002' },
{ name: 'Gatorade', description: 'Bebida deportiva 500ml', price: 35, costPrice: 18, stock: 50, categoryId: bebidasCategory?.id, sku: 'BEB-002' }, { name: 'Beer', description: 'Craft beer 355ml', price: 45, costPrice: 22, stock: 48, categoryId: drinksCategory?.id, sku: 'DRK-003' },
{ name: 'Cerveza', description: 'Cerveza artesanal 355ml', price: 45, costPrice: 22, stock: 48, categoryId: bebidasCategory?.id, sku: 'BEB-003' }, { name: 'Chips', description: 'Potato chips 45g', price: 25, costPrice: 12, stock: 30, categoryId: snacksCategory?.id, sku: 'SNK-001' },
// Snacks { name: 'Energy Bar', description: 'Protein bar 50g', price: 30, costPrice: 15, stock: 25, categoryId: snacksCategory?.id, sku: 'SNK-002' },
{ name: 'Papas', description: 'Papas fritas 45g', price: 25, costPrice: 12, stock: 30, categoryId: snacksCategory?.id, sku: 'SNK-001' }, { name: 'Pickleballs', description: 'Franklin X-40 Outdoor (3 pack)', price: 180, costPrice: 90, stock: 20, categoryId: equipmentCategory?.id, sku: 'EQP-001' },
{ name: 'Barra energetica', description: 'Barra de proteina 50g', price: 30, costPrice: 15, stock: 25, categoryId: snacksCategory?.id, sku: 'SNK-002' }, { name: 'Paddle Grip', description: 'Replacement grip', price: 50, costPrice: 25, stock: 40, categoryId: equipmentCategory?.id, sku: 'EQP-002' },
// Equipamiento { name: 'Paddle Rental', description: 'Pickleball paddle rental (per session)', price: 100, costPrice: 0, stock: 10, categoryId: rentalCategory?.id, sku: 'RNT-001', trackStock: false },
{ name: 'Pelotas HEAD', description: 'Tubo de 3 pelotas HEAD Pro', price: 180, costPrice: 90, stock: 20, categoryId: equipamientoCategory?.id, sku: 'EQP-001' },
{ name: 'Grip', description: 'Overgrip Wilson Pro', price: 50, costPrice: 25, stock: 40, categoryId: equipamientoCategory?.id, sku: 'EQP-002' },
// Alquiler
{ name: 'Raqueta alquiler', description: 'Raqueta de padel (por hora)', price: 100, costPrice: 0, stock: 10, categoryId: alquilerCategory?.id, sku: 'ALQ-001', trackStock: false },
]; ];
for (const productData of productsData) { for (const productData of productsData) {
@@ -279,31 +203,49 @@ async function main() {
const membershipPlansData = [ const membershipPlansData = [
{ {
name: 'Basico', name: 'Day Pass',
description: 'Plan basico mensual con beneficios esenciales', description: 'Single day access to all courts',
price: 499, price: 300,
durationMonths: 1, durationMonths: 1,
courtHours: 2, courtHours: 0,
discountPercent: 10, discountPercent: 0,
benefits: ['2 horas gratis de cancha al mes', '10% descuento en reservas', '5% descuento en tienda'], benefits: ['Full day access', 'All courts', 'Night play included'],
}, },
{ {
name: 'Premium', name: '10-Day Pass',
description: 'Plan premium con mayores beneficios', description: '10 visits, any time of day',
price: 899, price: 2500,
durationMonths: 1, durationMonths: 3,
courtHours: 5,
discountPercent: 20,
benefits: ['5 horas gratis de cancha al mes', '20% descuento en reservas', '10% descuento en tienda', 'Acceso prioritario a torneos'],
},
{
name: 'VIP',
description: 'Plan VIP con todos los beneficios',
price: 1499,
durationMonths: 1,
courtHours: 10, courtHours: 10,
discountPercent: 15,
benefits: ['10 day passes', 'Valid any time', 'Save vs single day pass'],
},
{
name: '10-Morning Pass',
description: '10 morning sessions (7am-12pm)',
price: 2000,
durationMonths: 3,
courtHours: 10,
discountPercent: 10,
benefits: ['10 morning passes', '7:00 AM - 12:00 PM only', 'Best value for morning players'],
},
{
name: 'Monthly Individual',
description: 'Unlimited monthly access for one player',
price: 4000,
durationMonths: 1,
courtHours: 30,
discountPercent: 25,
benefits: ['Unlimited court access', 'Priority booking', 'All time slots'],
},
{
name: 'Monthly Family',
description: 'Unlimited monthly access for up to 4 family members',
price: 6500,
durationMonths: 1,
courtHours: 60,
discountPercent: 30, discountPercent: 30,
benefits: ['10 horas gratis de cancha al mes', '30% descuento en reservas', '15% descuento en tienda', 'Acceso prioritario a torneos', 'Invitados con descuento', 'Casillero incluido'], benefits: ['Up to 4 family members', 'Unlimited court access', 'Priority booking', 'All time slots'],
}, },
]; ];
@@ -317,7 +259,7 @@ async function main() {
}, },
}); });
membershipPlans.push(plan); membershipPlans.push(plan);
console.log(` Created membership plan: ${plan.name} - $${plan.price}/mes`); console.log(` Created membership plan: ${plan.name} - $${plan.price}`);
} }
console.log(''); console.log('');
@@ -386,31 +328,31 @@ async function main() {
console.log(''); console.log('');
// ============================================================================= // =============================================================================
// MEMBERSHIP FOR ONE CLIENT (Maria Garcia with Premium) // MEMBERSHIP FOR ONE CLIENT (Maria Garcia with Monthly Individual)
// ============================================================================= // =============================================================================
console.log('Creating sample membership...'); console.log('Creating sample membership...');
const premiumPlan = membershipPlans.find(p => p.name === 'Premium'); const monthlyPlan = membershipPlans.find(p => p.name === 'Monthly Individual');
const mariaClient = clients.find(c => c.firstName === 'Maria'); const mariaClient = clients.find(c => c.firstName === 'Maria');
if (premiumPlan && mariaClient) { if (monthlyPlan && mariaClient) {
const startDate = new Date(); const startDate = new Date();
const endDate = new Date(); const endDate = new Date();
endDate.setMonth(endDate.getMonth() + 1); endDate.setMonth(endDate.getMonth() + 1);
const membership = await prisma.membership.create({ const membership = await prisma.membership.create({
data: { data: {
planId: premiumPlan.id, planId: monthlyPlan.id,
clientId: mariaClient.id, clientId: mariaClient.id,
startDate, startDate,
endDate, endDate,
status: MembershipStatus.ACTIVE, status: MembershipStatus.ACTIVE,
remainingHours: premiumPlan.courtHours, remainingHours: monthlyPlan.courtHours,
autoRenew: true, autoRenew: true,
}, },
}); });
console.log(` Created Premium membership for ${mariaClient.firstName} ${mariaClient.lastName}`); console.log(` Created Monthly Individual membership for ${mariaClient.firstName} ${mariaClient.lastName}`);
} }
console.log(''); console.log('');
@@ -424,9 +366,9 @@ async function main() {
console.log(''); console.log('');
console.log('Summary:'); console.log('Summary:');
console.log(` - 1 Organization: ${organization.name}`); console.log(` - 1 Organization: ${organization.name}`);
console.log(` - ${sites.length} Sites`); console.log(` - ${sites.length} Site`);
console.log(` - ${courts.length} Courts (${courts.length / sites.length} per site)`); console.log(` - ${courts.length} Courts`);
console.log(` - 4 Users (1 super admin + 3 site admins)`); console.log(` - 1 Admin user`);
console.log(` - ${categories.length} Product Categories`); console.log(` - ${categories.length} Product Categories`);
console.log(` - ${productsData.length} Products`); console.log(` - ${productsData.length} Products`);
console.log(` - ${membershipPlans.length} Membership Plans`); console.log(` - ${membershipPlans.length} Membership Plans`);
@@ -434,8 +376,7 @@ async function main() {
console.log(` - 1 Active Membership`); console.log(` - 1 Active Membership`);
console.log(''); console.log('');
console.log('Login credentials:'); console.log('Login credentials:');
console.log(' Super Admin: admin@smashpoint.com / admin123'); console.log(' Admin: ivan@horuxfin.com / Aasi940812');
console.log(' Site Admins: norte@smashpoint.com, sur@smashpoint.com, centro@smashpoint.com / admin123');
console.log(''); console.log('');
} }