Araponga API • Developer Portal

Infraestrutura territorial para comunidades locais.

O Araponga é uma plataforma comunitária territory-first. O território organiza contexto, visibilidade e governança. Este portal documenta o produto e a API exatamente como implementada hoje, para acelerar o onboarding de desenvolvedores com segurança e previsibilidade.

Visão geral

API orientada a território + curadoria comunitária.

A API da Araponga cria um núcleo confiável para território, vínculos, feed e mapa. Ela prioriza regras explícitas (visibilidade, validação e moderação) para que experiências locais sejam auditáveis e evoluam com segurança.

Por que território?

Território é o recorte geográfico base. Ele separa o “onde” do “quem” e do “o quê”. Isso evita que conteúdo social distorça o mapa e mantém o contexto local como primeira-class.

Governança em camadas

Vínculos (visitor/resident), validações comunitárias e moderação (reports/bloqueios) formam as camadas que definem o que aparece no feed e no mapa.

Como o Araponga funciona

Do visitante ao morador validado

Visitante

Visitantes declaram vínculo com role=Visitor. O status já nasce como VALIDATED, permitindo participação básica e acesso a conteúdo público.

Pedido de moradia

Para virar morador, o usuário declara role=Resident. O vínculo fica PENDING até passar pela aprovação comunitária.

Aprovação comunitária

Apenas moradores VALIDATED do território podem aprovar pedidos via PATCH /api/v1/territories/{territoryId}/membership/{membershipId}/validation.

Fundador

Se ainda não existe nenhum morador validado no território, o primeiro residente é autoaprovado e se torna o fundador.

Territórios

Unidade primária com vínculo estrutural

Estado atual

Territórios continuam sendo a unidade primária de organização. Todo conteúdo e governança são ancorados diretamente no território selecionado.

ParentTerritoryId

O campo ParentTerritoryId existe apenas para modelar hierarquia estrutural (ex.: bairro → município). Ele ainda não gera herança de permissões, feeds ou validações.

Roadmap (não implementado)

Herança de permissões, feeds agregados e regras automáticas por hierarquia permanecem como roadmap e não fazem parte do backend atual.

Conceitos de produto

Semântica de negócio

Territory-first

Território é uma célula geográfica neutra. Não carrega conteúdo social embutido; ele apenas organiza contexto, priorização e governança.

Memberships

Vínculos entre usuário e território podem ser VISITOR ou RESIDENT. O status de verificação segue PENDING, VALIDATED ou REJECTED e influencia visibilidade e autorização.

Feature flags por território

Cada território pode habilitar flags como AlertPosts e EventPosts em /api/v1/territories/{territoryId}/features. Elas controlam quais tipos de post são aceitos.

Curadoria/Validação

A validação de vínculos de moradia é comunitária: apenas moradores VALIDATED aprovam pedidos. Curadores continuam responsáveis por validação de entidades do mapa e alertas ambientais.

Moderação & segurança

Reports e bloqueios moldam o que aparece no feed e no mapa. Bloqueios filtram o conteúdo de usuários bloqueados tanto no feed quanto em entidades do mapa criadas por eles. Limiares automáticos ainda não estão implementados no backend atual.

Modelo de domínio

Entidades principais e relacionamentos

Diagrama de relacionamento entre User, Territory, Membership, Feed, Map e Moderação
O diagrama resume as relações centrais implementadas hoje no backend.

O que liga com o quê

  • User cria identidade autenticada e recebe role (Visitor/Resident/Curator).
  • TerritoryMembership conecta User ↔ Territory e define role/status.
  • CommunityPost pertence ao Territory e pode referenciar MapEntity.
  • PostGeoAnchor ancora posts no mapa.
  • MapEntity pertence ao Territory, começa como sugerida e pode ser validada.
  • Reports e Blocks modulam visibilidade e segurança.
  • Feature Flags habilitam tipos de post por território (AlertPosts/EventPosts).

Por que existe

  • Separar território de identidade evita acoplamento social no mapa.
  • Vínculos explicitam presença local e governança comunitária.
  • Posts + geo anchors conectam feed e mapa sem confundir o domínio.
  • Moderação mantém confiança com regras auditáveis.
Fluxos principais

Sequências orientadas a produto e API

1. Autenticação social → JWT

Use POST /api/v1/auth/social com Provider, ExternalId, DisplayName e CPF ou ForeignDocument. A resposta traz o token JWT.

curl -X POST http://localhost:8080/api/v1/auth/social \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "google",
    "externalId": "abc-123",
    "displayName": "Ana Souza",
    "cpf": "12345678900",
    "email": "ana@exemplo.com"
  }'

2. Descoberta de território

GET /api/v1/territories lista territórios disponíveis. Para busca, use /search ou /nearby com lat e lng.

curl "http://localhost:8080/api/v1/territories/nearby?lat=-23.55&lng=-46.63&radiusKm=10"

3. Seleção de território (sessão)

Defina o território ativo com POST /api/v1/territories/selection usando X-Session-Id. Esse header substitui o territoryId em várias rotas.

curl -X POST http://localhost:8080/api/v1/territories/selection \
  -H "Content-Type: application/json" \
  -H "X-Session-Id: session-123" \
  -d '{"territoryId": "11111111-1111-1111-1111-111111111111"}'

4. Feed territorial

GET /api/v1/feed retorna posts filtrados pelo território ativo. Visitantes veem apenas posts públicos publicados. Moradores veem conteúdo ampliado.

curl http://localhost:8080/api/v1/feed \
  -H "Authorization: Bearer <token>" \
  -H "X-Session-Id: session-123"

5. Criar post + âncoras geográficas

Para criar post use POST /api/v1/feed. É obrigatório enviar X-Geo-Latitude/X-Geo-Longitude e ao menos uma âncora geográfica. Visitantes só podem criar posts do tipo Event (eventos pendentes de aprovação).

curl -X POST http://localhost:8080/api/v1/feed \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -H "X-Session-Id: session-123" \
  -H "X-Geo-Latitude: -23.55" \
  -H "X-Geo-Longitude: -46.63" \
  -d '{
    "title": "Mutirão de limpeza",
    "content": "Encontro sábado 9h.",
    "type": "Event",
    "visibility": "Public",
    "mapEntityId": null,
    "geoAnchors": [{"latitude": -23.55, "longitude": -46.63, "type": "EVENT"}]
  }'

6. Mapa: entidades, pins e validação

Use GET /api/v1/map/entities e /pins para visualizar. Sugestões usam POST /api/v1/map/entities (categorias: estabelecimento, órgão do governo, espaço público, espaço natural). Confirmações usam /confirmations e validações /validation são exclusivas para curadores.

curl -X POST http://localhost:8080/api/v1/map/entities \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -H "X-Session-Id: session-123" \
  -d '{
    "name": "Praça Central",
    "category": "espaço público",
    "latitude": -23.55,
    "longitude": -46.63
  }'

7. Membership: visitor → resident

POST /api/v1/territories/{territoryId}/membership declara vínculo. A validação (morador) é feita por moradores validados em /validation. O status atual está em GET /api/v1/territories/{territoryId}/membership/me. Se não houver morador validado, o primeiro residente é autoaprovado como fundador. Quando a policy exige presença, envie X-Geo-Latitude/X-Geo-Longitude.

8. Moderação: reports e bloqueios

Reports podem ser enviados para posts e usuários. Bloqueios removem conteúdo do feed e do mapa de quem foi bloqueado. Use POST /api/v1/reports/posts/{postId}, POST /api/v1/reports/users/{userId} e POST /api/v1/blocks/users/{userId}.

Autenticação

JWT (HS256)

O token é emitido pelo endpoint /api/v1/auth/social. Ele utiliza algoritmo HS256 e valida issuer e audience conforme configuração em appsettings.json.

Configuração Chave Local
Issuer Jwt:Issuer backend/Araponga.Api/appsettings.json
Audience Jwt:Audience backend/Araponga.Api/appsettings.json
SigningKey Jwt:SigningKey backend/Araponga.Api/appsettings.json
Erro 401: token ausente, inválido, expirado ou com issuer/audience incorretos. Em geral, autorizações negadas retornam 401, mas a validação de membership sem morador validado retorna 403.
Contexto e headers

Território, sessão e geolocalização

Várias rotas aceitam o território via territoryId na query ou via sessão com X-Session-Id. Além disso, algumas operações exigem presença geográfica.

Header Uso Onde é obrigatório
X-Session-Id Seleciona território ativo da sessão. Feed, Mapa, Health, Moderação quando territoryId não está na query.
X-Geo-Latitude / X-Geo-Longitude Comprova presença no território. Criação de posts e declaração de membership conforme policy.
PresencePolicy: a exigência de geolocalização para membership é configurada em PresencePolicy:Policy. O valor padrão atual é ResidentOnly.
OpenAPI

API Explorer (Swagger UI local)

O explorer usa a especificação real da API. Ele tenta carregar o Swagger dinâmico em /swagger/v1/swagger.json (quando o backend roda em Development) e usa fallback para ./openapi.json. A navegação é feita por tags, endpoints e schemas.

Baixar OpenAPI (JSON)

Explorer pronto para carregar.

Erros & convenções

Como interpretar respostas

Formato de erro

Erros de validação costumam retornar {"error": "mensagem"}. Exceções não tratadas retornam ProblemDetails com title, status, detail, traceId e path.

Códigos comuns

  • 400 dados inválidos ou headers obrigatórios ausentes.
  • 401 token ausente/ inválido ou falta de permissão.
  • 404 recurso inexistente (territory, post, user).
  • 409 não usado atualmente.
  • 500 exceções não tratadas (ProblemDetails).
Health check: GET /health responde {"status": "ok"} e GET /api/v1/health/indicators exibe indicadores do território ativo. Logs seguem a configuração padrão de Logging no appsettings.json.
Quickstart

Copie e cole (5–10 comandos)

# 1) Rodar API ASPNETCORE_ENVIRONMENT=Development dotnet run --project backend/Araponga.Api --urls http://localhost:8080 # 2) Autenticação social (gera token) curl -X POST http://localhost:8080/api/v1/auth/social \ -H "Content-Type: application/json" \ -d '{"provider":"google","externalId":"abc-123","displayName":"Ana","cpf":"12345678900"}' # 3) Descobrir território curl http://localhost:8080/api/v1/territories # 4) Selecionar território (X-Session-Id) curl -X POST http://localhost:8080/api/v1/territories/selection \ -H "Content-Type: application/json" \ -H "X-Session-Id: session-123" \ -d '{"territoryId":"11111111-1111-1111-1111-111111111111"}' # 5) Listar feed curl http://localhost:8080/api/v1/feed \ -H "Authorization: Bearer <token>" \ -H "X-Session-Id: session-123" # 6) Listar pins do mapa curl http://localhost:8080/api/v1/map/pins \ -H "Authorization: Bearer <token>" \ -H "X-Session-Id: session-123"
Versões & compatibilidade

Versionamento

A API atual utiliza prefixo /api/v1. Mudanças compatíveis devem manter o contrato dentro dessa versão. Para evolução maior, a estratégia recomendada é introduzir um novo prefixo.

Consulte o changelog do repositório em /CHANGELOG.md para histórico.