@luanpdd/kit-mcp 1.35.0 → 1.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +2 -2
- package/bin/mcp.js +6 -6
- package/bin/ui.js +74 -74
- package/gates/ai-prompt-stability.md +120 -120
- package/gates/budget-description.md +68 -68
- package/gates/confidence.md +29 -29
- package/gates/dependency-check.md +33 -33
- package/gates/dept-cycle-prevention.md +179 -179
- package/gates/golden-signals-coverage.md +133 -133
- package/gates/legacy-refactor-safety.md +178 -178
- package/gates/multi-tenant-rls-coverage.md +102 -102
- package/gates/no-personal-uuid.md +72 -72
- package/gates/obs-agents-mcp-supabase.md +86 -86
- package/gates/obs-skills-frontmatter.md +76 -76
- package/gates/observability-coverage.md +151 -151
- package/gates/omm-no-regression.md +83 -83
- package/gates/postmortem-template-required.md +127 -127
- package/gates/prr-checklist-coverage.md +128 -128
- package/gates/regression.md +32 -32
- package/gates/release-pipeline-policy.md +132 -132
- package/gates/secrets-scan.md +33 -33
- package/gates/service-role-not-in-user-facing.md +113 -113
- package/gates/skill-must-include.md +71 -71
- package/gates/sync-idempotent.md +62 -62
- package/gates/verify-phase-goal.md +34 -34
- package/kit/agents/designer-ui.md +216 -216
- package/kit/agents/workflow-generator.md +537 -167
- package/kit/commands/adicionar-backlog.md +1 -1
- package/kit/commands/adicionar-fase.md +1 -1
- package/kit/commands/adicionar-tarefa.md +1 -1
- package/kit/commands/auditar-observabilidade.md +103 -103
- package/kit/commands/auditar-toil.md +129 -129
- package/kit/commands/caracterizar-prompt.md +195 -195
- package/kit/commands/criar-workflow.md +158 -158
- package/kit/commands/definir-perfil.md +1 -1
- package/kit/commands/definir-slo.md +108 -108
- package/kit/commands/fio.md +1 -1
- package/kit/commands/golden-signals.md +142 -142
- package/kit/commands/instrumentar-fase.md +200 -200
- package/kit/commands/investigar-producao.md +162 -162
- package/kit/commands/observabilidade.md +118 -118
- package/kit/commands/postmortem.md +179 -179
- package/kit/commands/prr.md +205 -205
- package/kit/commands/publicar-rapido.md +207 -207
- package/kit/commands/risk-budget.md +220 -220
- package/kit/commands/sre.md +230 -230
- package/kit/file-manifest.json +424 -424
- package/kit/framework/references/output-style.md +22 -22
- package/kit/hooks/post-apply-migration.js +199 -199
- package/kit/hooks/sidecar-tool-publisher.js +210 -210
- package/kit/skills/_shared-dados-distribuidos/glossary.md +224 -224
- package/kit/skills/_shared-legacy/glossary.md +389 -389
- package/kit/skills/_shared-multi-tenant/glossary.md +186 -186
- package/kit/skills/_shared-observability/glossary.md +396 -396
- package/kit/skills/_shared-sre/glossary.md +712 -712
- package/kit/skills/_shared-supabase/glossary.md +234 -234
- package/kit/skills/blameless-postmortems/SKILL.md +340 -340
- package/kit/skills/burn-rate-alerting/SKILL.md +258 -258
- package/kit/skills/cascading-failures/SKILL.md +311 -311
- package/kit/skills/core-analysis-loop/SKILL.md +352 -352
- package/kit/skills/distributed-tracing/SKILL.md +362 -362
- package/kit/skills/dynamic-workflow-authoring/SKILL.md +327 -223
- package/kit/skills/eliminating-toil/SKILL.md +243 -243
- package/kit/skills/event-based-slos/SKILL.md +296 -296
- package/kit/skills/four-golden-signals/SKILL.md +314 -314
- package/kit/skills/hermetic-builds/SKILL.md +323 -323
- package/kit/skills/legacy-monster-methods/SKILL.md +444 -444
- package/kit/skills/llm-as-dependency/SKILL.md +436 -436
- package/kit/skills/load-shedding-graceful-degradation/SKILL.md +396 -396
- package/kit/skills/observability-driven-development/SKILL.md +315 -315
- package/kit/skills/observability-maturity-model/SKILL.md +222 -222
- package/kit/skills/opentelemetry-standard/SKILL.md +351 -351
- package/kit/skills/production-readiness-review/SKILL.md +305 -305
- package/kit/skills/release-engineering/SKILL.md +367 -367
- package/kit/skills/retry-strategies/SKILL.md +372 -372
- package/kit/skills/sre-risk-management/SKILL.md +221 -221
- package/kit/skills/structured-events/SKILL.md +265 -265
- package/kit/skills/supabase-cron-queues/SKILL.md +275 -275
- package/kit/skills/supabase-database-functions/SKILL.md +332 -332
- package/kit/skills/supabase-declarative-schema/SKILL.md +183 -183
- package/kit/skills/supabase-pgvector-rag/SKILL.md +253 -253
- package/kit/skills/supabase-postgres-style/SKILL.md +138 -138
- package/kit/skills/supabase-storage/SKILL.md +234 -234
- package/kit/skills/telemetry-pipelines/SKILL.md +259 -259
- package/kit/skills/telemetry-sampling/SKILL.md +256 -256
- package/kit/skills/ui-anti-padroes-ia/SKILL.md +261 -261
- package/kit/skills/ui-contexto-produto/SKILL.md +248 -248
- package/kit/skills/ui-cor-estrategia/SKILL.md +213 -213
- package/kit/skills/ui-critica-auditoria/SKILL.md +260 -260
- package/kit/skills/ui-motion-funcional/SKILL.md +264 -264
- package/kit/skills/ui-ritmo-espacial/SKILL.md +259 -259
- package/kit/skills/ui-tipografia/SKILL.md +211 -211
- package/package.json +1 -1
- package/src/cli/index.js +1114 -1114
- package/src/cli/render.js +194 -194
- package/src/cli/upgrade-check.js +135 -135
- package/src/core/error-redaction.js +76 -76
- package/src/core/failures.js +153 -153
- package/src/core/gate-runner.js +205 -205
- package/src/core/gates.js +82 -82
- package/src/core/logger.js +170 -170
- package/src/core/manifest-verify.js +174 -174
- package/src/core/metrics.js +268 -268
- package/src/core/notify.js +60 -60
- package/src/core/path-safety.js +141 -141
- package/src/core/replays.js +120 -120
- package/src/core/ui.js +185 -185
- package/src/mcp-server/install.js +149 -149
- package/src/mcp-server/roots.js +124 -124
- package/src/ui/auto-spawn.js +113 -113
- package/src/ui/browser.js +78 -78
- package/src/ui/client.js +130 -130
- package/src/ui/events.js +65 -65
- package/src/ui/lockfile.js +191 -191
- package/src/ui/port.js +67 -67
- package/src/ui/server.js +547 -547
- package/src/ui/wrapper.js +129 -129
|
@@ -1,186 +1,186 @@
|
|
|
1
|
-
# Glossário Multi-Tenant SaaS B2B — Termos, Patterns e Convenções
|
|
2
|
-
|
|
3
|
-
> Arquivo de referência compartilhado pelas skills da Suíte Multi-Tenant v1.21. **NÃO é skill** — não tem `description:` triggerável; não aparece em `listKit`. Cross-referenciado pelas 15 skills via Markdown link relativo.
|
|
4
|
-
>
|
|
5
|
-
> **Cross-suite reference ATIVO:** termos Supabase já definidos em [`_shared-supabase/glossary.md`](../_shared-supabase/glossary.md) — esta skill **não duplica**, apenas linka. Termos como `RLS`, `auth.uid()`, `app_metadata`, `service_role`, `pg_cron`, `pgmq`, `STABLE`, `SECURITY INVOKER`, `search_path = ''` são definidos lá.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## (a) Termos PT-BR ↔ EN — Multi-Tenancy Core
|
|
10
|
-
|
|
11
|
-
### Tenancy
|
|
12
|
-
|
|
13
|
-
| EN | PT-BR / Significado |
|
|
14
|
-
|---|---|
|
|
15
|
-
| **tenant** | Inquilino — entidade de top-level que isola dados entre clientes (organização/escritório). Em B2B SaaS = `organizations` row. |
|
|
16
|
-
| **`org_id`** | Coluna canônica em **toda tabela multi-tenant** que identifica a qual `organizations.id` aquela linha pertence. RLS sempre filtra por `org_id`. |
|
|
17
|
-
| **multi-tenant** | App que serve N tenants do mesmo deployment, com isolamento de dados entre eles (tipicamente via RLS). |
|
|
18
|
-
| **single-tenant** | App que serve 1 tenant por deployment (típico enterprise on-prem). |
|
|
19
|
-
| **isolation strategy** | Como tenants são separados — **single schema + `org_id`** (default 90% B2B), schema-per-tenant, ou DB-per-tenant. Ver skill [`b2b-saas-architecture`](../b2b-saas-architecture/SKILL.md). |
|
|
20
|
-
| **cross-tenant query** | Query que toca dados de mais de um tenant — apenas super_admin pode executar. Sempre auditada. |
|
|
21
|
-
| **tenant routing** | Mapeamento URL → tenant. Padrão canônico: `/orgs/[slug]/...`. |
|
|
22
|
-
|
|
23
|
-
### Hierarquia
|
|
24
|
-
|
|
25
|
-
| EN | PT-BR / Significado |
|
|
26
|
-
|---|---|
|
|
27
|
-
| **organization** | Tenant root. Tabela `public.organizations`. Tem `owner_id`, `plan`, `slug` (imutável). |
|
|
28
|
-
| **department** | Sub-divisão opcional de uma org. Tabela `public.departments` com `org_id` FK + `parent_id` para hierarquia (até 5 níveis máx por convenção). |
|
|
29
|
-
| **member** | User pertencente a uma org. Tabela `public.organization_members(org_id, user_id, role_id)`. |
|
|
30
|
-
| **department member** | User pertencente a um dept. Tabela `public.department_members(dept_id, user_id, role_id)`. `role_id` NULL = herda do `organization_members`. |
|
|
31
|
-
| **leader** | Membro de departamento com flag `is_leader = true`. Não é uma role — é capability adicional dentro do dept. |
|
|
32
|
-
|
|
33
|
-
### RBAC
|
|
34
|
-
|
|
35
|
-
| EN | PT-BR / Significado |
|
|
36
|
-
|---|---|
|
|
37
|
-
| **RBAC** | Role-Based Access Control — autorização por role (não por user direto). Cada user tem 1 role por org. |
|
|
38
|
-
| **role** | Função/cargo dentro de uma org. Tabela `public.roles(org_id, name)`. 3 built-in (owner/admin/member) + custom permitidos. |
|
|
39
|
-
| **permission** | Capacidade granular — string `<resource>:<action>` (ex: `leads:create`, `members:invite`). Tabela `public.permissions(action, resource)`. |
|
|
40
|
-
| **permission matrix** | Mapeamento N:M de roles ↔ permissions. Tabela `public.role_permissions(role_id, permission_id)`. |
|
|
41
|
-
| **role inheritance** | Department member sem role própria herda role do organization_members. NULL → herda; preenchido → sobrescreve. |
|
|
42
|
-
| **role escalation rule** | Regra canônica: usuário só pode atribuir roles ≤ ao próprio role (admin não cria owner; member não cria admin). |
|
|
43
|
-
|
|
44
|
-
### Super-admin
|
|
45
|
-
|
|
46
|
-
| EN | PT-BR / Significado |
|
|
47
|
-
|---|---|
|
|
48
|
-
| **super_admin** | Usuário com `app_metadata.super_admin = true` (set apenas via service_role). Bypassa todas as RLS via helper function `private.is_super_admin()`. |
|
|
49
|
-
| **impersonation** | Super-admin assume identidade de outro user temporariamente para suporte. **Sempre** com banner visual + reason obrigatório + TTL 30min. |
|
|
50
|
-
| **platform admin** | Sinônimo de super_admin no contexto B2B SaaS. |
|
|
51
|
-
| **cross-tenant view** | Lista todos tenants para super_admin (Settings → All Organizations). Apenas super_admin enxerga. |
|
|
52
|
-
|
|
53
|
-
### Invite Flow
|
|
54
|
-
|
|
55
|
-
| EN | PT-BR / Significado |
|
|
56
|
-
|---|---|
|
|
57
|
-
| **invitation token** | Hash SHA-256 de uma string aleatória de 32 bytes. Armazenado no banco; raw token enviado por email. Single-use, TTL 7 dias. |
|
|
58
|
-
| **invite state machine** | `pending → accepted | rejected | cancelled | expired`. Transições enforced via trigger ou check constraint. |
|
|
59
|
-
| **email-locked invite** | Invite válido apenas se quem clica está logado com email destino. Anti-pattern: link compartilhável (qualquer um aceita). |
|
|
60
|
-
| **first admin** | Usuário criador da org — ganha role `owner` na criação, sem invite. |
|
|
61
|
-
| **bulk invite** | UI permite invite N emails de uma vez. Cada um gera linha em `org_invites` independente. |
|
|
62
|
-
|
|
63
|
-
### Audit Log
|
|
64
|
-
|
|
65
|
-
| EN | PT-BR / Significado |
|
|
66
|
-
|---|---|
|
|
67
|
-
| **audit log** | Tabela `public.audit_logs` append-only registrando eventos críticos com `tenant_id` indexado. |
|
|
68
|
-
| **append-only table** | Tabela onde `DELETE` e `UPDATE` são revogados via `REVOKE DELETE, UPDATE FROM authenticated`. Apenas service_role pode mutar (via partition swap, raramente). |
|
|
69
|
-
| **event taxonomy** | 7 eventos canônicos mínimos: `login`, `member_invited`, `role_changed`, `data_exported`, `member_removed`, `settings_changed`, `super_admin_action`. |
|
|
70
|
-
| **legal hold** | Flag boolean `legal_hold` em row de audit_log que **bloqueia** delete enquanto DSR LGPD está pendente. |
|
|
71
|
-
| **PII sanitization** | Antes de armazenar em audit_log, hash de `actor_email` e `target_phone` (SHA-256). Nunca raw PII em log. |
|
|
72
|
-
|
|
73
|
-
### LGPD
|
|
74
|
-
|
|
75
|
-
| EN | PT-BR / Significado |
|
|
76
|
-
|---|---|
|
|
77
|
-
| **LGPD** | Lei Geral de Proteção de Dados (Brasil) — Lei 13.709/2018. Equivalente brasileiro do GDPR. |
|
|
78
|
-
| **DSR** | Data Subject Request — pedido formal do titular dos dados exercendo direito previsto em Art. 18 LGPD. SLA legal 15 dias (Art. 19). |
|
|
79
|
-
| **9 direitos LGPD Art. 18** | Confirmação · Acesso · Correção · Anonimização/Bloqueio/Eliminação · Portabilidade · Eliminação · Informação sobre compartilhamento · Revogação de consentimento · Revisão de decisão automatizada |
|
|
80
|
-
| **anonymization** | Padrão de erasure: preservar UUID, apagar PII (`name → NULL`, `email → SHA-256 hash`, `phone → NULL`). Permite manter audit trail sem violar LGPD. |
|
|
81
|
-
| **consent grain** | Granularidade do consentimento — separado por finalidade (analytics ≠ marketing ≠ third-party-share). Default opt-out (Art. 8 §5 LGPD). |
|
|
82
|
-
| **adequacy decision** | Decisão da ANPD/comissão equivalente reconhecendo país como destino seguro de transferência internacional. Brasil-UE estabelecida em jan/2026. |
|
|
83
|
-
|
|
84
|
-
### Webhooks (Evolution Go / Meta Cloud)
|
|
85
|
-
|
|
86
|
-
| EN | PT-BR / Significado |
|
|
87
|
-
|---|---|
|
|
88
|
-
| **Evolution Go** | Implementação alternativa do WhatsApp via biblioteca `whatsmeow` (Go) — usa protocolo WhatsApp Web não-oficial. Não é Meta Cloud API. |
|
|
89
|
-
| **Meta Cloud API** | API oficial WhatsApp Business da Meta. Requer Business Account, número aprovado, custo por conversa. |
|
|
90
|
-
| **HMAC-SHA256 signature** | Validação de webhook Meta — header `X-Hub-Signature-256: sha256=<hmac>`. Computar HMAC sobre **raw body antes de JSON.parse**. |
|
|
91
|
-
| **timing-safe comparison** | Comparação de strings em tempo constante (`crypto.timingSafeEqual`) para evitar timing attacks na validação HMAC. |
|
|
92
|
-
| **idempotency key** | `(org_id, message_id)` unique constraint — `ON CONFLICT DO NOTHING` evita duplicatas em retry Meta (entrega at-least-once). |
|
|
93
|
-
| **webhook event types** | 19 tipos documentados Evolution Go: `messages.upsert`, `messages.update`, `groups.upsert`, etc. |
|
|
94
|
-
| **rate limit Meta** | 80 msg/s default. Exceder = erro 131056, escala para 24h ban. |
|
|
95
|
-
| **throttle Evolution Go** | 1 msg/s (manual, biblioteca não enforce). Acima disso = ban Meta de qualquer forma (mesma infra subjacente). |
|
|
96
|
-
| **conversation state machine** | Modelagem de fluxo conversa WhatsApp (lead → qualified → opt-in → conversation → action). Estados persistidos em PG (não em memória). Implementado com `xstate v5`. |
|
|
97
|
-
|
|
98
|
-
### CRM Lead Pipeline
|
|
99
|
-
|
|
100
|
-
| EN | PT-BR / Significado |
|
|
101
|
-
|---|---|
|
|
102
|
-
| **lead** | Contato em estágio inicial do funil de vendas. Tabela `public.leads(org_id, contact_email, contact_phone, stage, owner_id)`. |
|
|
103
|
-
| **stages canônicos** | `lead → qualified → proposal → negotiation → won | lost`. Transições enforced via trigger BEFORE UPDATE (não só CHECK constraint que client pode burlar). |
|
|
104
|
-
| **ownership transfer** | Mudar `owner_id` de um lead. Sempre dispara: notificação ao novo owner + entry em audit_log com `previous_owner_id, new_owner_id, reason`. |
|
|
105
|
-
| **lead dedup** | Unique constraint `(org_id, contact_phone)` + `(org_id, contact_email)`. Lookup obrigatório antes de criar lead via integração WhatsApp. |
|
|
106
|
-
| **scoring** | Pontuação de lead (manual ou auto). Diferenciador (não table stakes). Out-of-scope v1.21. |
|
|
107
|
-
|
|
108
|
-
### React Patterns
|
|
109
|
-
|
|
110
|
-
| EN | PT-BR / Significado |
|
|
111
|
-
|---|---|
|
|
112
|
-
| **org switcher** | Componente UI que troca tenant ativo. Padrão canônico: URL `/orgs/[slug]/...` (Next.js middleware) ou `useParams()` (Vite SPA). |
|
|
113
|
-
| **permission gate** | Componente declarativo `<PermissionGate permission="leads:create">` que esconde UI quando user não tem permission. **Apenas UX** — server-side enforcement obrigatório via RLS. |
|
|
114
|
-
| **CASL** | Biblioteca canônica RBAC para React 2026. `@casl/ability` 6.8 + `@casl/react` 4.x. Isomorfica (frontend + backend). |
|
|
115
|
-
| **JWT stale** | Após mudança de role, JWT do client ainda tem role antiga até refresh (~1h). Mitigação: `supabase.auth.refreshSession()` imediatamente após operação de role change + RLS como enforcement final. |
|
|
116
|
-
| **shadcn/ui** | Component library copy-paste (não NPM package). Componentes para member management: `data-table`, `dialog`, `select`, `badge`, `dropdown-menu`, `avatar`, `command`, `form`, `toast`. |
|
|
117
|
-
|
|
118
|
-
---
|
|
119
|
-
|
|
120
|
-
## (b) Decisões Arquiteturais Vinculantes (cristalizadas em Phase 106)
|
|
121
|
-
|
|
122
|
-
1. **Single Schema + `org_id` + RLS** é estratégia default (90% B2B). Schema-per-tenant é exceção justificada por compliance.
|
|
123
|
-
2. **JWT minimal** — apenas `super_admin: bool` em `app_metadata`. Lista de orgs no JWT é anti-pattern.
|
|
124
|
-
3. **Helper functions PG STABLE** — todas as funções `private.is_member_of`, `private.has_role`, `private.has_permission`, `private.is_super_admin` marcadas `STABLE`. VOLATILE = re-execução por linha.
|
|
125
|
-
4. **7 tabelas core** — `organizations`, `departments`, `roles`, `permissions`, `role_permissions`, `organization_members`, `department_members` (+ auxiliar `organization_slug_history`).
|
|
126
|
-
5. **Slug imutável** com redirect trail via `organization_slug_history`. Mutação direta = bookmarks/webhooks/OAuth quebram.
|
|
127
|
-
6. **Audit log append-only** — REVOKE DELETE, UPDATE para `authenticated`. Apenas service_role pode mutar.
|
|
128
|
-
7. **DSR erasure via anonymization** — preserva UUID, apaga PII. Hard delete destrói audit trail.
|
|
129
|
-
8. **HMAC validation antes de JSON.parse** — sobre raw body. Validar após parse = inválido.
|
|
130
|
-
|
|
131
|
-
---
|
|
132
|
-
|
|
133
|
-
## (c) Convenções de Naming (todas as tabelas multi-tenant)
|
|
134
|
-
|
|
135
|
-
| Padrão | Exemplo |
|
|
136
|
-
|---|---|
|
|
137
|
-
| Tabelas em snake_case plural | `organizations`, `organization_members`, `department_members`, `role_permissions` |
|
|
138
|
-
| Colunas em snake_case singular | `org_id`, `user_id`, `role_id`, `created_at`, `is_leader` |
|
|
139
|
-
| FK naming `<entidade>_id` | `org_id`, `user_id`, `dept_id`, `role_id`, `permission_id` |
|
|
140
|
-
| Boolean prefix `is_` ou `has_` | `is_leader`, `is_super_admin`, `is_built_in`, `has_permission` |
|
|
141
|
-
| Timestamps ISO 8601 | `created_at`, `updated_at`, `joined_at`, `expires_at`, `accepted_at` |
|
|
142
|
-
| Helper functions em schema `private` | `private.is_member_of`, `private.has_role`, `private.has_permission`, `private.is_super_admin` |
|
|
143
|
-
| Audit triggers em schema `private` | `private.track_org_slug_change`, `private.create_audit_partition`, `private.on_org_created` |
|
|
144
|
-
|
|
145
|
-
---
|
|
146
|
-
|
|
147
|
-
## (d) Cross-Refs Externos
|
|
148
|
-
|
|
149
|
-
- [Supabase RLS Best Practices](https://makerkit.dev/blog/tutorials/supabase-rls-best-practices)
|
|
150
|
-
- [Supabase Custom Access Token Hook](https://supabase.com/docs/guides/auth/auth-hooks/custom-access-token-hook)
|
|
151
|
-
- [Supabase Supavisor 1M Connections](https://supabase.com/blog/supavisor-1-million)
|
|
152
|
-
- [Meta Developers — WhatsApp Webhooks](https://developers.facebook.com/docs/whatsapp/cloud-api/guides/set-up-webhooks/)
|
|
153
|
-
- [Meta Developers — Messaging Limits](https://developers.facebook.com/docs/whatsapp/messaging-limits/)
|
|
154
|
-
- [Evolution API Documentation](https://doc.evolution-api.com/v2/en/configuration/webhooks)
|
|
155
|
-
- [LGPD Brazil — Lei 13.709/2018](https://www.planalto.gov.br/ccivil_03/_ato2015-2018/2018/lei/l13709.htm)
|
|
156
|
-
- [ANPD — International Data Transfers Deadline 2025](https://www.mydata-trust.com/2025/08/19/brazil-data-transfers-deadline/)
|
|
157
|
-
- [CASL Documentation](https://casl.js.org/)
|
|
158
|
-
- [shadcn/ui](https://ui.shadcn.com/)
|
|
159
|
-
|
|
160
|
-
---
|
|
161
|
-
|
|
162
|
-
## (e) Cross-Suite Invocation Pattern (introduzido v1.21)
|
|
163
|
-
|
|
164
|
-
Agents da Suíte Multi-Tenant **não duplicam** lógica Supabase. Padrão canônico de delegação:
|
|
165
|
-
|
|
166
|
-
```
|
|
167
|
-
b2b-saas-architect (v1.21)
|
|
168
|
-
└─→ Task(supabase-architect) # plano de migration + tier/branches
|
|
169
|
-
└─→ Task(supabase-migration-writer) # SQL final
|
|
170
|
-
|
|
171
|
-
multi-tenant-rls-writer (v1.21)
|
|
172
|
-
├─ herda anti-pitfalls supabase-rls-writer (v1.8) via cross-ref Markdown
|
|
173
|
-
└─ adiciona helper functions hierárquicas + super_admin bypass
|
|
174
|
-
|
|
175
|
-
evolution-go-integrator (v1.21)
|
|
176
|
-
└─→ Task(supabase-edge-fn-writer) # Deno code da Edge Function
|
|
177
|
-
|
|
178
|
-
audit-log-implementer (v1.21)
|
|
179
|
-
└─ usa skill supabase-cron-queues (v1.8) para retention scheduling
|
|
180
|
-
|
|
181
|
-
org-onboarding-implementer (v1.21)
|
|
182
|
-
├─→ Task(supabase-migration-writer) # migration de criação de org
|
|
183
|
-
└─→ Task(supabase-edge-fn-writer) # Edge Function setup wizard
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
**Anti-pattern:** agent v1.21 reescrever lógica de RLS do zero (deve herdar e estender). Agent v1.21 escrever Edge Function direto (deve delegar para `supabase-edge-fn-writer`).
|
|
1
|
+
# Glossário Multi-Tenant SaaS B2B — Termos, Patterns e Convenções
|
|
2
|
+
|
|
3
|
+
> Arquivo de referência compartilhado pelas skills da Suíte Multi-Tenant v1.21. **NÃO é skill** — não tem `description:` triggerável; não aparece em `listKit`. Cross-referenciado pelas 15 skills via Markdown link relativo.
|
|
4
|
+
>
|
|
5
|
+
> **Cross-suite reference ATIVO:** termos Supabase já definidos em [`_shared-supabase/glossary.md`](../_shared-supabase/glossary.md) — esta skill **não duplica**, apenas linka. Termos como `RLS`, `auth.uid()`, `app_metadata`, `service_role`, `pg_cron`, `pgmq`, `STABLE`, `SECURITY INVOKER`, `search_path = ''` são definidos lá.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## (a) Termos PT-BR ↔ EN — Multi-Tenancy Core
|
|
10
|
+
|
|
11
|
+
### Tenancy
|
|
12
|
+
|
|
13
|
+
| EN | PT-BR / Significado |
|
|
14
|
+
|---|---|
|
|
15
|
+
| **tenant** | Inquilino — entidade de top-level que isola dados entre clientes (organização/escritório). Em B2B SaaS = `organizations` row. |
|
|
16
|
+
| **`org_id`** | Coluna canônica em **toda tabela multi-tenant** que identifica a qual `organizations.id` aquela linha pertence. RLS sempre filtra por `org_id`. |
|
|
17
|
+
| **multi-tenant** | App que serve N tenants do mesmo deployment, com isolamento de dados entre eles (tipicamente via RLS). |
|
|
18
|
+
| **single-tenant** | App que serve 1 tenant por deployment (típico enterprise on-prem). |
|
|
19
|
+
| **isolation strategy** | Como tenants são separados — **single schema + `org_id`** (default 90% B2B), schema-per-tenant, ou DB-per-tenant. Ver skill [`b2b-saas-architecture`](../b2b-saas-architecture/SKILL.md). |
|
|
20
|
+
| **cross-tenant query** | Query que toca dados de mais de um tenant — apenas super_admin pode executar. Sempre auditada. |
|
|
21
|
+
| **tenant routing** | Mapeamento URL → tenant. Padrão canônico: `/orgs/[slug]/...`. |
|
|
22
|
+
|
|
23
|
+
### Hierarquia
|
|
24
|
+
|
|
25
|
+
| EN | PT-BR / Significado |
|
|
26
|
+
|---|---|
|
|
27
|
+
| **organization** | Tenant root. Tabela `public.organizations`. Tem `owner_id`, `plan`, `slug` (imutável). |
|
|
28
|
+
| **department** | Sub-divisão opcional de uma org. Tabela `public.departments` com `org_id` FK + `parent_id` para hierarquia (até 5 níveis máx por convenção). |
|
|
29
|
+
| **member** | User pertencente a uma org. Tabela `public.organization_members(org_id, user_id, role_id)`. |
|
|
30
|
+
| **department member** | User pertencente a um dept. Tabela `public.department_members(dept_id, user_id, role_id)`. `role_id` NULL = herda do `organization_members`. |
|
|
31
|
+
| **leader** | Membro de departamento com flag `is_leader = true`. Não é uma role — é capability adicional dentro do dept. |
|
|
32
|
+
|
|
33
|
+
### RBAC
|
|
34
|
+
|
|
35
|
+
| EN | PT-BR / Significado |
|
|
36
|
+
|---|---|
|
|
37
|
+
| **RBAC** | Role-Based Access Control — autorização por role (não por user direto). Cada user tem 1 role por org. |
|
|
38
|
+
| **role** | Função/cargo dentro de uma org. Tabela `public.roles(org_id, name)`. 3 built-in (owner/admin/member) + custom permitidos. |
|
|
39
|
+
| **permission** | Capacidade granular — string `<resource>:<action>` (ex: `leads:create`, `members:invite`). Tabela `public.permissions(action, resource)`. |
|
|
40
|
+
| **permission matrix** | Mapeamento N:M de roles ↔ permissions. Tabela `public.role_permissions(role_id, permission_id)`. |
|
|
41
|
+
| **role inheritance** | Department member sem role própria herda role do organization_members. NULL → herda; preenchido → sobrescreve. |
|
|
42
|
+
| **role escalation rule** | Regra canônica: usuário só pode atribuir roles ≤ ao próprio role (admin não cria owner; member não cria admin). |
|
|
43
|
+
|
|
44
|
+
### Super-admin
|
|
45
|
+
|
|
46
|
+
| EN | PT-BR / Significado |
|
|
47
|
+
|---|---|
|
|
48
|
+
| **super_admin** | Usuário com `app_metadata.super_admin = true` (set apenas via service_role). Bypassa todas as RLS via helper function `private.is_super_admin()`. |
|
|
49
|
+
| **impersonation** | Super-admin assume identidade de outro user temporariamente para suporte. **Sempre** com banner visual + reason obrigatório + TTL 30min. |
|
|
50
|
+
| **platform admin** | Sinônimo de super_admin no contexto B2B SaaS. |
|
|
51
|
+
| **cross-tenant view** | Lista todos tenants para super_admin (Settings → All Organizations). Apenas super_admin enxerga. |
|
|
52
|
+
|
|
53
|
+
### Invite Flow
|
|
54
|
+
|
|
55
|
+
| EN | PT-BR / Significado |
|
|
56
|
+
|---|---|
|
|
57
|
+
| **invitation token** | Hash SHA-256 de uma string aleatória de 32 bytes. Armazenado no banco; raw token enviado por email. Single-use, TTL 7 dias. |
|
|
58
|
+
| **invite state machine** | `pending → accepted | rejected | cancelled | expired`. Transições enforced via trigger ou check constraint. |
|
|
59
|
+
| **email-locked invite** | Invite válido apenas se quem clica está logado com email destino. Anti-pattern: link compartilhável (qualquer um aceita). |
|
|
60
|
+
| **first admin** | Usuário criador da org — ganha role `owner` na criação, sem invite. |
|
|
61
|
+
| **bulk invite** | UI permite invite N emails de uma vez. Cada um gera linha em `org_invites` independente. |
|
|
62
|
+
|
|
63
|
+
### Audit Log
|
|
64
|
+
|
|
65
|
+
| EN | PT-BR / Significado |
|
|
66
|
+
|---|---|
|
|
67
|
+
| **audit log** | Tabela `public.audit_logs` append-only registrando eventos críticos com `tenant_id` indexado. |
|
|
68
|
+
| **append-only table** | Tabela onde `DELETE` e `UPDATE` são revogados via `REVOKE DELETE, UPDATE FROM authenticated`. Apenas service_role pode mutar (via partition swap, raramente). |
|
|
69
|
+
| **event taxonomy** | 7 eventos canônicos mínimos: `login`, `member_invited`, `role_changed`, `data_exported`, `member_removed`, `settings_changed`, `super_admin_action`. |
|
|
70
|
+
| **legal hold** | Flag boolean `legal_hold` em row de audit_log que **bloqueia** delete enquanto DSR LGPD está pendente. |
|
|
71
|
+
| **PII sanitization** | Antes de armazenar em audit_log, hash de `actor_email` e `target_phone` (SHA-256). Nunca raw PII em log. |
|
|
72
|
+
|
|
73
|
+
### LGPD
|
|
74
|
+
|
|
75
|
+
| EN | PT-BR / Significado |
|
|
76
|
+
|---|---|
|
|
77
|
+
| **LGPD** | Lei Geral de Proteção de Dados (Brasil) — Lei 13.709/2018. Equivalente brasileiro do GDPR. |
|
|
78
|
+
| **DSR** | Data Subject Request — pedido formal do titular dos dados exercendo direito previsto em Art. 18 LGPD. SLA legal 15 dias (Art. 19). |
|
|
79
|
+
| **9 direitos LGPD Art. 18** | Confirmação · Acesso · Correção · Anonimização/Bloqueio/Eliminação · Portabilidade · Eliminação · Informação sobre compartilhamento · Revogação de consentimento · Revisão de decisão automatizada |
|
|
80
|
+
| **anonymization** | Padrão de erasure: preservar UUID, apagar PII (`name → NULL`, `email → SHA-256 hash`, `phone → NULL`). Permite manter audit trail sem violar LGPD. |
|
|
81
|
+
| **consent grain** | Granularidade do consentimento — separado por finalidade (analytics ≠ marketing ≠ third-party-share). Default opt-out (Art. 8 §5 LGPD). |
|
|
82
|
+
| **adequacy decision** | Decisão da ANPD/comissão equivalente reconhecendo país como destino seguro de transferência internacional. Brasil-UE estabelecida em jan/2026. |
|
|
83
|
+
|
|
84
|
+
### Webhooks (Evolution Go / Meta Cloud)
|
|
85
|
+
|
|
86
|
+
| EN | PT-BR / Significado |
|
|
87
|
+
|---|---|
|
|
88
|
+
| **Evolution Go** | Implementação alternativa do WhatsApp via biblioteca `whatsmeow` (Go) — usa protocolo WhatsApp Web não-oficial. Não é Meta Cloud API. |
|
|
89
|
+
| **Meta Cloud API** | API oficial WhatsApp Business da Meta. Requer Business Account, número aprovado, custo por conversa. |
|
|
90
|
+
| **HMAC-SHA256 signature** | Validação de webhook Meta — header `X-Hub-Signature-256: sha256=<hmac>`. Computar HMAC sobre **raw body antes de JSON.parse**. |
|
|
91
|
+
| **timing-safe comparison** | Comparação de strings em tempo constante (`crypto.timingSafeEqual`) para evitar timing attacks na validação HMAC. |
|
|
92
|
+
| **idempotency key** | `(org_id, message_id)` unique constraint — `ON CONFLICT DO NOTHING` evita duplicatas em retry Meta (entrega at-least-once). |
|
|
93
|
+
| **webhook event types** | 19 tipos documentados Evolution Go: `messages.upsert`, `messages.update`, `groups.upsert`, etc. |
|
|
94
|
+
| **rate limit Meta** | 80 msg/s default. Exceder = erro 131056, escala para 24h ban. |
|
|
95
|
+
| **throttle Evolution Go** | 1 msg/s (manual, biblioteca não enforce). Acima disso = ban Meta de qualquer forma (mesma infra subjacente). |
|
|
96
|
+
| **conversation state machine** | Modelagem de fluxo conversa WhatsApp (lead → qualified → opt-in → conversation → action). Estados persistidos em PG (não em memória). Implementado com `xstate v5`. |
|
|
97
|
+
|
|
98
|
+
### CRM Lead Pipeline
|
|
99
|
+
|
|
100
|
+
| EN | PT-BR / Significado |
|
|
101
|
+
|---|---|
|
|
102
|
+
| **lead** | Contato em estágio inicial do funil de vendas. Tabela `public.leads(org_id, contact_email, contact_phone, stage, owner_id)`. |
|
|
103
|
+
| **stages canônicos** | `lead → qualified → proposal → negotiation → won | lost`. Transições enforced via trigger BEFORE UPDATE (não só CHECK constraint que client pode burlar). |
|
|
104
|
+
| **ownership transfer** | Mudar `owner_id` de um lead. Sempre dispara: notificação ao novo owner + entry em audit_log com `previous_owner_id, new_owner_id, reason`. |
|
|
105
|
+
| **lead dedup** | Unique constraint `(org_id, contact_phone)` + `(org_id, contact_email)`. Lookup obrigatório antes de criar lead via integração WhatsApp. |
|
|
106
|
+
| **scoring** | Pontuação de lead (manual ou auto). Diferenciador (não table stakes). Out-of-scope v1.21. |
|
|
107
|
+
|
|
108
|
+
### React Patterns
|
|
109
|
+
|
|
110
|
+
| EN | PT-BR / Significado |
|
|
111
|
+
|---|---|
|
|
112
|
+
| **org switcher** | Componente UI que troca tenant ativo. Padrão canônico: URL `/orgs/[slug]/...` (Next.js middleware) ou `useParams()` (Vite SPA). |
|
|
113
|
+
| **permission gate** | Componente declarativo `<PermissionGate permission="leads:create">` que esconde UI quando user não tem permission. **Apenas UX** — server-side enforcement obrigatório via RLS. |
|
|
114
|
+
| **CASL** | Biblioteca canônica RBAC para React 2026. `@casl/ability` 6.8 + `@casl/react` 4.x. Isomorfica (frontend + backend). |
|
|
115
|
+
| **JWT stale** | Após mudança de role, JWT do client ainda tem role antiga até refresh (~1h). Mitigação: `supabase.auth.refreshSession()` imediatamente após operação de role change + RLS como enforcement final. |
|
|
116
|
+
| **shadcn/ui** | Component library copy-paste (não NPM package). Componentes para member management: `data-table`, `dialog`, `select`, `badge`, `dropdown-menu`, `avatar`, `command`, `form`, `toast`. |
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## (b) Decisões Arquiteturais Vinculantes (cristalizadas em Phase 106)
|
|
121
|
+
|
|
122
|
+
1. **Single Schema + `org_id` + RLS** é estratégia default (90% B2B). Schema-per-tenant é exceção justificada por compliance.
|
|
123
|
+
2. **JWT minimal** — apenas `super_admin: bool` em `app_metadata`. Lista de orgs no JWT é anti-pattern.
|
|
124
|
+
3. **Helper functions PG STABLE** — todas as funções `private.is_member_of`, `private.has_role`, `private.has_permission`, `private.is_super_admin` marcadas `STABLE`. VOLATILE = re-execução por linha.
|
|
125
|
+
4. **7 tabelas core** — `organizations`, `departments`, `roles`, `permissions`, `role_permissions`, `organization_members`, `department_members` (+ auxiliar `organization_slug_history`).
|
|
126
|
+
5. **Slug imutável** com redirect trail via `organization_slug_history`. Mutação direta = bookmarks/webhooks/OAuth quebram.
|
|
127
|
+
6. **Audit log append-only** — REVOKE DELETE, UPDATE para `authenticated`. Apenas service_role pode mutar.
|
|
128
|
+
7. **DSR erasure via anonymization** — preserva UUID, apaga PII. Hard delete destrói audit trail.
|
|
129
|
+
8. **HMAC validation antes de JSON.parse** — sobre raw body. Validar após parse = inválido.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## (c) Convenções de Naming (todas as tabelas multi-tenant)
|
|
134
|
+
|
|
135
|
+
| Padrão | Exemplo |
|
|
136
|
+
|---|---|
|
|
137
|
+
| Tabelas em snake_case plural | `organizations`, `organization_members`, `department_members`, `role_permissions` |
|
|
138
|
+
| Colunas em snake_case singular | `org_id`, `user_id`, `role_id`, `created_at`, `is_leader` |
|
|
139
|
+
| FK naming `<entidade>_id` | `org_id`, `user_id`, `dept_id`, `role_id`, `permission_id` |
|
|
140
|
+
| Boolean prefix `is_` ou `has_` | `is_leader`, `is_super_admin`, `is_built_in`, `has_permission` |
|
|
141
|
+
| Timestamps ISO 8601 | `created_at`, `updated_at`, `joined_at`, `expires_at`, `accepted_at` |
|
|
142
|
+
| Helper functions em schema `private` | `private.is_member_of`, `private.has_role`, `private.has_permission`, `private.is_super_admin` |
|
|
143
|
+
| Audit triggers em schema `private` | `private.track_org_slug_change`, `private.create_audit_partition`, `private.on_org_created` |
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## (d) Cross-Refs Externos
|
|
148
|
+
|
|
149
|
+
- [Supabase RLS Best Practices](https://makerkit.dev/blog/tutorials/supabase-rls-best-practices)
|
|
150
|
+
- [Supabase Custom Access Token Hook](https://supabase.com/docs/guides/auth/auth-hooks/custom-access-token-hook)
|
|
151
|
+
- [Supabase Supavisor 1M Connections](https://supabase.com/blog/supavisor-1-million)
|
|
152
|
+
- [Meta Developers — WhatsApp Webhooks](https://developers.facebook.com/docs/whatsapp/cloud-api/guides/set-up-webhooks/)
|
|
153
|
+
- [Meta Developers — Messaging Limits](https://developers.facebook.com/docs/whatsapp/messaging-limits/)
|
|
154
|
+
- [Evolution API Documentation](https://doc.evolution-api.com/v2/en/configuration/webhooks)
|
|
155
|
+
- [LGPD Brazil — Lei 13.709/2018](https://www.planalto.gov.br/ccivil_03/_ato2015-2018/2018/lei/l13709.htm)
|
|
156
|
+
- [ANPD — International Data Transfers Deadline 2025](https://www.mydata-trust.com/2025/08/19/brazil-data-transfers-deadline/)
|
|
157
|
+
- [CASL Documentation](https://casl.js.org/)
|
|
158
|
+
- [shadcn/ui](https://ui.shadcn.com/)
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## (e) Cross-Suite Invocation Pattern (introduzido v1.21)
|
|
163
|
+
|
|
164
|
+
Agents da Suíte Multi-Tenant **não duplicam** lógica Supabase. Padrão canônico de delegação:
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
b2b-saas-architect (v1.21)
|
|
168
|
+
└─→ Task(supabase-architect) # plano de migration + tier/branches
|
|
169
|
+
└─→ Task(supabase-migration-writer) # SQL final
|
|
170
|
+
|
|
171
|
+
multi-tenant-rls-writer (v1.21)
|
|
172
|
+
├─ herda anti-pitfalls supabase-rls-writer (v1.8) via cross-ref Markdown
|
|
173
|
+
└─ adiciona helper functions hierárquicas + super_admin bypass
|
|
174
|
+
|
|
175
|
+
evolution-go-integrator (v1.21)
|
|
176
|
+
└─→ Task(supabase-edge-fn-writer) # Deno code da Edge Function
|
|
177
|
+
|
|
178
|
+
audit-log-implementer (v1.21)
|
|
179
|
+
└─ usa skill supabase-cron-queues (v1.8) para retention scheduling
|
|
180
|
+
|
|
181
|
+
org-onboarding-implementer (v1.21)
|
|
182
|
+
├─→ Task(supabase-migration-writer) # migration de criação de org
|
|
183
|
+
└─→ Task(supabase-edge-fn-writer) # Edge Function setup wizard
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**Anti-pattern:** agent v1.21 reescrever lógica de RLS do zero (deve herdar e estender). Agent v1.21 escrever Edge Function direto (deve delegar para `supabase-edge-fn-writer`).
|