forlogic-core 2.1.1 → 2.1.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.
package/dist/README.md ADDED
@@ -0,0 +1,1079 @@
1
+ # 🧱 Guia de Desenvolvimento
2
+
3
+ > **IMPORTANTE**: Este README é genérico para todos os projetos. Para configurações específicas do projeto (como schema padrão), consulte o **Custom Knowledge** do projeto nas configurações do Lovable.
4
+
5
+ ---
6
+
7
+ ## 📦 Instalação
8
+
9
+ ### Pré-requisitos
10
+
11
+ A biblioteca `forlogic-core` requer as seguintes **peer dependencies** instaladas no seu projeto:
12
+
13
+ ```bash
14
+ # Dependências obrigatórias
15
+ npm install react@^18.0.0 react-dom@^18.0.0
16
+ npm install lucide-react@>=0.400.0
17
+
18
+ # Internacionalização (i18n)
19
+ npm install i18next@^25.0.0 react-i18next@^16.0.0
20
+ ```
21
+
22
+ ### Instalar a Biblioteca
23
+
24
+ ```bash
25
+ npm install forlogic-core
26
+ ```
27
+
28
+ **Nota**: O npm/yarn irá alertar automaticamente se alguma peer dependency estiver faltando ou com versão incompatível.
29
+
30
+ ### Sincronizar regras e convenções
31
+
32
+ ```bash
33
+ npx lib-update
34
+ ```
35
+
36
+ > Copia apenas `docs/KNOWLEDGE.md` (regras + mapa de módulos) e `.note/memory/rules/`.
37
+ > Documentação de componentes é acessada via rota `/ds` ou cross-project.
38
+
39
+ ### ⚠️ IMPORTANTE: Imports de i18n
40
+
41
+ **Sempre** importe hooks de internacionalização do `forlogic-core`, nunca diretamente de `react-i18next`:
42
+
43
+ ```tsx
44
+ // ❌ ERRADO - Causa conflito de instâncias (erro NO_I18NEXT_INSTANCE)
45
+ import { useTranslation } from 'react-i18next';
46
+
47
+ // ✅ CORRETO - Usa a mesma instância configurada pelo CoreProviders
48
+ import { useTranslation } from 'forlogic-core';
49
+ ```
50
+
51
+ Isso garante que todos os componentes compartilhem a mesma instância do i18next configurada pelo `CoreProviders`.
52
+
53
+ ---
54
+
55
+ ## 📦 LIB-FIRST: Sempre Use Componentes da forlogic-core
56
+
57
+ > **⚠️ REGRA FUNDAMENTAL**: Antes de criar qualquer componente, serviço ou utilitário no projeto, VERIFIQUE se já existe na `forlogic-core`.
58
+
59
+ ### 🤔 Por Quê?
60
+
61
+ A `forlogic-core` é a **biblioteca central** de componentes, serviços e utilitários compartilhados entre todos os projetos. Quando você cria um componente local que já existe na lib:
62
+
63
+ 1. **❌ Drift de Design** - O componente local não acompanha evoluções futuras da lib
64
+ 2. **❌ Duplicação de Código** - Aumenta tamanho do bundle e manutenção
65
+ 3. **❌ Inconsistência** - UI/UX diferente entre projetos
66
+ 4. **❌ Retrabalho** - Correções de bugs precisam ser feitas em múltiplos lugares
67
+
68
+ ### 📋 Checklist OBRIGATÓRIO Antes de Criar Componentes
69
+
70
+ ```markdown
71
+ - [ ] Pesquisei se o componente existe na forlogic-core?
72
+ - [ ] Verifiquei a documentação do Design System (/design_system)?
73
+ - [ ] Confirmei que a funcionalidade não pode ser alcançada com props/variantes existentes?
74
+ - [ ] Se não existe, solicitei a inclusão na lib para beneficiar todos os projetos?
75
+ ```
76
+
77
+ ### ✅ CORRETO: Usar da Lib
78
+
79
+ ```typescript
80
+ // ✅ Sempre importe da forlogic-core
81
+ import {
82
+ Button,
83
+ Input,
84
+ Dialog,
85
+ Combobox,
86
+ SplitButton,
87
+ RichTextEditor,
88
+ createCrudPage,
89
+ cn,
90
+ formatDatetime
91
+ } from 'forlogic-core';
92
+ ```
93
+
94
+ ### ❌ PROIBIDO: Criar Localmente (se existe na lib)
95
+
96
+ ```typescript
97
+ // ❌ NUNCA crie pastas/arquivos que já existem na lib
98
+ src/components/ui/button.tsx // Existe na lib
99
+ src/components/ui/dialog.tsx // Existe na lib
100
+ src/lib/utils.ts // cn() existe na lib
101
+ src/components/SplitButton.tsx // Existe na lib (a partir de v1.12.2)
102
+ ```
103
+
104
+ ### 🔄 Processo Quando Precisa de Customização
105
+
106
+ | Cenário | Ação Correta |
107
+ | ----------------------------------- | ---------------------------------------------------- |
108
+ | Componente não existe na lib | ✅ Criar localmente E solicitar inclusão na lib |
109
+ | Precisa de variante nova | ✅ Solicitar variante na lib (PR ou pedido) |
110
+ | Precisa de comportamento específico | ✅ Usar composição/wrapper ao invés de recriar |
111
+ | Bug no componente da lib | ✅ Reportar e corrigir na lib, não criar cópia local |
112
+
113
+ ### 📖 Onde Verificar Componentes Disponíveis
114
+
115
+ | Recurso | Descrição |
116
+ | --------------------------------- | --------------------------------------------------- |
117
+ | `/design_system` | Design System com todos os componentes documentados |
118
+ | `forlogic-core/lib/exports/ui.ts` | Lista de exports de UI |
119
+ | `forlogic-core/lib/index.ts` | Index principal com todos os exports |
120
+ | `npx lib-update` | Sincroniza regras e KNOWLEDGE.md |
121
+
122
+ ### ⚠️ Exceções (quando PODE criar localmente)
123
+
124
+ 1. **Componente específico de negócio** - Ex: `InvoiceCard`, `UserProfileWidget`
125
+ 2. **Composição de componentes da lib** - Ex: wrapper que combina Dialog + Form
126
+ 3. **Componente temporário** - Protótipo que será migrado para a lib depois
127
+ 4. **Funcionalidade não generalizável** - Algo tão específico que não faz sentido na lib
128
+
129
+ > **📝 Mesmo nas exceções, avalie se o componente poderia ser generalizado e incluído na lib para beneficiar outros projetos.**
130
+
131
+ ---
132
+
133
+ ## 🤖 REGRAS CRÍTICAS
134
+
135
+ > **📋 Schema Padrão**: Veja no **Custom Knowledge** do projeto (Settings → Manage Knowledge) qual é o schema padrão deste projeto específico.
136
+
137
+ ### ⚠️ TOP 4 ERROS MAIS COMUNS
138
+
139
+ 1. **ESQUECER SCHEMA**
140
+
141
+ ```typescript
142
+ // ❌ ERRADO
143
+ .from('table')
144
+
145
+ // ✅ CORRETO (verifique o schema padrão no Custom Knowledge)
146
+ .schema('SEU_SCHEMA').from('table')
147
+ ```
148
+
149
+ 2. **RLS COM SINTAXE INCORRETA**
150
+
151
+ ```sql
152
+ -- ❌ ERRADO: Usar WITH CHECK em SELECT
153
+ CREATE POLICY "Users view own" ON seu_schema.table
154
+ FOR SELECT WITH CHECK (auth.uid() = id_user);
155
+
156
+ -- ✅ CORRETO: USING para SELECT
157
+ CREATE POLICY "Users view own" ON seu_schema.table
158
+ FOR SELECT USING (
159
+ ((SELECT auth.jwt()) ->> 'alias'::text) = alias
160
+ );
161
+ ```
162
+
163
+ 3. **CRIAR POLÍTICAS DELETE**
164
+
165
+ ```sql
166
+ -- ❌ PROIBIDO: Política DELETE
167
+ CREATE POLICY "table_delete" ON seu_schema.table
168
+ FOR DELETE USING (...);
169
+
170
+ -- ✅ CORRETO: Use soft delete com UPDATE
171
+ ALTER TABLE seu_schema.table ADD COLUMN deleted_at TIMESTAMP WITH TIME ZONE;
172
+ ```
173
+
174
+ 4. **CRIAR ÍNDICES AUTOMATICAMENTE**
175
+
176
+ ```sql
177
+ -- ❌ PROIBIDO criar índices sem aprovação
178
+ CREATE INDEX idx_table_user ON seu_schema.table(id_user);
179
+
180
+ -- ✅ Apenas quando solicitado explicitamente e aprovado
181
+ ```
182
+
183
+ ---
184
+
185
+ ## 📝 CONVENÇÕES DE NOMENCLATURA
186
+
187
+ ### ⚠️ PADRÕES OBRIGATÓRIOS
188
+
189
+ **Foreign Keys (Chaves Estrangeiras):**
190
+
191
+ ```typescript
192
+ // ❌ ERRADO
193
+ process_id: string
194
+ user_id: string
195
+
196
+ // ✅ CORRETO - Sempre prefixo id_
197
+ id_process: string
198
+ id_user: string
199
+ ```
200
+
201
+ **Booleans:**
202
+
203
+ ```typescript
204
+ // ❌ ERRADO
205
+ active: boolean
206
+ removed: boolean
207
+
208
+ // ✅ CORRETO - Sempre prefixo is_
209
+ is_active: boolean
210
+ is_removed: boolean
211
+ ```
212
+
213
+ **Timestamps:**
214
+
215
+ ```typescript
216
+ // ❌ ERRADO
217
+ creation_date: string
218
+ update_time: string
219
+
220
+ // ✅ CORRETO - Sempre sufixo _at
221
+ created_at: string
222
+ updated_at: string
223
+ deleted_at: string
224
+ ```
225
+
226
+ ---
227
+
228
+ ## 🚫 ÍNDICES: ABSOLUTAMENTE PROIBIDO CRIAR AUTOMATICAMENTE
229
+
230
+ ### ⚠️ REGRA DE OURO
231
+
232
+ **NUNCA, EM HIPÓTESE ALGUMA, criar índices automaticamente em migrations!**
233
+
234
+ ### 🤔 Por Quê?
235
+
236
+ 1. **Custo**: Índices ocupam espaço em disco e custam dinheiro
237
+ 2. **Performance de Escrita**: Cada índice adiciona overhead em INSERTs/UPDATEs
238
+ 3. **Otimização Prematura**: 99% dos índices criados "por precaução" nunca são usados
239
+ 4. **Manutenção**: Índices desnecessários dificultam manutenção e análise de queries
240
+
241
+ ### ❌ Casos PROIBIDOS (mesmo que pareçam "boas práticas")
242
+
243
+ ```sql
244
+ -- ❌ PROIBIDO: Índice em FK "porque é boa prática"
245
+ CREATE INDEX idx_subprocess_process ON subprocesses(id_process);
246
+
247
+ -- ❌ PROIBIDO: Índice em campo de busca "porque pode ser útil"
248
+ CREATE INDEX idx_process_title ON processes(title);
249
+
250
+ -- ❌ PROIBIDO: Índice composto "por precaução"
251
+ CREATE INDEX idx_deliverable_status ON deliverables(id_subprocess, is_completed);
252
+ ```
253
+
254
+ ### ✅ Quando Criar Índices?
255
+
256
+ **APENAS** quando:
257
+
258
+ 1. ✅ **Solicitado explicitamente** pelo usuário
259
+ 2. ✅ **Análise de performance** comprovou necessidade (EXPLAIN ANALYZE)
260
+ 3. ✅ **Aprovação prévia** do usuário para incluir na migration
261
+
262
+ ### 📋 Checklist OBRIGATÓRIO Antes de Qualquer Migration
263
+
264
+ ```markdown
265
+ - [ ] A migration NÃO contém NENHUM `CREATE INDEX`?
266
+ - [ ] A migration NÃO contém políticas DELETE?
267
+ - [ ] Se contém índice, o usuário solicitou EXPLICITAMENTE?
268
+ - [ ] Se contém índice, foi feita análise de performance (EXPLAIN ANALYZE)?
269
+ - [ ] Se contém índice, o usuário APROVOU adicionar à migration?
270
+ - [ ] Estou usando soft delete ao invés de DELETE físico?
271
+ - [ ] Especifiquei o schema correto em todas as tabelas?
272
+ - [ ] Usei sintaxe correta nas políticas RLS (USING vs WITH CHECK)?
273
+ ```
274
+
275
+ ### 🔧 Processo Correto Para Criar Índices
276
+
277
+ 1. **Usuário solicita** OU problemas de performance são detectados
278
+ 2. **Rodar EXPLAIN ANALYZE** para confirmar necessidade
279
+ 3. **Perguntar ao usuário**: "Posso criar o índice X na coluna Y? Isso vai melhorar a query Z mas adiciona overhead."
280
+ 4. **Aguardar aprovação** do usuário
281
+ 5. **Criar migration separada** apenas com os índices aprovados
282
+
283
+ ### 📝 Template de Migration de Índices (quando aprovado)
284
+
285
+ ```sql
286
+ -- Migration: [TIMESTAMP]_add_performance_indexes.sql
287
+ -- Aprovado em: [DATA]
288
+ -- Justificativa: [RAZÃO ESPECÍFICA]
289
+
290
+ CREATE INDEX idx_processes_title ON processes.processes(title);
291
+ -- Melhora busca por título em 80% (EXPLAIN ANALYZE anexo)
292
+ ```
293
+
294
+ ---
295
+
296
+ ## ⚙️ Configuração Vite e Tailwind (Projetos Consumidores)
297
+
298
+ A biblioteca `forlogic-core` exporta configurações padronizadas de Vite e Tailwind para garantir consistência de segurança e estilo em todos os projetos.
299
+
300
+ ### 📦 Imports Disponíveis
301
+
302
+ ```typescript
303
+ // Configurações Vite (headers de segurança, CSP, CORS)
304
+ import { createSecurityHeadersPlugin, createForlogicViteConfig } from 'forlogic-core/vite';
305
+
306
+ // Preset Tailwind (cores, animações, gradientes)
307
+ import { forlogicTailwindPreset, forlogicContentPaths } from 'forlogic-core/tailwind';
308
+ ```
309
+
310
+ ---
311
+
312
+ ### 🔒 Plugin de Headers de Segurança (Vite)
313
+
314
+ O plugin configura automaticamente:
315
+
316
+ - **Content Security Policy (CSP)** - Proteção contra XSS e injeção de scripts
317
+ - **CORS seguro** - Origens confiáveis sem usar `*`
318
+ - **Headers OWASP** - HSTS, X-Content-Type-Options, X-Frame-Options, etc.
319
+ - **Permissions Policy** - Controle de APIs do navegador
320
+
321
+ #### Uso Básico
322
+
323
+ ```typescript
324
+ // vite.config.ts
325
+ import { defineConfig } from 'vite';
326
+ import react from '@vitejs/plugin-react-swc';
327
+ import { createSecurityHeadersPlugin } from 'forlogic-core/vite';
328
+
329
+ export default defineConfig(({ mode }) => ({
330
+ plugins: [
331
+ react(),
332
+ createSecurityHeadersPlugin(mode === 'development', {
333
+ supabaseUrls: ['https://seu-projeto.supabase.co'],
334
+ }),
335
+ ],
336
+ }));
337
+ ```
338
+
339
+ #### Configuração Completa
340
+
341
+ ```typescript
342
+ // vite.config.ts
343
+ import { defineConfig } from 'vite';
344
+ import react from '@vitejs/plugin-react-swc';
345
+ import { createSecurityHeadersPlugin } from 'forlogic-core/vite';
346
+
347
+ export default defineConfig(({ mode }) => ({
348
+ plugins: [
349
+ react(),
350
+ createSecurityHeadersPlugin(mode === 'development', {
351
+ // URLs do Supabase para permitir conexões
352
+ supabaseUrls: [
353
+ 'https://seu-projeto-dev.supabase.co',
354
+ 'https://seu-projeto-prod.supabase.co',
355
+ ],
356
+
357
+ // Origens confiáveis adicionais para CORS
358
+ trustedOrigins: [
359
+ 'https://meu-app.com',
360
+ 'https://admin.meu-app.com',
361
+ ],
362
+
363
+ // APIs externas para connect-src
364
+ additionalConnectSrc: [
365
+ 'https://api.exemplo.com',
366
+ 'wss://websocket.exemplo.com',
367
+ ],
368
+
369
+ // CDNs de scripts/estilos/fontes adicionais
370
+ additionalScriptSrc: ['https://cdn.analytics.com'],
371
+ additionalStyleSrc: ['https://fonts.custom.com'],
372
+ additionalFontSrc: ['https://fonts.gstatic.com'],
373
+
374
+ // URI para reportar violações CSP
375
+ cspReportUri: 'https://seu-projeto.supabase.co/functions/v1/csp-report',
376
+
377
+ // Opções de produção (defaults: true)
378
+ enableTrustedTypes: true,
379
+ upgradeInsecureRequests: true,
380
+ }),
381
+ ],
382
+ }));
383
+ ```
384
+
385
+ #### Opções do Plugin
386
+
387
+ | Opção | Tipo | Padrão | Descrição |
388
+ | ------------------------- | ---------- | ------ | --------------------------------------- |
389
+ | `supabaseUrls` | `string[]` | `[]` | URLs do Supabase permitidas |
390
+ | `trustedOrigins` | `string[]` | `[]` | Origens confiáveis adicionais para CORS |
391
+ | `additionalScriptSrc` | `string[]` | `[]` | Fontes de script adicionais para CSP |
392
+ | `additionalStyleSrc` | `string[]` | `[]` | Fontes de estilo adicionais para CSP |
393
+ | `additionalConnectSrc` | `string[]` | `[]` | APIs/WebSockets adicionais para CSP |
394
+ | `additionalFontSrc` | `string[]` | `[]` | Fontes de font adicionais para CSP |
395
+ | `cspReportUri` | `string` | - | URI para relatório de violações CSP |
396
+ | `enableTrustedTypes` | `boolean` | `true` | Habilitar Trusted Types em produção |
397
+ | `upgradeInsecureRequests` | `boolean` | `true` | Upgrade HTTP→HTTPS em produção |
398
+
399
+ ---
400
+
401
+ ### 🏗️ Factory de Configuração Vite (Opcional)
402
+
403
+ Para projetos que desejam usar a configuração padronizada com segurança:
404
+
405
+ ```typescript
406
+ // vite.config.ts
407
+ import { defineConfig } from 'vite';
408
+ import react from '@vitejs/plugin-react-swc';
409
+ import path from 'path';
410
+ import { createForlogicViteConfig } from 'forlogic-core/vite';
411
+
412
+ const forlogicConfig = createForlogicViteConfig({
413
+ security: {
414
+ supabaseUrls: ['https://seu-projeto.supabase.co'],
415
+ trustedOrigins: ['https://meu-app.com'],
416
+ },
417
+ server: { host: '::', port: 8080 },
418
+ build: { chunkSizeWarningLimit: 4000 },
419
+ });
420
+
421
+ export default defineConfig(({ mode }) => {
422
+ const isDev = mode === 'development';
423
+ const baseConfig = forlogicConfig(isDev);
424
+
425
+ return {
426
+ ...baseConfig,
427
+ plugins: [react(), ...baseConfig.plugins],
428
+ // IMPORTANTE: resolve.alias deve usar caminhos absolutos
429
+ resolve: {
430
+ alias: {
431
+ '@': path.resolve(__dirname, './src'),
432
+ },
433
+ },
434
+ };
435
+ });
436
+ ```
437
+
438
+ > **⚠️ IMPORTANTE**: A factory **não** configura `resolve.alias` porque caminhos relativos não funcionam corretamente no build. Cada projeto deve definir seus próprios aliases com `path.resolve(__dirname, './caminho')` para garantir caminhos absolutos.
439
+
440
+ ---
441
+
442
+ ### 📋 Template Completo para Projetos Consumidores
443
+
444
+ Copie e adapte este template para novos projetos:
445
+
446
+ ```typescript
447
+ // vite.config.ts
448
+ import { defineConfig } from 'vite';
449
+ import react from '@vitejs/plugin-react-swc';
450
+ import path from 'path';
451
+ import { createSecurityHeadersPlugin } from 'forlogic-core/vite';
452
+
453
+ export default defineConfig(({ mode }) => {
454
+ const isDev = mode === 'development';
455
+
456
+ return {
457
+ server: {
458
+ host: '::',
459
+ port: 8080,
460
+ },
461
+
462
+ // Força re-bundle quando atualizar forlogic-core
463
+ optimizeDeps: {
464
+ force: true,
465
+ },
466
+
467
+ plugins: [
468
+ react(),
469
+ // Headers de segurança (CSP, CORS, etc.)
470
+ createSecurityHeadersPlugin(isDev, {
471
+ supabaseUrls: [
472
+ 'https://SEU_PROJETO.supabase.co',
473
+ ],
474
+ additionalConnectSrc: [
475
+ 'https://*.qualiex.com',
476
+ ],
477
+ // Opcional: URI para relatório de violações CSP
478
+ cspReportUri: isDev
479
+ ? 'https://SEU_PROJETO_DEV.supabase.co/functions/v1/csp-report'
480
+ : 'https://SEU_PROJETO_PROD.supabase.co/functions/v1/csp-report',
481
+ }),
482
+ ],
483
+
484
+ // CRÍTICO: Aliases devem usar caminhos absolutos
485
+ resolve: {
486
+ alias: {
487
+ '@': path.resolve(__dirname, './src'),
488
+ },
489
+ },
490
+
491
+ publicDir: false,
492
+
493
+ esbuild: {
494
+ sourcemap: true,
495
+ target: 'es2020',
496
+ },
497
+
498
+ build: {
499
+ chunkSizeWarningLimit: 4000,
500
+ },
501
+ };
502
+ });
503
+ ```
504
+
505
+ #### Checklist de Configuração
506
+
507
+ ```markdown
508
+ - [ ] Substituiu `SEU_PROJETO` pelas URLs do Supabase
509
+ - [ ] Adicionou origens confiáveis em `additionalConnectSrc` se necessário
510
+ - [ ] Verificou que `resolve.alias` usa `path.resolve(__dirname, ...)`
511
+ - [ ] Reiniciou o servidor após modificar o arquivo
512
+ ```
513
+
514
+ ---
515
+
516
+ ### 🔄 Forçar Re-bundle de Dependências
517
+
518
+ Se você atualizar a `forlogic-core` e as mudanças não aparecerem no preview:
519
+
520
+ ```typescript
521
+ // vite.config.ts
522
+ export default defineConfig(({ mode }) => ({
523
+ optimizeDeps: {
524
+ force: true, // Força re-otimização a cada restart do dev server
525
+ },
526
+ // ...
527
+ }));
528
+ ```
529
+
530
+ > **⚠️ IMPORTANTE**: Após adicionar `force: true`, reinicie o servidor completamente (pare e inicie novamente).
531
+
532
+ ---
533
+
534
+ ### 🎨 Preset Tailwind CSS
535
+
536
+ O preset inclui:
537
+
538
+ - **Cores semânticas** - primary, secondary, destructive, success, warning, etc.
539
+ - **Border radius** - lg, md, sm padronizados
540
+ - **Animações** - accordion, fade, slide, scale
541
+ - **Gradientes** - primary, secondary, accent
542
+ - **Sombras** - xs até 2xl, inner, primary
543
+
544
+ #### Uso Básico
545
+
546
+ ```typescript
547
+ // tailwind.config.ts
548
+ import type { Config } from 'tailwindcss';
549
+ import { forlogicTailwindPreset, forlogicContentPaths } from 'forlogic-core/tailwind';
550
+
551
+ export default {
552
+ presets: [forlogicTailwindPreset],
553
+ content: [
554
+ ...forlogicContentPaths,
555
+ // Paths adicionais específicos do seu projeto
556
+ ],
557
+ } satisfies Config;
558
+ ```
559
+
560
+ #### Uso com Extensões
561
+
562
+ ```typescript
563
+ // tailwind.config.ts
564
+ import type { Config } from 'tailwindcss';
565
+ import { forlogicTailwindPreset, forlogicContentPaths } from 'forlogic-core/tailwind';
566
+
567
+ export default {
568
+ presets: [forlogicTailwindPreset],
569
+ content: [
570
+ ...forlogicContentPaths,
571
+ ],
572
+ theme: {
573
+ extend: {
574
+ // Extensões específicas do seu projeto
575
+ colors: {
576
+ brand: {
577
+ 50: 'hsl(var(--brand-50))',
578
+ // ...
579
+ },
580
+ },
581
+ },
582
+ },
583
+ plugins: [
584
+ require('tailwindcss-animate'),
585
+ // Plugins adicionais
586
+ ],
587
+ } satisfies Config;
588
+ ```
589
+
590
+ #### Content Paths Padrão
591
+
592
+ O `forlogicContentPaths` inclui:
593
+
594
+ ```typescript
595
+ [
596
+ './pages/**/*.{ts,tsx}',
597
+ './components/**/*.{ts,tsx}',
598
+ './app/**/*.{ts,tsx}',
599
+ './src/**/*.{ts,tsx}',
600
+ './lib/**/*.{ts,tsx}',
601
+ './node_modules/forlogic-core/dist/**/*.{js,ts,jsx,tsx}',
602
+ ]
603
+ ```
604
+
605
+ ---
606
+
607
+ ### 📋 Checklist de Configuração
608
+
609
+ ```markdown
610
+ - [ ] Instalou `forlogic-core` no projeto?
611
+ - [ ] Configurou `vite.config.ts` com `createSecurityHeadersPlugin`?
612
+ - [ ] Adicionou URLs do Supabase em `supabaseUrls`?
613
+ - [ ] Configurou `tailwind.config.ts` com `forlogicTailwindPreset`?
614
+ - [ ] Adicionou `forlogicContentPaths` ao content?
615
+ - [ ] Definiu variáveis CSS no `index.css` (--primary, --background, etc.)?
616
+ ```
617
+
618
+ ---
619
+
620
+ ### 🔧 Configuração do package.json (Publicação da Lib)
621
+
622
+ Para projetos que estão **publicando** a `forlogic-core`, adicione os exports condicionais:
623
+
624
+ ```json
625
+ {
626
+ "exports": {
627
+ ".": {
628
+ "import": "./dist/index.esm.js",
629
+ "require": "./dist/index.js",
630
+ "types": "./dist/index.d.ts"
631
+ },
632
+ "./vite": {
633
+ "import": "./dist/vite/index.esm.js",
634
+ "require": "./dist/vite/index.js",
635
+ "types": "./dist/vite/index.d.ts"
636
+ },
637
+ "./tailwind": {
638
+ "import": "./dist/tailwind/index.esm.js",
639
+ "require": "./dist/tailwind/index.js",
640
+ "types": "./dist/tailwind/index.d.ts"
641
+ }
642
+ }
643
+ }
644
+ ```
645
+
646
+ ---
647
+
648
+ ## 🚩 Feature Flags (Variáveis de Ambiente)
649
+
650
+ A biblioteca suporta feature flags para habilitar/desabilitar funcionalidades opcionais.
651
+
652
+ ### Variáveis Disponíveis
653
+
654
+ | Variável | Descrição | Valores | Padrão |
655
+ | ---------------------------- | ------------------------------------------------------------------------------------ | -------------------- | --------- |
656
+ | `VITE_SHOW_USER_PREFERENCES` | Exibe opção de "Preferências" no menu do usuário (idioma, timezone, formato de data) | `"true"` / `"false"` | Não exibe |
657
+ | `VITE_I18N_DEBUG_MODE` | Modo debug de internacionalização (mostra chaves ao invés de traduções) | `"true"` / `"false"` | `"false"` |
658
+ | `VITE_IS_QUALIEX` | Define se usa logos Qualiex ou Forlogic | `"true"` / `"false"` | `"false"` |
659
+
660
+ ### Configuração
661
+
662
+ Adicione no seu arquivo `.env`:
663
+
664
+ ```env
665
+ # Habilitar opção de preferências no perfil do usuário
666
+ VITE_SHOW_USER_PREFERENCES=true
667
+
668
+ # Modo debug de i18n (mostra chaves com ícones)
669
+ VITE_I18N_DEBUG_MODE=false
670
+
671
+ # Usar logos Qualiex
672
+ VITE_IS_QUALIEX=true
673
+ ```
674
+
675
+ > **Nota**: Variáveis de ambiente em Vite precisam ter o prefixo `VITE_` para serem expostas ao cliente.
676
+
677
+ ---
678
+
679
+ ## 🌐 Setup de Traduções para Projetos Consumidores
680
+
681
+ O sistema de i18n usa **namespaces**: a lib fornece traduções base no namespace `core` e cada projeto injeta suas traduções no namespace `app`. A resolução é: `app` → `core` → fallback `pt-BR`.
682
+
683
+ ### Requisitos
684
+
685
+ | Requisito | Descrição |
686
+ | ------------------ | ----------------------------------------- |
687
+ | `i18next` | Peer dependency instalada |
688
+ | `react-i18next` | Peer dependency instalada |
689
+ | `CoreProviders` | Wrapper no App.tsx |
690
+
691
+ ### Passo 1: Instalar Peer Dependencies
692
+
693
+ ```bash
694
+ npm install i18next@^25.0.0 react-i18next@^16.0.0
695
+ ```
696
+
697
+ ### Passo 2: Criar JSONs de Tradução do Projeto
698
+
699
+ Crie arquivos JSON flat (um por idioma) com as traduções específicas do seu projeto:
700
+
701
+ ```json
702
+ // src/i18n/pt-BR.json
703
+ {
704
+ "objective": "Objetivo",
705
+ "key_result": "Resultado-chave",
706
+ "cycle": "Ciclo"
707
+ }
708
+ ```
709
+
710
+ ### Passo 3: Passar para CoreProviders via `appTranslations`
711
+
712
+ ```tsx
713
+ // src/App.tsx
714
+ import { CoreProviders } from 'forlogic-core';
715
+ import { BrowserRouter, Routes, Route } from 'react-router-dom';
716
+ import ptBR from './i18n/pt-BR.json';
717
+ // import enUS from './i18n/en-US.json'; // quando tiver
718
+
719
+ function App() {
720
+ return (
721
+ <CoreProviders
722
+ moduleAlias="performance"
723
+ appTranslations={{
724
+ 'pt-BR': ptBR,
725
+ // 'en-US': enUS,
726
+ }}
727
+ >
728
+ <BrowserRouter>
729
+ <Routes>
730
+ {/* Suas rotas */}
731
+ </Routes>
732
+ </BrowserRouter>
733
+ </CoreProviders>
734
+ );
735
+ }
736
+
737
+ export default App;
738
+ ```
739
+
740
+ ### Passo 4: Usar useTranslation do forlogic-core
741
+
742
+ ```tsx
743
+ // ❌ ERRADO - Cria instância separada (erro NO_I18NEXT_INSTANCE)
744
+ import { useTranslation } from 'react-i18next';
745
+
746
+ // ✅ CORRETO - Usa mesma instância configurada
747
+ import { useTranslation } from 'forlogic-core';
748
+
749
+ function MeuComponente() {
750
+ const { t } = useTranslation();
751
+ return (
752
+ <div>
753
+ <h1>{t('objective')}</h1> {/* namespace app → "Objetivo" */}
754
+ <Button>{t('save')}</Button> {/* app → não encontra → core → "Salvar" */}
755
+ </div>
756
+ );
757
+ }
758
+ ```
759
+
760
+ ### Como funciona a resolução de namespaces
761
+
762
+ ```
763
+ t('save')
764
+ 1. Busca em namespace 'app' (projeto) → não encontrou
765
+ 2. Busca em namespace 'core' (lib) → "Salvar" ✅
766
+
767
+ t('objective')
768
+ 1. Busca em namespace 'app' (projeto) → "Objetivo" ✅
769
+
770
+ t('save') com override no app
771
+ 1. Busca em namespace 'app' → "Gravar" ✅ (sobrescreve o core)
772
+ ```
773
+
774
+ ### Troubleshooting
775
+
776
+ #### Traduções mostram apenas as chaves
777
+
778
+ | Causa | Solução |
779
+ | ------------------------------------ | ------------------------------------------------------ |
780
+ | Peer dependencies faltando | Instalar `i18next` e `react-i18next` |
781
+ | Import de `react-i18next` direto | Usar import de `forlogic-core` |
782
+ | `appTranslations` não passado | Adicionar prop no `CoreProviders` |
783
+ | JSON com formato errado | Deve ser flat: `{ "key": "value" }`, sem nesting |
784
+
785
+ #### Debug: Verificar se traduções foram carregadas
786
+
787
+ ```tsx
788
+ import { i18n } from 'forlogic-core';
789
+
790
+ console.log('i18n initialized:', i18n.isInitialized);
791
+ console.log('Current language:', i18n.language);
792
+ console.log('Loaded resources:', i18n.store.data);
793
+ // Deve mostrar: { 'pt-BR': { core: {...}, app: {...} } }
794
+ ```
795
+
796
+ ### Checklist de Configuração
797
+
798
+ ```markdown
799
+ - [ ] Instalou `i18next@^25.0.0` e `react-i18next@^16.0.0`?
800
+ - [ ] Criou JSONs de tradução em `src/i18n/pt-BR.json`?
801
+ - [ ] Passou `appTranslations` para o `CoreProviders`?
802
+ - [ ] Todos os imports de `useTranslation` são de `forlogic-core` (nunca de `react-i18next`)?
803
+ - [ ] O `App.tsx` usa `CoreProviders`?
804
+ ```
805
+
806
+ ---
807
+
808
+ ## 🚀 Quick Setup: CoreProviders
809
+
810
+ O `CoreProviders` é um componente que encapsula todos os providers essenciais da biblioteca, simplificando drasticamente a configuração de novos projetos.
811
+
812
+ ### O que está incluído
813
+
814
+ O `CoreProviders` encapsula automaticamente:
815
+
816
+ | Provider | Descrição |
817
+ | --------------------- | ----------------------------------------------------------- |
818
+ | `ErrorBoundary` | Captura e trata erros de renderização React |
819
+ | `I18nextProvider` | Sistema de internacionalização (i18n) |
820
+ | `QueryClientProvider` | Cache e gerenciamento de queries (React Query) |
821
+ | `AuthProvider` | Autenticação e gerenciamento de sessão |
822
+ | `LocaleProvider` | Gerenciamento de locale (idioma, timezone, formato de data) |
823
+ | `TranslationLoader` | Carregamento dinâmico de traduções do banco de dados |
824
+
825
+ ### Uso Básico
826
+
827
+ ```tsx
828
+ import { CoreProviders } from 'forlogic-core';
829
+ import { BrowserRouter, Routes, Route } from 'react-router-dom';
830
+
831
+ function App() {
832
+ return (
833
+ <CoreProviders>
834
+ <BrowserRouter>
835
+ <Routes>
836
+ {/* Suas rotas aqui */}
837
+ </Routes>
838
+ </BrowserRouter>
839
+ </CoreProviders>
840
+ );
841
+ }
842
+ ```
843
+
844
+ ### Com QueryClient Customizado
845
+
846
+ Se você precisar de configurações específicas para o React Query:
847
+
848
+ ```tsx
849
+ import { CoreProviders } from 'forlogic-core';
850
+ import { QueryClient } from '@tanstack/react-query';
851
+ import { BrowserRouter } from 'react-router-dom';
852
+
853
+ const queryClient = new QueryClient({
854
+ defaultOptions: {
855
+ queries: {
856
+ staleTime: 10 * 60 * 1000, // 10 minutos
857
+ retry: 2,
858
+ refetchOnWindowFocus: false,
859
+ },
860
+ },
861
+ });
862
+
863
+ function App() {
864
+ return (
865
+ <CoreProviders queryClient={queryClient}>
866
+ <BrowserRouter>
867
+ {/* Suas rotas */}
868
+ </BrowserRouter>
869
+ </CoreProviders>
870
+ );
871
+ }
872
+ ```
873
+
874
+ ### Props
875
+
876
+ | Prop | Tipo | Obrigatório | Descrição |
877
+ | ------------- | ------------- | ----------- | --------------------------------------------------------------------------- |
878
+ | `children` | `ReactNode` | ✅ | Componentes filhos a serem envolvidos |
879
+ | `queryClient` | `QueryClient` | ❌ | Instância customizada do QueryClient. Se não fornecido, um default é criado |
880
+
881
+ ### QueryClient Default
882
+
883
+ Se você não fornecer um `queryClient`, o `CoreProviders` cria um com as seguintes configurações:
884
+
885
+ ```typescript
886
+ {
887
+ defaultOptions: {
888
+ queries: {
889
+ staleTime: 5 * 60 * 1000, // 5 minutos
890
+ retry: 1,
891
+ },
892
+ },
893
+ }
894
+ ```
895
+
896
+ ### Benefícios
897
+
898
+ - ✅ **Zero configuração de i18n** - Traduções funcionam automaticamente
899
+ - ✅ **Autenticação pronta** - `useAuth()` disponível em qualquer componente filho
900
+ - ✅ **Tratamento de erros** - ErrorBoundary captura erros de renderização
901
+ - ✅ **React Query configurado** - Cache e queries prontos para uso
902
+ - ✅ **Locale gerenciado** - Preferências de idioma, timezone e formato de data
903
+ - ✅ **Atualizações centralizadas** - Novos providers são adicionados automaticamente
904
+
905
+ ---
906
+
907
+ ## 🎯 Ações Principais de Módulo (SidebarActionTrigger)
908
+
909
+ O `SidebarActionTrigger` permite adicionar ações principais de módulo no sidebar, diferenciadas visualmente da navegação. São gatilhos de ação, não destinos de navegação.
910
+
911
+ ### Conceito
912
+
913
+ | Característica | Descrição |
914
+ | ------------------- | ----------------------------------------------------------- |
915
+ | **Ação de módulo** | Válida apenas dentro do contexto do módulo ao qual pertence |
916
+ | **Não global** | Não aplicável a todo o sistema |
917
+ | **Não contextual** | Não depende de seleção de item específico |
918
+ | **Destaque visual** | Exibida com aparência diferenciada da navegação |
919
+
920
+ ### Uso Básico
921
+
922
+ ```tsx
923
+ import { AppSidebar, SidebarConfig } from 'forlogic-core';
924
+ import { Plus, FileText, Folder } from 'lucide-react';
925
+
926
+ const sidebarConfig: SidebarConfig = {
927
+ appName: 'Meu Módulo',
928
+
929
+ // Ações principais do módulo
930
+ moduleActions: {
931
+ triggerLabel: 'Criar',
932
+ triggerIcon: Plus,
933
+ actions: [
934
+ {
935
+ id: 'create-item',
936
+ label: 'Novo Item',
937
+ icon: FileText,
938
+ onClick: () => openCreateDialog()
939
+ },
940
+ {
941
+ id: 'create-folder',
942
+ label: 'Nova Pasta',
943
+ icon: Folder,
944
+ onClick: () => openFolderDialog()
945
+ },
946
+ ]
947
+ },
948
+
949
+ // Navegação
950
+ navigation: [
951
+ { label: 'Visão Geral', path: '/', icon: Home },
952
+ { label: 'Configurações', path: '/settings', icon: Settings },
953
+ ]
954
+ };
955
+
956
+ <AppSidebar config={sidebarConfig} />
957
+ ```
958
+
959
+ ### Comportamento
960
+
961
+ | Cenário | Comportamento |
962
+ | --------------------- | --------------------------------- |
963
+ | **Uma ação** | Clique executa a ação diretamente |
964
+ | **Múltiplas ações** | Clique exibe dropdown com opções |
965
+ | **Modal aberto** | Gatilho fica desabilitado |
966
+ | **Sidebar colapsada** | Exibe apenas ícone com tooltip |
967
+
968
+ ### Props do SidebarActionTrigger
969
+
970
+ | Prop | Tipo | Obrigatório | Descrição |
971
+ | ------------- | ---------------------- | ----------- | --------------------------- |
972
+ | `config` | `SidebarActionsConfig` | ✅ | Configuração das ações |
973
+ | `isCollapsed` | `boolean` | ❌ | Se a sidebar está colapsada |
974
+ | `isDisabled` | `boolean` | ❌ | Desabilita o gatilho |
975
+
976
+ ### Interface SidebarModuleAction
977
+
978
+ ```typescript
979
+ interface SidebarModuleAction {
980
+ id: string; // Identificador único
981
+ label: string; // Texto do botão/opção
982
+ icon?: LucideIcon; // Ícone opcional
983
+ onClick: () => void; // Callback de execução
984
+ disabled?: boolean; // Estado desabilitado
985
+ permissionCheck?: () => Promise<boolean>;
986
+ }
987
+ ```
988
+
989
+ ### Interface SidebarActionsConfig
990
+
991
+ ```typescript
992
+ interface SidebarActionsConfig {
993
+ triggerLabel?: string; // Rótulo do gatilho (padrão: 'Criar')
994
+ triggerIcon?: LucideIcon; // Ícone do gatilho (padrão: Plus)
995
+ actions: SidebarModuleAction[];
996
+ }
997
+ ```
998
+
999
+ ### Gerenciamento de Modais (Opcional)
1000
+
1001
+ Para desabilitar o gatilho quando há modais abertos, use o `ModalStateProvider`:
1002
+
1003
+ ```tsx
1004
+ import { CoreProviders, ModalStateProvider, useModalState } from 'forlogic-core';
1005
+
1006
+ // No App.tsx (opcional - CoreProviders não inclui por padrão)
1007
+ <CoreProviders>
1008
+ <ModalStateProvider>
1009
+ <AppLayout />
1010
+ </ModalStateProvider>
1011
+ </CoreProviders>
1012
+
1013
+ // Em componentes com modal
1014
+ function MeuDialog({ open, onOpenChange }) {
1015
+ const { registerModal, unregisterModal } = useModalState();
1016
+
1017
+ useEffect(() => {
1018
+ if (open) {
1019
+ registerModal('meu-dialog');
1020
+ } else {
1021
+ unregisterModal('meu-dialog');
1022
+ }
1023
+ }, [open]);
1024
+
1025
+ return <Dialog open={open} onOpenChange={onOpenChange}>...</Dialog>;
1026
+ }
1027
+ ```
1028
+
1029
+ ### Diretriz para Uso via Prompt
1030
+
1031
+ #### ✅ Prompts corretos:
1032
+
1033
+ - "Adicione uma ação principal 'Criar Processo' no sidebar do módulo"
1034
+ - "Configure o módulo para ter duas ações principais: 'Novo Item' e 'Nova Pasta'"
1035
+ - "Adicione o botão de criar no topo do sidebar como ação de módulo"
1036
+
1037
+ #### ❌ Prompts ambíguos (evitar):
1038
+
1039
+ - "Coloque um botão de criar no menu" (ambíguo - qual menu?)
1040
+ - "Adicione navegação para criar" (ação ≠ navegação)
1041
+ - "Crie um link para nova entidade" (link = navegação, não ação)
1042
+
1043
+ ## 🛠️ CLI: Sincronizar Regras e Convenções
1044
+
1045
+ O `forlogic-core` disponibiliza um comando CLI para sincronizar regras e convenções arquiteturais para projetos consumidores.
1046
+
1047
+ ### Uso
1048
+
1049
+ ```bash
1050
+ # Via npx (recomendado)
1051
+ npx lib-update
1052
+
1053
+ # Ou adicione ao package.json do seu projeto:
1054
+ {
1055
+ "scripts": {
1056
+ "lib-update": "lib-update"
1057
+ }
1058
+ }
1059
+
1060
+ # E execute:
1061
+ npm run lib-update
1062
+ ```
1063
+
1064
+ ### O que é sincronizado
1065
+
1066
+ | Arquivo/Diretório | Descrição |
1067
+ | ----------------------- | ------------------------------------------------ |
1068
+ | `docs/KNOWLEDGE.md` | Regras críticas + mapa de módulos para IA/Lovable |
1069
+ | `.note/memory/rules/` | Regras de schema, RLS, índices, .env |
1070
+
1071
+ ### O que NÃO é sincronizado (leitura via cross-project → projeto **Admin**)
1072
+
1073
+ | Recurso | Como acessar |
1074
+ | --------------------------- | --------------------------------------------------------- |
1075
+ | Documentação de componentes | Rota `/ds` no projeto **Admin** ou cross-project |
1076
+ | Props, exemplos, tipos | Ler dos `*Doc.tsx` via cross-project → projeto **Admin** |
1077
+ | Padrões de layout/CRUD | `.note/memory/patterns/` via cross-project → **Admin** |
1078
+
1079
+ > 💡 A IA consegue ler o código-fonte do forlogic-core no projeto **Admin** via cross-project visibility.