ZERADO
This commit is contained in:
@@ -0,0 +1,231 @@
|
||||
|
||||
<!doctype html>
|
||||
<html lang="pt-BR">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>Agência PSI — Billing (Arquitetura Oficial v1.1)</title>
|
||||
|
||||
<style>
|
||||
:root{
|
||||
--bg0:#f6f8fc;
|
||||
--bg1:#eef2f8;
|
||||
--panel:rgba(255,255,255,.85);
|
||||
--border:rgba(15,23,42,.10);
|
||||
--text:rgba(15,23,42,.92);
|
||||
--muted:rgba(15,23,42,.70);
|
||||
--accent:#2563eb;
|
||||
--ok:#047857;
|
||||
--warn:#b45309;
|
||||
--danger:#b91c1c;
|
||||
--radius:18px;
|
||||
--shadow:0 18px 60px rgba(2,6,23,.10);
|
||||
--mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
||||
--sans: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial;
|
||||
}
|
||||
*{box-sizing:border-box}
|
||||
body{
|
||||
margin:0;
|
||||
font-family:var(--sans);
|
||||
background:linear-gradient(180deg,var(--bg0),var(--bg1));
|
||||
color:var(--text);
|
||||
}
|
||||
.layout{
|
||||
max-width:1100px;
|
||||
margin:0 auto;
|
||||
padding:40px 20px 80px;
|
||||
}
|
||||
header{
|
||||
border:1px solid var(--border);
|
||||
background:var(--panel);
|
||||
border-radius:var(--radius);
|
||||
padding:28px;
|
||||
box-shadow:var(--shadow);
|
||||
}
|
||||
h1{margin:0 0 12px;font-size:30px}
|
||||
h2{margin-top:40px;font-size:20px}
|
||||
p{color:var(--muted);line-height:1.6}
|
||||
.section{
|
||||
margin-top:30px;
|
||||
border:1px solid var(--border);
|
||||
background:var(--panel);
|
||||
padding:24px;
|
||||
border-radius:var(--radius);
|
||||
box-shadow:var(--shadow);
|
||||
}
|
||||
.rule{
|
||||
border-left:4px solid var(--accent);
|
||||
background:rgba(37,99,235,.08);
|
||||
padding:14px;
|
||||
border-radius:12px;
|
||||
margin:18px 0;
|
||||
}
|
||||
.ok{
|
||||
border-left:4px solid var(--ok);
|
||||
background:rgba(4,120,87,.08);
|
||||
padding:14px;
|
||||
border-radius:12px;
|
||||
margin:18px 0;
|
||||
}
|
||||
.warn{
|
||||
border-left:4px solid var(--warn);
|
||||
background:rgba(180,83,9,.10);
|
||||
padding:14px;
|
||||
border-radius:12px;
|
||||
margin:18px 0;
|
||||
}
|
||||
.danger{
|
||||
border-left:4px solid var(--danger);
|
||||
background:rgba(185,28,28,.08);
|
||||
padding:14px;
|
||||
border-radius:12px;
|
||||
margin:18px 0;
|
||||
}
|
||||
code,pre{font-family:var(--mono);font-size:13px}
|
||||
pre{
|
||||
background:rgba(2,6,23,.05);
|
||||
padding:14px;
|
||||
border-radius:12px;
|
||||
overflow:auto;
|
||||
}
|
||||
table{
|
||||
width:100%;
|
||||
border-collapse:collapse;
|
||||
margin-top:16px;
|
||||
}
|
||||
th,td{
|
||||
border:1px solid var(--border);
|
||||
padding:10px;
|
||||
font-size:13px;
|
||||
}
|
||||
th{background:rgba(15,23,42,.04)}
|
||||
footer{
|
||||
text-align:center;
|
||||
margin-top:50px;
|
||||
font-size:12px;
|
||||
color:var(--muted);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="layout">
|
||||
|
||||
<header>
|
||||
<h1>Billing — Arquitetura Oficial v1.1</h1>
|
||||
<p>Versão 1.1 inclui procedimento formal de migração controlada para planos core, mantendo guardrails ativos e auditáveis.</p>
|
||||
</header>
|
||||
|
||||
<div class="section">
|
||||
<h2>1. Fundamentos do Domínio</h2>
|
||||
<p>Billing define recursos e limites do produto. Não é camada de UI. É camada estrutural.</p>
|
||||
<div class="rule"><strong>Princípio:</strong> Role (RBAC) ≠ Plano (Billing). Plano dirige features e limites; role dirige acesso.</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>2. Planos Core (MVP)</h2>
|
||||
<ul>
|
||||
<li>clinic_free</li>
|
||||
<li>clinic_pro</li>
|
||||
<li>therapist_free</li>
|
||||
<li>therapist_pro</li>
|
||||
</ul>
|
||||
<div class="ok"><strong>Política:</strong> Planos core são estruturalmente protegidos por triggers.</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>3. Governança de Guardrails</h2>
|
||||
<ul>
|
||||
<li>Impedem alterar key de plano core</li>
|
||||
<li>Impedem alterar target de plano core</li>
|
||||
<li>Impedem deletar plano com subscription ativa</li>
|
||||
</ul>
|
||||
<div class="danger"><strong>Proibido:</strong> desabilitar triggers diretamente em produção.</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>4. Procedimento Oficial de Correção de Plano Core</h2>
|
||||
<p>Correções estruturais devem ocorrer via função administrativa controlada.</p>
|
||||
|
||||
<pre>
|
||||
create or replace function admin_fix_plan_target(
|
||||
p_plan_key text,
|
||||
p_new_target text
|
||||
) returns void
|
||||
language plpgsql
|
||||
security definer
|
||||
as $$
|
||||
declare
|
||||
v_plan_id uuid;
|
||||
begin
|
||||
select id into v_plan_id
|
||||
from plans
|
||||
where key = p_plan_key
|
||||
for update;
|
||||
|
||||
if v_plan_id is null then
|
||||
raise exception 'Plano não encontrado.';
|
||||
end if;
|
||||
|
||||
if exists (
|
||||
select 1 from subscriptions where plan_id = v_plan_id
|
||||
) then
|
||||
raise exception 'Plano possui subscriptions ativas.';
|
||||
end if;
|
||||
|
||||
update plans
|
||||
set target = p_new_target
|
||||
where id = v_plan_id;
|
||||
|
||||
end;
|
||||
$$;
|
||||
</pre>
|
||||
|
||||
<div class="warn">
|
||||
Esta função deve ser executada apenas por role administrativa e registrada em log de auditoria.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>5. Entitlements (Contrato Oficial)</h2>
|
||||
<p>Entitlements são derivados exclusivamente de <code>plan_features</code>.</p>
|
||||
<pre>
|
||||
plan_features (
|
||||
plan_id uuid,
|
||||
feature_id uuid,
|
||||
enabled boolean,
|
||||
limits jsonb
|
||||
)
|
||||
</pre>
|
||||
<div class="rule">
|
||||
Formato oficial de limits:
|
||||
{"max": 30}
|
||||
{"per_month": 40}
|
||||
{"max_users": 1}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>6. Preço Vigente</h2>
|
||||
<pre>
|
||||
create unique index uq_plan_price_active
|
||||
on plan_prices (plan_id, interval, currency)
|
||||
where is_active = true and active_to is null;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>7. Onboarding</h2>
|
||||
<ul>
|
||||
<li>Tenant clinic → clinic_free</li>
|
||||
<li>Tenant therapist → therapist_free</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
Agência PSI — Billing Arquitetura Oficial v1.1
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user