Function bodies 439 total
generarJugadores function · typescript · L37-L77 (41 LOC)prisma/seed-test-players.ts
function generarJugadores() {
const jugadores: {
documento: string;
nombre: string;
apellido: string;
genero: 'MASCULINO' | 'FEMENINO';
email: string;
telefono: string;
ciudad: string;
}[] = [];
// 48 hombres (docs 2000001-2000048)
for (let i = 0; i < 48; i++) {
const doc = `${2000001 + i}`;
jugadores.push({
documento: doc,
nombre: nombresM[i],
apellido: apellidos[i],
genero: 'MASCULINO',
email: `jugador.m${i + 1}@test.com`,
telefono: `+5959820${String(i + 1).padStart(5, '0')}`,
ciudad: ciudades[i % ciudades.length],
});
}
// 48 mujeres (docs 3000001-3000048)
for (let i = 0; i < 48; i++) {
const doc = `${3000001 + i}`;
jugadores.push({
documento: doc,
nombre: nombresF[i],
apellido: apellidos[i],
genero: 'FEMENINO',
email: `jugadora.f${i + 1}@test.com`,
telefono: `+5959830${String(i + 1).padStart(5, '0')}`,
ciudad: ciudades[i % ciudades.lenginscribirParejas function · typescript · L218-L286 (69 LOC)prisma/seed-test-players.ts
async function inscribirParejas(
players: any[],
startIdx: number,
categoryId: string,
targetPairs: number,
) {
let created = 0;
for (let i = startIdx; i < players.length - 1 && created < targetPairs; i += 2) {
const j1 = players[i];
const j2 = players[i + 1];
// Verificar si ya existe pareja inscrita en esta categoría del torneo
const existingInscripcion = await prisma.inscripcion.findFirst({
where: {
tournamentId: torneo.id,
categoryId,
pareja: {
OR: [
{ jugador1Id: j1.id, jugador2Id: j2.id },
{ jugador1Id: j2.id, jugador2Id: j1.id },
],
},
},
});
if (existingInscripcion) {
created++;
continue;
}
const pareja = await prisma.pareja.create({
data: {
jugador1Id: j1.id,
jugador2Id: j2.id,
jugador2Documento: j2.documento,
},
});
cmain function · typescript · L124-L284 (161 LOC)prisma/seed-torneo-masivo.ts
async function main() {
const tournamentId = process.argv[2];
if (!tournamentId) {
console.error('❌ Uso: npx ts-node prisma/seed-torneo-masivo.ts <tournamentId>');
process.exit(1);
}
// ── 1. Fetch tournament + categories ──
const torneo = await prisma.tournament.findUnique({
where: { id: tournamentId },
include: {
categorias: { include: { category: true } },
modalidades: true,
},
});
if (!torneo) {
console.error(`❌ Torneo "${tournamentId}" no encontrado`);
process.exit(1);
}
console.log(`\n🏆 Torneo: "${torneo.nombre}" (${torneo.estado})`);
console.log(` Categorías: ${torneo.categorias.length}`);
// Map category name patterns to TournamentCategory IDs
const catMap: Record<string, { tcId: string; catId: string; catName: string }> = {};
for (const tc of torneo.categorias) {
const name = tc.category.nombre.toLowerCase();
catMap[`${tc.category.tipo}_${name}`] = {
tcId: tc.id,
catId: tc.categoryId,
findCat function · typescript · L160-L169 (10 LOC)prisma/seed-torneo-masivo.ts
function findCat(genero: 'MASCULINO' | 'FEMENINO', shortName: string) {
// shortName = "8va", "7ma", "6ta", "5ta", "4ta", "3ra", "2da", "1ra"
const entries = Object.entries(catMap);
for (const [key, val] of entries) {
if (key.startsWith(genero) && val.catName.toLowerCase().includes(shortName.toLowerCase())) {
return val;
}
}
return null;
}createPlayers function · typescript · L288-L295 (8 LOC)prisma/seed-torneo-masivo.ts
async function createPlayers(
count: number,
genero: 'MASCULINO' | 'FEMENINO',
docStart: number,
namePool: string[],
passwordHash: string,
roleId: string,
): Promise<{ id: string; documento: string }[]> {createPairsAndInscribe function · typescript · L335-L414 (80 LOC)prisma/seed-torneo-masivo.ts
async function createPairsAndInscribe(
players: { id: string; documento: string }[],
startIdx: number,
targetPairs: number,
tournamentId: string,
categoryId: string,
modalidad: string,
monto: number,
comision: number,
): Promise<number> {
let created = 0;
for (let i = 0; i < targetPairs; i++) {
const p1 = players[startIdx + i * 2];
const p2 = players[startIdx + i * 2 + 1];
if (!p1 || !p2) {
console.error(` ⚠️ No hay suficientes jugadores (necesitaba índice ${startIdx + i * 2 + 1})`);
break;
}
// Check duplicate
const existing = await prisma.inscripcion.findFirst({
where: {
tournamentId,
categoryId,
pareja: {
OR: [
{ jugador1Id: p1.id, jugador2Id: p2.id },
{ jugador1Id: p2.id, jugador2Id: p1.id },
],
},
},
});
if (existing) {
created++;
continue;
}
const pareja = await prisma.pareja.create({
data: {
AdminController.obtenerUsuarios method · typescript · L88-L93 (6 LOC)src/admin/admin.controller.ts
obtenerUsuarios(
@Query('search') search?: string,
@Query('estado') estado?: string,
) {
return this.adminService.obtenerUsuarios(search, estado);
}Repobility · severity-and-effort ranking · https://repobility.com
AdminController.obtenerUsuariosPremium method · typescript · L216-L221 (6 LOC)src/admin/admin.controller.ts
obtenerUsuariosPremium(
@Query('search') search?: string,
@Query('estado') estado?: string,
) {
return this.adminService.obtenerUsuariosPremium(search, estado);
}AdminController.seedTestData method · typescript · L277-L282 (6 LOC)src/admin/admin.controller.ts
seedTestData(
@Param('id') id: string,
@Body() dto: SeedTestDataDto,
) {
return this.adminService.seedTestData(id, dto.parejasPorCategoria);
}AdminService.obtenerTorneosPendientes method · typescript · L21-L49 (29 LOC)src/admin/admin.service.ts
async obtenerTorneosPendientes() {
const torneos = await this.prisma.tournament.findMany({
where: {
estado: 'PENDIENTE_APROBACION',
},
include: {
organizador: {
select: {
id: true,
nombre: true,
apellido: true,
email: true,
telefono: true,
},
},
categorias: {
include: {
category: true,
},
},
modalidades: true,
},
orderBy: {
createdAt: 'desc',
},
});
return torneos;
}AdminService.aprobarTorneo method · typescript · L51-L70 (20 LOC)src/admin/admin.service.ts
async aprobarTorneo(id: string) {
const torneo = await this.prisma.tournament.findUnique({
where: { id },
});
if (!torneo) {
throw new NotFoundException('Torneo no encontrado');
}
await this.prisma.tournament.update({
where: { id },
data: {
estado: 'PUBLICADO',
},
});
// TODO: Notificar al organizador
return { message: 'Torneo aprobado' };
}AdminService.rechazarTorneo method · typescript · L72-L91 (20 LOC)src/admin/admin.service.ts
async rechazarTorneo(id: string, motivo: string) {
const torneo = await this.prisma.tournament.findUnique({
where: { id },
});
if (!torneo) {
throw new NotFoundException('Torneo no encontrado');
}
await this.prisma.tournament.update({
where: { id },
data: {
estado: 'RECHAZADO',
},
});
// TODO: Notificar al organizador con el motivo
return { message: 'Torneo rechazado' };
}AdminService.obtenerSolicitudesOrganizador method · typescript · L95-L121 (27 LOC)src/admin/admin.service.ts
async obtenerSolicitudesOrganizador(estado?: string) {
const where: any = {};
if (estado) {
where.estado = estado;
}
const solicitudes = await this.prisma.solicitudOrganizador.findMany({
where,
include: {
user: {
select: {
id: true,
nombre: true,
apellido: true,
email: true,
telefono: true,
ciudad: true,
},
},
},
orderBy: {
createdAt: 'desc',
},
});
return solicitudes;
}AdminService.aprobarSolicitudOrganizador method · typescript · L123-L159 (37 LOC)src/admin/admin.service.ts
async aprobarSolicitudOrganizador(id: string) {
const solicitud = await this.prisma.solicitudOrganizador.findUnique({
where: { id },
include: { user: true },
});
if (!solicitud) {
throw new NotFoundException('Solicitud no encontrada');
}
// Buscar rol de organizador
const rolOrganizador = await this.prisma.role.findUnique({
where: { nombre: 'organizador' },
});
if (!rolOrganizador) {
throw new NotFoundException('Rol organizador no encontrado');
}
// Asignar rol
await this.prisma.userRole.create({
data: {
userId: solicitud.userId,
roleId: rolOrganizador.id,
},
});
// Actualizar solicitud
await this.prisma.solicitudOrganizador.update({
where: { id },
data: { estado: 'APROBADA' },
});
// TODO: Notificar al usuario
return { message: 'Solicitud aprobada' };
}AdminService.rechazarSolicitudOrganizador method · typescript · L161-L181 (21 LOC)src/admin/admin.service.ts
async rechazarSolicitudOrganizador(id: string, motivo: string) {
const solicitud = await this.prisma.solicitudOrganizador.findUnique({
where: { id },
});
if (!solicitud) {
throw new NotFoundException('Solicitud no encontrada');
}
await this.prisma.solicitudOrganizador.update({
where: { id },
data: {
estado: 'RECHAZADA',
motivo,
},
});
// TODO: Notificar al usuario con el motivo
return { message: 'Solicitud rechazada' };
}If a scraper extracted this row, it came from Repobility (https://repobility.com)
AdminService.obtenerFotosModeracion method · typescript · L185-L212 (28 LOC)src/admin/admin.service.ts
async obtenerFotosModeracion() {
const fotos = await this.prisma.foto.findMany({
where: {
estadoModeracion: 'PENDIENTE',
},
include: {
user: {
select: {
id: true,
nombre: true,
apellido: true,
email: true,
},
},
tournament: {
select: {
id: true,
nombre: true,
},
},
},
orderBy: {
createdAt: 'desc',
},
});
return fotos;
}AdminService.aprobarFoto method · typescript · L214-L231 (18 LOC)src/admin/admin.service.ts
async aprobarFoto(id: string) {
const foto = await this.prisma.foto.findUnique({
where: { id },
});
if (!foto) {
throw new NotFoundException('Foto no encontrada');
}
await this.prisma.foto.update({
where: { id },
data: {
estadoModeracion: 'APROBADA',
},
});
return { message: 'Foto aprobada' };
}AdminService.eliminarFotoInapropiada method · typescript · L233-L262 (30 LOC)src/admin/admin.service.ts
async eliminarFotoInapropiada(id: string, motivo: string) {
const foto = await this.prisma.foto.findUnique({
where: { id },
});
if (!foto) {
throw new NotFoundException('Foto no encontrada');
}
await this.prisma.foto.update({
where: { id },
data: {
estadoModeracion: 'RECHAZADA',
},
});
// Crear registro en moderación
await this.prisma.fotoPerfilModeracion.create({
data: {
userId: foto.userId,
fotoUrl: foto.urlImagen,
estado: 'RECHAZADA',
motivoRechazo: motivo,
},
});
// TODO: Notificar al usuario
return { message: 'Foto eliminada' };
}AdminService.obtenerUsuarios method · typescript · L266-L303 (38 LOC)src/admin/admin.service.ts
async obtenerUsuarios(search?: string, estado?: string) {
const where: any = {};
if (search) {
where.OR = [
{ nombre: { contains: search, mode: 'insensitive' } },
{ apellido: { contains: search, mode: 'insensitive' } },
{ email: { contains: search, mode: 'insensitive' } },
{ documento: { contains: search } },
];
}
if (estado) {
where.estado = estado;
}
const usuarios = await this.prisma.user.findMany({
where,
select: {
id: true,
nombre: true,
apellido: true,
documento: true,
email: true,
telefono: true,
ciudad: true,
estado: true,
esPremium: true,
createdAt: true,
},
orderBy: {
createdAt: 'desc',
},
take: 100,
});
return usuarios;
}AdminService.suspenderUsuario method · typescript · L305-L322 (18 LOC)src/admin/admin.service.ts
async suspenderUsuario(id: string, motivo: string) {
const usuario = await this.prisma.user.findUnique({
where: { id },
});
if (!usuario) {
throw new NotFoundException('Usuario no encontrado');
}
await this.prisma.user.update({
where: { id },
data: { estado: 'SUSPENDIDO' },
});
// TODO: Notificar al usuario con el motivo
return { message: 'Usuario suspendido' };
}AdminService.activarUsuario method · typescript · L324-L339 (16 LOC)src/admin/admin.service.ts
async activarUsuario(id: string) {
const usuario = await this.prisma.user.findUnique({
where: { id },
});
if (!usuario) {
throw new NotFoundException('Usuario no encontrado');
}
await this.prisma.user.update({
where: { id },
data: { estado: 'ACTIVO' },
});
return { message: 'Usuario activado' };
}AdminService.obtenerReportesFotos method · typescript · L343-L377 (35 LOC)src/admin/admin.service.ts
async obtenerReportesFotos(estado?: string) {
const where: any = {};
if (estado) {
where.estado = estado;
}
const reportes = await this.prisma.reporteFoto.findMany({
where,
include: {
foto: {
include: {
user: {
select: {
id: true,
nombre: true,
apellido: true,
},
},
},
},
user: {
select: {
id: true,
nombre: true,
apellido: true,
},
},
},
orderBy: {
createdAt: 'desc',
},
});
return reportes;
}AdminService.obtenerReportesUsuarios method · typescript · L379-L409 (31 LOC)src/admin/admin.service.ts
async obtenerReportesUsuarios(estado?: string) {
const where: any = {};
if (estado) {
where.estado = estado;
}
const reportes = await this.prisma.reporte.findMany({
where,
include: {
reportador: {
select: {
id: true,
nombre: true,
apellido: true,
},
},
reportado: {
select: {
id: true,
nombre: true,
apellido: true,
},
},
},
orderBy: {
createdAt: 'desc',
},
});
return reportes;
}Citation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
AdminService.resolverReporteFoto method · typescript · L411-L431 (21 LOC)src/admin/admin.service.ts
async resolverReporteFoto(id: string, accion: string) {
const reporte = await this.prisma.reporteFoto.findUnique({
where: { id },
include: { foto: true },
});
if (!reporte) {
throw new NotFoundException('Reporte no encontrado');
}
if (accion === 'ELIMINAR_FOTO') {
await this.eliminarFotoInapropiada(reporte.fotoId, 'Reportada como inapropiada');
}
await this.prisma.reporteFoto.update({
where: { id },
data: { estado: 'APROBADA' },
});
return { message: 'Reporte resuelto' };
}AdminService.resolverReporteUsuario method · typescript · L433-L452 (20 LOC)src/admin/admin.service.ts
async resolverReporteUsuario(id: string, accion: string) {
const reporte = await this.prisma.reporte.findUnique({
where: { id },
});
if (!reporte) {
throw new NotFoundException('Reporte no encontrado');
}
if (accion === 'SUSPENDER') {
await this.suspenderUsuario(reporte.reportadoId, 'Reportado por múltiples usuarios');
}
await this.prisma.reporte.update({
where: { id },
data: { estado: 'APROBADA' },
});
return { message: 'Reporte resuelto' };
}AdminService.obtenerSuscripciones method · typescript · L456-L481 (26 LOC)src/admin/admin.service.ts
async obtenerSuscripciones(estado?: string) {
const where: any = {};
if (estado) {
where.estado = estado;
}
const suscripciones = await this.prisma.suscripcion.findMany({
where,
include: {
user: {
select: {
id: true,
nombre: true,
apellido: true,
email: true,
},
},
plan: true,
},
orderBy: {
createdAt: 'desc',
},
});
return suscripciones;
}AdminService.extenderSuscripcion method · typescript · L483-L516 (34 LOC)src/admin/admin.service.ts
async extenderSuscripcion(id: string, dias: number) {
const suscripcion = await this.prisma.suscripcion.findUnique({
where: { id },
});
if (!suscripcion) {
throw new NotFoundException('Suscripción no encontrada');
}
const nuevaFechaFin = new Date(suscripcion.fechaFin);
nuevaFechaFin.setDate(nuevaFechaFin.getDate() + dias);
// If subscription was VENCIDA, reactivate it and set user as premium
const updateData: any = {
fechaFin: nuevaFechaFin,
fechaRenovacion: nuevaFechaFin,
};
if (suscripcion.estado === 'VENCIDA') {
updateData.estado = 'ACTIVA';
}
await this.prisma.suscripcion.update({
where: { id },
data: updateData,
});
// Ensure user is premium (especially if reactivated from VENCIDA)
await this.prisma.user.update({
where: { id: suscripcion.userId },
data: { esPremium: true },
});
return { message: `Suscripción extendida por ${dias} días` };
}AdminService.obtenerConfiguracionPuntos method · typescript · L520-L528 (9 LOC)src/admin/admin.service.ts
async obtenerConfiguracionPuntos() {
const configuracion = await this.prisma.configuracionPuntos.findMany({
orderBy: {
puntosBase: 'desc',
},
});
return configuracion;
}AdminService.actualizarConfiguracionPuntos method · typescript · L530-L548 (19 LOC)src/admin/admin.service.ts
async actualizarConfiguracionPuntos(id: string, data: any) {
const config = await this.prisma.configuracionPuntos.findUnique({
where: { id },
});
if (!config) {
throw new NotFoundException('Configuración no encontrada');
}
await this.prisma.configuracionPuntos.update({
where: { id },
data: {
puntosBase: data.puntosBase,
multiplicador: data.multiplicador,
},
});
return { message: 'Configuración actualizada' };
}AdminService.crearCupon method · typescript · L552-L565 (14 LOC)src/admin/admin.service.ts
async crearCupon(data: any) {
const cupon = await this.prisma.cupon.create({
data: {
codigo: data.codigo,
tipo: data.tipo,
valor: data.valor,
fechaInicio: new Date(data.fechaInicio),
fechaExpiracion: new Date(data.fechaExpiracion),
limiteUsos: data.limiteUsos,
},
});
return cupon;
}AdminService.obtenerCupones method · typescript · L567-L575 (9 LOC)src/admin/admin.service.ts
async obtenerCupones() {
const cupones = await this.prisma.cupon.findMany({
orderBy: {
createdAt: 'desc',
},
});
return cupones;
}Repobility analyzer · published findings · https://repobility.com
AdminService.desactivarCupon method · typescript · L577-L584 (8 LOC)src/admin/admin.service.ts
async desactivarCupon(id: string) {
await this.prisma.cupon.update({
where: { id },
data: { estado: 'INACTIVO' },
});
return { message: 'Cupón desactivado' };
}AdminService.obtenerMetricasDashboard method · typescript · L588-L604 (17 LOC)src/admin/admin.service.ts
async obtenerMetricasDashboard() {
const totalUsuarios = await this.prisma.user.count();
const usuariosPremium = await this.prisma.user.count({
where: { esPremium: true },
});
const totalTorneos = await this.prisma.tournament.count();
const torneosPendientes = await this.prisma.tournament.count({
where: { estado: 'PENDIENTE_APROBACION' },
});
return {
totalUsuarios,
usuariosPremium,
totalTorneos,
torneosPendientes,
};
}AdminService.obtenerMetricasUsuarios method · typescript · L606-L621 (16 LOC)src/admin/admin.service.ts
async obtenerMetricasUsuarios() {
const porEstado = await this.prisma.user.groupBy({
by: ['estado'],
_count: true,
});
const porGenero = await this.prisma.user.groupBy({
by: ['genero'],
_count: true,
});
return {
porEstado,
porGenero,
};
}AdminService.obtenerMetricasTorneos method · typescript · L623-L630 (8 LOC)src/admin/admin.service.ts
async obtenerMetricasTorneos() {
const porEstado = await this.prisma.tournament.groupBy({
by: ['estado'],
_count: true,
});
return { porEstado };
}AdminService.obtenerMetricasIngresos method · typescript · L632-L659 (28 LOC)src/admin/admin.service.ts
async obtenerMetricasIngresos() {
// Calcular ingresos totales de suscripciones
const suscripciones = await this.prisma.suscripcion.findMany({
where: { estado: 'ACTIVA' },
});
const mrrSuscripciones = suscripciones.reduce((acc, sub) => {
const precioMensual = sub.periodo === 'MENSUAL'
? sub.precio.toNumber()
: sub.precio.toNumber() / 12;
return acc + precioMensual;
}, 0);
// Calcular ingresos de comisiones
const pagos = await this.prisma.pago.findMany({
where: { estado: 'CONFIRMADO' },
});
const totalComisiones = pagos.reduce((acc, pago) => {
return acc + pago.comision.toNumber();
}, 0);
return {
mrr: mrrSuscripciones,
totalComisiones,
suscripcionesActivas: suscripciones.length,
};
}AdminService.obtenerUsuariosPremium method · typescript · L666-L718 (53 LOC)src/admin/admin.service.ts
async obtenerUsuariosPremium(search?: string, estado?: string) {
const where: any = { esPremium: true };
if (search) {
where.AND = [
{ esPremium: true },
{
OR: [
{ nombre: { contains: search, mode: 'insensitive' } },
{ apellido: { contains: search, mode: 'insensitive' } },
{ email: { contains: search, mode: 'insensitive' } },
{ documento: { contains: search } },
],
},
];
delete where.esPremium;
}
const usuarios = await this.prisma.user.findMany({
where,
select: {
id: true,
nombre: true,
apellido: true,
documento: true,
email: true,
telefono: true,
ciudad: true,
genero: true,
fotoUrl: true,
esPremium: true,
createdAt: true,
suscripciones: {
orderBy: { createdAt: 'desc' },
take: 1,
include: {
plan: true,
AdminService.obtenerMetricasPremium method · typescript · L723-L812 (90 LOC)src/admin/admin.service.ts
async obtenerMetricasPremium() {
const now = new Date();
const hace30Dias = new Date(now);
hace30Dias.setDate(hace30Dias.getDate() - 30);
const hace60Dias = new Date(now);
hace60Dias.setDate(hace60Dias.getDate() - 60);
// Conteos básicos
const totalPremium = await this.prisma.user.count({ where: { esPremium: true } });
const totalUsuarios = await this.prisma.user.count();
const suscripcionesActivas = await this.prisma.suscripcion.count({ where: { estado: 'ACTIVA' } });
const suscripcionesPendientes = await this.prisma.suscripcion.count({ where: { estado: 'PENDIENTE_PAGO' } });
// Nuevos premium últimos 30 días
const nuevosPremium30d = await this.prisma.suscripcion.count({
where: {
estado: 'ACTIVA',
createdAt: { gte: hace30Dias },
},
});
// Cancelaciones últimos 30 días
const cancelaciones30d = await this.prisma.suscripcion.count({
where: {
estado: { in: ['CANCELADA', 'VENCIDA'] },AdminService.obtenerTendenciasSuscripciones method · typescript · L817-L863 (47 LOC)src/admin/admin.service.ts
async obtenerTendenciasSuscripciones() {
const meses: {
mes: string;
nuevas: number;
canceladas: number;
ingresos: number;
}[] = [];
const now = new Date();
for (let i = 11; i >= 0; i--) {
const inicio = new Date(now.getFullYear(), now.getMonth() - i, 1);
const fin = new Date(now.getFullYear(), now.getMonth() - i + 1, 0, 23, 59, 59);
const nuevas = await this.prisma.suscripcion.count({
where: {
createdAt: { gte: inicio, lte: fin },
estado: { not: 'PENDIENTE_PAGO' },
},
});
const canceladas = await this.prisma.suscripcion.count({
where: {
estado: { in: ['CANCELADA', 'VENCIDA'] },
updatedAt: { gte: inicio, lte: fin },
},
});
// Revenue del mes (suscripciones creadas ese mes)
const susMes = await this.prisma.suscripcion.findMany({
where: {
createdAt: { gte: inicio, lte: fin },
estado: { in: ['ACTIRepobility · severity-and-effort ranking · https://repobility.com
AdminService.obtenerActividadPremium method · typescript · L868-L903 (36 LOC)src/admin/admin.service.ts
async obtenerActividadPremium() {
const suscripciones = await this.prisma.suscripcion.findMany({
orderBy: { updatedAt: 'desc' },
take: 20,
include: {
user: {
select: {
id: true,
nombre: true,
apellido: true,
email: true,
fotoUrl: true,
},
},
plan: {
select: {
nombre: true,
},
},
},
});
return suscripciones.map((s) => ({
id: s.id,
usuario: s.user,
plan: s.plan?.nombre,
estado: s.estado,
precio: s.precio.toNumber(),
fechaInicio: s.fechaInicio,
fechaFin: s.fechaFin,
autoRenovar: s.autoRenovar,
cuponAplicado: s.cuponAplicado,
createdAt: s.createdAt,
updatedAt: s.updatedAt,
}));
}AdminService.otorgarPremiumManual method · typescript · L908-L961 (54 LOC)src/admin/admin.service.ts
async otorgarPremiumManual(userId: string, dias: number, motivo: string) {
const user = await this.prisma.user.findUnique({
where: { id: userId },
});
if (!user) {
throw new NotFoundException('Usuario no encontrado');
}
// Buscar plan premium
const plan = await this.prisma.planPremium.findFirst({
where: { activo: true },
});
if (!plan) {
throw new NotFoundException('No hay plan premium activo');
}
// Cancelar suscripciones activas/pendientes existentes para evitar duplicados
await this.prisma.suscripcion.updateMany({
where: { userId, estado: { in: ['ACTIVA', 'PENDIENTE_PAGO'] } },
data: { estado: 'CANCELADA' },
});
const now = new Date();
const fechaFin = new Date(now);
fechaFin.setDate(fechaFin.getDate() + dias);
// Crear suscripción cortesía
const suscripcion = await this.prisma.suscripcion.create({
data: {
userId,
planId: plan.id,
periodo: 'MEAdminService.revocarPremium method · typescript · L966-L990 (25 LOC)src/admin/admin.service.ts
async revocarPremium(userId: string) {
const user = await this.prisma.user.findUnique({
where: { id: userId },
});
if (!user) {
throw new NotFoundException('Usuario no encontrado');
}
// Cancelar suscripciones activas y pendientes
await this.prisma.suscripcion.updateMany({
where: { userId, estado: { in: ['ACTIVA', 'PENDIENTE_PAGO'] } },
data: { estado: 'CANCELADA' },
});
// Quitar premium
await this.prisma.user.update({
where: { id: userId },
data: { esPremium: false },
});
return {
message: `Premium revocado para ${user.nombre} ${user.apellido}`,
};
}AdminService.obtenerEstadisticasCupones method · typescript · L995-L1028 (34 LOC)src/admin/admin.service.ts
async obtenerEstadisticasCupones() {
const cupones = await this.prisma.cupon.findMany({
orderBy: { createdAt: 'desc' },
});
const totalCupones = cupones.length;
const cuponesActivos = cupones.filter((c) => c.estado === 'ACTIVO').length;
const totalUsos = cupones.reduce((acc, c) => acc + c.usosActuales, 0);
const descuentoTotal = cupones.reduce((acc, c) => {
if (c.tipo === 'PORCENTAJE') return acc; // Can't calculate exact amount for percentage
return acc + c.valor.toNumber() * c.usosActuales;
}, 0);
// Top cupones por uso
const topCupones = [...cupones]
.sort((a, b) => b.usosActuales - a.usosActuales)
.slice(0, 5)
.map((c) => ({
codigo: c.codigo,
tipo: c.tipo,
valor: c.valor.toNumber(),
usos: c.usosActuales,
limite: c.limiteUsos,
estado: c.estado,
}));
return {
totalCupones,
cuponesActivos,
totalUsos,
descuentoTotal,
topCupAdminService.promoverOrganizadorPorDocumento method · typescript · L1032-L1086 (55 LOC)src/admin/admin.service.ts
async promoverOrganizadorPorDocumento(documento: string) {
// Buscar usuario por documento
const user = await this.prisma.user.findUnique({
where: { documento },
include: {
roles: {
include: { role: true },
},
},
});
if (!user) {
throw new NotFoundException(
`No se encontró usuario con documento: ${documento}`,
);
}
// Verificar si ya es organizador
const yaEsOrganizador = user.roles.some(
(ur) => ur.role.nombre === 'organizador',
);
if (yaEsOrganizador) {
throw new ConflictException(
`${user.nombre} ${user.apellido} ya tiene rol de organizador`,
);
}
// Buscar rol de organizador
const rolOrganizador = await this.prisma.role.findUnique({
where: { nombre: 'organizador' },
});
if (!rolOrganizador) {
throw new NotFoundException('Rol organizador no encontrado');
}
// Asignar rol
await this.prisma.userRole.create({
AdminService.actualizarConfiguracionSistema method · typescript · L1096-L1123 (28 LOC)src/admin/admin.service.ts
async actualizarConfiguracionSistema(clave: string, valor: string) {
const config = await this.prisma.configuracionSistema.findUnique({
where: { clave },
});
if (!config) {
throw new NotFoundException(
`Configuración '${clave}' no encontrada`,
);
}
// Validar que el valor sea numérico para comisiones
if (clave === 'COMISION_INSCRIPCION') {
const numVal = parseFloat(valor);
if (isNaN(numVal) || numVal < 0 || numVal > 100) {
throw new BadRequestException(
'El porcentaje de comisión debe ser un número entre 0 y 100',
);
}
}
await this.prisma.configuracionSistema.update({
where: { clave },
data: { valor },
});
return { message: `Configuración '${clave}' actualizada a: ${valor}` };
}AdminService.obtenerValorConfiguracion method · typescript · L1125-L1130 (6 LOC)src/admin/admin.service.ts
async obtenerValorConfiguracion(clave: string): Promise<string | null> {
const config = await this.prisma.configuracionSistema.findUnique({
where: { clave },
});
return config?.valor ?? null;
}AdminService.setComisionTorneo method · typescript · L1136-L1159 (24 LOC)src/admin/admin.service.ts
async setComisionTorneo(tournamentId: string, comisionPorcentaje: number | null) {
const tournament = await this.prisma.tournament.findUnique({
where: { id: tournamentId },
});
if (!tournament) throw new NotFoundException('Torneo no encontrado');
if (comisionPorcentaje !== null) {
if (comisionPorcentaje < 0 || comisionPorcentaje > 100) {
throw new BadRequestException('La comisión debe estar entre 0 y 100');
}
}
await this.prisma.tournament.update({
where: { id: tournamentId },
data: { comisionPorcentaje },
});
return {
message: comisionPorcentaje !== null
? `Comisión del torneo configurada a ${comisionPorcentaje}%`
: 'Comisión del torneo eliminada (usará la configuración global)',
comisionPorcentaje,
};
}If a scraper extracted this row, it came from Repobility (https://repobility.com)
AdminService.getComisionTorneo method · typescript · L1161-L1179 (19 LOC)src/admin/admin.service.ts
async getComisionTorneo(tournamentId: string) {
const tournament = await this.prisma.tournament.findUnique({
where: { id: tournamentId },
select: { id: true, nombre: true, comisionPorcentaje: true },
});
if (!tournament) throw new NotFoundException('Torneo no encontrado');
const globalConfig = await this.prisma.configuracionSistema.findUnique({
where: { clave: 'COMISION_INSCRIPCION' },
});
return {
tournamentId: tournament.id,
nombre: tournament.nombre,
comisionPorcentaje: tournament.comisionPorcentaje,
comisionGlobal: globalConfig ? parseFloat(globalConfig.valor) : 5,
usandoGlobal: tournament.comisionPorcentaje === null,
};
}AdminService.obtenerFinanzasDashboard method · typescript · L1185-L1250 (66 LOC)src/admin/admin.service.ts
async obtenerFinanzasDashboard() {
// Comisión fija actual
const configComision = await this.prisma.configuracionSistema.findUnique({
where: { clave: 'COMISION_FIJA_POR_JUGADOR' },
});
const comisionFijaPorJugador = configComision ? parseFloat(configComision.valor) : 5000;
// Total comisiones de pagos confirmados
const pagosConfirmados = await this.prisma.pago.findMany({
where: { estado: 'CONFIRMADO' },
select: { comision: true, inscripcionId: true },
});
const totalIngresosComisiones = pagosConfirmados.reduce(
(acc, p) => acc + p.comision.toNumber(), 0,
);
// Pagos confirmados del mes actual
const now = new Date();
const inicioMes = new Date(now.getFullYear(), now.getMonth(), 1);
const pagosMes = await this.prisma.pago.findMany({
where: {
estado: 'CONFIRMADO',
fechaConfirm: { gte: inicioMes },
},
select: { comision: true },
});
const comisionesMes = pagosMes.reducAdminService.obtenerFinanzasTorneos method · typescript · L1252-L1310 (59 LOC)src/admin/admin.service.ts
async obtenerFinanzasTorneos(estado?: string) {
const where: any = {};
if (estado) {
where.estado = estado;
}
const torneos = await this.prisma.tournament.findMany({
where,
select: {
id: true,
nombre: true,
flyerUrl: true,
estado: true,
fechaInicio: true,
fechaFin: true,
costoInscripcion: true,
createdAt: true,
inscripciones: {
select: {
id: true,
estado: true,
pagos: {
where: { estado: 'CONFIRMADO' },
select: { comision: true },
},
},
},
},
orderBy: { createdAt: 'desc' },
});
return torneos.map((t) => {
let inscripcionesConfirmadas = 0;
let comisionesGeneradas = 0;
for (const insc of t.inscripciones) {
if (insc.estado === 'CONFIRMADA') {
inscripcionesConfirmadas++;
}
for (const pago of insc.pagos) {
page 1 / 9next ›