Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Danielsl4/TFG_DAM_2526/llms.txt

Use this file to discover all available pages before exploring further.

FutsalLeague Manager uses PostgreSQL as its primary data store. The repository includes an initialization script that creates all 15 tables and their associated ENUM types in the correct dependency order. This guide takes you from a blank PostgreSQL instance to a fully initialized database ready for the backend API.

Prerequisites

  • PostgreSQL 14 or newer — earlier versions are untested.
  • The unaccent extension, which ships with the standard postgresql-contrib package on most distributions. It is required for accent-insensitive username and search queries used by the auth and player search endpoints.
The unaccent extension must be enabled in the target database before running init_db.js. The backend’s auth queries use unaccent() directly in SQL, so the API will fail to handle login and registration if the extension is missing.

Create the database and enable extensions

Connect to PostgreSQL as a superuser and run:
CREATE DATABASE futsalleague;
\c futsalleague
CREATE EXTENSION IF NOT EXISTS unaccent;

Connection pooling

The backend connects via pg.Pool configured in db.js with the following settings:
SettingValueDescription
connectionStringDATABASE_URL env varFull PostgreSQL connection string
max50Maximum concurrent connections in the pool
idleTimeoutMillis30000Connections idle for 30 s are closed
connectionTimeoutMillis5000Acquiring a connection times out after 5 s
ssl.rejectUnauthorizedfalseAccepts self-signed certificates (suitable for managed cloud databases)
Set DATABASE_URL in your environment before starting the API:
DATABASE_URL=postgresql://user:password@localhost:5432/futsalleague

Run the initialization script

From the backend/ directory, run:
node init_db.js
The script creates all ENUM types and 15 tables using CREATE TABLE IF NOT EXISTS, so it is safe to re-run against an existing database — it will not drop or alter existing data. On success it prints:
Starting table creation...
All tables have been created successfully.

Schema overview

ENUM types

TypeValues
match_phasefase_de_grupos, octavos, cuartos, semis, final
match_statuspendiente, en_curso, finalizado
event_typegol, tarjeta_amarilla, tarjeta_roja
roleadmin, referee, user
vote_typelocal, empate, visitante

Tables

seasons

Season records. The is_active boolean identifies the current season. All other tables reference season_id for data partitioning.

groups

Competition groups within a season. Cascades delete from seasons.

teams

Team master records including kit color, logo URL, delegate, coach, and phone. Soft-deleted via is_active.

players

Player master records with birth date and photo URL. Soft-deleted via is_active.

team_players

Player–team–season association with jersey numbers. Enforces UNIQUE(team_id, player_id, season_id) so a player can only appear once per team per season.

fields

Playing fields and venues. Soft-deleted via is_active.

matches

Match records including home/away teams, group, season, field, date, goal tallies, penalty goals, phase, status, observations, and referee lock info. Enforces home_team_id <> away_team_id.

match_events

Individual in-match events (goals, yellow cards, red cards) linked to a player and match.

users

User accounts with hashed passwords, roles, email verification status, verification token, and password-reset token with expiry.

user_points

Prediction points per user per season. Composite primary key (user_id, season_id).

team_followers

Many-to-many follow relationship between users and teams. Composite primary key (user_id, team_id).

team_stats

Aggregated team statistics (played, won, drawn, lost, goals for/against, points, cards) per group per season. Enforces UNIQUE(team_id, group_id, season_id).

player_stats

Aggregated player statistics (goals, cards, matches played) per season. Enforces UNIQUE(player_id, season_id).

match_votes

User match predictions (local / draw / away). Enforces UNIQUE(match_id, user_id) so each user casts at most one vote per match.

audit_logs

Admin action audit trail. Stores the acting user, action name, entity type, entity ID, and a JSONB details blob with a timestamp.

Key constraints

TableConstraintPurpose
team_playersUNIQUE(team_id, player_id, season_id)Prevents duplicate player registrations per team per season
match_votesUNIQUE(match_id, user_id)Ensures one prediction per user per match
team_statsUNIQUE(team_id, group_id, season_id)One stats row per team per group per season
player_statsUNIQUE(player_id, season_id)One stats row per player per season
matchesCHECK (home_team_id <> away_team_id)Prevents a team from being scheduled against itself
usersUNIQUE on username and emailEnforces unique accounts

Backup considerations

Because stats tables (team_stats, player_stats) are derived from match events, a full pg_dump of all tables is the safest backup strategy:
pg_dump -U your_user -d futsalleague -F c -f futsalleague_backup.dump
Restore with:
pg_restore -U your_user -d futsalleague futsalleague_backup.dump

Build docs developers (and LLMs) love