FASE 2 COMPLETADA: Perfiles, Social y Ranking

Implementados 3 módulos principales:

1. PERFILES EXTENDIDOS
   - Campos adicionales: ciudad, fecha nacimiento, años jugando
   - Estadísticas: partidos jugados/ganados/perdidos
   - Historial de cambios de nivel
   - Búsqueda de usuarios con filtros

2. SISTEMA SOCIAL
   - Amigos: solicitudes, aceptar, rechazar, bloquear
   - Grupos: crear, gestionar miembros, roles
   - Reservas recurrentes: fijos semanales

3. RANKING Y ESTADÍSTICAS
   - Registro de partidos 2v2 con confirmación
   - Sistema de puntos con bonus y multiplicadores
   - Ranking mensual, anual y global
   - Estadísticas personales y globales

Nuevos endpoints:
- /users/* - Perfiles y búsqueda
- /friends/* - Gestión de amistades
- /groups/* - Grupos de jugadores
- /recurring/* - Reservas recurrentes
- /matches/* - Registro de partidos
- /ranking/* - Clasificaciones
- /stats/* - Estadísticas

Nuevos usuarios de prueba:
- carlos@padel.com / 123456
- ana@padel.com / 123456
- pedro@padel.com / 123456
- maria@padel.com / 123456
This commit is contained in:
2026-01-31 08:22:41 +00:00
parent b558372810
commit e20c5b956b
34 changed files with 6081 additions and 15 deletions

View File

@@ -0,0 +1,192 @@
import { PrismaClient } from '@prisma/client';
import { hashPassword } from '../src/utils/password';
import { UserRole, PlayerLevel, FriendStatus, GroupRole, CourtType } from '../src/utils/constants';
const prisma = new PrismaClient();
async function main() {
console.log('🌱 Seeding Fase 2 data...\n');
// Crear jugadores adicionales para pruebas sociales
const usersData = [
{ email: 'carlos@padel.com', firstName: 'Carlos', lastName: 'Martínez', level: PlayerLevel.ADVANCED },
{ email: 'ana@padel.com', firstName: 'Ana', lastName: 'López', level: PlayerLevel.INTERMEDIATE },
{ email: 'pedro@padel.com', firstName: 'Pedro', lastName: 'Sánchez', level: PlayerLevel.BEGINNER },
{ email: 'maria@padel.com', firstName: 'María', lastName: 'García', level: PlayerLevel.COMPETITION },
];
const createdUsers = [];
for (const userData of usersData) {
const password = await hashPassword('123456');
const user = await prisma.user.upsert({
where: { email: userData.email },
update: {},
create: {
email: userData.email,
password,
firstName: userData.firstName,
lastName: userData.lastName,
role: UserRole.PLAYER,
playerLevel: userData.level,
city: 'Madrid',
yearsPlaying: Math.floor(Math.random() * 10) + 1,
matchesPlayed: Math.floor(Math.random() * 50),
matchesWon: Math.floor(Math.random() * 30),
isActive: true,
},
});
createdUsers.push(user);
console.log(`✅ Usuario creado: ${user.firstName} ${user.lastName} (${user.email})`);
}
// Obtener el admin y user original
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 && createdUsers.length >= 2) {
// Crear relaciones de amistad
const friendships = [
{ requester: user.id, addressee: createdUsers[0].id }, // Juan - Carlos
{ requester: createdUsers[1].id, addressee: user.id }, // Ana - Juan (pendiente)
{ requester: user.id, addressee: createdUsers[2].id }, // Juan - Pedro
];
for (const friendship of friendships) {
await prisma.friend.upsert({
where: {
requesterId_addresseeId: {
requesterId: friendship.requester,
addresseeId: friendship.addressee,
},
},
update: {},
create: {
requesterId: friendship.requester,
addresseeId: friendship.addressee,
status: FriendStatus.ACCEPTED,
},
});
}
console.log('\n✅ Amistades creadas');
// Crear un grupo
const group = await prisma.group.upsert({
where: { id: 'group-1' },
update: {},
create: {
id: 'group-1',
name: 'Los Padelistas',
description: 'Grupo de jugadores regulares los fines de semana',
createdBy: admin.id,
members: {
create: [
{ userId: admin.id, role: GroupRole.ADMIN },
{ userId: user.id, role: GroupRole.MEMBER },
{ userId: createdUsers[0].id, role: GroupRole.MEMBER },
{ userId: createdUsers[1].id, role: GroupRole.MEMBER },
],
},
},
});
console.log(`✅ Grupo creado: ${group.name}`);
// Crear reserva recurrente
const court = await prisma.court.findFirst({ where: { isActive: true } });
if (court) {
const recurring = await prisma.recurringBooking.create({
data: {
userId: user.id,
courtId: court.id,
dayOfWeek: 6, // Sábado
startTime: '10:00',
endTime: '12:00',
startDate: new Date(),
isActive: true,
},
});
console.log(`✅ Reserva recurrente creada: Sábados ${recurring.startTime}-${recurring.endTime}`);
}
// Registrar algunos partidos
const matchResults = [
{
team1: [user.id, createdUsers[0].id],
team2: [createdUsers[1].id, createdUsers[2].id],
score1: 6,
score2: 4,
playedAt: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000), // Hace 1 semana
},
{
team1: [user.id, createdUsers[1].id],
team2: [createdUsers[0].id, createdUsers[2].id],
score1: 3,
score2: 6,
playedAt: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000), // Hace 3 días
},
];
for (const match of matchResults) {
await prisma.matchResult.create({
data: {
team1Player1Id: match.team1[0],
team1Player2Id: match.team1[1],
team2Player1Id: match.team2[0],
team2Player2Id: match.team2[1],
team1Score: match.score1,
team2Score: match.score2,
winner: match.score1 > match.score2 ? 'TEAM1' : 'TEAM2',
playedAt: match.playedAt,
confirmedBy: [match.team1[0], match.team2[0]],
},
});
}
console.log(`✅ Partidos registrados: ${matchResults.length}`);
// Crear estadísticas de usuario
for (const u of [user, ...createdUsers.slice(0, 2)]) {
await prisma.userStats.upsert({
where: {
userId_period_periodValue: {
userId: u.id,
period: 'ALL_TIME',
periodValue: 'all',
},
},
update: {},
create: {
userId: u.id,
period: 'ALL_TIME',
periodValue: 'all',
matchesPlayed: Math.floor(Math.random() * 30) + 5,
matchesWon: Math.floor(Math.random() * 20),
matchesLost: Math.floor(Math.random() * 10),
points: Math.floor(Math.random() * 500) + 100,
},
});
}
console.log(`✅ Estadísticas de usuarios creadas`);
}
// Actualizar puntos totales de usuarios
await prisma.user.updateMany({
data: {
totalPoints: { increment: 100 },
},
});
console.log('\n🎾 Fase 2 seed completado!');
console.log('\nNuevos usuarios de prueba:');
console.log(' carlos@padel.com / 123456');
console.log(' ana@padel.com / 123456');
console.log(' pedro@padel.com / 123456');
console.log(' maria@padel.com / 123456');
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});