forlogic-core 2.2.2 → 2.2.3

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.
@@ -70,10 +70,44 @@ supabase.from('tabela').select('*');
70
70
  |-------|---------|
71
71
  | Schema obrigatório | `.schema('...')` em toda query Supabase |
72
72
  | Sem DELETE físico | Soft delete com `deleted_at` |
73
+ | **Sem acesso anon** | RLS policies devem usar `TO authenticated` — **nunca** conceder acesso ao role `anon` sem justificativa documentada |
73
74
  | Lib-first | Usar `forlogic-core` antes de criar componente |
74
75
  | Import do Supabase | `getSupabaseClient()` de `forlogic-core` |
75
76
  | Import de i18n | `useTranslation` de `forlogic-core`, nunca de `react-i18next` |
76
77
  | Sem hardcoded admin | Nunca localStorage/sessionStorage para roles |
78
+ | **PK Override** | `VITE_SUPABASE_PK_OVERRIDE` **obrigatória** no `.env` — nunca remover. Ver `@Admin docs/design-system/patterns/feature-flags.md` |
79
+
80
+ ### Política de acesso `anon` no Supabase
81
+
82
+ **Por padrão, nenhuma tabela, function ou storage policy deve conceder acesso ao role `anon`.**
83
+
84
+ Todas as policies devem usar `TO authenticated` e validar o JWT do tenant:
85
+
86
+ ```sql
87
+ -- ✅ CORRETO
88
+ CREATE POLICY "select" ON schema.tabela
89
+ FOR SELECT TO authenticated
90
+ USING (((SELECT auth.jwt()) ->> 'alias'::text) = alias);
91
+
92
+ -- ❌ ERRADO — nunca usar anon
93
+ CREATE POLICY "select" ON schema.tabela
94
+ FOR SELECT TO anon, authenticated
95
+ USING (true);
96
+ ```
97
+
98
+ **Exceções são permitidas apenas quando:**
99
+
100
+ 1. A funcionalidade é **intencionalmente pública** (ex: validação de certificado, página de candidatura externa)
101
+ 2. A exceção está **documentada na migration SQL** com comentário `-- ANON: <motivo>`
102
+ 3. A exceção está **registrada no `@security-memory`** do projeto
103
+
104
+ **Funções `SECURITY DEFINER`:** por padrão, revogar permissão de `anon`:
105
+
106
+ ```sql
107
+ REVOKE EXECUTE ON FUNCTION schema.minha_funcao FROM anon;
108
+ -- Manter apenas authenticated
109
+ GRANT EXECUTE ON FUNCTION schema.minha_funcao TO authenticated;
110
+ ```
77
111
 
78
112
  ---
79
113
 
@@ -10,6 +10,7 @@
10
10
  | `VITE_SHOW_EDIT_PROFILE` | Exibe "Editar Perfil" no menu do usuário (foto e idioma) | Não exibe |
11
11
  | `VITE_WIKI_URL` | Exibe botão "Wiki" no header da aplicação. O valor é a URL que será aberta ao clicar | Não exibe |
12
12
  | `VITE_SHOW_ADMIN_REPORTS` | Exibe relatórios administrativos | `"false"` |
13
+ | `VITE_SUPABASE_PK_OVERRIDE` | **Obrigatória.** Publishable key correta do Supabase. Ver [seção abaixo](#vite_supabase_pk_override). | — |
13
14
 
14
15
  ## Uso
15
16
 
@@ -19,6 +20,62 @@ VITE_I18N_DEBUG_MODE=false
19
20
  VITE_IS_QUALIEX=true
20
21
  VITE_WIKI_URL=https://wiki.example.com
21
22
  VITE_SHOW_ADMIN_REPORTS=false
23
+ VITE_SUPABASE_PK_OVERRIDE="sb_publishable_w-TKU0hE4bjM_uOgt3fK1g_ewrXKJ8J"
22
24
  ```
23
25
 
24
26
  Variáveis Vite precisam do prefixo `VITE_` para serem expostas ao cliente.
27
+
28
+ ---
29
+
30
+ ## `VITE_SUPABASE_PK_OVERRIDE`
31
+
32
+ ### Problema
33
+
34
+ O Supabase desativou as legacy API keys (formato JWT `eyJhbGci...`). A integração Supabase do Lovable **sobrescreve automaticamente** `VITE_SUPABASE_PUBLISHABLE_KEY` no `.env` com a legacy anon key a cada prompt, causando `401 Unauthorized` em todas as requests.
35
+
36
+ ### Solução
37
+
38
+ A lib `forlogic-core` implementa um mecanismo de override:
39
+
40
+ 1. Se `VITE_SUPABASE_PK_OVERRIDE` existir no `.env` → a lib usa essa key (ignora `VITE_SUPABASE_PUBLISHABLE_KEY`)
41
+ 2. Se não existir → usa `VITE_SUPABASE_PUBLISHABLE_KEY` normalmente
42
+ 3. Se a key ativa for uma JWT legada → exibe banner vermelho no preview (DEV) + erro no console
43
+
44
+ O Lovable **nunca toca** em `VITE_SUPABASE_PK_OVERRIDE` porque só auto-popula estas 3 variáveis:
45
+ - `VITE_SUPABASE_URL`
46
+ - `VITE_SUPABASE_PUBLISHABLE_KEY`
47
+ - `VITE_SUPABASE_PROJECT_ID`
48
+
49
+ ### Configuração obrigatória
50
+
51
+ **Todo projeto consumidor** que aponta para o Supabase `ccjfvpnndclajkleyqkc` deve adicionar no `.env`:
52
+
53
+ ```env
54
+ VITE_SUPABASE_PK_OVERRIDE="sb_publishable_w-TKU0hE4bjM_uOgt3fK1g_ewrXKJ8J"
55
+ ```
56
+
57
+ ### Como funciona internamente
58
+
59
+ ```text
60
+ VITE_SUPABASE_PK_OVERRIDE existe?
61
+ ├─ SIM → usar ela (ignora VITE_SUPABASE_PUBLISHABLE_KEY)
62
+ │ console.info: "✅ Usando VITE_SUPABASE_PK_OVERRIDE..."
63
+ └─ NÃO → usar VITE_SUPABASE_PUBLISHABLE_KEY
64
+ ├─ Formato sb_publishable_* → OK
65
+ └─ Formato eyJ* (JWT legada) → ⛔ Erro
66
+ ├─ console.error com diagnóstico completo
67
+ └─ Banner vermelho fixo no topo (apenas DEV)
68
+ ```
69
+
70
+ ### Arquivos relevantes na lib
71
+
72
+ | Arquivo | Responsabilidade |
73
+ |---------|-----------------|
74
+ | `lib/supabase/legacyKeyGuard.ts` | `resolvePublishableKey()`, `isLegacyAnonKey()`, `warnIfLegacyKey()` |
75
+ | `lib/supabase/SupabaseSingleton.ts` | Usa `resolvePublishableKey()` para a key do client |
76
+ | `lib/supabase/publicClient.ts` | Idem para o client público |
77
+ | `lib/providers/CoreProviders.tsx` | Renderiza `LegacyKeyBanner` em DEV |
78
+
79
+ ### ⚠️ Nunca remova esta variável do `.env`
80
+
81
+ Mesmo que o Lovable corrija a integração no futuro, a presença do override não causa nenhum efeito colateral negativo — é um fallback seguro.
@@ -46,3 +46,4 @@ export default {
46
46
  - [ ] `forlogicTailwindPreset` no tailwind.config.ts
47
47
  - [ ] `forlogicContentPaths` no content
48
48
  - [ ] Variáveis CSS definidas no index.css (--primary, --background, etc.)
49
+ - [ ] `VITE_SUPABASE_PK_OVERRIDE` no `.env` com a publishable key correta (ver `feature-flags.md`)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forlogic-core",
3
- "version": "2.2.2",
3
+ "version": "2.2.3",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",