# Auditoria Completa — Sinapse (Jarvis + A.R.C.A + MV Members)
**Data:** 30/06/2026 | **Auditor:** OpenClaw (Claude Opus 4.6)

---

## RISCOS CRITICOS TRANSVERSAIS (afetam os 3 projetos)

### 1. Servidor SEM firewall — portas de banco/cache expostas na internet
Todos os 3 projetos expoem PostgreSQL, Redis e outros servicos em `0.0.0.0`. UFW esta **inativo**, iptables policy = ACCEPT. Qualquer pessoa na internet pode conectar diretamente nos bancos.

| Projeto | Portas expostas |
|---|---|
| Jarvis | PG 5433, Redis 6380, Qdrant 6334, Whisper 8090 |
| A.R.C.A | PG 5432, Qdrant 6333, Portainer 9000 |
| MV Members | PG 5440, Redis 6385 (sem senha!), MinIO 9010/9011 |

**Acao:** `ufw enable` + regras allow 22/80/443 + bind `127.0.0.1` nos docker-compose. **30 min resolve tudo.**

### 2. Secrets em texto plano sem rotacao
Os 3 `.env` tem chaves Anthropic, Hotmart, Stripe, etc. em texto plano. O MV Members tem JWT secret previsivel (`mv-members-jwt-secret-change-in-production-2026`).

### 3. Backup incompleto
- **Jarvis:** crontab vazio, zero backup automatizado
- **A.R.C.A:** diretorio de backup nao existe, backup salva dentro de container efemero
- **MV Members:** sem backup nenhum

O sinapse-backup cobre Jarvis e A.R.C.A nos dumps, mas o script precisa ser auditado pra confirmar que realmente roda.

---

## JARVIS — Detalhamento

### Riscos Criticos
| # | Problema | Arquivo |
|---|---|---|
| RC-2 | **40+ endpoints sem auth** — DynamicForm, GanttPro (incluindo IA que queima creditos), Quiz, Analytics, Meetings — todos publicos | `dynamicform.py`, `ganttpro.py`, `quiz_funnel.py`, `analytics.py` |
| RC-3 | Upload de arquivos sem auth e sem validacao de tipo | `dynamicform.py:1110` |
| RC-4 | Docker socket montado no backend (RCE = root escape) | `docker-compose.yml:89` |
| RC-7 | CORS `allow_origins=["*"]` | `main.py:885` |

### Bugs
| # | Problema |
|---|---|
| B-1 | SQL dinamico com f-string em `chat.py:2341` — fragil |
| B-2 | Auth do modulo Direcao e hash estatico sem expiracao |
| B-4 | Modelo Claude hardcoded `claude-haiku-4-5-20251001` — vai quebrar quando deprecar |
| B-6 | `create_all()` roda em producao (deveria ser Alembic) |
| B-7 | 525 blocos `except Exception` expoem detalhes internos |

### Performance
| # | Problema |
|---|---|
| P-1 | HTTP clients criados por request em 5 conectores (Gmail, Panda, GitHub, CAPI, Notion) |
| P-2 | Notion/Drive carregam dados ilimitados em memoria |
| P-3 | Sem paginacao em listagens (GanttPro, DynamicForm) |
| P-4 | FKs sem indice (meetings, tasks, financial, ganttpro) |
| P-6 | `ganttpro.py` = 7.825 linhas, `analytics.py` = 3.992 linhas |

### Propostas
1. **Middleware de auth global** — proteger `/api/` inteiro com allowlist de endpoints publicos (4-8h)
2. **Rate limiting** — SlowAPI/Redis: login 5/min, IA 20/min, upload 10/min
3. **Docker socket proxy** — substituir montagem direta por proxy restritivo
4. **Git flow** — repo tem zero commits, qualquer mudanca e irreversivel

### Divida Tecnica
- Token refresh duplicado 5x no frontend `api.js`
- IP/dominio hardcoded no frontend
- Access token 24h (deveria ser 15-60min)
- Embedding fallback produz vetores sem semantica

---

## A.R.C.A — Detalhamento

### Riscos Criticos
| # | Problema | Arquivo |
|---|---|---|
| RC-3 | Admin panel usa senha estatica em vez de JWT | `admin.py:89-94` |
| RC-4 | JWT expira em 30 dias sem refresh token | `config.py:49` |
| RC-5 | **Diagnosticos NAO criptografados** — `diagnoses`, `observations`, `sex` em texto plano (LGPD Art. 11) | `patient.py:22-24` |
| RC-6 | Webhook Panda aceita requests sem token valido | `webhook.py:38-42` |
| RC-8 | Swagger/docs exposto em producao | `nginx/arca_routes.inc` |

### Bugs
| # | Problema |
|---|---|
| B-1 | N+1 query na listagem de pacientes |
| B-2 | Busca por nome descriptografa TODOS pacientes em memoria |
| B-3 | 124 ocorrencias de `except Exception: pass` |
| B-4 | code-server consumindo 66% CPU e 4.2GB RAM (container orfao) |
| B-5 | waha-talk em 92% da memoria (235/256MB) — proximo de OOM |

### Performance
| # | Problema |
|---|---|
| P-1 | Indices ausentes em 8 tabelas criticas (patients.doctor_id, documents.doctor_id, audit_logs, etc.) |
| P-2 | Cache Redis subutilizado (so feature flags) |
| P-3 | Fernet recriado a cada operacao crypto |

### Propostas
1. **Criptografar diagnosticos e observacoes** — usar mesmo Fernet existente (2h)
2. **Implementar refresh tokens** com httpOnly cookie (4h)
3. **Alembic** — substituir 50+ `ALTER TABLE` no startup (4h)
4. **Backup automatizado com cron** (3h)
5. **Separar Whisper** em container dedicado (evitar OOM)

### Divida Tecnica
- Frontend em HTML/JS vanilla sem bundling
- Token JWT em localStorage (vulneravel a XSS)
- Service Worker cacheia paginas com dados clinicos
- Zero testes automatizados

---

## MV MEMBERS — Detalhamento

### Riscos Criticos
| # | Problema | Arquivo |
|---|---|---|
| RC-4 | **Sem HTTPS** — so listen 80, sem certificado SSL | `nginx/default.conf` |
| RC-5 | XSS via `dangerouslySetInnerHTML` sem sanitizacao | `LessonPlayer.tsx`, `Chat.tsx` |
| RC-6 | **Endpoint de aulas sem verificacao de acesso** — qualquer aluna autenticada acessa qualquer aula | `lessons.py:14` |

### Bugs
| # | Problema |
|---|---|
| B-1 | Webhook Hotmart bypassa validacao se HOTTOK vazio |
| B-2 | Eager loading carrega 6 tabelas em cada request autenticado |
| B-3 | Cascata Course>Module>Lesson>Progress (centenas de queries) |
| B-6 | pgvector embeddings com dimensoes erradas (1536 vs 384) — padding com zeros invalida busca |
| B-7 | Forgot-password troca senha diretamente (DoS — sem rate limit) |
| B-8 | Upload com path traversal via extensao do filename |

### Performance
| # | Problema |
|---|---|
| P-1 | Nenhuma FK tem `index=True` — full table scans |
| P-2 | RAG usa ILIKE sem indice (full table scan) |
| P-4 | Celery cria nova engine a cada task |
| P-5 | Whisper model carregado a cada transcricao |
| P-8 | Reports fazem N+1 extensivo (3 queries por aula) |

### Propostas
1. **HTTPS com Certbot** — urgente, trafego em texto plano (1h)
2. **Verificacao de acesso nas aulas** — adicionar check de enrollment (1h)
3. **DOMPurify** no frontend para sanitizar HTML (30min)
4. **URLs de video assinadas** — anti-pirataria no Panda Video
5. **Notificacao de expiracao** — email/WhatsApp 7/3/1 dias antes
6. **Busca vetorial funcional** — alinhar dimensoes e criar indice HNSW

### Divida Tecnica
- Admin.tsx monolitico com ~3500 linhas
- `is_admin` convive com `role` (inconsistente)
- Frontend `loadUser` confia em localStorage sem validar
- Containers sem `mem_limit`
- Swagger exposto em producao

---

## PLANO DE ACAO PRIORIZADO

### URGENTE (hoje)
| # | Acao | Esforco | Impacto |
|---|---|---|---|
| 1 | Ativar firewall + fechar portas expostas (3 projetos) | 30 min | Elimina acesso direto aos bancos |
| 2 | Rotacionar JWT secret do MV Members | 5 min | Impede forja de tokens |
| 3 | Configurar HTTPS no MV Members | 1h | Trafego deixa de ser texto plano |
| 4 | Verificar backup script do sinapse-backup | 15 min | Confirmar que dados estao protegidos |

### Esta semana
| # | Acao | Esforco |
|---|---|---|
| 5 | Auth nos endpoints do Jarvis (DynamicForm, GanttPro, Quiz) | 4-8h |
| 6 | Criptografar diagnosticos na A.R.C.A | 2h |
| 7 | Access check nas aulas do MV Members | 1h |
| 8 | Sanitizacao XSS no MV Members | 30min |
| 9 | Remover Docker socket do Jarvis | 30min |
| 10 | Restringir CORS do Jarvis | 15min |

### Proximo sprint
| # | Acao | Esforco |
|---|---|---|
| 11 | Indices em FKs (3 projetos) | 2-3h |
| 12 | Implementar refresh tokens (A.R.C.A + MV) | 4-6h |
| 13 | Rate limiting nos 3 projetos | 4h |
| 14 | Corrigir eager loading do MV Members | 3h |
| 15 | Alembic na A.R.C.A | 4h |

### Backlog
- Git flow no Jarvis (zero commits)
- Quebrar arquivos gigantes (ganttpro 7.8k linhas)
- Frontend build pipeline na A.R.C.A
- Suite de testes
- Monitoramento (Prometheus/Grafana)
