@lastbrain/app 0.1.33 → 0.1.36

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.
@@ -1,38 +1,41 @@
1
+ // GENERATED FILE - DO NOT EDIT MANUALLY
2
+ // This file is auto-generated from markdown files in docs/
3
+ // Run 'pnpm sync:docs' to regenerate
1
4
  import React from "react";
2
- import { Card, CardBody, CardHeader, Chip, Snippet } from "@lastbrain/ui";
5
+ import { Card, CardBody, CardHeader, Snippet,Alert } from "@lastbrain/ui";
3
6
  import {
7
+ FileText,
4
8
  Rocket,
5
9
  Building2,
6
10
  BookOpen,
7
11
  Database,
8
- Palette,
9
- Link as LinkIcon,
12
+ User,
10
13
  Shield,
11
14
  Zap,
15
+ Palette,
16
+ HardDrive,
17
+ Link
12
18
  } from "lucide-react";
13
19
 
14
20
  export function DefaultDocumentation() {
15
21
  return (
16
22
  <div className="space-y-6">
23
+
17
24
  <Card id="section-welcome" className="scroll-mt-32">
18
25
  <CardHeader>
19
- <div className="flex items-center justify-between w-full">
20
- <h1 className="text-3xl font-bold">Documentation LastBrain</h1>
21
- <Chip color="primary" variant="flat">
22
- v1.0.0
23
- </Chip>
24
- </div>
26
+ <h2 className="text-2xl font-semibold flex items-center gap-2">
27
+ <FileText size={24} />
28
+ Documentation LastBrain
29
+ </h2>
25
30
  </CardHeader>
26
- <CardBody className="space-y-6">
27
- <div>
28
- <p className="text-slate-600 dark:text-slate-400 text-lg">
29
- LastBrain est un framework modulaire pour créer des applications
30
- Next.js avec une architecture basée sur des modules réutilisables.
31
- </p>
32
- </div>
31
+ <CardBody className="space-y-4">
32
+ <p className="text-slate-600 dark:text-slate-400">Framework modulaire pour créer rapidement des applications Next.js avec système de modules, authentification et base de données.</p>
33
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">LastBrain est un framework modulaire pour créer des applications Next.js avec une architecture basée sur des modules réutilisables.</p>
34
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2"><strong>Version:</strong> v1.0.0</p>
33
35
  </CardBody>
34
36
  </Card>
35
37
 
38
+
36
39
  <Card id="section-quickstart" className="scroll-mt-32">
37
40
  <CardHeader>
38
41
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -41,68 +44,102 @@ export function DefaultDocumentation() {
41
44
  </h2>
42
45
  </CardHeader>
43
46
  <CardBody className="space-y-4">
44
- <div>
45
- <h3 className="text-lg font-semibold mb-2">Installation</h3>
47
+ <p className="text-slate-600 dark:text-slate-400"><strong>Note importante :</strong> LastBrain est un écosystème de packages interconnectés. L'application générée utilise automatiquement <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">@lastbrain/core</code>, <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">@lastbrain/ui</code>, et les modules comme <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">@lastbrain/module-auth</code> et <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">@lastbrain/module-ai</code>. Tous ces packages sont nécessaires pour le bon fonctionnement.</p>
46
48
  <Snippet symbol="" hideSymbol className="text-sm mb-2">
47
- pnpm install
49
+ {`# 1. Créer une nouvelle application (utilise @latest pour la version la plus récente)`}
48
50
  </Snippet>
49
- </div>
50
-
51
- <div>
52
- <h3 className="text-lg font-semibold mb-2">
53
- Initialiser la base de données
54
- </h3>
55
51
  <Snippet symbol="" hideSymbol className="text-sm mb-2">
56
- pnpm db:init
52
+ {`pnpx @lastbrain/app@latest init mon-app`}
57
53
  </Snippet>
58
- <p className="text-sm text-slate-600 dark:text-slate-400">
59
- Démarre Supabase en local et applique les migrations
60
- </p>
61
- </div>
62
-
63
- <div>
64
- <h3 className="text-lg font-semibold mb-2">Ajouter des modules</h3>
65
54
  <Snippet symbol="" hideSymbol className="text-sm mb-2">
66
- pnpm lastbrain list-modules
55
+ {`# 2. Accéder au dossier`}
67
56
  </Snippet>
68
57
  <Snippet symbol="" hideSymbol className="text-sm mb-2">
69
- pnpm lastbrain add-module auth
58
+ {`cd mon-app`}
70
59
  </Snippet>
71
- <p className="text-sm text-slate-600 dark:text-slate-400">
72
- Modules disponibles : <strong>auth</strong> (authentification),{" "}
73
- <strong>ai</strong> (génération IA)
74
- </p>
75
- </div>
76
-
77
- <div>
78
- <h3 className="text-lg font-semibold mb-2">
79
- Construire les modules
80
- </h3>
81
60
  <Snippet symbol="" hideSymbol className="text-sm mb-2">
82
- pnpm build:modules
61
+ {`# 3. Initialiser Supabase`}
83
62
  </Snippet>
84
- <p className="text-sm text-slate-600 dark:text-slate-400">
85
- Génère les pages et routes à partir des modules installés
86
- </p>
87
- </div>
88
-
89
- <div>
90
- <h3 className="text-lg font-semibold mb-2">
91
- Lancer le serveur de développement
92
- </h3>
93
63
  <Snippet symbol="" hideSymbol className="text-sm mb-2">
94
- pnpm dev
64
+ {`pnpm db:init`}
95
65
  </Snippet>
96
- <p className="text-sm text-slate-600 dark:text-slate-400">
97
- Ouvre l'application sur{" "}
98
- <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
99
- http://localhost:3000
100
- </code>
101
- </p>
102
- </div>
66
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
67
+ {`# 4. Démarrer l'application`}
68
+ </Snippet>
69
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
70
+ {`pnpm dev`}
71
+ </Snippet>
72
+ <h3 className="text-lg font-semibold mb-2">Explication de la commande</h3>
73
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
74
+ {`pnpx @lastbrain/app@latest init mon-app`}
75
+ </Snippet>
76
+ <div className="space-y-2">
77
+ <div className="flex items-start gap-2">
78
+ <span className="text-green-600">✅</span>
79
+ <span><strong><code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">pnpx</code></strong> : Exécute un package npm sans l'installer globalement</span>
80
+ </div>
81
+ <div className="flex items-start gap-2">
82
+ <span className="text-green-600">✅</span>
83
+ <span><strong><code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">@lastbrain/app@latest</code></strong> : Package CLI de LastBrain en version la plus récente</span>
84
+ </div>
85
+ <div className="flex items-start gap-2">
86
+ <span className="text-green-600">✅</span>
87
+ <span><strong><code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">init</code></strong> : Commande pour initialiser une nouvelle application</span>
88
+ </div>
89
+ <div className="flex items-start gap-2">
90
+ <span className="text-green-600">✅</span>
91
+ <span><strong><code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">mon-app</code></strong> : Nom du dossier de votre application</span>
92
+ </div>
93
+ </div>
94
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Cette commande va :</p>
95
+ <div className="space-y-2">
96
+ <div className="flex items-start gap-2">
97
+ <span className="text-green-600">✅</span>
98
+ <span>Créer la structure Next.js complète</span>
99
+ </div>
100
+ <div className="flex items-start gap-2">
101
+ <span className="text-green-600">✅</span>
102
+ <span>Installer automatiquement tous les packages nécessaires (<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">@lastbrain/core</code>, <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">@lastbrain/ui</code>, modules...)</span>
103
+ </div>
104
+ <div className="flex items-start gap-2">
105
+ <span className="text-green-600">✅</span>
106
+ <span>Configurer Supabase et les migrations</span>
107
+ </div>
108
+ <div className="flex items-start gap-2">
109
+ <span className="text-green-600">✅</span>
110
+ <span>Générer les routes des modules sélectionnés</span>
111
+ </div>
112
+ </div>
113
+ <h3 className="text-lg font-semibold mb-2">Création du Compte Admin</h3>
114
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
115
+ {`# Promouvoir votre compte en admin via Supabase`}
116
+ </Snippet>
117
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
118
+ {`update auth.users`}
119
+ </Snippet>
120
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
121
+ {`set raw_app_meta_data = jsonb_set(`}
122
+ </Snippet>
123
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
124
+ {` coalesce(raw_app_meta_data, '{}'::jsonb),`}
125
+ </Snippet>
126
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
127
+ {` '{roles}',`}
128
+ </Snippet>
129
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
130
+ {` '["admin"]'::jsonb`}
131
+ </Snippet>
132
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
133
+ {`)`}
134
+ </Snippet>
135
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
136
+ {`where email = 'votre@email.com';`}
137
+ </Snippet>
138
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Votre application est maintenant disponible sur <a href="http://localhost:3000" className="text-blue-600 hover:underline" target="_blank" rel="noopener noreferrer">http://localhost:3000</a> ! 🎉</p>
103
139
  </CardBody>
104
140
  </Card>
105
141
 
142
+
106
143
  <Card id="section-architecture" className="scroll-mt-32">
107
144
  <CardHeader>
108
145
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -111,62 +148,19 @@ export function DefaultDocumentation() {
111
148
  </h2>
112
149
  </CardHeader>
113
150
  <CardBody className="space-y-4">
114
- <p className="text-slate-600 dark:text-slate-400">
115
- Le projet est organisé en monorepo avec pnpm workspaces :
116
- </p>
117
-
118
- <div className="space-y-3">
119
- <div className="border-l-4 border-blue-500 pl-4">
120
- <h3 className="font-semibold text-lg mb-1">
121
- <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
122
- @lastbrain/app
123
- </code>
124
- </h3>
125
- <p className="text-sm text-slate-600 dark:text-slate-400">
126
- Framework principal et CLI. Contient les layouts, scripts de
127
- build, templates et la logique de génération des pages.
128
- </p>
129
- </div>
130
-
131
- <div className="border-l-4 border-green-500 pl-4">
132
- <h3 className="font-semibold text-lg mb-1">
133
- <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
134
- @lastbrain/core
135
- </code>
136
- </h3>
137
- <p className="text-sm text-slate-600 dark:text-slate-400">
138
- Utilitaires et types partagés. Contient les helpers Supabase,
139
- fonctions serveur et types TypeScript communs.
140
- </p>
141
- </div>
142
-
143
- <div className="border-l-4 border-purple-500 pl-4">
144
- <h3 className="font-semibold text-lg mb-1">
145
- <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
146
- @lastbrain/ui
147
- </code>
148
- </h3>
149
- <p className="text-sm text-slate-600 dark:text-slate-400">
150
- Composants UI réutilisables basés sur NextUI et Tailwind CSS.
151
- Fournit les composants Card, Button, Input, etc.
152
- </p>
153
- </div>
154
-
155
- <div className="border-l-4 border-orange-500 pl-4">
156
- <h3 className="font-semibold text-lg mb-1">
157
- <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
158
- @lastbrain/module-*
159
- </code>
160
- </h3>
161
- <p className="text-sm text-slate-600 dark:text-slate-400">
162
- Modules fonctionnels (auth, ai, etc.). Chaque module contient
163
- ses pages, APIs, composants, migrations et documentation.
164
- </p>
165
- </div>
166
- </div>
151
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Le projet est organisé en monorepo avec pnpm workspaces :</p>
152
+ <h3 className="text-lg font-semibold mb-2">@lastbrain/app</h3>
153
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Framework principal et CLI. Contient les layouts, scripts de build, templates et la logique de génération des pages.</p>
154
+ <h3 className="text-lg font-semibold mb-2">@lastbrain/core</h3>
155
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Utilitaires et types partagés. Contient les helpers Supabase, fonctions serveur et types TypeScript communs.</p>
156
+ <h3 className="text-lg font-semibold mb-2">@lastbrain/ui</h3>
157
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Composants UI réutilisables basés sur NextUI et Tailwind CSS. Fournit les composants Card, Button, Input, etc.</p>
158
+ <h3 className="text-lg font-semibold mb-2">@lastbrain/module-\*</h3>
159
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Modules fonctionnels (auth, ai, etc.). Chaque module contient ses pages, APIs, composants, migrations et documentation.</p>
167
160
  </CardBody>
168
161
  </Card>
169
162
 
163
+
170
164
  <Card id="section-create-module" className="scroll-mt-32">
171
165
  <CardHeader>
172
166
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -175,74 +169,48 @@ export function DefaultDocumentation() {
175
169
  </h2>
176
170
  </CardHeader>
177
171
  <CardBody className="space-y-4">
178
- <div>
179
172
  <h3 className="text-lg font-semibold mb-2">Commande CLI</h3>
180
173
  <Snippet symbol="" hideSymbol className="text-sm mb-2">
181
- pnpm lastbrain create-module mon-module
174
+ {`pnpm lastbrain create-module mon-module`}
182
175
  </Snippet>
183
- <p className="text-sm text-slate-600 dark:text-slate-400 mb-4">
184
- Crée un nouveau module dans{" "}
185
- <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
186
- packages/module-mon-module
187
- </code>
188
- </p>
189
- </div>
190
-
191
- <div>
192
- <h3 className="text-lg font-semibold mb-2">
193
- Structure d'un module
194
- </h3>
195
- <div className="bg-slate-50 dark:bg-slate-900 p-4 rounded-lg text-sm font-mono">
196
- <div className="space-y-1">
197
- <div>📁 module-mon-module/</div>
198
- <div className="ml-4">├── 📄 package.json</div>
199
- <div className="ml-4">├── 📄 mon-module.build.config.ts</div>
200
- <div className="ml-4">└── 📁 src/</div>
201
- <div className="ml-8">├── 📄 index.ts</div>
202
- <div className="ml-8">├── 📄 server.ts</div>
203
- <div className="ml-8">├── 📁 web/</div>
204
- <div className="ml-8">├── 📁 api/</div>
205
- <div className="ml-8">├── 📁 components/</div>
206
- <div className="ml-8">└── 📁 supabase/</div>
207
- <div className="ml-12">└── 📁 migrations/</div>
208
- </div>
209
- </div>
210
- </div>
211
-
212
- <div>
213
- <h3 className="text-lg font-semibold mb-2">
214
- Configuration du module
215
- </h3>
216
- <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
217
- Le fichier{" "}
218
- <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
219
- {"{slug}"}.build.config.ts
220
- </code>{" "}
221
- définit les pages et APIs :
222
- </p>
223
- <div className="bg-slate-50 dark:bg-slate-900 p-4 rounded-lg text-sm font-mono overflow-x-auto">
224
- <pre>{`export default {
176
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Crée un nouveau module dans <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">packages/module-mon-module</code></p>
177
+ <h3 className="text-lg font-semibold mb-2">Structure d'un module</h3>
178
+ <Alert hideIcon color="primary" className="p-4 mb-4 whitespace-pre-wrap">{`📁 module-mon-module/
179
+ ├── 📄 package.json
180
+ ├── 📄 mon-module.build.config.ts
181
+ └── 📁 src/
182
+ ├── 📄 index.ts
183
+ ├── 📄 server.ts
184
+ ├── 📁 web/
185
+ ├── 📁 api/
186
+ ├── 📁 components/
187
+ └── 📁 supabase/
188
+ └── 📁 migrations/`}</Alert>
189
+ <h3 className="text-lg font-semibold mb-2">Configuration du module</h3>
190
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Le fichier <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">module-name.build.config.ts</code> définit les pages et APIs :</p>
191
+ <Alert hideIcon color="primary" className="p-4 mb-4">
192
+ <pre className="whitespace-pre-wrap">{`export default {
225
193
  name: "Mon Module",
226
194
  description: "Description du module",
227
195
  pages: [
228
196
  {
229
197
  path: "/ma-page",
230
198
  component: "./web/MaPage",
231
- layout: "auth"
232
- }
199
+ layout: "auth",
200
+ },
233
201
  ],
234
202
  apis: [
235
203
  {
236
204
  path: "/api/mon-api",
237
- handler: "./api/mon-api"
238
- }
239
- ]
240
- }`}</pre>
241
- </div>
242
- </div>
205
+ handler: "./api/mon-api",
206
+ },
207
+ ],
208
+ };`}</pre>
209
+ </Alert>
243
210
  </CardBody>
244
211
  </Card>
245
212
 
213
+
246
214
  <Card id="section-database" className="scroll-mt-32">
247
215
  <CardHeader>
248
216
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -251,108 +219,60 @@ export function DefaultDocumentation() {
251
219
  </h2>
252
220
  </CardHeader>
253
221
  <CardBody className="space-y-4">
254
- <div>
255
222
  <h3 className="text-lg font-semibold mb-2">Supabase local</h3>
256
- <p className="text-sm text-slate-600 dark:text-slate-400 mb-3">
257
- LastBrain utilise Supabase pour la base de données et
258
- l'authentification.
259
- </p>
260
-
261
- <div className="space-y-3">
262
- <div>
263
- <p className="text-sm font-medium mb-1">Démarrer Supabase :</p>
264
- <Snippet symbol="" hideSymbol className="text-sm">
265
- pnpm db:init
266
- </Snippet>
267
- </div>
268
-
269
- <div>
270
- <p className="text-sm font-medium mb-1">
271
- Synchroniser les migrations :
272
- </p>
273
- <Snippet symbol="" hideSymbol className="text-sm">
274
- pnpm db:migrations:sync
275
- </Snippet>
276
- </div>
277
-
278
- <div>
279
- <p className="text-sm font-medium mb-1">
280
- Créer une migration :
281
- </p>
282
- <Snippet symbol="" hideSymbol className="text-sm">
283
- supabase migration new ma_migration
284
- </Snippet>
285
- </div>
286
- </div>
287
- </div>
288
-
289
- <div>
290
- <h3 className="text-lg font-semibold mb-2">
291
- Migrations des modules
292
- </h3>
293
- <p className="text-sm text-slate-600 dark:text-slate-400">
294
- Les modules peuvent avoir leurs propres migrations dans{" "}
295
- <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
296
- supabase/migrations/
297
- </code>
298
- . Elles sont automatiquement synchronisées lors du build.
299
- </p>
300
- </div>
223
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">LastBrain utilise Supabase pour la base de données et l'authentification.</p>
224
+ <h4 className="font-medium mb-2">Démarrer Supabase</h4>
225
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
226
+ {`pnpm db:init`}
227
+ </Snippet>
228
+ <h4 className="font-medium mb-2">Synchroniser les migrations</h4>
229
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
230
+ {`pnpm db:migrations:sync`}
231
+ </Snippet>
232
+ <h4 className="font-medium mb-2">Créer une migration</h4>
233
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
234
+ {`supabase migration new ma_migration`}
235
+ </Snippet>
236
+ <h3 className="text-lg font-semibold mb-2">Migrations des modules</h3>
237
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Les modules peuvent avoir leurs propres migrations dans <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">supabase/migrations/</code>. Elles sont automatiquement synchronisées lors du build.</p>
301
238
  </CardBody>
302
239
  </Card>
303
240
 
241
+
304
242
  <Card id="section-admin" className="scroll-mt-32">
305
243
  <CardHeader>
306
- <h2 className="text-2xl font-semibold">
307
- 👤 Créer un Compte Administrateur
244
+ <h2 className="text-2xl font-semibold flex items-center gap-2">
245
+ <User size={24} />
246
+ Créer un Compte Administrateur
308
247
  </h2>
309
248
  </CardHeader>
310
249
  <CardBody className="space-y-4">
311
- <ol className="list-decimal list-inside space-y-4">
312
- <li className="text-lg">
313
- <strong>Créer un compte</strong>
314
- <p className="text-slate-600 dark:text-slate-400 ml-6 mb-2">
315
- Allez sur{" "}
316
- <code className="px-2 py-1 bg-slate-100 dark:bg-slate-800 rounded">
317
- /signup
318
- </code>{" "}
319
- et créez votre compte
320
- </p>
321
- </li>
322
- <li className="text-lg">
323
- <strong>Promouvoir en administrateur</strong>
324
- <p className="text-slate-600 dark:text-slate-400 ml-6 mb-2">
325
- Exécutez cette requête SQL dans le Studio Supabase (
326
- <code className="px-2 py-1 bg-slate-100 dark:bg-slate-800 rounded">
327
- http://localhost:54323
328
- </code>
329
- ) ou via psql :
330
- </p>
331
- <div className="ml-6">
332
- <Snippet symbol="" hideSymbol className="text-sm">
333
- <span>{`update auth.users`}</span>
334
- <span>{`set raw_app_meta_data = jsonb_set(`}</span>
335
- <span>{`coalesce(raw_app_meta_data, '{}'::jsonb),`}</span>
336
- <span>{`'{roles}',`}</span>
337
- <span>{`'["admin"]'::jsonb`}</span>
338
- <span>{`)`}</span>
339
- <span>{`where email = 'votre@email.com';`}</span>
340
- </Snippet>
341
- </div>
342
- </li>
343
- <li className="text-lg">
344
- <strong>Accéder à l'interface admin</strong>
345
- <p className="text-slate-600 dark:text-slate-400 ml-6">
346
- Vous pouvez maintenant accéder à{" "}
347
- <code className="px-2 py-1 bg-slate-100 dark:bg-slate-800 rounded">
348
- /admin
349
- </code>
350
- </p>
351
- </li>
352
- </ol>
250
+ <h3 className="text-lg font-semibold mb-2">1. Créer un compte</h3>
251
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Allez sur <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">/signup</code> et créez votre compte</p>
252
+ <h3 className="text-lg font-semibold mb-2">2. Promouvoir en administrateur</h3>
253
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Exécutez cette requête SQL dans le Studio Supabase (<code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">http://localhost:54323</code>) ou via psql :</p>
254
+ <Snippet hideSymbol color="primary" className="text-sm mb-2">
255
+ <span>{`update auth.users
256
+ `}</span>
257
+ <span>{`set raw_app_meta_data = jsonb_set(
258
+ `}</span>
259
+ <span>{` coalesce(raw_app_meta_data, '{}'::jsonb),
260
+ `}</span>
261
+ <span>{` '{roles}',
262
+ `}</span>
263
+ <span>{` '["admin"]'::jsonb
264
+ `}</span>
265
+ <span>{`)
266
+ `}</span>
267
+ <span>{`where email = 'votre@email.com';
268
+ `}</span>
269
+ </Snippet>
270
+ <h3 className="text-lg font-semibold mb-2">3. Accéder à l'interface admin</h3>
271
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Vous pouvez maintenant accéder à <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">/admin</code></p>
353
272
  </CardBody>
354
273
  </Card>
355
274
 
275
+
356
276
  <Card id="section-development" className="scroll-mt-32">
357
277
  <CardHeader>
358
278
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -361,43 +281,30 @@ export function DefaultDocumentation() {
361
281
  </h2>
362
282
  </CardHeader>
363
283
  <CardBody className="space-y-4">
364
- <div>
365
- <h3 className="text-lg font-semibold mb-2">
366
- Lancer le serveur de développement
367
- </h3>
368
- <Snippet symbol="" hideSymbol className="text-sm">
369
- pnpm dev
284
+ <h3 className="text-lg font-semibold mb-2">Lancer le serveur de développement</h3>
285
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
286
+ {`pnpm dev`}
370
287
  </Snippet>
371
- </div>
372
- <div>
373
- <h3 className="text-lg font-semibold mb-2">
374
- Générer les routes des modules
375
- </h3>
376
- <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
377
- À exécuter après avoir ajouté ou modifié des modules
378
- </p>
379
- <Snippet symbol="" hideSymbol className="text-sm">
380
- pnpm build:modules
288
+ <h3 className="text-lg font-semibold mb-2">Générer les routes des modules</h3>
289
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">À exécuter après avoir ajouté ou modifié des modules</p>
290
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
291
+ {`pnpm build:modules`}
381
292
  </Snippet>
382
- </div>
383
- <div>
384
293
  <h3 className="text-lg font-semibold mb-2">Build de production</h3>
385
- <Snippet symbol="" hideSymbol className="text-sm">
386
- pnpm build
294
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
295
+ {`pnpm build`}
387
296
  </Snippet>
388
- </div>
389
- <div>
390
297
  <h3 className="text-lg font-semibold mb-2">Développer un module</h3>
391
298
  <Snippet symbol="" hideSymbol className="text-sm mb-2">
392
- cd packages/module-auth
299
+ {`cd packages/module-auth`}
393
300
  </Snippet>
394
- <Snippet symbol="" hideSymbol className="text-sm">
395
- pnpm dev
301
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
302
+ {`pnpm dev`}
396
303
  </Snippet>
397
- </div>
398
304
  </CardBody>
399
305
  </Card>
400
306
 
307
+
401
308
  <Card id="section-routes" className="scroll-mt-32">
402
309
  <CardHeader>
403
310
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -406,36 +313,27 @@ export function DefaultDocumentation() {
406
313
  </h2>
407
314
  </CardHeader>
408
315
  <CardBody className="space-y-4">
409
- <p className="text-slate-600 dark:text-slate-400 mb-4">
410
- Le middleware protège automatiquement vos routes selon ces règles :
411
- </p>
412
- <div className="space-y-2">
413
- <div className="p-3 bg-slate-50 dark:bg-slate-900 rounded">
414
- <code className="text-blue-600 dark:text-blue-400">/auth/*</code>
415
- <span className="ml-2">→ Authentification requise</span>
416
- </div>
417
- <div className="p-3 bg-slate-50 dark:bg-slate-900 rounded">
418
- <code className="text-purple-600 dark:text-purple-400">
419
- /admin/*
420
- </code>
421
- <span className="ml-2">→ Superadmin uniquement</span>
422
- </div>
423
- <div className="p-3 bg-slate-50 dark:bg-slate-900 rounded">
424
- <code className="text-green-600 dark:text-green-400">
425
- /docs/*
426
- </code>
427
- <span className="ml-2">→ Accès public</span>
316
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Le middleware protège automatiquement vos routes selon ces règles :</p>
317
+ <h3 className="text-lg font-semibold mb-2">Routes</h3>
318
+ <div className="space-y-2">
319
+ <div className="flex items-start gap-2">
320
+ <span className="text-green-600">✅</span>
321
+ <span><code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">/auth/*</code> → Authentification requise</span>
322
+ </div>
323
+ <div className="flex items-start gap-2">
324
+ <span className="text-green-600">✅</span>
325
+ <span><code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">/admin/*</code> → Superadmin uniquement</span>
326
+ </div>
327
+ <div className="flex items-start gap-2">
328
+ <span className="text-green-600">✅</span>
329
+ <span><code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">/docs/*</code> → Accès public</span>
330
+ </div>
428
331
  </div>
429
- </div>
430
- <p className="text-sm text-slate-600 dark:text-slate-400 mt-4">
431
- Le middleware se trouve dans{" "}
432
- <code className="px-2 py-1 bg-slate-100 dark:bg-slate-800 rounded">
433
- middleware.ts
434
- </code>
435
- </p>
332
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Le middleware se trouve dans <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">middleware.ts</code></p>
436
333
  </CardBody>
437
334
  </Card>
438
335
 
336
+
439
337
  <Card id="section-workflow" className="scroll-mt-32">
440
338
  <CardHeader>
441
339
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -444,56 +342,34 @@ export function DefaultDocumentation() {
444
342
  </h2>
445
343
  </CardHeader>
446
344
  <CardBody className="space-y-4">
447
- <div>
448
- <h3 className="text-lg font-semibold mb-2">
449
- 1. Modifier un module
450
- </h3>
451
- <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
452
- Éditez les fichiers dans{" "}
453
- <code className="px-2 py-1 bg-slate-100 dark:bg-slate-800 rounded">
454
- packages/module-*/src
455
- </code>
456
- </p>
457
- </div>
458
- <div>
459
- <h3 className="text-lg font-semibold mb-2">
460
- 2. Compiler le module
461
- </h3>
345
+ <h3 className="text-lg font-semibold mb-2">1. Modifier un module</h3>
346
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Éditez les fichiers dans <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">packages/module-*/src</code></p>
347
+ <h3 className="text-lg font-semibold mb-2">2. Compiler le module</h3>
462
348
  <Snippet symbol="" hideSymbol className="text-sm mb-2">
463
- cd packages/module-auth
349
+ {`cd packages/module-auth`}
464
350
  </Snippet>
465
- <Snippet symbol="" hideSymbol className="text-sm">
466
- pnpm build
351
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
352
+ {`pnpm build`}
467
353
  </Snippet>
468
- </div>
469
- <div>
470
- <h3 className="text-lg font-semibold mb-2">
471
- 3. Régénérer les pages
472
- </h3>
354
+ <h3 className="text-lg font-semibold mb-2">3. Régénérer les pages</h3>
473
355
  <Snippet symbol="" hideSymbol className="text-sm mb-2">
474
- cd apps/my-app
356
+ {`cd apps/my-app`}
475
357
  </Snippet>
476
- <Snippet symbol="" hideSymbol className="text-sm">
477
- pnpm build:modules
358
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
359
+ {`pnpm build:modules`}
478
360
  </Snippet>
479
- </div>
480
- <div>
481
- <h3 className="text-lg font-semibold mb-2">
482
- 4. Appliquer les migrations
483
- </h3>
484
- <Snippet symbol="" hideSymbol className="text-sm">
485
- supabase migration up
361
+ <h3 className="text-lg font-semibold mb-2">4. Appliquer les migrations</h3>
362
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
363
+ {`supabase migration up`}
486
364
  </Snippet>
487
- </div>
488
- <div>
489
365
  <h3 className="text-lg font-semibold mb-2">5. Tester</h3>
490
- <Snippet symbol="" hideSymbol className="text-sm">
491
- pnpm dev
366
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
367
+ {`pnpm dev`}
492
368
  </Snippet>
493
- </div>
494
369
  </CardBody>
495
370
  </Card>
496
371
 
372
+
497
373
  <Card id="section-ui" className="scroll-mt-32">
498
374
  <CardHeader>
499
375
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -502,127 +378,55 @@ export function DefaultDocumentation() {
502
378
  </h2>
503
379
  </CardHeader>
504
380
  <CardBody className="space-y-4">
505
- <div>
506
381
  <h3 className="text-lg font-semibold mb-2">Composants NextUI</h3>
507
- <p className="text-sm text-slate-600 dark:text-slate-400 mb-3">
508
- Le package{" "}
509
- <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
510
- @lastbrain/ui
511
- </code>
512
- réexporte les composants NextUI avec une configuration Tailwind
513
- personnalisée.
514
- </p>
515
- </div>
516
-
517
- <div>
382
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Le package <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">@lastbrain/ui</code> réexporte les composants NextUI avec une configuration Tailwind personnalisée.</p>
518
383
  <h3 className="text-lg font-semibold mb-2">Thèmes</h3>
519
- <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
520
- Le mode sombre/clair est géré par{" "}
521
- <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
522
- next-themes
523
- </code>
524
- . Le switch est disponible dans le header de l'application.
525
- </p>
526
- </div>
527
-
528
- <div>
384
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Le mode sombre/clair est géré par <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">next-themes</code>. Le switch est disponible dans le header de l'application.</p>
529
385
  <h3 className="text-lg font-semibold mb-2">Tailwind CSS v4</h3>
530
- <p className="text-sm text-slate-600 dark:text-slate-400">
531
- Le projet utilise Tailwind CSS v4 avec un preset personnalisé
532
- partagé via{" "}
533
- <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
534
- @lastbrain/ui/tailwind.preset
535
- </code>
536
- .
537
- </p>
538
- </div>
386
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Le projet utilise Tailwind CSS v4 avec un preset personnalisé partagé via <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">@lastbrain/ui/tailwind.preset</code>.</p>
539
387
  </CardBody>
540
388
  </Card>
541
389
 
390
+
542
391
  <Card id="section-storage" className="scroll-mt-32">
543
392
  <CardHeader>
544
393
  <h2 className="text-2xl font-semibold flex items-center gap-2">
545
- <Database size={24} />
394
+ <HardDrive size={24} />
546
395
  Système de Proxy Storage
547
396
  </h2>
548
397
  </CardHeader>
549
398
  <CardBody className="space-y-4">
550
- <p className="text-slate-600 dark:text-slate-400">
551
- LastBrain intègre un système de proxy pour les fichiers Supabase
552
- Storage qui permet d'utiliser des URLs propres avec contrôle d'accès
553
- granulaire.
554
- </p>
555
-
556
- <div>
557
- <h3 className="text-lg font-semibold mb-2">
558
- URLs Proxy vs URLs Supabase
559
- </h3>
560
- <div className="space-y-3">
561
- <div className="bg-red-50 dark:bg-red-950 p-3 rounded-lg">
562
- <p className="text-sm font-medium text-red-700 dark:text-red-300 mb-1">
563
- URL Supabase classique (longue)
564
- </p>
565
- <code className="text-xs text-red-600 dark:text-red-400 break-all">
566
- https://xxx.supabase.co/storage/v1/object/public/avatar/user_128_123456.webp
567
- </code>
568
- </div>
569
- <div className="bg-green-50 dark:bg-green-950 p-3 rounded-lg">
570
- <p className="text-sm font-medium text-green-700 dark:text-green-300 mb-1">
571
- URL Proxy (propre)
572
- </p>
573
- <code className="text-xs text-green-600 dark:text-green-400">
574
- /api/storage/avatar/user_128_123456.webp
575
- </code>
576
- </div>
577
- </div>
578
- </div>
579
-
580
- <div>
581
- <h3 className="text-lg font-semibold mb-2">
582
- Configuration des Buckets
583
- </h3>
584
- <div className="space-y-3">
585
- <div className="border-l-4 border-green-500 pl-4">
586
- <h4 className="font-semibold text-green-600 dark:text-green-400">
587
- 📂 avatar (Public)
588
- </h4>
589
- <p className="text-sm text-slate-600 dark:text-slate-400">
590
- Photos de profil et avatars • 10MB max • Types: JPEG, PNG,
591
- WebP, GIF
592
- </p>
593
- <code className="text-xs bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
594
- /api/storage/avatar/user_128_123456.webp
595
- </code>
596
- </div>
597
-
598
- <div className="border-l-4 border-blue-500 pl-4">
599
- <h4 className="font-semibold text-blue-600 dark:text-blue-400">
600
- 🔒 app (Privé)
601
- </h4>
602
- <p className="text-sm text-slate-600 dark:text-slate-400">
603
- Fichiers privés des utilisateurs • 100MB max •
604
- Authentification requise
605
- </p>
606
- <code className="text-xs bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
607
- /api/storage/app/user-id/documents/file.pdf
608
- </code>
609
- </div>
610
- </div>
611
- </div>
612
-
613
- <div>
614
- <h3 className="text-lg font-semibold mb-2">
615
- Utilisation dans le code
616
- </h3>
617
- <div className="bg-slate-50 dark:bg-slate-900 p-4 rounded-lg text-sm font-mono overflow-x-auto">
618
- <pre>{`// Upload d'un fichier
399
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">LastBrain intègre un système de proxy pour les fichiers Supabase Storage qui permet d'utiliser des URLs propres avec contrôle d'accès granulaire.</p>
400
+ <h3 className="text-lg font-semibold mb-2">URLs Proxy vs URLs Supabase</h3>
401
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2"><strong>❌ URL Supabase classique (longue)</strong></p>
402
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
403
+ {`https://xxx.supabase.co/storage/v1/object/public/avatar/user_128_123456.webp`}
404
+ </Snippet>
405
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2"><strong>✅ URL Proxy (propre)</strong></p>
406
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
407
+ {`/api/storage/avatar/user_128_123456.webp`}
408
+ </Snippet>
409
+ <h3 className="text-lg font-semibold mb-2">Configuration des Buckets</h3>
410
+ <h4 className="font-medium mb-2">📂 avatar (Public)</h4>
411
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Photos de profil et avatars • 10MB max • Types: JPEG, PNG, WebP, GIF</p>
412
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
413
+ {`/api/storage/avatar/user_128_123456.webp`}
414
+ </Snippet>
415
+ <h4 className="font-medium mb-2">🔒 app (Privé)</h4>
416
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Fichiers privés des utilisateurs • 100MB max • Authentification requise</p>
417
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
418
+ {`/api/storage/app/user-id/documents/file.pdf`}
419
+ </Snippet>
420
+ <h3 className="text-lg font-semibold mb-2">Utilisation dans le code</h3>
421
+ <Alert hideIcon color="primary" className="p-4 mb-4">
422
+ <pre className="whitespace-pre-wrap">{`// Upload d'un fichier
619
423
  import { uploadFile } from "@/api/storage";
620
424
 
621
425
  const proxyUrl = await uploadFile(
622
- "avatar",
623
- "user_128_123456.webp",
624
- file,
625
- "image/webp"
426
+ "avatar",
427
+ "user_128_123456.webp",
428
+ file,
429
+ "image/webp",
626
430
  );
627
431
  // Retourne: "/api/storage/avatar/user_128_123456.webp"
628
432
 
@@ -631,41 +435,32 @@ import { storagePathToProxyUrl } from "@/lib/storage";
631
435
 
632
436
  const proxyUrl = storagePathToProxyUrl("avatar/user_128_123456.webp");
633
437
  // Retourne: "/api/storage/avatar/user_128_123456.webp"`}</pre>
634
- </div>
635
- </div>
636
-
637
- <div>
438
+ </Alert>
638
439
  <h3 className="text-lg font-semibold mb-2">Avantages du système</h3>
639
- <div className="grid grid-cols-1 md:grid-cols-2 gap-3 text-sm">
440
+ <div className="space-y-2">
640
441
  <div className="flex items-start gap-2">
641
- <span className="text-green-600">✅</span>
642
- <span>URLs plus courtes et lisibles</span>
442
+ <span>✅ URLs plus courtes et lisibles</span>
643
443
  </div>
644
444
  <div className="flex items-start gap-2">
645
- <span className="text-green-600">✅</span>
646
- <span>Contrôle d'accès granulaire</span>
445
+ <span>✅ Contrôle d'accès granulaire</span>
647
446
  </div>
648
447
  <div className="flex items-start gap-2">
649
- <span className="text-green-600">✅</span>
650
- <span>Cache optimisé (1 an)</span>
448
+ <span>✅ Cache optimisé (1 an)</span>
651
449
  </div>
652
450
  <div className="flex items-start gap-2">
653
- <span className="text-green-600">✅</span>
654
- <span>Sécurité améliorée</span>
451
+ <span>✅ Sécurité améliorée</span>
655
452
  </div>
656
453
  <div className="flex items-start gap-2">
657
- <span className="text-green-600">✅</span>
658
- <span>Détection auto des types MIME</span>
454
+ <span>✅ Détection auto des types MIME</span>
659
455
  </div>
660
456
  <div className="flex items-start gap-2">
661
- <span className="text-green-600">✅</span>
662
- <span>Extensible facilement</span>
457
+ <span>✅ Extensible facilement</span>
663
458
  </div>
664
459
  </div>
665
- </div>
666
460
  </CardBody>
667
461
  </Card>
668
462
 
463
+
669
464
  <Card id="section-realtime" className="scroll-mt-32">
670
465
  <CardHeader>
671
466
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -674,28 +469,14 @@ const proxyUrl = storagePathToProxyUrl("avatar/user_128_123456.webp");
674
469
  </h2>
675
470
  </CardHeader>
676
471
  <CardBody className="space-y-4">
677
- <p className="text-slate-600 dark:text-slate-400">
678
- LastBrain intègre un système de notifications et de synchronisation
679
- en temps réel basé sur Supabase Realtime. Le système est entièrement
680
- automatisé et scalable.
681
- </p>
682
-
683
- <div>
684
- <h3 className="text-lg font-semibold mb-2">
685
- Configuration dans les modules
686
- </h3>
687
- <p className="text-sm text-slate-600 dark:text-slate-400 mb-3">
688
- Ajoutez la configuration realtime dans votre{" "}
689
- <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
690
- build.config.ts
691
- </code>{" "}
692
- pour activer la synchronisation en temps réel :
693
- </p>
694
- <div className="bg-slate-50 dark:bg-slate-900 p-4 rounded-lg text-sm font-mono overflow-x-auto">
695
- <pre>{`export default {
472
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">LastBrain intègre un système de notifications et de synchronisation en temps réel basé sur Supabase Realtime. Le système est entièrement automatisé et scalable.</p>
473
+ <h3 className="text-lg font-semibold mb-2">Configuration dans les modules</h3>
474
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Ajoutez la configuration realtime dans votre <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">build.config.ts</code> pour activer la synchronisation en temps réel :</p>
475
+ <Alert hideIcon color="primary" className="p-4 mb-4">
476
+ <pre className="whitespace-pre-wrap">{`export default {
696
477
  name: "Module Auth",
697
478
  description: "Gestion de l'authentification",
698
-
479
+
699
480
  // Configuration realtime
700
481
  realtime: {
701
482
  moduleId: "module-auth",
@@ -705,63 +486,38 @@ const proxyUrl = storagePathToProxyUrl("avatar/user_128_123456.webp");
705
486
  table: "user_notifications",
706
487
  event: "*", // INSERT, UPDATE, DELETE ou *
707
488
  filter: "owner_id=eq.\${USER_ID}",
708
- broadcast: "user_notifications_updated"
489
+ broadcast: "user_notifications_updated",
709
490
  },
710
491
  {
711
- schema: "public",
492
+ schema: "public",
712
493
  table: "user_profiles",
713
494
  event: "*",
714
495
  filter: "owner_id=eq.\${USER_ID}",
715
- broadcast: "user_profile_updated"
716
- }
717
- ]
496
+ broadcast: "user_profile_updated",
497
+ },
498
+ ],
718
499
  },
719
-
500
+
720
501
  pages: [
721
502
  // vos pages...
722
- ]
723
- }`}</pre>
724
- </div>
725
- </div>
726
-
727
- <div>
728
- <h3 className="text-lg font-semibold mb-2">
729
- Génération automatique de la configuration
730
- </h3>
731
- <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
732
- Lors du build des modules, la configuration realtime est
733
- automatiquement générée :
734
- </p>
735
- <Snippet symbol="" hideSymbol className="text-sm mb-3">
736
- pnpm build:modules
503
+ ],
504
+ };`}</pre>
505
+ </Alert>
506
+ <h3 className="text-lg font-semibold mb-2">Génération automatique de la configuration</h3>
507
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Lors du build des modules, la configuration realtime est automatiquement générée :</p>
508
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
509
+ {`pnpm build:modules`}
737
510
  </Snippet>
738
- <p className="text-sm text-slate-600 dark:text-slate-400">
739
- Cela génère automatiquement{" "}
740
- <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
741
- config/realtime.ts
742
- </code>{" "}
743
- avec toutes les configurations des modules.
744
- </p>
745
- </div>
746
-
747
- <div>
748
- <h3 className="text-lg font-semibold mb-2">
749
- Utilisation dans les composants
750
- </h3>
751
- <p className="text-sm text-slate-600 dark:text-slate-400 mb-3">
752
- Utilisez les hooks pré-construits pour écouter les changements :
753
- </p>
754
- <div className="space-y-4">
755
- <div>
756
- <h4 className="font-medium mb-2">
757
- 1. Hook générique pour une table
758
- </h4>
759
- <div className="bg-slate-50 dark:bg-slate-900 p-4 rounded-lg text-sm font-mono overflow-x-auto">
760
- <pre>{`import { useTableRealtime } from "@lastbrain/core";
511
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Cela génère automatiquement <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">config/realtime.ts</code> avec toutes les configurations des modules.</p>
512
+ <h3 className="text-lg font-semibold mb-2">Utilisation dans les composants</h3>
513
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Utilisez les hooks pré-construits pour écouter les changements :</p>
514
+ <h4 className="font-medium mb-2">1. Hook générique pour une table</h4>
515
+ <Alert hideIcon color="primary" className="p-4 mb-4">
516
+ <pre className="whitespace-pre-wrap">{`import { useTableRealtime } from "@lastbrain/core";
761
517
 
762
518
  function MonComposant() {
763
519
  const signal = useTableRealtime("user_notifications");
764
-
520
+
765
521
  useEffect(() => {
766
522
  if (signal.hasUpdates) {
767
523
  console.log("Nouvelle notification!");
@@ -770,19 +526,14 @@ function MonComposant() {
770
526
  }
771
527
  }, [signal.tick]);
772
528
  }`}</pre>
773
- </div>
774
- </div>
775
-
776
- <div>
777
- <h4 className="font-medium mb-2">
778
- 2. Hook spécialisé pour les notifications
779
- </h4>
780
- <div className="bg-slate-50 dark:bg-slate-900 p-4 rounded-lg text-sm font-mono overflow-x-auto">
781
- <pre>{`import { useNotifications } from "../hooks/useNotifications";
529
+ </Alert>
530
+ <h4 className="font-medium mb-2">2. Hook spécialisé pour les notifications</h4>
531
+ <Alert hideIcon color="primary" className="p-4 mb-4">
532
+ <pre className="whitespace-pre-wrap">{`import { useNotifications } from "../hooks/useNotifications";
782
533
 
783
534
  function NotificationBell() {
784
535
  const { notifications, loading, hasUpdates } = useNotifications();
785
-
536
+
786
537
  return (
787
538
  <div>
788
539
  🔔 {notifications.length}
@@ -790,19 +541,14 @@ function NotificationBell() {
790
541
  </div>
791
542
  );
792
543
  }`}</pre>
793
- </div>
794
- </div>
795
-
796
- <div>
797
- <h4 className="font-medium mb-2">
798
- 3. Hook bas niveau avec EventBus
799
- </h4>
800
- <div className="bg-slate-50 dark:bg-slate-900 p-4 rounded-lg text-sm font-mono overflow-x-auto">
801
- <pre>{`import { useRealtimeSignal } from "@lastbrain/core";
544
+ </Alert>
545
+ <h4 className="font-medium mb-2">3. Hook bas niveau avec EventBus</h4>
546
+ <Alert hideIcon color="primary" className="p-4 mb-4">
547
+ <pre className="whitespace-pre-wrap">{`import { useRealtimeSignal } from "@lastbrain/core";
802
548
 
803
549
  function MonComposant() {
804
550
  const signal = useRealtimeSignal("user_notifications_updated");
805
-
551
+
806
552
  useEffect(() => {
807
553
  if (signal.hasUpdates) {
808
554
  // Événement spécifique reçu
@@ -811,126 +557,56 @@ function MonComposant() {
811
557
  }
812
558
  }, [signal.tick]);
813
559
  }`}</pre>
814
- </div>
815
- </div>
816
- </div>
817
- </div>
818
-
819
- <div>
820
- <h3 className="text-lg font-semibold mb-2">
821
- Architecture du système
822
- </h3>
823
- <div className="space-y-3">
824
- <div className="border-l-4 border-blue-500 pl-4">
825
- <h4 className="font-semibold text-blue-600 dark:text-blue-400">
826
- 🎯 EventBus Global
827
- </h4>
828
- <p className="text-sm text-slate-600 dark:text-slate-400">
829
- Système central de coordination des événements realtime à
830
- travers toute l'application.
831
- </p>
832
- </div>
833
-
834
- <div className="border-l-4 border-green-500 pl-4">
835
- <h4 className="font-semibold text-green-600 dark:text-green-400">
836
- 🔌 RealtimeProvider
837
- </h4>
838
- <p className="text-sm text-slate-600 dark:text-slate-400">
839
- Provider React qui établit les connexions Supabase Realtime
840
- basées sur la configuration des modules.
841
- </p>
560
+ </Alert>
561
+ <h3 className="text-lg font-semibold mb-2">Architecture du système</h3>
562
+ <h4 className="font-medium mb-2">🎯 EventBus Global</h4>
563
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Système central de coordination des événements realtime à travers toute l'application.</p>
564
+ <h4 className="font-medium mb-2">🔌 RealtimeProvider</h4>
565
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Provider React qui établit les connexions Supabase Realtime basées sur la configuration des modules.</p>
566
+ <h4 className="font-medium mb-2">⚡ Hooks Scalables</h4>
567
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Collection de hooks React pour écouter des tables ou événements spécifiques avec auto-refresh.</p>
568
+ <h4 className="font-medium mb-2">🛠️ Build intégré</h4>
569
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Génération automatique de la configuration TypeScript lors du build des modules.</p>
570
+ <h3 className="text-lg font-semibold mb-2">Avantages du système</h3>
571
+ <div className="space-y-2">
572
+ <div className="flex items-start gap-2">
573
+ <span>✅ Configuration déclarative dans les modules</span>
842
574
  </div>
843
-
844
- <div className="border-l-4 border-purple-500 pl-4">
845
- <h4 className="font-semibold text-purple-600 dark:text-purple-400">
846
- ⚡ Hooks Scalables
847
- </h4>
848
- <p className="text-sm text-slate-600 dark:text-slate-400">
849
- Collection de hooks React pour écouter des tables ou
850
- événements spécifiques avec auto-refresh.
851
- </p>
575
+ <div className="flex items-start gap-2">
576
+ <span>✅ Génération automatique de config</span>
852
577
  </div>
853
-
854
- <div className="border-l-4 border-orange-500 pl-4">
855
- <h4 className="font-semibold text-orange-600 dark:text-orange-400">
856
- 🛠️ Build intégré
857
- </h4>
858
- <p className="text-sm text-slate-600 dark:text-slate-400">
859
- Génération automatique de la configuration TypeScript lors du
860
- build des modules.
861
- </p>
578
+ <div className="flex items-start gap-2">
579
+ <span>✅ Hooks React prêts à l'emploi</span>
862
580
  </div>
863
- </div>
864
- </div>
865
-
866
- <div>
867
- <h3 className="text-lg font-semibold mb-2">Avantages du système</h3>
868
- <div className="grid grid-cols-1 md:grid-cols-2 gap-3 text-sm">
869
581
  <div className="flex items-start gap-2">
870
- <span className="text-green-600">✅</span>
871
- <span>Configuration déclarative dans les modules</span>
582
+ <span>✅ Sécurité RLS de Supabase</span>
872
583
  </div>
873
584
  <div className="flex items-start gap-2">
874
- <span className="text-green-600">✅</span>
875
- <span>Génération automatique de config</span>
585
+ <span>✅ Scalable pour n'importe quelle table</span>
876
586
  </div>
877
587
  <div className="flex items-start gap-2">
878
- <span className="text-green-600">✅</span>
879
- <span>Hooks React prêts à l'emploi</span>
588
+ <span>✅ TypeScript avec types générés</span>
880
589
  </div>
590
+ </div>
591
+ <h3 className="text-lg font-semibold mb-2">Exemples d'utilisation</h3>
592
+ <div className="space-y-2">
881
593
  <div className="flex items-start gap-2">
882
594
  <span className="text-green-600">✅</span>
883
- <span>Sécurité RLS de Supabase</span>
595
+ <span><strong>🔔 Notifications</strong>: Affichage en temps réel des nouvelles notifications avec badge et auto-refresh</span>
884
596
  </div>
885
597
  <div className="flex items-start gap-2">
886
598
  <span className="text-green-600">✅</span>
887
- <span>Scalable pour n'importe quelle table</span>
599
+ <span><strong>👥 Utilisateurs en ligne</strong>: Suivi des connexions/déconnexions des utilisateurs en direct</span>
888
600
  </div>
889
601
  <div className="flex items-start gap-2">
890
602
  <span className="text-green-600">✅</span>
891
- <span>TypeScript avec types générés</span>
892
- </div>
893
- </div>
894
- </div>
895
-
896
- <div>
897
- <h3 className="text-lg font-semibold mb-2">
898
- Exemples d'utilisation
899
- </h3>
900
- <div className="space-y-3">
901
- <div className="p-3 bg-blue-50 dark:bg-blue-950 rounded-lg">
902
- <h4 className="font-medium text-blue-700 dark:text-blue-300 mb-1">
903
- 🔔 Notifications
904
- </h4>
905
- <p className="text-sm text-blue-600 dark:text-blue-400">
906
- Affichage en temps réel des nouvelles notifications avec badge
907
- et auto-refresh
908
- </p>
909
- </div>
910
-
911
- <div className="p-3 bg-purple-50 dark:bg-purple-950 rounded-lg">
912
- <h4 className="font-medium text-purple-700 dark:text-purple-300 mb-1">
913
- 👥 Utilisateurs en ligne
914
- </h4>
915
- <p className="text-sm text-purple-600 dark:text-purple-400">
916
- Suivi des connexions/déconnexions des utilisateurs en direct
917
- </p>
918
- </div>
919
-
920
- <div className="p-3 bg-green-50 dark:bg-green-950 rounded-lg">
921
- <h4 className="font-medium text-green-700 dark:text-green-300 mb-1">
922
- 📊 Données collaboratives
923
- </h4>
924
- <p className="text-sm text-green-600 dark:text-green-400">
925
- Synchronisation automatique des modifications de données entre
926
- utilisateurs
927
- </p>
603
+ <span><strong>📊 Données collaboratives</strong>: Synchronisation automatique des modifications de données entre utilisateurs</span>
928
604
  </div>
929
605
  </div>
930
- </div>
931
606
  </CardBody>
932
607
  </Card>
933
608
 
609
+
934
610
  <Card id="section-module-docs" className="scroll-mt-32">
935
611
  <CardHeader>
936
612
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -939,24 +615,11 @@ function MonComposant() {
939
615
  </h2>
940
616
  </CardHeader>
941
617
  <CardBody className="space-y-4">
942
- <p className="text-slate-600 dark:text-slate-400">
943
- Chaque module peut exporter un composant de documentation qui sera
944
- automatiquement intégré dans cette page.
945
- </p>
946
-
947
- <div>
948
- <h3 className="text-lg font-semibold mb-2">
949
- Créer une documentation
950
- </h3>
951
- <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
952
- Dans votre module, créez{" "}
953
- <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
954
- src/components/Doc.tsx
955
- </code>{" "}
956
- :
957
- </p>
958
- <div className="bg-slate-50 dark:bg-slate-900 p-4 rounded-lg text-sm font-mono overflow-x-auto">
959
- <pre>{`export function MonModuleDoc() {
618
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Chaque module peut exporter un composant de documentation qui sera automatiquement intégré dans cette page.</p>
619
+ <h3 className="text-lg font-semibold mb-2">Créer une documentation</h3>
620
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Dans votre module, créez <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">src/components/Doc.tsx</code> :</p>
621
+ <Alert hideIcon color="primary" className="p-4 mb-4">
622
+ <pre className="whitespace-pre-wrap">{`export function MonModuleDoc() {
960
623
  return (
961
624
  <div>
962
625
  <h1>Mon Module</h1>
@@ -964,84 +627,134 @@ function MonComposant() {
964
627
  </div>
965
628
  );
966
629
  }`}</pre>
967
- </div>
968
- </div>
969
-
970
- <div>
971
- <h3 className="text-lg font-semibold mb-2">
972
- Exporter la documentation
973
- </h3>
974
- <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
975
- Dans{" "}
976
- <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
977
- src/index.ts
978
- </code>{" "}
979
- :
980
- </p>
981
- <div className="bg-slate-50 dark:bg-slate-900 p-4 rounded-lg text-sm font-mono">
982
- <pre>{`export { MonModuleDoc } from "./components/Doc.js";`}</pre>
983
- </div>
984
- </div>
630
+ </Alert>
631
+ <h3 className="text-lg font-semibold mb-2">Exporter la documentation</h3>
632
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Dans <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">src/index.ts</code> :</p>
633
+ <Alert hideIcon color="primary" className="p-4 mb-4">
634
+ <pre className="whitespace-pre-wrap">{`export { MonModuleDoc } from "./components/Doc.js";`}</pre>
635
+ </Alert>
985
636
  </CardBody>
986
637
  </Card>
987
638
 
639
+
988
640
  <Card id="section-links" className="scroll-mt-32">
989
641
  <CardHeader>
990
642
  <h2 className="text-2xl font-semibold flex items-center gap-2">
991
- <LinkIcon size={24} />
992
- Liens utiles
643
+ <Link size={24} />
644
+ Liens utiles & remerciements 🙏
993
645
  </h2>
994
646
  </CardHeader>
995
647
  <CardBody>
996
- <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
997
- <a
998
- href="https://nextjs.org/docs"
999
- target="_blank"
1000
- rel="noopener noreferrer"
1001
- className="p-4 border border-slate-200 dark:border-slate-700 rounded-lg hover:bg-slate-50 dark:hover:bg-slate-800 transition-colors"
1002
- >
1003
- <h3 className="font-semibold mb-1">Next.js</h3>
1004
- <p className="text-sm text-slate-600 dark:text-slate-400">
1005
- Documentation officielle
1006
- </p>
1007
- </a>
1008
-
1009
- <a
1010
- href="https://supabase.com/docs"
1011
- target="_blank"
1012
- rel="noopener noreferrer"
1013
- className="p-4 border border-slate-200 dark:border-slate-700 rounded-lg hover:bg-slate-50 dark:hover:bg-slate-800 transition-colors"
1014
- >
1015
- <h3 className="font-semibold mb-1">Supabase</h3>
1016
- <p className="text-sm text-slate-600 dark:text-slate-400">
1017
- Documentation officielle
1018
- </p>
1019
- </a>
648
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
649
+ <Card className="hover:shadow-lg transition-shadow" isPressable as="a" href="https://nextjs.org/docs" target="_blank" rel="noopener noreferrer">
650
+ <CardBody>
651
+ <h3 className="text-lg font-semibold mb-2">Next.js</h3>
652
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-3">Documentation officielle</p>
653
+ <p className="text-xs text-blue-600 dark:text-blue-400 truncate">https://nextjs.org/docs</p>
654
+ </CardBody>
655
+ </Card>
656
+ <Card className="hover:shadow-lg transition-shadow" isPressable as="a" href="https://supabase.com/docs" target="_blank" rel="noopener noreferrer">
657
+ <CardBody>
658
+ <h3 className="text-lg font-semibold mb-2">Supabase</h3>
659
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-3">Documentation officielle</p>
660
+ <p className="text-xs text-blue-600 dark:text-blue-400 truncate">https://supabase.com/docs</p>
661
+ </CardBody>
662
+ </Card>
663
+ <Card className="hover:shadow-lg transition-shadow" isPressable as="a" href="https://www.heroui.com/docs" target="_blank" rel="noopener noreferrer">
664
+ <CardBody>
665
+ <h3 className="text-lg font-semibold mb-2">Heroui</h3>
666
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-3">Composants UI</p>
667
+ <p className="text-xs text-blue-600 dark:text-blue-400 truncate">https://www.heroui.com/docs</p>
668
+ </CardBody>
669
+ </Card>
670
+ <Card className="hover:shadow-lg transition-shadow" isPressable as="a" href="https://tailwindcss.com/docs" target="_blank" rel="noopener noreferrer">
671
+ <CardBody>
672
+ <h3 className="text-lg font-semibold mb-2">Tailwind CSS</h3>
673
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-3">Framework CSS</p>
674
+ <p className="text-xs text-blue-600 dark:text-blue-400 truncate">https://tailwindcss.com/docs</p>
675
+ </CardBody>
676
+ </Card>
677
+ <Card className="hover:shadow-lg transition-shadow" isPressable as="a" href="https://lucide.dev/" target="_blank" rel="noopener noreferrer">
678
+ <CardBody>
679
+ <h3 className="text-lg font-semibold mb-2">Lucide Icons</h3>
680
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-3">Icones SVG</p>
681
+ <p className="text-xs text-blue-600 dark:text-blue-400 truncate">https://lucide.dev/</p>
682
+ </CardBody>
683
+ </Card>
684
+ <Card className="hover:shadow-lg transition-shadow" isPressable as="a" href="https://stripe.com/docs" target="_blank" rel="noopener noreferrer">
685
+ <CardBody>
686
+ <h3 className="text-lg font-semibold mb-2">Stripe</h3>
687
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-3">Système de paiement</p>
688
+ <p className="text-xs text-blue-600 dark:text-blue-400 truncate">https://stripe.com/docs</p>
689
+ </CardBody>
690
+ </Card>
691
+ </div>
692
+ </CardBody>
693
+ </Card>
1020
694
 
1021
- <a
1022
- href="https://nextui.org/docs"
1023
- target="_blank"
1024
- rel="noopener noreferrer"
1025
- className="p-4 border border-slate-200 dark:border-slate-700 rounded-lg hover:bg-slate-50 dark:hover:bg-slate-800 transition-colors"
1026
- >
1027
- <h3 className="font-semibold mb-1">NextUI</h3>
1028
- <p className="text-sm text-slate-600 dark:text-slate-400">
1029
- Composants UI
1030
- </p>
1031
- </a>
1032
695
 
1033
- <a
1034
- href="https://tailwindcss.com/docs"
1035
- target="_blank"
1036
- rel="noopener noreferrer"
1037
- className="p-4 border border-slate-200 dark:border-slate-700 rounded-lg hover:bg-slate-50 dark:hover:bg-slate-800 transition-colors"
1038
- >
1039
- <h3 className="font-semibold mb-1">Tailwind CSS</h3>
1040
- <p className="text-sm text-slate-600 dark:text-slate-400">
1041
- Framework CSS
1042
- </p>
1043
- </a>
1044
- </div>
696
+ <Card id="section-modules" className="scroll-mt-32">
697
+ <CardHeader>
698
+ <h2 className="text-2xl font-semibold flex items-center gap-2">
699
+ <FileText size={24} />
700
+ Modules
701
+ </h2>
702
+ </CardHeader>
703
+ <CardBody className="space-y-4">
704
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Les modules LastBrain permettent d'ajouter des fonctionnalités complètes à votre application de manière modulaire.</p>
705
+ <h3 className="text-lg font-semibold mb-2">Modules Disponibles</h3>
706
+ <h4 className="font-medium mb-2">[module-ai](../packages/module-ai/README.md)</h4>
707
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">@lastbrain/module-ai</p>
708
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2"><strong>Pages</strong>: 1 auth, 2 admin</p>
709
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2"><strong>Tables</strong>: user_token_ledger, user_prompts</p>
710
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2"><a href="../packages/module-ai/README.md" className="text-blue-600 hover:underline" target="_blank" rel="noopener noreferrer">📖 Documentation complète →</a></p>
711
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">---</p>
712
+ <h4 className="font-medium mb-2">[module-auth](../packages/module-auth/README.md)</h4>
713
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">@lastbrain/module-auth</p>
714
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2"><strong>Pages</strong>: 3 publique(s), 3 auth, 2 admin</p>
715
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2"><strong>Tables</strong>: user_profil, user_address, user_notifications</p>
716
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2"><a href="../packages/module-auth/README.md" className="text-blue-600 hover:underline" target="_blank" rel="noopener noreferrer">📖 Documentation complète →</a></p>
717
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">---</p>
718
+ <h3 className="text-lg font-semibold mb-2">Commandes</h3>
719
+ <h4 className="font-medium mb-2">Installer un module</h4>
720
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
721
+ {`pnpm lastbrain add-module nom-du-module`}
722
+ </Snippet>
723
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
724
+ {`pnpm build:modules`}
725
+ </Snippet>
726
+ <h4 className="font-medium mb-2">Créer un nouveau module</h4>
727
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
728
+ {`pnpm lastbrain create-module nom-du-module`}
729
+ </Snippet>
730
+ <h4 className="font-medium mb-2">Générer la documentation des modules</h4>
731
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
732
+ {`pnpm generate:module-docs`}
733
+ </Snippet>
734
+ <h4 className="font-medium mb-2">Supprimer un module</h4>
735
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
736
+ {`pnpm lastbrain remove-module nom-du-module`}
737
+ </Snippet>
738
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
739
+ {`pnpm build:modules`}
740
+ </Snippet>
741
+ <h3 className="text-lg font-semibold mb-2">Développement de modules</h3>
742
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">Pour créer un nouveau module, consultez la <a href="./004_CREATE_MODULE.md" className="text-blue-600 hover:underline" target="_blank" rel="noopener noreferrer">documentation de création de modules</a>.</p>
743
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">La documentation de chaque module est générée automatiquement depuis :</p>
744
+ <div className="space-y-2">
745
+ <div className="flex items-start gap-2">
746
+ <span className="text-green-600">✅</span>
747
+ <span>Le fichier <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">module-name.build.config.ts</code> pour les pages et APIs</span>
748
+ </div>
749
+ <div className="flex items-start gap-2">
750
+ <span className="text-green-600">✅</span>
751
+ <span>Les fichiers de migration SQL pour les tables</span>
752
+ </div>
753
+ <div className="flex items-start gap-2">
754
+ <span className="text-green-600">✅</span>
755
+ <span>Le README.md est auto-généré avec <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">pnpm generate:module-docs</code></span>
756
+ </div>
757
+ </div>
1045
758
  </CardBody>
1046
759
  </Card>
1047
760
  </div>