KOLOS — Onda 3.1 (Booking): Modelo, Conflitos e Rotas
Documentação KOLOS

KOLOS — Onda 3.1 (Booking): Modelo, Conflitos e Rotas

Contexto

A Onda 3.1 é o motor de tempo do KOLOS: sem uma reserva consistente (Booking) não existe agenda, manutenção, day use nem competição.

O risco principal aqui é o clássico double booking (duas reservas para a mesma quadra no mesmo horário), incluindo cenários de concorrência.

Decisão

Implementar a fundação de Booking com:

  • Modelo Booking (entidade) com court, created_by_user, timeslot, type, status.
  • Regra de conflito por sobreposição de intervalo (overlap) no mesmo court_id.
  • Dupla camada de proteção:
    1. Validação na Action (mensagem de erro clara)
    2. Constraint no PostgreSQL (garantia final contra race condition)

Modelo (mínimo)

Entidade: Booking

Campos mínimos:

  • id (UUID)
  • court_id (UUID)
  • created_by_user_id (int)
  • type (enum/string):
    • BOOKING
    • MAINTENANCE
  • status (enum/string):
    • CONFIRMED
    • (futuro) CANCELLED
  • starts_at (timestamp com timezone)
  • ends_at (timestamp com timezone)

Invariante: ends_at > starts_at.

Regras de Conflito (Conflict Solver)

Uma reserva conflita quando, para o mesmo court_id:

  • starts_at < existing_ends_at e ends_at > existing_starts_at

O intervalo é tratado como [start, end) (inclusivo no início e exclusivo no fim), evitando conflito quando um booking termina exatamente no horário que outro começa.

Persistência (PostgreSQL)

Além da validação na Action, o PostgreSQL deve impedir overlap via exclusion constraint usando tstzrange.

  • Constraint (conceito):
    • EXCLUDE USING gist (court_id WITH =, tstzrange(starts_at, ends_at, '[)') WITH &&)

Nota: em ambientes de teste (SQLite) a constraint não existe; a validação na Action continua garantindo a regra.

Rotas e Acesso (MVP)

Mundo Player

  • GET /booking (booking)
    • Middleware: auth + role:player
    • Permite criar BOOKING para quadras ativas.

Mundo Venue Owner (Maintenance)

Nesta onda, a criação de MAINTENANCE será limitada a venue_owner/super_admin e dependerá de Policy (escopo por dono da arena).

Importante: staff ainda não possui vínculo/escopo de arena modelado (membership). Qualquer liberação sem esse vínculo seria incorreta.

Entregáveis desta onda

  • Migration bookings + constraint no Postgres.
  • CreateBookingAction + CreateBookingData.
  • Testes de conflito (overlap) e casos válidos.
  • UI mínima em Livewire/Flux na página /booking para criar e listar reservas.

Validação

  • sail bin pint
  • sail bin phpstan analyse
  • sail artisan test

Próximos passos (Onda 3.2)

  • Integrar Finance (wallet/transactions) a partir do Booking.
  • Evoluir tipos: DAY_USE, OPEN_MATCH, etc.
  • Membership do staff por arena para escopo correto em maintenance.