Pular para o conteúdo principal

Data Model

This document describes the actual data model implemented in the Taça UA platform, derived from the SQLAlchemy models across all microservices.


Database Architecture

The system uses a single PostgreSQL instance with schema-level isolation per microservice. Each service owns its schema exclusively for writes. A shared public_read schema serves as the read model for the Public API.

SchemaOwnerPurpose
modalitiesModalities ServiceCore domain entities: nucleos, courses, sport types, teams, members
matchesMatches ServiceMatch lifecycle, participants, lineups, comments
tournamentsTournaments ServiceTournament structure and competitors
rankingRanking ServiceScoring configuration and derived rankings
public_readRead Model UpdaterDenormalized read model consumed by the Public API

Every service also has an outbox_event table in its own schema for the transactional outbox pattern — events are written atomically with domain changes and relayed to RabbitMQ by a background publisher.


modalities Schema

Managed by the Modalities Service. This is the richest domain schema, holding the full organisational hierarchy.

Entity Hierarchy

Nucleo  (sports association)
└── Course (academic course, e.g. LEI, MECT)
└── Team (per modality, per course)
└── Student / Staff (members)

Tables

nucleo

Top-level organisational unit (e.g. "Núcleo de Engenharia").

ColumnTypeNotes
idUUID PK
nametext
abbreviationtextUnique
admins_idstext[]Array of admin user IDs
created_byUUID
created_at, updated_attimestamp

course

Academic course, always linked to a nucleo.

ColumnTypeNotes
idUUID PK
nametext
abbreviationtextUnique
nucleo_idUUID FK → nucleo.id
created_byUUID

modality_type

Sport category (e.g. "Futsal Masculino"). Defines the scoring tier structure.

ColumnTypeNotes
idUUID PK
nametextUnique
descriptiontextOptional
escaloesJSONArray of tier configs — each tier defines the number of participants and points awarded per finishing position
is_playoffbooleanWhether this type uses playoff brackets
created_byUUID

modality

A specific modality linked to a modality type.

ColumnTypeNotes
idUUID PK
nametextUnique
modality_type_idUUID FK → modality_type.id
created_byUUID

member (abstract base)

Single-table inheritance base for all people in the system.

ColumnTypeNotes
idUUID PK
full_nametext
member_typevarchar(50)Discriminator: "student" or "staff"
created_byUUID

student (extends member)

ColumnTypeNotes
idUUID FK → member.idPK
course_idUUID FK → course.id
student_numbertextUnique
is_memberbooleanAAUAv membership validation flag

staff (extends member)

Technical staff (coaches, managers), distinct from athletes.

ColumnTypeNotes
idUUID FK → member.idPK
staff_numbertextOptional, unique
contacttextOptional, unique

team

A course's team for a specific modality.

ColumnTypeNotes
idUUID PK
(FK to course and modality)UUID
created_byUUID

matches Schema

Managed by the Matches Service.

match

ColumnTypeNotes
idUUID PK
tournament_idUUIDFK (indirect)
statusenumscheduled, in_progress, finished, cancelled
scheduled_attimestamp
locationtext

match_participant

A team or individual entered in a match.

ColumnTypeNotes
idUUID PK
match_idUUID FK → match.id
participant_typeenumteam or individual
entity_idUUIDTeam or student ID

lineup

Players selected for a specific match by a Core Admin.

ColumnTypeNotes
idUUID PK
match_idUUID FK
student_idUUID
jersey_numberintOptional equipment number

comment

Free-text notes attached to a match by Core Admins.


tournaments Schema

Managed by the Tournaments Service.

tournament

ColumnTypeNotes
idUUID PK
modality_idUUID
nametext
statusenumdraft, active, finished

tournament_competitor

A team (or individual) entered in a tournament.

tournament_ranking_position

Final position per competitor after tournament ends.


ranking Schema

Managed by the Ranking Service. Holds scoring configuration and derived ranking tables.

modality_type_escaloes

The tier point table — core of the scoring system.

ColumnTypeNotes
modality_type_idUUID
min_participants, max_participantsintSize range for this escalão (tier)
pointsint[]Points awarded per finishing position (index 0 = 1st place)

Derived ranking tables

TableKey columns
tournament_results(tournament_id, competitor_id)position
general_rankingscourse_idpoints (sum across all sports)
modality_rankings(modality_id, course_id)points
course_rankingscourse_idpoints + modality_breakdown (int[])

Shadow copies of modality_types, modalities, tournaments, tournament_competitors and courses are maintained locally to avoid cross-schema joins.


public_read Schema

Managed by the Read Model Updater, which consumes RabbitMQ events and keeps this schema in sync. This is the only schema read by the Public API.

Core tables (mirrors of domain data)

nucleos, courses, modality_types, modalities, students, staff, teams, team_players, tournaments, tournament_competitors, tournament_rankings, matches, match_participants, match_results, match_lineups, match_comments

Materialized views (denormalized for fast reads)

ViewUsed for
mv_team_detailsFull team info including course and nucleo
mv_student_detailsStudent with course, nucleo, membership status and teams
mv_tournament_detailsTournament with modality and season info
mv_match_detailsMatch with participants, scores and tournament context
mv_tournament_standingsOrdered standings per tournament
mv_general_rankingAggregated course points across all tournaments