# Auth/RBAC por App Membership em `/api/v1/data`

Atualizado em: 2026-02-27

## Objetivo
Garantir isolamento de acesso por `app` e por papel do usuario em todas as rotas `GET/POST/PATCH/DELETE` de `/api/v1/data/*`, com suporte a restricao por propriedade (`constraint_property`) quando configurada.

## Status Atual

### Implementado
- Enforce global no BFF Nuxt para toda rota `/api/v1/data/*`.
- Decisao de acesso central no Laravel via `GET /api/v1/auth/app-access/{appName}`.
- Aplicacao de constraint por dado nos handlers de:
  - listagem;
  - lookup;
  - dashboard metrics;
  - leitura por id;
  - update por id;
  - delete por id;
  - create.
- Suporte a aliases de app (`-` e `_`) na validacao.
- Suporte a membership curinga `app='*'` no endpoint `app-access` (acesso global por membership).
- Usuarios privilegiados com membership `owner` em todos os apps conhecidos e tambem em `task-board`/`task_board`.

### Ajuste de abilities
- Como o schema atual de `users` neste ambiente nao possui colunas `role` e `custom_abilities`, o calculo de abilities globais foi adaptado:
  - se houver membership ativo `app='*'` com role `owner/admin`, `allAbilities()` retorna `['*']`.
- Resultado esperado apos novo login: `abilities` no auth devem incluir `*`.

## Plano Tecnico por Camadas

### 1) Frontend
- Continuar enviando `auth_token` (cookie) e/ou `Authorization: Bearer`.
- Enviar contexto de `app` quando necessario (`?app=` ou `x-fastapp-app`) em casos ambiguos.
- Exibir UX consistente:
  - `401` para sessao/token invalido;
  - `403` para bloqueio de escopo/permissao.

### 2) Backend (Nuxt BFF)
- Middleware `server/middleware/rbac-data-scope.ts`:
  - intercepta `/api/v1/data/*`;
  - resolve `object` e `action` (`read/create/update/delete/lookup/metrics`);
  - resolve `app` por query/header/referer + metadata do objeto;
  - valida no Laravel (`/api/v1/auth/app-access/{app}`), com fallback em `/api/v1/auth/me` para compatibilidade;
  - injeta escopo em `event.context.rbacDataScope`.
- Utilitario `server/utils/rbac-data-scope.ts`:
  - injeta constraint no `where`;
  - injeta/valida constraint no body de escrita;
  - valida registro por `id` dentro do escopo;
  - injeta constraint na query forward para fontes externas.

### 3) Backend (Laravel API)
- Endpoint `GET /api/v1/auth/app-access/{appName}`:
  - valida membership no app solicitado;
  - considera aliases e membership curinga `*`;
  - resolve permissao por role + acao + objeto;
  - aplica fallback conservador para leitura quando nao ha matriz de permissao;
  - retorna `constraint` quando existir `constraint_property`.

### 4) Schema
- `fastapp_permission` deve manter convencao de nomes de permissao:
  - `objeto-read|create|update|delete`, `data.read`, `data:create`, etc.
- Para escopo por dono/equipe, preencher `constraint_property` (ex.: `owner_id`, `team_id`).

### 5) Dados
- `fastapp_user_app` e a fonte principal de autorizacao por app.
- Para acesso total administrado por membership, manter:
  - memberships por app com role `owner`; ou
  - membership curinga `app='*'` com role `owner`.
- Garantir `reference_id`/`reference_object` quando `constraint_property` exigir.

## Criterios de Aceite
1. Sem token, qualquer rota `/api/v1/data/*` retorna `401`.
2. Sem membership valido no app (nem curinga `*`), retorna `403`.
3. Com membership `owner/admin`, operacoes `POST/PATCH/DELETE` sao permitidas.
4. Com membership de leitura apenas, escrita retorna `403`.
5. Com `constraint_property`, leitura e escrita respeitam o escopo por registro.
6. Com membership curinga `*` role `owner`, acesso deve funcionar em app novo sem cadastro manual previo.
7. `GET /api/v1/auth/me` e login devem refletir `abilities: ['*']` para usuario com membership curinga `*` owner/admin (apos novo login/token).

## Validacao de Regressao
1. Smoke por rota:
   - `GET /api/v1/data/:object`
   - `POST /api/v1/data/:object`
   - `GET /api/v1/data/:object/:id`
   - `PATCH /api/v1/data/:object/:id`
   - `DELETE /api/v1/data/:object/:id`
   - `GET /api/v1/data/:object/lookup`
   - `GET /api/v1/data/:object/dashboard-metrics`
2. Matriz de papeis por app:
   - `owner/admin/member/viewer` x `read/create/update/delete`.
3. Casos de app ambiguo:
   - mesmo `object` em apps diferentes com `?app=` distinto.
4. Casos de aliases:
   - `task-board` vs `task_board`;
   - `central-filtros` vs `central_filtros`.
5. Caso curinga:
   - usuario com app `*` consegue acessar app nao previamente cadastrado no membership nominal.
6. Fontes externas:
   - confirmar forward de constraint e bloqueio por membership.
7. Nao regressao funcional:
   - envelope legado `{ total, limit, skip, data }` preservado.

## Observacoes
- O projeto legado `api-fastapp-cloud` nao entra no fluxo ativo.
- Base ativa considerada: `laravel-api`.
- O typecheck global do `lead-nuxt` possui erros preexistentes fora deste escopo; validar regressao focando nas rotas RBAC e no fluxo de auth.
