feat: add error handling to player creation and update gitignore for agent
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "MatchStatus" AS ENUM ('IN_PROGRESS', 'COMPLETED');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Group" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"logoUrl" TEXT,
|
||||
"primaryColor" TEXT NOT NULL DEFAULT '#000000',
|
||||
"secondaryColor" TEXT NOT NULL DEFAULT '#ffffff',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "Group_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Player" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"number" INTEGER NOT NULL,
|
||||
"position" TEXT NOT NULL DEFAULT 'MEI',
|
||||
"level" INTEGER NOT NULL DEFAULT 3,
|
||||
"groupId" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "Player_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Sponsor" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"logoUrl" TEXT,
|
||||
"groupId" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "Sponsor_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Match" (
|
||||
"id" TEXT NOT NULL,
|
||||
"date" TIMESTAMP(3) NOT NULL,
|
||||
"status" "MatchStatus" NOT NULL DEFAULT 'IN_PROGRESS',
|
||||
"groupId" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "Match_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Team" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"color" TEXT NOT NULL,
|
||||
"matchId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "Team_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "TeamPlayer" (
|
||||
"id" TEXT NOT NULL,
|
||||
"teamId" TEXT NOT NULL,
|
||||
"playerId" TEXT NOT NULL,
|
||||
|
||||
CONSTRAINT "TeamPlayer_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Player_number_groupId_key" ON "Player"("number", "groupId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Player" ADD CONSTRAINT "Player_groupId_fkey" FOREIGN KEY ("groupId") REFERENCES "Group"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Sponsor" ADD CONSTRAINT "Sponsor_groupId_fkey" FOREIGN KEY ("groupId") REFERENCES "Group"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Match" ADD CONSTRAINT "Match_groupId_fkey" FOREIGN KEY ("groupId") REFERENCES "Group"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Team" ADD CONSTRAINT "Team_matchId_fkey" FOREIGN KEY ("matchId") REFERENCES "Match"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "TeamPlayer" ADD CONSTRAINT "TeamPlayer_teamId_fkey" FOREIGN KEY ("teamId") REFERENCES "Team"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "TeamPlayer" ADD CONSTRAINT "TeamPlayer_playerId_fkey" FOREIGN KEY ("playerId") REFERENCES "Player"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
15
prisma/migrations/20260121025323_sync_schema/migration.sql
Normal file
15
prisma/migrations/20260121025323_sync_schema/migration.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- A unique constraint covering the columns `[email]` on the table `Group` will be added. If there are existing duplicate values, this will fail.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "Group" ADD COLUMN "email" TEXT,
|
||||
ADD COLUMN "password" TEXT;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Player" ALTER COLUMN "number" DROP NOT NULL;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Group_email_key" ON "Group"("email");
|
||||
@@ -0,0 +1,24 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Match" ADD COLUMN "drawSeed" TEXT,
|
||||
ADD COLUMN "location" TEXT,
|
||||
ADD COLUMN "maxPlayers" INTEGER;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Attendance" (
|
||||
"id" TEXT NOT NULL,
|
||||
"playerId" TEXT NOT NULL,
|
||||
"matchId" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'CONFIRMED',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "Attendance_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Attendance_playerId_matchId_key" ON "Attendance"("playerId", "matchId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Attendance" ADD CONSTRAINT "Attendance_playerId_fkey" FOREIGN KEY ("playerId") REFERENCES "Player"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Attendance" ADD CONSTRAINT "Attendance_matchId_fkey" FOREIGN KEY ("matchId") REFERENCES "Match"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,10 @@
|
||||
-- AlterEnum
|
||||
-- This migration adds more than one value to an enum.
|
||||
-- With PostgreSQL versions 11 and earlier, this is not possible
|
||||
-- in a single migration. This can be worked around by creating
|
||||
-- multiple migrations, each migration adding only one value to
|
||||
-- the enum.
|
||||
|
||||
|
||||
ALTER TYPE "MatchStatus" ADD VALUE 'SCHEDULED';
|
||||
ALTER TYPE "MatchStatus" ADD VALUE 'CANCELED';
|
||||
@@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Match" ALTER COLUMN "status" SET DEFAULT 'SCHEDULED';
|
||||
@@ -0,0 +1,17 @@
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "Attendance" DROP CONSTRAINT "Attendance_matchId_fkey";
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "Team" DROP CONSTRAINT "Team_matchId_fkey";
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "TeamPlayer" DROP CONSTRAINT "TeamPlayer_teamId_fkey";
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Attendance" ADD CONSTRAINT "Attendance_matchId_fkey" FOREIGN KEY ("matchId") REFERENCES "Match"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Team" ADD CONSTRAINT "Team_matchId_fkey" FOREIGN KEY ("matchId") REFERENCES "Match"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "TeamPlayer" ADD CONSTRAINT "TeamPlayer_teamId_fkey" FOREIGN KEY ("teamId") REFERENCES "Team"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,3 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Match" ADD COLUMN "isRecurring" BOOLEAN NOT NULL DEFAULT false,
|
||||
ADD COLUMN "recurrenceInterval" TEXT;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Match" ADD COLUMN "recurrenceEndDate" TIMESTAMP(3);
|
||||
3
prisma/migrations/migration_lock.toml
Normal file
3
prisma/migrations/migration_lock.toml
Normal file
@@ -0,0 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (e.g., Git)
|
||||
provider = "postgresql"
|
||||
206
prisma/schema.prisma
Normal file
206
prisma/schema.prisma
Normal file
@@ -0,0 +1,206 @@
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
binaryTargets = ["native", "linux-musl-openssl-3.0.x", "debian-openssl-3.0.x"]
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
// Super Admin da plataforma TemFut (acessa admin.localhost)
|
||||
model Admin {
|
||||
id String @id @default(cuid())
|
||||
email String @unique
|
||||
password String
|
||||
name String
|
||||
role AdminRole @default(ADMIN)
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
enum AdminRole {
|
||||
SUPER_ADMIN // Acesso total
|
||||
ADMIN // Acesso de leitura
|
||||
}
|
||||
|
||||
|
||||
model Group {
|
||||
id String @id @default(cuid())
|
||||
slug String @unique @default(cuid()) // Para subdomínios (ex: flamengo.temfut.com)
|
||||
name String
|
||||
logoUrl String?
|
||||
primaryColor String @default("#000000")
|
||||
secondaryColor String @default("#ffffff")
|
||||
createdAt DateTime @default(now())
|
||||
email String? @unique
|
||||
password String?
|
||||
plan Plan @default(FREE)
|
||||
planExpiresAt DateTime?
|
||||
matches Match[]
|
||||
players Player[]
|
||||
sponsors Sponsor[]
|
||||
arenas Arena[]
|
||||
financialEvents FinancialEvent[]
|
||||
pixKey String?
|
||||
pixName String?
|
||||
status GroupStatus @default(ACTIVE)
|
||||
}
|
||||
|
||||
enum GroupStatus {
|
||||
ACTIVE
|
||||
FROZEN
|
||||
}
|
||||
|
||||
enum Plan {
|
||||
FREE
|
||||
BASIC
|
||||
PRO
|
||||
}
|
||||
|
||||
model Player {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
number Int?
|
||||
position String @default("MEI")
|
||||
level Int @default(3)
|
||||
groupId String
|
||||
createdAt DateTime @default(now())
|
||||
group Group @relation(fields: [groupId], references: [id])
|
||||
teams TeamPlayer[]
|
||||
attendances Attendance[]
|
||||
payments Payment[]
|
||||
|
||||
@@unique([number, groupId])
|
||||
}
|
||||
|
||||
model Attendance {
|
||||
id String @id @default(cuid())
|
||||
playerId String
|
||||
player Player @relation(fields: [playerId], references: [id])
|
||||
matchId String
|
||||
match Match @relation(fields: [matchId], references: [id], onDelete: Cascade)
|
||||
status String @default("CONFIRMED") // CONFIRMED, CANCELED
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@unique([playerId, matchId])
|
||||
}
|
||||
|
||||
model Match {
|
||||
id String @id @default(cuid())
|
||||
date DateTime
|
||||
location String?
|
||||
arenaId String?
|
||||
arena Arena? @relation(fields: [arenaId], references: [id])
|
||||
maxPlayers Int?
|
||||
drawSeed String?
|
||||
status MatchStatus @default(SCHEDULED)
|
||||
groupId String
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
group Group @relation(fields: [groupId], references: [id])
|
||||
teams Team[]
|
||||
attendances Attendance[]
|
||||
isRecurring Boolean @default(false)
|
||||
recurrenceInterval String? // 'WEEKLY'
|
||||
recurrenceEndDate DateTime?
|
||||
}
|
||||
|
||||
model Team {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
color String
|
||||
matchId String
|
||||
match Match @relation(fields: [matchId], references: [id], onDelete: Cascade)
|
||||
players TeamPlayer[]
|
||||
}
|
||||
|
||||
model TeamPlayer {
|
||||
id String @id @default(cuid())
|
||||
teamId String
|
||||
playerId String
|
||||
player Player @relation(fields: [playerId], references: [id])
|
||||
team Team @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
enum MatchStatus {
|
||||
SCHEDULED
|
||||
IN_PROGRESS
|
||||
COMPLETED
|
||||
CANCELED
|
||||
}
|
||||
|
||||
model Sponsor {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
logoUrl String?
|
||||
groupId String
|
||||
createdAt DateTime @default(now())
|
||||
group Group @relation(fields: [groupId], references: [id])
|
||||
}
|
||||
|
||||
model Arena {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
address String?
|
||||
groupId String
|
||||
group Group @relation(fields: [groupId], references: [id])
|
||||
matches Match[]
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
model FinancialEvent {
|
||||
id String @id @default(cuid())
|
||||
title String
|
||||
description String?
|
||||
totalAmount Float? // Meta de arrecadação (opcional)
|
||||
pricePerPerson Float? // Valor por pessoa
|
||||
dueDate DateTime
|
||||
type FinancialEventType @default(MONTHLY_FEE)
|
||||
status FinancialEventStatus @default(OPEN)
|
||||
|
||||
groupId String
|
||||
group Group @relation(fields: [groupId], references: [id])
|
||||
|
||||
payments Payment[]
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
isRecurring Boolean @default(false)
|
||||
recurrenceInterval String? // 'MONTHLY', 'WEEKLY'
|
||||
recurrenceEndDate DateTime?
|
||||
}
|
||||
|
||||
model Payment {
|
||||
id String @id @default(cuid())
|
||||
financialEventId String
|
||||
financialEvent FinancialEvent @relation(fields: [financialEventId], references: [id], onDelete: Cascade)
|
||||
|
||||
playerId String
|
||||
player Player @relation(fields: [playerId], references: [id])
|
||||
|
||||
amount Float
|
||||
status PaymentStatus @default(PENDING)
|
||||
paidAt DateTime?
|
||||
method String? // PIX, CASH
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@unique([financialEventId, playerId])
|
||||
}
|
||||
|
||||
enum FinancialEventType {
|
||||
MONTHLY_FEE
|
||||
EXTRA_EVENT
|
||||
CONTRIBUTION
|
||||
}
|
||||
|
||||
enum FinancialEventStatus {
|
||||
OPEN
|
||||
CLOSED
|
||||
CANCELED
|
||||
}
|
||||
|
||||
enum PaymentStatus {
|
||||
PENDING
|
||||
PAID
|
||||
WAIVED
|
||||
}
|
||||
47
prisma/seed.ts
Normal file
47
prisma/seed.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { PrismaClient } from '@prisma/client'
|
||||
import bcrypt from 'bcryptjs'
|
||||
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
async function main() {
|
||||
const password = await bcrypt.hash('Android@2020', 12)
|
||||
|
||||
// 1. Criar Admin
|
||||
await prisma.admin.upsert({
|
||||
where: { email: 'admin@temfut.com' },
|
||||
update: {},
|
||||
create: {
|
||||
email: 'admin@temfut.com',
|
||||
name: 'Super Admin',
|
||||
password: password,
|
||||
role: 'SUPER_ADMIN'
|
||||
}
|
||||
})
|
||||
|
||||
// 2. Criar Pelada de Exemplo
|
||||
await prisma.group.upsert({
|
||||
where: { email: 'erik@idealpages.com.br' },
|
||||
update: {},
|
||||
create: {
|
||||
name: 'Fut de Quarta',
|
||||
slug: 'futdequarta',
|
||||
email: 'erik@idealpages.com.br',
|
||||
password: password,
|
||||
status: 'ACTIVE',
|
||||
plan: 'PRO',
|
||||
primaryColor: '#10b981',
|
||||
secondaryColor: '#000000'
|
||||
}
|
||||
})
|
||||
|
||||
console.log('Seed concluído com sucesso!')
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((e) => {
|
||||
console.error(e)
|
||||
process.exit(1)
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect()
|
||||
})
|
||||
Reference in New Issue
Block a user