✅ 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:
@@ -0,0 +1,228 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "level_history" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"oldLevel" TEXT NOT NULL,
|
||||
"newLevel" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"changedBy" TEXT NOT NULL,
|
||||
"reason" TEXT,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "level_history_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "friends" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"requesterId" TEXT NOT NULL,
|
||||
"addresseeId" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'PENDING',
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
CONSTRAINT "friends_requesterId_fkey" FOREIGN KEY ("requesterId") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||
CONSTRAINT "friends_addresseeId_fkey" FOREIGN KEY ("addresseeId") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "groups" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"createdById" TEXT NOT NULL,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
CONSTRAINT "groups_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "group_members" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"groupId" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"role" TEXT NOT NULL DEFAULT 'MEMBER',
|
||||
"joinedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "group_members_groupId_fkey" FOREIGN KEY ("groupId") REFERENCES "groups" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT "group_members_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "recurring_bookings" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"userId" TEXT NOT NULL,
|
||||
"courtId" TEXT NOT NULL,
|
||||
"dayOfWeek" INTEGER NOT NULL,
|
||||
"startTime" TEXT NOT NULL,
|
||||
"endTime" TEXT NOT NULL,
|
||||
"startDate" DATETIME NOT NULL,
|
||||
"endDate" DATETIME,
|
||||
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
CONSTRAINT "recurring_bookings_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||
CONSTRAINT "recurring_bookings_courtId_fkey" FOREIGN KEY ("courtId") REFERENCES "courts" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "match_results" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"bookingId" TEXT,
|
||||
"team1Player1Id" TEXT NOT NULL,
|
||||
"team1Player2Id" TEXT NOT NULL,
|
||||
"team2Player1Id" TEXT NOT NULL,
|
||||
"team2Player2Id" TEXT NOT NULL,
|
||||
"team1Score" INTEGER NOT NULL,
|
||||
"team2Score" INTEGER NOT NULL,
|
||||
"winner" TEXT NOT NULL,
|
||||
"playedAt" DATETIME NOT NULL,
|
||||
"confirmedBy" TEXT NOT NULL DEFAULT '[]',
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "match_results_bookingId_fkey" FOREIGN KEY ("bookingId") REFERENCES "bookings" ("id") ON DELETE SET NULL ON UPDATE CASCADE,
|
||||
CONSTRAINT "match_results_team1Player1Id_fkey" FOREIGN KEY ("team1Player1Id") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||
CONSTRAINT "match_results_team1Player2Id_fkey" FOREIGN KEY ("team1Player2Id") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||
CONSTRAINT "match_results_team2Player1Id_fkey" FOREIGN KEY ("team2Player1Id") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||
CONSTRAINT "match_results_team2Player2Id_fkey" FOREIGN KEY ("team2Player2Id") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "user_stats" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"userId" TEXT NOT NULL,
|
||||
"period" TEXT NOT NULL,
|
||||
"periodValue" TEXT NOT NULL,
|
||||
"matchesPlayed" INTEGER NOT NULL DEFAULT 0,
|
||||
"matchesWon" INTEGER NOT NULL DEFAULT 0,
|
||||
"matchesLost" INTEGER NOT NULL DEFAULT 0,
|
||||
"tournamentsPlayed" INTEGER NOT NULL DEFAULT 0,
|
||||
"tournamentsWon" INTEGER NOT NULL DEFAULT 0,
|
||||
"points" INTEGER NOT NULL DEFAULT 0,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
CONSTRAINT "user_stats_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- RedefineTables
|
||||
PRAGMA defer_foreign_keys=ON;
|
||||
PRAGMA foreign_keys=OFF;
|
||||
CREATE TABLE "new_bookings" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"date" DATETIME NOT NULL,
|
||||
"startTime" TEXT NOT NULL,
|
||||
"endTime" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'PENDING',
|
||||
"totalPrice" INTEGER NOT NULL,
|
||||
"notes" TEXT,
|
||||
"userId" TEXT NOT NULL,
|
||||
"courtId" TEXT NOT NULL,
|
||||
"recurringBookingId" TEXT,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
CONSTRAINT "bookings_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||
CONSTRAINT "bookings_courtId_fkey" FOREIGN KEY ("courtId") REFERENCES "courts" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||
CONSTRAINT "bookings_recurringBookingId_fkey" FOREIGN KEY ("recurringBookingId") REFERENCES "recurring_bookings" ("id") ON DELETE SET NULL ON UPDATE CASCADE
|
||||
);
|
||||
INSERT INTO "new_bookings" ("courtId", "createdAt", "date", "endTime", "id", "notes", "startTime", "status", "totalPrice", "updatedAt", "userId") SELECT "courtId", "createdAt", "date", "endTime", "id", "notes", "startTime", "status", "totalPrice", "updatedAt", "userId" FROM "bookings";
|
||||
DROP TABLE "bookings";
|
||||
ALTER TABLE "new_bookings" RENAME TO "bookings";
|
||||
CREATE INDEX "bookings_userId_idx" ON "bookings"("userId");
|
||||
CREATE INDEX "bookings_courtId_idx" ON "bookings"("courtId");
|
||||
CREATE INDEX "bookings_date_idx" ON "bookings"("date");
|
||||
CREATE INDEX "bookings_recurringBookingId_idx" ON "bookings"("recurringBookingId");
|
||||
CREATE TABLE "new_users" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"email" TEXT NOT NULL,
|
||||
"password" TEXT NOT NULL,
|
||||
"firstName" TEXT NOT NULL,
|
||||
"lastName" TEXT NOT NULL,
|
||||
"phone" TEXT,
|
||||
"avatarUrl" TEXT,
|
||||
"city" TEXT,
|
||||
"birthDate" DATETIME,
|
||||
"role" TEXT NOT NULL DEFAULT 'PLAYER',
|
||||
"playerLevel" TEXT NOT NULL DEFAULT 'BEGINNER',
|
||||
"handPreference" TEXT NOT NULL DEFAULT 'RIGHT',
|
||||
"positionPreference" TEXT NOT NULL DEFAULT 'BOTH',
|
||||
"bio" TEXT,
|
||||
"yearsPlaying" INTEGER,
|
||||
"matchesPlayed" INTEGER NOT NULL DEFAULT 0,
|
||||
"matchesWon" INTEGER NOT NULL DEFAULT 0,
|
||||
"matchesLost" INTEGER NOT NULL DEFAULT 0,
|
||||
"totalPoints" INTEGER NOT NULL DEFAULT 0,
|
||||
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||
"isVerified" BOOLEAN NOT NULL DEFAULT false,
|
||||
"lastLogin" DATETIME,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
INSERT INTO "new_users" ("avatarUrl", "bio", "createdAt", "email", "firstName", "handPreference", "id", "isActive", "isVerified", "lastLogin", "lastName", "password", "phone", "playerLevel", "positionPreference", "role", "updatedAt") SELECT "avatarUrl", "bio", "createdAt", "email", "firstName", "handPreference", "id", "isActive", "isVerified", "lastLogin", "lastName", "password", "phone", "playerLevel", "positionPreference", "role", "updatedAt" FROM "users";
|
||||
DROP TABLE "users";
|
||||
ALTER TABLE "new_users" RENAME TO "users";
|
||||
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
|
||||
PRAGMA foreign_keys=ON;
|
||||
PRAGMA defer_foreign_keys=OFF;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "level_history_userId_idx" ON "level_history"("userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "friends_requesterId_idx" ON "friends"("requesterId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "friends_addresseeId_idx" ON "friends"("addresseeId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "friends_status_idx" ON "friends"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "friends_requesterId_addresseeId_key" ON "friends"("requesterId", "addresseeId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "groups_createdById_idx" ON "groups"("createdById");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "group_members_groupId_idx" ON "group_members"("groupId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "group_members_userId_idx" ON "group_members"("userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "group_members_groupId_userId_key" ON "group_members"("groupId", "userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "recurring_bookings_userId_idx" ON "recurring_bookings"("userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "recurring_bookings_courtId_idx" ON "recurring_bookings"("courtId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "recurring_bookings_dayOfWeek_idx" ON "recurring_bookings"("dayOfWeek");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "recurring_bookings_isActive_idx" ON "recurring_bookings"("isActive");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "match_results_bookingId_key" ON "match_results"("bookingId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "match_results_team1Player1Id_idx" ON "match_results"("team1Player1Id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "match_results_team1Player2Id_idx" ON "match_results"("team1Player2Id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "match_results_team2Player1Id_idx" ON "match_results"("team2Player1Id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "match_results_team2Player2Id_idx" ON "match_results"("team2Player2Id");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "match_results_playedAt_idx" ON "match_results"("playedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "user_stats_userId_idx" ON "user_stats"("userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "user_stats_period_periodValue_idx" ON "user_stats"("period", "periodValue");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "user_stats_points_idx" ON "user_stats"("points");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "user_stats_userId_period_periodValue_key" ON "user_stats"("userId", "period", "periodValue");
|
||||
@@ -0,0 +1 @@
|
||||
-- This is an empty migration.
|
||||
Reference in New Issue
Block a user