forlogic-core 1.16.7 → 1.16.9
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/.note/memory/architecture/documentation-strategy.md +59 -0
- package/.note/memory/patterns/core-providers-setup.md +39 -0
- package/.note/memory/patterns/deprecated-patterns.md +14 -0
- package/.note/memory/patterns/feature-flags.md +19 -0
- package/.note/memory/patterns/header-metadata-pattern.md +62 -0
- package/.note/memory/patterns/i18n-setup.md +43 -0
- package/.note/memory/patterns/vite-tailwind-setup.md +49 -0
- package/.note/memory/rules/doc-sync-rule.md +32 -0
- package/.note/memory/rules/i18n-import-rule.md +29 -0
- package/.note/memory/rules/lib-first-rule.md +42 -0
- package/.note/memory/rules/no-auto-index-rule.md +37 -9
- package/.note/memory/rules/no-delete-policy-rule.md +41 -12
- package/.note/memory/rules/rls-syntax-rule.md +50 -0
- package/.note/memory/rules/sql-naming-rule.md +23 -0
- package/.note/memory/rules/supabase-import-rule.md +31 -0
- package/.note/memory/rules/supabase-schema-rule.md +5 -4
- package/.note/memory/ui/components/combo-tree.md +9 -1
- package/.note/memory/ui/design-system/documentation-standard.md +17 -0
- package/README.md +78 -212
- package/dist/README.md +78 -212
- package/dist/assets/AccordionDoc-BVPUJk8G.js +31 -0
- package/dist/assets/ActionButtonDoc-DLJ_K9ib.js +47 -0
- package/dist/assets/AlertDoc-CY1ybZeG.js +37 -0
- package/dist/assets/AppHeaderDoc-Crkw4dA9.js +67 -0
- package/dist/assets/AppSidebarDoc-ET-4j6wV.js +204 -0
- package/dist/assets/AuthDoc-B4v4Nci5.js +192 -0
- package/dist/assets/AvatarDoc-BLdMoyJd.js +11 -0
- package/dist/assets/BadgeDoc-CSNM1b6b.js +36 -0
- package/dist/assets/BaseFormDoc-DXiYuN6-.js +169 -0
- package/dist/assets/BodyContentDoc-Bp6YmUWX.js +83 -0
- package/dist/assets/BreadcrumbDoc-D7tqqTvo.js +75 -0
- package/dist/assets/ButtonDoc-C4JwIvU3.js +41 -0
- package/dist/assets/ButtonGroupDoc-QFfjC7Pm.js +7 -0
- package/dist/assets/CalendarDoc-COlEKqmv.js +81 -0
- package/dist/assets/CardDoc-BVhMoC2w.js +49 -0
- package/dist/assets/ChartDoc-BJ14EjI2.js +111 -0
- package/dist/assets/CheckboxDoc-Bcqpln9_.js +55 -0
- package/dist/assets/ColorPickerDoc-CcfmSwyC.js +10 -0
- package/dist/assets/ColorsFoundationDoc-uO6IiJbS.js +13 -0
- package/dist/assets/ComboTreeDoc-R4qE6XwB.js +46 -0
- package/dist/assets/ComboboxDoc-JIo_-gSN.js +134 -0
- package/dist/assets/ComponentDocTemplate-CRbRY-v5.js +1 -0
- package/dist/assets/ContextMenuDoc-C4-_0NLp.js +182 -0
- package/dist/assets/ContextsDoc-Cj9Aaoyo.js +184 -0
- package/dist/assets/CreateCrudPageDoc-D_SnMRJ2.js +106 -0
- package/dist/assets/CrudActionBarDoc-BYqtIabp.js +112 -0
- package/dist/assets/CrudGridDoc-DspxQrq5.js +85 -0
- package/dist/assets/CrudOverviewDoc-DLcOL_HZ.js +14 -0
- package/dist/assets/CrudPrimitivesDoc-BRS86nWg.js +164 -0
- package/dist/assets/CrudTableDoc-Daw8u2G_.js +113 -0
- package/dist/assets/DataListDoc-BrgVNhhR.js +13 -0
- package/dist/assets/DesignSystemHome-BFBNqq1J.js +1 -0
- package/dist/assets/DialogDoc-DCpRy4rg.js +981 -0
- package/dist/assets/DropdownMenuDoc-DT6LBa8Z.js +175 -0
- package/dist/assets/EmptyStateDoc-wydc09gG.js +35 -0
- package/dist/assets/EnvironmentsDoc-amIriwDD.js +96 -0
- package/dist/assets/ErrorBoundaryDoc-BEixy_Gl.js +111 -0
- package/dist/assets/FormDoc-DxoRt6p7.js +81 -0
- package/dist/assets/FoundationOverview-CxSbumIt.js +1 -0
- package/dist/assets/GridDoc-BpQqCMUE.js +28 -0
- package/dist/assets/HooksDoc-JNODhbaF.js +665 -0
- package/dist/assets/HoverCardDoc-CdqiYrIb.js +31 -0
- package/dist/assets/I18nDoc-B6LMXnE3.js +232 -0
- package/dist/assets/IconPickerDoc-BRdy58IC.js +10 -0
- package/dist/assets/IconsFoundationDoc-CrymfxTI.js +33 -0
- package/dist/assets/InputDoc-BK-SdpJ7.js +211 -0
- package/dist/assets/LabelDoc-DHvgzhaJ.js +42 -0
- package/dist/assets/LeadershipDoc-DRiB0spL.js +416 -0
- package/dist/assets/MediaDoc-B_vqnf72.js +459 -0
- package/dist/assets/MenubarDoc-Zvgczxe2.js +165 -0
- package/dist/assets/ModuleAccessDoc-Nuxb4S27.js +153 -0
- package/dist/assets/ModulesDialogDoc-iJWLkOZo.js +46 -0
- package/dist/assets/NavigationMenuDoc-CeWun1VF.js +116 -0
- package/dist/assets/OnboardingDialogDoc-xBL-rXeZ.js +55 -0
- package/dist/assets/PaginationDoc-CfvwxCMe.js +98 -0
- package/dist/assets/PaginationDoc-DqtRgXnF.js +27 -0
- package/dist/assets/PlacesDoc-nckioEzg.js +226 -0
- package/dist/assets/PopoverDoc-C3o2CZCT.js +64 -0
- package/dist/assets/ProgressDoc-BmWBNMPA.js +29 -0
- package/dist/assets/QualiexUserFieldDoc-CE1e4mx6.js +149 -0
- package/dist/assets/RadioGroupDoc-DMZH6NmR.js +57 -0
- package/dist/assets/RadiusDoc-BOZD3gPV.js +7 -0
- package/dist/assets/RequiredFieldsCounterDoc-CG-lmSSy.js +58 -0
- package/dist/assets/ResizableDoc-CqGkv6Cd.js +104 -0
- package/dist/assets/RichTextEditorDoc-m50ll-Od.js +24 -0
- package/dist/assets/ScrollAreaDoc-BzJ-APXo.js +28 -0
- package/dist/assets/SecurityDoc-B34gVeiV.js +204 -0
- package/dist/assets/SelectDoc-DXRv7QHK.js +80 -0
- package/dist/assets/SeparatorDoc-DcNh8k0P.js +4 -0
- package/dist/assets/ServicesDoc-8aXBd6yg.js +308 -0
- package/dist/assets/ShadowsDoc-Brl4hIDI.js +9 -0
- package/dist/assets/SignDoc-BdwerR-2.js +66 -0
- package/dist/assets/SkeletonDoc-BWgqgbDY.js +54 -0
- package/dist/assets/SliderDoc-E-NjbYVk.js +41 -0
- package/dist/assets/SpacingDoc-BzburM-r.js +12 -0
- package/dist/assets/SplitButtonDoc-BYUysmJp.js +53 -0
- package/dist/assets/StepSelectorDoc-PB1k4v7F.js +41 -0
- package/dist/assets/SwitchDoc-BLOG6kfj.js +56 -0
- package/dist/assets/TableDoc-Dwcs-lop.js +128 -0
- package/dist/assets/TabsDoc-Ovkh8ArV.js +42 -0
- package/dist/assets/TextareaDoc-DsBYxmbr.js +46 -0
- package/dist/assets/ToastDoc-BbZaFE_A.js +157 -0
- package/dist/assets/ToggleDoc-C28vbvhp.js +51 -0
- package/dist/assets/TooltipDoc-DL5cnLak.js +58 -0
- package/dist/assets/TruncatedCellDoc-BuDA8QcY.js +12 -0
- package/dist/assets/TypographyFoundationDoc-CPdH4PHa.js +7 -0
- package/dist/assets/UtilitiesDoc-CrQhyEfz.js +145 -0
- package/dist/assets/blocks-DO93nPjs.js +1 -0
- package/dist/assets/calendar-days-cMfwBSZx.js +1 -0
- package/dist/assets/circle-plus-D3NftMzS.js +1 -0
- package/dist/assets/circle-x-BVAVJ_oz.js +1 -0
- package/dist/assets/crown-B2MTZDnM.js +1 -0
- package/dist/assets/date-picker-zhJU-_kM.js +1 -0
- package/dist/assets/disabled-menu-item-C16xsaVs.js +1 -0
- package/dist/assets/drawer-oTqCOtsC.js +3 -0
- package/dist/assets/file-pen-line-CXv-Eye-.js +1 -0
- package/dist/assets/git-branch-V6-h6P9K.js +1 -0
- package/dist/assets/globe-CaUBIJU8.js +1 -0
- package/dist/assets/hash-B4MTXppl.js +1 -0
- package/dist/assets/hover-card-DEuucfxP.js +1 -0
- package/dist/assets/index-CE0k7Rdh.js +312 -0
- package/dist/assets/index-Cx3adT_u.css +1 -0
- package/dist/assets/life-buoy-BRndExxh.js +1 -0
- package/dist/assets/lucide-react-t7dCa4lv.js +1 -0
- package/dist/assets/monitor-Dg3HKTSE.js +1 -0
- package/dist/assets/package-3G45ARQh.js +1 -0
- package/dist/assets/pen-BYSSwjK4.js +1 -0
- package/dist/assets/pin-CMYagNhs.js +1 -0
- package/dist/assets/radio-group-BVun_Tmt.js +1 -0
- package/dist/assets/server-p0Sb0mKI.js +1 -0
- package/dist/assets/share-2-D-ZhCCq2.js +1 -0
- package/dist/assets/shield-x-Q7hAXWsG.js +1 -0
- package/dist/assets/step-selector-DHxgT2FL.js +1 -0
- package/dist/assets/text-align-start-6aYQqbX4.js +1 -0
- package/dist/assets/trash-DveAOiLF.js +1 -0
- package/dist/assets/useMockCrud-GY0KxHXr.js +1 -0
- package/dist/assets/user-check-CoGNBfIk.js +1 -0
- package/dist/assets/user-plus-Bad2xWIT.js +1 -0
- package/dist/bin/pull-docs.js +14 -13
- package/dist/components/modules/ModuleAccessGuard.d.ts +24 -2
- package/dist/components/ui/combo-tree.d.ts +2 -0
- package/dist/contexts/PageMetadataContext.d.ts +6 -1
- package/dist/crud/components/ColumnSettingsPopover.d.ts +17 -0
- package/dist/crud/components/CrudActionBar.d.ts +2 -1
- package/dist/crud/components/CrudTable.d.ts +5 -1
- package/dist/crud/components/GroupDropZone.d.ts +16 -0
- package/dist/crud/components/InlineRowActions.d.ts +15 -0
- package/dist/crud/hooks/useColumnDragReorder.d.ts +19 -0
- package/dist/crud/hooks/useColumnManager.d.ts +56 -0
- package/dist/crud/primitives/Table.d.ts +1 -1
- package/dist/crud/primitives/TreeTable.d.ts +2 -0
- package/dist/crud/primitives/index.d.ts +2 -1
- package/dist/crud/primitives/types.d.ts +33 -0
- package/dist/docs/KNOWLEDGE.md +68 -167
- package/dist/exports/crud.d.ts +2 -1
- package/dist/hooks/useDerivedContractedModules.d.ts +8 -0
- package/dist/i18n/config.d.ts +11 -0
- package/dist/i18n/index.d.ts +1 -1
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.html +35 -0
- package/dist/index.js +1 -1
- package/dist/providers/CoreProviders.d.ts +31 -34
- package/dist/types.d.ts +4 -0
- package/docs/KNOWLEDGE.md +68 -167
- package/package.json +2 -3
- package/docs/DESIGN_SYSTEM.md +0 -12174
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Estratégia de Documentação
|
|
2
|
+
|
|
3
|
+
## Fonte de verdade
|
|
4
|
+
|
|
5
|
+
| Tipo | Local | Sincronizado via `lib-update` |
|
|
6
|
+
|------|-------|-------------------------------|
|
|
7
|
+
| Regras críticas | `docs/KNOWLEDGE.md` | Sim |
|
|
8
|
+
| Regras da IA | `.note/memory/rules/` | Sim |
|
|
9
|
+
| Padrões de layout | `.note/memory/patterns/` | Não (cross-project) |
|
|
10
|
+
| Componentes/UI | `.note/memory/components/` | Não (cross-project) |
|
|
11
|
+
| Arquitetura | `.note/memory/architecture/` | Não (cross-project) |
|
|
12
|
+
| Design System visual | Rota `/ds` no app | — |
|
|
13
|
+
| Props e tipos | Código-fonte da lib | Cross-project |
|
|
14
|
+
|
|
15
|
+
## Memórias por categoria
|
|
16
|
+
|
|
17
|
+
### Rules (sincronizadas)
|
|
18
|
+
- `supabase-schema-rule` — Schema obrigatório em queries
|
|
19
|
+
- `supabase-import-rule` — Usar getSupabaseClient() da lib
|
|
20
|
+
- `no-delete-policy-rule` — Soft delete, sem FOR DELETE
|
|
21
|
+
- `no-auto-index-rule` — Sem índices preventivos
|
|
22
|
+
- `no-env-modification-rule` — Sem alterar .env
|
|
23
|
+
- `rls-syntax-rule` — Sintaxe RLS por operação
|
|
24
|
+
- `sql-naming-rule` — Nomenclatura de tabelas, FKs, booleans
|
|
25
|
+
- `lib-first-rule` — Priorizar forlogic-core
|
|
26
|
+
- `i18n-import-rule` — Import de forlogic-core, não react-i18next
|
|
27
|
+
- `doc-sync-rule` — Como funciona o lib-update
|
|
28
|
+
|
|
29
|
+
### Patterns (cross-project)
|
|
30
|
+
- `vite-tailwind-setup` — Config de build e preset
|
|
31
|
+
- `feature-flags` — Variáveis de ambiente disponíveis
|
|
32
|
+
- `i18n-setup` — Namespaces core/app
|
|
33
|
+
- `core-providers-setup` — Hierarquia de providers
|
|
34
|
+
- `header-metadata-pattern` — usePageMetadata
|
|
35
|
+
- `spa-navigation-pattern` — Navegação SPA
|
|
36
|
+
- `crud-toolbar-layout` — Layout 3 zonas
|
|
37
|
+
- `crud-action-bar-3-zone-layout` — ActionBar zones
|
|
38
|
+
- `crud-bulk-actions-dropdown-standard` — Ações em lote
|
|
39
|
+
- `single-scroll-pattern` — Scroll único
|
|
40
|
+
- `dialog-body-scroll-pattern` — Scroll em dialogs
|
|
41
|
+
- `body-content-scroll-usage` — BodyContent
|
|
42
|
+
- `deprecated-patterns` — Mapa de substituição
|
|
43
|
+
|
|
44
|
+
### Components (cross-project)
|
|
45
|
+
- `action-button-for-tables` — ActionButton em tabelas
|
|
46
|
+
- `alertdialog-permanent-deletion` — AlertDialog
|
|
47
|
+
- `baseform-custom-fields` — Campos customizados
|
|
48
|
+
- `baseform-usage` — Uso do BaseForm
|
|
49
|
+
- `delete-confirmation-dialog` — Dialog destrutivo
|
|
50
|
+
- `dialog-sizes-and-structure` — Tamanhos de dialog
|
|
51
|
+
- `dialog-variants` — Variantes de dialog
|
|
52
|
+
- `pagination-usage` — CrudPrimitivePagination
|
|
53
|
+
|
|
54
|
+
## O que NÃO é sincronizado
|
|
55
|
+
|
|
56
|
+
- `docs/PUBLISH.md` — Operacional
|
|
57
|
+
- `lib/media/README.md` — Coberto pelo DS
|
|
58
|
+
- Templates Vite completos — Coberto por patterns
|
|
59
|
+
- Referência de API de componentes — Coberto pelo DS (`/ds`)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Padrão: CoreProviders Setup
|
|
2
|
+
|
|
3
|
+
## Providers incluídos
|
|
4
|
+
|
|
5
|
+
| Provider | Descrição |
|
|
6
|
+
|----------|-----------|
|
|
7
|
+
| ErrorBoundary | Captura erros de renderização React |
|
|
8
|
+
| I18nextProvider | Sistema de internacionalização |
|
|
9
|
+
| QueryClientProvider | Cache e queries (React Query) |
|
|
10
|
+
| AuthProvider | Autenticação e sessão |
|
|
11
|
+
| LocaleProvider | Idioma, timezone, formato de data |
|
|
12
|
+
| ModuleProvider | Configuração de módulo ativo |
|
|
13
|
+
| ModuleAccessGuard | Bloqueio de acesso por módulo |
|
|
14
|
+
|
|
15
|
+
## Uso básico
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
<CoreProviders moduleAlias="performance" appTranslations={{ 'pt-BR': ptBR }}>
|
|
19
|
+
<BrowserRouter>
|
|
20
|
+
<Routes />
|
|
21
|
+
</BrowserRouter>
|
|
22
|
+
</CoreProviders>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Props
|
|
26
|
+
|
|
27
|
+
| Prop | Tipo | Obrigatório | Descrição |
|
|
28
|
+
|------|------|-------------|-----------|
|
|
29
|
+
| children | ReactNode | Sim | Componentes filhos |
|
|
30
|
+
| queryClient | QueryClient | Não | Instância customizada (default criado automaticamente) |
|
|
31
|
+
| moduleAlias | string | Não | Alias do módulo para verificação de acesso |
|
|
32
|
+
| moduleAccessGuardProps | object | Não | Props para o ModuleAccessGuard |
|
|
33
|
+
| appTranslations | Record<string, Record<string, string>> | Não | Traduções por idioma no namespace 'app' |
|
|
34
|
+
|
|
35
|
+
## QueryClient default
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
{ defaultOptions: { queries: { staleTime: 5 * 60 * 1000, retry: 1 } } }
|
|
39
|
+
```
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Padrões Deprecated
|
|
2
|
+
|
|
3
|
+
## Mapa de substituição
|
|
4
|
+
|
|
5
|
+
| Não usar | Usar | Motivo |
|
|
6
|
+
|----------|------|--------|
|
|
7
|
+
| `BulkActionBar` separado | Dropdown integrado no `CrudActionBar` | Consolidação de toolbar |
|
|
8
|
+
| `<MoreHorizontal>` genérico | `ActionButton` da lib | Padrão consistente de ações |
|
|
9
|
+
| Paginação manual | `CrudPrimitivePagination` com `variant="full"` | API unificada |
|
|
10
|
+
| `StatusSelect` | `Combobox` | Componente mais flexível |
|
|
11
|
+
| `DeleteConfirmationDialog` | `Dialog` com variant destrutiva | Componente padrão da lib |
|
|
12
|
+
| `Searchbar` | `Input` com ícone de busca | Simplificação |
|
|
13
|
+
| Schema `public` | `.schema('common')` | Schema customizado do projeto |
|
|
14
|
+
| `import { supabase }` local | `getSupabaseClient()` de `forlogic-core` | Auth headers automáticos |
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Padrão: Feature Flags (Variáveis de Ambiente)
|
|
2
|
+
|
|
3
|
+
## Variáveis disponíveis
|
|
4
|
+
|
|
5
|
+
| Variável | Descrição | Padrão |
|
|
6
|
+
|----------|-----------|--------|
|
|
7
|
+
| `VITE_SHOW_USER_PREFERENCES` | Exibe "Preferências" no menu do usuário (idioma, timezone, formato de data) | Não exibe |
|
|
8
|
+
| `VITE_I18N_DEBUG_MODE` | Modo debug de i18n (mostra chaves ao invés de traduções) | `"false"` |
|
|
9
|
+
| `VITE_IS_QUALIEX` | Usa logos Qualiex ao invés de Forlogic | `"false"` |
|
|
10
|
+
|
|
11
|
+
## Uso
|
|
12
|
+
|
|
13
|
+
```env
|
|
14
|
+
VITE_SHOW_USER_PREFERENCES=true
|
|
15
|
+
VITE_I18N_DEBUG_MODE=false
|
|
16
|
+
VITE_IS_QUALIEX=true
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Variáveis Vite precisam do prefixo `VITE_` para serem expostas ao cliente.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Padrão: Título, Subtítulo e Breadcrumbs via Header (usePageMetadata)
|
|
2
|
+
|
|
3
|
+
## Regra
|
|
4
|
+
|
|
5
|
+
**O padrão da aplicação é exibir título, subtítulo e breadcrumbs no header** usando `usePageMetadata()`.
|
|
6
|
+
|
|
7
|
+
- **NÃO** usar `BodyContent` ou `ContentContainer` com título/subtítulo internos por padrão.
|
|
8
|
+
- Breadcrumbs, títulos e subtítulos internos ao conteúdo são **exceções** e devem ser usados **somente quando explicitamente solicitados** pelo usuário.
|
|
9
|
+
|
|
10
|
+
## Uso Padrão
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
import { usePageMetadata } from 'forlogic-core';
|
|
14
|
+
|
|
15
|
+
export function MinhaPage() {
|
|
16
|
+
usePageMetadata({ title: 'Título', subtitle: 'Subtítulo descritivo' });
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div className="flex flex-col h-full p-4 gap-4">
|
|
20
|
+
{/* conteúdo direto, sem BodyContent/ContentContainer */}
|
|
21
|
+
</div>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Com Breadcrumbs
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
usePageMetadata({
|
|
30
|
+
title: 'Editar Usuário',
|
|
31
|
+
subtitle: 'Atualize os dados cadastrais',
|
|
32
|
+
breadcrumbs: [
|
|
33
|
+
{ label: 'Usuários', href: '/users' },
|
|
34
|
+
{ label: 'João Silva' }
|
|
35
|
+
]
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Subtitle com ReactNode
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
usePageMetadata({
|
|
43
|
+
title: 'Detalhes',
|
|
44
|
+
subtitle: <span>Veja a <Link to="/docs">documentação</Link></span>
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## ❌ Evitar (exceto quando pedido)
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
// NÃO fazer por padrão:
|
|
52
|
+
<BodyContent breadcrumbs={[{ label: 'Página' }]}>
|
|
53
|
+
<ContentContainer title="Título" subtitle="Subtítulo">
|
|
54
|
+
...
|
|
55
|
+
</ContentContainer>
|
|
56
|
+
</BodyContent>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Quando usar breadcrumbs/título interno
|
|
60
|
+
|
|
61
|
+
- Apenas quando o usuário **pedir explicitamente** breadcrumbs ou título dentro do conteúdo.
|
|
62
|
+
- Páginas com navegação hierárquica profunda podem justificar breadcrumbs, mas sempre confirmar antes.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Padrão: Setup de Traduções (i18n)
|
|
2
|
+
|
|
3
|
+
## Arquitetura de namespaces
|
|
4
|
+
|
|
5
|
+
- `core` — traduções base da lib (save, cancel, delete, etc.)
|
|
6
|
+
- `app` — traduções do projeto consumidor (injetadas via `CoreProviders`)
|
|
7
|
+
- Resolução: `app` → `core` → fallback `pt-BR`
|
|
8
|
+
|
|
9
|
+
## Setup em projetos consumidores
|
|
10
|
+
|
|
11
|
+
1. Criar JSONs flat em `src/i18n/pt-BR.json`: `{ "key": "value" }` (sem nesting)
|
|
12
|
+
2. Passar para CoreProviders:
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
<CoreProviders appTranslations={{ 'pt-BR': ptBR, 'en-US': enUS }}>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
3. Usar `useTranslation` de `forlogic-core` (nunca de `react-i18next`)
|
|
19
|
+
|
|
20
|
+
## Resolução de chaves
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
t('save') → app: não encontra → core: "Salvar"
|
|
24
|
+
t('objective') → app: "Objetivo"
|
|
25
|
+
t('save') com override no app → app: "Gravar" (sobrescreve core)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Debug
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { i18n } from 'forlogic-core';
|
|
32
|
+
console.log('Resources:', i18n.store.data);
|
|
33
|
+
// { 'pt-BR': { core: {...}, app: {...} } }
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Troubleshooting
|
|
37
|
+
|
|
38
|
+
| Causa | Solução |
|
|
39
|
+
|-------|---------|
|
|
40
|
+
| Chaves aparecem ao invés de traduções | Instalar peer deps `i18next` e `react-i18next` |
|
|
41
|
+
| Import de `react-i18next` direto | Usar import de `forlogic-core` |
|
|
42
|
+
| `appTranslations` não passado | Adicionar prop no CoreProviders |
|
|
43
|
+
| JSON com formato errado | Deve ser flat, sem nesting |
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Padrão: Setup Vite + Tailwind para Projetos Consumidores
|
|
2
|
+
|
|
3
|
+
## Vite — Security Headers
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { createSecurityHeadersPlugin } from 'forlogic-core/vite';
|
|
7
|
+
|
|
8
|
+
export default defineConfig(({ mode }) => ({
|
|
9
|
+
plugins: [
|
|
10
|
+
react(),
|
|
11
|
+
createSecurityHeadersPlugin(mode === 'development', {
|
|
12
|
+
supabaseUrls: ['https://SEU_PROJETO.supabase.co'],
|
|
13
|
+
additionalConnectSrc: ['https://*.qualiex.com'],
|
|
14
|
+
}),
|
|
15
|
+
],
|
|
16
|
+
resolve: {
|
|
17
|
+
alias: { '@': path.resolve(__dirname, './src') }, // DEVE ser absoluto
|
|
18
|
+
},
|
|
19
|
+
optimizeDeps: { force: true }, // Força re-bundle ao atualizar forlogic-core
|
|
20
|
+
publicDir: false,
|
|
21
|
+
esbuild: { sourcemap: true, target: 'es2020' },
|
|
22
|
+
build: { chunkSizeWarningLimit: 4000 },
|
|
23
|
+
}));
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Opções do plugin: `supabaseUrls`, `trustedOrigins`, `additionalScriptSrc`, `additionalStyleSrc`, `additionalConnectSrc`, `cspReportUri`, `enableTrustedTypes` (default true), `upgradeInsecureRequests` (default true).
|
|
27
|
+
|
|
28
|
+
Alternativa: `createForlogicViteConfig()` factory que retorna config completa (ver README).
|
|
29
|
+
|
|
30
|
+
## Tailwind
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { forlogicTailwindPreset, forlogicContentPaths } from 'forlogic-core/tailwind';
|
|
34
|
+
|
|
35
|
+
export default {
|
|
36
|
+
presets: [forlogicTailwindPreset],
|
|
37
|
+
content: [...forlogicContentPaths],
|
|
38
|
+
} satisfies Config;
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`forlogicContentPaths` inclui: `./src/**/*.{ts,tsx}`, `./lib/**/*.{ts,tsx}`, `./node_modules/forlogic-core/dist/**/*.{js,ts,jsx,tsx}`, etc.
|
|
42
|
+
|
|
43
|
+
## Checklist
|
|
44
|
+
|
|
45
|
+
- [ ] `createSecurityHeadersPlugin` no vite.config.ts com URLs do Supabase
|
|
46
|
+
- [ ] `resolve.alias` usa `path.resolve(__dirname, ...)`
|
|
47
|
+
- [ ] `forlogicTailwindPreset` no tailwind.config.ts
|
|
48
|
+
- [ ] `forlogicContentPaths` no content
|
|
49
|
+
- [ ] Variáveis CSS definidas no index.css (--primary, --background, etc.)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Regra: Sincronização Automática de Documentação
|
|
2
|
+
|
|
3
|
+
## Gatilho
|
|
4
|
+
|
|
5
|
+
Sempre que modificar qualquer arquivo em `lib/`, verificar se existe documentação correspondente em `src/design-system/docs/`.
|
|
6
|
+
|
|
7
|
+
## Ações obrigatórias
|
|
8
|
+
|
|
9
|
+
### 1. Componente/hook existente com doc existente
|
|
10
|
+
- Atualizar props, exemplos e descrições no `*Doc.tsx` correspondente para refletir a mudança
|
|
11
|
+
|
|
12
|
+
### 2. Componente/hook novo sem doc
|
|
13
|
+
- Criar `*Doc.tsx` usando `ComponentDocTemplate` (com prop `usage` obrigatória)
|
|
14
|
+
- Registrar no `src/design-system/config/docRegistry.ts` (lazy import)
|
|
15
|
+
- Registrar no `src/design-system/config/sections.ts` (sidebar + breadcrumb)
|
|
16
|
+
|
|
17
|
+
### 3. Mudanças arquiteturais
|
|
18
|
+
- Atualizar `docs/KNOWLEDGE.md` se afetar regras, mapa de módulos ou convenções
|
|
19
|
+
- Atualizar `.note/memory/` se afetar padrões documentados
|
|
20
|
+
|
|
21
|
+
## Mapeamento de referência
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
lib/components/ui/<comp>.tsx → src/design-system/docs/components/<Comp>Doc.tsx
|
|
25
|
+
lib/crud/components/<comp>.tsx → src/design-system/docs/components/crud/<Comp>Doc.tsx
|
|
26
|
+
lib/contexts/<Context>.tsx → src/design-system/docs/ContextsDoc.tsx
|
|
27
|
+
lib/hooks/<hook>.ts → src/design-system/docs/HooksDoc.tsx
|
|
28
|
+
lib/services/<Service>.ts → src/design-system/docs/ServicesDoc.tsx
|
|
29
|
+
lib/components/layout/<comp>.tsx → src/design-system/docs/components/layout/<Comp>Doc.tsx
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Consultar `.note/memory/documentation/consolidated-components-registry.md` para componentes agrupados sob uma única doc.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Regra: Import de i18n
|
|
2
|
+
|
|
3
|
+
## Regra
|
|
4
|
+
|
|
5
|
+
Sempre importar `useTranslation` de `forlogic-core`, nunca de `react-i18next`.
|
|
6
|
+
|
|
7
|
+
## Motivo
|
|
8
|
+
|
|
9
|
+
Importar de `react-i18next` cria uma instância separada do i18next, causando erro `NO_I18NEXT_INSTANCE` e traduções não funcionam.
|
|
10
|
+
|
|
11
|
+
## Correto
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { useTranslation } from 'forlogic-core';
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Errado
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { useTranslation } from 'react-i18next';
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Aplica-se a
|
|
24
|
+
|
|
25
|
+
- `useTranslation`
|
|
26
|
+
- `i18n` (instância)
|
|
27
|
+
- Qualquer hook/utilidade de i18n
|
|
28
|
+
|
|
29
|
+
Todos devem vir de `forlogic-core` para compartilhar a mesma instância configurada pelo `CoreProviders`.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Regra: Lib-First (forlogic-core)
|
|
2
|
+
|
|
3
|
+
## Regra
|
|
4
|
+
|
|
5
|
+
Antes de criar qualquer componente, serviço ou utilitário no projeto, verificar se já existe na `forlogic-core`.
|
|
6
|
+
|
|
7
|
+
## Checklist obrigatório
|
|
8
|
+
|
|
9
|
+
1. Pesquisar se o componente existe na forlogic-core (`lib/index.ts`, `lib/exports/`)
|
|
10
|
+
2. Verificar documentação do Design System (`/ds`)
|
|
11
|
+
3. Confirmar que a funcionalidade não pode ser alcançada com props/variantes existentes
|
|
12
|
+
|
|
13
|
+
## Correto
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { Button, Dialog, Combobox, createCrudPage, cn, formatDatetime } from 'forlogic-core';
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Proibido (se existe na lib)
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
src/components/ui/button.tsx // Existe na lib
|
|
23
|
+
src/components/ui/dialog.tsx // Existe na lib
|
|
24
|
+
src/lib/utils.ts // cn() existe na lib
|
|
25
|
+
src/components/SplitButton.tsx // Existe na lib
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Exceções (quando PODE criar localmente)
|
|
29
|
+
|
|
30
|
+
1. Componente específico de negócio (ex: `InvoiceCard`, `UserProfileWidget`)
|
|
31
|
+
2. Composição de componentes da lib (ex: wrapper que combina Dialog + Form)
|
|
32
|
+
3. Componente temporário (protótipo que será migrado para a lib)
|
|
33
|
+
4. Funcionalidade não generalizável
|
|
34
|
+
|
|
35
|
+
## Quando precisa de customização
|
|
36
|
+
|
|
37
|
+
| Cenário | Ação correta |
|
|
38
|
+
|---------|-------------|
|
|
39
|
+
| Componente não existe na lib | Criar localmente E solicitar inclusão na lib |
|
|
40
|
+
| Precisa de variante nova | Solicitar variante na lib |
|
|
41
|
+
| Precisa de comportamento específico | Usar composição/wrapper |
|
|
42
|
+
| Bug no componente da lib | Reportar e corrigir na lib, não criar cópia local |
|
|
@@ -1,20 +1,48 @@
|
|
|
1
|
-
#
|
|
2
|
-
Updated: now
|
|
1
|
+
# Regra: Sem índices automáticos
|
|
3
2
|
|
|
4
3
|
**NUNCA** criar índices automaticamente em migrations.
|
|
5
4
|
|
|
5
|
+
## Errado
|
|
6
|
+
|
|
6
7
|
```sql
|
|
7
|
-
-- ❌
|
|
8
|
-
CREATE INDEX idx_subprocess_process ON subprocesses(id_process);
|
|
9
|
-
CREATE INDEX idx_process_title ON processes(title);
|
|
8
|
+
-- ❌ Índice "por precaução"
|
|
9
|
+
CREATE INDEX idx_subprocess_process ON common.subprocesses(id_process);
|
|
10
|
+
CREATE INDEX idx_process_title ON common.processes(title);
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Correto
|
|
10
14
|
|
|
11
|
-
|
|
12
|
-
|
|
15
|
+
```sql
|
|
16
|
+
-- ✅ Criar tabela SEM índices
|
|
17
|
+
CREATE TABLE common.processes (
|
|
18
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
19
|
+
title TEXT NOT NULL,
|
|
20
|
+
id_process UUID REFERENCES common.processes(id),
|
|
21
|
+
created_at TIMESTAMPTZ DEFAULT now()
|
|
22
|
+
);
|
|
13
23
|
```
|
|
14
24
|
|
|
15
|
-
|
|
25
|
+
## Quando criar índices
|
|
26
|
+
|
|
27
|
+
APENAS quando:
|
|
16
28
|
1. Solicitado explicitamente pelo usuário
|
|
17
|
-
2. Análise de performance comprovou necessidade (EXPLAIN ANALYZE)
|
|
29
|
+
2. Análise de performance comprovou necessidade (`EXPLAIN ANALYZE`)
|
|
18
30
|
3. Aprovação prévia do usuário
|
|
19
31
|
|
|
32
|
+
## Template (quando aprovado)
|
|
33
|
+
|
|
34
|
+
```sql
|
|
35
|
+
-- Migration: add_index_<table>_<column>
|
|
36
|
+
-- Motivo: [justificativa com dados de EXPLAIN ANALYZE]
|
|
37
|
+
-- Aprovado por: [usuário]
|
|
38
|
+
CREATE INDEX idx_<table>_<column> ON common.<table>(<column>);
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Checklist de migration
|
|
42
|
+
|
|
43
|
+
- [ ] Tabela criada sem índices extras
|
|
44
|
+
- [ ] RLS habilitado (`ALTER TABLE ... ENABLE ROW LEVEL SECURITY`)
|
|
45
|
+
- [ ] Policies criadas (SELECT, INSERT, UPDATE — nunca DELETE)
|
|
46
|
+
- [ ] Soft delete configurado (`deleted_at` column)
|
|
47
|
+
|
|
20
48
|
**Motivo**: Índices custam espaço, impactam escrita e 99% dos "preventivos" nunca são usados.
|
|
@@ -1,23 +1,52 @@
|
|
|
1
|
-
#
|
|
2
|
-
Updated: now
|
|
1
|
+
# Regra: Sem DELETE físico
|
|
3
2
|
|
|
4
3
|
**NUNCA** criar política RLS de DELETE. Usar soft delete com UPDATE.
|
|
5
4
|
|
|
5
|
+
## Implementação
|
|
6
|
+
|
|
7
|
+
```sql
|
|
8
|
+
-- 1. Adicionar coluna de soft delete
|
|
9
|
+
ALTER TABLE common.tabela ADD COLUMN deleted_at TIMESTAMP WITH TIME ZONE;
|
|
10
|
+
|
|
11
|
+
-- 2. Policy SELECT filtrando deletados
|
|
12
|
+
CREATE POLICY "table_select" ON common.tabela
|
|
13
|
+
FOR SELECT USING (
|
|
14
|
+
deleted_at IS NULL
|
|
15
|
+
AND ((SELECT auth.jwt()) ->> 'alias'::text) = alias
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
-- 3. Policy UPDATE para permitir soft delete
|
|
19
|
+
CREATE POLICY "table_update" ON common.tabela
|
|
20
|
+
FOR UPDATE
|
|
21
|
+
USING (((SELECT auth.jwt()) ->> 'alias'::text) = alias)
|
|
22
|
+
WITH CHECK (((SELECT auth.jwt()) ->> 'alias'::text) = alias);
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Errado
|
|
26
|
+
|
|
6
27
|
```sql
|
|
7
28
|
-- ❌ PROIBIDO
|
|
8
|
-
CREATE POLICY "table_delete" ON common.
|
|
29
|
+
CREATE POLICY "table_delete" ON common.tabela
|
|
9
30
|
FOR DELETE USING (...);
|
|
10
31
|
|
|
11
|
-
--
|
|
12
|
-
|
|
32
|
+
-- ❌ DELETE físico no código
|
|
33
|
+
await supabase.schema('common').from('tabela').delete().eq('id', id);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Correto no código
|
|
13
37
|
|
|
14
|
-
|
|
15
|
-
|
|
38
|
+
```ts
|
|
39
|
+
// ✅ Soft delete via UPDATE
|
|
40
|
+
await supabase.schema('common')
|
|
41
|
+
.from('tabela')
|
|
42
|
+
.update({ deleted_at: new Date().toISOString() })
|
|
43
|
+
.eq('id', id);
|
|
16
44
|
```
|
|
17
45
|
|
|
18
|
-
|
|
46
|
+
## Sintaxe RLS
|
|
47
|
+
|
|
48
|
+
- `SELECT` → `USING`
|
|
49
|
+
- `INSERT` → `WITH CHECK`
|
|
50
|
+
- `UPDATE` → `USING` + `WITH CHECK`
|
|
19
51
|
|
|
20
|
-
**
|
|
21
|
-
- `SELECT` → usa `USING`
|
|
22
|
-
- `INSERT` → usa `WITH CHECK`
|
|
23
|
-
- `UPDATE` → usa `USING` E `WITH CHECK`
|
|
52
|
+
**Motivo**: Soft delete preserva histórico e evita problemas de integridade referencial.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Regra: Sintaxe RLS
|
|
2
|
+
|
|
3
|
+
## Sintaxe por operação
|
|
4
|
+
|
|
5
|
+
| Operação | Cláusula |
|
|
6
|
+
|----------|----------|
|
|
7
|
+
| SELECT | `USING` |
|
|
8
|
+
| INSERT | `WITH CHECK` |
|
|
9
|
+
| UPDATE | `USING` + `WITH CHECK` |
|
|
10
|
+
| DELETE | **PROIBIDO** (usar soft delete) |
|
|
11
|
+
|
|
12
|
+
## Padrão JWT com parênteses
|
|
13
|
+
|
|
14
|
+
Sempre usar `(SELECT auth.jwt())` com parênteses para evitar re-execução por linha:
|
|
15
|
+
|
|
16
|
+
```sql
|
|
17
|
+
-- ✅ Correto
|
|
18
|
+
CREATE POLICY "table_select" ON common.tabela
|
|
19
|
+
FOR SELECT USING (
|
|
20
|
+
((SELECT auth.jwt()) ->> 'alias'::text) = alias
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
-- ❌ Errado — re-executa por linha
|
|
24
|
+
CREATE POLICY "table_select" ON common.tabela
|
|
25
|
+
FOR SELECT USING (
|
|
26
|
+
(auth.jwt() ->> 'alias'::text) = alias
|
|
27
|
+
);
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Erros comuns
|
|
31
|
+
|
|
32
|
+
```sql
|
|
33
|
+
-- ❌ WITH CHECK em SELECT
|
|
34
|
+
FOR SELECT WITH CHECK (...);
|
|
35
|
+
|
|
36
|
+
-- ❌ USING em INSERT
|
|
37
|
+
FOR INSERT USING (...);
|
|
38
|
+
|
|
39
|
+
-- ❌ Parênteses extras no JWT
|
|
40
|
+
((SELECT (auth.jwt()) ->> 'alias'::text))
|
|
41
|
+
|
|
42
|
+
-- ❌ Policy DELETE
|
|
43
|
+
FOR DELETE USING (...);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Padrões multi-tenant
|
|
47
|
+
|
|
48
|
+
- **Por alias**: `((SELECT auth.jwt()) ->> 'alias'::text) = alias`
|
|
49
|
+
- **Por user**: `auth.uid() = id_user`
|
|
50
|
+
- **Por company**: `company_id = ((SELECT auth.jwt()) -> 'user_metadata' ->> 'company_id')::uuid`
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Regra: Nomenclatura SQL
|
|
2
|
+
|
|
3
|
+
## Convenções
|
|
4
|
+
|
|
5
|
+
| Tipo | Padrão | Exemplo |
|
|
6
|
+
|------|--------|---------|
|
|
7
|
+
| Tabelas | plural, snake_case | `processes`, `user_roles` |
|
|
8
|
+
| FK | `id_<tabela_singular>` | `id_process`, `id_user` |
|
|
9
|
+
| Boolean | `is_` ou `has_` | `is_active`, `has_access` |
|
|
10
|
+
| Timestamps | sufixo `_at` | `created_at`, `updated_at`, `deleted_at` |
|
|
11
|
+
|
|
12
|
+
## Errado
|
|
13
|
+
|
|
14
|
+
```sql
|
|
15
|
+
-- ❌ FK sem prefixo id_
|
|
16
|
+
process_id, userId, fk_process
|
|
17
|
+
|
|
18
|
+
-- ❌ Boolean sem prefixo
|
|
19
|
+
active, verified, access
|
|
20
|
+
|
|
21
|
+
-- ❌ Tabela singular ou camelCase
|
|
22
|
+
process, userRole, UserRoles
|
|
23
|
+
```
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Regra: Import do Supabase
|
|
2
|
+
|
|
3
|
+
## Regra
|
|
4
|
+
|
|
5
|
+
Sempre usar `getSupabaseClient()` ou `getPublicSupabaseClient()` de `forlogic-core`. Nunca importar de `@/integrations/supabase/client` nem criar instâncias com `createClient`.
|
|
6
|
+
|
|
7
|
+
## Correto
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { getSupabaseClient } from 'forlogic-core';
|
|
11
|
+
const supabase = getSupabaseClient();
|
|
12
|
+
|
|
13
|
+
// Para operações sem autenticação
|
|
14
|
+
import { getPublicSupabaseClient } from 'forlogic-core';
|
|
15
|
+
const publicClient = getPublicSupabaseClient();
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Errado
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
// ❌ Cliente local sem token do usuário
|
|
22
|
+
import { supabase } from '@/integrations/supabase/client';
|
|
23
|
+
|
|
24
|
+
// ❌ Instância manual sem headers de auth
|
|
25
|
+
import { createClient } from '@supabase/supabase-js';
|
|
26
|
+
const supabase = createClient(url, key);
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Motivo
|
|
30
|
+
|
|
31
|
+
O `getSupabaseClient()` injeta automaticamente o `supabase_token` do usuário nos headers, garantindo que as policies RLS funcionem. Clientes criados manualmente usam apenas a chave anônima, causando falhas silenciosas de permissão em schemas protegidos.
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# Memory: rules/supabase-schema-rule
|
|
2
2
|
Updated: now
|
|
3
3
|
|
|
4
|
-
**SEMPRE**
|
|
4
|
+
**SEMPRE** use `.schema()` com o schema definido em `docs/KNOWLEDGE.md` (seção 0).
|
|
5
|
+
Leia o valor de lá antes de escrever qualquer query Supabase.
|
|
5
6
|
|
|
6
7
|
```typescript
|
|
7
|
-
// ✅ CORRETO
|
|
8
|
+
// ✅ CORRETO — schema vem da seção 0 do KNOWLEDGE.md
|
|
8
9
|
const { data } = await supabase
|
|
9
|
-
.schema('
|
|
10
|
+
.schema('<SCHEMA do KNOWLEDGE.md>')
|
|
10
11
|
.from('tabela')
|
|
11
12
|
.select('*');
|
|
12
13
|
|
|
@@ -16,4 +17,4 @@ const { data } = await supabase
|
|
|
16
17
|
.select('*');
|
|
17
18
|
```
|
|
18
19
|
|
|
19
|
-
**Motivo**: O projeto usa schema customizado
|
|
20
|
+
**Motivo**: O projeto usa schema customizado (não o `public` padrão do Supabase). O valor exato está centralizado em `docs/KNOWLEDGE.md` seção 0.
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
# Memory: ui/components/combo-tree
|
|
2
2
|
Updated: today
|
|
3
3
|
|
|
4
|
-
O componente `ComboTree` permite a seleção de dados hierárquicos com busca recursiva e separação entre expansão (chevron) e seleção (label).
|
|
4
|
+
O componente `ComboTree` permite a seleção de dados hierárquicos com busca recursiva e separação entre expansão (chevron) e seleção (label).
|
|
5
|
+
|
|
6
|
+
## Layout
|
|
7
|
+
- O **chevron** (▶/▼) fica no **final da linha** (à direita), indicando que o nó tem filhos
|
|
8
|
+
- O **check** (✓) e o **ícone** ficam no início, seguidos pelo label
|
|
9
|
+
- Nós sem filhos não exibem chevron
|
|
10
|
+
|
|
11
|
+
## Ícones customizados por nó
|
|
5
12
|
|
|
6
13
|
- `icon` — ícone padrão (nó colapsado e não selecionado)
|
|
7
14
|
- `iconOpen` — ícone quando o nó está **expandido** (fallback para `icon`)
|
|
8
15
|
- `iconSelected` — ícone quando o nó está **selecionado** (fallback para `iconOpen` se expandido, senão `icon`)
|
|
16
|
+
- `iconClassName` — classe CSS para cor/estilo do ícone (fallback: `text-muted-foreground`)
|
|
9
17
|
|
|
10
18
|
Prioridade de resolução:
|
|
11
19
|
- Selecionado + Expandido → `iconSelected ?? iconOpen ?? icon`
|