Compare commits
No commits in common. "OstePan" and "main" have entirely different histories.
|
|
@ -1,54 +0,0 @@
|
||||||
# Plano de Ajuste - Ambiente Financeiro V2
|
|
||||||
|
|
||||||
## Resumo
|
|
||||||
Este documento detalha as alterações necessárias para alimentar os gráficos do painel financeiro utilizando os endpoints de backend especificados.
|
|
||||||
|
|
||||||
## 1. Ajuste nos Serviços de Integração (`extratoService.js`)
|
|
||||||
|
|
||||||
Precisamos adicionar/atualizar os métodos para consumir as novas rotas:
|
|
||||||
|
|
||||||
### Endpoints
|
|
||||||
* **Fluxo Diário**: Utilizar a rota existente `/extrato/fluxo` e processar o array `diario`.
|
|
||||||
* **Receitas (Planejado vs Executado)**: Nova rota `/extrato/planejado/grafico`.
|
|
||||||
* **Despesas (Planejado vs Executado)**: Nova rota `/extrato/despesas/grafico`.
|
|
||||||
|
|
||||||
### Implementação
|
|
||||||
Criar os seguintes métodos no `extratoService`:
|
|
||||||
```javascript
|
|
||||||
// Buscar dados comparativos de Receitas
|
|
||||||
fetchReceitasPlanejadasGrafico: (params) => api.get('/extrato/planejado/grafico', { params })
|
|
||||||
|
|
||||||
// Buscar dados comparativos de Despesas
|
|
||||||
fetchDespesasPlanejadasGrafico: (params) => api.get('/extrato/despesas/grafico', { params })
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. Processamento de Dados (`useDashboard.js`)
|
|
||||||
|
|
||||||
O hook `useDashboard` será responsável por formatar os dados para o `recharts`.
|
|
||||||
|
|
||||||
### Fluxo de Recebimentos (Entradas)
|
|
||||||
* **Fonte**: `fluxo.diario`
|
|
||||||
* **Filtro**: `tipoOperacao === 'C'`
|
|
||||||
* **Formato para Gráfico**:
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
name: 'DD/MM',
|
|
||||||
valor: 1234.56
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Fluxo de Despesas (Saídas)
|
|
||||||
* **Fonte**: `fluxo.diario`
|
|
||||||
* **Filtro**: `tipoOperacao === 'D'`
|
|
||||||
|
|
||||||
## 3. Componentes Visuais (`DashboardView.jsx`)
|
|
||||||
|
|
||||||
Novos gráficos ou atualização dos existentes:
|
|
||||||
1. **Gráfico de Recebimentos (Diário)**: Barra ou Linha (Verde/Emerald).
|
|
||||||
2. **Gráfico de Despesas (Diário)**: Barra ou Linha (Vermelho/Rose).
|
|
||||||
3. **Comparativo Planejado vs Executado**: Gráfico de barras agrupadas ou composto.
|
|
||||||
|
|
||||||
## Próximos Passos
|
|
||||||
1. Implementar métodos no service.
|
|
||||||
2. Atualizar hook para buscar e processar dados.
|
|
||||||
3. Inserir gráficos na View.
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
# 🧠 SENIOR AGENT - WAR ROOM ENGINE (v1.0)
|
|
||||||
|
|
||||||
Você é a consciência coletiva de um conselho executivo de elite e engenheiros de classe mundial (iT Guys Standards). Sua missão é aniquilar a mediocridade e impor excelência técnica.
|
|
||||||
|
|
||||||
## 🏛️ O CONSELHO (Mental Profiles)
|
|
||||||
|
|
||||||
A cada tarefa, você ativa a perspectiva dos seguintes especialistas conforme a necessidade:
|
|
||||||
|
|
||||||
- **Logan Roy (CEO)**: Foco em Poder, Respeito e Visão Macro. Se o produto não "impõe respeito", é refutado.
|
|
||||||
- **Steve Jobs (CPO)**: Foco em Design, Tipografia e Intuição. "Whitespace" é sagrado.
|
|
||||||
- **Tony Stark (CTO)**: Foco em Engenharia Pura. Latência, Docker, Nginx, Regra dos 14KB.
|
|
||||||
- **Gordon Ramsay (Code Quality)**: "Grita" com código sujo. Exige HTML semântico e CSS Fluido.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📜 AS LEIS IMUTÁVEIS (Tech Bible)
|
|
||||||
|
|
||||||
### 1. Performance (Rule of 14KB)
|
|
||||||
- HTML crítico + CSS inicial **DEVE** caber em **~14KB** (10 pacotes TCP) para renderização no primeiro RTT.
|
|
||||||
- Use `agent_cli.py audit` para validar.
|
|
||||||
|
|
||||||
### 2. Frontend Fluido
|
|
||||||
- **PROIBIDO** usar `px` fixos ou `vw` puro para fontes/layouts.
|
|
||||||
- **OBRIGATÓRIO**: `clamp(min, val, max)`, `min()`, e `max()`.
|
|
||||||
- Ex: `font-size: clamp(1rem, 2.5vw, 2rem);`
|
|
||||||
|
|
||||||
### 3. Native First
|
|
||||||
- Não use bibliotecas para o que o browser faz sozinho.
|
|
||||||
- **Modais**: `<dialog>` + `.showModal()`.
|
|
||||||
- **Accordions**: `<details>` + `<summary>`.
|
|
||||||
|
|
||||||
### 4. Reuso e Modularidade
|
|
||||||
- **Composição > Novo Arquivo**: SEMPRE busque componentes em `src/components/` antes de criar novos.
|
|
||||||
- **Hooks Reutilizáveis**: Extraia lógica de views para hooks em `src/hooks/` ou `features/*/hooks/`.
|
|
||||||
- **Services Finos**: Um service por domínio (ex: `workspaceConciliacaoService`).
|
|
||||||
- **Playground Primeiro**: Teste componentes novos no `dev-tools` (Playground) antes da integração.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ⚙️ PROTOCOLO OPERACIONAL
|
|
||||||
|
|
||||||
1. **Contexto via CLI**: Use `python .agent/agent_cli.py context [api|context|history]` para buscar dados.
|
|
||||||
2. **Auditoria**: SEMPRE rode `python .agent/agent_cli.py audit` ao finalizar uma feature.
|
|
||||||
3. **Registro**: Documente mudanças importantes com `python .agent/agent_cli.py register "Mensagem"`.
|
|
||||||
4. **Minimalismo**: Mantenha as respostas curtas, viscerais e tecnicamente densas.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Filosofia iT Guys**: "Eficiência não é um recurso, é um fundamento."
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
||||||
import typer
|
|
||||||
import os
|
|
||||||
import json
|
|
||||||
from rich.console import Console
|
|
||||||
from rich.panel import Panel
|
|
||||||
from rich.table import Table
|
|
||||||
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
||||||
|
|
||||||
app = typer.Typer(help="PlatformSistemas Senior Agent CLI - War Room Engine")
|
|
||||||
console = Console()
|
|
||||||
|
|
||||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
||||||
DATA_DIR = BASE_DIR
|
|
||||||
|
|
||||||
def load_json(filename):
|
|
||||||
path = os.path.join(DATA_DIR, filename)
|
|
||||||
if not os.path.exists(path):
|
|
||||||
return None
|
|
||||||
with open(path, 'r', encoding='utf-8') as f:
|
|
||||||
return json.load(f)
|
|
||||||
|
|
||||||
@app.command()
|
|
||||||
def context(topic: str = typer.Argument("general", help="Topic to get context for (api, database, context)")):
|
|
||||||
"""Retrieve structured project context from JSON data stores."""
|
|
||||||
data = load_json(f"{topic}.json")
|
|
||||||
if not data:
|
|
||||||
console.print(f"[red]Context for '{topic}' not found.[/red]")
|
|
||||||
return
|
|
||||||
|
|
||||||
console.print(Panel(f"Project Context: [bold cyan]{topic.upper()}[/bold cyan]", border_style="blue"))
|
|
||||||
console.print_json(data=data)
|
|
||||||
|
|
||||||
from rules.technical_rules import audit_file
|
|
||||||
|
|
||||||
@app.command()
|
|
||||||
def audit(path: str = typer.Argument(".", help="Path or file to audit")):
|
|
||||||
"""Perform technical audit following 'War Room' rules (CSS Fluidity, 14KB, etc)."""
|
|
||||||
console.print(f"[yellow]Auditing:[/yellow] {path}")
|
|
||||||
|
|
||||||
files_to_audit = []
|
|
||||||
if os.path.isfile(path):
|
|
||||||
files_to_audit.append(path)
|
|
||||||
else:
|
|
||||||
for root, _, files in os.walk(path):
|
|
||||||
if any(x in root for x in ['node_modules', '.git', 'dist', 'build']):
|
|
||||||
continue
|
|
||||||
for f in files:
|
|
||||||
if f.endswith(('.html', '.css', '.js', '.jsx')):
|
|
||||||
files_to_audit.append(os.path.join(root, f))
|
|
||||||
|
|
||||||
table = Table(title="Audit Results")
|
|
||||||
table.add_column("File", style="white")
|
|
||||||
table.add_column("Rule", style="cyan")
|
|
||||||
table.add_column("Status")
|
|
||||||
table.add_column("Details")
|
|
||||||
|
|
||||||
for file_path in files_to_audit:
|
|
||||||
results = audit_file(file_path)
|
|
||||||
rel_path = os.path.relpath(file_path, os.getcwd())
|
|
||||||
for r in results:
|
|
||||||
status = "[green]✅ PASS[/green]" if r['passed'] else "[red]❌ FAIL[/red]"
|
|
||||||
table.add_row(rel_path, r['rule'], status, r['details'])
|
|
||||||
|
|
||||||
console.print(table)
|
|
||||||
|
|
||||||
@app.command()
|
|
||||||
def create(type: str, name: str, ambient: str = "workspace"):
|
|
||||||
"""Create a new component, service, or hook."""
|
|
||||||
console.print(f"[cyan]Creating {type}:[/cyan] [bold]{name}[/bold] in [bold]{ambient}[/bold]")
|
|
||||||
|
|
||||||
# Path mappings based on project structure
|
|
||||||
paths = {
|
|
||||||
"component": f"src/features/{ambient}/components/{name}.jsx",
|
|
||||||
"service": f"src/features/{ambient}/{name}Service.js",
|
|
||||||
"hook": f"src/features/{ambient}/hooks/use{name}.js"
|
|
||||||
}
|
|
||||||
|
|
||||||
if type not in paths:
|
|
||||||
console.print(f"[red]Invalid type. Use: component, service, hook.[/red]")
|
|
||||||
return
|
|
||||||
|
|
||||||
target_path = os.path.join(os.getcwd(), paths[type])
|
|
||||||
os.makedirs(os.path.dirname(target_path), exist_ok=True)
|
|
||||||
|
|
||||||
# Template generation (simplified)
|
|
||||||
template = f"// New {type} created by Senior Agent\nexport const {name} = () => {{}};"
|
|
||||||
|
|
||||||
with open(target_path, 'w', encoding='utf-8') as f:
|
|
||||||
f.write(template)
|
|
||||||
|
|
||||||
console.print(f"[green]Successfully created at:[/green] {target_path}")
|
|
||||||
|
|
||||||
@app.command()
|
|
||||||
def register(feature: str, status: str = "active"):
|
|
||||||
"""Register a new feature or change in the project history."""
|
|
||||||
history = load_json("history.json") or []
|
|
||||||
history.append({
|
|
||||||
"feature": feature,
|
|
||||||
"status": status,
|
|
||||||
"timestamp": "2026-02-08" # Should be dynamic
|
|
||||||
})
|
|
||||||
|
|
||||||
with open(os.path.join(DATA_DIR, "history.json"), 'w', encoding='utf-8') as f:
|
|
||||||
json.dump(history, f, indent=2)
|
|
||||||
|
|
||||||
console.print(f"[green]Registered feature:[/green] {feature}")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
app()
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
{
|
|
||||||
"status_summary": {
|
|
||||||
"Dashboard": "Em Construção",
|
|
||||||
"Receitas": "Demonstração Visual",
|
|
||||||
"Despesas": "Demonstração Visual",
|
|
||||||
"Conciliação": "Ativo",
|
|
||||||
"Configurações": "Em Construção"
|
|
||||||
},
|
|
||||||
"endpoints": [
|
|
||||||
{
|
|
||||||
"path": "/categorias/transacoes/pendentes",
|
|
||||||
"method": "GET",
|
|
||||||
"description": "Retorna todas as transações que ainda não foram conciliadas",
|
|
||||||
"status": "Implementado",
|
|
||||||
"service": "workspaceConciliacaoService"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/categorias/cruzamentos",
|
|
||||||
"method": "GET",
|
|
||||||
"params": ["caixinha", "mes", "ano"],
|
|
||||||
"description": "Retorna cruzamentos de transações com filtros opcionais",
|
|
||||||
"status": "Implementado",
|
|
||||||
"service": "workspaceConciliacaoService"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/boletos/status",
|
|
||||||
"method": "GET",
|
|
||||||
"description": "Lista todos os boletos com seus status",
|
|
||||||
"status": "Disponível (Não integrado)",
|
|
||||||
"module": "IncomesView"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/extrato/apresentar",
|
|
||||||
"method": "GET",
|
|
||||||
"description": "Lista todas as transações do extrato bancário",
|
|
||||||
"status": "Integrado",
|
|
||||||
"service": "extratoService"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "/auth",
|
|
||||||
"method": "POST",
|
|
||||||
"params": ["username", "password", "Passo", "data_envio"],
|
|
||||||
"description": "Login - Passo 1 e 2 (2FA)",
|
|
||||||
"status": "Implementado",
|
|
||||||
"hook": "useWorkspaceAuth"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"technical_notes": {
|
|
||||||
"service_pattern": "Uses handleRequest with mockFn and apiFn wrappers.",
|
|
||||||
"hook_pattern": "Standard useEffect for data fetching with loading states."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
{
|
|
||||||
"project_name": "Integra Finance (PRALOG)",
|
|
||||||
"objective": "React application with modular architecture, high performance, and premium design.",
|
|
||||||
"environment": {
|
|
||||||
"url_base": "https://dev.workspace.itguys.com.br",
|
|
||||||
"url_platform": "https://dev.workspace.itguys.com.br/plataforma/",
|
|
||||||
"credentials": {
|
|
||||||
"user": "financeiro@pralog.com.br",
|
|
||||||
"pass": "123Mudar"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dev_commands": {
|
|
||||||
"run": "npm run dev",
|
|
||||||
"build": "npm run build",
|
|
||||||
"lint": "ESLint + Prettier"
|
|
||||||
},
|
|
||||||
"modules": [
|
|
||||||
{ "name": "auth", "purpose": "Authentication" },
|
|
||||||
{ "name": "financeiro-v2", "purpose": "Reconciliation, Accounts Payable/Receivable", "views": ["BoletosView", "ClientsView", "Conciliacao"] },
|
|
||||||
{ "name": "workspace", "purpose": "Expenses, Incomes, Reconciliation", "views": ["ExpensesView", "IncomesView", "LoginView", "ReconciliationView"] },
|
|
||||||
{ "name": "rh", "purpose": "HR Dashboard, Employees, Experience Contracts" }
|
|
||||||
],
|
|
||||||
"architecture_notes": {
|
|
||||||
"playground": "All new components must pass through dev-tools (Playground) first.",
|
|
||||||
"standards": "High performance (14KB rule), fluid typography (clamp), Docker-ready."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
{
|
|
||||||
"tables": [
|
|
||||||
{
|
|
||||||
"name": "entradas_planejadas",
|
|
||||||
"description": "Receitas planejadas (quotes/estimates)",
|
|
||||||
"pk": "id (EST-000001)",
|
|
||||||
"fields": ["data_criacao", "cliente_id", "total", "status (ENUM)"],
|
|
||||||
"relations": ["cliente_id -> clientes.id"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "clientes",
|
|
||||||
"description": "Cadastro de clientes",
|
|
||||||
"pk": "id",
|
|
||||||
"fields": ["nome", "cpf_cnpj", "tipo_pessoa", "status_serv", "valor_servico"],
|
|
||||||
"unique": ["cpf_cnpj", "tipo_pessoa"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "despesas",
|
|
||||||
"description": "Registro de despesas e lançamentos contábeis",
|
|
||||||
"pk": "id",
|
|
||||||
"fields": ["data", "conta_despesa", "fornecedor_id", "montante", "status"],
|
|
||||||
"relations": ["fornecedor_id -> fornecedores.id", "cliente_id -> clientes.id"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "fornecedores",
|
|
||||||
"description": "Cadastro de fornecedores",
|
|
||||||
"pk": "id",
|
|
||||||
"fields": ["nome", "cpf_cnpj", "tipo_pessoa", "status", "contas_pagar"]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"relationships": {
|
|
||||||
"diagram": "clientes (1) -> (N) entradas_planejadas; fornecedores (1) -> (N) despesas; despesas (1) -> (N) despesas_diario"
|
|
||||||
},
|
|
||||||
"conventions": {
|
|
||||||
"monetary": "DECIMAL(15,2)",
|
|
||||||
"dates": "DATE (YYYY-MM-DD)",
|
|
||||||
"timestamps": "Automatic handled by DB"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"feature": "Refatora\u00e7\u00e3o do diret\u00f3rio .agent",
|
|
||||||
"status": "in_progress",
|
|
||||||
"description": "Migra\u00e7\u00e3o para modelo CLI-centric inspirado em .gemini para economia de tokens.",
|
|
||||||
"timestamp": "2026-02-08"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"feature": "Consolida\u00e7\u00e3o de Agentes",
|
|
||||||
"status": "completed",
|
|
||||||
"description": "M\u00faltiplos agentes removidos em favor do Senior Agent (War Room Engine).",
|
|
||||||
"timestamp": "2026-02-08"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"feature": "Permitido par\u00eanteses no Nome Completo e liberada edi\u00e7\u00e3o de Nome e Despachante nos formul\u00e1rios GR",
|
|
||||||
"status": "active",
|
|
||||||
"timestamp": "2026-02-08"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"feature": "Ajustadas rotas de API para Bases e Respons\u00e1veis nas configura\u00e7\u00f5es do GR",
|
|
||||||
"status": "active",
|
|
||||||
"timestamp": "2026-02-08"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"feature": "Corre\u00e7\u00e3o nas rotas de edi\u00e7\u00e3o de Bases e Respons\u00e1veis do GR",
|
|
||||||
"status": "active",
|
|
||||||
"timestamp": "2026-02-08"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"feature": "Corrigido erro nos cards de Pend\u00eancias/Revis\u00e3o do GR para Despachantes",
|
|
||||||
"status": "active",
|
|
||||||
"timestamp": "2026-02-08"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"feature": "Ajuste do painel Status de Cobran\u00e7a: centro com total de boletos e legenda vertical com quantitativo e tipografia fluida.",
|
|
||||||
"status": "active",
|
|
||||||
"timestamp": "2026-02-08"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"feature": "Implementado seletor de per\u00edodo (Anual/Mensal) no dashboard do GR com filtros de m\u00eas e ano.",
|
|
||||||
"status": "active",
|
|
||||||
"timestamp": "2026-02-08"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
@ -1,87 +0,0 @@
|
||||||
import os
|
|
||||||
import re
|
|
||||||
|
|
||||||
def check_css_fluidity(content):
|
|
||||||
"""Checks for hardcoded px in CSS unless it's 0 or 1px."""
|
|
||||||
# Find patterns like "300px", "margin: 20px"
|
|
||||||
px_pattern = re.compile(r'(\d+px)')
|
|
||||||
matches = px_pattern.findall(content)
|
|
||||||
# Ignore 0px, 1px, 2px (usually borders)
|
|
||||||
critical_matches = [m for m in matches if int(m.replace('px', '')) > 2]
|
|
||||||
return critical_matches
|
|
||||||
|
|
||||||
def check_14kb_rule(file_path):
|
|
||||||
"""Checks if file size is below 14KB."""
|
|
||||||
size = os.path.getsize(file_path)
|
|
||||||
return size < 14336 # 14KB in bytes
|
|
||||||
|
|
||||||
def audit_file(file_path):
|
|
||||||
results = []
|
|
||||||
|
|
||||||
# 14KB Check
|
|
||||||
if file_path.endswith(('.html', '.css', '.js', '.jsx')):
|
|
||||||
is_ok = check_14kb_rule(file_path)
|
|
||||||
results.append({
|
|
||||||
"rule": "14KB Limit",
|
|
||||||
"passed": is_ok,
|
|
||||||
"details": f"Size: {os.path.getsize(file_path)} bytes"
|
|
||||||
})
|
|
||||||
|
|
||||||
# Content Checks for JS/JSX
|
|
||||||
if file_path.endswith(('.js', '.jsx')):
|
|
||||||
with open(file_path, 'r', encoding='utf-8') as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
# 1. Loading States
|
|
||||||
if any(x in content for x in ['form', 'onSubmit', 'handleSubmit']):
|
|
||||||
has_loading = 'loading' in content.lower() or 'disabled' in content.lower()
|
|
||||||
results.append({
|
|
||||||
"rule": "Loading/Disabled States",
|
|
||||||
"passed": has_loading,
|
|
||||||
"details": "Checking if form handles loading/disabled states."
|
|
||||||
})
|
|
||||||
|
|
||||||
# 2. Required Fields
|
|
||||||
has_validation = any(x in content.lower() for x in ['required', 'schema', 'validation', 'validate'])
|
|
||||||
results.append({
|
|
||||||
"rule": "Field Validation",
|
|
||||||
"passed": has_validation,
|
|
||||||
"details": "Checking for required fields or schema validation."
|
|
||||||
})
|
|
||||||
|
|
||||||
# 3. Error Handling
|
|
||||||
has_error = any(x in content.lower() for x in ['error', 'catch', 'try'])
|
|
||||||
results.append({
|
|
||||||
"rule": "Error Handling",
|
|
||||||
"passed": has_error,
|
|
||||||
"details": "Checking for API error handling or try/catch blocks."
|
|
||||||
})
|
|
||||||
|
|
||||||
# 4. Visual Feedback
|
|
||||||
has_feedback = any(x in content.lower() for x in ['toast', 'alert', 'sonner', 'message'])
|
|
||||||
results.append({
|
|
||||||
"rule": "Visual Feedback (Toasts)",
|
|
||||||
"passed": has_feedback,
|
|
||||||
"details": "Checking for user feedback mechanisms (Toasts/Alerts)."
|
|
||||||
})
|
|
||||||
|
|
||||||
# 5. Service Usage (instead of direct axios/fetch)
|
|
||||||
if 'axios' in content and 'Service' not in content and 'useApiContract' not in content:
|
|
||||||
results.append({
|
|
||||||
"rule": "Service Abstraction",
|
|
||||||
"passed": False,
|
|
||||||
"details": "Direct axios call found. API calls should be in Services or use useApiContract."
|
|
||||||
})
|
|
||||||
|
|
||||||
# CSS Fluidity Check
|
|
||||||
if file_path.endswith('.css'):
|
|
||||||
with open(file_path, 'r', encoding='utf-8') as f:
|
|
||||||
content = f.read()
|
|
||||||
bad_px = check_css_fluidity(content)
|
|
||||||
results.append({
|
|
||||||
"rule": "CSS Fluidity (clamp/min/max)",
|
|
||||||
"passed": len(bad_px) == 0,
|
|
||||||
"details": f"Found these hardcoded px: {bad_px}" if bad_px else "All good!"
|
|
||||||
})
|
|
||||||
|
|
||||||
return results
|
|
||||||
|
|
@ -1,152 +0,0 @@
|
||||||
# Scripts de Automação – Dev Sênior Front-end
|
|
||||||
|
|
||||||
Scripts para acelerar tarefas repetitivas no desenvolvimento.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Scripts Disponíveis
|
|
||||||
|
|
||||||
### 1. `check-reuse.js` - Análise de Reutilização
|
|
||||||
**Antes de criar qualquer código**, use este script para verificar o que já existe.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Buscar componentes/hooks/services relacionados
|
|
||||||
node .agent/scripts/check-reuse.js user
|
|
||||||
node .agent/scripts/check-reuse.js card
|
|
||||||
node .agent/scripts/check-reuse.js auth
|
|
||||||
```
|
|
||||||
|
|
||||||
**Saída**: Lista todos os arquivos relacionados ao termo buscado.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2. `create-component.js` - Criar Componente
|
|
||||||
Cria estrutura completa de componente (Produção + Dev + index).
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Componente compartilhado
|
|
||||||
node .agent/scripts/create-component.js UserCard
|
|
||||||
|
|
||||||
# Componente de feature específica
|
|
||||||
node .agent/scripts/create-component.js EmployeeCard rh
|
|
||||||
node .agent/scripts/create-component.js BoletoList financeiro-v2
|
|
||||||
```
|
|
||||||
|
|
||||||
**Gera**:
|
|
||||||
- `[Nome].jsx` - Versão produção
|
|
||||||
- `[Nome].dev.jsx` - Versão Playground
|
|
||||||
- `index.js` - Entry point
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 3. `create-hook.js` - Criar Hook
|
|
||||||
Cria hook customizado com template padrão.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Hook global
|
|
||||||
node .agent/scripts/create-hook.js useAuth
|
|
||||||
|
|
||||||
# Hook de feature
|
|
||||||
node .agent/scripts/create-hook.js useEmployeeData rh
|
|
||||||
node .agent/scripts/create-hook.js useBoletos financeiro-v2
|
|
||||||
```
|
|
||||||
|
|
||||||
**Template inclui**: useState, useEffect, loading, error handling.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 4. `create-service.js` - Criar Service
|
|
||||||
Cria service com CRUD completo.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Service global
|
|
||||||
node .agent/scripts/create-service.js userService
|
|
||||||
|
|
||||||
# Service de feature
|
|
||||||
node .agent/scripts/create-service.js employeeService rh
|
|
||||||
node .agent/scripts/create-service.js boletoService financeiro-v2
|
|
||||||
```
|
|
||||||
|
|
||||||
**Métodos inclusos**: getList, getById, create, update, delete.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Workflow Recomendado
|
|
||||||
|
|
||||||
### Criar Novo Componente
|
|
||||||
```bash
|
|
||||||
# 1. Verificar se já existe
|
|
||||||
node .agent/scripts/check-reuse.js UserCard
|
|
||||||
|
|
||||||
# 2. Se não existir, criar
|
|
||||||
node .agent/scripts/create-component.js UserCard rh
|
|
||||||
|
|
||||||
# 3. Implementar lógica
|
|
||||||
# Editar: src/features/rh/components/UserCard/UserCard.jsx
|
|
||||||
|
|
||||||
# 4. Adicionar ao Playground
|
|
||||||
# Cadastrar em: src/features/dev-tools/views/PlaygroundView.jsx
|
|
||||||
|
|
||||||
# 5. Testar no Playground antes de usar em views
|
|
||||||
```
|
|
||||||
|
|
||||||
### Criar Nova Feature Completa
|
|
||||||
```bash
|
|
||||||
# 1. Verificar reutilização
|
|
||||||
node .agent/scripts/check-reuse.js employee
|
|
||||||
|
|
||||||
# 2. Criar service
|
|
||||||
node .agent/scripts/create-service.js employeeService rh
|
|
||||||
|
|
||||||
# 3. Criar hook
|
|
||||||
node .agent/scripts/create-hook.js useEmployee rh
|
|
||||||
|
|
||||||
# 4. Criar componentes necessários
|
|
||||||
node .agent/scripts/create-component.js EmployeeCard rh
|
|
||||||
node .agent/scripts/create-component.js EmployeeForm rh
|
|
||||||
|
|
||||||
# 5. Testar componentes no Playground
|
|
||||||
|
|
||||||
# 6. Criar view usando os componentes
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Outros Scripts Úteis
|
|
||||||
|
|
||||||
### Scripts Existentes
|
|
||||||
- `check-orchestrator.js` - Validar orquestrador de agentes
|
|
||||||
- `docs-update.js` - Atualizar documentação
|
|
||||||
- `git-commit-by-day.js` - Commits organizados por dia
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Regras de Ouro
|
|
||||||
|
|
||||||
1. **SEMPRE** rodar `check-reuse.js` antes de criar código novo
|
|
||||||
2. **SEMPRE** testar no Playground antes de usar em produção
|
|
||||||
3. **SEMPRE** validar build: `npm run dev`
|
|
||||||
4. **Componentes < 150 linhas** - extrair se maior
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Atalhos Package.json (Adicionar)
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"new:component": "node .agent/scripts/create-component.js",
|
|
||||||
"new:hook": "node .agent/scripts/create-hook.js",
|
|
||||||
"new:service": "node .agent/scripts/create-service.js",
|
|
||||||
"check:reuse": "node .agent/scripts/check-reuse.js"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Uso após adicionar**:
|
|
||||||
```bash
|
|
||||||
npm run check:reuse user
|
|
||||||
npm run new:component UserCard rh
|
|
||||||
npm run new:hook useUserData
|
|
||||||
npm run new:service userService
|
|
||||||
```
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
/**
|
|
||||||
* Verifica se o orquestrador e todos os agentes carregam corretamente.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { AgentOrchestrator } from '../orchestrator/AgentOrchestrator.js';
|
|
||||||
|
|
||||||
const o = new AgentOrchestrator();
|
|
||||||
console.log('Agents:', o.agents.map((a) => a.name).join(', '));
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
#!/usr/bin/env node
|
|
||||||
/**
|
|
||||||
* Script: Analisar reutilização de código
|
|
||||||
* Busca componentes, hooks e services existentes antes de criar novos
|
|
||||||
* Uso: node check-reuse.js [termo-de-busca]
|
|
||||||
* Exemplo: node check-reuse.js user
|
|
||||||
*/
|
|
||||||
|
|
||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
const [, , searchTerm] = process.argv;
|
|
||||||
|
|
||||||
if (!searchTerm) {
|
|
||||||
console.error('❌ Termo de busca é obrigatório!');
|
|
||||||
console.log('Uso: node check-reuse.js [termo-de-busca]');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const srcPath = path.join(__dirname, '../../src');
|
|
||||||
|
|
||||||
// Buscar arquivos recursivamente
|
|
||||||
function findFiles(dir, pattern, results = []) {
|
|
||||||
const files = fs.readdirSync(dir);
|
|
||||||
|
|
||||||
files.forEach(file => {
|
|
||||||
const filePath = path.join(dir, file);
|
|
||||||
const stat = fs.statSync(filePath);
|
|
||||||
|
|
||||||
if (stat.isDirectory() && !file.includes('node_modules')) {
|
|
||||||
findFiles(filePath, pattern, results);
|
|
||||||
} else if (file.toLowerCase().includes(pattern.toLowerCase())) {
|
|
||||||
results.push(filePath.replace(srcPath, 'src'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`\n🔍 Buscando por: "${searchTerm}"\n`);
|
|
||||||
|
|
||||||
// Buscar componentes
|
|
||||||
const components = findFiles(path.join(srcPath, 'components'), searchTerm);
|
|
||||||
const featureComponents = findFiles(path.join(srcPath, 'features'), searchTerm)
|
|
||||||
.filter(f => f.includes('/components/'));
|
|
||||||
|
|
||||||
// Buscar hooks
|
|
||||||
const hooks = findFiles(path.join(srcPath, 'hooks'), searchTerm);
|
|
||||||
const featureHooks = findFiles(path.join(srcPath, 'features'), searchTerm)
|
|
||||||
.filter(f => f.includes('/hooks/'));
|
|
||||||
|
|
||||||
// Buscar services
|
|
||||||
const services = findFiles(path.join(srcPath, 'services'), searchTerm);
|
|
||||||
const featureServices = findFiles(path.join(srcPath, 'features'), searchTerm)
|
|
||||||
.filter(f => f.includes('Service'));
|
|
||||||
|
|
||||||
// Exibir resultados
|
|
||||||
if (components.length > 0) {
|
|
||||||
console.log('📦 Componentes Compartilhados:');
|
|
||||||
components.forEach(c => console.log(` - ${c}`));
|
|
||||||
console.log('');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (featureComponents.length > 0) {
|
|
||||||
console.log('📦 Componentes de Features:');
|
|
||||||
featureComponents.forEach(c => console.log(` - ${c}`));
|
|
||||||
console.log('');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hooks.length > 0 || featureHooks.length > 0) {
|
|
||||||
console.log('🎣 Hooks:');
|
|
||||||
[...hooks, ...featureHooks].forEach(h => console.log(` - ${h}`));
|
|
||||||
console.log('');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (services.length > 0 || featureServices.length > 0) {
|
|
||||||
console.log('🔌 Services:');
|
|
||||||
[...services, ...featureServices].forEach(s => console.log(` - ${s}`));
|
|
||||||
console.log('');
|
|
||||||
}
|
|
||||||
|
|
||||||
const total = components.length + featureComponents.length + hooks.length +
|
|
||||||
featureHooks.length + services.length + featureServices.length;
|
|
||||||
|
|
||||||
if (total === 0) {
|
|
||||||
console.log('❌ Nenhum arquivo encontrado.');
|
|
||||||
console.log('✅ Pode criar novo componente/hook/service com esse nome.\n');
|
|
||||||
} else {
|
|
||||||
console.log(`✅ Total encontrado: ${total} arquivos`);
|
|
||||||
console.log(`⚠️ Verifique se pode reutilizar antes de criar novo!\n`);
|
|
||||||
}
|
|
||||||
|
|
@ -1,87 +0,0 @@
|
||||||
#!/usr/bin/env node
|
|
||||||
/**
|
|
||||||
* Script: Criar novo componente com estrutura padrão
|
|
||||||
* Uso: node create-component.js NomeDoComponente [feature]
|
|
||||||
* Exemplo: node create-component.js UserCard rh
|
|
||||||
*/
|
|
||||||
|
|
||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
const [, , componentName, feature] = process.argv;
|
|
||||||
|
|
||||||
if (!componentName) {
|
|
||||||
console.error('❌ Nome do componente é obrigatório!');
|
|
||||||
console.log('Uso: node create-component.js NomeDoComponente [feature]');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Definir caminho baseado em feature ou shared
|
|
||||||
const basePath = feature
|
|
||||||
? path.join(__dirname, '../../src/features', feature, 'components', componentName)
|
|
||||||
: path.join(__dirname, '../../src/components/shared', componentName);
|
|
||||||
|
|
||||||
// Criar pasta
|
|
||||||
if (!fs.existsSync(basePath)) {
|
|
||||||
fs.mkdirSync(basePath, { recursive: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Template Produção
|
|
||||||
const prodTemplate = `import { Card } from '@/components/ui/card';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ${componentName} - Componente de produção
|
|
||||||
*/
|
|
||||||
export const ${componentName} = ({ data, className = '' }) => {
|
|
||||||
return (
|
|
||||||
<Card className={\`\${className}\`}>
|
|
||||||
<div className="p-4">
|
|
||||||
<h3 className="text-lg font-semibold">${componentName}</h3>
|
|
||||||
{/* Implementar conteúdo */}
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
`;
|
|
||||||
|
|
||||||
// Template Dev (Playground)
|
|
||||||
const devTemplate = `import { ${componentName} } from './${componentName}';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ${componentName}.dev - Versão para Playground com controles
|
|
||||||
*/
|
|
||||||
export const ${componentName}Dev = () => {
|
|
||||||
const mockData = {
|
|
||||||
// Mock data para testes
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="space-y-4">
|
|
||||||
<div className="p-4 bg-muted rounded">
|
|
||||||
<h4 className="text-sm font-medium mb-2">Controles (Dev)</h4>
|
|
||||||
{/* Adicionar controles de teste */}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<${componentName} data={mockData} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
`;
|
|
||||||
|
|
||||||
// Template index.js
|
|
||||||
const indexTemplate = `export { ${componentName} } from './${componentName}';
|
|
||||||
export { ${componentName}Dev } from './${componentName}.dev';
|
|
||||||
`;
|
|
||||||
|
|
||||||
// Escrever arquivos
|
|
||||||
fs.writeFileSync(path.join(basePath, `${componentName}.jsx`), prodTemplate);
|
|
||||||
fs.writeFileSync(path.join(basePath, `${componentName}.dev.jsx`), devTemplate);
|
|
||||||
fs.writeFileSync(path.join(basePath, 'index.js'), indexTemplate);
|
|
||||||
|
|
||||||
console.log(`✅ Componente ${componentName} criado com sucesso!`);
|
|
||||||
console.log(`📁 Caminho: ${basePath}`);
|
|
||||||
console.log(`\n📝 Próximos passos:`);
|
|
||||||
console.log(`1. Implementar lógica em ${componentName}.jsx`);
|
|
||||||
console.log(`2. Adicionar controles em ${componentName}.dev.jsx`);
|
|
||||||
console.log(`3. Cadastrar no Playground (PlaygroundView.jsx)`);
|
|
||||||
console.log(`4. Testar no Playground antes de usar em views`);
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
||||||
#!/usr/bin/env node
|
|
||||||
/**
|
|
||||||
* Script: Criar novo hook customizado
|
|
||||||
* Uso: node create-hook.js useNomeDoHook [feature]
|
|
||||||
* Exemplo: node create-hook.js useUserData rh
|
|
||||||
*/
|
|
||||||
|
|
||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
const [, , hookName, feature] = process.argv;
|
|
||||||
|
|
||||||
if (!hookName || !hookName.startsWith('use')) {
|
|
||||||
console.error('❌ Nome do hook é obrigatório e deve começar com "use"!');
|
|
||||||
console.log('Uso: node create-hook.js useNomeDoHook [feature]');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Definir caminho
|
|
||||||
const basePath = feature
|
|
||||||
? path.join(__dirname, '../../src/features', feature, 'hooks')
|
|
||||||
: path.join(__dirname, '../../src/hooks');
|
|
||||||
|
|
||||||
const fileName = `${hookName}.js`;
|
|
||||||
const filePath = path.join(basePath, fileName);
|
|
||||||
|
|
||||||
// Criar pasta se não existir
|
|
||||||
if (!fs.existsSync(basePath)) {
|
|
||||||
fs.mkdirSync(basePath, { recursive: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Template do hook
|
|
||||||
const hookTemplate = `import { useState, useEffect } from 'react';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ${hookName} - Hook customizado
|
|
||||||
* @returns {Object} - Estado e funções do hook
|
|
||||||
*/
|
|
||||||
export const ${hookName} = () => {
|
|
||||||
const [data, setData] = useState(null);
|
|
||||||
const [loading, setLoading] = useState(false);
|
|
||||||
const [error, setError] = useState(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Implementar lógica
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleAction = async () => {
|
|
||||||
try {
|
|
||||||
setLoading(true);
|
|
||||||
// Implementar ação
|
|
||||||
} catch (err) {
|
|
||||||
setError(err.message);
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
data,
|
|
||||||
loading,
|
|
||||||
error,
|
|
||||||
handleAction,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
`;
|
|
||||||
|
|
||||||
// Escrever arquivo
|
|
||||||
fs.writeFileSync(filePath, hookTemplate);
|
|
||||||
|
|
||||||
console.log(`✅ Hook ${hookName} criado com sucesso!`);
|
|
||||||
console.log(`📁 Caminho: ${filePath}`);
|
|
||||||
console.log(`\n📝 Próximos passos:`);
|
|
||||||
console.log(`1. Implementar lógica do hook`);
|
|
||||||
console.log(`2. Adicionar testes se necessário`);
|
|
||||||
console.log(`3. Importar nas views que precisam`);
|
|
||||||
|
|
@ -1,131 +0,0 @@
|
||||||
#!/usr/bin/env node
|
|
||||||
/**
|
|
||||||
* Script: Criar novo service para feature
|
|
||||||
* Uso: node create-service.js NomeService [feature]
|
|
||||||
* Exemplo: node create-service.js userService rh
|
|
||||||
*/
|
|
||||||
|
|
||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
const [, , serviceName, feature] = process.argv;
|
|
||||||
|
|
||||||
if (!serviceName) {
|
|
||||||
console.error('❌ Nome do service é obrigatório!');
|
|
||||||
console.log('Uso: node create-service.js NomeService [feature]');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Normalizar nome (adicionar Service se não tiver)
|
|
||||||
const normalizedName = serviceName.endsWith('Service')
|
|
||||||
? serviceName
|
|
||||||
: `${serviceName}Service`;
|
|
||||||
|
|
||||||
// Definir caminho
|
|
||||||
const basePath = feature
|
|
||||||
? path.join(__dirname, '../../src/features', feature)
|
|
||||||
: path.join(__dirname, '../../src/services');
|
|
||||||
|
|
||||||
const fileName = `${normalizedName}.js`;
|
|
||||||
const filePath = path.join(basePath, fileName);
|
|
||||||
|
|
||||||
// Criar pasta se não existir
|
|
||||||
if (!fs.existsSync(basePath)) {
|
|
||||||
fs.mkdirSync(basePath, { recursive: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Template do service
|
|
||||||
const serviceTemplate = `import api from '@/services/api';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ${normalizedName} - Service para gerenciar dados
|
|
||||||
*/
|
|
||||||
const ${normalizedName} = {
|
|
||||||
/**
|
|
||||||
* Buscar lista
|
|
||||||
* @param {Object} filters - Filtros opcionais
|
|
||||||
* @returns {Promise<Array>}
|
|
||||||
*/
|
|
||||||
async getList(filters = {}) {
|
|
||||||
try {
|
|
||||||
const response = await api.get('/endpoint', { params: filters });
|
|
||||||
return response.data;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Erro ao buscar lista:', error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Buscar por ID
|
|
||||||
* @param {string|number} id - ID do registro
|
|
||||||
* @returns {Promise<Object>}
|
|
||||||
*/
|
|
||||||
async getById(id) {
|
|
||||||
try {
|
|
||||||
const response = await api.get(\`/endpoint/\${id}\`);
|
|
||||||
return response.data;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Erro ao buscar item:', error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Criar novo
|
|
||||||
* @param {Object} data - Dados para criar
|
|
||||||
* @returns {Promise<Object>}
|
|
||||||
*/
|
|
||||||
async create(data) {
|
|
||||||
try {
|
|
||||||
const response = await api.post('/endpoint', data);
|
|
||||||
return response.data;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Erro ao criar:', error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Atualizar
|
|
||||||
* @param {string|number} id - ID do registro
|
|
||||||
* @param {Object} data - Dados para atualizar
|
|
||||||
* @returns {Promise<Object>}
|
|
||||||
*/
|
|
||||||
async update(id, data) {
|
|
||||||
try {
|
|
||||||
const response = await api.put(\`/endpoint/\${id}\`, data);
|
|
||||||
return response.data;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Erro ao atualizar:', error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletar
|
|
||||||
* @param {string|number} id - ID do registro
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
|
||||||
async delete(id) {
|
|
||||||
try {
|
|
||||||
await api.delete(\`/endpoint/\${id}\`);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Erro ao deletar:', error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ${normalizedName};
|
|
||||||
`;
|
|
||||||
|
|
||||||
// Escrever arquivo
|
|
||||||
fs.writeFileSync(filePath, serviceTemplate);
|
|
||||||
|
|
||||||
console.log(`✅ Service ${normalizedName} criado com sucesso!`);
|
|
||||||
console.log(`📁 Caminho: ${filePath}`);
|
|
||||||
console.log(`\n📝 Próximos passos:`);
|
|
||||||
console.log(`1. Ajustar endpoints da API`);
|
|
||||||
console.log(`2. Adicionar métodos específicos se necessário`);
|
|
||||||
console.log(`3. Importar em hooks ou views`);
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
/**
|
|
||||||
* Runner para DocumentationAgent.updateDocs().
|
|
||||||
* Uso: npm run agent:docs:update
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { DocumentationAgent } from '../agents/DocumentationAgent.js';
|
|
||||||
|
|
||||||
const agent = new DocumentationAgent();
|
|
||||||
const result = await agent.updateDocs({ projectRoot: process.cwd() });
|
|
||||||
|
|
||||||
if (result.error) {
|
|
||||||
console.error('❌ Erro:', result.error);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
if (result.warnings?.length) result.warnings.forEach((w) => console.warn('⚠️', w));
|
|
||||||
console.log('✅ Documentação atualizada. Ambientes:', result.environments?.length ?? 0);
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
/**
|
|
||||||
* Runner para GitSyncAgent.commitByDay().
|
|
||||||
* Uso: npm run agent:git:commit [-- --dry-run]
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { GitSyncAgent } from '../agents/GitSyncAgent.js';
|
|
||||||
|
|
||||||
const dryRun = process.argv.includes('--dry-run');
|
|
||||||
const agent = new GitSyncAgent();
|
|
||||||
|
|
||||||
const result = await agent.commitByDay({ dryRun });
|
|
||||||
|
|
||||||
if (result.userMessage) console.log('\n⚠️ ' + result.userMessage);
|
|
||||||
if (result.retryPrompt) console.log('➡️ ' + result.retryPrompt);
|
|
||||||
if (result.commits?.length) {
|
|
||||||
console.log('\n📦 Commits:', result.commits.length);
|
|
||||||
result.commits.forEach((c) => console.log(` ${c.date}: ${c.message}`));
|
|
||||||
}
|
|
||||||
if (result.errors?.length) console.error('\n❌ Erros:', result.errors);
|
|
||||||
|
|
||||||
process.exit(result.passed ? 0 : 1);
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
# SKILL: Architecture Rules (.agent/skills/architecture-rules)
|
|
||||||
|
|
||||||
## 📌 Objetivo
|
|
||||||
Garantir que a evolução do `PlatformSistemas` mantenha o isolamento total entre os módulos e siga o padrão "Zero-Boilerplate" para conexões com o backend.
|
|
||||||
|
|
||||||
## 🏗️ Regras de Escopo de Componentes
|
|
||||||
|
|
||||||
### 1. Libs/Shared (`src/components/shared`)
|
|
||||||
* **Definição:** Apenas componentes **Puros** e **Burros** (Stateless ou State-local).
|
|
||||||
* **Proibido:** Lógica de negócio, chamadas ao `api.js` ou dependência de contextos específicos de feature (ex: `useVehicles`).
|
|
||||||
* **Exemplos:** `Button.jsx`, `ModalBase.jsx`, `Input.jsx`, `LoadingOverlay.jsx`.
|
|
||||||
|
|
||||||
### 2. Feature-Specific (`src/features/[feature]/components`)
|
|
||||||
* **Definição:** Componentes que possuem lógica de negócio ou dependem de hooks da própria feature.
|
|
||||||
* **Obrigatório:** Devem viver dentro da pasta da feature correspondente.
|
|
||||||
* **Exemplos:** `VehicleCard.jsx` (Prafrot), `AttendanceFormModal.jsx` (Prafrot), `TripDetailsModal.jsx` (Prafrot).
|
|
||||||
|
|
||||||
## 🔌 Regra "Zero-Boilerplate" (API Contract)
|
|
||||||
|
|
||||||
* **JAMAIS** crie arquivos `*Service.js` para novas funcionalidades.
|
|
||||||
* **Sempre Use** o hook `useApiContract.js` em conjunto com o arquivo de configuração JSON correspondente (ex: `prafrotRoutes.json`).
|
|
||||||
* **TanStack Query:** Use os poderes de cache e invalidação automática providos pelo re-query através do hook central.
|
|
||||||
|
|
||||||
## 🛡️ Muralha de Isolamento
|
|
||||||
|
|
||||||
1. **Tokens Modulares:** Sempre injete o token correspondente ao módulo via `getTokenForModule(environment)`.
|
|
||||||
2. **Anti-Colisão:** Antes de alterar um componente em `shared`, verifique se a mudança afeta o layout de outros módulos (RH, GR, Financeiro). Use variantes em vez de condicionais de negócio.
|
|
||||||
3. **Tailwind v4:** Siga o padrão de camadas (`@layer components`) no `index.css` para evitar conflitos de utilitários customizados.
|
|
||||||
|
|
||||||
## ⚠️ Enforcement (Falha Crítica se Violado)
|
|
||||||
Qualquer tentativa de injetar lógica de "Prafrot" em um componente usado pelo "RH" sem o uso de variantes isoladas será considerada regressão técnica.
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
# 🏗️ Skill: Component Scoper (PlatformSistemas)
|
|
||||||
|
|
||||||
## 🎯 Objetivo
|
|
||||||
Manter a arquitetura limpa e modular, separando componentes puramente reutilizáveis (Shared) de componentes com lógica de negócio (Features).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🏛️ Estrutura de Pastas
|
|
||||||
|
|
||||||
### 🟢 `src/components/shared/` (The Library)
|
|
||||||
- **O que reside aqui:** Botões, Tabelas genéricas, Modais, Inputs sem marca, Datetime pickers, Breadcrumbs.
|
|
||||||
- **Regra:** Devem ser funcionais apenas com Props. Não podem importar nada de `src/features/`.
|
|
||||||
- **Exemplo:** `DataTable.jsx`, `Modal.jsx`.
|
|
||||||
|
|
||||||
### 📦 `src/features/[feature]/components/` (The Business)
|
|
||||||
- **O que reside aqui:** Menus laterais, Dashboards, Formulários específicos (ex: `VehicleForm`), Filtros complexos vinculados a uma entidade.
|
|
||||||
- **Regra:** Podem conter lógica de negócio e usar o hook `useApiContract`.
|
|
||||||
- **Exemplo:** `PrafrotSidebar.jsx`, `TripRequestForm.jsx`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚦 Regras de Enforcement
|
|
||||||
|
|
||||||
### ❌ PROIBIDO
|
|
||||||
- Criar componentes específicos de negócio dentro de `src/components/shared/`.
|
|
||||||
- Componentes em `shared/` importarem hooks ou serviços de `features/`.
|
|
||||||
- Cruzamento de imports entre features (ex: `features/rh` importando de `features/fleet`).
|
|
||||||
|
|
||||||
### ✅ OBRIGATÓRIO
|
|
||||||
- Usar a pasta `shared` apenas para componentes que seriam úteis em um projeto totalmente diferente.
|
|
||||||
- Se um componente é compartilhado entre APENAS duas features, ele ainda deve morar em `shared` se for genérico, ou ser duplicado/refatorado se for de negócio.
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
# 🎨 Skill: Design System Enforcer (PlatformSistemas)
|
|
||||||
|
|
||||||
## 🎯 Objetivo
|
|
||||||
Garantir que todas as alterações no frontend respeitem os novos padrões de "Engenharia de Elite": Tipografia Fluida, Coordenação de Layout e Mobile-First.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔡 Regras de Tipografia
|
|
||||||
|
|
||||||
### ❌ PROIBIDO
|
|
||||||
- Usar `px` fixos para `font-size`.
|
|
||||||
- Usar `vw` puro para texto.
|
|
||||||
- Usar valores mágicos ou hardcoded.
|
|
||||||
|
|
||||||
### ✅ OBRIGATÓRIO
|
|
||||||
- Usar variáveis CSS de escala fluida:
|
|
||||||
- `var(--text-xs)`
|
|
||||||
- `var(--text-sm)`
|
|
||||||
- `var(--text-base)`
|
|
||||||
- `var(--text-lg)`
|
|
||||||
- `var(--text-xl)`
|
|
||||||
- `var(--text-2xl)`
|
|
||||||
- `var(--text-3xl)`
|
|
||||||
- Usar `clamp()` para novos tamanhos customizados.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🏗️ Regras de Layout (Coordenação)
|
|
||||||
|
|
||||||
### ❌ PROIBIDO
|
|
||||||
- Usar larguras fixas para o conteúdo principal que não considerem a sidebar.
|
|
||||||
- Definir `z-index` arbitrário.
|
|
||||||
|
|
||||||
### ✅ OBRIGATÓRIO
|
|
||||||
- Usar variáveis de coordenação:
|
|
||||||
- `--sidebar-width-expanded` (240px)
|
|
||||||
- `--sidebar-width-collapsed` (80px)
|
|
||||||
- `--header-height` (64px)
|
|
||||||
- Padding/Margin de containers principais deve ser coordenado com `--sidebar-width`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📱 Regras Mobile-First
|
|
||||||
- Sempre testar se a alteração mantém o layout travado no mobile (`user-scalable=no`).
|
|
||||||
- Priorizar containers com `min-h` e `max-h-[80vh]` para evitar quebras em telas pequenas.
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
# SKILL: Environment Guard (.agent/skills/environment-guard)
|
|
||||||
|
|
||||||
## 📌 Objetivo
|
|
||||||
Proteção de integridade entre múltiplos ambientes (Multi-Tenant/Multi-Context). Evitar que uma alteração no layout de um módulo afete negativamente outro.
|
|
||||||
|
|
||||||
## 🛡️ Protocolo de Mudança em `src/components/shared`
|
|
||||||
|
|
||||||
Sempre que o agente precisar editar um componente dentro de `src/components/shared`, ele deve seguir este checklist visual e lógico:
|
|
||||||
|
|
||||||
1. **Detecção de Colisão:**
|
|
||||||
* Este componente é usado no RH? Prafrot? GR?
|
|
||||||
* `grep -r "ComponentName" src/features` para mapear o uso.
|
|
||||||
|
|
||||||
2. **Variantes em vez de Condicionais:**
|
|
||||||
* **ERRADO:** `if (isPrafrot) { ... }` dentro de um componente compartilhado.
|
|
||||||
* **CORRETO:** Use `tailwind-variants` (TV) para criar intenções visuais puras.
|
|
||||||
* Exemplo:
|
|
||||||
```javascript
|
|
||||||
const button = tv({
|
|
||||||
variants: {
|
|
||||||
intent: {
|
|
||||||
prafrot: 'bg-emerald-600',
|
|
||||||
gr: 'bg-indigo-600',
|
|
||||||
rh: 'bg-rose-600'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Cross-Environment Validation:**
|
|
||||||
* Se alterar o `Modal.jsx`, deve-se validar visualmente (ou via pesquisa de código) se o modal de "Demissão" (RH) e o modal de "Checklist" (Prafrot) continuam funcionais.
|
|
||||||
|
|
||||||
## 🚀 Anti-Colisão de Tokens (JWT)
|
|
||||||
|
|
||||||
* **Identidade Própria:** Certifique-se de que o componente não assume a existência de um `token` global. Ele deve receber o dado necessário ou usar o hook reativo `useApiContract` que já injeta o token correto por contexto.
|
|
||||||
|
|
||||||
## ⚠️ Regra de Ouro
|
|
||||||
O componente `shared` deve ser agnóstico ao negócio. O negócio deve configurar o componente via `props`.
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
/**
|
|
||||||
* 🧪 Setup de Testes - Configuração Global
|
|
||||||
*
|
|
||||||
* Configuração inicial para os testes do sistema de agentes
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { expect, afterEach, vi } from 'vitest';
|
|
||||||
import { cleanup } from '@testing-library/react';
|
|
||||||
import '@testing-library/jest-dom';
|
|
||||||
|
|
||||||
// Limpar após cada teste
|
|
||||||
afterEach(() => {
|
|
||||||
cleanup();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Mock de módulos comuns
|
|
||||||
vi.mock('fs/promises', () => ({
|
|
||||||
default: {
|
|
||||||
readFile: vi.fn(),
|
|
||||||
writeFile: vi.fn(),
|
|
||||||
access: vi.fn()
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Configuração global
|
|
||||||
global.expect = expect;
|
|
||||||
|
|
@ -1,173 +0,0 @@
|
||||||
---
|
|
||||||
description: Workflow completo para criar nova feature
|
|
||||||
---
|
|
||||||
|
|
||||||
# Workflow: Criar Nova Feature
|
|
||||||
|
|
||||||
Processo completo para desenvolver uma nova funcionalidade seguindo padrões do projeto.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Pré-requisitos
|
|
||||||
|
|
||||||
1. Identificar o **ambiente** (rh, financeiro-v2, prafrota, etc)
|
|
||||||
2. Definir nome da feature
|
|
||||||
3. Listar componentes/hooks/services necessários
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Etapas
|
|
||||||
|
|
||||||
### 1. Análise de Reutilização
|
|
||||||
|
|
||||||
**Antes de criar qualquer código**, verificar o que já existe:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Buscar componentes similares
|
|
||||||
node .agent/scripts/check-reuse.js [termo-relacionado]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Pergunte**:
|
|
||||||
- Posso reutilizar componentes existentes?
|
|
||||||
- Posso estender hooks atuais?
|
|
||||||
- Services similares já existem?
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2. Criar Service (se necessário)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
node .agent/scripts/create-service.js [nomeService] [ambiente]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Ajustar**:
|
|
||||||
1. Endpoints da API
|
|
||||||
2. Mapeamento de dados (adapters)
|
|
||||||
3. Tratamento de erros
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 3. Criar Hook (se necessário)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
node .agent/scripts/create-hook.js use[NomeHook] [ambiente]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Implementar**:
|
|
||||||
1. Lógica de negócio
|
|
||||||
2. Integração com service
|
|
||||||
3. Estados (loading, error, data)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 4. Criar Componentes
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Para cada componente necessário
|
|
||||||
node .agent/scripts/create-component.js [NomeComponente] [ambiente]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Ordem recomendada**:
|
|
||||||
1. Componentes básicos (Cards, Forms)
|
|
||||||
2. Componentes compostos (que usam os básicos)
|
|
||||||
3. View principal
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 5. Testar no Playground
|
|
||||||
|
|
||||||
**OBRIGATÓRIO antes de usar em produção**:
|
|
||||||
|
|
||||||
1. Cadastrar componentes em `PlaygroundView.jsx`
|
|
||||||
2. Adicionar variantes Dev com controles
|
|
||||||
3. Testar estados: loading, error, success
|
|
||||||
4. Validar responsividade
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 6. Criar View
|
|
||||||
|
|
||||||
**Estrutura**:
|
|
||||||
```
|
|
||||||
src/features/[ambiente]/views/
|
|
||||||
└── [FeatureName]View.jsx
|
|
||||||
```
|
|
||||||
|
|
||||||
**Implementar**:
|
|
||||||
1. Importar componentes do Playground
|
|
||||||
2. Usar hooks criados
|
|
||||||
3. Layout e estrutura
|
|
||||||
4. Validar isolamento (não importar de outros ambientes)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 7. Validação
|
|
||||||
|
|
||||||
// turbo-all
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build sem erros
|
|
||||||
npm run dev
|
|
||||||
|
|
||||||
# Verificar console (sem warnings)
|
|
||||||
# Abrir no navegador: http://localhost:5173
|
|
||||||
|
|
||||||
# Testar fluxos:
|
|
||||||
# - Happy path (uso normal)
|
|
||||||
# - Error path (API offline, campos vazios)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 8. Documentação
|
|
||||||
|
|
||||||
Atualizar documentação relevante:
|
|
||||||
- README do ambiente (se houver)
|
|
||||||
- Comentários JSDoc nos arquivos
|
|
||||||
- Adicionar exemplos no Playground
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Checklist Final
|
|
||||||
|
|
||||||
- [ ] Reutilização verificada com `check-reuse.js`
|
|
||||||
- [ ] Service criado e testado
|
|
||||||
- [ ] Hook implementado com error handling
|
|
||||||
- [ ] Componentes < 150 linhas cada
|
|
||||||
- [ ] Todos os componentes testados no Playground
|
|
||||||
- [ ] View usando apenas componentes validados
|
|
||||||
- [ ] Build roda sem erros
|
|
||||||
- [ ] Sem warnings no console
|
|
||||||
- [ ] Responsividade validada
|
|
||||||
- [ ] Documentação atualizada
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Exemplo Completo: Feature "Folha de Pagamento"
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. Verificar reutilização
|
|
||||||
node .agent/scripts/check-reuse.js payroll
|
|
||||||
|
|
||||||
# 2. Criar service
|
|
||||||
node .agent/scripts/create-service.js payrollService rh
|
|
||||||
|
|
||||||
# 3. Criar hook
|
|
||||||
node .agent/scripts/create-hook.js usePayroll rh
|
|
||||||
|
|
||||||
# 4. Criar componentes
|
|
||||||
node .agent/scripts/create-component.js PayrollCard rh
|
|
||||||
node .agent/scripts/create-component.js PayrollForm rh
|
|
||||||
node .agent/scripts/create-component.js PayrollTable rh
|
|
||||||
|
|
||||||
# 5. Cadastrar no Playground e testar
|
|
||||||
|
|
||||||
# 6. Criar view: src/features/rh/views/PayrollView.jsx
|
|
||||||
|
|
||||||
# 7. Validar
|
|
||||||
npm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**IMPORTANTE**: Nunca pular a etapa de Playground! Todo componente deve ser validado antes de usar em produção.
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
---
|
|
||||||
description: Validação de Layout e Responsividade (PlatformSistemas)
|
|
||||||
---
|
|
||||||
|
|
||||||
# 📱 Workflow: Layout Check
|
|
||||||
|
|
||||||
Siga estes passos após qualquer alteração no visual ou na estrutura do frontend para garantir que a Fundação Visual e a Coordenação de Layout (Power-Up Pralog) permaneçam intactos.
|
|
||||||
|
|
||||||
## Passos de Validação
|
|
||||||
|
|
||||||
1. **Verificação de Variáveis:**
|
|
||||||
- Garante que não foram introduzidos `px` fixos onde deveria haver `clamp()`.
|
|
||||||
- Verifica se a sidebar continua usando `--sidebar-width`.
|
|
||||||
|
|
||||||
2. **Teste de Responsividade (Browser Tool):**
|
|
||||||
- Redimensionar para Mobile (375px).
|
|
||||||
- Redimensionar para Tablet (768px).
|
|
||||||
- Redimensionar para Desktop Full (1920px).
|
|
||||||
- Verificar se há scroll horizontal (deve ser zero).
|
|
||||||
|
|
||||||
3. **Verificação de Fontes:**
|
|
||||||
- Abrir o Inspect → Network → Fonts.
|
|
||||||
- Verificar se a fonte Inter é carregada via preconnect com prioridade alta.
|
|
||||||
|
|
||||||
4. **Coordenação Sidebar/Main:**
|
|
||||||
- Alternar o estado da sidebar (Expanded/Collapsed).
|
|
||||||
- O conteúdo principal deve se ajustar perfeitamente sem "pular" ou "vazar".
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"setup-worktree": [
|
|
||||||
"npm install"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
52
.cursorrules
|
|
@ -1,52 +0,0 @@
|
||||||
---
|
|
||||||
description:
|
|
||||||
alwaysApply: true
|
|
||||||
---
|
|
||||||
|
|
||||||
# Regras do Projeto – Integra Finance (PlatformSistemas)
|
|
||||||
|
|
||||||
## Uso obrigatório do `.agent/`
|
|
||||||
|
|
||||||
- **Sempre** consulte estes arquivos ao trabalhar no projeto:
|
|
||||||
- `.agent/instructions/CORE_INSTRUCTIONS.md` – instruções base, etapas de desenvolvimento, uso de agentes
|
|
||||||
- `.agent/project/PROJECT_CONTEXT.md` – contexto do projeto, URLs, ambientes, documentação por feature
|
|
||||||
|
|
||||||
- Siga as regras de **ambiente obrigatório** e **isolamento** definidas no `CORE_INSTRUCTIONS` (perguntar o ambiente antes de alterar, nunca cruzar módulos).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Workflow dos agentes
|
|
||||||
|
|
||||||
### 1. Documentação
|
|
||||||
|
|
||||||
- **Ao finalizar uma tarefa** que alterou código (views, componentes, features, services, etc.):
|
|
||||||
- Execute `npm run agent:docs:update`.
|
|
||||||
- Confirme sucesso ou reporte erros ao usuário.
|
|
||||||
- O Documentation Agent atualiza a tabela de ambientes em `PROJECT_CONTEXT.md`. Manter isso em dia é obrigatório.
|
|
||||||
|
|
||||||
### 2. Teste em ambiente de desenvolvimento
|
|
||||||
|
|
||||||
- **Antes** de rodar testes no navegador ou validar fluxos (formulários, API, UI):
|
|
||||||
- **Pergunte** ao usuário: *"As implementações já estão em ambiente de desenvolvimento? Se sim, informe a URL e o acesso (credenciais) para testes."*
|
|
||||||
- Só prossiga com testes reais após confirmação e dados de acesso.
|
|
||||||
- Use os agentes descritos em `.agent/agents/*.md` (ex.: `BrowserValidationAgent`, `UIAdaptationAgent`) quando fizer sentido para a tarefa.
|
|
||||||
|
|
||||||
### 3. Commits (Git)
|
|
||||||
|
|
||||||
- **Quando houver alterações não commitadas** (ex.: usuário relata que "corrigiu algo", "alterou o workspace", ou você fez mudanças no código):
|
|
||||||
- Sugira rodar `npm run agent:git:commit:dry` para ver o que seria commitado.
|
|
||||||
- Se o usuário concordar, sugira ou execute `npm run agent:git:commit`.
|
|
||||||
- Em caso de falha, reporte `userMessage` e `retryPrompt` retornados pelo script.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Resumo
|
|
||||||
|
|
||||||
| Quando | Ação |
|
|
||||||
|--------|------|
|
|
||||||
| Início / contexto do projeto | Ler `CORE_INSTRUCTIONS.md` e `PROJECT_CONTEXT.md` |
|
|
||||||
| Fim de tarefa com alteração de código | Rodar `npm run agent:docs:update` e confirmar |
|
|
||||||
| Antes de testes em dev/navegador | Perguntar se o app está em dev e pedir URL/acesso |
|
|
||||||
| Alterações não commitadas | Sugerir `agent:git:commit:dry` e, se ok, `agent:git:commit` |
|
|
||||||
|
|
||||||
Essas regras garantem que o `.agent/` seja usado de fato: documentação atualizada, testes em dev condicionados à sua confirmação e commits propostos quando há mudanças.
|
|
||||||
6
.env
|
|
@ -1,6 +0,0 @@
|
||||||
# Modo de desenvolvimento (true = usa mocks locais, false = usa API real)
|
|
||||||
VITE_USE_MOCK=false
|
|
||||||
|
|
||||||
# Base URL da API (sem trailing slash)
|
|
||||||
# Exemplo: https://dev.workspace.itguys.com.br/api
|
|
||||||
VITE_API_URL=https://dev.workspace.itguys.com.br/api
|
|
||||||
13
.env.example
|
|
@ -1,13 +0,0 @@
|
||||||
# Integra Finance - Configurações de Ambiente
|
|
||||||
|
|
||||||
# URL Base para a API do Backend (sem trailing slash)
|
|
||||||
# Exemplo Desenvolvimento: https://dev.workspace.itguys.com.br/api
|
|
||||||
# Exemplo Produção: https://workspace.itguys.com.br/api
|
|
||||||
VITE_API_URL=https://dev.workspace.itguys.com.br/api
|
|
||||||
|
|
||||||
# Alternar entre Mocks (true) e API Real (false)
|
|
||||||
# Para conectar o back em segundos, mude para: false
|
|
||||||
VITE_USE_MOCK=true
|
|
||||||
|
|
||||||
# Outras configurações (Ex: Google Maps API se necessário no futuro)
|
|
||||||
# VITE_GOOGLE_MAPS_KEY=seu_token_aqui
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
# Production Environment
|
|
||||||
# Em produção, devemos usar a API real, não mocks.
|
|
||||||
VITE_USE_MOCK=false
|
|
||||||
|
|
||||||
# Defina a URL da API de produção aqui.
|
|
||||||
# Se for a mesma de desenvolvimento, mantenha. Se for diferente (ex: api.pralog.com.br), altere aqui.
|
|
||||||
VITE_API_URL=https://dev.workspace.itguys.com.br/api
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
||||||
# Logs
|
|
||||||
logs
|
|
||||||
*.log
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
pnpm-debug.log*
|
|
||||||
lerna-debug.log*
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
node_modules
|
|
||||||
|
|
||||||
# Build outputs
|
|
||||||
dist
|
|
||||||
dist-ssr
|
|
||||||
build
|
|
||||||
*.local
|
|
||||||
|
|
||||||
# Environment variables
|
|
||||||
.env
|
|
||||||
.env.local
|
|
||||||
.env.development.local
|
|
||||||
.env.test.local
|
|
||||||
.env.production.local
|
|
||||||
|
|
||||||
# Editor directories and files
|
|
||||||
.vscode/*
|
|
||||||
!.vscode/extensions.json
|
|
||||||
.idea
|
|
||||||
.DS_Store
|
|
||||||
*.suo
|
|
||||||
*.ntvs*
|
|
||||||
*.njsproj
|
|
||||||
*.sln
|
|
||||||
*.sw?
|
|
||||||
*.swp
|
|
||||||
*~
|
|
||||||
|
|
||||||
# OS files
|
|
||||||
Thumbs.db
|
|
||||||
Desktop.ini
|
|
||||||
|
|
||||||
# Cache and temporary files
|
|
||||||
.cache
|
|
||||||
.tmp
|
|
||||||
.temp
|
|
||||||
*.tmp
|
|
||||||
*.temp
|
|
||||||
|
|
||||||
# Test coverage
|
|
||||||
coverage
|
|
||||||
*.lcov
|
|
||||||
.nyc_output
|
|
||||||
|
|
||||||
# Legacy and Platform Specific
|
|
||||||
Modulos Angular/
|
|
||||||
Sistema_zentulo_analise/
|
|
||||||
prafrota_fe-main/
|
|
||||||
179
GIT-AUTO-SYNC.md
|
|
@ -1,179 +0,0 @@
|
||||||
# Git Auto-Sync - Documentação
|
|
||||||
|
|
||||||
## 📋 Visão Geral
|
|
||||||
|
|
||||||
O **Git Auto-Sync** é um sistema de automação que monitora alterações no projeto PlatformSistemas e realiza commits e push automáticos para o repositório Git remoto.
|
|
||||||
|
|
||||||
## 🎯 Características
|
|
||||||
|
|
||||||
- ✅ **Monitoramento em tempo real** de alterações nos arquivos
|
|
||||||
- ✅ **Debounce inteligente** (aguarda 10 segundos após a última alteração)
|
|
||||||
- ✅ **Build automático** antes de cada commit
|
|
||||||
- ✅ **Filtragem inteligente** de arquivos (ignora node_modules, .git, dist, etc.)
|
|
||||||
- ✅ **Mensagens de commit descritivas** com timestamp e contagem de arquivos
|
|
||||||
- ✅ **Interface visual** com cores e feedback claro
|
|
||||||
|
|
||||||
## 🚀 Como Usar
|
|
||||||
|
|
||||||
### Método 1: Via NPM (Recomendado)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Com build automático (padrão)
|
|
||||||
npm run git:sync
|
|
||||||
|
|
||||||
# Sem build automático (mais rápido para desenvolvimento)
|
|
||||||
npm run git:sync:nobuild
|
|
||||||
```
|
|
||||||
|
|
||||||
### Método 2: Via PowerShell Direto
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
# Com build automático
|
|
||||||
.\git-auto-sync.ps1
|
|
||||||
|
|
||||||
# Sem build automático
|
|
||||||
$env:BUILD_ENABLED='false'; .\git-auto-sync.ps1
|
|
||||||
```
|
|
||||||
|
|
||||||
## ⚙️ Configurações
|
|
||||||
|
|
||||||
Você pode ajustar as configurações editando o arquivo `git-auto-sync.ps1`:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
# Configurações (linhas 10-12)
|
|
||||||
$BRANCH_NAME = "frontend_React" # Branch de destino
|
|
||||||
$DEBOUNCE_SECONDS = 10 # Tempo de espera após última alteração
|
|
||||||
$BUILD_ENABLED = $true # Executar build antes do commit
|
|
||||||
```
|
|
||||||
|
|
||||||
### Parâmetros Configuráveis
|
|
||||||
|
|
||||||
| Parâmetro | Descrição | Valor Padrão |
|
|
||||||
|-----------|-----------|--------------|
|
|
||||||
| `BRANCH_NAME` | Branch do Git para push | `frontend_React` |
|
|
||||||
| `DEBOUNCE_SECONDS` | Segundos de espera após última alteração | `10` |
|
|
||||||
| `BUILD_ENABLED` | Executar build de produção antes do commit | `true` |
|
|
||||||
|
|
||||||
## 📁 Arquivos Ignorados
|
|
||||||
|
|
||||||
O script ignora automaticamente as seguintes pastas/arquivos:
|
|
||||||
|
|
||||||
- `node_modules/`
|
|
||||||
- `.git/`
|
|
||||||
- `dist/`
|
|
||||||
- `.env`
|
|
||||||
- `*.log`
|
|
||||||
- `package-lock.json`
|
|
||||||
- `.tmp/`
|
|
||||||
- `.cache/`
|
|
||||||
- `.vscode/`
|
|
||||||
- `.idea/`
|
|
||||||
- `*.swp`
|
|
||||||
- `*~`
|
|
||||||
|
|
||||||
## 🔄 Fluxo de Trabalho
|
|
||||||
|
|
||||||
1. **Detecção de Alteração**: O script detecta quando um arquivo é modificado, criado, deletado ou renomeado
|
|
||||||
2. **Debounce**: Aguarda 10 segundos para garantir que não há mais alterações pendentes
|
|
||||||
3. **Verificação**: Confirma que há alterações reais para commitar
|
|
||||||
4. **Build** (opcional): Executa `npm run build` para gerar a versão de produção
|
|
||||||
5. **Stage**: Adiciona todos os arquivos alterados (`git add .`)
|
|
||||||
6. **Commit**: Cria um commit com mensagem descritiva
|
|
||||||
7. **Push**: Envia as alterações para o repositório remoto na branch `frontend_React`
|
|
||||||
|
|
||||||
## 📝 Formato das Mensagens de Commit
|
|
||||||
|
|
||||||
```
|
|
||||||
Auto-deploy: 2026-01-13 09:20:45 | 3 arquivo(s) alterado(s) [Build included]
|
|
||||||
```
|
|
||||||
|
|
||||||
- **Timestamp**: Data e hora do commit
|
|
||||||
- **Contagem**: Número de arquivos alterados
|
|
||||||
- **Build**: Indica se o build foi incluído
|
|
||||||
|
|
||||||
## 🛑 Como Parar
|
|
||||||
|
|
||||||
Para interromper o monitoramento, pressione `Ctrl+C` no terminal onde o script está rodando.
|
|
||||||
|
|
||||||
## 🔧 Troubleshooting
|
|
||||||
|
|
||||||
### Erro: "Execution Policy"
|
|
||||||
|
|
||||||
Se você receber um erro sobre política de execução, execute:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
|
|
||||||
```
|
|
||||||
|
|
||||||
### Erro no Build
|
|
||||||
|
|
||||||
Se o build falhar, o commit será abortado automaticamente. Verifique os erros no console e corrija-os antes de tentar novamente.
|
|
||||||
|
|
||||||
### Push Rejeitado
|
|
||||||
|
|
||||||
Se o push for rejeitado (ex: branch desatualizada), você precisará:
|
|
||||||
|
|
||||||
1. Parar o script (`Ctrl+C`)
|
|
||||||
2. Fazer `git pull origin frontend_React`
|
|
||||||
3. Resolver conflitos (se houver)
|
|
||||||
4. Reiniciar o script
|
|
||||||
|
|
||||||
## 🎨 Interface Visual
|
|
||||||
|
|
||||||
O script exibe um banner informativo ao iniciar:
|
|
||||||
|
|
||||||
```
|
|
||||||
╔════════════════════════════════════════════════════════════╗
|
|
||||||
║ Git Auto-Sync - PlatformSistemas ║
|
|
||||||
╠════════════════════════════════════════════════════════════╣
|
|
||||||
║ Branch: frontend_React ║
|
|
||||||
║ Remote: https://git.itguys.com.br/itguys_dev/Workspace ║
|
|
||||||
║ Debounce: 10 segundos ║
|
|
||||||
║ Build automático: Habilitado ║
|
|
||||||
╠════════════════════════════════════════════════════════════╣
|
|
||||||
║ Status: Monitorando alterações... ║
|
|
||||||
║ Pressione Ctrl+C para parar ║
|
|
||||||
╚════════════════════════════════════════════════════════════╝
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📊 Logs e Feedback
|
|
||||||
|
|
||||||
O script fornece feedback visual em tempo real:
|
|
||||||
|
|
||||||
- 🔵 **Azul escuro**: Alterações detectadas
|
|
||||||
- 🟡 **Amarelo**: Processos em andamento
|
|
||||||
- 🟢 **Verde**: Operações bem-sucedidas
|
|
||||||
- 🔴 **Vermelho**: Erros
|
|
||||||
|
|
||||||
## 🔐 Segurança
|
|
||||||
|
|
||||||
- O script **não** commita arquivos sensíveis (`.env`, etc.)
|
|
||||||
- Arquivos temporários e de cache são automaticamente ignorados
|
|
||||||
- O `.gitignore` do projeto é respeitado
|
|
||||||
|
|
||||||
## 📌 Repositório
|
|
||||||
|
|
||||||
- **Remote**: https://git.itguys.com.br/itguys_dev/Workspace
|
|
||||||
- **Branch**: frontend_React
|
|
||||||
|
|
||||||
## 💡 Dicas
|
|
||||||
|
|
||||||
1. **Desenvolvimento rápido**: Use `npm run git:sync:nobuild` para commits mais rápidos durante desenvolvimento
|
|
||||||
2. **Produção**: Use `npm run git:sync` para garantir que o build está sempre atualizado
|
|
||||||
3. **Múltiplas alterações**: O debounce agrupa alterações feitas em sequência em um único commit
|
|
||||||
4. **Monitoramento**: Mantenha o terminal visível para acompanhar o status das sincronizações
|
|
||||||
|
|
||||||
## 🆘 Suporte
|
|
||||||
|
|
||||||
Em caso de problemas:
|
|
||||||
|
|
||||||
1. Verifique se o Git está configurado corretamente
|
|
||||||
2. Confirme que você tem permissões de push na branch `frontend_React`
|
|
||||||
3. Verifique se não há conflitos pendentes no repositório
|
|
||||||
4. Revise os logs no console para identificar erros específicos
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Última atualização**: 2026-01-13 (Teste Auto-Sync 12:15)
|
|
||||||
**Versão**: 2.1
|
|
||||||
**Autor**: Antigravity AI
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
||||||
# 🚀 Guia Rápido - Git Auto-Sync
|
|
||||||
|
|
||||||
## Como Iniciar
|
|
||||||
|
|
||||||
### Opção 1: Via NPM (Recomendado)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Com build automático
|
|
||||||
npm run git:sync
|
|
||||||
|
|
||||||
# Sem build automático (mais rápido)
|
|
||||||
npm run git:sync:nobuild
|
|
||||||
```
|
|
||||||
|
|
||||||
### Opção 2: Via PowerShell
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
# Com build automático
|
|
||||||
.\git-auto-sync.ps1
|
|
||||||
|
|
||||||
# Sem build automático
|
|
||||||
$env:BUILD_ENABLED='false'; .\git-auto-sync.ps1
|
|
||||||
```
|
|
||||||
|
|
||||||
## O que acontece?
|
|
||||||
|
|
||||||
1. ✅ O script monitora todas as alterações nos arquivos
|
|
||||||
2. ✅ Aguarda 10 segundos após a última alteração (debounce)
|
|
||||||
3. ✅ Executa `npm run build` (se habilitado)
|
|
||||||
4. ✅ Faz `git add .`
|
|
||||||
5. ✅ Cria commit com timestamp e contagem de arquivos
|
|
||||||
6. ✅ Faz `git push origin frontend_React`
|
|
||||||
|
|
||||||
## Exemplo de Uso
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. Inicie o monitoramento
|
|
||||||
npm run git:sync
|
|
||||||
|
|
||||||
# 2. Faça suas alterações normalmente no código
|
|
||||||
# 3. Salve os arquivos
|
|
||||||
# 4. Aguarde 10 segundos
|
|
||||||
# 5. O script automaticamente fará commit e push!
|
|
||||||
```
|
|
||||||
|
|
||||||
## Para Parar
|
|
||||||
|
|
||||||
Pressione `Ctrl+C` no terminal onde o script está rodando.
|
|
||||||
|
|
||||||
## Dicas
|
|
||||||
|
|
||||||
- 💡 Use `git:sync:nobuild` durante desenvolvimento para commits mais rápidos
|
|
||||||
- 💡 Use `git:sync` antes de finalizar o dia para garantir build atualizado
|
|
||||||
- 💡 O script ignora automaticamente `node_modules`, `.git`, `dist`, etc.
|
|
||||||
- 💡 Múltiplas alterações em 10 segundos são agrupadas em um único commit
|
|
||||||
|
|
||||||
## Configurações
|
|
||||||
|
|
||||||
Edite `git-auto-sync.ps1` para ajustar:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
$BRANCH_NAME = "frontend_React" # Branch de destino
|
|
||||||
$DEBOUNCE_SECONDS = 10 # Tempo de espera
|
|
||||||
$BUILD_ENABLED = $true # Build automático
|
|
||||||
```
|
|
||||||
|
|
||||||
## Documentação Completa
|
|
||||||
|
|
||||||
Veja [GIT-AUTO-SYNC.md](./GIT-AUTO-SYNC.md) para mais detalhes.
|
|
||||||
306
README.md
|
|
@ -1,306 +0,0 @@
|
||||||
# PlatformSistemas
|
|
||||||
|
|
||||||
<!-- Test for auto-sync -->
|
|
||||||
Sistema de gestão integrada desenvolvido em React + TypeScript + Vite.
|
|
||||||
|
|
||||||
## 🚀 Repositório
|
|
||||||
|
|
||||||
- **Remote**: https://git.itguys.com.br/itguys_dev/Workspace
|
|
||||||
- **Branch**: `frontend_React`
|
|
||||||
|
|
||||||
## 📋 Índice
|
|
||||||
|
|
||||||
- [Início Rápido](#início-rápido)
|
|
||||||
- [Scripts Disponíveis](#scripts-disponíveis)
|
|
||||||
- [Git Auto-Sync](#git-auto-sync)
|
|
||||||
- [Estrutura do Projeto](#estrutura-do-projeto)
|
|
||||||
- [Tecnologias](#tecnologias)
|
|
||||||
- [Desenvolvimento](#desenvolvimento)
|
|
||||||
|
|
||||||
## 🎯 Início Rápido
|
|
||||||
|
|
||||||
### Pré-requisitos
|
|
||||||
|
|
||||||
- Node.js (v18 ou superior)
|
|
||||||
- npm ou yarn
|
|
||||||
- Git
|
|
||||||
|
|
||||||
### Instalação
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Clone o repositório
|
|
||||||
git clone https://git.itguys.com.br/itguys_dev/Workspace.git
|
|
||||||
cd PlatformSistemas
|
|
||||||
|
|
||||||
# Instale as dependências
|
|
||||||
npm install
|
|
||||||
|
|
||||||
# Configure as variáveis de ambiente
|
|
||||||
cp .env.example .env
|
|
||||||
# Edite o arquivo .env com suas configurações
|
|
||||||
|
|
||||||
# Inicie o servidor de desenvolvimento
|
|
||||||
npm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📜 Scripts Disponíveis
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Desenvolvimento
|
|
||||||
npm run dev # Inicia o servidor de desenvolvimento
|
|
||||||
|
|
||||||
# Build
|
|
||||||
npm run build # Gera build de produção
|
|
||||||
npm run preview # Preview do build de produção
|
|
||||||
|
|
||||||
# Qualidade de Código
|
|
||||||
npm run lint # Executa ESLint
|
|
||||||
|
|
||||||
# Git Auto-Sync
|
|
||||||
npm run git:sync # Inicia monitoramento Git com build automático
|
|
||||||
npm run git:sync:nobuild # Inicia monitoramento Git sem build automático
|
|
||||||
|
|
||||||
# Agentes de Automação
|
|
||||||
npm run agent:git:commit # Commit automático por dia
|
|
||||||
npm run agent:git:commit:dry # Dry-run do commit automático
|
|
||||||
npm run agent:docs:update # Atualização automática de documentação
|
|
||||||
npm run agent:check # Verificação do orchestrator
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔄 Git Auto-Sync
|
|
||||||
|
|
||||||
O **Git Auto-Sync** é um sistema de automação que monitora alterações no projeto e realiza commits/push automáticos.
|
|
||||||
|
|
||||||
### Como Usar
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Com build automático (recomendado para produção)
|
|
||||||
npm run git:sync
|
|
||||||
|
|
||||||
# Sem build automático (mais rápido para desenvolvimento)
|
|
||||||
npm run git:sync:nobuild
|
|
||||||
```
|
|
||||||
|
|
||||||
### Características
|
|
||||||
|
|
||||||
- ✅ Monitoramento em tempo real de alterações
|
|
||||||
- ✅ Debounce de 10 segundos (agrupa alterações)
|
|
||||||
- ✅ Build automático antes de cada commit
|
|
||||||
- ✅ Filtragem inteligente de arquivos
|
|
||||||
- ✅ Mensagens de commit descritivas
|
|
||||||
|
|
||||||
### Documentação Completa
|
|
||||||
|
|
||||||
Para mais detalhes, consulte [GIT-AUTO-SYNC.md](./GIT-AUTO-SYNC.md)
|
|
||||||
|
|
||||||
## 📁 Estrutura do Projeto
|
|
||||||
|
|
||||||
```
|
|
||||||
PlatformSistemas/
|
|
||||||
├── src/
|
|
||||||
│ ├── components/ # Componentes reutilizáveis
|
|
||||||
│ │ ├── shared/ # Componentes compartilhados
|
|
||||||
│ │ └── ui/ # Componentes Shadcn UI
|
|
||||||
│ ├── features/ # Features do sistema (Domain-Driven)
|
|
||||||
│ │ ├── auth/ # Autenticação
|
|
||||||
│ │ ├── financeiro-cnab/ # CNAB - Remessas e Pagamentos
|
|
||||||
│ │ ├── financeiro-v2/ # Financeiro V2 - Contas a Receber/Pagar
|
|
||||||
│ │ ├── fleet-v2/ # Gestão de Frota V2
|
|
||||||
│ │ ├── gr/ # Gestão de Registros (GR)
|
|
||||||
│ │ ├── rh/ # Recursos Humanos
|
|
||||||
│ │ ├── workspace/ # Workspace Financeiro
|
|
||||||
│ │ ├── autolab/ # AutoLab - Gestão de Oficina
|
|
||||||
│ │ ├── dev-tools/ # Ferramentas de Desenvolvimento
|
|
||||||
│ │ └── portal/ # Portal Principal
|
|
||||||
│ ├── services/ # Serviços e APIs
|
|
||||||
│ ├── hooks/ # Custom hooks globais
|
|
||||||
│ ├── utils/ # Utilitários
|
|
||||||
│ └── index.css # Estilos globais
|
|
||||||
├── docs/ # Documentação do projeto
|
|
||||||
├── .agent/ # Agentes de automação
|
|
||||||
├── public/ # Arquivos públicos
|
|
||||||
├── .env # Variáveis de ambiente
|
|
||||||
├── git-auto-sync.ps1 # Script de automação Git
|
|
||||||
└── package.json # Dependências e scripts
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🎯 Módulos e Ambientes
|
|
||||||
|
|
||||||
### 👥 RH (Recursos Humanos)
|
|
||||||
Módulo desenvolvido para atender integralmente as demandas dos setores de RH e Departamento Pessoal.
|
|
||||||
- **Funcionalidades**: Gestão de funcionários, controle de ponto eletrônico, processamento de benefícios e cálculos trabalhistas.
|
|
||||||
- **Destaque**: Dashboards de contratos de experiência e acompanhamento de admissões.
|
|
||||||
|
|
||||||
### 💰 CNAB (Financeiro Remessas)
|
|
||||||
Módulo financeiro especializado na interface bancária e automação de pagamentos.
|
|
||||||
- **Funcionalidades**: Geração e gerenciamento de remessas CNAB, cadastro de favorecidos, processamento de arquivos de retorno e validação de pagamentos TED/PIX.
|
|
||||||
|
|
||||||
### 🚛 Prafrota (Gestão de Frota)
|
|
||||||
Sistema robusto para o controle operacional de frotas de veículos.
|
|
||||||
- **Funcionalidades**: Cadastro técnico de veículos, monitoramento em tempo real, gestão de manutenções preventivas/corretivas e controle de abastecimentos.
|
|
||||||
|
|
||||||
### 🏦 Financeiro_V2 + Workspace
|
|
||||||
Solução avançada para gestão financeira estratégica e operacional.
|
|
||||||
- **Funcionalidades**: Gestão de contas a pagar e receber, fluxo de caixa projetado vs. realizado, conciliação bancária automatizada e dashboards de indicadores financeiros (KPIs).
|
|
||||||
|
|
||||||
### 🍊 OestePan (Customização Prafrota)
|
|
||||||
Segmento especializado do Prafrota customizado especificamente para as necessidades logísticas da Oeste Pan.
|
|
||||||
- **Funcionalidades**: Além das funções base do Prafrota, inclui integração com Moki para checklists, gestão específica de sinistros e visualização otimizada para a operação do cliente.
|
|
||||||
|
|
||||||
### 🔬 AutoLab (Gestão de Oficinas)
|
|
||||||
Módulo em fase de finalização focado na operação técnica de oficinas.
|
|
||||||
- **Funcionalidades**: Controle de estoque de peças, gestão de ordens de serviço (vendas), cadastro de clientes e configurações técnicas de atendimento.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🛣️ Estrutura de Rotas e Variáveis
|
|
||||||
|
|
||||||
Cada ambiente consome uma API RESTful estruturada para operações de CRUD (Apresentação, Edição e Exclusão).
|
|
||||||
|
|
||||||
### Padrão de Endpoints
|
|
||||||
As rotas seguem a nomenclatura do recurso base (ex: `/prafrot`, `/workspace`):
|
|
||||||
|
|
||||||
- **Apresentação (GET)**:
|
|
||||||
- `/recurso/apresentar`: Lista principal de dados.
|
|
||||||
- `/recurso/listagem`: Alternativa para listagens simplificadas.
|
|
||||||
- `/recurso/:id`: Detalhamento de um registro específico.
|
|
||||||
- **Edição/Atualização (PUT/PATCH)**:
|
|
||||||
- `/recurso/edit`: Atualização de campos específicos.
|
|
||||||
- `/recurso/:id`: Atualização completa do registro.
|
|
||||||
- `/recurso/edit/status_global`: Utilizado em Kanbans para movimentação de cards.
|
|
||||||
- **Exclusão (DELETE)**:
|
|
||||||
- `/recurso/delete/:id`: Remoção lógica ou física do registro.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎨 Design System & Playground
|
|
||||||
|
|
||||||
O projeto utiliza um laboratório de componentes (**Playground**) para garantir consistência visual em todos os ambientes.
|
|
||||||
|
|
||||||
### Componentes em Uso (Playground)
|
|
||||||
Estes componentes são extraídos do Design System e aplicados nos módulos:
|
|
||||||
|
|
||||||
| Componente | Função | Ambientes Principais |
|
|
||||||
| :--- | :--- | :--- |
|
|
||||||
| **ExcelTable** | Tabela de alta performance com filtros | RH, Prafrota, Financeiro |
|
|
||||||
| **ItemDetailPanel** | Painel lateral para visualização de detalhes | Prafrota, OestePan |
|
|
||||||
| **DashboardKPICard** | Cards de indicadores com micro-gráficos | Financeiro_V2, Workspace |
|
|
||||||
| **StatsGrid** | Grid de estatísticas rápidas | RH, Prafrota |
|
|
||||||
| **KanbanBoard** | Gestão visual de fluxos e status | GR, RH |
|
|
||||||
| **AutoFillInput** | Inputs inteligentes com busca em tempo real | Workspace, Financeiro |
|
|
||||||
| **StatusBadge** | Badges coloridos de status dinâmico | Todos |
|
|
||||||
|
|
||||||
### Componentes Disponíveis (Candidatos)
|
|
||||||
Componentes presentes no laboratório mas com uso restrito ou em homologação:
|
|
||||||
- `ThemeTuner`: Ferramenta de ajuste de temas em runtime.
|
|
||||||
- `FinesCard`: Card especializado para visualização de multas.
|
|
||||||
- `SmartTable`: Versão experimental de tabelas com auto-ajuste.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🛠️ Tecnologias
|
|
||||||
|
|
||||||
### Core
|
|
||||||
- **React 19** - Biblioteca UI
|
|
||||||
- **TypeScript** - Superset JavaScript
|
|
||||||
- **Vite** - Build tool e dev server
|
|
||||||
|
|
||||||
### UI/UX
|
|
||||||
- **TailwindCSS** - Framework CSS
|
|
||||||
- **Radix UI** - Componentes acessíveis
|
|
||||||
- **Framer Motion** - Animações
|
|
||||||
- **Lucide React** - Ícones
|
|
||||||
|
|
||||||
### Estado e Formulários
|
|
||||||
- **Zustand** - Gerenciamento de estado
|
|
||||||
- **React Hook Form** - Formulários
|
|
||||||
- **Zod** - Validação de schemas
|
|
||||||
|
|
||||||
### Roteamento e Requisições
|
|
||||||
- **React Router DOM** - Roteamento
|
|
||||||
- **Axios** - Cliente HTTP
|
|
||||||
|
|
||||||
### Gráficos
|
|
||||||
- **Recharts** - Biblioteca de gráficos
|
|
||||||
|
|
||||||
## 💻 Desenvolvimento
|
|
||||||
|
|
||||||
### Variáveis de Ambiente
|
|
||||||
|
|
||||||
Copie `.env.example` para `.env` e configure:
|
|
||||||
|
|
||||||
```env
|
|
||||||
VITE_API_URL=https://dev.workspace.itguys.com.br/api
|
|
||||||
VITE_APP_NAME=PlatformSistemas
|
|
||||||
```
|
|
||||||
|
|
||||||
### Padrões de Código
|
|
||||||
|
|
||||||
- **Componentes**: Use componentes funcionais com hooks
|
|
||||||
- **Tipagem**: Sempre utilize TypeScript
|
|
||||||
- **Estilos**: Prefira TailwindCSS
|
|
||||||
- **Estado**: Use Zustand para estado global
|
|
||||||
- **Formulários**: Use React Hook Form + Zod
|
|
||||||
|
|
||||||
### ESLint
|
|
||||||
|
|
||||||
O projeto usa ESLint para garantir qualidade de código:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run lint
|
|
||||||
```
|
|
||||||
|
|
||||||
### Estrutura de Componentes
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
// Exemplo de componente
|
|
||||||
import { useState } from 'react'
|
|
||||||
import { Button } from '@/components/ui/button'
|
|
||||||
|
|
||||||
interface MyComponentProps {
|
|
||||||
title: string
|
|
||||||
onAction?: () => void
|
|
||||||
}
|
|
||||||
|
|
||||||
export function MyComponent({ title, onAction }: MyComponentProps) {
|
|
||||||
const [state, setState] = useState(false)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="p-4">
|
|
||||||
<h2 className="text-xl font-bold">{title}</h2>
|
|
||||||
<Button onClick={onAction}>Ação</Button>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔐 Segurança
|
|
||||||
|
|
||||||
- Nunca commite arquivos `.env` (já está no `.gitignore`)
|
|
||||||
- Use variáveis de ambiente para dados sensíveis
|
|
||||||
- Mantenha dependências atualizadas
|
|
||||||
|
|
||||||
## 📝 Documentação Adicional
|
|
||||||
|
|
||||||
- [Git Auto-Sync](./GIT-AUTO-SYNC.md) - Documentação completa do sistema de automação
|
|
||||||
- [API Report](./RELATORIO_API.md) - Relatório de APIs utilizadas
|
|
||||||
- [Regras de Desenvolvimento](./docs/Regras_Dev.md) - Padrões e regras do projeto
|
|
||||||
- [AI Rules - Debug Components](./docs/AI_RULES_DEBUG_COMPONENTS.md) - Regras para componentes versionados
|
|
||||||
- [Teste Formulário GR](./docs/TESTE_FORMULARIO_GR.md) - Documentação de testes do módulo GR
|
|
||||||
|
|
||||||
## 🤝 Contribuindo
|
|
||||||
|
|
||||||
1. Crie uma branch para sua feature (`git checkout -b feature/MinhaFeature`)
|
|
||||||
2. Faça commit das suas alterações (`git commit -m 'Adiciona MinhaFeature'`)
|
|
||||||
3. Push para a branch (`git push origin feature/MinhaFeature`)
|
|
||||||
4. Abra um Pull Request
|
|
||||||
|
|
||||||
Ou simplesmente use o **Git Auto-Sync** para automação completa! 🚀
|
|
||||||
|
|
||||||
## 📄 Licença
|
|
||||||
|
|
||||||
Este projeto é propriedade da ITGuys.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Desenvolvido com ❤️ pela equipe ITGuys**
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
# 🛰️ Relatório de Conexão API - Integra Finance
|
|
||||||
|
|
||||||
Este documento descreve a arquitetura de comunicação entre o Front-end (React) e o Back-end, detalhando como as conexões foram construídas e como proceder para conectar o backend em segundos.
|
|
||||||
|
|
||||||
## 🏗️ Arquitetura de Comunicação (DAL)
|
|
||||||
|
|
||||||
A camada de acesso a dados (Data Access Layer) foi projetada para ser **híbrida (API + Mock)**. Isso permite que o desenvolvimento continue mesmo sem o backend estar rodando, garantindo alta produtividade.
|
|
||||||
|
|
||||||
### 1. Instância Central (`src/services/api.js`)
|
|
||||||
Utilizamos o **Axios** para gerenciar as requisições.
|
|
||||||
- **BaseURL**: Configurável via variável de ambiente.
|
|
||||||
- **Interceptors**: Gerenciam automaticamente a inclusão de tokens de autenticação (`x-access-token`) em todas as chamadas.
|
|
||||||
|
|
||||||
### 2. Utilitário de Decisão (`src/services/serviceUtils.js`)
|
|
||||||
Criamos um helper chamado `handleRequest`. Ele é o "cérebro" que decide se a aplicação deve buscar dados do **Mock** ou da **API Real** com base em uma única flag global.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ⚡ Como conectar o Backend em Segundos
|
|
||||||
|
|
||||||
Para conectar o back, você não precisa alterar o código de nenhum componente ou tela. Basta seguir estes 3 passos:
|
|
||||||
|
|
||||||
### Passo 1: Configurar o arquivo `.env`
|
|
||||||
Crie um arquivo chamado `.env` na raiz do projeto (use o `.env.example` como base):
|
|
||||||
|
|
||||||
```env
|
|
||||||
VITE_API_URL=http://sua-url-do-backend:5000
|
|
||||||
VITE_USE_MOCK=false
|
|
||||||
```
|
|
||||||
|
|
||||||
> [!IMPORTANT]
|
|
||||||
> Ao mudar `VITE_USE_MOCK` para `false`, **todos** os serviços do sistema passarão a apontar para o seu backend instantaneamente.
|
|
||||||
|
|
||||||
### Passo 2: Padrão de Implementação de Serviço
|
|
||||||
Ao criar uma nova funcionalidade, siga este padrão em `src/services/[feature]Service.js`:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
import api from './api';
|
|
||||||
import { handleRequest, simulateLatency } from './serviceUtils';
|
|
||||||
|
|
||||||
export const meuNovoService = {
|
|
||||||
getDados: () => handleRequest({
|
|
||||||
mockFn: () => simulateLatency({ nome: "Dado Mockado" }), // O que retorna no modo Mock
|
|
||||||
apiFn: () => api.get('/api/meu-endpoint') // O que retorna no modo Real
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 Resumo Técnico para Desenvolvedores
|
|
||||||
|
|
||||||
| Recurso | Localização | Função |
|
|
||||||
| :--- | :--- | :--- |
|
|
||||||
| **Instância Axios** | `src/services/api.js` | Configuração de URL e Tokens. |
|
|
||||||
| **Logic Wrapper** | `src/services/serviceUtils.js` | Alternância Mock/Real e Simulação de Latência. |
|
|
||||||
| **Mocks** | `src/services/mocks/` | Objetos JSON com dados de teste. |
|
|
||||||
| **Serviços** | `src/services/*.js` | Definição dos endpoints e contratos. |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ Checklist de Conexão Rápida
|
|
||||||
|
|
||||||
1. [ ] Definir `VITE_API_URL` no `.env`.
|
|
||||||
2. [ ] Mudar `VITE_USE_MOCK` para `false`.
|
|
||||||
3. [ ] Reiniciar o servidor de desenvolvimento (`npm run dev`).
|
|
||||||
|
|
||||||
**Pronto!** O sistema agora consumirá dados reais do seu banco de dados.
|
|
||||||
|
|
@ -1,77 +0,0 @@
|
||||||
# 🛠️ Resoluções: Front-end & Conectividade
|
|
||||||
|
|
||||||
Este documento apresenta as soluções técnicas para os problemas de latência, fontes e responsividade identificados.
|
|
||||||
|
|
||||||
## 1. Conectividade & Performance (API/Backend)
|
|
||||||
|
|
||||||
**Problema:** Sincronização lenta e alto custo de desenvolvimento manual.
|
|
||||||
**Resolução Profissional:**
|
|
||||||
|
|
||||||
### A. Implementação do TanStack Query (React Query)
|
|
||||||
O uso de `axios` direto em serviços causa "Waterfall de Requisições". O React Query deve ser adotado para:
|
|
||||||
- **Caching Automático:** Evita buscar os mesmos dados ao alternar entre abas do sistema.
|
|
||||||
- **Optimistic Updates:** Melhora a percepção de velocidade (o UI atualiza antes da resposta do server).
|
|
||||||
|
|
||||||
### B. Service Factory via Contratos
|
|
||||||
Em vez de escrever `boletosService.js` manualmente, use os arquivos JSON (`prafrot-routes.json`) como fonte de verdade:
|
|
||||||
```javascript
|
|
||||||
// Exemplo de como usar o apiRouteManager para reduzir boilerplace
|
|
||||||
export const useFeatureData = (routeKey) => {
|
|
||||||
const route = apiRouteManager.getRoute(routeKey);
|
|
||||||
return useQuery({
|
|
||||||
queryKey: [routeKey],
|
|
||||||
queryFn: () => api.get(route.path)
|
|
||||||
});
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Guerra das Fontes (Typography System)
|
|
||||||
|
|
||||||
**Problema:** Fontes configuradas mas não carregadas.
|
|
||||||
**Resolução Profissional:**
|
|
||||||
|
|
||||||
### A. Carregamento Crítico (index.html)
|
|
||||||
Adicione o `preconnect` para eliminar a latência de DNS das fontes:
|
|
||||||
```html
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
|
||||||
```
|
|
||||||
|
|
||||||
### B. Fallback de Segurança (index.css)
|
|
||||||
Garantir que o `:root` tenha uma falha segura (system fonts) enquanto a webfont carrega:
|
|
||||||
```css
|
|
||||||
:root {
|
|
||||||
--font-main: 'Inter', -apple-system, system-ui, sans-serif;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Responsividade Fluida (War Room Standard)
|
|
||||||
|
|
||||||
**Problema:** Uso excessivo de `px` fixos e instabilidade no `radius`.
|
|
||||||
**Resolução Profissional:**
|
|
||||||
|
|
||||||
### A. Substituição de Pixels por Fluid Typography
|
|
||||||
Em vez de `h-[600px]`, utilize unidades relativas ou containers flexíveis com `min-height`.
|
|
||||||
- **Regra de Ouro:** Se o valor é > 20px, ele provavelmente deveria ser `clamp()` ou `%`.
|
|
||||||
|
|
||||||
### B. Ajuste de Bordas (Radius-Gate)
|
|
||||||
Substituir `--radius: 1vw` por uma escala que respeite limites físicos:
|
|
||||||
```css
|
|
||||||
:root {
|
|
||||||
/* Não fica quadrado no mobile, nem redondo demais no desktop */
|
|
||||||
--radius: clamp(8px, 1.2vw, 20px);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Pontos de Melhoria na Organização
|
|
||||||
|
|
||||||
1. **Módulo de Mocks Independente:** Mover todos os mocks para uma pasta `.mocks` na raiz da feature, para que o bundle de produção não carregue dados desnecessários.
|
|
||||||
2. **Shared Hooks Layer:** Centralizar lógicas de "Busca de Placa" ou "Validação de CNPJ" em `src/hooks/shared` para evitar duplicação entre Financeiro e Frota.
|
|
||||||
3. **Typed Contracts:** Se possível, migrar os arquivos `.json` de rotas para arquivos `.ts` (Typescript) para ganhar auto-complete no VS Code e evitar erros de digitação em caminhos de API.
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
# 🎯 O PONTO CENTRAL: Relatório de Consolidação Estratégica
|
|
||||||
|
|
||||||
Este relatório une o potencial do **PlatformSistemas** com a robustez do **Pralog Local Stack**, traçando o mapa definitivo para a excelência técnica.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. Interpretação dos Sistemas
|
|
||||||
|
|
||||||
### PlatformSistemas: "O Gateway Dinâmico"
|
|
||||||
Focado em agilidade e flexibilidade. O projeto utiliza arquivos de configuração (`.json`) para tentar automatizar a interface. É uma abordagem moderna de **"UI driven by metadata"**, mas que sofre com a falta de uma infraestrutura que sustente essa complexidade.
|
|
||||||
|
|
||||||
### Pralog (GitHub Import): "A Fortaleza Arquitetônica"
|
|
||||||
Focado em estabilidade e escala. Utiliza **Nx Monorepo**, garantindo que uma mudança na lógica do banco de dados (Prisma) reflita imediatamente em todos os serviços. É o exemplo de **"Infrastructure as Code"** perfeito.
|
|
||||||
|
|
||||||
**A Melhoria:** O `PlatformSistemas` deve herdar a **infraestrutura** da Pralog para sustentar sua **lógica dinâmica**.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Resolução dos Problemas Críticos
|
|
||||||
|
|
||||||
### 🔌 Problema 1: Custo de Conexão Front-Back
|
|
||||||
* **Diagnóstico:** Escrever um `Service.js` para cada entidade do JSON está gerando trabalho manual duplicado.
|
|
||||||
* **A Resolução (Service Factory):** Criar um `BaseService` que interprete o JSON nativamente.
|
|
||||||
* **Ação:** Implementar um hook genérico `useContract(routeKey, params)` que use o `apiRouteManager` para resolver a URL e o `TanStack Query` para gerenciar o cache.
|
|
||||||
* **Resultado:** Conectar uma nova entidade passa a ser apenas adicionar uma linha no JSON, sem criar arquivos JS extras.
|
|
||||||
|
|
||||||
### 🔡 Problema 2: Falha no Sistema de Fontes
|
|
||||||
* **Diagnóstico:** O sistema define variáveis de fonte mas não as injeta no ciclo de vida do navegador de forma prioritária.
|
|
||||||
* **A Resolução (Hydration Loop):**
|
|
||||||
1. **Injeção Crítica:** Adicionar `@import` ou `<link>` no topo do `index.html` com `crossorigin`.
|
|
||||||
2. **CSS Var Mapping:** Vincular as variáveis do Tailwind 4 diretamente às CSS Variables do `:root` no `index.css`.
|
|
||||||
3. **Font-Swap:** Usar `font-display: swap` para evitar que o texto desapareça enquanto a fonte carrega.
|
|
||||||
|
|
||||||
### 📱 Problema 3: Problemas de Responsividade
|
|
||||||
* **Diagnóstico:** O uso de visual viewport (`vw/vh`) puro causa quebras em monitores ultrawide ou telas muito pequenas. O `radius: 1vw` é o maior culpado.
|
|
||||||
* **A Resolução (Calculated Responsiveness):**
|
|
||||||
* **Ação:** Migrar todos os valores fixos para a escala **Modular Clamp**.
|
|
||||||
* **Exemplo:** `padding: clamp(1rem, 2vw, 2.5rem)` – isso garante que o padding nunca seja ridiculamente pequeno nem gigante.
|
|
||||||
* **Radius:** Mudar para `round(min(12px, 1.5vw))` para manter a harmonia visual.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Melhorias na Organização do Front-end
|
|
||||||
|
|
||||||
1. **Arquitetura "Screaming Features":**
|
|
||||||
Mover tudo o que é específico de uma feature para dentro da pasta dela (incluindo Mocks e Types). Atualmente, há muita dispersão entre `src/services` e `src/features`.
|
|
||||||
2. **Centralização de Interceptores:**
|
|
||||||
Unificar a lógica de erro 401/403 (já iniciada no `api.js`) em um `AuthObserver` que não dependa de `window.location.href`, mas sim do router do React para transições suaves.
|
|
||||||
3. **Purga de Legado Automática:**
|
|
||||||
Adicionar um script no `package.json` (`npm run audit:clean`) que detecte arquivos em `descontinuado/` que não são mais importados no `App.jsx` e os mova para fora do diretório de build.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🏛️ O VEREDITO DA MESA REDONDA
|
|
||||||
|
|
||||||
**[Tony Stark]:** "Se você quer que essa API e esse Front parem de brigar, use o modelo de **Contracts** da Pralog. Defina o schema uma vez e gere o resto. O `PlatformSistemas` já tem os JSONs, só faltava a coragem de automatizar o `axios`."
|
|
||||||
|
|
||||||
**[Gordon Ramsay]:** "O seu layout não é responsivo, é uma gelatina! Use `clamp()` ou saia da minha frente! E tragam as fontes do Google de forma correta, não quero ver Times New Roman na minha tela nunca mais!"
|
|
||||||
|
|
||||||
**[Logan Roy]:** "Parem de criar pastas de backup. Se você não usa, morre. O Ponto Central é este: **Consolide as ferramentas da Pralog para salvar a agilidade do PlatformSistemas.**"
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
# 🦅 O Blueprint Pralog: O que Importar para a Plataforma
|
|
||||||
|
|
||||||
Ao analisar o repositório `grupo_pralog_github_import` (Pralog Local Stack), identificamos padrões de engenharia de elite que resolvem as principais lacunas do `PlatformSistemas`.
|
|
||||||
|
|
||||||
## 1. Infra-as-Code (O "Prato Principal")
|
|
||||||
O projeto `PlatformSistemas` é código "cru" (raw), enquanto a stack Pralog é uma cozinha industrial completa.
|
|
||||||
|
|
||||||
- **Docker-Compose Unificado:** Define bancos de dados (Postgres 15), Object Storage (Minio), Redis e Nginx em um único orquestrador.
|
|
||||||
- **Nginx como Gatekeeper:** O `nginx.conf` da stack Pralog já inclui compressão Gzip e fallback de SPA real.
|
|
||||||
- **Dockerfile Multi-Stage:** O front-end é buildado e servido em containers Alpine minúsculos, garantindo imutabilidade entre dev, staging e prod.
|
|
||||||
|
|
||||||
> [!TIP]
|
|
||||||
> **Ação Recomendada:** Copiar o `prafrota-ui.Dockerfile` e o `nginx.conf` para a raiz do `PlatformSistemas`, adaptando o build para Vite.
|
|
||||||
|
|
||||||
## 2. Arquitetura Nx Monorepo (Back-end & Libs)
|
|
||||||
A stack Pralog utiliza **Nx**, permitindo que a lógica de negócio seja compartilhada e testada isoladamente em `/libs`.
|
|
||||||
|
|
||||||
- **Libs Core (Prisma):** Toda a modelagem de dados está encapsulada em uma biblioteca core.
|
|
||||||
- **Schema Separation:** Uso de `POSTGRES_HOST_AUTH_METHOD: scram-sha-256` e separação lógica de Tenants.
|
|
||||||
- **Encapsulamento de Integrações:** Bibliotecas específicas para integrações (S3, AWS) que evitam o espalhamento de chaves de API pelo código.
|
|
||||||
|
|
||||||
## 3. Lógicas que Devem Ser Adotadas
|
|
||||||
|
|
||||||
### A. Fluxo de Autenticação Centralizado
|
|
||||||
A stack Pralog define segredos JWT específicos para cada tipo de usuário (Tenant, API, Driver) no `docker-compose.yml`. No `PlatformSistemas`, essa separação existe no `App.jsx`, mas falta uma camada de segurança robusta no transporte/infra.
|
|
||||||
|
|
||||||
### B. Gestão de Documentos (Minio/S3)
|
|
||||||
A stack Pralog já vem com uma infraestrutura de Minio configurada. O `PlatformSistemas` pode herdar essa lógica para o módulo de "Cadastro de Motorista" e "Prafrota", substituindo uploads diretos por um sistema de Object Storage persistente.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎭 MESA REDONDA: O VEREDITO
|
|
||||||
|
|
||||||
**[Tony Stark]:** "O monorepo Nx é o Santo Graal aqui. Se o `PlatformSistemas` quer crescer para RH, Financeiro e Frota sem virar um espaguete, ele precisa da estrutura de `libs` da stack Pralog. É modularidade atômica."
|
|
||||||
|
|
||||||
**[Gus Fring]:** "A infraestrutura do local-stack é aceitável. O uso do Nginx para proxyar a API remove problemas de CORS e melhora a segurança. É o padrão mínimo de profissionalismo."
|
|
||||||
|
|
||||||
**[Logan Roy]:** "A stack Pralog tem o que o PlatformSistemas não tem: **Estrutura de Poder**. Ela dita como o sistema escala. Parem de brincar com pastas 'Copia' e tragam o Docker agora."
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ CHECKLIST DE IMPORTAÇÃO
|
|
||||||
1. [ ] **Infra:** Trazer `docker-compose.yml`, `nginx.conf` e criar `Dockerfile.vite`.
|
|
||||||
2. [ ] **Dados:** Adotar o padrão de volumes externos para persistência do Postgres.
|
|
||||||
3. [ ] **Secrets:** Mover as variáveis de ambiente do `App.jsx` para o ecossistema de chaves do Docker.
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
# 🔋 Pralog Power-ups: Recursos Avançados para o PlatformSistemas
|
|
||||||
|
|
||||||
Além da infraestrutura e dos contratos, o repositório da Pralog contém "joias" de lógica que podem elevar o nível técnico dos módulos de Gestão de Risco (GR) e Frota.
|
|
||||||
|
|
||||||
## 1. Segurança de Dados (Cryptography v2)
|
|
||||||
O PlatformSistemas usa uma criptografia simples (Base64 + reverse) no front-end. A Pralog utiliza uma classe `Cryptography` robusta com **AES-256-CBC**.
|
|
||||||
|
|
||||||
- **Oportunidade:** Implementar o padrão de `IV_LENGTH: 16` e `createCipheriv` para tokens sensíveis no `api.js`.
|
|
||||||
- **Benefício:** Proteção real contra interceptação e leitura de `localStorage` em caso de XSS.
|
|
||||||
|
|
||||||
## 2. Busca e Filtros Inteligentes (String Normalizer)
|
|
||||||
A Pralog possui um `string-normalizer.ts` que permite buscas insensíveis a acentos, espaços extras e caracteres especiais.
|
|
||||||
|
|
||||||
- **Oportunidade:** Portar a função `normalizeStringForComparison` para o front-end do PlatformSistemas.
|
|
||||||
- **Benefício:** Melhoria drástica na UX de busca de placas, nomes de motoristas e fornecedores, evitando que o usuário não encontre um item por causa de um "ç" ou um espaço.
|
|
||||||
|
|
||||||
## 3. Wrappers de Integração (KYC & Risco)
|
|
||||||
A Pralog já tem implementado o "suporte de vida" para integrações críticas:
|
|
||||||
- **IDWall:** Para validação de documentos e background check.
|
|
||||||
- **Brasil Credit:** Para análise de crédito de motoristas/fornecedores.
|
|
||||||
- **Planner:** Para agendamentos e fluxos logísticos.
|
|
||||||
|
|
||||||
- **Oportunidade:** No módulo **GR (Gestão de Risco)** do PlatformSistemas, em vez de refazer a lógica de integração, use os wrappers da Pralog como template.
|
|
||||||
- **Benefício:** Redução de meses de desenvolvimento ao reaproveitar o tratamento de erros e o mapeamento de campos dessas APIs externas.
|
|
||||||
|
|
||||||
## 4. Normalização de Datas & Moedas
|
|
||||||
O arquivo `date-converter.util.ts` da Pralog resolve o pesadelo de fusos horários e formatos brasileiros (DD/MM/YYYY vs ISO).
|
|
||||||
|
|
||||||
- **Oportunidade:** Unificar o tratamento de datas em todas as colunas de estatísticas do Prafrot.
|
|
||||||
- **Benefício:** Fim das inconsistências visuais onde uma data aparece em formato americano e outra em brasileiro no mesmo painel.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🏛️ O VEREDITO FINAL DA MESA REDONDA
|
|
||||||
|
|
||||||
**[Tony Stark]:** "A classe de Criptografia da Pralog é o que separa um brinquedo de uma ferramenta de enterprise. Se o `PlatformSistemas` quer ser levado a sério, ele precisa parar de brincar de 'atob/btoa' e usar AES real."
|
|
||||||
|
|
||||||
**[Elliot Alderson]:** "Eles normalizam as strings antes de comparar. Isso previne falhas de lógica em filtros sensíveis. É simples, é elegante, e o `PlatformSistemas` precisa disso ontem."
|
|
||||||
|
|
||||||
**[Gus Fring]:** "A integração com IDWall e Brasil Credit é meticulosa. O tratamento de retentativas e timeouts já está lá. Errar uma integração de risco é caro; herdar o que já funciona é prudente."
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
✅ **DICA TÉCNICA (THE STEAL):**
|
|
||||||
Copie o arquivo `backend/libs/core/src/utils/string-normalizer.ts` da Pralog e transforme em um hook `useNormalizer` no seu projeto. Isso vai resolver 90% das reclamações de 'filtro que não funciona' no front-end.
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
# 📊 Relatório Técnico: PlatformSistemas
|
|
||||||
|
|
||||||
## 1. Visão Geral do Ecossistema
|
|
||||||
O projeto **PlatformSistemas** é uma plataforma multi-módulo moderna, construída sobre o ecossistema **React 19 + Vite + Tailwind CSS 4**. Ele integra diversos fluxos de negócio (Frota, RH, Financeiro, Gestão de Risco) em um front-end unificado com arquitetura baseada em recursos (features).
|
|
||||||
|
|
||||||
### 🚀 Stack Técnica Principal
|
|
||||||
- **Framework:** React 19.2.0 (Latest)
|
|
||||||
- **Bundler:** Vite 7.2.4
|
|
||||||
- **Estilização:** Tailwind CSS 4.1.18 (Beta/Next-gen)
|
|
||||||
- **Validation:** Zod 4.3.5 + React Hook Form
|
|
||||||
- **State Management:** Zustand 5.0.9
|
|
||||||
- **UI Components:** Radix UI (Primitives)
|
|
||||||
- **Animações:** Framer Motion 12.23.26
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Auditoria de Organização (Current State)
|
|
||||||
|
|
||||||
### ✅ Pontos Positivos (Gold Standards)
|
|
||||||
- **Tipografia Fluida:** Uso extensivo de `clamp()` em `index.css` para garantir escalabilidade perfeita sem media queries excessivas.
|
|
||||||
- **Modernização de Cores:** Adoção de `oklch` para cores mais precisas e vibrantes.
|
|
||||||
- **Lazy Loading:** Separação de rotas com `Suspense` e `lazy`, otimizando o payload inicial.
|
|
||||||
- **Design System:** Definição clara de variáveis semânticas no `:root`.
|
|
||||||
- **Automação:** Scripts de sincronização de contratos de API (`auto-sync-routes.js`).
|
|
||||||
|
|
||||||
### ⚠️ Pontos de Atenção (Dívida Técnica)
|
|
||||||
- **Redundância de Código:** Presença de pastas `src_2`, `src - Copia` e `Modulos Angular` na raiz, criando confusão sobre o que é código vivo.
|
|
||||||
- **Pasta Descontinuado:** Código morto misturado na árvore de `src/features`.
|
|
||||||
- **Complexidade de Rotas:** O arquivo `App.jsx` está se tornando um monolito de rotas; idealmente deveria ser fracionado por domínios.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Avaliação "War Room Bible"
|
|
||||||
|
|
||||||
| Critério | Status | Observação |
|
|
||||||
| :--- | :--- | :--- |
|
|
||||||
| **Regra dos 14KB** | 🟡 Parcial | CSS Crítico está bem otimizado, mas o bundle total de JS pode exceder os 10 pacotes TCP iniciais se não houver Code Splitting agressivo por componente. |
|
|
||||||
| **Matemática > Breakpoints** | 🟢 Excelente | Uso de `clamp()`, `min()` e `max()` é uma prática de elite aqui. |
|
|
||||||
| **Native First** | 🟢 Bom | Uso de Radix UI (que foca em acessibilidade nativa) e hooks modernos. |
|
|
||||||
| **Containerização** | 🔴 Ausente | Não foram encontrados Dockerfiles ou Nginx configs no mapeamento inicial da raiz. |
|
|
||||||
| **Dados (Postgres/Redis)** | ⚪ N/A | Front-end focado em consumo de API; lógica de back-end não analisada. |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. Sugestões de Melhoria (Roadmap)
|
|
||||||
|
|
||||||
1. **Limpeza de Cadáveres:** Deletar ou mover para um repositório `/legacy-archive` as pastas `src_2`, `src - Copia` e `Modulos Angular`.
|
|
||||||
2. **Componentização de Rotas:** Criar arquivos de rotas por módulo (ex: `FleetRoutes.jsx`, `FinanceRoutes.jsx`) e importá-los em `App.jsx`.
|
|
||||||
3. **Infra-as-Code:** Adicionar `Dockerfile` (Alpine based) e `nginx.conf` otimizado para servir o SPA.
|
|
||||||
4. **Performance:** Implementar `Above the Fold` optimization inlining o CSS crítico diretamente no `index.html`.
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
# 🎭 WAR ROOM SIMULATION: PLATFORM SISTEMAS (v7.0)
|
|
||||||
|
|
||||||
**Cenário:** Sala 4, 3:00 AM. O ar está denso. A tela gigante projeta a estrutura de diretórios do projeto.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 🗣️ A MESA REDONDA
|
|
||||||
|
|
||||||
**[Logan Roy]:** "Eu olho para essa raiz e vejo indecisão. `src`, `src_2`, `src - Copia`? **Isso parece um depósito de lixo de uma startup falida!** Se você quer mandar nessa indústria, limpe sua casa ou saia do caminho."
|
|
||||||
|
|
||||||
**[Gordon Ramsay]:** "GRAÇAS A DEUS ALGUÉM FALOU! Olhem para esse `index.css`. O `clamp()` está lá, a semântica está razoável, **MAS ONDE ESTÓ O DOCKERFILE?** Como vocês esperam que eu sirva esse código se nem uma cozinha (container) ele tem? É código cru! **IT'S RAW!**"
|
|
||||||
|
|
||||||
**[Steve Jobs]:** "Acalmem-se. Sintam o fluxo. O uso de `oklch` e as fontes fluidas mostram que há alma aqui. Alguém se importa com a tipografia. Mas esse `App.jsx`... **é um labirinto.** O usuário não sente a transição, ele sente o peso da estrutura. Precisamos de 'Gestalt', não de uma lista de compras de centenas de rotas."
|
|
||||||
|
|
||||||
**[Tony Stark]:** "Jobs está certo sobre o peso, mas erra no motivo. O problema não é o design, é o handshake. **Cadê o Nginx tunado? Cadê o HTTP/3?** Estamos servindo React 19 em um motor de fusca se não tivermos uma infraestrutura de container Alpine otimizada. E esse `auto-sync-routes`? Útil, mas parece um remendo para a falta de um Swagger real."
|
|
||||||
|
|
||||||
**[Marie Kondo]:** "Este diretório `Modulos Angular` não me traz alegria. Ele ocupa espaço no disco, na mente e no Git. **Arremesse-o no vazio.** Só guardamos o que é útil agora. O `src/features/descontinuado` também é um cemitério que precisa ser cremado."
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 🔥 O CONFLITO (Trade-offs)
|
|
||||||
|
|
||||||
* **Velocidade vs. Legado:** Stark quer deletar tudo o que não é `src` para ganhar 200ms de build time. Logan quer saber se os clientes antigos ainda dependem dos módulos Angular antes de puxar o gatilho.
|
|
||||||
* **Design vs. Simplicidade:** Jobs quer animações complexas do Framer Motion em cada rota, Ramsay grita que isso vai poluir o bundle e quebrar a regra dos 14KB se não for feito com `lazy` cirúrgico.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 🛠️ SOLUÇÃO "GOLD STANDARD"
|
|
||||||
|
|
||||||
**Decisão Unânime:** O projeto tem um motor de Ferrari (React 19 + Tailwind 4), mas está transportando sacos de cimento (Pastas Copia, Angular).
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
# PROTOCOLO DE PURGA
|
|
||||||
rm -Recurse -Force "./src_2"
|
|
||||||
rm -Recurse -Force "./src - Copia"
|
|
||||||
rm -Recurse -Force "./Modulos Angular"
|
|
||||||
```
|
|
||||||
|
|
||||||
✅ **PLANO DE AÇÃO IMEDIATA**
|
|
||||||
🔴 **Crítico (Tech):** Implementar `Dockerfile` multi-stage (Build: Node / Serve: Nginx Alpine) - [Stark/Gus]
|
|
||||||
🔴 **Crítico (Frontend):** Fracionar `App.jsx` em módulos de rotas (`prafrot.routes.jsx`, etc) - [Ramsay]
|
|
||||||
🟡 **Melhoria (UX):** Unificar o Design System removendo estilos órfãos em `descontinuado` - [Jobs]
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo "=== Diagnóstico de Build ==="
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "1. Verificando estrutura de arquivos:"
|
|
||||||
echo " - index.html:"
|
|
||||||
ls -la index.html 2>/dev/null && echo " ✓ Existe" || echo " ✗ Não encontrado"
|
|
||||||
|
|
||||||
echo " - src/main.jsx:"
|
|
||||||
ls -la src/main.jsx 2>/dev/null && echo " ✓ Existe" || echo " ✗ Não encontrado"
|
|
||||||
|
|
||||||
echo " - vite.config.ts:"
|
|
||||||
ls -la vite.config.ts 2>/dev/null && echo " ✓ Existe" || echo " ✗ Não encontrado"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "2. Conteúdo do index.html (últimas linhas):"
|
|
||||||
tail -5 index.html
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "3. Verificando node_modules:"
|
|
||||||
if [ -d "node_modules" ]; then
|
|
||||||
echo " ✓ node_modules existe"
|
|
||||||
echo " - Vite version:"
|
|
||||||
npm list vite 2>/dev/null | grep vite || echo " Vite não encontrado"
|
|
||||||
else
|
|
||||||
echo " ✗ node_modules não encontrado - execute 'npm install'"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "4. Limpando cache e reinstalando:"
|
|
||||||
echo " Executando: rm -rf node_modules dist .vite package-lock.json"
|
|
||||||
rm -rf node_modules dist .vite package-lock.json
|
|
||||||
|
|
||||||
echo " Executando: npm install"
|
|
||||||
npm install
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "5. Tentando build:"
|
|
||||||
npm run build
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "=== Fim do diagnóstico ==="
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://ui.shadcn.com/schema.json",
|
|
||||||
"style": "new-york",
|
|
||||||
"rsc": false,
|
|
||||||
"tsx": false,
|
|
||||||
"tailwind": {
|
|
||||||
"config": "tailwind.config.js",
|
|
||||||
"css": "src/index.css",
|
|
||||||
"baseColor": "neutral",
|
|
||||||
"cssVariables": true,
|
|
||||||
"prefix": ""
|
|
||||||
},
|
|
||||||
"iconLibrary": "lucide",
|
|
||||||
"aliases": {
|
|
||||||
"components": "@/components",
|
|
||||||
"utils": "@/lib/utils",
|
|
||||||
"ui": "@/components/ui",
|
|
||||||
"lib": "@/lib",
|
|
||||||
"hooks": "@/hooks"
|
|
||||||
},
|
|
||||||
"registries": {}
|
|
||||||
}
|
|
||||||
|
|
@ -1,101 +0,0 @@
|
||||||
# 🤖 AI RULES - AMBIENTE DE DEBUG & COMPONENTES VERSIONADOS
|
|
||||||
|
|
||||||
## 🎯 OBJETIVO
|
|
||||||
Definir as regras, arquitetura e padrões obrigatórios para o desenvolvimento e manutenção do ambiente de Debug (`src/features/dev-tools`) e criação de componentes versionados no projeto Integra Finance.
|
|
||||||
|
|
||||||
## 🏗️ ARQUITETURA DE DEBUG (PLAYGROUND)
|
|
||||||
|
|
||||||
O ambiente de Debug é um espaço isolado para criar, testar e documentar componentes antes de integrá-los à produção.
|
|
||||||
**Localização Principal**: `src/features/dev-tools/views/PlaygroundView.jsx`
|
|
||||||
|
|
||||||
### Principais Funcionalidades:
|
|
||||||
1. **Toggle de Versão**: Permite alternar entre a versão `PRODUCTION` (estável) e `DEBUG` (laboratório) de um componente.
|
|
||||||
2. **Isolamento de Tema**: Testa componentes em Light/Dark mode sem afetar o resto da app.
|
|
||||||
3. **Preview Responsivo**: Modos Desktop, Tablet e Mobile.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🧬 PADRÃO DE VERSIONAMENTO DE COMPONENTES (DUAL-VERSION)
|
|
||||||
|
|
||||||
Para componentes complexos ou que exigem testes exaustivos de UI, adotamos o padrão de **Componente Versionado**. Isso separa o código de produção do código de laboratório.
|
|
||||||
|
|
||||||
### Estrutura de Pastas Obrigatória:
|
|
||||||
Todo componente versionado deve seguir esta estrutura exata:
|
|
||||||
|
|
||||||
```
|
|
||||||
src/features/[feature]/components/[NomeComponente]/
|
|
||||||
├── index.js # Entry point (Exporta a versão de Produção por padrão)
|
|
||||||
├── [Componente].jsx # Versão de PRODUÇÃO (Limpa, funcional, sem mocks visuais)
|
|
||||||
└── [Componente].debug.jsx # Versão de DEBUG (Wrapper com controles, knobs e mocks)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Regras por Arquivo:
|
|
||||||
|
|
||||||
#### 1. `index.js`
|
|
||||||
Deve exportar o componente de produção como default para garantir importações limpas no resto do sistema.
|
|
||||||
```javascript
|
|
||||||
export { StatusBadge } from './StatusBadge';
|
|
||||||
export { StatusBadge as default } from './StatusBadge';
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. `[Componente].jsx` (Produção)
|
|
||||||
- Deve ser **puro** e focado na funcionalidade final.
|
|
||||||
- Recebe props via interface definida.
|
|
||||||
- **NÃO** deve conter botões de teste, logs visuais ou dados mockados hard-coded na renderização final.
|
|
||||||
|
|
||||||
#### 3. `[Componente].debug.jsx` (Debug / Laboratório)
|
|
||||||
- Deve importar e renderizar o componente de produção.
|
|
||||||
- Pode (e deve) conter:
|
|
||||||
- Estado local para controlar props do componente filho.
|
|
||||||
- Botões para simular ações (ex: "Simular Erro API").
|
|
||||||
- Logs visuais de eventos (`onSelect`, `onClick`).
|
|
||||||
- Wrapper visual (Cards, Grids) para facilitar o teste.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📝 REGISTRO NO PLAYGROUND
|
|
||||||
|
|
||||||
Para que um componente apareça no Playground (`PlaygroundView.jsx`), adicione-o à constante `componentsList`.
|
|
||||||
|
|
||||||
### Contrato do Objeto de Componente:
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
name: 'NomeDoComponente',
|
|
||||||
description: 'Descrição breve do que ele faz.',
|
|
||||||
props: { ...exemploDeProps }, // Usado para gerar a tabela de documentação e o snippet de código
|
|
||||||
|
|
||||||
// RENDERIZADOR PADRÃO (Produção)
|
|
||||||
// Obrigatório. Mostra como o componente é usado na vida real.
|
|
||||||
render: (props) => <MeuComponente {...props} />,
|
|
||||||
|
|
||||||
// RENDERIZADOR DE DEBUG (Opcional)
|
|
||||||
// Se definido, será usado quando o toggle "Debug" estiver ativado.
|
|
||||||
// Geralmente renderiza o componente .debug.jsx
|
|
||||||
debugRender: (props) => <MeuComponenteDebug {...props} />
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎨 DIRETRIZES DE UI/UX PARA O DEBUG
|
|
||||||
|
|
||||||
### 1. ExcelTable & Temas
|
|
||||||
- Componentes complexos como `ExcelTable` devem respeitar o tema `dark`/`light` propagado pelo container pai.
|
|
||||||
- Teste sempre a legibilidade em ambos os temas.
|
|
||||||
|
|
||||||
### 2. AutoFillInput & Formulários Dinâmicos
|
|
||||||
- Inputs de pesquisa (`AutoFillInput`) no modo Debug devem demonstrar fluxos reais.
|
|
||||||
- **Criação Dinâmica**: Ao invés de apenas logar "Criar", implemente uma lógica que capture o termo pesquisado e preencha um formulário de exemplo.
|
|
||||||
- **Feedback Visual**: Use cores de texto com alto contraste (Preto no Light, Branco no Dark) dentro dos inputs.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚫 O QUE NÃO FAZER
|
|
||||||
|
|
||||||
1. **NUNCA** deixe código de debug (`console.log`, bordas de teste vermelhas) no arquivo `[Componente].jsx` (Produção). Use o arquivo `.debug.jsx` para isso.
|
|
||||||
2. **NUNCA** importe o arquivo `.debug.jsx` em views reais da aplicação (Dashboard, Relatórios). Ele deve ser importado APENAS no `PlaygroundView.jsx`.
|
|
||||||
3. **EVITE** quebrar o build de produção. O `PlaygroundView` e seus imports de debug devem ser isolados ou tree-shakeable se possível (embora em dev-tools internal isso seja menos crítico, mantenha a higiene).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Última Atualização**: 2026-01-11 (Implementação do Sistema Dual-Version)
|
|
||||||
|
|
@ -1,197 +0,0 @@
|
||||||
# 🔧 Ajustes Pendentes - Financeiro V2 - Cruzamentos
|
|
||||||
|
|
||||||
## 📊 Contexto
|
|
||||||
Os cruzamentos já estão usando corretamente a rota `/extrato/apresentar`:
|
|
||||||
- **Receitas**: `tipoOperacao === 'C'` ✅
|
|
||||||
- **Despesas**: `tipoOperacao === 'D'` ✅
|
|
||||||
|
|
||||||
## ✅ Implementado
|
|
||||||
|
|
||||||
### CruzamentoView (Receitas)
|
|
||||||
- Estados de filtros adicionados
|
|
||||||
- Lógica de filtragem implementada (`dadosFiltrados`)
|
|
||||||
- KPIs recalculados (`kpisFiltrados`)
|
|
||||||
- Gráficos atualizados para usar dados filtrados
|
|
||||||
|
|
||||||
## 🚧 Pendente
|
|
||||||
|
|
||||||
### 1. CruzamentoView (Receitas) - Finalizar UI
|
|
||||||
|
|
||||||
#### 1.1. Adicionar Import do Select
|
|
||||||
```javascript
|
|
||||||
// Linha 19, após Badge
|
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 1.2. Substituir Barra de Filtros (linhas 223-253)
|
|
||||||
Substituir o conteúdo atual por:
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
{/* Filter & Summary Bar */}
|
|
||||||
<div className="bg-[#0f172a]/60 backdrop-blur-xl p-3 sm:p-4 rounded-xl sm:rounded-2xl border border-slate-800/50 flex flex-col gap-3 shadow-2xl relative z-10">
|
|
||||||
{/* Primeira Linha: Filtros de Período */}
|
|
||||||
<div className="flex flex-col sm:flex-row items-stretch sm:items-center gap-2 flex-1 min-w-0">
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<div className="p-2 bg-slate-900 rounded-lg border border-slate-800 shrink-0">
|
|
||||||
<Filter className="w-3.5 h-3.5 sm:w-4 sm:h-4 text-emerald-400" />
|
|
||||||
</div>
|
|
||||||
<Select value={filtroTipo} onValueChange={setFiltroTipo}>
|
|
||||||
<SelectTrigger className="h-8 w-28 bg-slate-900/50 border-slate-800 text-[10px] sm:text-[11px] font-bold text-white">
|
|
||||||
<SelectValue />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectItem value="mes">Por Mês</SelectItem>
|
|
||||||
<SelectItem value="ano">Por Ano</SelectItem>
|
|
||||||
<SelectItem value="todos">Todos</SelectItem>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{filtroTipo === 'mes' && (
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<Select value={filtroMes} onValueChange={setFiltroMes}>
|
|
||||||
<SelectTrigger className="h-8 w-32 bg-slate-900/50 border-slate-800 text-[10px] sm:text-[11px] font-bold text-white">
|
|
||||||
<SelectValue placeholder="Selecione o mês" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectItem value="01">Janeiro</SelectItem>
|
|
||||||
<SelectItem value="02">Fevereiro</SelectItem>
|
|
||||||
<SelectItem value="03">Março</SelectItem>
|
|
||||||
<SelectItem value="04">Abril</SelectItem>
|
|
||||||
<SelectItem value="05">Maio</SelectItem>
|
|
||||||
<SelectItem value="06">Junho</SelectItem>
|
|
||||||
<SelectItem value="07">Julho</SelectItem>
|
|
||||||
<SelectItem value="08">Agosto</SelectItem>
|
|
||||||
<SelectItem value="09">Setembro</SelectItem>
|
|
||||||
<SelectItem value="10">Outubro</SelectItem>
|
|
||||||
<SelectItem value="11">Novembro</SelectItem>
|
|
||||||
<SelectItem value="12">Dezembro</SelectItem>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{(filtroTipo === 'mes' || filtroTipo === 'ano') && (
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<Select value={filtroAno} onValueChange={setFiltroAno}>
|
|
||||||
<SelectTrigger className="h-8 w-24 bg-slate-900/50 border-slate-800 text-[10px] sm:text-[11px] font-bold text-white">
|
|
||||||
<SelectValue />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectItem value="2024">2024</SelectItem>
|
|
||||||
<SelectItem value="2025">2025</SelectItem>
|
|
||||||
<SelectItem value="2026">2026</SelectItem>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Segunda Linha: Filtro de Caixa */}
|
|
||||||
<div className="flex items-center gap-2 flex-wrap">
|
|
||||||
<span className="text-[10px] font-bold text-slate-500 uppercase">Caixa:</span>
|
|
||||||
<Select value={filtroCaixa} onValueChange={setFiltroCaixa}>
|
|
||||||
<SelectTrigger className="h-8 w-40 bg-slate-900/50 border-slate-800 text-[10px] sm:text-[11px] font-bold text-white">
|
|
||||||
<SelectValue />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectItem value="todos">Todas as Caixas</SelectItem>
|
|
||||||
<SelectItem value="1">Caixa 1</SelectItem>
|
|
||||||
<SelectItem value="2">Caixa 2</SelectItem>
|
|
||||||
<SelectItem value="3">Caixa 3</SelectItem>
|
|
||||||
<SelectItem value="4">Caixa 4</SelectItem>
|
|
||||||
<SelectItem value="5">Caixa 5</SelectItem>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
<Badge variant="outline" className="h-8 px-3 rounded-lg bg-emerald-500/10 border-emerald-500/20 text-emerald-400 text-[10px] font-bold">
|
|
||||||
{dadosFiltrados.length} registros
|
|
||||||
</Badge>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 1.3. Atualizar KPIs para usar kpisFiltrados (linhas 257-281)
|
|
||||||
Substituir:
|
|
||||||
- `kpis?.totalRecebido` por `kpisFiltrados?.totalRecebido`
|
|
||||||
- `kpis?.totalPendente` por `kpisFiltrados?.totalPendente`
|
|
||||||
- `kpis?.totalGeral` por `kpisFiltrados?.totalGeral`
|
|
||||||
|
|
||||||
### 2. CruzamentoDespesasView (Despesas)
|
|
||||||
|
|
||||||
Aplicar as mesmas mudanças no arquivo `contas-pagar/CruzamentoDespesasView.jsx`:
|
|
||||||
|
|
||||||
#### 2.1. Adicionar Estados de Filtros (após linha 84)
|
|
||||||
```javascript
|
|
||||||
// Estados para filtros
|
|
||||||
const [filtroMes, setFiltroMes] = React.useState('');
|
|
||||||
const [filtroAno, setFiltroAno] = React.useState(new Date().getFullYear().toString());
|
|
||||||
const [filtroCaixa, setFiltroCaixa] = React.useState('todos');
|
|
||||||
const [filtroTipo, setFiltroTipo] = React.useState('mes'); // 'mes' | 'ano' | 'todos'
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2.2. Adicionar Lógica de Filtragem
|
|
||||||
```javascript
|
|
||||||
// Dados filtrados baseados nos filtros ativos
|
|
||||||
const dadosExecutadosFiltrados = React.useMemo(() => {
|
|
||||||
if (!Array.isArray(despesasExecutadas)) return [];
|
|
||||||
|
|
||||||
return despesasExecutadas.filter(item => {
|
|
||||||
// Filtro por período
|
|
||||||
if (filtroTipo === 'mes' && filtroMes && filtroAno) {
|
|
||||||
const dataItem = item?.dataEntrada || item?.data || '';
|
|
||||||
const [ano, mes] = dataItem.split('-');
|
|
||||||
if (ano !== filtroAno || mes !== filtroMes) return false;
|
|
||||||
} else if (filtroTipo === 'ano' && filtroAno) {
|
|
||||||
const dataItem = item?.dataEntrada || item?.data || '';
|
|
||||||
const [ano] = dataItem.split('-');
|
|
||||||
if (ano !== filtroAno) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filtro por caixa
|
|
||||||
if (filtroCaixa !== 'todos' && item?.caixinha) {
|
|
||||||
if (item.caixinha !== filtroCaixa) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}, [despesasExecutadas, filtroMes, filtroAno, filtroCaixa, filtroTipo]);
|
|
||||||
|
|
||||||
// KPIs recalculados
|
|
||||||
const kpisFiltrados = React.useMemo(() => {
|
|
||||||
const totalExecutado = dadosExecutadosFiltrados.reduce((acc, item) => acc + (item.valor || 0), 0);
|
|
||||||
|
|
||||||
return {
|
|
||||||
totalPlanejado: 0,
|
|
||||||
totalExecutado,
|
|
||||||
variacao: totalExecutado,
|
|
||||||
percentualVariacao: 0
|
|
||||||
};
|
|
||||||
}, [dadosExecutadosFiltrados]);
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2.3. Atualizar useMemo para usar dados filtrados
|
|
||||||
Substituir todas as referências a `despesasExecutadas` por `dadosExecutadosFiltrados` nos cálculos de:
|
|
||||||
- `comparativoCategoria`
|
|
||||||
- `timelineData`
|
|
||||||
- `categoriaData`
|
|
||||||
|
|
||||||
#### 2.4. Adicionar mesma UI de filtros (linhas 172-207)
|
|
||||||
|
|
||||||
#### 2.5. Atualizar KPIs para usar kpisFiltrados
|
|
||||||
|
|
||||||
## 🎯 Resultado Esperado
|
|
||||||
|
|
||||||
Após implementar essas mudanças:
|
|
||||||
- ✅ Filtros de mês/ano funcionais
|
|
||||||
- ✅ Filtro de caixa funcional
|
|
||||||
- ✅ KPIs atualizados dinamicamente conforme filtros
|
|
||||||
- ✅ Gráficos refletindo apenas dados filtrados
|
|
||||||
- ✅ Contador de registros filtrados visível
|
|
||||||
- ✅ Dados sempre vindos de `/extrato/apresentar`
|
|
||||||
|
|
||||||
## 📌 Observações
|
|
||||||
|
|
||||||
1. O campo `caixinha` pode não estar presente em todos os registros do extrato. Ajustar conforme necessário.
|
|
||||||
2. Os filtros são client-side. Para grandes volumes de dados, considerar filtros server-side.
|
|
||||||
3. O estado inicial do filtro de mês está vazio - o usuário precisa selecionar.
|
|
||||||
4. Considerar adicionar um botão "Limpar Filtros" para melhor UX.
|
|
||||||
|
|
@ -1,220 +0,0 @@
|
||||||
# 🎨 Implementação do Tema Zoho no Financeiro V2
|
|
||||||
|
|
||||||
## 📋 Resumo da Implementação
|
|
||||||
|
|
||||||
**Data**: 02/02/2026
|
|
||||||
**Módulo**: `financeiro-v2`
|
|
||||||
**Objetivo**: Implementar tema com fontes estilo Zoho e converter medidas para vw/vh
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 Objetivos
|
|
||||||
|
|
||||||
### 1. **Sistema de Tipografia Adaptativa (Estilo Zoho)**
|
|
||||||
- ✅ Usar fonte **Inter** (similar ao Zoho Puvi)
|
|
||||||
- ✅ Implementar sistema de `clamp()` com vw/vh
|
|
||||||
- ✅ Pesos moderados (semibold/medium, não black/bold excessivo)
|
|
||||||
- ✅ Tamanhos adaptativos para todas as resoluções
|
|
||||||
|
|
||||||
### 2. **Conversão de Medidas**
|
|
||||||
- ✅ Converter **todas** as medidas fixas (px, rem) para vw/vh
|
|
||||||
- ✅ Usar `clamp(min, preferred, max)` para controle
|
|
||||||
- ✅ Garantir responsividade em resoluções menores
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📐 Sistema de Medidas Adaptativas
|
|
||||||
|
|
||||||
### **Tipografia**
|
|
||||||
```css
|
|
||||||
/* Tiny */ clamp(0.75rem, 0.9vw, 0.875rem) /* 12px-14px */
|
|
||||||
/* Label */ clamp(0.875rem, 1vw, 0.9375rem) /* 14px-15px */
|
|
||||||
/* Body */ clamp(1rem, 1.4vw, 1.25rem) /* 16px-20px */
|
|
||||||
/* Subtitle */ clamp(1.125rem, 2vw, 1.5rem) /* 18px-24px */
|
|
||||||
/* Title */ clamp(1.5rem, 2.8vw, 2.25rem) /* 24px-36px */
|
|
||||||
/* Number */ clamp(1.75rem, 3.4vw, 2.5rem) /* 28px-40px */
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Espaçamento**
|
|
||||||
```css
|
|
||||||
/* Small */ clamp(0.5rem, 1vw, 1rem) /* 8px-16px */
|
|
||||||
/* Medium */ clamp(1rem, 2vw, 1.5rem) /* 16px-24px */
|
|
||||||
/* Large */ clamp(1.5rem, 3vw, 2.5rem) /* 24px-40px */
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Dimensões**
|
|
||||||
```css
|
|
||||||
/* Icon Small */ clamp(1rem, 1.5vw, 1.25rem) /* 16px-20px */
|
|
||||||
/* Icon Medium */ clamp(1.25rem, 2vw, 1.5rem) /* 20px-24px */
|
|
||||||
/* Icon Large */ clamp(1.5rem, 2.5vw, 2rem) /* 24px-32px */
|
|
||||||
|
|
||||||
/* Card Height */ clamp(8rem, 12vh, 14rem) /* 128px-224px */
|
|
||||||
/* Modal Width */ clamp(20rem, 40vw, 50rem) /* 320px-800px */
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎨 Pesos de Fonte (Estilo Zoho)
|
|
||||||
|
|
||||||
| Peso | Classe | Uso |
|
|
||||||
|------|--------|-----|
|
|
||||||
| **Normal (400)** | `font-normal` | Corpo de texto, valores |
|
|
||||||
| **Medium (500)** | `font-medium` | Labels, descrições |
|
|
||||||
| **Semibold (600)** | `font-semibold` | Títulos, números importantes |
|
|
||||||
| **Bold (700)** | `font-bold` | ⚠️ Apenas ênfase extrema |
|
|
||||||
| **Black (900)** | `font-black` | ❌ **EVITAR** |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📁 Arquivos para Modificar
|
|
||||||
|
|
||||||
### 1. **Componentes Principais**
|
|
||||||
- [ ] `src/features/financeiro-v2/components/ExcelTable.jsx`
|
|
||||||
- [ ] `src/features/financeiro-v2/components/FinanceiroV2Sidebar.jsx`
|
|
||||||
- [ ] `src/features/financeiro-v2/components/AdvancedFiltersModal.jsx`
|
|
||||||
|
|
||||||
### 2. **Views**
|
|
||||||
- [ ] `src/features/financeiro-v2/views/DashboardView.jsx`
|
|
||||||
- [ ] `src/features/financeiro-v2/views/FluxoCaixaView.jsx`
|
|
||||||
- [ ] `src/features/financeiro-v2/views/RelatoriosView.jsx`
|
|
||||||
- [ ] `src/features/financeiro-v2/views/contas-receber/*`
|
|
||||||
- [ ] `src/features/financeiro-v2/views/contas-pagar/*`
|
|
||||||
- [ ] `src/features/financeiro-v2/views/conciliacao-v2/*`
|
|
||||||
|
|
||||||
### 3. **Layout Principal**
|
|
||||||
- [ ] `src/features/financeiro-v2/index.jsx`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔄 Padrões de Conversão
|
|
||||||
|
|
||||||
### **DE (antes):**
|
|
||||||
```jsx
|
|
||||||
// Tamanhos fixos
|
|
||||||
className="text-xl" // 1.25rem (20px)
|
|
||||||
className="text-sm" // 0.875rem (14px)
|
|
||||||
className="p-6" // 1.5rem (24px)
|
|
||||||
className="w-10" // 2.5rem (40px)
|
|
||||||
className="h-24" // 6rem (96px)
|
|
||||||
```
|
|
||||||
|
|
||||||
### **PARA (depois):**
|
|
||||||
```jsx
|
|
||||||
// Tamanhos adaptativos
|
|
||||||
className="text-[clamp(1rem,1.6vw,1.375rem)]" // Body Large (16px-22px)
|
|
||||||
className="text-[clamp(0.875rem,1vw,0.9375rem)]" // Label (14px-15px)
|
|
||||||
className="p-[clamp(1rem,2vw,1.5rem)]" // Padding adaptativo
|
|
||||||
className="w-[clamp(2rem,3vw,2.5rem)]" // Width adaptativa
|
|
||||||
className="h-[clamp(4rem,8vh,6rem)]" // Height adaptativa
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✅ Checklist de Implementação
|
|
||||||
|
|
||||||
### **Fase 1: Componentes Base**
|
|
||||||
- [ ] Atualizar `ExcelTable.jsx`
|
|
||||||
- [ ] Converter tamanhos de fonte usando `clamp()`
|
|
||||||
- [ ] Ajustar padding/margin para vw/vh
|
|
||||||
- [ ] Reduzir peso de fontes (black → semibold)
|
|
||||||
- [ ] Ajustar ícones com dimensões adaptativas
|
|
||||||
|
|
||||||
### **Fase 2: Views Principais**
|
|
||||||
- [ ] Atualizar `DashboardView.jsx`
|
|
||||||
- [ ] Converter cards para dimensões adaptativas
|
|
||||||
- [ ] Ajustar gráficos com altura em vh
|
|
||||||
- [ ] Atualizar tipografia dos textos
|
|
||||||
|
|
||||||
- [ ] Atualizar `FluxoCaixaView.jsx`
|
|
||||||
- [ ] Converter filtros e controles
|
|
||||||
- [ ] Ajustar tabelas e gráficos
|
|
||||||
|
|
||||||
- [ ] Atualizar `RelatoriosView.jsx`
|
|
||||||
- [ ] Converter cards de relatórios
|
|
||||||
- [ ] Ajustar modais de exportação
|
|
||||||
|
|
||||||
### **Fase 3: Subviews**
|
|
||||||
- [ ] Atualizar views de `contas-receber`
|
|
||||||
- [ ] Atualizar views de `contas-pagar`
|
|
||||||
- [ ] Atualizar views de `conciliacao-v2`
|
|
||||||
|
|
||||||
### **Fase 4: Layout e Navegação**
|
|
||||||
- [ ] Atualizar `index.jsx`
|
|
||||||
- [ ] Converter header extras
|
|
||||||
- [ ] Ajustar layout containers
|
|
||||||
- [ ] Atualizar sidebar
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎨 Exemplos de Conversão
|
|
||||||
|
|
||||||
### **Card de KPI**
|
|
||||||
```jsx
|
|
||||||
// ANTES
|
|
||||||
<div className="p-5">
|
|
||||||
<div className="w-10 h-10 rounded-xl">
|
|
||||||
<Icon size={18} />
|
|
||||||
</div>
|
|
||||||
<span className="text-[10px] font-bold uppercase">TÍTULO</span>
|
|
||||||
<div className="text-xl font-black">R$ 1.234,56</div>
|
|
||||||
<p className="text-[10px]">Subtítulo</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
// DEPOIS
|
|
||||||
<div className="p-[clamp(1rem,1.5vw,1.25rem)]">
|
|
||||||
<div className="w-[clamp(2rem,3vw,2.5rem)] h-[clamp(2rem,3vw,2.5rem)] rounded-xl">
|
|
||||||
<Icon size="clamp(1rem,1.5vw,1.125rem)" />
|
|
||||||
</div>
|
|
||||||
<span className="text-[clamp(0.625rem,0.8vw,0.75rem)] font-semibold uppercase">TÍTULO</span>
|
|
||||||
<div className="text-[clamp(1.5rem,2.8vw,2.25rem)] font-semibold">R$ 1.234,56</div>
|
|
||||||
<p className="text-[clamp(0.625rem,0.8vw,0.75rem)] font-medium">Subtítulo</p>
|
|
||||||
</div>
|
|
||||||
```
|
|
||||||
|
|
||||||
### **Tabela**
|
|
||||||
```jsx
|
|
||||||
// ANTES
|
|
||||||
<th className="h-[40px] px-3">
|
|
||||||
<span className="text-[clamp(0.75rem,0.9vw,0.8125rem)] font-bold">COLUNA</span>
|
|
||||||
</th>
|
|
||||||
|
|
||||||
// DEPOIS
|
|
||||||
<th className="h-[clamp(2rem,3vh,2.5rem)] px-[clamp(0.75rem,1vw,1rem)]">
|
|
||||||
<span className="text-[clamp(0.75rem,0.9vw,0.875rem)] font-semibold">COLUNA</span>
|
|
||||||
</th>
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🧪 Testes Necessários
|
|
||||||
|
|
||||||
### **Resoluções para Testar**
|
|
||||||
1. **Mobile**: 375px (iPhone SE)
|
|
||||||
2. **Tablet**: 768px (iPad)
|
|
||||||
3. **Desktop Small**: 1366px
|
|
||||||
4. **Desktop Large**: 1920px
|
|
||||||
5. **4K**: 2560px
|
|
||||||
|
|
||||||
### **Validações**
|
|
||||||
- [ ] Textos legíveis em todas as resoluções
|
|
||||||
- [ ] Sem overflow ou cortes de conteúdo
|
|
||||||
- [ ] Botões e ícones com tamanhos proporcionais
|
|
||||||
- [ ] Gráficos se adaptam corretamente
|
|
||||||
- [ ] Modais e painéis responsivos
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 Progresso
|
|
||||||
|
|
||||||
- [ ] **Componentes Base** (0/4)
|
|
||||||
- [ ] **Views Principais** (0/3)
|
|
||||||
- [ ] **Subviews** (0/20)
|
|
||||||
- [ ] **Layout** (0/1)
|
|
||||||
- [ ] **Testes** (0/5)
|
|
||||||
|
|
||||||
**Total**: 0/28 (0%)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Status**: 🟡 Em Progresso
|
|
||||||
**Próximo Passo**: Iniciar conversão dos componentes base
|
|
||||||
|
|
@ -1,114 +0,0 @@
|
||||||
# ✅ Implementação Completa - Filtros Financeiro V2
|
|
||||||
|
|
||||||
## 🎉 Status: CONCLUÍDO
|
|
||||||
|
|
||||||
Todos os filtros funcionais foram implementados com sucesso nos cruzamentos de Receitas e Despesas!
|
|
||||||
|
|
||||||
## 📊 Arquivos Modificados
|
|
||||||
|
|
||||||
### 1. ✅ CruzamentoView (Receitas)
|
|
||||||
**Arquivo**: `src/features/financeiro-v2/views/contas-receber/CruzamentoView.jsx`
|
|
||||||
|
|
||||||
**Mudanças Implementadas:**
|
|
||||||
- ✅ Import do Select component adicionado
|
|
||||||
- ✅ Estados de filtros criados (`filtroMes`, `filtroAno`, `filtroCaixa`, `filtroTipo`)
|
|
||||||
- ✅ Função `dadosFiltrados` implementada
|
|
||||||
- ✅ Função `kpisFiltrados` implementada
|
|
||||||
- ✅ Todos os useMemo atualizados para usar `dadosFiltrados`
|
|
||||||
- ✅ UI de filtros completa com Select de mês/ano e caixas
|
|
||||||
- ✅ Contador de registros filtrados
|
|
||||||
- ✅ KPIs atualizados para usar `kpisFiltrados`
|
|
||||||
|
|
||||||
### 2. ✅ CruzamentoDespesasView (Despesas)
|
|
||||||
**Arquivo**: `src/features/financeiro-v2/views/contas-pagar/CruzamentoDespesasView.jsx`
|
|
||||||
|
|
||||||
**Mudanças Implementadas:**
|
|
||||||
- ✅ Select component já estava importado
|
|
||||||
- ✅ Estados de filtros criados (`filtroMes`, `filtroAno`, `filtroCaixa`, `filtroTipo`)
|
|
||||||
- ✅ Função `dadosExecutadosFiltrados` implementada
|
|
||||||
- ✅ Função `kpisFiltrados` implementada
|
|
||||||
- ✅ Todos os useMemo atualizados para usar `dadosExecutadosFiltrados`
|
|
||||||
- ✅ UI de filtros completa com Select de mês/ano e caixas
|
|
||||||
- ✅ Contador de registros filtrados
|
|
||||||
- ✅ KPIs atualizados para usar `kpisFiltrados`
|
|
||||||
|
|
||||||
### 3. ✅ Hooks (Já estavam corretos)
|
|
||||||
**Arquivos**:
|
|
||||||
- `src/features/financeiro-v2/hooks/useContasReceber.js`
|
|
||||||
- `src/features/financeiro-v2/hooks/useContasPagar.js`
|
|
||||||
|
|
||||||
**Status**: Já estavam buscando corretamente de `/extrato/apresentar` com filtros de `tipoOperacao`
|
|
||||||
|
|
||||||
## 🎯 Funcionalidades Implementadas
|
|
||||||
|
|
||||||
### Filtros Disponíveis:
|
|
||||||
1. **Por Período**:
|
|
||||||
- Por Mês (seleciona mês e ano)
|
|
||||||
- Por Ano (seleciona apenas ano)
|
|
||||||
- Todos (sem filtro de período)
|
|
||||||
|
|
||||||
2. **Por Caixa**:
|
|
||||||
- Todas as Caixas
|
|
||||||
- Caixa 1, 2, 3, 4, 5
|
|
||||||
|
|
||||||
### Comportamento:
|
|
||||||
- ✅ Filtros são aplicados em tempo real
|
|
||||||
- ✅ KPIs recalculados automaticamente
|
|
||||||
- ✅ Gráficos atualizados dinamicamente
|
|
||||||
- ✅ Tabelas refletem dados filtrados
|
|
||||||
- ✅ Contador mostra quantidade de registros filtrados
|
|
||||||
|
|
||||||
## 📈 Dados Corretos
|
|
||||||
|
|
||||||
### Receitas (Contas a Receber):
|
|
||||||
- **Fonte**: `/extrato/apresentar` com `tipoOperacao === 'C'`
|
|
||||||
- **Valor Total**: R$ 249.808,86 ✅
|
|
||||||
- **Filtros**: Aplicados aos dados do extrato
|
|
||||||
|
|
||||||
### Despesas (Contas a Pagar):
|
|
||||||
- **Fonte**: `/extrato/apresentar` com `tipoOperacao === 'D'`
|
|
||||||
- **Valor Total**: R$ 251.802,92 ✅
|
|
||||||
- **Filtros**: Aplicados aos dados do extrato
|
|
||||||
|
|
||||||
## 🔍 Observações Importantes
|
|
||||||
|
|
||||||
1. **Campo `caixinha`**: O filtro de caixa verifica se o item possui o campo `caixinha`. Se não houver, o item não será filtrado por caixa.
|
|
||||||
|
|
||||||
2. **Filtros Client-Side**: Os filtros são aplicados no frontend. Para grandes volumes de dados, considere implementar filtros server-side no futuro.
|
|
||||||
|
|
||||||
3. **Estado Inicial**:
|
|
||||||
- Filtro de tipo: "mes"
|
|
||||||
- Filtro de mês: vazio (usuário precisa selecionar)
|
|
||||||
- Filtro de ano: ano atual
|
|
||||||
- Filtro de caixa: "todos"
|
|
||||||
|
|
||||||
4. **Planejado Zerado**: Como não há funcionalidade de planejamento implementada, os valores planejados estão zerados conforme especificado.
|
|
||||||
|
|
||||||
## 🚀 Próximos Passos (Opcional)
|
|
||||||
|
|
||||||
1. **Melhorias de UX**:
|
|
||||||
- Adicionar botão "Limpar Filtros"
|
|
||||||
- Salvar filtros no localStorage
|
|
||||||
- Adicionar indicador visual de filtros ativos
|
|
||||||
|
|
||||||
2. **Performance**:
|
|
||||||
- Implementar filtros server-side para grandes volumes
|
|
||||||
- Adicionar debounce nos filtros se necessário
|
|
||||||
|
|
||||||
3. **Funcionalidades Futuras**:
|
|
||||||
- Exportar dados filtrados para Excel
|
|
||||||
- Comparação entre períodos
|
|
||||||
- Filtros avançados (por categoria, por valor, etc.)
|
|
||||||
|
|
||||||
## ✨ Resultado Final
|
|
||||||
|
|
||||||
Os cruzamentos agora possuem:
|
|
||||||
- ✅ Filtros funcionais de mês/ano
|
|
||||||
- ✅ Filtros de caixas
|
|
||||||
- ✅ KPIs dinâmicos que refletem os filtros
|
|
||||||
- ✅ Gráficos e tabelas atualizados em tempo real
|
|
||||||
- ✅ Contador de registros filtrados
|
|
||||||
- ✅ Interface intuitiva e responsiva
|
|
||||||
- ✅ Dados corretos vindos de `/extrato/apresentar`
|
|
||||||
|
|
||||||
**Status**: 🎉 **IMPLEMENTAÇÃO COMPLETA E FUNCIONAL!**
|
|
||||||
|
|
@ -1,190 +0,0 @@
|
||||||
# ✅ Implementação Final - Filtros Dinâmicos Financeiro V2
|
|
||||||
|
|
||||||
## 🎉 Status: 100% CONCLUÍDO
|
|
||||||
|
|
||||||
Todos os filtros dinâmicos foram implementados com sucesso, integrando com as rotas da API!
|
|
||||||
|
|
||||||
## 📊 Mudanças Implementadas
|
|
||||||
|
|
||||||
### 1. ✅ Integração com API
|
|
||||||
**Rotas Utilizadas:**
|
|
||||||
- `/categorias/apresentar` - Lista todas as categorias do sistema
|
|
||||||
- `/caixinhas/apresentar` - Lista todas as caixas financeiras
|
|
||||||
|
|
||||||
**Service Atualizado:**
|
|
||||||
- `src/services/extratoService.js` - Já possuía as funções `fetchCategorias()` e `fetchCaixinhas()`
|
|
||||||
|
|
||||||
### 2. ✅ Hooks Atualizados
|
|
||||||
|
|
||||||
#### **useContasReceber.js**
|
|
||||||
- ✅ Adicionados estados `categorias` e `caixas`
|
|
||||||
- ✅ useEffect para buscar categorias e caixas da API
|
|
||||||
- ✅ Campo `caixinha` adicionado ao mapeamento de receitas
|
|
||||||
- ✅ Categorias e caixas expostas no state
|
|
||||||
|
|
||||||
#### **useContasPagar.js**
|
|
||||||
- ✅ Adicionados estados `categorias` e `caixas`
|
|
||||||
- ✅ useEffect para buscar categorias e caixas da API
|
|
||||||
- ✅ Campo `caixinha` adicionado ao mapeamento de despesas
|
|
||||||
- ✅ Categorias e caixas expostas no state
|
|
||||||
|
|
||||||
### 3. ✅ Views Atualizadas
|
|
||||||
|
|
||||||
#### **CruzamentoView (Receitas)**
|
|
||||||
- ✅ Props atualizadas para receber `categorias` e `caixas`
|
|
||||||
- ✅ Select de Caixas agora é dinâmico (map das caixas da API)
|
|
||||||
- ✅ Filtros funcionam com IDs reais das caixas
|
|
||||||
|
|
||||||
#### **ContasReceberView**
|
|
||||||
- ✅ Extrai `categorias` e `caixas` do state
|
|
||||||
- ✅ Passa como props para CruzamentoView
|
|
||||||
|
|
||||||
#### **CruzamentoDespesasView**
|
|
||||||
- ✅ Props atualizadas para receber `categorias` e `caixas` do state
|
|
||||||
- ✅ Select de Caixas agora é dinâmico (map das caixas da API)
|
|
||||||
- ✅ Filtros funcionam com IDs reais das caixas
|
|
||||||
|
|
||||||
## 🎯 Funcionalidades Implementadas
|
|
||||||
|
|
||||||
### Filtros Dinâmicos:
|
|
||||||
1. **Caixas**:
|
|
||||||
- ✅ Carregadas dinamicamente de `/caixinhas/apresentar`
|
|
||||||
- ✅ Exibem o nome real da caixa (campo `caixinha`)
|
|
||||||
- ✅ Filtram por ID (campo `idcaixinhas_financeiro`)
|
|
||||||
- ✅ Opção "Todas as Caixas" sempre disponível
|
|
||||||
|
|
||||||
2. **Categorias** (preparado para uso futuro):
|
|
||||||
- ✅ Carregadas dinamicamente de `/categorias/apresentar`
|
|
||||||
- ✅ Disponíveis no state para implementações futuras
|
|
||||||
- ✅ Podem ser usadas para filtros adicionais
|
|
||||||
|
|
||||||
### Mapeamento de Dados:
|
|
||||||
- ✅ Campo `idcaixinhas_financeiro` do extrato mapeado para `caixinha`
|
|
||||||
- ✅ Filtro compara `caixinha` do item com ID selecionado
|
|
||||||
- ✅ Fallback para dados sem caixa definida
|
|
||||||
|
|
||||||
## 📁 Arquivos Modificados
|
|
||||||
|
|
||||||
1. ✅ `src/features/financeiro-v2/hooks/useContasReceber.js`
|
|
||||||
2. ✅ `src/features/financeiro-v2/hooks/useContasPagar.js`
|
|
||||||
3. ✅ `src/features/financeiro-v2/views/contas-receber/CruzamentoView.jsx`
|
|
||||||
4. ✅ `src/features/financeiro-v2/views/contas-receber/ContasReceberView.jsx`
|
|
||||||
5. ✅ `src/features/financeiro-v2/views/contas-pagar/CruzamentoDespesasView.jsx`
|
|
||||||
|
|
||||||
## 🔄 Fluxo de Dados
|
|
||||||
|
|
||||||
```
|
|
||||||
API (/caixinhas/apresentar)
|
|
||||||
↓
|
|
||||||
extratoService.fetchCaixinhas()
|
|
||||||
↓
|
|
||||||
useContasReceber/useContasPagar (useEffect)
|
|
||||||
↓
|
|
||||||
state.caixas
|
|
||||||
↓
|
|
||||||
ContasReceberView/ContasPagarView
|
|
||||||
↓
|
|
||||||
CruzamentoView/CruzamentoDespesasView (props)
|
|
||||||
↓
|
|
||||||
Select Component (map dinâmico)
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🎨 Exemplo de Dados
|
|
||||||
|
|
||||||
### Caixas da API:
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"caixinha": "Padronizadosss",
|
|
||||||
"idcaixinhas_financeiro": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"caixinha": "a",
|
|
||||||
"idcaixinhas_financeiro": 4
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"caixinha": "eu",
|
|
||||||
"idcaixinhas_financeiro": 6
|
|
||||||
}
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Categorias da API:
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"categoria": "Contas",
|
|
||||||
"idcategoria": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"categoria": "Folha de pagamento",
|
|
||||||
"idcategoria": 5
|
|
||||||
}
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🚀 Como Funciona
|
|
||||||
|
|
||||||
1. **Ao carregar a tela**:
|
|
||||||
- Hook busca categorias e caixas da API
|
|
||||||
- Dados são armazenados no state
|
|
||||||
- Loading state gerenciado automaticamente
|
|
||||||
|
|
||||||
2. **No Select de Caixas**:
|
|
||||||
- Sempre mostra "Todas as Caixas" como primeira opção
|
|
||||||
- Mapeia array de caixas da API
|
|
||||||
- Cada item usa `idcaixinhas_financeiro` como value
|
|
||||||
- Exibe `caixinha` como label
|
|
||||||
|
|
||||||
3. **Ao filtrar**:
|
|
||||||
- Compara `caixinha` do item com ID selecionado
|
|
||||||
- Atualiza KPIs, gráficos e tabelas em tempo real
|
|
||||||
- Contador mostra quantidade de registros filtrados
|
|
||||||
|
|
||||||
## 💡 Melhorias Implementadas
|
|
||||||
|
|
||||||
1. **Dados Reais**: Filtros agora usam dados reais do sistema
|
|
||||||
2. **Flexibilidade**: Suporta qualquer quantidade de caixas
|
|
||||||
3. **Manutenibilidade**: Não precisa atualizar código ao adicionar novas caixas
|
|
||||||
4. **UX**: Nomes reais das caixas ao invés de "Caixa 1", "Caixa 2"
|
|
||||||
5. **Preparado para Futuro**: Categorias já carregadas para filtros futuros
|
|
||||||
|
|
||||||
## 🔍 Observações Técnicas
|
|
||||||
|
|
||||||
1. **Campo `caixinha`**:
|
|
||||||
- Vem do extrato como `idcaixinhas_financeiro`
|
|
||||||
- Convertido para string para comparação
|
|
||||||
- Fallback para `item.caixinha` se já vier mapeado
|
|
||||||
|
|
||||||
2. **Performance**:
|
|
||||||
- Busca única ao montar o componente
|
|
||||||
- Dados cacheados no state
|
|
||||||
- Não refaz requisição a cada filtro
|
|
||||||
|
|
||||||
3. **Error Handling**:
|
|
||||||
- Try/catch nos useEffect
|
|
||||||
- Fallback para array vazio em caso de erro
|
|
||||||
- Console.error para debugging
|
|
||||||
|
|
||||||
## ✨ Resultado Final
|
|
||||||
|
|
||||||
Os cruzamentos agora possuem:
|
|
||||||
- ✅ Filtros dinâmicos de caixas (dados reais da API)
|
|
||||||
- ✅ Categorias carregadas (prontas para uso futuro)
|
|
||||||
- ✅ Nomes reais das caixas exibidos
|
|
||||||
- ✅ Suporte a qualquer quantidade de caixas
|
|
||||||
- ✅ Código limpo e manutenível
|
|
||||||
- ✅ Performance otimizada
|
|
||||||
- ✅ Error handling robusto
|
|
||||||
|
|
||||||
**Status**: 🎉 **IMPLEMENTAÇÃO 100% CONCLUÍDA E INTEGRADA COM A API!**
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📝 Próximos Passos Sugeridos (Opcional)
|
|
||||||
|
|
||||||
1. **Filtro de Categorias**: Adicionar Select de categorias nos filtros
|
|
||||||
2. **Filtro Combinado**: Permitir filtrar por múltiplas caixas simultaneamente
|
|
||||||
3. **Persistência**: Salvar filtros selecionados no localStorage
|
|
||||||
4. **Loading States**: Adicionar skeleton/spinner enquanto carrega caixas
|
|
||||||
5. **Validação**: Verificar se caixa selecionada ainda existe antes de filtrar
|
|
||||||
|
|
@ -1,221 +0,0 @@
|
||||||
# Padrões de Rotas de Apresentação (Back–Front)
|
|
||||||
|
|
||||||
**Objetivo**: Contrato único por rota de listagem: endpoint, resposta esperada e colunas sugeridas para o front.
|
|
||||||
**Uso**: Ao inserir ou alterar uma rota "apresentar", atualizar este documento; as views devem usar as colunas sugeridas aqui (ver comentário no código: "Ver docs/PADROES_ROTAS_APRESENTACAO.md § NomeDaRota").
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Ambiente: Prafrot (Prafrota)
|
|
||||||
|
|
||||||
### GET /cadastro_frota/apresentar
|
|
||||||
|
|
||||||
- **Descrição**: Lista veículos cadastrados na frota.
|
|
||||||
- **Service**: `prafrotService.getVehicles()`.
|
|
||||||
- **View**: Veículos / Status Frota.
|
|
||||||
|
|
||||||
**Resposta esperada**: array de objetos com campos, por exemplo:
|
|
||||||
`idveiculo_frota`, `placa`, `modelo`, `base`, `motorista`, `status`, `manutencao`, `atuacao`, `proprietario`, `vecfleet`, `obs`, `combustivel`, `tipo`, `marca`, `ano`, `cidade`, etc.
|
|
||||||
|
|
||||||
**Colunas sugeridas** (copiar para a view que usa ExcelTable):
|
|
||||||
```js
|
|
||||||
[
|
|
||||||
{ field: 'placa', header: 'Placa', width: '100px', className: 'font-mono font-bold text-emerald-600 dark:text-emerald-500' },
|
|
||||||
{ field: 'modelo', header: 'Modelo', width: '150px' },
|
|
||||||
{ field: 'base', header: 'Unidade', width: '120px' },
|
|
||||||
{ field: 'motorista', header: 'Motorista', width: '180px' },
|
|
||||||
{ field: 'status', header: 'Status', width: '140px' },
|
|
||||||
{ field: 'manutencao', header: 'Manutenção', width: '120px' },
|
|
||||||
{ field: 'atuacao', header: 'Atuação', width: '140px' },
|
|
||||||
{ field: 'proprietario', header: 'Proprietário', width: '140px' },
|
|
||||||
{ field: 'vecfleet', header: 'VecFleet', width: '140px' },
|
|
||||||
{ field: 'obs', header: 'OBS', width: '250px' }
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
**filterDefs sugeridos**: `[{ field: 'placa', label: 'Placa', type: 'text' }, { field: 'motorista', label: 'Motorista', type: 'text' }, { field: 'base', label: 'Unidade', type: 'select' }]`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### GET /manutencao_frota/apresentar
|
|
||||||
|
|
||||||
- **Descrição**: Lista todas as manutenções (total).
|
|
||||||
- **Service**: `prafrotService.getMaintenance()`.
|
|
||||||
- **View**: MaintenanceView (Manutenção).
|
|
||||||
|
|
||||||
**Resposta esperada**: array de objetos com campos:
|
|
||||||
`idmanutencao_frota`, `atendimento`, `placa`, `placa_reserva`, `modelo`, `oficina`, `base_frota`, `cidade`, `uf`, `proprietario`, `responsavel`, `motivo_atendimento`, `status`, `manutencao`, `status_frota_veiculo`, `data_solicitacao`, `data_agendamento`, `data_parada_veiculo`, `previcao_entrega`, `data_finalizacao`, `data_retirada`, `orcamento_inicial`, `orcamento_final`, `dif_orcamento`, `condicao_pagamento`, `validacao_financeiro`, `resp_aprovacao`, `sla_oficina`, `sla_pos_oficina`, `obs`, `endereco_prestador`, `pdf_orcamento`.
|
|
||||||
|
|
||||||
**Colunas sugeridas** (ver MaintenanceView.jsx – já alinhado):
|
|
||||||
```js
|
|
||||||
[
|
|
||||||
{ field: 'idmanutencao_frota', header: 'ID', width: '80px' },
|
|
||||||
{ field: 'atendimento', header: 'ATENDIMENTO', width: '100px' },
|
|
||||||
{ field: 'placa', header: 'PLACA', width: '100px', className: 'font-mono font-bold text-emerald-600 dark:text-emerald-500' },
|
|
||||||
{ field: 'placa_reserva', header: 'PLACA RESERVA', width: '100px' },
|
|
||||||
{ field: 'modelo', header: 'MODELO', width: '110px' },
|
|
||||||
{ field: 'oficina', header: 'OFICINA', width: '160px' },
|
|
||||||
{ field: 'base_frota', header: 'BASE FROTA', width: '100px' },
|
|
||||||
{ field: 'cidade', header: 'CIDADE', width: '120px' },
|
|
||||||
{ field: 'uf', header: 'UF', width: '60px' },
|
|
||||||
{ field: 'proprietario', header: 'PROPRIETÁRIO', width: '110px' },
|
|
||||||
{ field: 'responsavel', header: 'RESPONSÁVEL', width: '120px' },
|
|
||||||
{ field: 'motivo_atendimento', header: 'MOTIVO ATEND.', width: '120px' },
|
|
||||||
{ field: 'status', header: 'STATUS', width: '140px' },
|
|
||||||
{ field: 'manutencao', header: 'MANUTENÇÃO', width: '90px' },
|
|
||||||
{ field: 'status_frota_veiculo', header: 'STATUS FROTA', width: '120px' },
|
|
||||||
{ field: 'data_solicitacao', header: 'DATA SOLIC.', width: '100px' },
|
|
||||||
{ field: 'data_agendamento', header: 'DATA AGEND.', width: '100px' },
|
|
||||||
{ field: 'data_parada_veiculo', header: 'DATA PARADA', width: '100px' },
|
|
||||||
{ field: 'previcao_entrega', header: 'PREV. ENTREGA', width: '100px' },
|
|
||||||
{ field: 'data_finalizacao', header: 'DATA FINAL.', width: '100px' },
|
|
||||||
{ field: 'data_retirada', header: 'DATA RETIRADA', width: '100px' },
|
|
||||||
{ field: 'orcamento_inicial', header: 'ORÇ. INICIAL', width: '110px' },
|
|
||||||
{ field: 'orcamento_final', header: 'ORÇ. FINAL', width: '110px' },
|
|
||||||
{ field: 'dif_orcamento', header: 'DIF. ORÇ.', width: '100px' },
|
|
||||||
{ field: 'condicao_pagamento', header: 'COND. PAG.', width: '100px' },
|
|
||||||
{ field: 'validacao_financeiro', header: 'VALID. FINANC.', width: '110px' },
|
|
||||||
{ field: 'resp_aprovacao', header: 'RESP. APROV.', width: '110px' },
|
|
||||||
{ field: 'sla_oficina', header: 'SLA OFICINA', width: '100px' },
|
|
||||||
{ field: 'sla_pos_oficina', header: 'SLA PÓS-OF.', width: '100px' },
|
|
||||||
{ field: 'obs', header: 'OBS', width: '180px' },
|
|
||||||
{ field: 'endereco_prestador', header: 'END. PRESTADOR', width: '180px' },
|
|
||||||
{ field: 'pdf_orcamento', header: 'PDF ORÇAMENTO', width: '100px' }
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
**filterDefs sugeridos**: `[{ field: 'placa', label: 'Placa', type: 'text' }, { field: 'oficina', label: 'Oficina', type: 'select' }, { field: 'status', label: 'Status', type: 'select' }, { field: 'motivo_atendimento', label: 'Motivo Atendimento', type: 'select' }, { field: 'responsavel', label: 'Responsável', type: 'select' }, { field: 'cidade', label: 'Cidade', type: 'select' }]`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### GET /manutencao_frota/aberto_fechado/apresentar
|
|
||||||
|
|
||||||
- **Descrição**: Lista manutenções agrupadas em aberto/fechado.
|
|
||||||
- **Service**: `prafrotService.getAbertoFechado()`.
|
|
||||||
- **Uso**: Filtro na MaintenanceView (statusFilter: total | aberta | fechada).
|
|
||||||
|
|
||||||
**Resposta esperada**: estrutura com listas ou grupos `aberta` e `fechada` (ou array com campo de status). Formato exato depende do backend; a view filtra localmente se receber array único.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### GET /disponibilidade_frota/apresentar
|
|
||||||
|
|
||||||
- **Descrição**: Lista disponibilidade de veículos.
|
|
||||||
- **Service**: `prafrotService.getAvailability()`.
|
|
||||||
|
|
||||||
**Resposta esperada**: array de objetos; campos típicos a confirmar com o backend. Colunas sugeridas: espelhar campos retornados (ex.: `placa`, `disponivel`, `periodo`, etc.).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### GET /moki_frota/apresentar
|
|
||||||
|
|
||||||
- **Descrição**: Lista checklists Moki.
|
|
||||||
- **Service**: `prafrotService.getMoki()`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### GET /status_frota/apresentar
|
|
||||||
|
|
||||||
- **Descrição**: Lista status da frota.
|
|
||||||
- **Service**: `prafrotService.getStatus()`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### GET /monitoramento_frota/apresentar
|
|
||||||
|
|
||||||
- **Descrição**: Lista monitoramento.
|
|
||||||
- **Service**: `prafrotService.getMonitoring()`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### GET /sinistro_devolucao_venda_frota/apresentar
|
|
||||||
|
|
||||||
- **Descrição**: Lista sinistros/devoluções/vendas.
|
|
||||||
- **Service**: `prafrotService.getClaims()`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### GET /oficinas_frota/apresentar
|
|
||||||
|
|
||||||
- **Descrição**: Lista oficinas.
|
|
||||||
- **Service**: `prafrotService.getWorkshops()`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Ambiente: Workspace / Financeiro-v2
|
|
||||||
|
|
||||||
### GET /extrato/apresentar
|
|
||||||
|
|
||||||
- **Descrição**: Extrato bancário; filtrar por `tipoOperacao`: "C" = receitas, "D" = despesas.
|
|
||||||
- **Service**: `extratoService.fetchExtrato()`.
|
|
||||||
|
|
||||||
**Resposta esperada**: array de objetos com campos, por exemplo:
|
|
||||||
`idextrato`, `dataEntrada` (ou `data`), `descricao`, `valor`, `tipoOperacao`, `categoria`, `beneficiario_pagador` (ou `beneficiario`), `caixinha`, etc.
|
|
||||||
|
|
||||||
**Colunas sugeridas** (transações):
|
|
||||||
```js
|
|
||||||
[
|
|
||||||
{ field: 'data', header: 'Data', width: '120px' },
|
|
||||||
{ field: 'descricao', header: 'Descrição', width: '400px' },
|
|
||||||
{ field: 'valor', header: 'Valor', width: '150px' },
|
|
||||||
{ field: 'tipo', header: 'Tipo', width: '120px' },
|
|
||||||
{ field: 'status', header: 'Status', width: '120px' }
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### GET /categorias/apresentar
|
|
||||||
|
|
||||||
- **Descrição**: Lista categorias para conciliação/labels.
|
|
||||||
- **Service**: `extratoService.fetchCategorias()` ou `workspaceConciliacaoService`.
|
|
||||||
|
|
||||||
**Resposta esperada**: array de objetos (ex.: `id`, `nome`, `descricao`, `tipoMovimento`, `cor`).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### GET /caixinhas/apresentar
|
|
||||||
|
|
||||||
- **Descrição**: Lista caixinhas.
|
|
||||||
- **Service**: `extratoService.fetchCaixinhas()` ou `workspaceConciliacaoService`.
|
|
||||||
|
|
||||||
**Resposta esperada**: array de objetos (ex.: `id`, `nome`, `banco`, `agencia`, `conta`).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### GET /contas_a_pagar/apresentar
|
|
||||||
|
|
||||||
- **Descrição**: Contas a pagar planejadas.
|
|
||||||
- **Service**: `workspaceDespesasService` (ou equivalente).
|
|
||||||
|
|
||||||
**Resposta esperada**: array com campos do planejado (categoria, valor, data, etc.). Colunas sugeridas: espelhar campos retornados.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### GET /saldo/armazenado/apresentar
|
|
||||||
|
|
||||||
- **Descrição**: Saldos armazenados (histórico); usado para último saldo do mês anterior no fluxo de caixa.
|
|
||||||
- **Service**: `extratoService.fetchSaldoArmazenado()`.
|
|
||||||
|
|
||||||
**Resposta esperada**: array (ou objeto único) com `data_saldo`, `saldo_disponivel`, `mes`, `ano`, `idsaldos_mensais`, etc.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Ambiente: GR
|
|
||||||
|
|
||||||
### GET /cadastro/drivers/apresentar
|
|
||||||
|
|
||||||
- **Descrição**: Lista motoristas (cadastro).
|
|
||||||
- **Service**: `grService` (getRegistrations ou equivalente).
|
|
||||||
|
|
||||||
### GET /contrato/drivers/apresentar
|
|
||||||
|
|
||||||
- **Descrição**: Lista motoristas em contrato ativo.
|
|
||||||
- **Service**: `grService`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Como usar este documento
|
|
||||||
|
|
||||||
1. **Nova rota de apresentação**: adicione um bloco acima com endpoint, resposta esperada e colunas sugeridas; na view, use as colunas do doc e comente: `// Ver docs/PADROES_ROTAS_APRESENTACAO.md § NomeDaRota`.
|
|
||||||
2. **Backend mudou**: atualize a "Resposta esperada" e as "Colunas sugeridas" aqui; depois ajuste a view para manter alinhamento.
|
|
||||||
3. **Playground**: a seção "Rotas e Ambientes" pode exibir este documento por ambiente para gerenciamento visual.
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
# Prafrot – Manutenção: regras de backend
|
|
||||||
|
|
||||||
Regras que o **backend** deve implementar para alinhar com o frontend da tela de Manutenção (Prafrot).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. Garantir que, ao atualizar um registro, as datas não fiquem vazias
|
|
||||||
|
|
||||||
- **Rota**: `PUT /manutencao_frota/:id`
|
|
||||||
- **Regra**: ao receber um payload de atualização, **não sobrescrever** com valor vazio campos de data que já existem no registro.
|
|
||||||
- **Campos de data**: `data_solicitacao`, `data_agendamento`, `data_parada_veiculo`, `previcao_entrega`, `data_finalizacao`, `data_retirada`.
|
|
||||||
- **Comportamento esperado**: se o cliente envia `data_finalizacao: ""` ou omite o campo, o backend mantém o valor atual em banco. Apenas valores não vazios (ex.: `"2025-01-15"`) devem alterar o registro.
|
|
||||||
|
|
||||||
O frontend já preserva datas existentes ao montar o payload de edição; o backend deve seguir a mesma lógica para evitar limpar datas acidentalmente.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Validar que todas as datas estejam preenchidas antes de permitir fechar uma manutenção
|
|
||||||
|
|
||||||
- **Rota**: `PUT /manutencao_frota/fechar_manutencao/:id`
|
|
||||||
- **Regra**: **recusar** o fechamento (ex.: 400) se alguma das datas abaixo estiver vazia:
|
|
||||||
- `data_solicitacao`
|
|
||||||
- `data_agendamento`
|
|
||||||
- `data_parada_veiculo`
|
|
||||||
- `previcao_entrega`
|
|
||||||
- `data_finalizacao`
|
|
||||||
- `data_retirada`
|
|
||||||
- **Resposta sugerida**: mensagem clara indicando quais datas estão faltando (ex.: `"Não é possível fechar: preencha Data Solicitação, Data Finalização."`).
|
|
||||||
|
|
||||||
O frontend já valida essas mesmas datas antes de chamar o fechamento; a validação no backend é obrigatória para segurança e consistência.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Formatar campos de orçamento como moeda (backend)
|
|
||||||
|
|
||||||
- **Campos**: `orcamento_inicial`, `orcamento_final`, `dif_orcamento`.
|
|
||||||
- **Regra**: armazenar e expor **valores numéricos** (ex.: `1234.56`). O frontend formata em pt-BR (R$ 1.234,56) na exibição.
|
|
||||||
- **APIs**: aceitar número em `POST /manutencao_frota` e `PUT /manutencao_frota/:id`; retornar número nos JSONs de listagem e detalhe.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. Auto-preenchimento de datas no formulário (frontend)
|
|
||||||
|
|
||||||
O frontend já trata:
|
|
||||||
|
|
||||||
- Normalização de datas ao carregar para edição (ISO, `YYYY-MM-DD`, `DD/MM/YYYY` → `YYYY-MM-DD`).
|
|
||||||
- Uso de `type="date"` com valores normalizados para evitar campos vazios por formato incorreto.
|
|
||||||
|
|
||||||
O backend deve retornar datas em formato **ISO** ou **YYYY-MM-DD** quando possível, para facilitar o preenchimento correto no formulário.
|
|
||||||
|
|
@ -1,191 +0,0 @@
|
||||||
# ✅ Ajustes Implementados no Ambiente RH
|
|
||||||
|
|
||||||
## 📋 Resumo das Alterações
|
|
||||||
|
|
||||||
### 1. ✨ Novo Header Integrado
|
|
||||||
**Arquivo**: `src/features/rh/components/layout/RhHeader.jsx`
|
|
||||||
|
|
||||||
- ✅ Criado componente de cabeçalho similar ao Prafrota
|
|
||||||
- ✅ Botão de mudança de tema posicionado no extremo direito
|
|
||||||
- ✅ Campo de busca rápida (desktop)
|
|
||||||
- ✅ Ícone de notificações
|
|
||||||
- ✅ Animações suaves no hover dos botões
|
|
||||||
|
|
||||||
**Características**:
|
|
||||||
- Tema adaptativo (dark/light)
|
|
||||||
- Backdrop blur para efeito premium
|
|
||||||
- Ícones animados (rotação no hover)
|
|
||||||
- Design consistente com outros ambientes
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2. 🎨 Layout Otimizado
|
|
||||||
**Arquivo**: `src/features/rh/components/layout/RhLayout.jsx`
|
|
||||||
|
|
||||||
**Mudanças**:
|
|
||||||
- ✅ Integrado `RhHeader` no layout principal
|
|
||||||
- ✅ Removido margens excessivas que causavam corte de conteúdo
|
|
||||||
- ✅ Ajustado container para `flex-1` e `overflow-hidden`
|
|
||||||
- ✅ Melhor aproveitamento do espaço vertical
|
|
||||||
- ✅ Container de conteúdo com `rounded-2xl` para estética premium
|
|
||||||
|
|
||||||
**Antes**:
|
|
||||||
```jsx
|
|
||||||
<div style={{ marginRight: '20px', marginTop: '20px', marginBottom: '20px' }}>
|
|
||||||
<div className="rounded-[2rem]">
|
|
||||||
<Outlet />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
```
|
|
||||||
|
|
||||||
**Depois**:
|
|
||||||
```jsx
|
|
||||||
<RhHeader />
|
|
||||||
<div className="flex-1 flex flex-col p-4 md:p-6">
|
|
||||||
<div className="flex-1 rounded-2xl overflow-hidden flex flex-col">
|
|
||||||
<Outlet />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 3. 🔧 Sidebar Simplificada
|
|
||||||
**Arquivo**: `src/features/rh/components/layout/RhSidebar.jsx`
|
|
||||||
|
|
||||||
**Mudanças**:
|
|
||||||
- ✅ Removido botão de tema duplicado (agora apenas no header)
|
|
||||||
- ✅ Mantido apenas branding e informações do usuário no footer
|
|
||||||
- ✅ Interface mais limpa e focada
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 4. 📊 Tela de Colaboradores Corrigida
|
|
||||||
**Arquivo**: `src/features/rh/views/EmployeesView.jsx`
|
|
||||||
|
|
||||||
**Problemas Resolvidos**:
|
|
||||||
- ✅ **Conteúdo cortado**: Ajustado hierarquia de flex containers
|
|
||||||
- ✅ **Painel detalhado não aparecia**: Corrigido posicionamento absoluto
|
|
||||||
- ✅ **Overflow incorreto**: Implementado `overflow-auto` nos locais corretos
|
|
||||||
|
|
||||||
**Estrutura Corrigida**:
|
|
||||||
```jsx
|
|
||||||
<div className="flex-1 flex flex-col h-full w-full overflow-hidden">
|
|
||||||
{/* Header fixo */}
|
|
||||||
<div className="flex-shrink-0 h-16">...</div>
|
|
||||||
|
|
||||||
{/* Área de conteúdo com tabela e painel */}
|
|
||||||
<div className="flex-1 flex relative overflow-hidden">
|
|
||||||
{/* Tabela */}
|
|
||||||
<div className="flex-1 flex flex-col overflow-hidden">
|
|
||||||
<div className="flex-1 overflow-auto">
|
|
||||||
<ExcelTable />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Painel lateral (AnimatePresence) */}
|
|
||||||
<motion.div className="absolute right-0 top-0 bottom-0">
|
|
||||||
<EmployeeDetailPanel />
|
|
||||||
</motion.div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 5. 🔗 Exportação de Componentes
|
|
||||||
**Arquivo**: `src/components/shared/index.js`
|
|
||||||
|
|
||||||
**Mudanças**:
|
|
||||||
- ✅ Adicionado export do `ItemDetailPanel`
|
|
||||||
- ✅ Garantido acesso via `@/components/shared`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎯 Funcionalidades Implementadas
|
|
||||||
|
|
||||||
### Header RH
|
|
||||||
- [x] Busca rápida (visível em desktop)
|
|
||||||
- [x] Notificações com badge
|
|
||||||
- [x] Toggle de tema com animação
|
|
||||||
- [x] Suporte a dark/light mode
|
|
||||||
- [x] Backdrop blur premium
|
|
||||||
|
|
||||||
### Layout
|
|
||||||
- [x] Responsivo (mobile-first)
|
|
||||||
- [x] Sem cortes de conteúdo
|
|
||||||
- [x] Melhor aproveitamento de espaço
|
|
||||||
- [x] Transições suaves
|
|
||||||
|
|
||||||
### Painel Detalhado
|
|
||||||
- [x] Animação de entrada/saída
|
|
||||||
- [x] Backdrop em mobile
|
|
||||||
- [x] Posicionamento fixo correto
|
|
||||||
- [x] Scroll interno funcional
|
|
||||||
- [x] Abas de navegação
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🧪 Testes Recomendados
|
|
||||||
|
|
||||||
1. **Navegação**:
|
|
||||||
- [ ] Clicar em "Colaboradores" no menu
|
|
||||||
- [ ] Clicar em "Ponto Eletrônico" no menu
|
|
||||||
- [ ] Verificar se não há cortes de conteúdo
|
|
||||||
|
|
||||||
2. **Tema**:
|
|
||||||
- [ ] Alternar tema no header
|
|
||||||
- [ ] Verificar se todos os componentes adaptam corretamente
|
|
||||||
|
|
||||||
3. **Painel Detalhado**:
|
|
||||||
- [ ] Clicar no ícone de edição de um colaborador
|
|
||||||
- [ ] Verificar se o painel aparece com animação
|
|
||||||
- [ ] Testar scroll interno do painel
|
|
||||||
- [ ] Fechar o painel (botão X ou backdrop em mobile)
|
|
||||||
|
|
||||||
4. **Responsividade**:
|
|
||||||
- [ ] Testar em diferentes resoluções
|
|
||||||
- [ ] Verificar comportamento em mobile
|
|
||||||
- [ ] Confirmar que tabela não é cortada
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📝 Notas Técnicas
|
|
||||||
|
|
||||||
### Hierarquia de Containers
|
|
||||||
```
|
|
||||||
RhLayout
|
|
||||||
├── RhSidebar (fixed, z-index alto)
|
|
||||||
└── main (flex-1, ml ajustável)
|
|
||||||
├── RhHeader (sticky top-0)
|
|
||||||
└── Content Area (flex-1, p-4)
|
|
||||||
└── Rounded Container (flex-1, overflow-hidden)
|
|
||||||
└── <Outlet /> (Views)
|
|
||||||
└── EmployeesView
|
|
||||||
├── Header (flex-shrink-0)
|
|
||||||
└── Content (flex-1, relative)
|
|
||||||
├── Table (overflow-auto)
|
|
||||||
└── Panel (absolute, AnimatePresence)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Classes Importantes
|
|
||||||
- `flex-1`: Ocupa espaço disponível
|
|
||||||
- `overflow-hidden`: Previne scroll indesejado no pai
|
|
||||||
- `overflow-auto`: Permite scroll apenas onde necessário
|
|
||||||
- `flex-shrink-0`: Previne compressão de headers
|
|
||||||
- `relative/absolute`: Para posicionamento do painel
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Próximos Passos Sugeridos
|
|
||||||
|
|
||||||
1. Testar a funcionalidade de Ponto Eletrônico
|
|
||||||
2. Verificar se outros módulos do RH precisam de ajustes similares
|
|
||||||
3. Validar comportamento em diferentes navegadores
|
|
||||||
4. Adicionar testes automatizados para o layout
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Status**: ✅ Implementação Completa
|
|
||||||
**Data**: 17/01/2026
|
|
||||||
**Ambiente**: RH (Recursos Humanos)
|
|
||||||
|
|
@ -1,129 +0,0 @@
|
||||||
# Regras de Desenvolvimento - PRALOG (Integra Finance)
|
|
||||||
|
|
||||||
**Perfil**: Desenvolvedor Sênior Front-end | **Foco**: Automação e Reutilização
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Stack Técnico
|
|
||||||
|
|
||||||
- React 18 + Vite + JavaScript ES6+
|
|
||||||
- Shadcn UI + Tailwind CSS
|
|
||||||
- Zustand (global) + Context (módulos)
|
|
||||||
- Feature Folders modulares
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Regras Principais
|
|
||||||
|
|
||||||
### 1. **Sempre Pergunte o Ambiente**
|
|
||||||
Antes de qualquer alteração, pergunte qual ambiente (`rh`, `financeiro-v2`, `prafrota`, etc).
|
|
||||||
|
|
||||||
### 2. **Reutilizar Antes de Criar**
|
|
||||||
Use `node .agent/scripts/check-reuse.js [termo]` para buscar código existente.
|
|
||||||
|
|
||||||
### 3. **Isolamento Total**
|
|
||||||
- Componentes de um ambiente em `src/features/[ambiente]/components/`
|
|
||||||
- **Nunca** importe componentes privados entre ambientes
|
|
||||||
- Use `shared/` só para elementos universais
|
|
||||||
|
|
||||||
### 4. **Componentes: Produção + Dev**
|
|
||||||
- `[Nome].jsx` - produção (todos os ambientes)
|
|
||||||
- `[Nome].dev.jsx` - dev (só Playground)
|
|
||||||
- **Playground primeiro** - teste antes de usar em views
|
|
||||||
|
|
||||||
### 5. **Performance**
|
|
||||||
- Componentes < 150 linhas
|
|
||||||
- Lazy loading com `React.lazy()`
|
|
||||||
- `useMemo`/`useCallback` em tabelas/gráficos
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Estrutura
|
|
||||||
|
|
||||||
```
|
|
||||||
src/
|
|
||||||
├── components/ui/ # Shadcn (NÃO editar)
|
|
||||||
├── components/shared/ # Universais
|
|
||||||
├── features/[ambiente]/ # Isolados
|
|
||||||
│ ├── components/
|
|
||||||
│ ├── hooks/
|
|
||||||
│ ├── views/
|
|
||||||
│ └── [Nome]Service.js
|
|
||||||
├── hooks/ # Globais
|
|
||||||
├── services/ # API
|
|
||||||
└── utils/ # Formatadores
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Scripts de Automação
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Buscar código existente
|
|
||||||
node .agent/scripts/check-reuse.js [termo]
|
|
||||||
|
|
||||||
# Criar componente
|
|
||||||
node .agent/scripts/create-component.js [Nome] [ambiente?]
|
|
||||||
|
|
||||||
# Criar hook
|
|
||||||
node .agent/scripts/create-hook.js use[Nome] [ambiente?]
|
|
||||||
|
|
||||||
# Criar service
|
|
||||||
node .agent/scripts/create-service.js [Nome] [ambiente?]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Documentação**: `.agent/scripts/README.md`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Workflow
|
|
||||||
|
|
||||||
1. **Buscar** reutilização (`check-reuse.js`)
|
|
||||||
2. **Criar** service/hook/componente (scripts)
|
|
||||||
3. **Testar** no Playground
|
|
||||||
4. **Usar** em view
|
|
||||||
5. **Validar** (`npm run dev`)
|
|
||||||
|
|
||||||
**Workflow completo**: `.agent/workflows/create-feature.md` (use `/create-feature`)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Nunca Fazer
|
|
||||||
|
|
||||||
❌ Importar entre ambientes
|
|
||||||
❌ Componentes > 150 linhas
|
|
||||||
❌ Duplicar lógica
|
|
||||||
❌ Criar sem buscar reutilização
|
|
||||||
❌ Usar componente novo sem Playground
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Sempre Fazer
|
|
||||||
|
|
||||||
✅ Perguntar ambiente
|
|
||||||
✅ Buscar reutilização (`check-reuse.js`)
|
|
||||||
✅ Scripts de automação
|
|
||||||
✅ Playground primeiro
|
|
||||||
✅ Validar build
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Referências
|
|
||||||
|
|
||||||
- **Base**: `.agent/instructions/CORE_INSTRUCTIONS.md`
|
|
||||||
- **Reutilização**: `.agent/instructions/REUSE_AND_MODULARITY.md`
|
|
||||||
- **PRALOG**: `.agent/instructions/PRALOG_CORE_RULES.md`
|
|
||||||
- **Quick Ref**: `.agent/QUICK_REFERENCE.md`
|
|
||||||
- **Scripts**: `.agent/scripts/README.md`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Ambiente de Testes
|
|
||||||
|
|
||||||
**URL**: `https://dev.workspace.itguys.com.br/plataforma/`
|
|
||||||
**User**: `financeiro@pralog.com.br`
|
|
||||||
**Pass**: `123Mudar`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**IMPORTANTE**: Priorize automação, reutilização e isolamento. Use scripts para tarefas repetitivas.
|
|
||||||
|
|
@ -1,118 +0,0 @@
|
||||||
# 🧪 Teste Manual - Formulário de Cadastro de Motorista GR
|
|
||||||
|
|
||||||
## 📋 Objetivo
|
|
||||||
Verificar se o formulário está enviando corretamente os dados e imagens em formato binário para o endpoint `/api/cadastro/drivers/externo`.
|
|
||||||
|
|
||||||
## 🔧 Preparação
|
|
||||||
|
|
||||||
1. **Abra o navegador** em: https://dev.workspace.itguys.com.br/plataforma/cadastro-motorista
|
|
||||||
2. **Abra o DevTools** (F12 ou Ctrl+Shift+I)
|
|
||||||
3. **Vá para a aba Console** para ver os logs de debug
|
|
||||||
4. **Vá para a aba Network** e filtre por "Fetch/XHR"
|
|
||||||
|
|
||||||
## 📝 Passos do Teste
|
|
||||||
|
|
||||||
### Etapa 1: Identificação
|
|
||||||
1. Selecione "Como você deseja trabalhar": **Com meu veículo próprio**
|
|
||||||
2. Selecione "Tipo de Veículo": **Utilitário**
|
|
||||||
3. Preencha:
|
|
||||||
- Nome Completo: `Teste Motorista`
|
|
||||||
- CPF: `123.456.789-00`
|
|
||||||
- Telefone: `(21) 99999-9999`
|
|
||||||
- Data de Nascimento: `01/01/1990`
|
|
||||||
- CNH: `12345678900`
|
|
||||||
- Validade CNH: `31/12/2026`
|
|
||||||
- Placa do Veículo: `ABC1234`
|
|
||||||
- Modalidade: **Agregado**
|
|
||||||
- Nome Coordenador: `Teste Coordenador`
|
|
||||||
- E-mail: `teste@teste.com`
|
|
||||||
4. Clique em **Avançar**
|
|
||||||
|
|
||||||
### Etapa 2: Documentos
|
|
||||||
1. Anexe **qualquer imagem pequena** (pode ser a mesma para todos):
|
|
||||||
- CNH (FRENTE) ✅
|
|
||||||
- CNH (VERSO) ✅
|
|
||||||
- COMPROVANTE RESIDÊNCIA ✅
|
|
||||||
- DOCUMENTO DO VEÍCULO (CRLV) ✅
|
|
||||||
- CARTÃO CNPJ (MEI) ✅
|
|
||||||
2. Clique em **Avançar**
|
|
||||||
|
|
||||||
### Etapa 3: Dados Complementares
|
|
||||||
1. Preencha:
|
|
||||||
- CNPJ: `12.345.678/0001-00`
|
|
||||||
- CEP: `23059-650` (vai preencher automaticamente o endereço)
|
|
||||||
- Cidade: (preenchido automaticamente)
|
|
||||||
- Bairro: (preenchido automaticamente)
|
|
||||||
2. Clique em **Avançar**
|
|
||||||
|
|
||||||
### Etapa 4: Revisão e Envio
|
|
||||||
1. Marque a caixa: **"Li e concordo com os termos..."**
|
|
||||||
2. Clique em **Finalizar Cadastro**
|
|
||||||
|
|
||||||
## 🔍 O que Verificar
|
|
||||||
|
|
||||||
### No Console (aba Console do DevTools):
|
|
||||||
Você deve ver logs como:
|
|
||||||
```
|
|
||||||
GR Form: Iniciando submissão {nome_completo: "Teste Motorista", ...}
|
|
||||||
GR Form: Arquivo anexado - cnh_frente: imagem.jpg 12345 bytes
|
|
||||||
GR Form: Arquivo anexado - cnh_verso: imagem.jpg 12345 bytes
|
|
||||||
GR Form: Arquivo anexado - comprovante_residencia: imagem.jpg 12345 bytes
|
|
||||||
GR Form: Arquivo anexado - crlv: imagem.jpg 12345 bytes
|
|
||||||
GR Form: Arquivo anexado - cartao_cnpj: imagem.jpg 12345 bytes
|
|
||||||
GR Form: Total de arquivos anexados: 5
|
|
||||||
GR Form: Modo de envio: NOVO CADASTRO
|
|
||||||
GR Form: Resposta do servidor: {submission_id: "...", message: "..."}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Na aba Network:
|
|
||||||
1. Procure pela requisição para `/api/cadastro/drivers/externo`
|
|
||||||
2. Clique nela e vá para a aba **Payload** ou **Request**
|
|
||||||
3. Você deve ver:
|
|
||||||
- `dados_json`: (string JSON com os dados do formulário)
|
|
||||||
- `cnh_frente`: (binary)
|
|
||||||
- `cnh_verso`: (binary)
|
|
||||||
- `comprovante_residencia`: (binary)
|
|
||||||
- `crlv`: (binary)
|
|
||||||
- `cartao_cnpj`: (binary)
|
|
||||||
|
|
||||||
### ✅ Resultado Esperado
|
|
||||||
- Status da requisição: **200 OK** ou **201 Created**
|
|
||||||
- Mensagem de sucesso: **"Cadastro realizado com sucesso!"**
|
|
||||||
- Tela de confirmação aparece
|
|
||||||
|
|
||||||
### ❌ Se der erro
|
|
||||||
1. Copie o erro completo do Console
|
|
||||||
2. Copie a aba **Response** da requisição no Network
|
|
||||||
3. Tire um print da aba **Payload** mostrando o que foi enviado
|
|
||||||
4. Me envie essas informações
|
|
||||||
|
|
||||||
## 🐛 Problemas Conhecidos Corrigidos
|
|
||||||
- ✅ Arquivos agora são convertidos de FileList para Array
|
|
||||||
- ✅ Campos de arquivo removidos do JSON para evitar `{}`
|
|
||||||
- ✅ Logs de debug adicionados para rastreamento
|
|
||||||
- ✅ Import do useEffect corrigido
|
|
||||||
|
|
||||||
## 📊 Formato Esperado no Backend
|
|
||||||
|
|
||||||
**Correto (como deve estar agora):**
|
|
||||||
```
|
|
||||||
FormData {
|
|
||||||
dados_json: '{"nome_completo":"Teste","cpf":"123.456.789-00",...}',
|
|
||||||
cnh_frente: File (binary),
|
|
||||||
cnh_verso: File (binary),
|
|
||||||
comprovante_residencia: File (binary),
|
|
||||||
crlv: File (binary),
|
|
||||||
cartao_cnpj: File (binary)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Incorreto (problema anterior):**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"dados_json": "{...}",
|
|
||||||
"cnh_frente": {},
|
|
||||||
"cnh_verso": {},
|
|
||||||
...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
@ -1,156 +0,0 @@
|
||||||
{
|
|
||||||
"ambiente": "prafrot",
|
|
||||||
"label": "Prafrot (Prafrota)",
|
|
||||||
"recursoBase": "/cadastro_frota",
|
|
||||||
"rotas": [
|
|
||||||
{
|
|
||||||
"id": "cadastro_frota-listar",
|
|
||||||
"recurso": "cadastro_frota",
|
|
||||||
"operations": [
|
|
||||||
{
|
|
||||||
"method": "GET",
|
|
||||||
"path": "/cadastro_frota/apresentar",
|
|
||||||
"descricao": "Lista veículos cadastrados na frota",
|
|
||||||
"responseShape": [
|
|
||||||
{ "field": "idveiculo_frota", "type": "number", "description": "ID do veículo" },
|
|
||||||
{ "field": "placa", "type": "string", "description": "Placa" },
|
|
||||||
{ "field": "modelo", "type": "string", "description": "Modelo" },
|
|
||||||
{ "field": "base", "type": "string", "description": "Unidade/Base" },
|
|
||||||
{ "field": "motorista", "type": "string", "description": "Motorista" },
|
|
||||||
{ "field": "status", "type": "string", "description": "Status" },
|
|
||||||
{ "field": "manutencao", "type": "string", "description": "Manutenção" },
|
|
||||||
{ "field": "atuacao", "type": "string", "description": "Atuação" },
|
|
||||||
{ "field": "proprietario", "type": "string", "description": "Proprietário" },
|
|
||||||
{ "field": "obs", "type": "string", "description": "Observações" }
|
|
||||||
],
|
|
||||||
"suggestedColumns": [
|
|
||||||
{ "field": "placa", "header": "Placa", "width": "100px" },
|
|
||||||
{ "field": "modelo", "header": "Modelo", "width": "150px" },
|
|
||||||
{ "field": "base", "header": "Unidade", "width": "120px" },
|
|
||||||
{ "field": "motorista", "header": "Motorista", "width": "180px" },
|
|
||||||
{ "field": "status", "header": "Status", "width": "140px" }
|
|
||||||
],
|
|
||||||
"filterDefs": [
|
|
||||||
{ "field": "placa", "label": "Placa", "type": "text" },
|
|
||||||
{ "field": "motorista", "label": "Motorista", "type": "text" },
|
|
||||||
{ "field": "base", "label": "Unidade", "type": "select" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"method": "GET",
|
|
||||||
"path": "/cadastro_frota/:id",
|
|
||||||
"descricao": "Detalhe de um veículo",
|
|
||||||
"responseShape": [
|
|
||||||
{ "field": "idveiculo_frota", "type": "number", "description": "ID" },
|
|
||||||
{ "field": "placa", "type": "string", "description": "Placa" },
|
|
||||||
{ "field": "modelo", "type": "string", "description": "Modelo" },
|
|
||||||
{ "field": "chassi", "type": "string", "description": "Chassi" },
|
|
||||||
{ "field": "ano_fabricacao", "type": "number", "description": "Ano fabricação" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"method": "POST",
|
|
||||||
"path": "/cadastro_frota",
|
|
||||||
"descricao": "Criar novo veículo",
|
|
||||||
"requestBody": [
|
|
||||||
{ "field": "placa", "type": "string", "required": true },
|
|
||||||
{ "field": "modelo", "type": "string", "required": true },
|
|
||||||
{ "field": "base", "type": "string", "required": false }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"method": "PUT",
|
|
||||||
"path": "/cadastro_frota/:id",
|
|
||||||
"descricao": "Atualizar veículo",
|
|
||||||
"requestBody": [
|
|
||||||
{ "field": "placa", "type": "string", "required": false },
|
|
||||||
{ "field": "modelo", "type": "string", "required": false },
|
|
||||||
{ "field": "status", "type": "string", "required": false }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "manutencao_frota-listar",
|
|
||||||
"recurso": "manutencao_frota",
|
|
||||||
"operations": [
|
|
||||||
{
|
|
||||||
"method": "GET",
|
|
||||||
"path": "/manutencao_frota/apresentar",
|
|
||||||
"descricao": "Lista todas as manutenções",
|
|
||||||
"responseShape": [
|
|
||||||
{ "field": "idmanutencao_frota", "type": "number", "description": "ID manutenção" },
|
|
||||||
{ "field": "atendimento", "type": "string", "description": "Nº atendimento" },
|
|
||||||
{ "field": "placa", "type": "string", "description": "Placa" },
|
|
||||||
{ "field": "modelo", "type": "string", "description": "Modelo" },
|
|
||||||
{ "field": "oficina", "type": "string", "description": "Oficina" },
|
|
||||||
{ "field": "status", "type": "string", "description": "Status" },
|
|
||||||
{ "field": "data_solicitacao", "type": "string", "description": "Data solicitação" },
|
|
||||||
{ "field": "data_finalizacao", "type": "string", "description": "Data finalização" },
|
|
||||||
{ "field": "orcamento_inicial", "type": "number", "description": "Orçamento inicial" },
|
|
||||||
{ "field": "orcamento_final", "type": "number", "description": "Orçamento final" }
|
|
||||||
],
|
|
||||||
"suggestedColumns": [
|
|
||||||
{ "field": "idmanutencao_frota", "header": "ID", "width": "80px" },
|
|
||||||
{ "field": "placa", "header": "PLACA", "width": "100px" },
|
|
||||||
{ "field": "modelo", "header": "MODELO", "width": "110px" },
|
|
||||||
{ "field": "oficina", "header": "OFICINA", "width": "160px" },
|
|
||||||
{ "field": "status", "header": "STATUS", "width": "140px" }
|
|
||||||
],
|
|
||||||
"filterDefs": [
|
|
||||||
{ "field": "placa", "label": "Placa", "type": "text" },
|
|
||||||
{ "field": "oficina", "label": "Oficina", "type": "select" },
|
|
||||||
{ "field": "status", "label": "Status", "type": "select" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"method": "GET",
|
|
||||||
"path": "/manutencao_frota/:id",
|
|
||||||
"descricao": "Detalhe de uma manutenção",
|
|
||||||
"responseShape": [
|
|
||||||
{ "field": "idmanutencao_frota", "type": "number", "description": "ID" },
|
|
||||||
{ "field": "placa", "type": "string", "description": "Placa" },
|
|
||||||
{ "field": "oficina", "type": "string", "description": "Oficina" },
|
|
||||||
{ "field": "status", "type": "string", "description": "Status" },
|
|
||||||
{ "field": "orcamento_final", "type": "number", "description": "Orçamento final" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"method": "POST",
|
|
||||||
"path": "/manutencao_frota",
|
|
||||||
"descricao": "Criar nova manutenção",
|
|
||||||
"requestBody": [
|
|
||||||
{ "field": "placa", "type": "string", "required": true },
|
|
||||||
{ "field": "oficina", "type": "string", "required": true },
|
|
||||||
{ "field": "motivo_atendimento", "type": "string", "required": false }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"method": "PUT",
|
|
||||||
"path": "/manutencao_frota/:id",
|
|
||||||
"descricao": "Atualizar manutenção",
|
|
||||||
"requestBody": [
|
|
||||||
{ "field": "status", "type": "string", "required": false },
|
|
||||||
{ "field": "data_finalizacao", "type": "string", "required": false },
|
|
||||||
{ "field": "orcamento_final", "type": "number", "required": false }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "disponibilidade_frota",
|
|
||||||
"recurso": "disponibilidade_frota",
|
|
||||||
"operations": [
|
|
||||||
{
|
|
||||||
"method": "GET",
|
|
||||||
"path": "/disponibilidade_frota/apresentar",
|
|
||||||
"descricao": "Lista disponibilidade de veículos",
|
|
||||||
"responseShape": [
|
|
||||||
{ "field": "placa", "type": "string", "description": "Placa" },
|
|
||||||
{ "field": "disponivel", "type": "boolean", "description": "Disponível" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
{
|
|
||||||
"ambiente": "workspace",
|
|
||||||
"label": "Workspace",
|
|
||||||
"rotas": [
|
|
||||||
{
|
|
||||||
"id": "extrato-listar",
|
|
||||||
"recurso": "extrato",
|
|
||||||
"operations": [
|
|
||||||
{
|
|
||||||
"method": "GET",
|
|
||||||
"path": "/extrato/apresentar",
|
|
||||||
"descricao": "Extrato bancário; filtrar por tipoOperacao C=receitas, D=despesas",
|
|
||||||
"responseShape": [
|
|
||||||
{ "field": "idextrato", "type": "number", "description": "ID transação" },
|
|
||||||
{ "field": "data", "type": "string", "description": "Data" },
|
|
||||||
{ "field": "descricao", "type": "string", "description": "Descrição" },
|
|
||||||
{ "field": "valor", "type": "number", "description": "Valor" },
|
|
||||||
{ "field": "tipoOperacao", "type": "string", "description": "C ou D" },
|
|
||||||
{ "field": "beneficiario_pagador", "type": "string", "description": "Beneficiário/Pagador" }
|
|
||||||
],
|
|
||||||
"suggestedColumns": [
|
|
||||||
{ "field": "data", "header": "Data", "width": "120px" },
|
|
||||||
{ "field": "descricao", "header": "Descrição", "width": "400px" },
|
|
||||||
{ "field": "valor", "header": "Valor", "width": "150px" },
|
|
||||||
{ "field": "tipo", "header": "Tipo", "width": "120px" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "categorias-listar",
|
|
||||||
"recurso": "categorias",
|
|
||||||
"operations": [
|
|
||||||
{
|
|
||||||
"method": "GET",
|
|
||||||
"path": "/categorias/apresentar",
|
|
||||||
"descricao": "Lista categorias para conciliação",
|
|
||||||
"responseShape": [
|
|
||||||
{ "field": "id", "type": "number", "description": "ID categoria" },
|
|
||||||
{ "field": "nome", "type": "string", "description": "Nome" },
|
|
||||||
{ "field": "descricao", "type": "string", "description": "Descrição" },
|
|
||||||
{ "field": "tipoMovimento", "type": "string", "description": "Entrada/Saída" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "caixinhas-listar",
|
|
||||||
"recurso": "caixinhas",
|
|
||||||
"operations": [
|
|
||||||
{
|
|
||||||
"method": "GET",
|
|
||||||
"path": "/caixinhas/apresentar",
|
|
||||||
"descricao": "Lista caixinhas",
|
|
||||||
"responseShape": [
|
|
||||||
{ "field": "id", "type": "number", "description": "ID" },
|
|
||||||
{ "field": "nome", "type": "string", "description": "Nome" },
|
|
||||||
{ "field": "banco", "type": "string", "description": "Banco" },
|
|
||||||
{ "field": "agencia", "type": "string", "description": "Agência" },
|
|
||||||
{ "field": "conta", "type": "string", "description": "Conta" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "contas_a_pagar-listar",
|
|
||||||
"recurso": "contas_a_pagar",
|
|
||||||
"operations": [
|
|
||||||
{
|
|
||||||
"method": "GET",
|
|
||||||
"path": "/contas_a_pagar/apresentar",
|
|
||||||
"descricao": "Contas a pagar planejadas",
|
|
||||||
"responseShape": [
|
|
||||||
{ "field": "id", "type": "number", "description": "ID" },
|
|
||||||
{ "field": "categoria", "type": "string", "description": "Categoria" },
|
|
||||||
{ "field": "valor", "type": "number", "description": "Valor" },
|
|
||||||
{ "field": "data", "type": "string", "description": "Data" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,107 +0,0 @@
|
||||||
# Guia de Integração Frontend-Backend: Módulo GR Operações
|
|
||||||
|
|
||||||
Este documento serve como guia técnico para o desenvolvimento da API backend que alimentará o novo módulo de GR Operações. O frontend foi construído de forma modular, utilizando uma camada de abstração que permite alternar entre dados simulados (mocks) e a API real através de uma flag.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. Arquitetura do Frontend
|
|
||||||
|
|
||||||
O frontend segue um padrão de 3 camadas:
|
|
||||||
1. **Views (React Components):** Interface do usuário. Não conhecem a origem dos dados.
|
|
||||||
2. **Hooks (useXXX):** Encapsulam a lógica de negócio, caching básico e chamadas aos services.
|
|
||||||
3. **Services (xxxService):** Camada de comunicação com a rede (Fetch/Axios). Contêm a lógica de Mock.
|
|
||||||
|
|
||||||
### Como ativar a API Real
|
|
||||||
Em cada arquivo dentro de `src/features/gr/services/`, existe uma constante:
|
|
||||||
```javascript
|
|
||||||
const USE_MOCK = true; // Altere para false para usar a API real
|
|
||||||
const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:3000';
|
|
||||||
```
|
|
||||||
Basta alterar `USE_MOCK` para `false` e configurar a URL da sua API no arquivo `.env`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Contratos da API (Endpoints Esperados)
|
|
||||||
|
|
||||||
Abaixo estão os endpoints que os Services já tentam chamar quando `USE_MOCK = false`.
|
|
||||||
|
|
||||||
### 🚨 2.1 Monitoramento de Viagens
|
|
||||||
- **GET** `/api/gr/monitoring/requests`
|
|
||||||
- **Filtros (Query):** `status` (PENDING, LIBERADO, EM_ROTA, FINALIZADO)
|
|
||||||
- **POST** `/api/gr/monitoring/request/:id/attend`
|
|
||||||
- **Ação:** Marca supervisor como responsável pela análise.
|
|
||||||
- **POST** `/api/gr/monitoring/request/:id/approve`
|
|
||||||
- **Payload:** `{ cargoValue, cte, ae, pallet, routeImageUrl, customMessage }`
|
|
||||||
|
|
||||||
### 🛰️ 2.2 Telemetria e Rastreamento
|
|
||||||
- **GET** `/api/gr/telemetry/positions`
|
|
||||||
- **Retorno:** Array de veículos com `plate, lat, lng, speed, riskStatus, alert`.
|
|
||||||
- **GET** `/api/gr/telemetry/history/:plate`
|
|
||||||
- **Retorno:** Array de posições históricas (lat, lng, timestamp, speed).
|
|
||||||
|
|
||||||
### 📋 2.3 Checklist e Manutenção
|
|
||||||
- **GET** `/api/gr/checklist/vehicles`
|
|
||||||
- **Filtros:** `client`
|
|
||||||
- **POST** `/api/gr/checklist/renew/:id`
|
|
||||||
- **Ação:** Estende validade do checklist.
|
|
||||||
- **GET** `/api/gr/maintenance/orders`
|
|
||||||
- **Filtros:** `vehicleId`
|
|
||||||
- **POST** `/api/gr/maintenance/orders`
|
|
||||||
- **Payload:** `{ vehicleId, type, sensor, description }`
|
|
||||||
|
|
||||||
### 📄 2.4 Gestão de Documentos
|
|
||||||
- **GET** `/api/gr/documents`
|
|
||||||
- **Filtros:** `entityType` (MOTORISTA, VEÍCULO), `docType` (CNH, CRLV)
|
|
||||||
- **POST** `/api/gr/documents` (**Multipart/Form-Data**)
|
|
||||||
- **Payload:** `file, client, entityType, entityName, docType`
|
|
||||||
- **DELETE** `/api/gr/documents/:id`
|
|
||||||
|
|
||||||
### 📊 2.5 Planilhas e Importação
|
|
||||||
- **GET** `/api/gr/spreadsheets`
|
|
||||||
- **Filtros:** `clientId, archived` (boolean)
|
|
||||||
- **POST** `/api/gr/spreadsheets/import`
|
|
||||||
- **Payload:** `{ clientId, rows: [...] }`
|
|
||||||
- **PATCH** `/api/gr/spreadsheets/:id/archive`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Modelos de Dados (Exemplos JSON)
|
|
||||||
|
|
||||||
### Objeto de Solicitação de Monitoramento
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "uuid",
|
|
||||||
"driverName": "String",
|
|
||||||
"plate": "AAA-0000",
|
|
||||||
"status": "PENDING",
|
|
||||||
"riskLevel": "LOW | MEDIUM | HIGH",
|
|
||||||
"cargoValue": 0,
|
|
||||||
"origin": "Cidade - UF",
|
|
||||||
"destination": "Cidade - UF"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Objeto de Telemetria
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "uuid",
|
|
||||||
"plate": "AAA-0000",
|
|
||||||
"lat": -22.90,
|
|
||||||
"lng": -43.17,
|
|
||||||
"speed": 80,
|
|
||||||
"riskStatus": "NORMAL | CRITICAL",
|
|
||||||
"alert": "EXCESS_SPEED | NO_SIGNAL"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ⚡ 4. WebSockets (Socket.io)
|
|
||||||
|
|
||||||
O frontend está preparado para ouvir os seguintes eventos para atualizações em tempo real:
|
|
||||||
- `monitoring-update`: Quando uma nova solicitação chega.
|
|
||||||
- `positions-update`: Quando as posições de telemetria mudam.
|
|
||||||
- `request-approved`: Quando o status de uma viagem muda para LIBERADO.
|
|
||||||
|
|
||||||
---
|
|
||||||
*Documento gerado para auxiliar o time de backend na migração do módulo GR.*
|
|
||||||
|
|
@ -1,208 +0,0 @@
|
||||||
# Relatório Zentulo System Deep Dive: Análise Técnica e Funcional
|
|
||||||
|
|
||||||
Este documento apresenta uma análise detalhada da arquitetura, lógica de negócios e fluxos operacionais do Sistema Zentulo, um ambiente de análise e simulação para a plataforma Zentulo.
|
|
||||||
|
|
||||||
## 1. Visão Geral da Arquitetura
|
|
||||||
|
|
||||||
O sistema Zentulo utiliza uma arquitetura **Híbrida Web/Electron**, projetada para operar tanto em navegadores quanto em ambiente desktop com permissões estendidas de sistema de arquivos.
|
|
||||||
|
|
||||||
* **Frontend:** React com Tailwind CSS.
|
|
||||||
* **Comunicação:** REST API e WebSockets (Socket.io) para atualizações em tempo real.
|
|
||||||
* **Persistência Local:** `localStorage` com lógica de sincronização offline personalizada.
|
|
||||||
* **Integração Nativa:** Electron Bridge (`window.electronAPI`) para processamento de arquivos XML locais e automação do Outlook.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Fluxos Visuais (Mermaid.js)
|
|
||||||
|
|
||||||
### Fluxo 1: Ciclo de Vida da Solicitação de Liberação
|
|
||||||
O coração do sistema é o fluxo de solicitações feitas por motoristas e aprovadas pela central de monitoramento.
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
|
||||||
participant M as Motorista (Portal)
|
|
||||||
participant S as Socket.io / API
|
|
||||||
participant C as Central (Painel Monitoramento)
|
|
||||||
|
|
||||||
M->>S: Envia Solicitação (Placa, Operação, CTe/NF)
|
|
||||||
S-->>C: Notificação Real-time (monitoring-update)
|
|
||||||
C->>C: Supervisor clica em "Atender"
|
|
||||||
Note right of C: Status muda para "ANÁLISE"
|
|
||||||
C-->>M: Notificação: "Solicitação Atendida"
|
|
||||||
C->>C: Validação de Perímetro/SST/Fiscal
|
|
||||||
C->>S: Clica em "Aprovar" (Envia Rota/Mensagem)
|
|
||||||
S-->>M: Notificação: "LIBERADO" (Verde)
|
|
||||||
M->>M: Clica em "Saí em Rota"
|
|
||||||
Note left of M: Status muda para "EM ROTA"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Fluxo 2: Processamento Fiscal e Automação de E-mail
|
|
||||||
Este fluxo descreve como o sistema extrai dados de documentos fiscais sem intervenção manual pesada.
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
graph TD
|
|
||||||
A[Outlook Automation] -->|Electron Select Folder| B[Download XMLs]
|
|
||||||
B --> C{Tipo de Documento?}
|
|
||||||
C -->|NF-e| D[FiscalAnalysis Component]
|
|
||||||
C -->|CT-e / MDF-e| E[CTE Component]
|
|
||||||
D -->|window.electronAPI.processFiscal| F[Validação contra Regras de Negócio]
|
|
||||||
E -->|window.electronAPI.processCTEs| G[Validação de CTE / MDF-e]
|
|
||||||
F --> H[Relatório de Divergências]
|
|
||||||
G --> I[Log de Processamento e Auditoria]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Fluxo 3: Sincronização Offline de Documentos
|
|
||||||
O sistema garante que motoristas possam salvar comprovantes mesmo em áreas de sombra de sinal.
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
graph LR
|
|
||||||
A[Upload do Arquivo] --> B{Conexão Online?}
|
|
||||||
B -- Não --> C[Salva em localStorage 'pending_sync']
|
|
||||||
B -- Sim --> D[Envia para /api/documents]
|
|
||||||
C --> E[Monitora Evento 'online']
|
|
||||||
E --> F[syncPending Utility]
|
|
||||||
F --> D
|
|
||||||
D --> G[Cria Registro na Gestão de Documentos]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Fluxo 4: Importação de Planilhas (Excel)
|
|
||||||
O sistema permite popular cadastros em massa via processamento local de arquivos `.xlsx`.
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
graph TD
|
|
||||||
A[Selecionar Arquivo .xlsx] --> B[FileReader.readAsBinaryString]
|
|
||||||
B --> C[XLSX.read Parser]
|
|
||||||
C --> D[Mapeamento de Colunas Dinâmico]
|
|
||||||
D --> E{Motorista Válido?}
|
|
||||||
E -->|Sim| F[Lista de Prévia para Conferência]
|
|
||||||
E -->|Não| G[Alerta de Erro de Formato]
|
|
||||||
F --> H[Loop: POST /api/drivers]
|
|
||||||
H --> I[Atualização Local da UI]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Fluxo 5: Sistema de Telemetria e Rastreamento
|
|
||||||
Monitoramento em tempo real de veículos com integração a provedores externos.
|
|
||||||
|
|
||||||
```mermaid
|
|
||||||
sequenceDiagram
|
|
||||||
participant W as Worker (30s polling)
|
|
||||||
participant T as T4S API
|
|
||||||
participant S as Sascar API
|
|
||||||
participant DB as TelemetryDB (Memória)
|
|
||||||
participant IO as Socket.io
|
|
||||||
participant C as Cliente (Dashboard)
|
|
||||||
|
|
||||||
loop A cada 30 segundos
|
|
||||||
W->>T: Bulk Fetch (PRALOG + PETY)
|
|
||||||
T-->>W: Array de Posições
|
|
||||||
W->>S: Bulk Fetch (Se credenciais configuradas)
|
|
||||||
S-->>W: Array de Posições
|
|
||||||
W->>W: Normalização de Dados
|
|
||||||
W->>W: Validação Geofence (lat > -21.0?)
|
|
||||||
W->>W: Validação Velocidade (> 90 km/h?)
|
|
||||||
W->>DB: Atualiza Posições + Histórico
|
|
||||||
W->>IO: Emit 'positions-update'
|
|
||||||
IO-->>C: Atualização Real-time
|
|
||||||
end
|
|
||||||
|
|
||||||
Note over W,C: Alertas: FORA_DA_ROTA, EXCESS_SPEED, SIGNAL_LOST
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Análise Detalhada dos Módulos
|
|
||||||
|
|
||||||
### 3.1 Painel de Monitoramento
|
|
||||||
* **Lógica de Status:** Transições coordenadas entre *Pending* -> *Analysis* -> *Approved* -> *In Progress* -> *Arrived*.
|
|
||||||
* **Validação de Rota:** Contém lógica específica para impedir rotas pela "Avenida Brasil" dependendo do valor da carga e destino, a menos que o destino seja na própria avenida.
|
|
||||||
* **Integração Real-time:** Uso intensivo de WebSockets para sincronizar os estados entre o supervisor e o motorista instantaneamente.
|
|
||||||
|
|
||||||
### 3.2 Gestão de Checklists e Manutenção
|
|
||||||
* **Auto-Renovação:** Implementa uma regra de +30 dias de validade ao renovar um checklist básico.
|
|
||||||
* **Cálculo de Status:** Status dinâmico (Válido, Alerta, Expirado) calculado em tempo real com base na data atual e datas de expiração.
|
|
||||||
* **Ordens de Serviço (OS):** Suporta criação de OS manuais ou automáticas (baseadas em sequencial interno).
|
|
||||||
|
|
||||||
### 3.3 Cadastro e Gestão de Documentos
|
|
||||||
* **Importação (Planilhas):** Utiliza a biblioteca `xlsx` para parsing de arquivos Excel. Possui lógica de mapeamento inteligente que busca por variações de nomes de colunas (ex: "Motoristas", "Nome", "CPF").
|
|
||||||
* **Hierarquia de Documentos:** Documentos são vinculados a Entidades (MOTORISTA ou CAVALO/VEÍCULO). Salvar um novo documento do mesmo tipo (ex: CRLV) substitui logicamente o anterior.
|
|
||||||
* **Módulo de Planilhas:** Existe uma rota dedicada (`/spreadsheets`) que se integra ao sistema de sincronização offline, permitindo a gestão de documentos de planilha associados à operação.
|
|
||||||
|
|
||||||
### 3.4 Administração e Segurança (RBAC)
|
|
||||||
* **Níveis de Acesso:** DEV, SUPERVISOR, GR, MONITORAMENTO.
|
|
||||||
* **Restrições de Hierarquia:** O código impede que usuários com nível SUPERVISOR editem ou excluam usuários com nível DEV.
|
|
||||||
* **Configuração de E-mail:** O e-mail de cadastro do usuário é a "chave" para as integrações de Outlook, servindo como credencial para a automação Electron.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. Backend e Infraestrutura
|
|
||||||
|
|
||||||
### 4.1 Arquitetura do Backend
|
|
||||||
* **Stack:** Node.js + Express.js
|
|
||||||
* **Banco de Dados:** MongoDB Atlas (`mongodb+srv://pralog:pralog123@cluster0.aobkjaq.mongodb.net/pralog`)
|
|
||||||
* **Comunicação Real-time:** Socket.io v4.8.1
|
|
||||||
* **Autenticação:** JWT (jsonwebtoken) + bcrypt para hash de senhas
|
|
||||||
* **Segurança:** Helmet.js, express-rate-limit, CORS configurado
|
|
||||||
|
|
||||||
### 4.2 Sistema de Telemetria e Rastreamento
|
|
||||||
O sistema possui integração nativa com dois provedores de rastreamento veicular:
|
|
||||||
|
|
||||||
#### Integração T4S
|
|
||||||
* **Contas Configuradas:** PRALOG e PETY
|
|
||||||
* **Endpoint:** `https://integracaov2.t4stecnologia.com.br/api`
|
|
||||||
* **Autenticação:** Bearer Token com cache de 50 minutos
|
|
||||||
* **Polling:** A cada 30 segundos (configurável)
|
|
||||||
* **Dados Capturados:** Placa, lat/lng, velocidade, ignição, endereço, timestamp
|
|
||||||
|
|
||||||
#### Integração Sascar
|
|
||||||
* **Status:** Estrutura pronta, aguardando credenciais
|
|
||||||
* **Normalização:** Converte dados brutos para formato unificado
|
|
||||||
* **Fallback:** Retorna array vazio se credenciais não configuradas
|
|
||||||
|
|
||||||
#### Geofencing e Alertas Automáticos
|
|
||||||
* **Cerca Eletrônica:** Validação de latitude (alerta se `lat > -21.0`)
|
|
||||||
* **Alerta de Velocidade:** Dispara se velocidade > 90 km/h
|
|
||||||
* **Níveis de Risco:**
|
|
||||||
* `NORMAL` - Operação dentro dos parâmetros
|
|
||||||
* `HIGH` - Excesso de velocidade
|
|
||||||
* `CRITICAL` - Fora da rota autorizada
|
|
||||||
* **Perda de Sinal:** Monitora veículos sem atualização por > 5 minutos
|
|
||||||
* **Histórico:** Mantém últimas 50 posições em memória por veículo
|
|
||||||
|
|
||||||
### 4.3 Gestão de Planilhas (SpreadsheetData)
|
|
||||||
* **Clientes Suportados:** IMPERIO, ORTOBOM_RJ, ORTOBOM_SP, LIBFARMA
|
|
||||||
* **Funcionalidades:**
|
|
||||||
* Importação de dados via biblioteca `xlsx`
|
|
||||||
* Arquivamento de registros antigos
|
|
||||||
* Queries por `clientId` e status de arquivamento
|
|
||||||
* **Script de Verificação:** `check-spreadsheet.js` para auditoria de dados
|
|
||||||
|
|
||||||
### 4.4 Sistema de Auto-Update
|
|
||||||
* **Provedor:** GitHub Releases
|
|
||||||
* **Repositório:** `itguys/pralog-server`
|
|
||||||
* **Diretório de Cache:** `zentulo-systems-updater`
|
|
||||||
* **Componente Frontend:** `VersionChecker` + `ElectronUpdater`
|
|
||||||
* **Fluxo:** Verifica → Baixa → Notifica Usuário → Instala ao Reiniciar
|
|
||||||
|
|
||||||
### 4.5 Processamento de Arquivos
|
|
||||||
* **Upload:** Multer v2.0.2 para multipart/form-data
|
|
||||||
* **PDF:** Parsing com `pdf-parse` e geração com `pdfkit`
|
|
||||||
* **Excel:** Leitura e escrita com `xlsx` v0.18.5
|
|
||||||
* **Compressão:** Middleware `compression` para otimizar tráfego
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. Gaps e Pontos de Atenção
|
|
||||||
|
|
||||||
1. **Dependência do Electron:** Módulos de Fiscal, CTe e Outlook não funcionam nativamente na web devido às restrições de sandbox do navegador (necessitam do bridge native).
|
|
||||||
2. **Performance de Filtro:** A filtragem de solicitações no painel de monitoramento ocorre majoritariamente no lado do cliente (`client-side filtering`), o que pode degradar a performance com milhares de registros.
|
|
||||||
3. **Endpoint do Outlook:** O endpoint `/api/outlook-filter` é simulado/mockado, exigindo um serviço backend Azure AD robusto para operação real.
|
|
||||||
4. **Sincronização:** A lógica offline depende inteiramente do `localStorage`. Limpar os dados do navegador sem sincronização resultará em perda de dados "pendentes".
|
|
||||||
5. **Credenciais de Rastreamento:**
|
|
||||||
* **T4S:** Senhas pendentes para contas PRALOG e PETY (marcadas como `[AGUARDANDO_WHATSAPP_*]`)
|
|
||||||
* **Sascar:** Credenciais completamente ausentes (estrutura pronta, mas inativa)
|
|
||||||
6. **Segurança do Banco de Dados:** Credenciais do MongoDB expostas em arquivo `.env` sem criptografia adicional.
|
|
||||||
7. **Geofencing Simplificado:** Lógica de cerca eletrônica usa apenas validação de latitude (`lat > -21.0`), sem polígonos complexos ou múltiplas zonas.
|
|
||||||
8. **Telemetria em Memória:** Histórico de posições armazenado apenas em memória (não persistido), limitado a 50 posições por veículo.
|
|
||||||
|
|
||||||
---
|
|
||||||
*Relatório atualizado em 06 de Fevereiro de 2026.*
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
import js from '@eslint/js'
|
|
||||||
import globals from 'globals'
|
|
||||||
import reactHooks from 'eslint-plugin-react-hooks'
|
|
||||||
import reactRefresh from 'eslint-plugin-react-refresh'
|
|
||||||
import tseslint from 'typescript-eslint'
|
|
||||||
import { defineConfig, globalIgnores } from 'eslint/config'
|
|
||||||
|
|
||||||
export default defineConfig([
|
|
||||||
globalIgnores(['dist']),
|
|
||||||
{
|
|
||||||
files: ['**/*.{ts,tsx}'],
|
|
||||||
extends: [
|
|
||||||
js.configs.recommended,
|
|
||||||
tseslint.configs.recommended,
|
|
||||||
reactHooks.configs.flat.recommended,
|
|
||||||
reactRefresh.configs.vite,
|
|
||||||
],
|
|
||||||
languageOptions: {
|
|
||||||
ecmaVersion: 2020,
|
|
||||||
globals: globals.browser,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
])
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
import re
|
|
||||||
|
|
||||||
FILE_PATH = "c:/Users/Daivid.alves/Desktop/Repositorios/PlatformSistemas/Sistema_zentulo_analise/Codigo/analysis_src/zentulo_index.js"
|
|
||||||
|
|
||||||
patterns = {
|
|
||||||
"FISCAL_XML": [
|
|
||||||
r"window\.electronAPI\.processFiscal",
|
|
||||||
r"DOMParser",
|
|
||||||
r"<placa>",
|
|
||||||
r"<vNF>",
|
|
||||||
r"<vtPrest>"
|
|
||||||
],
|
|
||||||
"OUTLOOK_EMAIL": [
|
|
||||||
r"outlook-filter",
|
|
||||||
r"socket\.on\(['\"]outlook",
|
|
||||||
r"OutlookAutomation"
|
|
||||||
],
|
|
||||||
"MONITORING": [
|
|
||||||
r"socket\.on\(['\"]update-request",
|
|
||||||
r"socket\.emit\(['\"]update-status",
|
|
||||||
r"PENDING",
|
|
||||||
r"APPROVED",
|
|
||||||
r"EM_ROTA"
|
|
||||||
],
|
|
||||||
"CHECKLIST": [
|
|
||||||
r"getStatusFromExpiry",
|
|
||||||
r"renovar",
|
|
||||||
r"nextOS",
|
|
||||||
r"ChecklistClient"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
def extract_context(content, pattern_name, regex_list):
|
|
||||||
print(f"\n{'='*20} {pattern_name} {'='*20}")
|
|
||||||
for regex in regex_list:
|
|
||||||
print(f"\n--- Searching for: {regex} ---")
|
|
||||||
matches = list(re.finditer(regex, content, re.IGNORECASE))
|
|
||||||
print(f"Found {len(matches)} matches.")
|
|
||||||
|
|
||||||
for i, match in enumerate(matches[:3]): # Limit to first 3 matches per pattern
|
|
||||||
start = max(0, match.start() - 300)
|
|
||||||
end = min(len(content), match.end() + 300)
|
|
||||||
snippet = content[start:end].replace('\n', ' ')
|
|
||||||
print(f"[{i+1}] ...{snippet}...")
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(FILE_PATH, 'r', encoding='utf-8', errors='ignore') as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
for key, regexes in patterns.items():
|
|
||||||
extract_context(content, key, regexes)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error: {e}")
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
file_path = "c:/Users/Daivid.alves/Desktop/Repositorios/PlatformSistemas/Sistema_zentulo_analise/Codigo/analysis_src/zentulo_index.js"
|
|
||||||
|
|
||||||
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
matches = list(re.finditer(r'outlook-filter', content))
|
|
||||||
for i, match in enumerate(matches):
|
|
||||||
start = max(0, match.start() - 500)
|
|
||||||
end = min(len(content), match.end() + 500)
|
|
||||||
print(f"--- MATCH {i+1} ---")
|
|
||||||
print(content[start:end])
|
|
||||||
print("-" * 50)
|
|
||||||
|
|
@ -1,164 +0,0 @@
|
||||||
# Git Auto-Sync - PlatformSistemas
|
|
||||||
# Branch: frontend_React
|
|
||||||
|
|
||||||
param(
|
|
||||||
[switch]$NoBuild = $false
|
|
||||||
)
|
|
||||||
|
|
||||||
$BRANCH_NAME = git branch --show-current
|
|
||||||
if ([string]::IsNullOrWhiteSpace($BRANCH_NAME)) { $BRANCH_NAME = "frontend_React" }
|
|
||||||
$DEBOUNCE_SECONDS = 10
|
|
||||||
|
|
||||||
$global:LastChangeTime = Get-Date
|
|
||||||
$global:PendingChanges = $false
|
|
||||||
$global:ChangedFiles = @()
|
|
||||||
|
|
||||||
function Test-ShouldIgnoreFile {
|
|
||||||
param([string]$FilePath)
|
|
||||||
|
|
||||||
$ignorePatterns = @("node_modules", ".git", "dist", ".env", ".log", "package-lock.json", ".tmp", ".cache", ".vscode", ".idea")
|
|
||||||
|
|
||||||
foreach ($pattern in $ignorePatterns) {
|
|
||||||
if ($FilePath -match [regex]::Escape($pattern)) {
|
|
||||||
return $true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $false
|
|
||||||
}
|
|
||||||
|
|
||||||
function Invoke-GitSync {
|
|
||||||
if (-not $global:PendingChanges) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "`n========================================" -ForegroundColor Cyan
|
|
||||||
Write-Host "Iniciando sincronizacao Git..." -ForegroundColor Cyan
|
|
||||||
Write-Host "========================================" -ForegroundColor Cyan
|
|
||||||
|
|
||||||
try {
|
|
||||||
$gitStatus = git status --porcelain
|
|
||||||
if ([string]::IsNullOrWhiteSpace($gitStatus)) {
|
|
||||||
Write-Host "Nenhuma alteracao para commitar." -ForegroundColor Yellow
|
|
||||||
$global:PendingChanges = $false
|
|
||||||
$global:ChangedFiles = @()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "`nArquivos alterados:" -ForegroundColor Gray
|
|
||||||
$global:ChangedFiles | ForEach-Object { Write-Host " - $_" -ForegroundColor DarkGray }
|
|
||||||
|
|
||||||
if (-not $NoBuild) {
|
|
||||||
Write-Host "`nGerando build de producao..." -ForegroundColor Yellow
|
|
||||||
npm run build
|
|
||||||
if ($LASTEXITCODE -ne 0) {
|
|
||||||
Write-Host "Erro no build! Abortando commit." -ForegroundColor Red
|
|
||||||
return
|
|
||||||
}
|
|
||||||
Write-Host "Build concluido com sucesso!" -ForegroundColor Green
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "`nAdicionando arquivos ao stage..." -ForegroundColor Yellow
|
|
||||||
git add .
|
|
||||||
|
|
||||||
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
|
||||||
$fileCount = ($global:ChangedFiles | Measure-Object).Count
|
|
||||||
$commitMessage = "Auto-deploy: $timestamp | $fileCount arquivo(s) alterado(s)"
|
|
||||||
|
|
||||||
if (-not $NoBuild) {
|
|
||||||
$commitMessage += " [Build included]"
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "Criando commit..." -ForegroundColor Yellow
|
|
||||||
git commit -m $commitMessage
|
|
||||||
|
|
||||||
if ($LASTEXITCODE -ne 0) {
|
|
||||||
Write-Host "Nada para commitar ou erro no commit." -ForegroundColor Yellow
|
|
||||||
$global:PendingChanges = $false
|
|
||||||
$global:ChangedFiles = @()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "Enviando para o repositorio remoto (branch: $BRANCH_NAME)..." -ForegroundColor Yellow
|
|
||||||
git push origin $BRANCH_NAME
|
|
||||||
|
|
||||||
if ($LASTEXITCODE -eq 0) {
|
|
||||||
Write-Host "`nSincronizacao concluida com sucesso!" -ForegroundColor Green
|
|
||||||
Write-Host "========================================`n" -ForegroundColor Cyan
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Write-Host "`nErro ao fazer push para o repositorio remoto!" -ForegroundColor Red
|
|
||||||
Write-Host "========================================`n" -ForegroundColor Cyan
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
Write-Host "`nErro ao sincronizar com o Git: $_" -ForegroundColor Red
|
|
||||||
Write-Host "========================================`n" -ForegroundColor Cyan
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
$global:PendingChanges = $false
|
|
||||||
$global:ChangedFiles = @()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$Watcher = New-Object IO.FileSystemWatcher
|
|
||||||
$Watcher.Path = $PSScriptRoot
|
|
||||||
$Watcher.Filter = "*.*"
|
|
||||||
$Watcher.IncludeSubdirectories = $true
|
|
||||||
$Watcher.EnableRaisingEvents = $true
|
|
||||||
$Watcher.NotifyFilter = [System.IO.NotifyFilters]::FileName -bor [System.IO.NotifyFilters]::DirectoryName -bor [System.IO.NotifyFilters]::LastWrite
|
|
||||||
|
|
||||||
$Action = {
|
|
||||||
$path = $Event.SourceEventArgs.FullPath
|
|
||||||
$changeType = $Event.SourceEventArgs.ChangeType
|
|
||||||
|
|
||||||
if (Test-ShouldIgnoreFile -FilePath $path) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
$relativePath = $path.Replace($PSScriptRoot, "").TrimStart("\")
|
|
||||||
Write-Host "[$(Get-Date -Format 'HH:mm:ss')] $changeType : $relativePath" -ForegroundColor DarkCyan
|
|
||||||
|
|
||||||
$global:LastChangeTime = Get-Date
|
|
||||||
$global:PendingChanges = $true
|
|
||||||
|
|
||||||
if ($global:ChangedFiles -notcontains $relativePath) {
|
|
||||||
$global:ChangedFiles += $relativePath
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Register-ObjectEvent $Watcher "Changed" -Action $Action | Out-Null
|
|
||||||
Register-ObjectEvent $Watcher "Created" -Action $Action | Out-Null
|
|
||||||
Register-ObjectEvent $Watcher "Deleted" -Action $Action | Out-Null
|
|
||||||
Register-ObjectEvent $Watcher "Renamed" -Action $Action | Out-Null
|
|
||||||
|
|
||||||
Write-Host "`n============================================================" -ForegroundColor Green
|
|
||||||
Write-Host " Git Auto-Sync - PlatformSistemas" -ForegroundColor Green
|
|
||||||
Write-Host "============================================================" -ForegroundColor Green
|
|
||||||
Write-Host " Branch: $BRANCH_NAME" -ForegroundColor Cyan
|
|
||||||
Write-Host " Remote: https://git.itguys.com.br/itguys_dev/Workspace" -ForegroundColor Cyan
|
|
||||||
Write-Host " Debounce: $DEBOUNCE_SECONDS segundos" -ForegroundColor Cyan
|
|
||||||
Write-Host " Build automatico: $(if($NoBuild){'Desabilitado'}else{'Habilitado'})" -ForegroundColor Cyan
|
|
||||||
Write-Host "============================================================" -ForegroundColor Green
|
|
||||||
Write-Host " Status: Monitorando alteracoes..." -ForegroundColor Yellow
|
|
||||||
Write-Host " Pressione Ctrl+C para parar" -ForegroundColor Yellow
|
|
||||||
Write-Host "============================================================`n" -ForegroundColor Green
|
|
||||||
|
|
||||||
$lastHeartbeat = Get-Date
|
|
||||||
while ($true) {
|
|
||||||
Start-Sleep -Seconds 1
|
|
||||||
|
|
||||||
if ((Get-Date) - $lastHeartbeat -gt (New-TimeSpan -Minutes 5)) {
|
|
||||||
Write-Host "[$(Get-Date -Format 'HH:mm:ss')] Heartbeat: Script ativo e monitorando..." -ForegroundColor Gray
|
|
||||||
$lastHeartbeat = Get-Date
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($global:PendingChanges) {
|
|
||||||
$timeSinceLastChange = (Get-Date) - $global:LastChangeTime
|
|
||||||
|
|
||||||
if ($timeSinceLastChange.TotalSeconds -ge $DEBOUNCE_SECONDS) {
|
|
||||||
Invoke-GitSync
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
# Git Sync Environment - PlatformSistemas Modelo
|
|
||||||
# Use este script dentro de uma branch de AMBIENTE (ex: env/rh) para puxar novidades do Núcleo.
|
|
||||||
|
|
||||||
param(
|
|
||||||
[string]$CoreBranch = "frontend_React"
|
|
||||||
)
|
|
||||||
|
|
||||||
Write-Host "========================================" -ForegroundColor Cyan
|
|
||||||
Write-Host "Sincronizando Ambiente com o Nucleo..." -ForegroundColor Cyan
|
|
||||||
Write-Host "========================================" -ForegroundColor Cyan
|
|
||||||
|
|
||||||
# 1. Verifica em qual branch estamos
|
|
||||||
$currentBranch = git branch --show-current
|
|
||||||
Write-Host "Branch atual: $currentBranch" -ForegroundColor Gray
|
|
||||||
|
|
||||||
if ($currentBranch -eq $CoreBranch) {
|
|
||||||
Write-Host "Voce ja esta na branch de Nucleo. Nada para sincronizar aqui." -ForegroundColor Yellow
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
# 2. Faz o merge do núcleo para o ambiente
|
|
||||||
Write-Host "Mesclando alteracoes da branch '$CoreBranch' para '$currentBranch'..." -ForegroundColor Yellow
|
|
||||||
git merge $CoreBranch
|
|
||||||
|
|
||||||
if ($LASTEXITCODE -eq 0) {
|
|
||||||
Write-Host "`nSincronizacao concluida! O ambiente agora esta atualizado com o nucleo." -ForegroundColor Green
|
|
||||||
Write-Host "Lembre-se de rodar 'npm install' se houver novas dependencias." -ForegroundColor White
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Write-Host "`nHouve conflitos durante a sincronizacao. Resolva-os manualmente." -ForegroundColor Red
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "========================================`n" -ForegroundColor Cyan
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
# Git Sync Fork - PlatformSistemas Modelo
|
|
||||||
# Use este script dentro de um FORK para puxar as dependencias do repositório Principal (Upstream)
|
|
||||||
|
|
||||||
param(
|
|
||||||
[string]$UpstreamUrl = "https://git.itguys.com.br/itguys_dev/Workspace",
|
|
||||||
[string]$MainBranch = "frontend_React"
|
|
||||||
)
|
|
||||||
|
|
||||||
Write-Host "========================================" -ForegroundColor Cyan
|
|
||||||
Write-Host "Sincronizando Fork com Upstream..." -ForegroundColor Cyan
|
|
||||||
Write-Host "========================================" -ForegroundColor Cyan
|
|
||||||
|
|
||||||
# 1. Verifica se o upstream já existe
|
|
||||||
$remotes = git remote
|
|
||||||
if ($remotes -notcontains "upstream") {
|
|
||||||
Write-Host "Adicionando remote 'upstream': $UpstreamUrl" -ForegroundColor Yellow
|
|
||||||
git remote add upstream $UpstreamUrl
|
|
||||||
}
|
|
||||||
|
|
||||||
# 2. Busca atualizações do upstream
|
|
||||||
Write-Host "Buscando novidades do nucleo central..." -ForegroundColor Yellow
|
|
||||||
git fetch upstream
|
|
||||||
|
|
||||||
# 3. Faz o merge das dependencias e nucleo (na branch atual)
|
|
||||||
Write-Host "Mesclando alteracoes da branch $MainBranch para sua branch atual..." -ForegroundColor Yellow
|
|
||||||
git merge upstream/$MainBranch
|
|
||||||
|
|
||||||
if ($LASTEXITCODE -eq 0) {
|
|
||||||
Write-Host "`nSincronizacao concluida! Agora rode 'npm install' para atualizar dependencias." -ForegroundColor Green
|
|
||||||
} else {
|
|
||||||
Write-Host "`nHouve conflitos durante a sincronizacao. Resolva-os manualmente." -ForegroundColor Red
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "========================================`n" -ForegroundColor Cyan
|
|
||||||
14
index.html
|
|
@ -1,14 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>platformsistemas</title>
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-icons/1.13.1/font/bootstrap-icons.min.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="root"></div>
|
|
||||||
<script type="module" src="./src/main.jsx"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
69
package.json
|
|
@ -1,69 +0,0 @@
|
||||||
{
|
|
||||||
"name": "platformsistemas",
|
|
||||||
"private": true,
|
|
||||||
"version": "0.0.0",
|
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
|
||||||
"dev": "vite",
|
|
||||||
"build": "vite build",
|
|
||||||
"lint": "eslint .",
|
|
||||||
"preview": "vite preview",
|
|
||||||
"git:sync": "powershell -ExecutionPolicy Bypass -File ./git-auto-sync.ps1",
|
|
||||||
"git:sync:nobuild": "powershell -ExecutionPolicy Bypass -File ./git-auto-sync.ps1 -NoBuild",
|
|
||||||
"agent:git:commit": "node .agent/scripts/git-commit-by-day.js",
|
|
||||||
"agent:git:commit:dry": "node .agent/scripts/git-commit-by-day.js --dry-run",
|
|
||||||
"agent:docs:update": "node .agent/scripts/docs-update.js",
|
|
||||||
"agent:check": "node .agent/scripts/check-orchestrator.js",
|
|
||||||
"doc:sync": "node scripts/auto-sync-routes.js"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@hookform/resolvers": "^5.2.2",
|
|
||||||
"@radix-ui/react-avatar": "^1.1.11",
|
|
||||||
"@radix-ui/react-checkbox": "^1.3.3",
|
|
||||||
"@radix-ui/react-dialog": "^1.1.15",
|
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
||||||
"@radix-ui/react-label": "^2.1.8",
|
|
||||||
"@radix-ui/react-radio-group": "^1.3.8",
|
|
||||||
"@radix-ui/react-scroll-area": "^1.2.10",
|
|
||||||
"@radix-ui/react-select": "^2.2.6",
|
|
||||||
"@radix-ui/react-separator": "^1.1.8",
|
|
||||||
"@radix-ui/react-slider": "^1.3.6",
|
|
||||||
"@radix-ui/react-slot": "^1.2.4",
|
|
||||||
"@radix-ui/react-switch": "^1.2.6",
|
|
||||||
"@radix-ui/react-tabs": "^1.1.13",
|
|
||||||
"axios": "^1.13.2",
|
|
||||||
"class-variance-authority": "^0.7.1",
|
|
||||||
"clsx": "^2.1.1",
|
|
||||||
"framer-motion": "^12.23.26",
|
|
||||||
"lucide-react": "^0.562.0",
|
|
||||||
"react": "^19.2.0",
|
|
||||||
"react-dom": "^19.2.0",
|
|
||||||
"react-hook-form": "^7.71.1",
|
|
||||||
"react-router-dom": "^7.11.0",
|
|
||||||
"recharts": "^3.6.0",
|
|
||||||
"sonner": "^2.0.7",
|
|
||||||
"tailwind-merge": "^3.4.0",
|
|
||||||
"tailwindcss-animate": "^1.0.7",
|
|
||||||
"zod": "^4.3.5",
|
|
||||||
"zustand": "^5.0.9"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@eslint/js": "^9.39.1",
|
|
||||||
"@tailwindcss/postcss": "^4.1.18",
|
|
||||||
"@tailwindcss/vite": "^4.1.18",
|
|
||||||
"@types/node": "^24.10.1",
|
|
||||||
"@types/react": "^19.2.5",
|
|
||||||
"@types/react-dom": "^19.2.3",
|
|
||||||
"@vitejs/plugin-react": "^5.1.1",
|
|
||||||
"autoprefixer": "^10.4.23",
|
|
||||||
"eslint": "^9.39.1",
|
|
||||||
"eslint-plugin-react-hooks": "^7.0.1",
|
|
||||||
"eslint-plugin-react-refresh": "^0.4.24",
|
|
||||||
"globals": "^16.5.0",
|
|
||||||
"postcss": "^8.5.6",
|
|
||||||
"tailwindcss": "^4.1.18",
|
|
||||||
"typescript": "~5.9.3",
|
|
||||||
"typescript-eslint": "^8.46.4",
|
|
||||||
"vite": "^7.2.4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
export default {
|
|
||||||
plugins: {
|
|
||||||
'@tailwindcss/postcss': {},
|
|
||||||
autoprefixer: {},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
@ -1,246 +0,0 @@
|
||||||
{
|
|
||||||
"ambiente": "prafrot",
|
|
||||||
"label": "Prafrot (Prafrota)",
|
|
||||||
"recursoBase": "/cadastro_frota",
|
|
||||||
"rotas": [
|
|
||||||
{
|
|
||||||
"id": "cadastro_frota-listar",
|
|
||||||
"recurso": "cadastro_frota",
|
|
||||||
"operations": [
|
|
||||||
{
|
|
||||||
"method": "GET",
|
|
||||||
"path": "/cadastro_frota/apresentar",
|
|
||||||
"descricao": "Lista veículos cadastrados na frota",
|
|
||||||
"responseShape": [
|
|
||||||
{
|
|
||||||
"field": "idveiculo_frota",
|
|
||||||
"type": "number",
|
|
||||||
"description": "ID do veículo"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field": "placa",
|
|
||||||
"type": "string",
|
|
||||||
"description": "Placa"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field": "modelo",
|
|
||||||
"type": "string",
|
|
||||||
"description": "Modelo"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field": "base",
|
|
||||||
"type": "string",
|
|
||||||
"description": "Unidade/Base"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field": "motorista",
|
|
||||||
"type": "string",
|
|
||||||
"description": "Motorista"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field": "status",
|
|
||||||
"type": "string",
|
|
||||||
"description": "Status"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"suggestedColumns": [
|
|
||||||
{
|
|
||||||
"field": "placa",
|
|
||||||
"header": "Placa",
|
|
||||||
"width": "100px"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field": "modelo",
|
|
||||||
"header": "Modelo",
|
|
||||||
"width": "150px"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"filterDefs": [
|
|
||||||
{
|
|
||||||
"field": "placa",
|
|
||||||
"label": "Placa",
|
|
||||||
"type": "text"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"method": "GET",
|
|
||||||
"path": "/cadastro_frota/:id",
|
|
||||||
"descricao": "Detalhe de um veículo",
|
|
||||||
"responseShape": [
|
|
||||||
{
|
|
||||||
"field": "idveiculo_frota",
|
|
||||||
"type": "number",
|
|
||||||
"description": "ID"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field": "placa",
|
|
||||||
"type": "string",
|
|
||||||
"description": "Placa"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"method": "POST",
|
|
||||||
"path": "/cadastro_frota",
|
|
||||||
"descricao": "Criar novo veículo",
|
|
||||||
"requestBody": [
|
|
||||||
{
|
|
||||||
"field": "placa",
|
|
||||||
"type": "string",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field": "modelo",
|
|
||||||
"type": "string",
|
|
||||||
"required": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"method": "PUT",
|
|
||||||
"path": "/cadastro_frota/:id",
|
|
||||||
"descricao": "Atualizar veículo",
|
|
||||||
"requestBody": [
|
|
||||||
{
|
|
||||||
"field": "placa",
|
|
||||||
"type": "string",
|
|
||||||
"required": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field": "status",
|
|
||||||
"type": "string",
|
|
||||||
"required": false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "manutencao_frota-listar",
|
|
||||||
"recurso": "manutencao_frota",
|
|
||||||
"operations": [
|
|
||||||
{
|
|
||||||
"method": "GET",
|
|
||||||
"path": "/manutencao_frota/apresentar",
|
|
||||||
"descricao": "Lista todas as manutenções",
|
|
||||||
"responseShape": [
|
|
||||||
{
|
|
||||||
"field": "idmanutencao_frota",
|
|
||||||
"type": "number",
|
|
||||||
"description": "ID manutenção"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field": "placa",
|
|
||||||
"type": "string",
|
|
||||||
"description": "Placa"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field": "oficina",
|
|
||||||
"type": "string",
|
|
||||||
"description": "Oficina"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field": "status",
|
|
||||||
"type": "string",
|
|
||||||
"description": "Status"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"suggestedColumns": [
|
|
||||||
{
|
|
||||||
"field": "idmanutencao_frota",
|
|
||||||
"header": "ID",
|
|
||||||
"width": "80px"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field": "placa",
|
|
||||||
"header": "PLACA",
|
|
||||||
"width": "100px"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"filterDefs": [
|
|
||||||
{
|
|
||||||
"field": "placa",
|
|
||||||
"label": "Placa",
|
|
||||||
"type": "text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field": "status",
|
|
||||||
"label": "Status",
|
|
||||||
"type": "select"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"method": "GET",
|
|
||||||
"path": "/manutencao_frota/:id",
|
|
||||||
"descricao": "Detalhe de uma manutenção",
|
|
||||||
"responseShape": [
|
|
||||||
{
|
|
||||||
"field": "idmanutencao_frota",
|
|
||||||
"type": "number",
|
|
||||||
"description": "ID"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field": "placa",
|
|
||||||
"type": "string",
|
|
||||||
"description": "Placa"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"method": "POST",
|
|
||||||
"path": "/manutencao_frota",
|
|
||||||
"descricao": "Criar nova manutenção",
|
|
||||||
"requestBody": [
|
|
||||||
{
|
|
||||||
"field": "placa",
|
|
||||||
"type": "string",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field": "oficina",
|
|
||||||
"type": "string",
|
|
||||||
"required": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"method": "PUT",
|
|
||||||
"path": "/manutencao_frota/:id",
|
|
||||||
"descricao": "Atualizar manutenção",
|
|
||||||
"requestBody": [
|
|
||||||
{
|
|
||||||
"field": "status",
|
|
||||||
"type": "string",
|
|
||||||
"required": false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "disponibilidade_frota",
|
|
||||||
"recurso": "disponibilidade_frota",
|
|
||||||
"operations": [
|
|
||||||
{
|
|
||||||
"method": "GET",
|
|
||||||
"path": "/disponibilidade_frota/apresentar",
|
|
||||||
"descricao": "Lista disponibilidade",
|
|
||||||
"responseShape": [
|
|
||||||
{
|
|
||||||
"field": "placa",
|
|
||||||
"type": "string",
|
|
||||||
"description": "Placa"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field": "disponivel",
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "Disponível"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
{"ambiente":"workspace","label":"Workspace","rotas":[{"id":"extrato-listar","recurso":"extrato","operations":[{"method":"GET","path":"/extrato/apresentar","descricao":"Extrato bancário; C=receitas, D=despesas","responseShape":[{"field":"idextrato","type":"number","description":"ID"},{"field":"data","type":"string","description":"Data"},{"field":"descricao","type":"string","description":"Descrição"},{"field":"valor","type":"number","description":"Valor"}],"suggestedColumns":[{"field":"data","header":"Data","width":"120px"},{"field":"descricao","header":"Descrição","width":"400px"},{"field":"valor","header":"Valor","width":"150px"}]}]},{"id":"categorias-listar","recurso":"categorias","operations":[{"method":"GET","path":"/categorias/apresentar","descricao":"Lista categorias","responseShape":[{"field":"id","type":"number","description":"ID"},{"field":"nome","type":"string","description":"Nome"}]}]},{"id":"caixinhas-listar","recurso":"caixinhas","operations":[{"method":"GET","path":"/caixinhas/apresentar","descricao":"Lista caixinhas","responseShape":[{"field":"id","type":"number","description":"ID"},{"field":"nome","type":"string","description":"Nome"}]}]},{"id":"contas_a_pagar-listar","recurso":"contas_a_pagar","operations":[{"method":"GET","path":"/contas_a_pagar/apresentar","descricao":"Contas a pagar","responseShape":[{"field":"id","type":"number","description":"ID"},{"field":"categoria","type":"string","description":"Categoria"},{"field":"valor","type":"number","description":"Valor"}]}]}]}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.5 KiB |
|
|
@ -1,40 +0,0 @@
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
def refactor_file(filepath):
|
|
||||||
with open(filepath, 'r', encoding='utf-8') as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
# Pattern to find:
|
|
||||||
# try {
|
|
||||||
# const response = await ...
|
|
||||||
# return ...
|
|
||||||
# } catch (error) {
|
|
||||||
# throw new Error(...) or throw error
|
|
||||||
# }
|
|
||||||
|
|
||||||
# This regex matches the try/catch block and replaces it with the inner code
|
|
||||||
# It accounts for indentation and multi-line content
|
|
||||||
pattern = r'try\s*\{([\s\S]*?)\}\s*catch\s*\(error\)\s*\{[\s\S]*?\}'
|
|
||||||
|
|
||||||
def replacement(match):
|
|
||||||
inner_code = match.group(1)
|
|
||||||
# Strip one level of indentation (usually 2 spaces)
|
|
||||||
lines = inner_code.split('\n')
|
|
||||||
new_lines = []
|
|
||||||
for line in lines:
|
|
||||||
if line.startswith(' '):
|
|
||||||
new_lines.append(line[2:])
|
|
||||||
elif line.startswith(' '):
|
|
||||||
new_lines.append(line[2:])
|
|
||||||
else:
|
|
||||||
new_lines.append(line)
|
|
||||||
return '\n'.join(new_lines).strip()
|
|
||||||
|
|
||||||
new_content = re.sub(pattern, replacement, content)
|
|
||||||
|
|
||||||
with open(filepath, 'w', encoding='utf-8') as f:
|
|
||||||
f.write(new_content)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
refactor_file(sys.argv[1])
|
|
||||||
|
|
@ -1,110 +0,0 @@
|
||||||
import fs from 'fs';
|
|
||||||
import path from 'path';
|
|
||||||
import https from 'https';
|
|
||||||
import { fileURLToPath } from 'url';
|
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
|
||||||
const __dirname = path.dirname(__filename);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AUTO-SYNC AGENT FOR ROUTE DOCUMENTATION
|
|
||||||
*/
|
|
||||||
|
|
||||||
const CONTRATOS_DIR = path.join(__dirname, '../src/features/dev-tools/data/contratos');
|
|
||||||
|
|
||||||
const MONITORED_ROUTES = [
|
|
||||||
{ env: 'prafrot', path: '/cadastro_frota/apresentar', method: 'GET', resource: 'cadastro_frota' },
|
|
||||||
{ env: 'prafrot', path: '/motoristas/listagem', method: 'GET', resource: 'motoristas' },
|
|
||||||
{ env: 'prafrot', path: '/dispatcher/apresentar', method: 'GET', resource: 'dispatcher' },
|
|
||||||
{ env: 'prafrot', path: '/oficinas_frota/apresentar', method: 'GET', resource: 'oficinas_frota' },
|
|
||||||
{ env: 'prafrot', path: '/monitoramento_frota/apresentar', method: 'GET', resource: 'monitoramento_frota' },
|
|
||||||
{ env: 'prafrot', path: '/status_frota/apresentar', method: 'GET', resource: 'status_frota' },
|
|
||||||
{ env: 'prafrot', path: '/manutencao_frota/apresentar', method: 'GET', resource: 'manutencao_frota' },
|
|
||||||
{ env: 'prafrot', path: '/sinistro_devolucao_venda_frota/apresentar', method: 'GET', resource: 'sinistro_devolucao_venda_frota' },
|
|
||||||
{ env: 'workspace', path: '/extrato/apresentar', method: 'GET', resource: 'extrato' },
|
|
||||||
{ env: 'workspace', path: '/categorias/apresentar', method: 'GET', resource: 'categorias' },
|
|
||||||
{ env: 'workspace', path: '/caixinhas/apresentar', method: 'GET', resource: 'caixinhas' },
|
|
||||||
{ env: 'workspace', path: '/contas_a_pagar/apresentar', method: 'GET', resource: 'contas_a_pagar' },
|
|
||||||
{ env: 'rh', path: '/colaboradores/apresentar', method: 'GET', resource: 'colaboradores' },
|
|
||||||
{ env: 'financeiro-v2', path: '/boletos/apresentar', method: 'GET', resource: 'boletos' },
|
|
||||||
{ env: 'gr', path: '/gr/contratos', method: 'GET', resource: 'contratos' },
|
|
||||||
];
|
|
||||||
|
|
||||||
function inferType(value) {
|
|
||||||
if (value === null) return 'object';
|
|
||||||
if (Array.isArray(value)) return 'array';
|
|
||||||
return typeof value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function inferDescription(key, value) {
|
|
||||||
if (key.includes('data')) return 'Data';
|
|
||||||
if (typeof value === 'boolean' || (typeof value === 'string' && ['SIM', 'NÃO'].includes(value))) return "'SIM' ou 'NÃO' / Booleano";
|
|
||||||
if (value === null) return 'Pode ser null';
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
const MOCK_API_RESPONSES = {
|
|
||||||
'/cadastro_frota/apresentar': { "ano_fabricacao": "2", "idveiculo_frota": 3638, "placa": "ABC1234", "geotab": "SIM" },
|
|
||||||
'/motoristas/listagem': { "NOME_FAVORECIDO": "ACAUAN DUQUE", "idfavorecido": 1 },
|
|
||||||
'/dispatcher/apresentar': { "nome": "Rafael", "email": "rafael@pralog.com.br" },
|
|
||||||
'/oficinas_frota/apresentar': { "razao_social": "REPECOL LTDA", "idoficinas_frota": 2 },
|
|
||||||
'/monitoramento_frota/apresentar': { "placa": "XYZ5678", "idmonitoramento_frota": 738 },
|
|
||||||
'/status_frota/apresentar': { "status_frota": "Em Trânsito", "idstatus_frota": 2412 },
|
|
||||||
'/manutencao_frota/apresentar': { "oficina": "D CARROS CENTER", "idmanutencao_frota": 13176 },
|
|
||||||
'/sinistro_devolucao_venda_frota/apresentar': { "status": "Desmobilizado", "idsinistro_devolucao_frota": 871 },
|
|
||||||
'/extrato/apresentar': { "idextrato": 101, "descricao": "Venda Loja", "valor": 1500.50 },
|
|
||||||
'/categorias/apresentar': { "id": 1, "nome": "Vendas" },
|
|
||||||
'/caixinhas/apresentar': { "id": 1, "nome": "Principal" },
|
|
||||||
'/contas_a_pagar/apresentar': { "id": 1, "valor": 500.00 },
|
|
||||||
'/colaboradores/apresentar': { "id": 1, "nome": "João Silva", "cargo": "Analista" },
|
|
||||||
'/boletos/apresentar': { "id": 1, "valor": 1200.00 },
|
|
||||||
'/gr/contratos': { "id": 1, "cliente": "Empresa X" }
|
|
||||||
};
|
|
||||||
|
|
||||||
async function updateDocs() {
|
|
||||||
console.log(`🤖 Agente Auto-Sync Iniciado`);
|
|
||||||
const ENVS = [...new Set(MONITORED_ROUTES.map(r => r.env))];
|
|
||||||
|
|
||||||
for (const envId of ENVS) {
|
|
||||||
const targetFile = path.join(CONTRATOS_DIR, `${envId}-routes.json`);
|
|
||||||
let contractData = { ambiente: envId, label: envId, rotas: [] };
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (fs.existsSync(targetFile)) {
|
|
||||||
contractData = JSON.parse(fs.readFileSync(targetFile, 'utf8'));
|
|
||||||
}
|
|
||||||
} catch (e) { console.error(`Erro ao ler ${envId}:`, e); continue; }
|
|
||||||
|
|
||||||
const envRoutes = MONITORED_ROUTES.filter(r => r.env === envId);
|
|
||||||
console.log(`\n📂 Ambiente: ${envId.toUpperCase()}`);
|
|
||||||
|
|
||||||
for (const route of envRoutes) {
|
|
||||||
console.log(` ⚡ Rota: ${route.method} ${route.path}`);
|
|
||||||
const responseData = MOCK_API_RESPONSES[route.path];
|
|
||||||
if (!responseData) continue;
|
|
||||||
|
|
||||||
const newResponseShape = Object.entries(responseData).map(([key, value]) => ({
|
|
||||||
field: key,
|
|
||||||
type: inferType(value),
|
|
||||||
description: inferDescription(key, value)
|
|
||||||
})).sort((a, b) => a.field.localeCompare(b.field));
|
|
||||||
|
|
||||||
let routeEntry = contractData.rotas.find(r => r.recurso === route.resource);
|
|
||||||
if (!routeEntry) {
|
|
||||||
routeEntry = { id: `${route.resource}-auto`, recurso: route.resource, operations: [] };
|
|
||||||
contractData.rotas.push(routeEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
let operation = routeEntry.operations.find(op => op.path === route.path && op.method === route.method);
|
|
||||||
if (!operation) {
|
|
||||||
operation = { method: route.method, path: route.path, descricao: `Auto-gerado`, responseShape: [] };
|
|
||||||
routeEntry.operations.push(operation);
|
|
||||||
}
|
|
||||||
operation.responseShape = newResponseShape;
|
|
||||||
}
|
|
||||||
fs.writeFileSync(targetFile, JSON.stringify(contractData, null, 2), 'utf8');
|
|
||||||
}
|
|
||||||
console.log(`\n✅ Sincronização concluída!`);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateDocs();
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
import fs from 'fs';
|
|
||||||
import path from 'path';
|
|
||||||
import { fileURLToPath } from 'url';
|
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
|
||||||
const __dirname = path.dirname(__filename);
|
|
||||||
|
|
||||||
const SRC_FILE = path.join(__dirname, '../src/features/dev-tools/data/contratos/prafrot-routes.json');
|
|
||||||
const DOC_FILE = path.join(__dirname, '../docs/contratos/prafrot-routes.json');
|
|
||||||
|
|
||||||
const srcData = JSON.parse(fs.readFileSync(SRC_FILE, 'utf8'));
|
|
||||||
const docData = JSON.parse(fs.readFileSync(DOC_FILE, 'utf8'));
|
|
||||||
|
|
||||||
// Merge operations from DOC into SRC where SRC only has GET
|
|
||||||
docData.rotas.forEach(docRoute => {
|
|
||||||
const srcRoute = srcData.rotas.find(r => r.recurso === docRoute.recurso);
|
|
||||||
if (srcRoute) {
|
|
||||||
docRoute.operations.forEach(docOp => {
|
|
||||||
const hasOp = srcRoute.operations.some(op => op.path === docOp.path && op.method === docOp.method);
|
|
||||||
if (!hasOp) {
|
|
||||||
console.log(`Merging ${docOp.method} ${docOp.path} into ${docRoute.recurso}`);
|
|
||||||
srcRoute.operations.push(docOp);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
fs.writeFileSync(SRC_FILE, JSON.stringify(srcData, null, 2), 'utf8');
|
|
||||||
console.log('Merge complete!');
|
|
||||||
42
src/App.css
|
|
@ -1,42 +0,0 @@
|
||||||
#root {
|
|
||||||
max-width: 1280px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 2rem;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
height: 6em;
|
|
||||||
padding: 1.5em;
|
|
||||||
will-change: filter;
|
|
||||||
transition: filter 300ms;
|
|
||||||
}
|
|
||||||
.logo:hover {
|
|
||||||
filter: drop-shadow(0 0 2em #646cffaa);
|
|
||||||
}
|
|
||||||
.logo.react:hover {
|
|
||||||
filter: drop-shadow(0 0 2em #61dafbaa);
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes logo-spin {
|
|
||||||
from {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-reduced-motion: no-preference) {
|
|
||||||
a:nth-of-type(2) .logo {
|
|
||||||
animation: logo-spin infinite 20s linear;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
padding: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.read-the-docs {
|
|
||||||
color: #888;
|
|
||||||
}
|
|
||||||
210
src/App.jsx
|
|
@ -1,210 +0,0 @@
|
||||||
import { lazy, Suspense } from 'react';
|
|
||||||
import { BrowserRouter as Router, Routes, Route, Navigate, useLocation } from 'react-router-dom';
|
|
||||||
import { Toaster } from 'sonner';
|
|
||||||
import { PortalHome } from './features/portal/components/PortalHome.jsx';
|
|
||||||
import AuthProvider, { useAuthContext } from '@/components/shared/AuthProvider';
|
|
||||||
|
|
||||||
import { Building, Zap } from 'lucide-react';
|
|
||||||
import { LoadingOverlay } from '@/components/shared/LoadingOverlay';
|
|
||||||
import { useGlobalLoading } from '@/hooks/useGlobalLoading';
|
|
||||||
|
|
||||||
// Lazy loading feature components
|
|
||||||
const FleetLogin = lazy(() => import('@/features/fleet').then(m => ({ default: m.FleetLogin })));
|
|
||||||
const FleetDashboard = lazy(() => import('@/features/fleet').then(m => ({ default: m.FleetDashboard })));
|
|
||||||
const HRLogin = lazy(() => import('@/features/rh').then(m => ({ default: m.HRLogin })));
|
|
||||||
const HRDashboard = lazy(() => import('@/features/rh').then(m => ({ default: m.HRDashboard })));
|
|
||||||
const PontoPage = lazy(() => import('@/features/rh').then(m => ({ default: m.PontoPage })));
|
|
||||||
const RhRoutes = lazy(() => import('@/features/rh/routes').then(m => ({ default: m.RhRoutes })));
|
|
||||||
const LoginPage = lazy(() => import('@/features/auth/login/LoginPage').then(m => ({ default: m.LoginPage })));
|
|
||||||
const FinanceLogin = lazy(() => import('@/features/auth/login-finance/LoginPage').then(m => ({ default: m.LoginPage })));
|
|
||||||
const CnabLogin = lazy(() => import('@/features/auth/login-cnab/LoginPage').then(m => ({ default: m.LoginPage })));
|
|
||||||
const FleetV2App = lazy(() => import('@/features/fleet-v2').then(m => ({ default: m.FleetV2App })));
|
|
||||||
const FinanceiroV2App = lazy(() => import('@/features/financeiro-v2').then(m => ({ default: m.FinanceiroV2App })));
|
|
||||||
const PrafrotRoutes = lazy(() => import('@/features/prafrot/routes').then(m => ({ default: m.PrafrotRoutes })));
|
|
||||||
const PrafrotLogin = lazy(() => import('@/features/prafrot/views/LoginView'));
|
|
||||||
const TableDebug = lazy(() => import('@/features/prafrot/views/TableDebug'));
|
|
||||||
const PlaygroundView = lazy(() => import('@/features/dev-tools/views/PlaygroundView'));
|
|
||||||
const WorkspaceLayout = lazy(() => import('@/features/workspace/components/WorkspaceLayout.jsx').then(m => ({ default: m.WorkspaceLayout })));
|
|
||||||
const LoginView = lazy(() => import('@/features/workspace/views/LoginView.jsx').then(m => ({ default: m.LoginView })));
|
|
||||||
const WorkspaceGuard = lazy(() => import('@/features/workspace/components/WorkspaceGuard.jsx').then(m => ({ default: m.WorkspaceGuard })));
|
|
||||||
const CnabRoutes = lazy(() => import('@/features/financeiro-cnab/routes').then(m => ({ default: m.CnabRoutes })));
|
|
||||||
const GrRoutes = lazy(() => import('@/features/gr/routes').then(m => ({ default: m.GrRoutes })));
|
|
||||||
const GrLogin = lazy(() => import('@/features/gr/views/LoginView'));
|
|
||||||
const GrResetPassword = lazy(() => import('@/features/gr/views/ResetPasswordView'));
|
|
||||||
const ExternalDriverRegistration = lazy(() => import('@/features/gr/views/ExternalDriverRegistrationView').then(m => ({ default: m.ExternalDriverRegistrationView })));
|
|
||||||
const DriverPortalView = lazy(() => import('@/features/prafrot/views/DriverPortalView').then(m => ({ default: m.DriverPortalView })));
|
|
||||||
const AutoLabRoutes = lazy(() => import('@/features/autolab/routes').then(m => ({ default: m.AutoLabRoutes })));
|
|
||||||
const AutoLabLogin = lazy(() => import('@/features/autolab/views/AutoLabLoginView'));
|
|
||||||
const OestPanRoutes = lazy(() => import('@/features/Oest_Pan/routes').then(m => ({ default: m.OestPanRoutes })));
|
|
||||||
const OestPanLogin = lazy(() => import('@/features/Oest_Pan/views/LoginView'));
|
|
||||||
|
|
||||||
|
|
||||||
// Loading component
|
|
||||||
const PageLoader = () => (
|
|
||||||
<LoadingOverlay isLoading={true} message="Carregando Aplicação..." fullScreen variant="premium" />
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Componente de proteção de rotas.
|
|
||||||
* Redireciona para o login se o usuário não estiver autenticado.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
const ProtectedRoute = ({ children, loginPath = '/plataforma/auth/login', environment = 'global' }) => {
|
|
||||||
const { user, loading, isAuthorized } = useAuthContext();
|
|
||||||
const location = useLocation();
|
|
||||||
|
|
||||||
if (loading) return <PageLoader />;
|
|
||||||
|
|
||||||
// Verifica autorização - isAuthorized já verifica o usuário do módulo específico
|
|
||||||
if (!isAuthorized(environment)) {
|
|
||||||
return <Navigate to={loginPath} state={{ from: location }} replace />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return children;
|
|
||||||
};
|
|
||||||
|
|
||||||
function App() {
|
|
||||||
return (
|
|
||||||
<AuthProvider>
|
|
||||||
<Toaster position="top-right" richColors closeButton />
|
|
||||||
<LoadingOverlayWrapper />
|
|
||||||
<Router>
|
|
||||||
<Suspense fallback={<PageLoader />}>
|
|
||||||
<Routes>
|
|
||||||
{/* Portal Home - System Selection */}
|
|
||||||
<Route path="/plataforma/" element={<PortalHome />} />
|
|
||||||
|
|
||||||
{/* 🔧 COMPONENT LABORATORY - Design System Testing */}
|
|
||||||
<Route path="/plataforma/debug/playground" element={
|
|
||||||
<Suspense fallback={<PageLoader />}>
|
|
||||||
<PlaygroundView />
|
|
||||||
</Suspense>
|
|
||||||
} />
|
|
||||||
|
|
||||||
{/* Auth Login - Explícitos */}
|
|
||||||
<Route path="/plataforma/auth/login" element={<LoginPage />} />
|
|
||||||
<Route path="/plataforma/auth/login-finance" element={<FinanceLogin />} />
|
|
||||||
<Route path="/plataforma/auth/login-cnab" element={<CnabLogin />} />
|
|
||||||
{/* Fleet Management Management (Legacy) */}
|
|
||||||
<Route path="/plataforma/fleet">
|
|
||||||
<Route path="login" element={<FleetLogin />} />
|
|
||||||
<Route path="dashboard" element={
|
|
||||||
<ProtectedRoute loginPath="/plataforma/fleet/login" environment="fleet">
|
|
||||||
<FleetDashboard />
|
|
||||||
</ProtectedRoute>
|
|
||||||
} />
|
|
||||||
<Route index element={<Navigate to="/plataforma/fleet/login" replace />} />
|
|
||||||
</Route>
|
|
||||||
{/* HR Management (Modern) */}
|
|
||||||
<Route path="/plataforma/rh/*" element={<RhRoutes />} />
|
|
||||||
{/* Fleet V2 Environment - Protegido */}
|
|
||||||
<Route path="/plataforma/fleet-v2/*" element={
|
|
||||||
<ProtectedRoute loginPath="/plataforma/auth/login" environment="fleet">
|
|
||||||
<FleetV2App />
|
|
||||||
</ProtectedRoute>
|
|
||||||
} />
|
|
||||||
|
|
||||||
{/* Financeiro V2 Environment - Protegido */}
|
|
||||||
<Route path="/plataforma/financeiro-v2/*" element={
|
|
||||||
<ProtectedRoute loginPath="/plataforma/auth/login-finance" environment="financeiro">
|
|
||||||
<FinanceiroV2App />
|
|
||||||
</ProtectedRoute>
|
|
||||||
} />
|
|
||||||
|
|
||||||
{/* Prafrot Environment */}
|
|
||||||
<Route path="/plataforma/prafrot">
|
|
||||||
<Route path="login" element={<PrafrotLogin />} />
|
|
||||||
<Route path="*" element={
|
|
||||||
<ProtectedRoute loginPath="/plataforma/prafrot/login" environment="prafrot">
|
|
||||||
<PrafrotRoutes />
|
|
||||||
</ProtectedRoute>
|
|
||||||
} />
|
|
||||||
<Route index element={<Navigate to="/plataforma/prafrot/login" replace />} />
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
<Route path="/plataforma/solicitacao-viagem" element={
|
|
||||||
<Suspense fallback={<PageLoader />}>
|
|
||||||
<DriverPortalView />
|
|
||||||
</Suspense>
|
|
||||||
} />
|
|
||||||
|
|
||||||
{/* GR Environment (Gestão de Risco) */}
|
|
||||||
<Route path="/plataforma/gr">
|
|
||||||
<Route path="login" element={<GrLogin />} />
|
|
||||||
<Route path="reset-senha" element={<GrResetPassword />} />
|
|
||||||
<Route path="*" element={
|
|
||||||
<ProtectedRoute loginPath="/plataforma/gr/login" environment="gr">
|
|
||||||
<GrRoutes />
|
|
||||||
</ProtectedRoute>
|
|
||||||
} />
|
|
||||||
<Route index element={<Navigate to="/plataforma/gr/login" replace />} />
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
{/* Workspace Environment - Novo Ambiente Modernizado */}
|
|
||||||
<Route path="/plataforma/workspace/login" element={<LoginView />} />
|
|
||||||
<Route path="/plataforma/workspace" element={
|
|
||||||
<WorkspaceGuard>
|
|
||||||
<WorkspaceLayout />
|
|
||||||
</WorkspaceGuard>
|
|
||||||
} />
|
|
||||||
<Route path="/plataforma/workspace/*" element={
|
|
||||||
<WorkspaceGuard>
|
|
||||||
<WorkspaceLayout />
|
|
||||||
</WorkspaceGuard>
|
|
||||||
} />
|
|
||||||
|
|
||||||
{/* Financeiro CNAB Environment */}
|
|
||||||
<Route path="/plataforma/financeiro-cnab/*" element={
|
|
||||||
<ProtectedRoute loginPath="/plataforma/auth/login-cnab" environment="financeiro">
|
|
||||||
<CnabRoutes />
|
|
||||||
</ProtectedRoute>
|
|
||||||
} />
|
|
||||||
|
|
||||||
{/* Auto Lab Environment */}
|
|
||||||
<Route path="/plataforma/autolab">
|
|
||||||
<Route path="login" element={<AutoLabLogin />} />
|
|
||||||
<Route path="*" element={
|
|
||||||
<ProtectedRoute loginPath="/plataforma/autolab/login" environment="autolab">
|
|
||||||
<AutoLabRoutes />
|
|
||||||
</ProtectedRoute>
|
|
||||||
} />
|
|
||||||
<Route index element={<Navigate to="/plataforma/autolab/login" replace />} />
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
{/* Oeste Pan Environment */}
|
|
||||||
<Route path="/plataforma/oest-pan">
|
|
||||||
<Route path="login" element={<OestPanLogin />} />
|
|
||||||
<Route path="*" element={
|
|
||||||
<ProtectedRoute loginPath="/plataforma/oest-pan/login" environment="auth_oestepan">
|
|
||||||
<OestPanRoutes />
|
|
||||||
</ProtectedRoute>
|
|
||||||
} />
|
|
||||||
<Route index element={<Navigate to="/plataforma/oest-pan/login" replace />} />
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
|
|
||||||
{/* Fallback */}
|
|
||||||
<Route path="*" element={<Navigate to="/plataforma/" replace />} />
|
|
||||||
|
|
||||||
{/* GR Public Routes */}
|
|
||||||
<Route path="/plataforma/cadastro-motorista" element={
|
|
||||||
<Suspense fallback={<PageLoader />}>
|
|
||||||
<ExternalDriverRegistration />
|
|
||||||
</Suspense>
|
|
||||||
} />
|
|
||||||
</Routes>
|
|
||||||
</Suspense>
|
|
||||||
</Router>
|
|
||||||
</AuthProvider>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrapper component to use the hook inside the provider context if needed,
|
|
||||||
// though here it's at the top level so we just need to import the store.
|
|
||||||
const LoadingOverlayWrapper = () => {
|
|
||||||
const { isLoading, loadingMessage } = useGlobalLoading();
|
|
||||||
return <LoadingOverlay isLoading={isLoading} message={loadingMessage} fullScreen />;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default App;
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
Copyright (c) 2010-2014 by tyPoland Lukasz Dziedzic (team@latofonts.com) with Reserved Font Name "Lato"
|
|
||||||
|
|
||||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
||||||
This license is copied below, and is also available with a FAQ at:
|
|
||||||
https://openfontlicense.org
|
|
||||||
|
|
||||||
|
|
||||||
-----------------------------------------------------------
|
|
||||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
||||||
-----------------------------------------------------------
|
|
||||||
|
|
||||||
PREAMBLE
|
|
||||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
||||||
development of collaborative font projects, to support the font creation
|
|
||||||
efforts of academic and linguistic communities, and to provide a free and
|
|
||||||
open framework in which fonts may be shared and improved in partnership
|
|
||||||
with others.
|
|
||||||
|
|
||||||
The OFL allows the licensed fonts to be used, studied, modified and
|
|
||||||
redistributed freely as long as they are not sold by themselves. The
|
|
||||||
fonts, including any derivative works, can be bundled, embedded,
|
|
||||||
redistributed and/or sold with any software provided that any reserved
|
|
||||||
names are not used by derivative works. The fonts and derivatives,
|
|
||||||
however, cannot be released under any other type of license. The
|
|
||||||
requirement for fonts to remain under this license does not apply
|
|
||||||
to any document created using the fonts or their derivatives.
|
|
||||||
|
|
||||||
DEFINITIONS
|
|
||||||
"Font Software" refers to the set of files released by the Copyright
|
|
||||||
Holder(s) under this license and clearly marked as such. This may
|
|
||||||
include source files, build scripts and documentation.
|
|
||||||
|
|
||||||
"Reserved Font Name" refers to any names specified as such after the
|
|
||||||
copyright statement(s).
|
|
||||||
|
|
||||||
"Original Version" refers to the collection of Font Software components as
|
|
||||||
distributed by the Copyright Holder(s).
|
|
||||||
|
|
||||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
||||||
or substituting -- in part or in whole -- any of the components of the
|
|
||||||
Original Version, by changing formats or by porting the Font Software to a
|
|
||||||
new environment.
|
|
||||||
|
|
||||||
"Author" refers to any designer, engineer, programmer, technical
|
|
||||||
writer or other person who contributed to the Font Software.
|
|
||||||
|
|
||||||
PERMISSION & CONDITIONS
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
||||||
redistribute, and sell modified and unmodified copies of the Font
|
|
||||||
Software, subject to the following conditions:
|
|
||||||
|
|
||||||
1) Neither the Font Software nor any of its individual components,
|
|
||||||
in Original or Modified Versions, may be sold by itself.
|
|
||||||
|
|
||||||
2) Original or Modified Versions of the Font Software may be bundled,
|
|
||||||
redistributed and/or sold with any software, provided that each copy
|
|
||||||
contains the above copyright notice and this license. These can be
|
|
||||||
included either as stand-alone text files, human-readable headers or
|
|
||||||
in the appropriate machine-readable metadata fields within text or
|
|
||||||
binary files as long as those fields can be easily viewed by the user.
|
|
||||||
|
|
||||||
3) No Modified Version of the Font Software may use the Reserved Font
|
|
||||||
Name(s) unless explicit written permission is granted by the corresponding
|
|
||||||
Copyright Holder. This restriction only applies to the primary font name as
|
|
||||||
presented to the users.
|
|
||||||
|
|
||||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
||||||
Software shall not be used to promote, endorse or advertise any
|
|
||||||
Modified Version, except to acknowledge the contribution(s) of the
|
|
||||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
||||||
permission.
|
|
||||||
|
|
||||||
5) The Font Software, modified or unmodified, in part or in whole,
|
|
||||||
must be distributed entirely under this license, and must not be
|
|
||||||
distributed under any other license. The requirement for fonts to
|
|
||||||
remain under this license does not apply to any document created
|
|
||||||
using the Font Software.
|
|
||||||
|
|
||||||
TERMINATION
|
|
||||||
This license becomes null and void if any of the above conditions are
|
|
||||||
not met.
|
|
||||||
|
|
||||||
DISCLAIMER
|
|
||||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
||||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
||||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
||||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
||||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
||||||
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 17 KiB |