forlogic-core 1.4.15 → 1.5.1

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.
@@ -0,0 +1,473 @@
1
+ # 🚨 Troubleshooting - Soluções para Problemas Comuns
2
+
3
+ Guia completo de solução de erros com a biblioteca ForLogic Core.
4
+
5
+ ---
6
+
7
+ ## 🔴 ERRO CRÍTICO: "isLoading is undefined" ou "manager is undefined"
8
+
9
+ ### Sintoma
10
+ ```
11
+ TypeError: Cannot read properties of undefined (reading 'isLoading')
12
+ TypeError: manager is undefined
13
+ ```
14
+
15
+ ### Causas
16
+ 1. **Ordem incorreta dos providers React**
17
+ 2. **Uso incorreto da API** (passar `service` ao invés de `manager` para `createCrudPage`)
18
+
19
+ ### ✅ Solução 1: Ordem Correta dos Providers
20
+
21
+ A ordem dos providers é **CRÍTICA** para o funcionamento correto da biblioteca:
22
+
23
+ ```tsx
24
+ // src/App.tsx - ORDEM CORRETA ✅
25
+ import { ErrorBoundary } from 'forlogic-core';
26
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
27
+ import { AuthProvider } from 'forlogic-core';
28
+ import { BrowserRouter } from 'react-router-dom';
29
+
30
+ const queryClient = new QueryClient();
31
+
32
+ function App() {
33
+ return (
34
+ <ErrorBoundary> {/* 1️⃣ PRIMEIRO */}
35
+ <QueryClientProvider client={queryClient}> {/* 2️⃣ SEGUNDO */}
36
+ <AuthProvider> {/* 3️⃣ TERCEIRO */}
37
+ <BrowserRouter> {/* 4️⃣ QUARTO */}
38
+ {/* Suas rotas aqui */}
39
+ </BrowserRouter>
40
+ </AuthProvider>
41
+ </QueryClientProvider>
42
+ </ErrorBoundary>
43
+ );
44
+ }
45
+ ```
46
+
47
+ ### ❌ Ordem Incorreta (Causa o Erro)
48
+ ```tsx
49
+ // ❌ ERRADO - Causa "isLoading is undefined"
50
+ <BrowserRouter>
51
+ <AuthProvider>
52
+ <QueryClientProvider client={queryClient}>
53
+ <ErrorBoundary>
54
+ {/* ... */}
55
+ </ErrorBoundary>
56
+ </QueryClientProvider>
57
+ </AuthProvider>
58
+ </BrowserRouter>
59
+ ```
60
+
61
+ ### Por Que a Ordem Importa?
62
+
63
+ 1. **ErrorBoundary** precisa capturar erros de todos os providers
64
+ 2. **QueryClientProvider** precisa ter acesso ao contexto de auth para invalidar cache no logout
65
+ 3. **AuthProvider** depende do QueryClient para gerenciar estado de autenticação
66
+ 4. **BrowserRouter** precisa estar dentro dos providers para rotas funcionarem
67
+
68
+ **Referência:** Ver "Quick Start → Seção 2" no [README.md](../README.md).
69
+
70
+ ### ✅ Solução 2: Use a API Corretamente
71
+
72
+ `createCrudPage` SEMPRE espera `manager` (do `useCrudHook`), NUNCA `service` diretamente.
73
+
74
+ #### ❌ ERRADO (Causa "isLoading is undefined"):
75
+ ```typescript
76
+ const { service, useCrudHook } = createSimpleService<Entity>({ tableName: 'entities' });
77
+
78
+ // ❌ ISTO NÃO FUNCIONA - createCrudPage não aceita service
79
+ export const EntitiesPage = createCrudPage({
80
+ service, // ❌ ERRADO - causa erro
81
+ config
82
+ });
83
+ ```
84
+
85
+ #### ✅ CORRETO:
86
+ ```typescript
87
+ const { service, useCrudHook } = createSimpleService<Entity>({ tableName: 'entities' });
88
+
89
+ export const EntitiesPage = () => {
90
+ const manager = useCrudHook(); // ✅ Chamar hook dentro do componente
91
+
92
+ const handleSave = createSimpleSaveHandler(manager, createFn, updateFn);
93
+
94
+ const CrudPageComponent = createCrudPage({
95
+ manager, // ✅ Passar manager, NÃO service
96
+ config: {
97
+ entityName: 'Entity',
98
+ entityNamePlural: 'Entities',
99
+ columns: [...],
100
+ formSections: [...]
101
+ },
102
+ onSave: handleSave
103
+ });
104
+
105
+ return <CrudPageComponent />;
106
+ };
107
+ ```
108
+
109
+ **Referência:** Ver [AI_RULES.md](AI_RULES.md) → Regra #2 ou [templates/basic-crud-page.tsx](templates/basic-crud-page.tsx).
110
+
111
+ **Por que isso acontece:**
112
+ - `createCrudPage` internamente usa `manager.isLoading`, `manager.data`, etc.
113
+ - Se você passa `service` ao invés de `manager`, essas propriedades não existem
114
+ - Você DEVE chamar `useCrudHook()` dentro de um componente React para obter o `manager`
115
+
116
+ ---
117
+
118
+ ## 🔄 Cache Não Funciona / Queries Não Invalidam
119
+
120
+ ### Sintomas
121
+ - Dados não atualizam ao trocar de unidade
122
+ - Cache não limpa no logout
123
+ - Dados antigos aparecem após login
124
+
125
+ ### Causa
126
+ `QueryClientProvider` não tem acesso ao `AuthProvider` devido à ordem incorreta.
127
+
128
+ ### ✅ Solução
129
+ Seguir a [ordem correta dos providers](#-solução-1-ordem-correta-dos-providers) acima.
130
+
131
+ ---
132
+
133
+ ## 🔐 LoginPage/CallbackPage Não Funcionam
134
+
135
+ ### Sintomas
136
+ - Redirecionamento infinito
137
+ - Página em branco
138
+ - Erro "Cannot read properties of undefined"
139
+
140
+ ### Causas Comuns
141
+
142
+ #### 1. Ordem Incorreta dos Providers ⚠️
143
+ **Solução:** [Ver ordem correta](#-solução-1-ordem-correta-dos-providers)
144
+
145
+ #### 2. Configuração de Rotas Incorreta
146
+ ```tsx
147
+ // ❌ ERRADO
148
+ <Route path="/auth/login" element={<LoginPage />} />
149
+ <Route path="/auth/callback" element={<CallbackPage />} />
150
+
151
+ // ✅ CORRETO
152
+ <Route path="/login" element={<LoginPage />} />
153
+ <Route path="/callback" element={<CallbackPage />} />
154
+ ```
155
+
156
+ **Referência:** Ver [templates/app-layout.tsx](templates/app-layout.tsx) para estrutura completa de rotas de autenticação.
157
+
158
+ #### 3. URLs Não Configuradas no Supabase
159
+ Configure em: **Authentication → URL Configuration**
160
+ - Site URL: `http://localhost:5173` (dev) ou `https://seudominio.com` (prod)
161
+ - Redirect URLs: `http://localhost:5173/callback` e `https://seudominio.com/callback`
162
+
163
+ #### 4. ProtectedRoute Envolvendo Páginas de Auth
164
+ ```tsx
165
+ // ❌ ERRADO
166
+ <Route path="/login" element={<ProtectedRoute><LoginPage /></ProtectedRoute>} />
167
+
168
+ // ✅ CORRETO
169
+ <Route path="/login" element={<LoginPage />} />
170
+ ```
171
+
172
+ ---
173
+
174
+ ## 📦 "Cannot find module 'forlogic-core'"
175
+
176
+ ### Sintoma
177
+ ```
178
+ Error: Cannot find module 'forlogic-core'
179
+ ```
180
+
181
+ ### ✅ Solução
182
+ ```bash
183
+ npm install forlogic-core
184
+ ```
185
+
186
+ Verifique se está em `package.json`:
187
+ ```json
188
+ {
189
+ "dependencies": {
190
+ "forlogic-core": "^x.x.x"
191
+ }
192
+ }
193
+ ```
194
+
195
+ ---
196
+
197
+ ## 🔷 Erros de Tipo TypeScript
198
+
199
+ ### Sintoma
200
+ ```
201
+ Type 'X' is not assignable to type 'Y'
202
+ ```
203
+
204
+ ### ✅ Solução: Use Named Imports
205
+ ```tsx
206
+ // ❌ ERRADO
207
+ import Button from 'forlogic-core';
208
+
209
+ // ✅ CORRETO
210
+ import { Button } from 'forlogic-core';
211
+ ```
212
+
213
+ **Referência:** Ver [README.md](../README.md) → "Instalação".
214
+
215
+ ---
216
+
217
+ ## 📐 Sidebar Não Aparece
218
+
219
+ ### Causas Comuns
220
+
221
+ #### 1. AppLayout Fora do AuthProvider
222
+ ```tsx
223
+ // ❌ ERRADO
224
+ <AppLayout>
225
+ <AuthProvider>
226
+ {/* ... */}
227
+ </AuthProvider>
228
+ </AppLayout>
229
+
230
+ // ✅ CORRETO
231
+ <AuthProvider>
232
+ <AppLayout>
233
+ {/* ... */}
234
+ </AppLayout>
235
+ </AuthProvider>
236
+ ```
237
+
238
+ #### 2. sidebarConfig Não Passado
239
+ ```tsx
240
+ // ❌ ERRADO
241
+ <AppLayout>
242
+ <Routes>{/* ... */}</Routes>
243
+ </AppLayout>
244
+
245
+ // ✅ CORRETO
246
+ import { sidebarConfig } from './config/sidebar';
247
+
248
+ <AppLayout sidebarConfig={sidebarConfig}>
249
+ <Routes>{/* ... */}</Routes>
250
+ </AppLayout>
251
+ ```
252
+
253
+ **Referência:** Ver [templates/app-layout.tsx](templates/app-layout.tsx) para exemplo completo de layout.
254
+
255
+ ---
256
+
257
+ ## 📄 createCrudPage Não Renderiza
258
+
259
+ ### Sintomas
260
+ - Página em branco
261
+ - Erro de renderização
262
+
263
+ ### Causas Comuns
264
+
265
+ #### 1. Service Mal Configurado
266
+ ```tsx
267
+ // ❌ ERRADO - Falta generic type
268
+ const service = createSimpleService('users');
269
+
270
+ // ✅ CORRETO
271
+ const service = createSimpleService<User>('users');
272
+ ```
273
+
274
+ #### 2. Tipos de Campo Inconsistentes
275
+ ```tsx
276
+ // ❌ ERRADO
277
+ const config = generateCrudConfig<User>({
278
+ fields: {
279
+ age: { type: 'text' } // age é number, não text
280
+ }
281
+ });
282
+
283
+ // ✅ CORRETO
284
+ const config = generateCrudConfig<User>({
285
+ fields: {
286
+ age: { type: 'number' }
287
+ }
288
+ });
289
+ ```
290
+
291
+ **Referência:** Ver [AI_RULES.md](AI_RULES.md) → Regra #2 e [templates/basic-crud-page.tsx](templates/basic-crud-page.tsx).
292
+
293
+ ---
294
+
295
+ ## 👤 useAuth Retorna null/undefined
296
+
297
+ ### Sintoma
298
+ ```tsx
299
+ const { user } = useAuth(); // user é sempre null
300
+ ```
301
+
302
+ ### Causas Comuns
303
+
304
+ #### 1. useAuth Fora do AuthProvider
305
+ ```tsx
306
+ // ❌ ERRADO
307
+ function App() {
308
+ const { user } = useAuth(); // ❌ Fora do AuthProvider
309
+ return <AuthProvider>{/* ... */}</AuthProvider>;
310
+ }
311
+
312
+ // ✅ CORRETO
313
+ function AppContent() {
314
+ const { user } = useAuth(); // ✅ Dentro do AuthProvider
315
+ return <div>{user?.email}</div>;
316
+ }
317
+
318
+ function App() {
319
+ return (
320
+ <AuthProvider>
321
+ <AppContent />
322
+ </AuthProvider>
323
+ );
324
+ }
325
+ ```
326
+
327
+ #### 2. Ordem Incorreta dos Providers
328
+ **Referência:** Ver [README.md](../README.md) → "Quick Start" → Seção 2 (Estrutura de Providers).
329
+
330
+ ---
331
+
332
+ ## 🔄 Update Cria Novo Registro ao Invés de Atualizar
333
+
334
+ ### Sintoma
335
+ Ao editar e salvar um registro, é criado um novo registro ao invés de atualizar o existente.
336
+
337
+ ### Causa
338
+ O `id` não está sendo preservado no payload de atualização.
339
+
340
+ ### ✅ Solução 1: Use createSimpleSaveHandler (Recomendado)
341
+
342
+ ```tsx
343
+ import { createSimpleSaveHandler } from 'forlogic-core';
344
+
345
+ const ExamplesPage = createCrudPage({
346
+ config,
347
+ service,
348
+ saveHandler: createSimpleSaveHandler(service), // ✅ Preserva ID automaticamente
349
+ });
350
+ ```
351
+
352
+ **O que `createSimpleSaveHandler` faz:**
353
+ - ✅ Preserva o `id` no payload de update
354
+ - ✅ Remove campos imutáveis (`alias`, `created_at`, etc.)
355
+ - ✅ Trata update e insert corretamente
356
+
357
+ ### ✅ Solução 2: Handler Customizado Manual
358
+
359
+ Se precisar de lógica customizada:
360
+
361
+ ```tsx
362
+ const ExamplesPage = createCrudPage({
363
+ config,
364
+ service,
365
+ saveHandler: async (formData, editingItem) => {
366
+ // ✅ CRÍTICO: Preservar o ID
367
+ const dataToSave = editingItem?.id
368
+ ? { ...formData, id: editingItem.id } // Update: inclui ID
369
+ : formData; // Insert: sem ID
370
+
371
+ // ✅ Remover campos imutáveis em updates
372
+ if (editingItem?.id) {
373
+ delete dataToSave.alias;
374
+ delete dataToSave.created_at;
375
+ delete dataToSave.updated_at;
376
+ }
377
+
378
+ // Sua lógica customizada aqui
379
+ await service.save(dataToSave);
380
+ },
381
+ });
382
+ ```
383
+
384
+ ### ❌ Erros Comuns
385
+
386
+ #### Erro 1: Remover o ID do payload
387
+ ```tsx
388
+ // ❌ ERRADO - Remove o ID
389
+ const dataToSave = { ...formData };
390
+ delete dataToSave.id; // ❌ Causa criação de novo registro
391
+ await service.save(dataToSave);
392
+ ```
393
+
394
+ #### Erro 2: Enviar campos imutáveis em UPDATE
395
+ ```tsx
396
+ // ❌ ERRADO - Envia alias em UPDATE
397
+ const dataToSave = {
398
+ ...formData,
399
+ id: editingItem.id,
400
+ alias: formData.alias // ❌ Causa erro RLS se alias é imutável
401
+ };
402
+ ```
403
+
404
+ #### Erro 3: Não verificar se é update ou insert
405
+ ```tsx
406
+ // ❌ ERRADO - Sempre inclui ID
407
+ const dataToSave = { ...formData, id: editingItem?.id };
408
+ await service.save(dataToSave); // ❌ Insert falha com ID null
409
+ ```
410
+
411
+ ### ✅ Checklist de Implementação Correta
412
+
413
+ - [ ] Usar `createSimpleSaveHandler` (recomendado) OU
414
+ - [ ] Handler customizado preserva `id` quando `editingItem?.id` existe
415
+ - [ ] Campos imutáveis (`alias`, `created_at`) removidos em updates
416
+ - [ ] Verificar `editingItem?.id` antes de incluir ID no payload
417
+ - [ ] Não enviar `id: null` em inserts
418
+
419
+ ### 🐛 Debug
420
+
421
+ Se ainda criar novos registros:
422
+
423
+ 1. **Console log do payload:**
424
+ ```tsx
425
+ console.log('Payload:', dataToSave);
426
+ console.log('EditingItem:', editingItem);
427
+ ```
428
+
429
+ 2. **Verificar se o ID está presente:**
430
+ ```tsx
431
+ if (editingItem?.id) {
432
+ console.log('UPDATE - ID:', editingItem.id);
433
+ } else {
434
+ console.log('INSERT - Sem ID');
435
+ }
436
+ ```
437
+
438
+ 3. **Checar network tab:** Procurar pela requisição PATCH/POST e ver o body.
439
+
440
+ ---
441
+
442
+ ## 🔐 Violação de RLS Policy
443
+
444
+ ### Sintoma
445
+ ```
446
+ Error: new row violates row-level security policy
447
+ ```
448
+
449
+ ### ✅ Solução
450
+ Revise as políticas RLS no Supabase:
451
+ 1. Acesse **Authentication → Policies**
452
+ 2. Verifique se as políticas permitem a operação
453
+ 3. Teste com SQL Editor:
454
+ ```sql
455
+ -- Testar insert
456
+ INSERT INTO sua_tabela (campo) VALUES ('valor');
457
+
458
+ -- Testar update
459
+ UPDATE sua_tabela SET campo = 'novo_valor' WHERE id = 'uuid';
460
+ ```
461
+
462
+ ---
463
+
464
+ ## 📚 Recursos Adicionais
465
+
466
+ - [README.md](../README.md) - Instalação e Quick Start
467
+ - [AI_RULES.md](./AI_RULES.md) - Regras críticas para desenvolvimento com IA
468
+ - [Templates](./templates/) - Códigos prontos
469
+ - [Hub da Docs](./README.md) - Navegação completa
470
+
471
+ ---
472
+
473
+ **💡 Dica:** Use Ctrl+F para buscar seu erro específico neste documento.