feat(web): telas de Estoque e Faturamento no EDEN Core
Continuação direta, sem parar para autorização (a pedido do usuário). 2 subagentes eden-frontend em paralelo. - Estoque: armazéns (CRUD), ativos com ações contextuais por status (só oferece Reservar/Instalar/Devolver quando válido para o status atual), entrada de ativo, detalhe com histórico de movimentos, ledger só-leitura, reservas genéricas. Achado real documentado no código: install/return gravam o movimento com reference_type='contract', não 'serialized_asset' — filtrar o ledger só pelo id do ativo nunca traz esse histórico; contornado buscando também pelos movimentos do contrato atual do ativo, registrado como pendência de backend. - Faturamento: assinaturas (valor mensal pré-preenchido do contrato, editável com aviso), fechamentos (aviso de idempotência ao regerar), detalhe do fechamento com tabela de faturas + consolidação com confirmação em duas etapas (irreversível), lista de faturas. Reconciliação manual de App.tsx/AuthenticatedLayout.tsx entre os 2 agentes, confirmando typecheck limpo a cada mesclagem. Um dos agentes restaurou a base do zero (sem git merge) — comparação byte a byte (diff -rq) contra main confirmou zero desvio antes de aceitar qualquer arquivo como genuinamente novo. Verificado: pnpm turbo run typecheck build (28/28); containers eden-api/eden-core reconstruídos; testado ao vivo através do proxy same-origin (porta 3001); trilha de auditoria conferida no Postgres. Os próprios agentes já haviam confirmado ao vivo contra a API real: invariante de serial duplicado (409), ciclo completo de ativo, e o fluxo idempotente de billing (gerar→regenerar→consolidar→409). Claude-Session: https://claude.ai/code/session_01BcWWuKfykGtUweXmHD6cKx Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
37
apps/core-web/src/routes/billing/BillingSubNav.tsx
Normal file
37
apps/core-web/src/routes/billing/BillingSubNav.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import { Link, useLocation } from "react-router-dom";
|
||||
|
||||
/**
|
||||
* Only one top-level nav slot is allocated for Billing ("Faturamento" →
|
||||
* /billing/subscriptions, per AuthenticatedLayout.tsx) but the module has
|
||||
* three screens (Assinaturas, Fechamentos, Faturas) — same problem CRM
|
||||
* solved with `CrmSubNav` (src/routes/crm/CrmSubNav.tsx), replicated here:
|
||||
* an in-page toggle instead of three top-level nav entries.
|
||||
*/
|
||||
const TABS = [
|
||||
{ key: "subscriptions", label: "Assinaturas", href: "/billing/subscriptions" },
|
||||
{ key: "runs", label: "Fechamentos", href: "/billing/runs" },
|
||||
{ key: "invoices", label: "Faturas", href: "/billing/invoices" },
|
||||
] as const;
|
||||
|
||||
export function BillingSubNav() {
|
||||
const location = useLocation();
|
||||
|
||||
return (
|
||||
<div className="mb-4 inline-flex rounded-md border border-border-color bg-white p-1">
|
||||
{TABS.map((tab) => {
|
||||
const active = location.pathname.startsWith(tab.href);
|
||||
return (
|
||||
<Link
|
||||
key={tab.key}
|
||||
to={tab.href}
|
||||
className={`rounded px-3 py-1.5 text-sm font-semibold ${
|
||||
active ? "bg-dark text-white" : "text-default hover:bg-light"
|
||||
}`}
|
||||
>
|
||||
{tab.label}
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user