Initial project import
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
# Prompt 06 — Painel Cliente (escritório): condomínios, contatos, espaços comuns, assembleias, documentos
|
||||
|
||||
## Contexto
|
||||
Prompts 01–05 concluídos: autenticação completa, painel master funcionando, empresas sendo provisionadas com tenant próprio. **Leia `10-tracker-progresso.md` antes de começar.**
|
||||
|
||||
Este prompt implementa o CRUD principal do menu **Cliente → Cadastro Condomínio**, que é o coração do sistema: condomínios, contatos (síndico/subsíndico/conselheiro), vínculo de funcionários, espaços comuns, assembleias e documentos.
|
||||
|
||||
Todos os endpoints deste prompt exigem `exigirFuncionario` (Prompt 04) e operam sobre o `db_empresa_<slug>` do `empresa_id` do token (usar `TenantDataSourceProvider` do Prompt 03).
|
||||
|
||||
## Objetivo
|
||||
CRUD completo de `condominios`, `contatos` + `contato_condominio`, `funcionario_condominio`, `espacos_comuns`, `assembleias`, `documentos` (upload de arquivo).
|
||||
|
||||
## Especificação
|
||||
|
||||
### 1. Condomínios
|
||||
```
|
||||
POST /api/condominios body: {"nome", "cnpj", "endereco"}
|
||||
GET /api/condominios lista todos do tenant
|
||||
GET /api/condominios/{id}
|
||||
→ resposta agregada: dados do condomínio + síndico atual (via ContatoCondominioDao) +
|
||||
contagem de assembleias futuras + contagem de avisos ativos (isso é o "checklist"
|
||||
que o funcionário usa como referência rápida)
|
||||
PUT /api/condominios/{id}
|
||||
```
|
||||
|
||||
### 2. Contatos (síndico/subsíndico/conselheiro)
|
||||
```
|
||||
POST /api/contatos body: {"nome", "telefone", "email"}
|
||||
→ cria a pessoa (sem vínculo ainda)
|
||||
POST /api/condominios/{id}/contatos/vincular
|
||||
body: {"contato_id" (ou dados de um contato novo pra criar+vincular numa chamada só),
|
||||
"tipo": "sindico"|"subsindico"|"conselheiro",
|
||||
"data_inicio_mandato", "data_fim_mandato"}
|
||||
→ grava em contato_condominio; se marcar tipo=sindico e já existir outro síndico ativo
|
||||
pro mesmo condomínio, perguntar/forçar: por padrão, encerrar automaticamente o mandato
|
||||
anterior (status='inativo', data_fim_mandato=hoje) e ativar o novo — deixar isso
|
||||
documentado no código como decisão de negócio
|
||||
GET /api/condominios/{id}/contatos lista todos os vínculos ativos daquele condomínio
|
||||
DELETE /api/condominios/{id}/contatos/{contatoId}?tipo=... (desvincula — não apaga o contato,
|
||||
só remove o vínculo daquele condomínio/tipo específico; um contato pode continuar
|
||||
vinculado a outros condomínios)
|
||||
```
|
||||
|
||||
### 3. Funcionários vinculados a condomínios
|
||||
```
|
||||
POST /api/condominios/{id}/funcionarios-vinculados
|
||||
body: {"funcionario_id"} (funcionario precisa existir em db_master, mesma empresa)
|
||||
GET /api/condominios/{id}/funcionarios-vinculados
|
||||
DELETE /api/condominios/{id}/funcionarios-vinculados/{funcionarioId}
|
||||
```
|
||||
|
||||
### 4. Espaços comuns
|
||||
```
|
||||
POST /api/condominios/{id}/espacos-comuns
|
||||
body: {"nome", "descricao", "valor_utilizacao_centavos", "indice_correcao"}
|
||||
GET /api/condominios/{id}/espacos-comuns
|
||||
PUT /api/condominios/{id}/espacos-comuns/{espacoId}
|
||||
→ se o valor mudar, atualizar data_ultimo_reajuste=hoje automaticamente
|
||||
```
|
||||
|
||||
### 5. Assembleias
|
||||
```
|
||||
POST /api/condominios/{id}/assembleias
|
||||
body: {"tipo", "data_hora", "local", "pauta"}
|
||||
GET /api/condominios/{id}/assembleias (ordenar por data_hora desc)
|
||||
PUT /api/condominios/{id}/assembleias/{id} (inclui mudar status: agendada/realizada/cancelada)
|
||||
```
|
||||
|
||||
### 6. Documentos (upload)
|
||||
```
|
||||
POST /api/condominios/{id}/documentos multipart/form-data: arquivo + tipo
|
||||
→ salvar o arquivo em um diretório local montado como volume Docker (ex: /app/uploads/
|
||||
<empresa_slug>/<condominio_id>/<uuid>-<nome_original>), gravar caminho_armazenamento
|
||||
com esse path relativo
|
||||
→ validar extensão (permitir: pdf, jpg, jpeg, png, docx) e tamanho máximo (ex: 10MB)
|
||||
GET /api/condominios/{id}/documentos
|
||||
GET /api/documentos/{id}/download → serve o arquivo (Content-Disposition: attachment)
|
||||
```
|
||||
Adicionar o volume de uploads no `docker-compose.yml` do Prompt 01 (`./uploads:/app/uploads`).
|
||||
|
||||
### 7. Auditoria
|
||||
Toda operação de `POST`/`PUT`/`DELETE` deste prompt deve gravar uma linha em `log_auditoria` (tabela_afetada, registro_id, ação, dados_anteriores/dados_novos em JSON, funcionario_id do token).
|
||||
|
||||
## Critérios de aceite
|
||||
- [ ] Criar um condomínio, vincular um síndico e um subsíndico, e chamar `GET /api/condominios/{id}` mostra o síndico atual corretamente.
|
||||
- [ ] Vincular um segundo síndico ao mesmo condomínio encerra automaticamente o mandato do primeiro (`status='inativo'`).
|
||||
- [ ] O mesmo `contato` pode ser vinculado como síndico em dois condomínios diferentes simultaneamente.
|
||||
- [ ] Upload de um PDF funciona; upload de um `.exe` é rejeitado com erro claro; upload de 15MB é rejeitado.
|
||||
- [ ] `log_auditoria` recebe uma linha para cada operação de escrita feita neste prompt (testar com pelo menos 3 operações diferentes).
|
||||
- [ ] Todos os endpoints só retornam/alteram dados do `empresa_id` do token — tentar acessar `/api/condominios/{id}` de outra empresa retorna 404 (não 403 — não revelar que o ID existe em outro tenant).
|
||||
|
||||
## Ao concluir
|
||||
Atualizar `10-tracker-progresso.md`: Prompt 06 concluído, data, resumo. Confirmar Prompts 01–05 seguem marcados.
|
||||
Reference in New Issue
Block a user