Status: Approved · v2 · SPEC-DOMAIN-FIELD-001
depends_on: SPEC-DOMAIN-TERRITORY-001, SPEC-DOMAIN-PERMISSION-001
used_by: IS-MVP-01.6, IS-MVP-13.1
Campos
Página pública e gestão básica de locais esportivos, com contato e partidas vinculadas.
Objetivo e limites
Esta especificação define o comportamento canônico do domínio Campos no RaizFC. Ela deve ser consultada antes de alterar contratos, mocks, endpoints, telas, permissões ou Increment Specifications relacionados.
Incluído no MVP
- Criação por autenticado.
- Distrito obrigatório e neighborhood opcional.
- Página pública, contato, galeria e jogos vinculados.
- Endereço público ou texto livre.
- Gestão e permissões.
Fora do MVP
- Agenda própria.
- Reserva.
- Pagamento.
- Carteira e sponsors.
- Mapa avançado.
Atores e responsabilidades
| Ator | Responsabilidade |
|---|---|
| Visitante | Consulta localização aproximada, contato e jogos. |
| Criador/gestor | Edita página, galeria e dados. |
| Gestor de partida | Vincula campo ou usa local livre. |
| Operação | Resolve duplicidade e denúncia. |
Conceitos canônicos
Field
Local esportivo cadastrado.
Free Location
Texto/endereço inserido diretamente em uma partida.
Address Visibility
public, approximate ou private; MVP prioriza public/text.
Field Claim
Reivindicação de página abandoned/inativa.
Invariantes
- Campo possui districtId.
- Neighborhood, se usado, pertence ao distrito.
- Criador vira primary_owner.
- Campo não possui wallet ou sponsors no MVP.
- Partida pode existir sem fieldId usando freeLocation.
- Alteração de um campo real vinculado a partida não muda automaticamente o snapshot histórico do jogo.
Estados
| Estado | Significado | Visibilidade/efeito |
|---|---|---|
| active | Disponível | Página normal. |
| inactive | Sem operação atual | Aviso público. |
| abandoned | Sem gestão | Reivindicável. |
| closed | Encerrado | Histórico. |
| suspended | Bloqueado | Página limitada. |
| duplicated_merged | Unificado | Redirect. |
Transições permitidas
| Origem | Ação | Destino | Autoridade | Efeitos |
|---|---|---|---|---|
| — | create | active | Autenticado | Owner e página. |
| active | deactivate | inactive | Owner/operação | Aviso. |
| active/inactive | mark_abandoned | abandoned | Operação | Reivindicação. |
| abandoned | approve_claim | active | Operação | Novo owner. |
| any | merge | duplicated_merged | Operação | Redirect. |
Permissões
| Permission key | Quem recebe por padrão | Ação protegida | Auditoria |
|---|---|---|---|
| field.editProfile | Admin/Owner | Editar | Sim |
| field.manageGallery | Media/Admin | Galeria | Sim |
| field.manageManagers | Admin/Owner | Acessos | Sim |
Fluxos funcionais
Criação
- Usuário informa nome, distrito, localização, contato e visibilidade.
- Sistema busca duplicados próximos por texto/território.
- Cria página active e owner.
Vínculo em partida
- Gestor pesquisa campo.
- Seleciona e salva fieldId com snapshot de nome/local.
- Edição posterior do campo não reescreve histórico sem ação explícita.
Reivindicação
- Usuário solicita página abandoned.
- Envia justificativa/evidência.
- Operação aprova e transfere owner.
Casos-limite e erros
| Cenário | Comportamento esperado | Código/estado |
|---|---|---|
| Possível duplicado | Sugerir página existente | FIELD_POSSIBLE_DUPLICATE |
| Endereço privado em página pública | Retornar apenas approximate/text seguro | FIELD_ADDRESS_PRIVATE |
| Campo suspenso em nova partida | Bloquear novo vínculo | FIELD_SUSPENDED |
| Neighborhood incompatível | Rejeitar | NEIGHBORHOOD_DISTRICT_MISMATCH |
Privacidade e exposição pública
- Contato e endereço têm visibilidade configurável.
- Jogos públicos podem revelar localização apenas no nível permitido.
- Solicitações de claim são privadas.
Notificações e auditoria
- Nova partida vinculada opcional para gestores.
- Denúncia/claim/status.
- Audit log de endereço e contato.
API relacionada
| Método | Rota | Acesso | Finalidade |
|---|---|---|---|
| POST | /api/v1/fields | Autenticado | Criar |
| GET | /api/v1/fields/:slug | Público | Página |
| PATCH | /api/v1/fields/:id | field.editProfile | Editar |
| GET | /api/v1/fields/:id/matches | Público | Jogos |
| POST | /api/v1/fields/:id/gallery | field.manageGallery | Mídia |
| GET | /api/v1/fields/:id/management-summary | Gestão | Resumo |
Contratos compartilhados
- FieldEntity
- PublicFieldDto
- FieldManagementDto
- FieldAddressDto
- AddressVisibility
- CreateFieldRequest
- UpdateFieldRequest
Requisitos de UX
- Página mostra identidade, localização conforme visibilidade, contato, jogos e galeria.
- Sem CTA de reserva no MVP; contato externo é claro.
- Gestão é simples e não simula agenda.
Comportamento dos mocks
- Campos active/inactive/abandoned/suspended.
- Endereço public/approximate/private.
- Jogos vinculados.
Critérios de aceite
- Distrito obrigatório.
- Sem wallet/sponsors.
- Partida aceita campo ou local livre.
- Snapshot histórico preservado.
- Privacidade do endereço respeitada.
Testes obrigatórios
- Criação/duplicidade.
- Address visibility.
- Vínculo/snapshot.
- Claim/status.
Pós-MVP
- Agenda, reservas, preços, pagamentos, mapa e disponibilidade.
Decisões registradas
- Campo é gerenciável.
- Página básica no MVP.
- Reserva fica pós-MVP.
Machine summary
spec: SPEC-DOMAIN-FIELD-001
domain: Campos
must_preserve:
- Campo possui districtId.
- Neighborhood, se usado, pertence ao distrito.
- Criador vira primary_owner.
- Campo não possui wallet ou sponsors no MVP.
- Partida pode existir sem fieldId usando freeLocation.
- Alteração de um campo real vinculado a partida não muda automaticamente o snapshot histórico do jogo.
touches:
- contracts
- mocks
- api
- frontend
- backend
- tests
- documentation