Pular para o conteúdo principal

Status: Approved · v2 · SPEC-API-PLAYER-001

depends_on: SPEC-DOMAIN-PLAYER-001, SPEC-DOMAIN-MATCH-001

used_by: IS-MVP-05.1, IS-MVP-05.2, IS-MVP-05.3

API do jogador

Perfil próprio, privacidade, vínculos, convites, confirmações de guest e estatísticas.

Princípios e padrões

  • Base path /api/v1; JSON UTF-8; chaves em camelCase.
  • Toda resposta usa ApiResponse<T> com ok, data|error e meta contendo requestId e timestamp.
  • IDs são strings opacas; datas são ISO-8601 UTC; dinheiro é inteiro em centavos com moeda BRL.
  • Listas usam page e pageSize no MVP; default 20, máximo 100; metadados ficam em meta.pagination.
  • Endpoints públicos usam DTOs públicos específicos; entidades internas, memberships, saldos e dados privados nunca vazam.
  • Erros de domínio são estáveis e acionáveis; stack traces e detalhes internos não são retornados.
  • Alterações sensíveis usam Idempotency-Key, confirmação recente quando necessário e audit log.
  • Uploads usam fluxo presigned; o backend valida propósito, MIME, tamanho e ownership antes de confirmar o asset.

Endpoints

MétodoRotaAcessoRequestResponseRegras principais
GET/players/meJogadorPlayerMeResponseDados privados e completeness.
PATCH/players/meJogadorUpdatePlayerProfileRequestPlayerMeResponsePosições, bio, contatos e availability.
PATCH/players/me/privacyJogadorUpdatePlayerPrivacyRequestPlayerPrivacyResponseMatriz explícita.
GET/players/me/team-linksJogadorPlayerLinkQueryTeamPlayerLinksResponseActive/former (implementado IS-MVP-05.2 reusando o TeamPlayerLinkDto compartilhado — ver nota).
GET/players/me/invitesJogadorPlayerInvitesResponsePending ordenados por invitedAt (sem campo de expiração ainda — ver nota).
POST/team-player-links/:linkId/respondJogador alvoRespondPlayerInviteRequestTeamPlayerLinkResponseAceita/rejeita (rota real — ver nota).
POST/team-player-links/:linkId/endJogador (vínculo ativo) ou team.manageSquadEndPlayerLinkRequestTeamPlayerLinkResponseVira former; jogador só encerra o próprio vínculo ativo.
GET/players/me/guest-confirmationsJogadorGuestConfirmationsResponsePossíveis históricos (IS-MVP-05.3).
POST/players/me/guest-confirmations/:id/respondJogadorGuestConfirmationRequestGuestConfirmationResponseConfirm/contest (IS-MVP-05.3).
GET/players/:playerId/statsPúblico conforme privacyStatsQueryPlayerStatsResponseSomente partidas validadas/confirmadas (IS-MVP-05.3).
GET/players/:playerId/historyPúblico conforme privacyHistoryQueryPlayerHistoryResponseTimes/campeonatos permitidos (IS-MVP-05.3).

IS-MVP-05.2: team-links/invites reutilizam TeamPlayerLinksResponse/TeamPlayerLinkDto (com categoryNames opcional, resolvido só nesta visão) em vez de tipos duplicados. Responder/encerrar vínculo reutilizam o recurso /team-player-links/:linkId/... já parcialmente implementado por IS-MVP-04.4 (SPEC-API-TEAM-TORCIDA-001) em vez de duplicar a mutação sob /players/me/invites/:linkId/... — as duas specs descreviam a mesma capacidade com rotas diferentes; esta reutiliza a família de rota já existente. TeamPlayerLinkDto não tem campo de expiração; a ordenação usa invitedAt como proxy até um mecanismo de expiração existir.

IS-MVP-05.3: GuestConfirmationDto referencia a partida com campos descritivos (categoryName/opponentName/matchDate) em vez de um matchId/publicRoute real — o domínio de gestão de partidas (EP-MVP-06.1) ainda não existe, e apontar para uma página de partida inexistente seria pior que um rótulo textual. A detecção do candidato compara CreateGuestPlayerRequest.privateContact (aceito desde IS-MVP-04.4 mas nunca persistido) com o contact do jogador já ativado; um match cria uma GuestConfirmationDto pendente. Confirmar converte o vínculo guest em registered/active (reaproveitando PublicPlayerRepositoryPort.updateTeamLinks, IS-MVP-05.2) e contribui uma linha determinística de stats (1 jogo, sem dado de partida real para compor uma quebra jogo a jogo) — recentMatches/championships permanecem vazios por falta de fonte real, não preenchidos com dado inventado. PlayerStatsDto/PlayerHistoryDto reutilizam PublicPlayerStatLineDto/PublicPlayerTeamLinkDto+PublicPlayerChampionshipDto (IS-MVP-01.2) em vez de duplicar formas.

Autenticação e autorização

  • Somente o próprio usuário altera perfil e privacy.
  • Times só criam vínculos; não editam perfil do jogador.
  • Stats públicas respeitam flags e guest confirmation.

Erros de domínio

CódigoHTTPQuando ocorreAção esperada no cliente
PLAYER_PROFILE_REQUIRED409Role/perfil ausenteAtivar jogador.
PROFILE_PRIVATE403Seção privadaOcultar.
GUEST_CONFIRMATION_MISMATCH422Evidência não corresponde (confirmação não pertence ao jogador)Contestar/suporte.
INVITE_ALREADY_RESOLVED409Decisão anterior (convite ou confirmação de guest já resolvidos)Atualizar.
GUEST_HISTORY_ALREADY_CLAIMED409Participação de convidado já associada a outro jogador (IS-MVP-05.3; listado em SPEC-DOMAIN-PLAYER-001 mas ausente desta tabela até agora)Atualizar/contestar.

Idempotência e concorrência

  • Responder convite/guest confirmation é idempotente.
  • Atualizações usam version para conflitos de edição.

Auditoria e efeitos colaterais

  • Privacy, status e vínculos geram audit do próprio usuário.
  • Invite response notifica time; contest guest gera pendência.

Exemplos

privacy

{
"profilePublic": true,
"contactsPublic": false,
"currentTeamsPublic": true,
"formerTeamsPublic": false,
"statsPublic": true,
"availabilityPublic": true
}

Mocks

  • Perfis completos/incompletos, private sections, invite/guest states.
  • Stats recalculadas em fixtures consistentes.

Testes obrigatórios

  • Privacy matrix.
  • Invite lifecycle.
  • Guest confirm associates history once.
  • Validated-only stats.
  • Player cannot be managed by third party.

Critérios de aceite

  • Painel próprio cobre todos os fluxos.
  • Dados privados nunca entram em public DTO/card/search.

Machine summary

spec: SPEC-API-PLAYER-001
api_group: API do jogador
base_path: /api/v1
response_envelope: ApiResponse<T>
ids: string
dates: ISO-8601
money: integer_cents