Continuação da leva "pelo menos mais 20 etapas" — 2 subagentes em paralelo.
## Documents (apps/api/src/documents/ + migration documents)
Metade "templates + geração" do eden.md módulo 4 (§1.1-1.3): document_templates,
document_template_versions (ciclo draft→publish, no máximo 1 rascunho por
template via índice único parcial, versão publicada imutável), document_generations
(idempotente por (template_version_id, origem), CHECK de origem única). Motor de
merge de variáveis ({{chave}}→valor, nunca lança exceção) como função pura
testável. A metade de Assinatura Eletrônica (envelopes, signatários, OTP,
cadeia de auditoria hash-chain — eden.md §1.4-1.9/§5-7, 9 tabelas satélite)
fica deliberadamente fora — grande e sensível demais para dividir espaço
com esta leva, fica para uma leva própria. PDF real via Chromium também
deferido; document_generations grava rendered_html, pdf_* ficam NULL.
## EDEN Parceiros / EDEN Assinante (apps/reseller-web, apps/subscriber-web)
Replicam o shell autenticado do core-web (leva anterior): login real com
suporte a MFA, sessão, AppShell do Design System — trocando só
applicationKey ("reseller"/"subscriber"), título e chave de localStorage
da sessão. As duas telas "Bootstrap da Fase 1" saem de circulação.
Testado ao vivo contra os containers reais: ciclo completo de template
(criar→draft→409 no segundo draft→editar→publicar→gerar documento com
merge de variáveis funcionando→regeneração idempotente reaproveita o
registro), e login via /v1/auth/login com applicationKey "reseller"/
"subscriber" retornando tokens válidos nos 2 portais reconstruídos.
pnpm turbo run typecheck build (28/28), pnpm --filter @eden/api test
(30/30, sem regressão), trilha de auditoria conferida no Postgres.
Claude-Session: https://claude.ai/code/session_01BcWWuKfykGtUweXmHD6cKx
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
36 lines
987 B
TypeScript
36 lines
987 B
TypeScript
import { useNavigate } from "react-router-dom";
|
|
import { Link, Outlet } from "react-router-dom";
|
|
import { AppShell } from "@eden/ui";
|
|
import type { AppShellNavItem } from "@eden/ui";
|
|
import { useAuth } from "../lib/auth/AuthContext.js";
|
|
|
|
const NAV_ITEMS: AppShellNavItem[] = [{ key: "dashboard", label: "Painel", href: "/", active: true }];
|
|
|
|
export function AuthenticatedLayout() {
|
|
const { user, logout } = useAuth();
|
|
const navigate = useNavigate();
|
|
|
|
async function handleLogout() {
|
|
await logout();
|
|
navigate("/login", { replace: true });
|
|
}
|
|
|
|
return (
|
|
<AppShell
|
|
appName="EDEN Parceiros"
|
|
logoSrc="/eden-logo-horizontal.png"
|
|
navItems={NAV_ITEMS}
|
|
userName={user?.fullName ?? user?.email}
|
|
userRole={user?.roleKey}
|
|
onLogout={handleLogout}
|
|
LinkComponent={({ href, className, children }) => (
|
|
<Link to={href} className={className}>
|
|
{children}
|
|
</Link>
|
|
)}
|
|
>
|
|
<Outlet />
|
|
</AppShell>
|
|
);
|
|
}
|