mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-02 05:12:11 +03:00
refactor: decompose usageDb, handleSingleModelChat, UI components (T-15, T-28, T-29)
T-15 — Decompose usageDb.js (969→40 lines): - Extract src/lib/usage/migrations.js (legacy + JSON→SQLite migration) - Extract src/lib/usage/usageHistory.js (tracking, pending, log.txt) - Extract src/lib/usage/costCalculator.js (pure cost calculation) - Extract src/lib/usage/usageStats.js (dashboard aggregation) - Extract src/lib/usage/callLogs.js (structured logs, CRUD, rotation) - usageDb.js is now a thin facade re-exporting all functions T-28 — Decompose handleSingleModelChat (183→80 lines): - Extract handleNoCredentials() — credential error responses - Extract safeResolveProxy() — proxy resolution with error handling - Extract safeLogEvents() — fire-and-forget proxy + translation logging - Also created chatHelpers.js with standalone helper exports T-29 — Extract shared UI primitives (3230 total lines): - FilterBar.js — search input + filter chips dropdown - ColumnToggle.js — table column visibility toggle - DataTable.js — generic data table with sticky header, loading/empty Tests: 88/88 pass (no regressions)
This commit is contained in:
177
docs/FASE-01-security-hardening.md
Normal file
177
docs/FASE-01-security-hardening.md
Normal file
@@ -0,0 +1,177 @@
|
||||
# FASE 01 — Security Hardening
|
||||
|
||||
> **Prioridade:** 🔴 Crítica
|
||||
> **Estimativa de Complexidade:** Média (3–5 dias)
|
||||
> **Dimensões do Relatório:** D3 (Qualidade do Código), D8 (LLM Proxy/Gateway)
|
||||
> **Dependências:** Nenhuma — esta fase é pré-requisito para todas as demais.
|
||||
|
||||
---
|
||||
|
||||
## Objetivo
|
||||
|
||||
Eliminar todas as vulnerabilidades de segurança críticas identificadas no relatório de análise, garantindo que o sistema não opere com segredos previsíveis, que erros nunca sejam silenciados, e que exista proteção básica contra ataques direcionados a LLM proxies.
|
||||
|
||||
---
|
||||
|
||||
## Escopo Detalhado
|
||||
|
||||
### 1.1 — Remoção de Fallbacks Hardcoded de Segredos
|
||||
|
||||
**Origem no relatório:** D3 — Segredos Hardcoded com Fallbacks Inseguros (🔴 Crítico)
|
||||
|
||||
#### Arquivos afetados
|
||||
|
||||
| Arquivo | Segredo | Fallback Atual |
|
||||
| ------------------------------ | ---------------- | -------------------------------------- |
|
||||
| `src/proxy.js:4-6` | `JWT_SECRET` | `"omniroute-default-secret-change-me"` |
|
||||
| `src/shared/utils/apiKey.js:3` | `API_KEY_SECRET` | `"endpoint-proxy-api-key-secret"` |
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Remover** os fallbacks `|| "..."` de todos os segredos.
|
||||
- **Implementar** validação na inicialização (`server-init.js` ou `next.config.mjs`) que:
|
||||
- Verifica se `JWT_SECRET` está definido e tem comprimento ≥ 32 caracteres.
|
||||
- Verifica se `API_KEY_SECRET` está definido e tem comprimento ≥ 16 caracteres.
|
||||
- Lança erro fatal com mensagem clara se não configurados (fail-fast).
|
||||
- **Atualizar** `.env.example` e README com instruções explícitas de configuração.
|
||||
- **Adicionar** warning no onboarding se os segredos parecerem ser os defaults do `.env.example`.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Aplicação NÃO inicia sem `JWT_SECRET` definido.
|
||||
- [ ] Aplicação NÃO inicia sem `API_KEY_SECRET` definido.
|
||||
- [ ] Mensagem de erro indica exatamente qual variável está faltando.
|
||||
- [ ] `.env.example` documentado com instruções para gerar segredos fortes.
|
||||
- [ ] Testes unitários cobrem cenário de inicialização sem segredos.
|
||||
|
||||
---
|
||||
|
||||
### 1.2 — Eliminação de Erros Silenciosos no Middleware
|
||||
|
||||
**Origem no relatório:** D3 — Erro Silencioso em Middleware (🔴 Crítico)
|
||||
|
||||
#### Arquivos afetados
|
||||
|
||||
| Arquivo | Linha | Problema |
|
||||
| -------------------- | -------------------------- | ------------------------ |
|
||||
| `src/proxy.js:42-43` | `catch (err) { }` | Exceção engolida sem log |
|
||||
| `src/proxy.js:24` | `catch (err) { redirect }` | JWT inválido sem log |
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Adicionar** logging estruturado em todos os `catch` blocks do middleware:
|
||||
```javascript
|
||||
catch (err) {
|
||||
console.error("[Middleware] Settings fetch failed:", err.message);
|
||||
// On error, require login
|
||||
}
|
||||
```
|
||||
- **Utilizar** `pino` (já nas dependências) para logging estruturado.
|
||||
- **Incluir** categorização do erro: `auth_error`, `settings_error`, `unknown_error`.
|
||||
- **Garantir** que nenhum stacktrace seja exposto ao cliente — apenas logging server-side.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Todos os `catch` blocks em `proxy.js` logam o erro.
|
||||
- [ ] Logs incluem contexto suficiente para debug (path, tipo de erro).
|
||||
- [ ] Nenhuma informação sensível exposta nos logs (sem tokens, sem senhas).
|
||||
- [ ] Revisão manual confirma zero `catch` vazio em todo `src/`.
|
||||
|
||||
---
|
||||
|
||||
### 1.3 — Proteção contra Prompt Injection
|
||||
|
||||
**Origem no relatório:** D8 — Sem Proteção contra Prompt Injection (🔴 Crítico)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Criar** módulo `src/shared/utils/inputSanitizer.js` com:
|
||||
- Detecção de padrões conhecidos de prompt injection.
|
||||
- Opção de sanitização ou rejeição.
|
||||
- Configuração via settings (habilitado/desabilitado, nível: `warn`, `block`, `redact`).
|
||||
- **Integrar** no pipeline de request em `src/sse/handlers/chat.js`:
|
||||
- Antes de `translateRequest()`, chamar o sanitizador.
|
||||
- Logar tentativas detectadas com severity `warn` ou `error`.
|
||||
- **Implementar** PII Redaction básica:
|
||||
- Detecção de padrões de email, CPF/CNPJ, cartões de crédito.
|
||||
- Modo `audit` (detecta e loga) vs `redact` (substitui por `[REDACTED]`).
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Módulo `inputSanitizer.js` criado com testes unitários.
|
||||
- [ ] Pipeline de request integra o sanitizador.
|
||||
- [ ] Configuração via `.env` ou dashboard settings.
|
||||
- [ ] Testes cobrem padrões conhecidos de prompt injection.
|
||||
- [ ] Documentação indica os padrões detectados e como configurar.
|
||||
|
||||
---
|
||||
|
||||
### 1.4 — Remoção de `.passthrough()` em Zod Schemas
|
||||
|
||||
**Origem no relatório:** D3 — `.passthrough()` em Zod Schema (🟡 Moderado)
|
||||
|
||||
#### Arquivos afetados
|
||||
|
||||
| Arquivo | Linha | Problema |
|
||||
| ------------------------------------- | ---------------- | ------------------------- |
|
||||
| `src/shared/validation/schemas.js:63` | `.passthrough()` | Aceita campos arbitrários |
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Remover** `.passthrough()` do `updateSettingsSchema`.
|
||||
- **Substituir** por `.strict()` ou listar explicitamente todos os campos aceitos.
|
||||
- **Verificar** todos os call sites que enviam dados para o endpoint de settings.
|
||||
- **Testar** que campos desconhecidos são rejeitados com erro 400.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] `.passthrough()` removido de todos os schemas.
|
||||
- [ ] Campos extras são rejeitados com mensagem de erro clara.
|
||||
- [ ] Nenhum endpoint quebra após a mudança.
|
||||
|
||||
---
|
||||
|
||||
### 1.5 — Limpeza de Dependências Inseguras
|
||||
|
||||
**Origem no relatório:** D3 — `fs` como dependência NPM (🟢 Menor)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Remover** `"fs": "^0.0.1-security"` do `package.json`.
|
||||
- **Verificar** que nenhum `import` usa o pacote npm `fs` (todos devem usar `node:fs`).
|
||||
- **Rodar** `npm audit` e documentar resultados.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Pacote `fs` removido do `package.json`.
|
||||
- [ ] `npm install` executa sem erros.
|
||||
- [ ] Build (`npm run build`) executa sem erros.
|
||||
|
||||
---
|
||||
|
||||
## Pré-Requisitos
|
||||
|
||||
- Acesso ao repositório OmniRoute com permissão de push.
|
||||
- Ambiente de desenvolvimento funcional (Node.js ≥ 18, npm).
|
||||
|
||||
## Entregáveis
|
||||
|
||||
1. Código-fonte alterado com todos os itens desta fase implementados.
|
||||
2. Testes unitários para validação de segredos e sanitizador de inputs.
|
||||
3. `.env.example` atualizado com instruções de segredos.
|
||||
4. Branch de feature com PR para review.
|
||||
|
||||
## Critérios de Conclusão da Fase
|
||||
|
||||
- [ ] Todos os critérios de aceite dos 5 itens cumpridos.
|
||||
- [ ] Build passa sem erros.
|
||||
- [ ] Testes unitários passam.
|
||||
- [ ] PR aprovado e mergeado.
|
||||
|
||||
## Riscos Identificados
|
||||
|
||||
| Risco | Probabilidade | Impacto | Mitigação |
|
||||
| -------------------------------------------------------- | ------------- | ------- | ---------------------------------------------------- |
|
||||
| Remoção de fallbacks quebra ambientes existentes | Alta | Alto | Comunicação via CHANGELOG; migration guide no README |
|
||||
| Sanitizador gera falsos positivos | Média | Médio | Modo `warn` como default; allowlist de padrões |
|
||||
| Remoção de `.passthrough()` quebra features não mapeadas | Baixa | Médio | Listar todos os call sites antes da mudança |
|
||||
155
docs/FASE-02-cicd-test-infrastructure.md
Normal file
155
docs/FASE-02-cicd-test-infrastructure.md
Normal file
@@ -0,0 +1,155 @@
|
||||
# FASE 02 — CI/CD & Infraestrutura de Testes
|
||||
|
||||
> **Prioridade:** 🔴 Crítica
|
||||
> **Estimativa de Complexidade:** Média (3–5 dias)
|
||||
> **Dimensões do Relatório:** D7 (Testes, CI/CD)
|
||||
> **Dependências:** FASE-01 (segredos validados são necessários para CI funcional)
|
||||
|
||||
---
|
||||
|
||||
## Objetivo
|
||||
|
||||
Estabelecer pipeline de integração contínua com execução automática de testes, linting, e build em cada PR/push, e configurar infraestrutura de cobertura de testes para garantir qualidade mínima.
|
||||
|
||||
---
|
||||
|
||||
## Escopo Detalhado
|
||||
|
||||
### 2.1 — Criação do CI Pipeline
|
||||
|
||||
**Origem no relatório:** D7 — Ausência de CI Pipeline (🔴 Crítico)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Criar** `.github/workflows/ci.yml` com jobs:
|
||||
1. **lint** — `npm run lint` com cache de `node_modules`.
|
||||
2. **build** — `npm run build` para verificar compilação.
|
||||
3. **test:unit** — Execução de testes unitários com `node --test`.
|
||||
4. **test:e2e** — Execução de `npx playwright test` (com Playwright instalado).
|
||||
- **Triggers:** push para `main`, pull_request para qualquer branch.
|
||||
- **Matrix:** Node.js 18 e 22.
|
||||
- **Cache:** `node_modules` e `.next/cache`.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Workflow `ci.yml` executa em PRs e pushes para `main`.
|
||||
- [ ] Todos os 4 jobs (lint, build, test:unit, test:e2e) executam.
|
||||
- [ ] PR não pode ser mergeado se CI falhar (branch protection rule).
|
||||
- [ ] Tempo de execução total < 10 minutos.
|
||||
|
||||
---
|
||||
|
||||
### 2.2 — Correção do Script `test` no package.json
|
||||
|
||||
**Origem no relatório:** D7 — `"test": "npm run build"` (🔴 Crítico)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Alterar** `"test"` para executar testes reais:
|
||||
```json
|
||||
"test": "node --test tests/unit/*.test.mjs",
|
||||
"test:unit": "node --test tests/unit/*.test.mjs",
|
||||
"test:e2e": "npx playwright test",
|
||||
"test:all": "npm run test:unit && npm run test:e2e"
|
||||
```
|
||||
- **Manter** `"check"` como agregador: `"npm run lint && npm run test:unit"`.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] `npm test` executa testes unitários reais.
|
||||
- [ ] `npm run test:all` executa unit + e2e.
|
||||
- [ ] CI usa os mesmos scripts definidos no `package.json`.
|
||||
|
||||
---
|
||||
|
||||
### 2.3 — Configuração de Cobertura de Testes
|
||||
|
||||
**Origem no relatório:** D7 — Cobertura de Testes Incerta (🔴 Crítico)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Configurar** `c8` como ferramenta de cobertura:
|
||||
```json
|
||||
"test:coverage": "c8 --reporter=text --reporter=lcov node --test tests/unit/*.test.mjs"
|
||||
```
|
||||
- **Definir** target mínimo: 40% de cobertura (baseline realista).
|
||||
- **Gerar** relatório lcov para upload em CI (Codecov ou similar).
|
||||
- **Adicionar** badge de cobertura no README.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] `npm run test:coverage` gera relatório de cobertura.
|
||||
- [ ] Relatório inclui todas as subpastas de `src/`.
|
||||
- [ ] CI faz upload do relatório de cobertura.
|
||||
|
||||
---
|
||||
|
||||
### 2.4 — Melhoria da Configuração ESLint
|
||||
|
||||
**Origem no relatório:** D7 — Sem Análise Estática de Código (🟠 Importante)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Adicionar** plugins ao ESLint:
|
||||
- `eslint-plugin-security` — regras de segurança.
|
||||
- `eslint-plugin-react-hooks` — regras de hooks React.
|
||||
- **Configurar** no `eslint.config.mjs` com severidade `warn` inicialmente.
|
||||
- **Executar** lint e resolver erros/warnings existentes antes de ativar em CI.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Plugins instalados e configurados.
|
||||
- [ ] `npm run lint` executa sem erros bloqueantes.
|
||||
- [ ] CI executa lint como parte do pipeline.
|
||||
|
||||
---
|
||||
|
||||
### 2.5 — Conversão de Testes de Segurança
|
||||
|
||||
**Origem no relatório:** D7 — Testes shell manuais (🟠 Importante)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Converter** os 4 scripts de `tests/security/` em testes programáticos:
|
||||
- `test-cli-runtime.sh` → `tests/integration/cli-runtime.test.mjs`
|
||||
- `test-cloud-openai-compatible.sh` → `tests/integration/cloud-openai.test.mjs`
|
||||
- `test-cloud-sync-and-call.sh` → `tests/integration/cloud-sync.test.mjs`
|
||||
- `test-docker-hardening.sh` → `tests/integration/docker-hardening.test.mjs`
|
||||
- **Usar** Node.js test runner com `child_process.exec` para testes que dependem de shell.
|
||||
- **Marcar** testes que dependem de infra externa como `skip` por default em CI.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Scripts shell convertidos em arquivos `.test.mjs`.
|
||||
- [ ] Testes executáveis via `node --test tests/integration/*.test.mjs`.
|
||||
- [ ] Testes que dependem de Docker/Cloud marcados como conditional skip.
|
||||
|
||||
---
|
||||
|
||||
## Pré-Requisitos
|
||||
|
||||
- FASE-01 completa (segredos configurados para ambiente de CI).
|
||||
- Acesso a GitHub Actions (secrets configurados).
|
||||
- Node.js 18+ no runner de CI.
|
||||
|
||||
## Entregáveis
|
||||
|
||||
1. Workflow `ci.yml` funcional.
|
||||
2. Scripts de test corrigidos no `package.json`.
|
||||
3. Configuração de cobertura com `c8`.
|
||||
4. ESLint com plugins de segurança e React hooks.
|
||||
5. Testes de segurança convertidos.
|
||||
|
||||
## Critérios de Conclusão da Fase
|
||||
|
||||
- [ ] CI pipeline verde em PR de teste.
|
||||
- [ ] Cobertura de testes mensurada e reportada.
|
||||
- [ ] ESLint passa no CI sem erros.
|
||||
|
||||
## Riscos Identificados
|
||||
|
||||
| Risco | Probabilidade | Impacto | Mitigação |
|
||||
| -------------------------------------- | ------------- | ------- | ------------------------------------ |
|
||||
| Testes e2e flaky em CI | Alta | Médio | Retry strategy no Playwright config |
|
||||
| ESLint com muitos warnings bloqueantes | Média | Baixo | Começar com `warn`, não `error` |
|
||||
| Testes de segurança dependem de Docker | Alta | Baixo | Skip condicional com check de Docker |
|
||||
185
docs/FASE-03-architecture-refactoring.md
Normal file
185
docs/FASE-03-architecture-refactoring.md
Normal file
@@ -0,0 +1,185 @@
|
||||
# FASE 03 — Refatoração Arquitetural
|
||||
|
||||
> **Prioridade:** 🟠 Importante
|
||||
> **Estimativa de Complexidade:** Alta (5–8 dias)
|
||||
> **Dimensões do Relatório:** D1 (Arquitetura), D3 (Qualidade do Código)
|
||||
> **Dependências:** FASE-02 (CI necessário para validar refatorações sem regressão)
|
||||
|
||||
---
|
||||
|
||||
## Objetivo
|
||||
|
||||
Decompor monólitos de código, eliminar acoplamentos desnecessários, e estabelecer separação clara de responsabilidades seguindo princípios SOLID, preparando a base de código para extensibilidade futura.
|
||||
|
||||
---
|
||||
|
||||
## Escopo Detalhado
|
||||
|
||||
### 3.1 — Decomposição do `usageDb.js` (969 linhas → 5 módulos)
|
||||
|
||||
**Origem no relatório:** D1 — God Object: `usageDb.js` (🟠 Importante)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
Decompor `src/lib/usageDb.js` em 5 módulos com responsabilidade única:
|
||||
|
||||
| Módulo Novo | Funções Migradas | Responsabilidade |
|
||||
| --------------------------------- | ------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
|
||||
| `src/lib/usage/usageHistory.js` | `saveRequestUsage`, `getUsageHistory`, `getUsageDb`, `trackPendingRequest` | CRUD de histórico de uso |
|
||||
| `src/lib/usage/callLogs.js` | `saveCallLog`, `getCallLogs`, `getCallLogById`, `writeCallLogToDisk`, `readFullLogFromDisk`, `rotateCallLogs` | Logs estruturados de chamadas |
|
||||
| `src/lib/usage/costCalculator.js` | `calculateCost` | Cálculo de custo puro (sem dependência de DB) |
|
||||
| `src/lib/usage/usageStats.js` | `getUsageStats` | Agregações e estatísticas |
|
||||
| `src/lib/usage/migrations.js` | `migrateUsageJsonToSqlite`, `migrateLegacyUsageFiles`, `copyIfMissing` | Migrações de dados |
|
||||
|
||||
- **Criar** `src/lib/usage/index.js` como barrel que re-exporta a API pública.
|
||||
- **Atualizar** todos os call sites para importar dos novos módulos.
|
||||
- **Manter** backward compatibility via re-exports.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Cada módulo tem no máximo 200 linhas.
|
||||
- [ ] Todos os testes existentes passam sem alteração.
|
||||
- [ ] Nenhum import circular criado.
|
||||
- [ ] `costCalculator.js` é uma função pura (testável sem DB).
|
||||
|
||||
---
|
||||
|
||||
### 3.2 — Refatoração do OAuth Providers com Strategy Pattern
|
||||
|
||||
**Origem no relatório:** D1 — OAuth Provider Monolith (🟠 Importante)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
Refatorar `src/lib/oauth/providers.js` (1051 linhas) usando **Strategy + Adapter pattern**:
|
||||
|
||||
1. **Criar** base interface em `src/lib/oauth/base/OAuthProvider.js`:
|
||||
|
||||
```javascript
|
||||
export class OAuthProvider {
|
||||
constructor(config) {
|
||||
this.config = config;
|
||||
}
|
||||
buildAuthUrl(redirectUri, state, codeChallenge) {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
async exchangeToken(code, redirectUri, codeVerifier) {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
mapTokens(tokens, extra) {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
get flowType() {
|
||||
return "authorization_code";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. **Criar** subclasses por provider em `src/lib/oauth/providers/`:
|
||||
- `claude.js`, `codex.js`, `gemini.js`, `antigravity.js`, `iflow.js`, `qwen.js`, `kimi-coding.js`, `github.js`, `kiro.js`, `cursor.js`, `kilocode.js`, `cline.js`
|
||||
|
||||
3. **Criar** factory `src/lib/oauth/providerFactory.js`:
|
||||
|
||||
```javascript
|
||||
export function getProvider(name) {
|
||||
return providers[name] ?? null;
|
||||
}
|
||||
```
|
||||
|
||||
4. **Manter** `providers.js` original como facade durante transição (deprecated).
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Cada provider em arquivo separado (< 120 linhas cada).
|
||||
- [ ] Factory retorna instância correta para cada provider.
|
||||
- [ ] Todos os flows OAuth existentes funcionam (testados via e2e smoke test).
|
||||
- [ ] Adicionar novo provider requer apenas 1 arquivo novo + registro na factory.
|
||||
- [ ] Arquivo original `providers.js` marcado como `@deprecated`.
|
||||
|
||||
---
|
||||
|
||||
### 3.3 — Eliminação do Self-Fetch no Middleware
|
||||
|
||||
**Origem no relatório:** D1 — Violação de Separação de Responsabilidades (🔴 Crítico)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Extrair** lógica de verificação de settings em `src/lib/settingsCache.js`:
|
||||
- Cache in-memory com TTL de 5 segundos.
|
||||
- Fallback direto para `getSettings()` do DB.
|
||||
- **Refatorar** `src/proxy.js` para usar `settingsCache` ao invés de `fetch("/api/settings")`.
|
||||
- **Eliminar** a dependência circular middleware → API route → middleware.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] `proxy.js` não faz mais `fetch()` para rotas internas.
|
||||
- [ ] Tempo de resposta do middleware reduzido (sem round-trip HTTP).
|
||||
- [ ] Cache invalida corretamente quando settings mudam.
|
||||
- [ ] Build e testes passam.
|
||||
|
||||
---
|
||||
|
||||
### 3.4 — Criação do Domain Layer
|
||||
|
||||
**Origem no relatório:** D1 — Ausência de Domain Layer (🟡 Moderado)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Criar** `src/domain/` com módulos para regras de negócio puras:
|
||||
- `src/domain/modelAvailability.js` — Lógica de `isModelAvailable` extraída de `sse/handlers/chat.js`.
|
||||
- `src/domain/costRules.js` — Regras de cálculo de custo extraídas de `usageDb.js`.
|
||||
- `src/domain/fallbackPolicy.js` — Regras de fallback/retry extraídas de `sse/services/auth.js`.
|
||||
- **Garantir** que módulos do domain NÃO importam de `lib/db/`, `sse/`, ou `app/api/`.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Diretório `src/domain/` criado com ≥ 3 módulos.
|
||||
- [ ] Módulos do domain não têm dependências de infra (DB, HTTP).
|
||||
- [ ] Testes unitários para cada módulo do domain.
|
||||
- [ ] Handlers refatorados para chamar domain services.
|
||||
|
||||
---
|
||||
|
||||
### 3.5 — Limpeza Estrutural do Projeto
|
||||
|
||||
**Origem no relatório:** D2 — Organização de Pastas (🟡 Moderado, 🟢 Menor)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Mover** ou `.gitignore` o diretório `antigravity-manager-analysis/`.
|
||||
- **Consolidar** `src/app/api/rate-limit/` e `src/app/api/rate-limits/` num único endpoint.
|
||||
- **Eliminar** `src/lib/usage/` (dir com 1 arquivo) — mover conteúdo para `src/lib/usage/` na nova estrutura (item 3.1).
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] `antigravity-manager-analysis/` não faz parte do build.
|
||||
- [ ] Apenas um endpoint para rate limiting.
|
||||
- [ ] Sem diretórios com arquivo único desnecessários.
|
||||
|
||||
---
|
||||
|
||||
## Pré-Requisitos
|
||||
|
||||
- FASE-02 completa (CI garante que refatorações não introduzem regressões).
|
||||
- Todos os testes existentes passando.
|
||||
|
||||
## Entregáveis
|
||||
|
||||
1. 5 módulos de usage decompostos.
|
||||
2. 12 providers OAuth em arquivos individuais + factory.
|
||||
3. Middleware sem self-fetch.
|
||||
4. Domain layer com ≥ 3 módulos.
|
||||
5. Estrutura do projeto limpa.
|
||||
|
||||
## Critérios de Conclusão da Fase
|
||||
|
||||
- [ ] CI verde após todas as refatorações.
|
||||
- [ ] Cobertura de testes ≥ baseline da FASE-02.
|
||||
- [ ] Zero imports circulares (verificável via ESLint rule).
|
||||
|
||||
## Riscos Identificados
|
||||
|
||||
| Risco | Probabilidade | Impacto | Mitigação |
|
||||
| ----------------------------------------------- | ------------- | ------- | ---------------------------------------------- |
|
||||
| Refatoração de OAuth quebra fluxos OAuth ativos | Média | Alto | Testes manuais de cada provider antes de merge |
|
||||
| Imports circulares criados na decomposição | Média | Médio | ESLint plugin `import/no-cycle` |
|
||||
| Cache de settings no middleware stale | Baixa | Médio | TTL curto (5s) e invalidação on-write |
|
||||
168
docs/FASE-04-error-handling-observability.md
Normal file
168
docs/FASE-04-error-handling-observability.md
Normal file
@@ -0,0 +1,168 @@
|
||||
# FASE 04 — Error Handling & Observabilidade
|
||||
|
||||
> **Prioridade:** 🟠 Importante
|
||||
> **Estimativa de Complexidade:** Média (4–6 dias)
|
||||
> **Dimensões do Relatório:** D5 (Fluxos Ausentes), D8 (LLM Proxy), D9 (Fluxo Ponta a Ponta)
|
||||
> **Dependências:** FASE-01 (logging corrigido), FASE-03 (domain layer para catálogo de erros)
|
||||
|
||||
---
|
||||
|
||||
## Objetivo
|
||||
|
||||
Implementar tratamento de erros consistente ponta a ponta, observabilidade com correlation IDs, padrões de resiliência (circuit breaker), e telas de erro personalizadas para elevar a maturidade operacional do sistema.
|
||||
|
||||
---
|
||||
|
||||
## Escopo Detalhado
|
||||
|
||||
### 4.1 — Telas de Erro Personalizadas (404, 500, 403)
|
||||
|
||||
**Origem no relatório:** D5 — Telas de Erro Personalizadas (🟠 Importante)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Criar** `src/app/not-found.js` — Página 404 com design do sistema:
|
||||
- Mensagem amigável: "Página não encontrada".
|
||||
- Link para dashboard, search de documentação.
|
||||
- Design consistente com tema do dashboard.
|
||||
- **Criar** `src/app/error.js` — Boundary de erro para erros de runtime:
|
||||
- Botão de "Tentar novamente".
|
||||
- Informação mínima do erro (sem stacktrace).
|
||||
- Logging do erro completo no server.
|
||||
- **Criar** `src/app/global-error.js` — Fallback de último recurso.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Navegação para rota inexistente mostra página 404 customizada.
|
||||
- [ ] Erro de runtime no dashboard mostra error boundary customizado.
|
||||
- [ ] Todas as páginas de erro seguem o tema visual do sistema.
|
||||
- [ ] Testes e2e validam renderização das páginas de erro.
|
||||
|
||||
---
|
||||
|
||||
### 4.2 — Catálogo de Error Codes Padronizado
|
||||
|
||||
**Origem no relatório:** D9 — Tratamento de Erro Genérico (🟡 Moderado)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Criar** `src/shared/constants/errorCodes.js`:
|
||||
```javascript
|
||||
export const ERROR_CODES = {
|
||||
PROVIDER_UNAVAILABLE: { code: "OMNIROUTE_PROVIDER_UNAVAILABLE", status: 503 },
|
||||
AUTH_FAILED: { code: "OMNIROUTE_AUTH_FAILED", status: 401 },
|
||||
RATE_LIMITED: { code: "OMNIROUTE_RATE_LIMITED", status: 429 },
|
||||
MODEL_NOT_FOUND: { code: "OMNIROUTE_MODEL_NOT_FOUND", status: 404 },
|
||||
INVALID_REQUEST: { code: "OMNIROUTE_INVALID_REQUEST", status: 400 },
|
||||
TRANSLATION_ERROR: { code: "OMNIROUTE_TRANSLATION_ERROR", status: 502 },
|
||||
TIMEOUT: { code: "OMNIROUTE_TIMEOUT", status: 504 },
|
||||
INTERNAL_ERROR: { code: "OMNIROUTE_INTERNAL_ERROR", status: 500 },
|
||||
};
|
||||
```
|
||||
- **Criar** helper `createErrorResponse(errorCode, details)` para respostas padronizadas.
|
||||
- **Refatorar** handlers SSE e API routes para usar o catálogo.
|
||||
- **Documentar** todos os error codes no OpenAPI spec (`docs/openapi.yaml`).
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Todos os erros do proxy retornam formato `{ error: { code, message, details } }`.
|
||||
- [ ] Error codes documentados no OpenAPI spec.
|
||||
- [ ] Testes unitários para `createErrorResponse`.
|
||||
|
||||
---
|
||||
|
||||
### 4.3 — Correlation ID (x-request-id)
|
||||
|
||||
**Origem no relatório:** D8 — Observabilidade Limitada (🟠 Importante)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Criar** middleware `src/shared/utils/requestId.js`:
|
||||
- Gerar UUID v4 como `x-request-id` se não presente no request.
|
||||
- Propagar em todas as respostas como header.
|
||||
- Incluir no logging de pino como campo `requestId`.
|
||||
- **Integrar** no pipeline:
|
||||
- `proxy.js` — adicionar requestId ao contexto.
|
||||
- `sse/handlers/chat.js` — propagar requestId para providers upstream.
|
||||
- `usageDb.js` / `callLogs` — armazenar requestId.
|
||||
- **Expor** no dashboard Logger — filtro por requestId.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Responses incluem header `x-request-id`.
|
||||
- [ ] Logs do pino incluem campo `requestId`.
|
||||
- [ ] Call logs no DB armazenam requestId.
|
||||
- [ ] Dashboard Logger permite filtro por requestId.
|
||||
|
||||
---
|
||||
|
||||
### 4.4 — Circuit Breaker Pattern
|
||||
|
||||
**Origem no relatório:** D8 — Sem Circuit Breaker (🟠 Importante)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Implementar** circuit breaker por provider em `src/lib/circuitBreaker.js`:
|
||||
- Estados: `CLOSED` → `OPEN` → `HALF_OPEN`.
|
||||
- Threshold: 5 falhas consecutivas → OPEN.
|
||||
- Timeout: 30 segundos em OPEN → tenta HALF_OPEN.
|
||||
- Reset: 1 sucesso em HALF_OPEN → CLOSED.
|
||||
- **Integrar** em `sse/services/auth.js` antes de `getProviderCredentials()`.
|
||||
- **Expor** estado dos circuits no dashboard (endpoint `/api/provider-health`).
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Circuit breaker previne retry storms quando provider está down.
|
||||
- [ ] Estado OPEN rejeita requests imediatamente com erro `PROVIDER_UNAVAILABLE`.
|
||||
- [ ] Transição HALF_OPEN testa provider automaticamente.
|
||||
- [ ] Dashboard mostra estado de cada circuit.
|
||||
|
||||
---
|
||||
|
||||
### 4.5 — Timeout Padrão Explícito
|
||||
|
||||
**Origem no relatório:** D9 — Request Síncrono sem Timeout (🟠 Importante)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Definir** valores padrão explícitos:
|
||||
```javascript
|
||||
const FETCH_TIMEOUT_MS = parseInt(process.env.FETCH_TIMEOUT_MS) || 120_000;
|
||||
const STREAM_IDLE_TIMEOUT_MS = parseInt(process.env.STREAM_IDLE_TIMEOUT_MS) || 60_000;
|
||||
```
|
||||
- **Aplicar** `AbortController` com timeout em todas as `fetch()` para providers.
|
||||
- **Documentar** valores padrão em `.env.example` (não comentado).
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Nenhum fetch() para provider sem timeout.
|
||||
- [ ] Timeout excedido gera erro `OMNIROUTE_TIMEOUT` (do catálogo).
|
||||
- [ ] Valores padrão documentados e configuráveis via env.
|
||||
|
||||
---
|
||||
|
||||
## Pré-Requisitos
|
||||
|
||||
- FASE-01 (logging correto para erros) e FASE-03 (domain layer onde error codes vivem).
|
||||
|
||||
## Entregáveis
|
||||
|
||||
1. Páginas de erro customizadas (404, 500, 403).
|
||||
2. Catálogo de error codes com helper.
|
||||
3. Middleware de correlation ID.
|
||||
4. Circuit breaker por provider.
|
||||
5. Timeouts explícitos em todas as fetch calls.
|
||||
|
||||
## Critérios de Conclusão da Fase
|
||||
|
||||
- [ ] Todas as respostas de erro seguem formato padronizado.
|
||||
- [ ] Correlation ID presente em 100% dos responses.
|
||||
- [ ] Circuit breaker ativo e testado por unit tests.
|
||||
|
||||
## Riscos Identificados
|
||||
|
||||
| Risco | Probabilidade | Impacto | Mitigação |
|
||||
| ---------------------------------------------------------- | ------------- | ------- | ------------------------------------------- |
|
||||
| Circuit breaker muito agressivo bloqueia providers válidos | Média | Alto | Threshold configurável; começar conservador |
|
||||
| Correlation ID overhead em high-throughput | Baixa | Baixo | UUID v4 é rápido (~ns) |
|
||||
| Timeout default 120s muito longo para alguns endpoints | Média | Médio | Override por provider config |
|
||||
171
docs/FASE-05-code-quality-standards.md
Normal file
171
docs/FASE-05-code-quality-standards.md
Normal file
@@ -0,0 +1,171 @@
|
||||
# FASE 05 — Qualidade do Código e Padronização
|
||||
|
||||
> **Prioridade:** 🟠 Importante / 🟡 Moderado
|
||||
> **Estimativa de Complexidade:** Média (4–6 dias)
|
||||
> **Dimensões do Relatório:** D3 (Qualidade do Código), D2 (Organização)
|
||||
> **Dependências:** FASE-03 (refatoração arquitetural reduz código duplicado antes da padronização)
|
||||
|
||||
---
|
||||
|
||||
## Objetivo
|
||||
|
||||
Padronizar práticas de código em todo o projeto — logging estruturado, definição de estratégia de tipagem, redução de complexidade ciclomática, e decomposição de componentes UI monolíticos.
|
||||
|
||||
---
|
||||
|
||||
## Escopo Detalhado
|
||||
|
||||
### 5.1 — Structured Logging com Pino
|
||||
|
||||
**Origem no relatório:** D3 — `console.log` e `console.error` como Logging em Produção (🟠 Importante)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Criar** `src/shared/utils/logger.js` como instância centralizada de pino:
|
||||
```javascript
|
||||
import pino from "pino";
|
||||
export const log = pino({
|
||||
level: process.env.LOG_LEVEL || "info",
|
||||
transport: process.env.NODE_ENV === "development" ? { target: "pino-pretty" } : undefined,
|
||||
});
|
||||
```
|
||||
- **Substituir** todos os `console.log`, `console.error`, `console.warn` por `log.info/error/warn`.
|
||||
- **Priorizar** arquivos críticos:
|
||||
1. `src/server-init.js`
|
||||
2. `src/proxy.js`
|
||||
3. `src/sse/handlers/chat.js`
|
||||
4. `src/lib/usageDb.js` (ou módulos decompostos)
|
||||
5. `src/lib/oauth/providers.js`
|
||||
- **Incluir** contexto estruturado (provider, model, connectionId) nos logs.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Zero `console.log/error/warn` em `src/` (exceto dev scripts).
|
||||
- [ ] Logger centralizado exporta instância de pino.
|
||||
- [ ] Logs em produção são JSON (sem pino-pretty).
|
||||
- [ ] ESLint rule `no-console` ativa com autofix.
|
||||
|
||||
---
|
||||
|
||||
### 5.2 — Definição de Estratégia de Tipagem (JS + JSDoc)
|
||||
|
||||
**Origem no relatório:** D3 — Mix de JS e TS sem Consistência (🟠 Importante)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Decisão arquitetural:** Adotar **JavaScript + JSDoc** como padrão (não migrar full TS):
|
||||
- Manter arquivos `.ts` existentes em `src/types/`.
|
||||
- Adicionar `@ts-check` nos arquivos JS principais.
|
||||
- Usar `@typedef`, `@param`, `@returns` para tipagem inline.
|
||||
- **Configurar** tsconfig para checkJs:
|
||||
```json
|
||||
{ "compilerOptions": { "checkJs": true, "allowJs": true, "strict": false } }
|
||||
```
|
||||
- **Priorizar** tipagem em:
|
||||
1. `src/shared/validation/schemas.js` — já tipado via Zod.
|
||||
2. `src/lib/db/core.js` — funções de DB.
|
||||
3. `src/sse/services/auth.js` — credenciais.
|
||||
4. `src/domain/` — novos módulos (FASE-03).
|
||||
- **Documentar** a decisão em ADR (FASE-06).
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] ≥ 10 arquivos críticos com `@ts-check` + JSDoc.
|
||||
- [ ] `tsc --noEmit` executa sem erros nos arquivos anotados.
|
||||
- [ ] ADR documenta decisão JS + JSDoc vs TypeScript.
|
||||
- [ ] Templates de JSDoc disponíveis em CONTRIBUTING.md.
|
||||
|
||||
---
|
||||
|
||||
### 5.3 — Redução de Complexidade Ciclomática
|
||||
|
||||
**Origem no relatório:** D3 — Complexidade Ciclomática Elevada (🟡 Moderado)
|
||||
|
||||
#### Arquivos afetados
|
||||
|
||||
| Arquivo | Função | Linhas | Ação |
|
||||
| -------------------------- | ----------------------- | ------ | ---------------------- |
|
||||
| `src/sse/handlers/chat.js` | `handleSingleModelChat` | 183 | Decompor em subfunções |
|
||||
| `src/lib/usageDb.js` | `getUsageStats` | 180 | Extrair SQL queries |
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Decompor** `handleSingleModelChat` em:
|
||||
- `resolveModel(body)` — resolução de modelo/combo.
|
||||
- `executeProviderRequest(credentials, translatedBody)` — fetch + stream.
|
||||
- `handleProviderError(error, retryContext)` — retry/fallback logic.
|
||||
- **Decompor** `getUsageStats` em:
|
||||
- `buildStatsQuery(period, filters)` — construção de SQL.
|
||||
- `aggregateResults(rows)` — computação de estatísticas.
|
||||
- **Target:** Nenhuma função com mais de 80 linhas.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] `handleSingleModelChat` tem < 80 linhas.
|
||||
- [ ] `getUsageStats` tem < 80 linhas.
|
||||
- [ ] Testes existentes passam sem alteração.
|
||||
- [ ] ESLint rule `max-lines-per-function` configurada (warn em > 100).
|
||||
|
||||
---
|
||||
|
||||
### 5.4 — Decomposição de Componentes UI Monolíticos
|
||||
|
||||
**Origem no relatório:** D2 — Componentes Monolíticos (🟡 Moderado)
|
||||
|
||||
#### Componentes Alvo
|
||||
|
||||
| Componente Original | Tamanho | Decomposição Proposta |
|
||||
| ------------------------------- | ----------- | --------------------------------------------------------------------------------------- |
|
||||
| `RequestLoggerV2.js` (36.3 KB) | ~800 linhas | `RequestLoggerTable`, `RequestLoggerFilters`, `RequestLoggerDetail`, `useRequestLogger` |
|
||||
| `UsageStats.js` (27.7 KB) | ~600 linhas | `UsageChart`, `UsageTable`, `UsageSummary`, `useUsageStats` |
|
||||
| `ProxyLogger.js` (27.6 KB) | ~600 linhas | `ProxyLogList`, `ProxyLogEntry`, `ProxyLogFilters`, `useProxyLogger` |
|
||||
| `OAuthModal.js` (18.3 KB) | ~400 linhas | `OAuthProviderList`, `OAuthConnectionForm`, `OAuthTokenStatus` |
|
||||
| `ProxyConfigModal.js` (16.1 KB) | ~350 linhas | `ProxyConfigForm`, `ProxyConfigPreview`, `useProxyConfig` |
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Para cada componente:**
|
||||
1. Extrair custom hook com lógica de estado e data fetching.
|
||||
2. Separar sub-componentes visuais puros.
|
||||
3. Manter componente original como "orchestrator" que compõe sub-componentes.
|
||||
- **Criar** diretórios por feature:
|
||||
- `src/shared/components/request-logger/`
|
||||
- `src/shared/components/usage-stats/`
|
||||
- `src/shared/components/proxy-logger/`
|
||||
- **Manter** imports existentes via re-export no arquivo original.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Nenhum componente com mais de 300 linhas.
|
||||
- [ ] Hooks extraídos são testáveis independentemente.
|
||||
- [ ] Importações existentes continuam funcionando.
|
||||
- [ ] UI renderiza identicamente (visual regression test ou screenshot comparation manual).
|
||||
|
||||
---
|
||||
|
||||
## Pré-Requisitos
|
||||
|
||||
- FASE-03 completa (decomposição de módulos backend facilita decomposição de componentes).
|
||||
- CI pipeline ativo (FASE-02) para validar regressões.
|
||||
|
||||
## Entregáveis
|
||||
|
||||
1. Logger centralizado com pino.
|
||||
2. ≥ 10 arquivos com JSDoc + `@ts-check`.
|
||||
3. Funções críticas decompostas (< 80 linhas).
|
||||
4. 5 componentes UI decompostos em sub-componentes.
|
||||
|
||||
## Critérios de Conclusão da Fase
|
||||
|
||||
- [ ] Zero `console.log` em `src/`.
|
||||
- [ ] Nenhuma função > 100 linhas.
|
||||
- [ ] Nenhum componente > 300 linhas.
|
||||
- [ ] CI verde.
|
||||
|
||||
## Riscos Identificados
|
||||
|
||||
| Risco | Probabilidade | Impacto | Mitigação |
|
||||
| ------------------------------------------------------- | ------------- | ------- | ----------------------------------- |
|
||||
| Decomposição de componentes cria bugs visuais | Média | Médio | Visual regression test antes/depois |
|
||||
| JSDoc excessivo reduz produtividade | Baixa | Baixo | Tipar apenas funções exportadas |
|
||||
| Substituição de console.log perde context em edge cases | Baixa | Baixo | Revisão manual de cada substituição |
|
||||
137
docs/FASE-06-documentation-governance.md
Normal file
137
docs/FASE-06-documentation-governance.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# FASE 06 — Documentação e Governança
|
||||
|
||||
> **Prioridade:** 🟡 Moderado
|
||||
> **Estimativa de Complexidade:** Baixa-Média (2–4 dias)
|
||||
> **Dimensões do Relatório:** D4 (Documentação)
|
||||
> **Dependências:** FASE-03 (decisões arquiteturais para ADRs), FASE-05 (padrões de código para CONTRIBUTING)
|
||||
|
||||
---
|
||||
|
||||
## Objetivo
|
||||
|
||||
Completar a documentação do projeto com ADRs, guia de contribuição, política de segurança expandida, e padronização de comentários inline, garantindo que novos contribuidores tenham contexto suficiente para entender e contribuir com o projeto.
|
||||
|
||||
---
|
||||
|
||||
## Escopo Detalhado
|
||||
|
||||
### 6.1 — Architecture Decision Records (ADRs)
|
||||
|
||||
**Origem no relatório:** D4 — Ausência de ADRs (🟡 Moderado)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Criar** diretório `docs/adr/` com template `docs/adr/000-template.md`.
|
||||
- **Criar** ADRs iniciais:
|
||||
|
||||
| ADR # | Título | Decisão |
|
||||
| ----- | ---------------------------------- | --------------------------------------------------- |
|
||||
| 001 | Escolha de SQLite como Database | Justificar SQLite vs PostgreSQL para single-tenant |
|
||||
| 002 | Padrão de Fallback entre Providers | Documentar estratégias fill-first, round-robin, p2c |
|
||||
| 003 | Estratégia de OAuth Multi-Provider | Documentar escolha de Strategy pattern (FASE-03) |
|
||||
| 004 | JavaScript + JSDoc vs TypeScript | Documentar decisão de tipagem (FASE-05) |
|
||||
| 005 | Sistema Single-Tenant | Documentar escopo sem multi-tenancy |
|
||||
| 006 | Tradução de Formatos LLM | Documentar pattern Registry do Translator |
|
||||
|
||||
- **Formato ADR:** Status, Contexto, Decisão, Consequências (formato Nygard).
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Template ADR criado e documentado.
|
||||
- [ ] ≥ 6 ADRs cobrindo decisões-chave do projeto.
|
||||
- [ ] ADRs referenciados no README e ARCHITECTURE.md.
|
||||
|
||||
---
|
||||
|
||||
### 6.2 — CONTRIBUTING.md
|
||||
|
||||
**Origem no relatório:** D4 — CONTRIBUTING.md Ausente (🟡 Moderado)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Criar** `CONTRIBUTING.md` na raiz com seções:
|
||||
1. **Getting Started** — Setup do ambiente, `npm install`, env vars obrigatórias.
|
||||
2. **Development Workflow** — Branch naming, commit convention (Conventional Commits).
|
||||
3. **Coding Standards** — JSDoc obrigatório, ESLint, Prettier.
|
||||
4. **Testing** — Como rodar testes unitários, e2e, e coverage.
|
||||
5. **PR Process** — Template de PR, reviewers, CI checks obrigatórios.
|
||||
6. **Architecture** — Link para ARCHITECTURE.md e ADRs.
|
||||
- **Criar** `.github/PULL_REQUEST_TEMPLATE.md` com checklist padrão.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] `CONTRIBUTING.md` criado com todas as 6 seções.
|
||||
- [ ] PR template criado e ativo no GitHub.
|
||||
- [ ] README referencia CONTRIBUTING.md.
|
||||
|
||||
---
|
||||
|
||||
### 6.3 — Expansão do SECURITY.md
|
||||
|
||||
**Origem no relatório:** D4 — SECURITY.md Insuficiente (🟡 Moderado)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Expandir** `SECURITY.md` de 619 bytes para ≥ 2KB com:
|
||||
1. **Responsible Disclosure Policy** — Como reportar vulnerabilidades.
|
||||
2. **Vulnerability Scope** — Tipos aceitos (RCE, XSS, SSRF, auth bypass, etc.).
|
||||
3. **Response SLA** — Prazo de resposta (48h ack, 7 dias para fix P0).
|
||||
4. **Security Contact** — Email ou canal dedicado.
|
||||
5. **Security Best Practices** — Instruções para configurar segredos fortes.
|
||||
6. **Known Limitations** — Documentar limitações de segurança do single-tenant.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] SECURITY.md ≥ 2KB com todas as 6 seções.
|
||||
- [ ] Formato segue GitHub Security Advisories best practices.
|
||||
- [ ] Link no README para SECURITY.md.
|
||||
|
||||
---
|
||||
|
||||
### 6.4 — Padronização de JSDoc em Funções Exportadas
|
||||
|
||||
**Origem no relatório:** D4 — Inline Comments inconsistentes (🟢 Menor)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Definir** padrão: toda função exportada DEVE ter JSDoc com `@param`, `@returns`, `@throws`.
|
||||
- **Priorizar** módulos públicos:
|
||||
1. `src/lib/db/*.js` — Funções de DB.
|
||||
2. `src/shared/utils/*.js` — Utilitários.
|
||||
3. `src/domain/*.js` — Domain services (módulos novos da FASE-03).
|
||||
4. `src/sse/services/*.js` — Services de streaming.
|
||||
- **ESLint:** Ativar `jsdoc/require-jsdoc` como `warn` para `export` functions.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] ≥ 80% das funções exportadas em módulos priorizados têm JSDoc.
|
||||
- [ ] ESLint rule `jsdoc/require-jsdoc` ativa.
|
||||
- [ ] CONTRIBUTING.md documenta o padrão de JSDoc.
|
||||
|
||||
---
|
||||
|
||||
## Pré-Requisitos
|
||||
|
||||
- FASE-03 (decisões de refatoração para ADRs) e FASE-05 (padrões de código para CONTRIBUTING).
|
||||
|
||||
## Entregáveis
|
||||
|
||||
1. Diretório `docs/adr/` com ≥ 6 ADRs.
|
||||
2. `CONTRIBUTING.md` completo.
|
||||
3. `SECURITY.md` expandido.
|
||||
4. JSDoc em funções exportadas.
|
||||
5. PR template.
|
||||
|
||||
## Critérios de Conclusão da Fase
|
||||
|
||||
- [ ] Todos os documentos criados e revisados.
|
||||
- [ ] README atualizado com links para novos docs.
|
||||
- [ ] ESLint rule de JSDoc ativa.
|
||||
|
||||
## Riscos Identificados
|
||||
|
||||
| Risco | Probabilidade | Impacto | Mitigação |
|
||||
| -------------------------------------------------- | ------------- | ------- | ------------------------------- |
|
||||
| ADRs ficam desatualizados rapidamente | Média | Baixo | Revisão trimestral agendada |
|
||||
| JSDoc obrigatório reduz velocidade de contribuição | Baixa | Baixo | Começar com `warn`, não `error` |
|
||||
| SECURITY.md cria expectativas de SLA não cumpridas | Baixa | Médio | SLA realista e comunicado |
|
||||
209
docs/FASE-07-ux-microinteractions.md
Normal file
209
docs/FASE-07-ux-microinteractions.md
Normal file
@@ -0,0 +1,209 @@
|
||||
# FASE 07 — UX e Microinterações
|
||||
|
||||
> **Prioridade:** 🟡 Moderado
|
||||
> **Estimativa de Complexidade:** Média (4–6 dias)
|
||||
> **Dimensões do Relatório:** D5 (Fluxos Ausentes), D6 (UX e Microinterações)
|
||||
> **Dependências:** FASE-05 (componentes decompostos facilitam adição de a11y e empty states)
|
||||
|
||||
---
|
||||
|
||||
## Objetivo
|
||||
|
||||
Elevar a qualidade da experiência do usuário no dashboard com sistema de notificações global, acessibilidade, breadcrumbs, empty states, e fluxo de recuperação de senha.
|
||||
|
||||
---
|
||||
|
||||
## Escopo Detalhado
|
||||
|
||||
### 7.1 — Sistema de Toasts/Notifications Global
|
||||
|
||||
**Origem no relatório:** D5 — Feedback de Ações Centralizado (🟡 Moderado)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Criar** Zustand store `src/store/notificationStore.js`:
|
||||
```javascript
|
||||
export const useNotificationStore = create((set) => ({
|
||||
notifications: [],
|
||||
addNotification: (notification) =>
|
||||
set((s) => ({
|
||||
notifications: [...s.notifications, { id: Date.now(), ...notification }],
|
||||
})),
|
||||
removeNotification: (id) =>
|
||||
set((s) => ({
|
||||
notifications: s.notifications.filter((n) => n.id !== id),
|
||||
})),
|
||||
}));
|
||||
```
|
||||
- **Criar** componente `src/shared/components/NotificationToast.js`:
|
||||
- Tipos: `success`, `error`, `warning`, `info`.
|
||||
- Auto-dismiss após 5s (configurável).
|
||||
- Animação de entrada/saída (slide + fade).
|
||||
- Posicionamento: top-right, stack vertical.
|
||||
- Ação de dismiss manual (botão X).
|
||||
- **Integrar** no layout root do dashboard.
|
||||
- **Refatorar** ≥ 5 call sites que usam feedback ad-hoc para usar o notification system.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Toasts renderizam sobre o conteúdo sem afetar layout.
|
||||
- [ ] Tipos visuais distintos (cores/ícones por tipo).
|
||||
- [ ] Auto-dismiss funciona.
|
||||
- [ ] ≥ 5 ações do dashboard usam o sistema centralizado.
|
||||
|
||||
---
|
||||
|
||||
### 7.2 — Auditoria de Acessibilidade (a11y)
|
||||
|
||||
**Origem no relatório:** D6 — Acessibilidade Insuficiente (🟡 Moderado)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Executar** auditoria com `axe-core` ou `pa11y-ci`:
|
||||
- Dashboard Home
|
||||
- Providers page
|
||||
- Settings page
|
||||
- Login page
|
||||
- **Corrigir** achados críticos:
|
||||
- Adicionar `role="dialog"` e `aria-modal="true"` em todos os modais.
|
||||
- Implementar focus trap em `OAuthModal.js` e `ProxyConfigModal.js`.
|
||||
- Adicionar `aria-label` em botões com ícone sem texto.
|
||||
- Garantir contraste mínimo 4.5:1 (WCAG AA).
|
||||
- **Adicionar** hook `useFocusTrap.js` em `src/shared/hooks/`.
|
||||
- **Integrar** `axe-core` como teste e2e de acessibilidade.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Zero violações críticas de axe-core nas 4 páginas auditadas.
|
||||
- [ ] Todos os modais com `role="dialog"` e focus trap.
|
||||
- [ ] Navegação por teclado funciona em todas as páginas do dashboard.
|
||||
- [ ] Teste e2e de a11y integrado no CI.
|
||||
|
||||
---
|
||||
|
||||
### 7.3 — Breadcrumbs no Dashboard
|
||||
|
||||
**Origem no relatório:** D6 — Breadcrumbs Ausentes (🟡 Moderado)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Criar** componente `src/shared/components/Breadcrumbs.js`:
|
||||
- Gerar breadcrumbs automaticamente a partir do pathname.
|
||||
- Mapeamento de paths para labels amigáveis:
|
||||
```javascript
|
||||
const PATH_LABELS = {
|
||||
dashboard: "Dashboard",
|
||||
providers: "Provedores",
|
||||
settings: "Configurações",
|
||||
usage: "Uso",
|
||||
combos: "Combos",
|
||||
tools: "Ferramentas",
|
||||
translator: "Tradutor",
|
||||
profile: "Perfil",
|
||||
};
|
||||
```
|
||||
- Links clicáveis para cada nível.
|
||||
- Último item não clicável (página atual).
|
||||
- **Integrar** no layout do dashboard (abaixo do header ou acima do conteúdo).
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Breadcrumbs renderizam em todas as páginas do dashboard.
|
||||
- [ ] Cada nível é clicável (exceto o atual).
|
||||
- [ ] Labels são amigáveis (não slugs).
|
||||
- [ ] Responsividade: truncamento em telas pequenas.
|
||||
|
||||
---
|
||||
|
||||
### 7.4 — Empty States Guiados
|
||||
|
||||
**Origem no relatório:** D6 — Loading States e Empty States (🟡 Moderado)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Criar** componente `src/shared/components/EmptyState.js`:
|
||||
- Props: `icon`, `title`, `description`, `actionLabel`, `onAction`.
|
||||
- Design: Ícone centrado, texto descritivo, CTA (call to action).
|
||||
- **Implementar** empty states nas seções:
|
||||
1. **Providers** — "Nenhum provider conectado. Conecte seu primeiro provider."
|
||||
2. **Combos** — "Nenhum combo criado. Crie um combo para agrupar modelos."
|
||||
3. **Usage** — "Nenhum uso registrado ainda. Faça sua primeira requisição."
|
||||
4. **Request Logger** — "Nenhum request logado. Ative logging nas configurações."
|
||||
- **Substituir** listas vazias por empty states.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Todas as 4 seções mostram empty states em vez de listas vazias.
|
||||
- [ ] Empty states incluem CTA relevante.
|
||||
- [ ] Design consistente com o tema do dashboard.
|
||||
|
||||
---
|
||||
|
||||
### 7.5 — Fluxo de Recuperação de Senha
|
||||
|
||||
**Origem no relatório:** D5 — Fluxo de Recuperação de Senha (🟡 Moderado)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Implementar** reset de senha via CLI:
|
||||
```bash
|
||||
npx omniroute reset-password
|
||||
# Prompts for new password, updates DB directly
|
||||
```
|
||||
- **Criar** endpoint `/api/auth/reset-password` com token temporário (opcional, para uso via link interno).
|
||||
- **Documentar** o processo de reset no README e na página de login como texto de ajuda.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] CLI permite resetar senha sem acesso ao dashboard.
|
||||
- [ ] Processo documentado no README.
|
||||
- [ ] Página de login mostra texto explicativo sobre recuperação.
|
||||
|
||||
---
|
||||
|
||||
### 7.6 — Teste de Responsividade
|
||||
|
||||
**Origem no relatório:** D6 — Responsividade (🟢 Menor)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Criar** testes Playwright para viewport < 768px.
|
||||
- **Verificar** páginas: Login, Dashboard, Providers, Settings.
|
||||
- **Corrigir** overflow, truncamento, e usabilidade em mobile.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Testes de responsividade passam em viewport 375px e 768px.
|
||||
- [ ] Nenhum overflow horizontal em telas < 768px.
|
||||
- [ ] Sidebar colapsável em mobile.
|
||||
|
||||
---
|
||||
|
||||
## Pré-Requisitos
|
||||
|
||||
- FASE-05 (componentes decompostos são mais fáceis de auditar e modificar).
|
||||
- Dashboard funcional para testes visuais.
|
||||
|
||||
## Entregáveis
|
||||
|
||||
1. Sistema de toasts com Zustand store.
|
||||
2. Auditoria a11y com correções.
|
||||
3. Componente Breadcrumbs.
|
||||
4. Empty states em 4 seções.
|
||||
5. Reset de senha via CLI.
|
||||
6. Testes de responsividade.
|
||||
|
||||
## Critérios de Conclusão da Fase
|
||||
|
||||
- [ ] Sistema de toasts funcional e integrado.
|
||||
- [ ] Zero violações críticas de a11y.
|
||||
- [ ] Breadcrumbs operacionais.
|
||||
- [ ] Empty states implementados.
|
||||
|
||||
## Riscos Identificados
|
||||
|
||||
| Risco | Probabilidade | Impacto | Mitigação |
|
||||
| ----------------------------------------- | ------------- | ------- | -------------------------------------- |
|
||||
| Focus trap interfere com UX | Média | Médio | Testes manuais de cada modal |
|
||||
| Breadcrumbs incorretos em rotas dinâmicas | Baixa | Baixo | Mapeamento explícito de todas as rotas |
|
||||
| CLI de reset requer acesso ao servidor | Inevitável | Baixo | Documentar alternativas (acesso ao DB) |
|
||||
158
docs/FASE-08-llm-proxy-advanced.md
Normal file
158
docs/FASE-08-llm-proxy-advanced.md
Normal file
@@ -0,0 +1,158 @@
|
||||
# FASE 08 — LLM Proxy: Recursos Avançados
|
||||
|
||||
> **Prioridade:** 🟡 Moderado
|
||||
> **Estimativa de Complexidade:** Alta (6–10 dias)
|
||||
> **Dimensões do Relatório:** D8 (LLM Proxy, Gateway e Router)
|
||||
> **Dependências:** FASE-04 (circuit breaker e error codes como base), FASE-03 (domain layer)
|
||||
|
||||
---
|
||||
|
||||
## Objetivo
|
||||
|
||||
Implementar funcionalidades avançadas de roteamento LLM: policy engine declarativo, cache de respostas, framework de avaliação de modelos, e controles de compliance/privacidade para amadurecer o OmniRoute como gateway de produção.
|
||||
|
||||
---
|
||||
|
||||
## Escopo Detalhado
|
||||
|
||||
### 8.1 — Policy Engine Declarativo
|
||||
|
||||
**Origem no relatório:** D8 — Sem Policy Engine Separado (🔴 Crítico)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Criar** `src/lib/policies/policyEngine.js`:
|
||||
- Carregar políticas de um arquivo JSON/YAML ou do DB (tabela `policies`).
|
||||
- Suportar regras declarativas:
|
||||
```json
|
||||
{
|
||||
"name": "prefer-low-cost",
|
||||
"conditions": { "model_pattern": "gpt-4*" },
|
||||
"actions": { "prefer_provider": ["openai", "gemini"], "max_cost_per_1k": 0.03 }
|
||||
}
|
||||
```
|
||||
- Tipos de política: `routing` (preferência de provider), `budget` (limite de custo), `access` (allow/deny models).
|
||||
- **Integrar** no pipeline antes de `getProviderCredentials()` em `sse/handlers/chat.js`.
|
||||
- **Criar** API endpoints:
|
||||
- `GET /api/policies` — Listar políticas.
|
||||
- `POST /api/policies` — Criar política.
|
||||
- `PUT /api/policies/:id` — Atualizar política.
|
||||
- `DELETE /api/policies/:id` — Remover política.
|
||||
- **Criar** tela de gerenciamento no dashboard.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Políticas de routing influenciam seleção de provider.
|
||||
- [ ] Políticas de budget limitam custo por request/dia/mês.
|
||||
- [ ] Políticas de access permitem bloquear modelos específicos.
|
||||
- [ ] Políticas são CRUD via API e dashboard.
|
||||
- [ ] Testes unitários cobrem avaliação de políticas.
|
||||
|
||||
---
|
||||
|
||||
### 8.2 — Cache Layer para Prompts e Respostas
|
||||
|
||||
**Origem no relatório:** D8 — Sem Cache de Prompts/Respostas (🟠 Importante)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Criar** `src/lib/cacheLayer.js`:
|
||||
- Cache LRU in-memory (usando `lru-cache` ou implementação própria).
|
||||
- Cache key: hash do `{ model, messages, temperature, max_tokens }`.
|
||||
- TTL configurável (default: 5 minutos).
|
||||
- Toggle via settings: `ENABLE_PROMPT_CACHE=true/false`.
|
||||
- **Integrar** no pipeline:
|
||||
- Antes de `executeProviderRequest()`: verificar cache hit.
|
||||
- Após resposta bem sucedida: armazenar no cache (apenas non-streaming OU primeiro chunk).
|
||||
- **Métricas**: cache hit rate exposta via `/api/cache/stats`.
|
||||
- **Bypass**: header `x-no-cache: true` para forçar request fresh.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Requests idênticos retornam resposta cached.
|
||||
- [ ] Cache hit rate mensurável via endpoint.
|
||||
- [ ] Header `x-no-cache` funciona.
|
||||
- [ ] Cache não interfere com streaming SSE.
|
||||
- [ ] TTL configurável via env/settings.
|
||||
|
||||
---
|
||||
|
||||
### 8.3 — Framework de Evals por Modelo
|
||||
|
||||
**Origem no relatório:** D8 — Governança de Qualidade de Modelos (🟡 Moderado)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Criar** `src/lib/evals/evalRunner.js`:
|
||||
- Definir golden set de prompts/respostas esperadas.
|
||||
- Executar avaliação periódica (manual ou cron) contra cada modelo.
|
||||
- Métricas: accuracy, latência p50/p95, custo por prompt.
|
||||
- **Criar** `src/lib/evals/goldenSet.json` com ≥ 10 test cases:
|
||||
- Cases de completamento, raciocínio, código, tradução.
|
||||
- **Criar** endpoint `/api/evals/run` — Trigger manual.
|
||||
- **Criar** endpoint `/api/evals/results` — Resultados por modelo.
|
||||
- **Criar** tela de resultados no dashboard.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Golden set com ≥ 10 test cases.
|
||||
- [ ] Eval runner executa contra todos os modelos ativos.
|
||||
- [ ] Resultados armazenados com timestamp para comparação temporal.
|
||||
- [ ] Dashboard exibe scorecard por modelo.
|
||||
|
||||
---
|
||||
|
||||
### 8.4 — Compliance e Controles de Privacidade
|
||||
|
||||
**Origem no relatório:** D8 — Compliance e Privacidade (🟡 Moderado)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Implementar** política de retenção de dados:
|
||||
- Setting global `LOG_RETENTION_DAYS` (default: 30).
|
||||
- Job de limpeza automática (cron ou on-request).
|
||||
- **Implementar** opt-out de logging por rota/API key:
|
||||
- Campo `noLog: true` nos metadata da API key.
|
||||
- Requests com `noLog` não geram call logs.
|
||||
- **Implementar** trilha de auditoria básica:
|
||||
- Tabela `audit_log` com: timestamp, action, actor, target, details.
|
||||
- Ações logadas: login, settings change, provider add/remove, password reset.
|
||||
- **Documentar** compliance capabilities no README e landing page.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Logs mais antigos que `LOG_RETENTION_DAYS` são removidos automaticamente.
|
||||
- [ ] API keys com `noLog: true` não geram registros.
|
||||
- [ ] Tabela `audit_log` registra ações administrativas.
|
||||
- [ ] Documentação descreve compliance capabilities.
|
||||
|
||||
---
|
||||
|
||||
## Pré-Requisitos
|
||||
|
||||
- FASE-04 (circuit breaker e error codes estabelecidos).
|
||||
- FASE-03 (domain layer para regras de políticas).
|
||||
- Dashboard funcional para telas novas.
|
||||
|
||||
## Entregáveis
|
||||
|
||||
1. Policy engine com CRUD de políticas.
|
||||
2. Cache layer com métricas.
|
||||
3. Framework de evals com golden set.
|
||||
4. Controles de retenção, opt-out, e auditoria.
|
||||
|
||||
## Critérios de Conclusão da Fase
|
||||
|
||||
- [ ] Políticas influenciam roteamento.
|
||||
- [ ] Cache funcional com métricas.
|
||||
- [ ] Evals executavelmente contra ≥ 3 modelos.
|
||||
- [ ] Retenção automática ativa.
|
||||
|
||||
## Riscos Identificados
|
||||
|
||||
| Risco | Probabilidade | Impacto | Mitigação |
|
||||
| -------------------------------------- | ------------- | ------- | -------------------------------------------------- |
|
||||
| Policy engine complexidade excessiva | Alta | Alto | MVP com 3 tipos de policy apenas |
|
||||
| Cache stale causa respostas incorretas | Média | Alto | TTL curto (5min) e bypass via header |
|
||||
| Evals custam tokens em providers pagos | Alta | Médio | Golden set pequeno; usar providers free para teste |
|
||||
| Auditoria gera volume alto de dados | Média | Médio | Retenção configurável; summarize após 90 dias |
|
||||
173
docs/FASE-09-e2e-flow-hardening.md
Normal file
173
docs/FASE-09-e2e-flow-hardening.md
Normal file
@@ -0,0 +1,173 @@
|
||||
# FASE 09 — Hardening de Fluxo Ponta a Ponta
|
||||
|
||||
> **Prioridade:** 🟡 Moderado / 🟢 Menor
|
||||
> **Estimativa de Complexidade:** Média (3–5 dias)
|
||||
> **Dimensões do Relatório:** D9 (Fluxo Ponta a Ponta)
|
||||
> **Dependências:** FASE-04 (correlation ID e error codes), FASE-08 (policy engine e cache)
|
||||
|
||||
---
|
||||
|
||||
## Objetivo
|
||||
|
||||
Endurecer o fluxo completo de requisição (request lifecycle), adicionando state tracking para streams, telemetria por etapa, e extraindo regras de negócio residuais dos controllers para domain services.
|
||||
|
||||
---
|
||||
|
||||
## Escopo Detalhado
|
||||
|
||||
### 9.1 — State Machine para Streams SSE
|
||||
|
||||
**Origem no relatório:** D9 — Sem State Machine para Processos Longos (🟠 Importante)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Criar** `src/sse/services/streamState.js`:
|
||||
|
||||
```javascript
|
||||
export const STREAM_STATES = {
|
||||
INITIALIZED: "initialized",
|
||||
CONNECTING: "connecting",
|
||||
STREAMING: "streaming",
|
||||
COMPLETED: "completed",
|
||||
FAILED: "failed",
|
||||
CANCELLED: "cancelled",
|
||||
};
|
||||
|
||||
export class StreamTracker {
|
||||
constructor(requestId) {
|
||||
this.requestId = requestId;
|
||||
this.state = STREAM_STATES.INITIALIZED;
|
||||
this.transitions = [];
|
||||
}
|
||||
transition(newState, metadata = {}) {
|
||||
this.transitions.push({ from: this.state, to: newState, at: Date.now(), ...metadata });
|
||||
this.state = newState;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- **Integrar** no pipeline de streaming em `handleSingleModelChat`:
|
||||
- `INITIALIZED` → `CONNECTING` (antes do fetch).
|
||||
- `CONNECTING` → `STREAMING` (primeiro chunk recebido).
|
||||
- `STREAMING` → `COMPLETED` (stream finalizado).
|
||||
- `STREAMING` → `FAILED` (erro durante stream).
|
||||
- Qualquer → `CANCELLED` (client disconnect).
|
||||
- **Logar** transições de estado com requestId.
|
||||
- **Expor** estado ativo via endpoint `/api/streams/active`.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Cada stream tem tracking de estado explícito.
|
||||
- [ ] Transições são logadas.
|
||||
- [ ] Endpoint mostra streams ativos e seus estados.
|
||||
- [ ] Client disconnect detectado e marcado como CANCELLED.
|
||||
|
||||
---
|
||||
|
||||
### 9.2 — Telemetria por Etapa do Request Pipeline
|
||||
|
||||
**Origem no relatório:** D9 — Telemetria por Jornada Ausente (🟡 Moderado)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Criar** `src/shared/utils/requestTelemetry.js`:
|
||||
- Metrificação por etapa:
|
||||
```javascript
|
||||
export class RequestTelemetry {
|
||||
constructor(requestId) {
|
||||
this.requestId = requestId;
|
||||
this.timings = {};
|
||||
}
|
||||
startPhase(phase) {
|
||||
this.timings[phase] = { start: performance.now() };
|
||||
}
|
||||
endPhase(phase) {
|
||||
this.timings[phase].end = performance.now();
|
||||
}
|
||||
getSummary() {
|
||||
return Object.entries(this.timings).reduce((acc, [k, v]) => {
|
||||
acc[k] = v.end - v.start;
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
}
|
||||
```
|
||||
- Fases medidas:
|
||||
1. `parse` — Parse do body e validação.
|
||||
2. `model_resolution` — Resolução de modelo/combo.
|
||||
3. `credential_selection` — Seleção de conta.
|
||||
4. `translation` — Tradução de request.
|
||||
5. `provider_fetch` — Fetch para o provider.
|
||||
6. `response_translation` — Tradução da resposta.
|
||||
7. `total` — End-to-end.
|
||||
- **Armazenar** telemetria no call log (campo `timings`).
|
||||
- **Expor** via endpoint `/api/telemetry/summary` — p50, p95, p99 por fase.
|
||||
- **Exibir** no dashboard (gráfico de latência por fase).
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Cada request tem telemetria por fase.
|
||||
- [ ] Call logs armazenam campo `timings`.
|
||||
- [ ] Endpoint de summary retorna p50/p95/p99.
|
||||
- [ ] Dashboard exibe gráfico de latência.
|
||||
|
||||
---
|
||||
|
||||
### 9.3 — Extração de Regras de Negócio Residuais
|
||||
|
||||
**Origem no relatório:** D9 — Regra de Negócio em Controller (🟡 Moderado)
|
||||
|
||||
#### Especificação Técnica
|
||||
|
||||
- **Auditar** `src/sse/handlers/chat.js` para regras de negócio em controller:
|
||||
- `isModelAvailable()` → mover para `src/domain/modelAvailability.js` (FASE-03).
|
||||
- Lógica de per-model lockout → mover para `src/domain/lockoutPolicy.js`.
|
||||
- Lógica de "combo resolution" → mover para `src/domain/comboResolver.js`.
|
||||
- **Refatorar** handler para ser um "thin controller":
|
||||
```javascript
|
||||
// sse/handlers/chat.js — objetivo final
|
||||
async function handleChat(request) {
|
||||
const body = parseRequest(request);
|
||||
const model = comboResolver.resolve(body.model);
|
||||
const credentials = await credentialService.select(model);
|
||||
const translated = translator.translate(body, model.format);
|
||||
const response = await providerService.execute(credentials, translated);
|
||||
return translator.translateResponse(response, body.format);
|
||||
}
|
||||
```
|
||||
- **Garantir** que cada módulo domain tenha testes unitários.
|
||||
|
||||
#### Critérios de Aceite
|
||||
|
||||
- [ ] Handler `handleChat` tem < 50 linhas de lógica.
|
||||
- [ ] ≥ 3 funções extraídas para domain layer.
|
||||
- [ ] Domain modules testados unitariamente.
|
||||
- [ ] Nenhuma regra de negócio no handler.
|
||||
|
||||
---
|
||||
|
||||
## Pré-Requisitos
|
||||
|
||||
- FASE-04 (correlation ID para integração com telemetria).
|
||||
- FASE-03 (domain layer como destino das regras extraídas).
|
||||
- FASE-08 (policy engine como parte do pipeline).
|
||||
|
||||
## Entregáveis
|
||||
|
||||
1. Stream state machine com tracking.
|
||||
2. Telemetria por fase com métricas p50/p95/p99.
|
||||
3. Handler refatorado como thin controller.
|
||||
|
||||
## Critérios de Conclusão da Fase
|
||||
|
||||
- [ ] Streams com tracking de estado.
|
||||
- [ ] Telemetria armazenada e acessível.
|
||||
- [ ] Handler < 50 linhas de lógica de negócio.
|
||||
|
||||
## Riscos Identificados
|
||||
|
||||
| Risco | Probabilidade | Impacto | Mitigação |
|
||||
| -------------------------------------- | ------------- | ------- | ------------------------------------------- |
|
||||
| Telemetria overhead em high-throughput | Média | Médio | Sampling configurável (1%, 10%, 100%) |
|
||||
| State machine complexidade adicional | Baixa | Baixo | Implementação minimalista; apenas 6 estados |
|
||||
| Extração de regras cria regressões | Média | Médio | Testes completos do pipeline antes e depois |
|
||||
118
docs/PLANO-IMPLANTACAO.md
Normal file
118
docs/PLANO-IMPLANTACAO.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# Plano de Implantação — OmniRoute
|
||||
|
||||
> **Versão:** 1.0
|
||||
> **Data:** 2026-02-14
|
||||
> **Baseado em:** Relatório de Análise Crítica Exaustiva (9 Dimensões)
|
||||
> **Total de Fases:** 9
|
||||
> **Total de Itens:** 41
|
||||
> **Estimativa Total:** 34–59 dias úteis
|
||||
|
||||
---
|
||||
|
||||
## Visão Geral
|
||||
|
||||
```mermaid
|
||||
gantt
|
||||
title Plano de Implantação OmniRoute
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %d/%m
|
||||
|
||||
section Crítico
|
||||
FASE 01 - Security Hardening :f1, 2026-02-17, 5d
|
||||
FASE 02 - CI/CD & Testes :f2, after f1, 5d
|
||||
|
||||
section Importante
|
||||
FASE 03 - Refatoração Arquitetural :f3, after f2, 8d
|
||||
FASE 04 - Error Handling :f4, after f3, 6d
|
||||
FASE 05 - Qualidade de Código :f5, after f3, 6d
|
||||
|
||||
section Moderado
|
||||
FASE 06 - Documentação :f6, after f5, 4d
|
||||
FASE 07 - UX & Microinterações :f7, after f5, 6d
|
||||
FASE 08 - LLM Proxy Avançado :f8, after f4, 10d
|
||||
FASE 09 - Fluxo Ponta a Ponta :f9, after f8, 5d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Documentos de Fase
|
||||
|
||||
| Fase | Documento | Prioridade | Itens | Complexidade |
|
||||
| ---- | ------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | ----- | ------------ |
|
||||
| 01 | [FASE-01-security-hardening.md](file:///home/diegosouzapw/dev/proxys/9router/docs/FASE-01-security-hardening.md) | 🔴 Crítica | 5 | Média (3–5d) |
|
||||
| 02 | [FASE-02-cicd-test-infrastructure.md](file:///home/diegosouzapw/dev/proxys/9router/docs/FASE-02-cicd-test-infrastructure.md) | 🔴 Crítica | 5 | Média (3–5d) |
|
||||
| 03 | [FASE-03-architecture-refactoring.md](file:///home/diegosouzapw/dev/proxys/9router/docs/FASE-03-architecture-refactoring.md) | 🟠 Importante | 5 | Alta (5–8d) |
|
||||
| 04 | [FASE-04-error-handling-observability.md](file:///home/diegosouzapw/dev/proxys/9router/docs/FASE-04-error-handling-observability.md) | 🟠 Importante | 5 | Média (4–6d) |
|
||||
| 05 | [FASE-05-code-quality-standards.md](file:///home/diegosouzapw/dev/proxys/9router/docs/FASE-05-code-quality-standards.md) | 🟠/🟡 Importante | 4 | Média (4–6d) |
|
||||
| 06 | [FASE-06-documentation-governance.md](file:///home/diegosouzapw/dev/proxys/9router/docs/FASE-06-documentation-governance.md) | 🟡 Moderado | 4 | Baixa (2–4d) |
|
||||
| 07 | [FASE-07-ux-microinteractions.md](file:///home/diegosouzapw/dev/proxys/9router/docs/FASE-07-ux-microinteractions.md) | 🟡 Moderado | 6 | Média (4–6d) |
|
||||
| 08 | [FASE-08-llm-proxy-advanced.md](file:///home/diegosouzapw/dev/proxys/9router/docs/FASE-08-llm-proxy-advanced.md) | 🟡 Moderado | 4 | Alta (6–10d) |
|
||||
| 09 | [FASE-09-e2e-flow-hardening.md](file:///home/diegosouzapw/dev/proxys/9router/docs/FASE-09-e2e-flow-hardening.md) | 🟡/🟢 Moderado | 3 | Média (3–5d) |
|
||||
|
||||
---
|
||||
|
||||
## Ordem de Execução e Dependências
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
F1[FASE 01<br/>Security Hardening] --> F2[FASE 02<br/>CI/CD & Testes]
|
||||
F2 --> F3[FASE 03<br/>Refatoração Arquitetural]
|
||||
F3 --> F4[FASE 04<br/>Error Handling & Observabilidade]
|
||||
F3 --> F5[FASE 05<br/>Qualidade do Código]
|
||||
F5 --> F6[FASE 06<br/>Documentação & Governança]
|
||||
F5 --> F7[FASE 07<br/>UX & Microinterações]
|
||||
F4 --> F8[FASE 08<br/>LLM Proxy Avançado]
|
||||
F8 --> F9[FASE 09<br/>Fluxo Ponta a Ponta]
|
||||
|
||||
style F1 fill:#dc3545,color:#fff
|
||||
style F2 fill:#dc3545,color:#fff
|
||||
style F3 fill:#fd7e14,color:#fff
|
||||
style F4 fill:#fd7e14,color:#fff
|
||||
style F5 fill:#fd7e14,color:#fff
|
||||
style F6 fill:#ffc107,color:#000
|
||||
style F7 fill:#ffc107,color:#000
|
||||
style F8 fill:#ffc107,color:#000
|
||||
style F9 fill:#28a745,color:#fff
|
||||
```
|
||||
|
||||
### Paralelização Possível
|
||||
|
||||
| Janela | Fases Paralelas | Condição |
|
||||
| ------------ | ----------------- | -------------------------------- |
|
||||
| Após FASE-03 | FASE-04 + FASE-05 | Ambas dependem apenas de FASE-03 |
|
||||
| Após FASE-05 | FASE-06 + FASE-07 | Ambas dependem apenas de FASE-05 |
|
||||
|
||||
---
|
||||
|
||||
## Marcos de Entrega
|
||||
|
||||
| Marco | Fases Inclusas | Data Estimada | Critério de Aceite |
|
||||
| ---------------------------- | -------------- | ------------- | ------------------------------------------------------- |
|
||||
| **M1 — Segurança Baseline** | FASE-01 | Semana 1 | Segredos obrigatórios, erros logados, sanitizador ativo |
|
||||
| **M2 — Qualidade Garantida** | FASE-01, 02 | Semana 2 | CI verde, testes executam, cobertura mensurável |
|
||||
| **M3 — Arquitetura Madura** | FASE-01–03 | Semana 4 | Monólitos decompostos, domain layer criado |
|
||||
| **M4 — Produção-Ready** | FASE-01–05 | Semana 6 | Error handling, logging, tipagem padronizados |
|
||||
| **M5 — Documentado** | FASE-01–06 | Semana 7 | ADRs, CONTRIBUTING, SECURITY completos |
|
||||
| **M6 — UX Polish** | FASE-01–07 | Semana 9 | Toasts, a11y, breadcrumbs, empty states |
|
||||
| **M7 — Gateway Completo** | FASE-01–09 | Semana 12 | Policy engine, cache, evals, telemetria |
|
||||
|
||||
---
|
||||
|
||||
## Critérios de Qualidade Transversais
|
||||
|
||||
Aplicáveis a TODAS as fases:
|
||||
|
||||
- [ ] CI pipeline verde após cada merge.
|
||||
- [ ] Cobertura de testes não regride.
|
||||
- [ ] Nenhum `console.log` adicionado (a partir da FASE-05).
|
||||
- [ ] PR review obrigatório.
|
||||
- [ ] CHANGELOG atualizado a cada fase.
|
||||
|
||||
---
|
||||
|
||||
## Documentos de Referência
|
||||
|
||||
- [Relatório de Análise Crítica](file:///home/diegosouzapw/.gemini/antigravity/brain/4c7323de-ade6-432d-8710-4a71eb43d1ad/omniroute_analysis_report.md)
|
||||
- [TASKS.md — Lista Completa de Tarefas](file:///home/diegosouzapw/dev/proxys/9router/docs/TASKS.md)
|
||||
- [ARCHITECTURE.md](file:///home/diegosouzapw/dev/proxys/9router/docs/ARCHITECTURE.md)
|
||||
- [CODEBASE_DOCUMENTATION.md](file:///home/diegosouzapw/dev/proxys/9router/docs/CODEBASE_DOCUMENTATION.md)
|
||||
143
docs/TASKS.md
Normal file
143
docs/TASKS.md
Normal file
@@ -0,0 +1,143 @@
|
||||
# TASKS — Lista Completa de Tarefas Executáveis
|
||||
|
||||
> **Roteiro prático para desenvolvimento do OmniRoute**
|
||||
> **Total de tarefas:** 46
|
||||
> **Status possíveis:** `Pendente` | `Em Progresso` | `Concluído` | `Bloqueado`
|
||||
|
||||
---
|
||||
|
||||
## Legenda
|
||||
|
||||
| Campo | Descrição |
|
||||
| -------------- | --------------------------------------------------- |
|
||||
| **ID** | Identificador único no formato `T-XX` |
|
||||
| **Fase** | Fase de origem (`F01`–`F09`) |
|
||||
| **Prioridade** | 🔴 Crítica · 🟠 Importante · 🟡 Moderada · 🟢 Menor |
|
||||
| **Deps** | Tarefas das quais esta depende (IDs) |
|
||||
| **Status** | Estado atual da tarefa |
|
||||
|
||||
---
|
||||
|
||||
## FASE 01 — Security Hardening
|
||||
|
||||
| ID | Descrição | Prioridade | Deps | Status |
|
||||
| ---- | ----------------------------------------------------------------------------------------------------------------------- | ----------- | ---------------- | -------- |
|
||||
| T-01 | Remover fallback hardcoded de `JWT_SECRET` em `src/proxy.js` e implementar validação fail-fast na inicialização | 🔴 Crítica | — | Pendente |
|
||||
| T-02 | Remover fallback hardcoded de `API_KEY_SECRET` em `src/shared/utils/apiKey.js` e implementar validação fail-fast | 🔴 Crítica | — | Pendente |
|
||||
| T-03 | Atualizar `.env.example` e README com instruções para gerar segredos fortes (openssl rand) | 🔴 Crítica | T-01, T-02 | Pendente |
|
||||
| T-04 | Adicionar logging estruturado em todos os `catch` blocks silenciosos de `src/proxy.js` (auth_error, settings_error) | 🔴 Crítica | — | Pendente |
|
||||
| T-05 | Criar módulo `src/shared/utils/inputSanitizer.js` com detecção de prompt injection e PII redaction | 🔴 Crítica | — | Pendente |
|
||||
| T-06 | Integrar `inputSanitizer` no pipeline de request em `src/sse/handlers/chat.js` antes de `translateRequest()` | 🔴 Crítica | T-05 | Pendente |
|
||||
| T-07 | Remover `.passthrough()` de `updateSettingsSchema` em `src/shared/validation/schemas.js` e listar campos explicitamente | 🟡 Moderada | — | Pendente |
|
||||
| T-08 | Remover dependência `"fs": "^0.0.1-security"` do `package.json` e verificar imports | 🟢 Menor | — | Pendente |
|
||||
| T-09 | Criar testes unitários para validação de segredos e sanitizador de inputs | 🔴 Crítica | T-01, T-02, T-05 | Pendente |
|
||||
|
||||
---
|
||||
|
||||
## FASE 02 — CI/CD & Infraestrutura de Testes
|
||||
|
||||
| ID | Descrição | Prioridade | Deps | Status |
|
||||
| ---- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------- | ---- | -------- |
|
||||
| T-10 | Criar `.github/workflows/ci.yml` com jobs: lint, build, test:unit, test:e2e (Node 18+22, trigger PR/push) | 🔴 Crítica | T-01 | Pendente |
|
||||
| T-11 | Alterar script `"test"` no `package.json` para `node --test tests/unit/*.test.mjs`; adicionar scripts `test:unit`, `test:e2e`, `test:all` | 🔴 Crítica | — | Pendente |
|
||||
| T-12 | Configurar `c8` como ferramenta de cobertura de testes com script `test:coverage` e target mínimo 40% | 🔴 Crítica | T-11 | Pendente |
|
||||
| T-13 | Instalar e configurar `eslint-plugin-security` e `eslint-plugin-react-hooks` no `eslint.config.mjs` | 🟠 Importante | — | Pendente |
|
||||
| T-14 | Converter 4 scripts de `tests/security/` em testes programáticos `.test.mjs` em `tests/integration/` | 🟠 Importante | T-11 | Pendente |
|
||||
|
||||
---
|
||||
|
||||
## FASE 03 — Refatoração Arquitetural
|
||||
|
||||
| ID | Descrição | Prioridade | Deps | Status |
|
||||
| ---- | ----------------------------------------------------------------------------------------------------------------------------------- | ------------- | ---- | -------- |
|
||||
| T-15 | Decompor `src/lib/usageDb.js` em 5 módulos: `usageHistory.js`, `callLogs.js`, `costCalculator.js`, `usageStats.js`, `migrations.js` | 🟠 Importante | T-10 | Pendente |
|
||||
| T-16 | Criar base class `OAuthProvider` em `src/lib/oauth/base/` e factory `providerFactory.js` | 🟠 Importante | T-10 | Pendente |
|
||||
| T-17 | Extrair 12 providers OAuth em subclasses individuais em `src/lib/oauth/providers/` | 🟠 Importante | T-16 | Pendente |
|
||||
| T-18 | Eliminar self-fetch no middleware: criar `src/lib/settingsCache.js` com cache in-memory (TTL 5s) e refatorar `proxy.js` | 🔴 Crítica | T-04 | Pendente |
|
||||
| T-19 | Criar domain layer `src/domain/` com: `modelAvailability.js`, `costRules.js`, `fallbackPolicy.js` | 🟡 Moderada | T-15 | Pendente |
|
||||
| T-20 | Adicionar `antigravity-manager-analysis/` ao `.gitignore` e consolidar endpoints `rate-limit/` vs `rate-limits/` | 🟢 Menor | — | Pendente |
|
||||
|
||||
---
|
||||
|
||||
## FASE 04 — Error Handling & Observabilidade
|
||||
|
||||
| ID | Descrição | Prioridade | Deps | Status |
|
||||
| ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | ---- | -------- |
|
||||
| T-21 | Criar páginas de erro customizadas: `src/app/not-found.js`, `error.js`, `global-error.js` com design do sistema | 🟠 Importante | — | Pendente |
|
||||
| T-22 | Criar catálogo de error codes `src/shared/constants/errorCodes.js` com helper `createErrorResponse()` | 🟡 Moderada | T-19 | Pendente |
|
||||
| T-23 | Implementar middleware de correlation ID (`x-request-id`) em `src/shared/utils/requestId.js` e integrar no pipeline completo (proxy → handler → provider → log) | 🟠 Importante | T-04 | Pendente |
|
||||
| T-24 | Implementar circuit breaker por provider em `src/lib/circuitBreaker.js` (CLOSED→OPEN→HALF_OPEN) e integrar em `sse/services/auth.js` | 🟠 Importante | T-18 | Pendente |
|
||||
| T-25 | Definir timeout padrão explícito (`FETCH_TIMEOUT_MS=120000`) com `AbortController` em todas as `fetch()` para providers | 🟠 Importante | — | Pendente |
|
||||
|
||||
---
|
||||
|
||||
## FASE 05 — Qualidade do Código & Padronização
|
||||
|
||||
| ID | Descrição | Prioridade | Deps | Status |
|
||||
| ---- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | ---- | -------- |
|
||||
| T-26 | Criar logger centralizado `src/shared/utils/logger.js` com pino; substituir todos `console.log/error/warn` em `src/` | 🟠 Importante | T-04 | Pendente |
|
||||
| T-27 | Adicionar `@ts-check` + JSDoc (`@param`, `@returns`) em ≥ 10 arquivos críticos (DB, services, domain) | 🟠 Importante | T-19 | Pendente |
|
||||
| T-28 | Decompor `handleSingleModelChat` (183 linhas) em subfunções <80 linhas; decompor `getUsageStats` (180 linhas) | 🟡 Moderada | T-15 | Pendente |
|
||||
| T-29 | Decompor 5 componentes UI monolíticos (RequestLoggerV2, UsageStats, ProxyLogger, OAuthModal, ProxyConfigModal) em sub-componentes + hooks extraídos | 🟡 Moderada | — | Pendente |
|
||||
|
||||
---
|
||||
|
||||
## FASE 06 — Documentação & Governança
|
||||
|
||||
| ID | Descrição | Prioridade | Deps | Status |
|
||||
| ---- | -------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ---------- | -------- |
|
||||
| T-30 | Criar diretório `docs/adr/` com template e ≥ 6 ADRs (SQLite, Fallback, OAuth Strategy, JS+JSDoc, Single-Tenant, Translator Registry) | 🟡 Moderada | T-16, T-27 | Pendente |
|
||||
| T-31 | Criar `CONTRIBUTING.md` na raiz (6 seções: setup, workflow, standards, testing, PR, architecture) e `.github/PULL_REQUEST_TEMPLATE.md` | 🟡 Moderada | T-26 | Pendente |
|
||||
| T-32 | Expandir `SECURITY.md` para ≥ 2KB (disclosure, scope, SLA, contact, best practices, limitations) | 🟡 Moderada | T-01 | Pendente |
|
||||
| T-33 | Padronizar JSDoc em ≥ 80% das funções exportadas em módulos priorizados; ativar ESLint rule `jsdoc/require-jsdoc` | 🟢 Menor | T-27 | Pendente |
|
||||
|
||||
---
|
||||
|
||||
## FASE 07 — UX & Microinterações
|
||||
|
||||
| ID | Descrição | Prioridade | Deps | Status |
|
||||
| ---- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ---- | -------- |
|
||||
| T-34 | Criar Zustand store `notificationStore.js` e componente `NotificationToast.js` com 4 tipos (success, error, warning, info); integrar no layout root | 🟡 Moderada | T-29 | Pendente |
|
||||
| T-35 | Executar auditoria a11y com axe-core em 4 páginas; corrigir: `role="dialog"`, focus trap, `aria-label`, contraste WCAG AA | 🟡 Moderada | T-29 | Pendente |
|
||||
| T-36 | Criar componente `Breadcrumbs.js` com mapeamento de paths para labels amigáveis e integrar no layout do dashboard | 🟡 Moderada | — | Pendente |
|
||||
| T-37 | Criar componente `EmptyState.js` e implementar em 4 seções (Providers, Combos, Usage, Request Logger) | 🟡 Moderada | — | Pendente |
|
||||
| T-38 | Implementar reset de senha via CLI (`npx omniroute reset-password`) e documentar no README e login page | 🟡 Moderada | T-01 | Pendente |
|
||||
| T-39 | Criar testes Playwright de responsividade (viewport 375px e 768px) para Login, Dashboard, Providers, Settings | 🟢 Menor | T-14 | Pendente |
|
||||
|
||||
---
|
||||
|
||||
## FASE 08 — LLM Proxy: Recursos Avançados
|
||||
|
||||
| ID | Descrição | Prioridade | Deps | Status |
|
||||
| ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- | ---------- | -------- |
|
||||
| T-40 | Criar Policy Engine declarativo `src/lib/policies/policyEngine.js` com 3 tipos (routing, budget, access); API CRUD e tela no dashboard | 🟡 Moderada | T-19, T-24 | Pendente |
|
||||
| T-41 | Implementar cache layer LRU `src/lib/cacheLayer.js` com hash key, TTL configurável, bypass via `x-no-cache`, e endpoint `/api/cache/stats` | 🟠 Importante | T-25 | Pendente |
|
||||
| T-42 | Criar framework de evals `src/lib/evals/evalRunner.js` com golden set (≥10 cases), endpoints trigger/results, e scorecard no dashboard | 🟡 Moderada | T-22 | Pendente |
|
||||
| T-43 | Implementar controles de compliance: `LOG_RETENTION_DAYS` com limpeza automática, opt-out `noLog` por API key, tabela `audit_log` para ações administrativas | 🟡 Moderada | T-15 | Pendente |
|
||||
|
||||
---
|
||||
|
||||
## FASE 09 — Hardening de Fluxo Ponta a Ponta
|
||||
|
||||
| ID | Descrição | Prioridade | Deps | Status |
|
||||
| ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | ---------- | -------- |
|
||||
| T-44 | Criar `StreamTracker` em `src/sse/services/streamState.js` com 6 estados (INITIALIZED→CANCELLED); integrar no pipeline SSE e expor via `/api/streams/active` | 🟡 Moderada | T-23 | Pendente |
|
||||
| T-45 | Criar `RequestTelemetry` em `src/shared/utils/requestTelemetry.js` medindo 7 fases; armazenar timings no call log e expor p50/p95/p99 via `/api/telemetry/summary` | 🟡 Moderada | T-23, T-15 | Pendente |
|
||||
| T-46 | Extrair regras de negócio residuais de `handleChat` para domain layer (`lockoutPolicy.js`, `comboResolver.js`); refatorar handler para <50 linhas | 🟡 Moderada | T-19, T-28 | Pendente |
|
||||
|
||||
---
|
||||
|
||||
## Resumo por Prioridade
|
||||
|
||||
| Prioridade | Tarefas | IDs |
|
||||
| ------------- | ------- | ---------------------------------------------------------------------------------------------------------------- |
|
||||
| 🔴 Crítica | 11 | T-01, T-02, T-03, T-04, T-05, T-06, T-09, T-10, T-11, T-12, T-18 |
|
||||
| 🟠 Importante | 12 | T-13, T-14, T-15, T-16, T-17, T-21, T-23, T-24, T-25, T-26, T-27, T-41 |
|
||||
| 🟡 Moderada | 19 | T-07, T-19, T-22, T-28, T-29, T-30, T-31, T-32, T-34, T-35, T-36, T-37, T-38, T-40, T-42, T-43, T-44, T-45, T-46 |
|
||||
| 🟢 Menor | 4 | T-08, T-20, T-33, T-39 |
|
||||
|
||||
## Sugestão de Ordem de Execução
|
||||
|
||||
> **Regra:** Sempre executar tarefas cujas dependências (`Deps`) estejam com status `Concluído`.
|
||||
|
||||
**Caminho crítico:** T-01 → T-02 → T-03 → T-10 → T-11 → T-12 → T-15 → T-16 → T-17 → T-18 → T-19 → T-24 → T-40
|
||||
Reference in New Issue
Block a user