@lastbrain/app 0.1.36 → 0.1.39

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.
Files changed (45) hide show
  1. package/dist/__tests__/module-registry.test.js +5 -16
  2. package/dist/layouts/AdminLayoutWithSidebar.d.ts.map +1 -1
  3. package/dist/layouts/AdminLayoutWithSidebar.js +36 -1
  4. package/dist/layouts/AuthLayoutWithSidebar.d.ts.map +1 -1
  5. package/dist/layouts/AuthLayoutWithSidebar.js +36 -1
  6. package/dist/layouts/PublicLayout.js +1 -1
  7. package/dist/layouts/PublicLayoutWithSidebar.d.ts.map +1 -1
  8. package/dist/layouts/PublicLayoutWithSidebar.js +36 -1
  9. package/dist/scripts/init-app.d.ts.map +1 -1
  10. package/dist/scripts/init-app.js +2 -2
  11. package/dist/scripts/module-add.d.ts +0 -11
  12. package/dist/scripts/module-add.d.ts.map +1 -1
  13. package/dist/scripts/module-add.js +45 -22
  14. package/dist/scripts/module-build.d.ts.map +1 -1
  15. package/dist/scripts/module-build.js +90 -1
  16. package/dist/scripts/module-create.d.ts +23 -0
  17. package/dist/scripts/module-create.d.ts.map +1 -1
  18. package/dist/scripts/module-create.js +289 -56
  19. package/dist/scripts/module-delete.d.ts +6 -0
  20. package/dist/scripts/module-delete.d.ts.map +1 -0
  21. package/dist/scripts/module-delete.js +143 -0
  22. package/dist/scripts/module-list.d.ts.map +1 -1
  23. package/dist/scripts/module-list.js +2 -2
  24. package/dist/scripts/module-remove.d.ts.map +1 -1
  25. package/dist/scripts/module-remove.js +20 -4
  26. package/dist/styles.css +1 -1
  27. package/dist/templates/DefaultDoc.d.ts.map +1 -1
  28. package/dist/templates/DefaultDoc.js +132 -9
  29. package/dist/templates/DocPage.d.ts.map +1 -1
  30. package/dist/templates/DocPage.js +24 -7
  31. package/package.json +4 -4
  32. package/src/__tests__/module-registry.test.ts +5 -17
  33. package/src/layouts/AdminLayoutWithSidebar.tsx +51 -1
  34. package/src/layouts/AuthLayoutWithSidebar.tsx +51 -1
  35. package/src/layouts/PublicLayout.tsx +1 -1
  36. package/src/layouts/PublicLayoutWithSidebar.tsx +51 -1
  37. package/src/scripts/init-app.ts +5 -2
  38. package/src/scripts/module-add.ts +55 -23
  39. package/src/scripts/module-build.ts +109 -1
  40. package/src/scripts/module-create.ts +392 -69
  41. package/src/scripts/module-delete.ts +202 -0
  42. package/src/scripts/module-list.ts +9 -2
  43. package/src/scripts/module-remove.ts +36 -4
  44. package/src/templates/DefaultDoc.tsx +1149 -424
  45. package/src/templates/DocPage.tsx +26 -10
@@ -2,7 +2,7 @@
2
2
  // This file is auto-generated from markdown files in docs/
3
3
  // Run 'pnpm sync:docs' to regenerate
4
4
  import React from "react";
5
- import { Card, CardBody, CardHeader, Snippet,Alert } from "@lastbrain/ui";
5
+ import { Card, CardBody, CardHeader, Snippet, Alert } from "@lastbrain/ui";
6
6
  import {
7
7
  FileText,
8
8
  Rocket,
@@ -14,13 +14,12 @@ import {
14
14
  Zap,
15
15
  Palette,
16
16
  HardDrive,
17
- Link
17
+ Link,
18
18
  } from "lucide-react";
19
19
 
20
20
  export function DefaultDocumentation() {
21
21
  return (
22
22
  <div className="space-y-6">
23
-
24
23
  <Card id="section-welcome" className="scroll-mt-32">
25
24
  <CardHeader>
26
25
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -29,13 +28,20 @@ export function DefaultDocumentation() {
29
28
  </h2>
30
29
  </CardHeader>
31
30
  <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>
31
+ <p className="text-slate-600 dark:text-slate-400">
32
+ Framework modulaire pour créer rapidement des applications Next.js
33
+ avec système de modules, authentification et base de données.
34
+ </p>
35
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
36
+ LastBrain est un framework modulaire pour créer des applications
37
+ Next.js avec une architecture basée sur des modules réutilisables.
38
+ </p>
39
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
40
+ <strong>Version:</strong> v1.0.0
41
+ </p>
35
42
  </CardBody>
36
43
  </Card>
37
44
 
38
-
39
45
  <Card id="section-quickstart" className="scroll-mt-32">
40
46
  <CardHeader>
41
47
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -44,102 +50,176 @@ export function DefaultDocumentation() {
44
50
  </h2>
45
51
  </CardHeader>
46
52
  <CardBody className="space-y-4">
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>
48
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
49
- {`# 1. Créer une nouvelle application (utilise @latest pour la version la plus récente)`}
50
- </Snippet>
51
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
52
- {`pnpx @lastbrain/app@latest init mon-app`}
53
- </Snippet>
54
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
55
- {`# 2. Accéder au dossier`}
56
- </Snippet>
57
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
58
- {`cd mon-app`}
59
- </Snippet>
60
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
61
- {`# 3. Initialiser Supabase`}
62
- </Snippet>
63
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
64
- {`pnpm db:init`}
65
- </Snippet>
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>
53
+ <p className="text-slate-600 dark:text-slate-400">
54
+ <strong>Note importante :</strong> LastBrain est un écosystème de
55
+ packages interconnectés. L'application générée utilise
56
+ automatiquement{" "}
57
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
58
+ @lastbrain/core
59
+ </code>
60
+ ,{" "}
61
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
62
+ @lastbrain/ui
63
+ </code>
64
+ , et les modules comme{" "}
65
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
66
+ @lastbrain/module-auth
67
+ </code>{" "}
68
+ et{" "}
69
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
70
+ @lastbrain/module-ai
71
+ </code>
72
+ . Tous ces packages sont nécessaires pour le bon fonctionnement.
73
+ </p>
74
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
75
+ {`# 1. Créer une nouvelle application (utilise @latest pour la version la plus récente)`}
76
+ </Snippet>
77
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
78
+ {`pnpx @lastbrain/app@latest init mon-app`}
79
+ </Snippet>
80
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
81
+ {`# 2. Accéder au dossier`}
82
+ </Snippet>
83
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
84
+ {`cd mon-app`}
85
+ </Snippet>
86
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
87
+ {`# 3. Initialiser Supabase`}
88
+ </Snippet>
89
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
90
+ {`pnpm db:init`}
91
+ </Snippet>
92
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
93
+ {`# 4. Démarrer l'application`}
94
+ </Snippet>
95
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
96
+ {`pnpm dev`}
97
+ </Snippet>
98
+ <h3 className="text-lg font-semibold mb-2">
99
+ Explication de la commande
100
+ </h3>
101
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
102
+ {`pnpx @lastbrain/app@latest init mon-app`}
103
+ </Snippet>
104
+ <div className="space-y-2">
105
+ <div className="flex items-start gap-2">
106
+ <span className="text-green-600">✅</span>
107
+ <span>
108
+ <strong>
109
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
110
+ pnpx
111
+ </code>
112
+ </strong>{" "}
113
+ : Exécute un package npm sans l'installer globalement
114
+ </span>
93
115
  </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>
116
+ <div className="flex items-start gap-2">
117
+ <span className="text-green-600">✅</span>
118
+ <span>
119
+ <strong>
120
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
121
+ @lastbrain/app@latest
122
+ </code>
123
+ </strong>{" "}
124
+ : Package CLI de LastBrain en version la plus récente
125
+ </span>
126
+ </div>
127
+ <div className="flex items-start gap-2">
128
+ <span className="text-green-600">✅</span>
129
+ <span>
130
+ <strong>
131
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
132
+ init
133
+ </code>
134
+ </strong>{" "}
135
+ : Commande pour initialiser une nouvelle application
136
+ </span>
137
+ </div>
138
+ <div className="flex items-start gap-2">
139
+ <span className="text-green-600">✅</span>
140
+ <span>
141
+ <strong>
142
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
143
+ mon-app
144
+ </code>
145
+ </strong>{" "}
146
+ : Nom du dossier de votre application
147
+ </span>
148
+ </div>
149
+ </div>
150
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
151
+ Cette commande va :
152
+ </p>
153
+ <div className="space-y-2">
154
+ <div className="flex items-start gap-2">
155
+ <span className="text-green-600">✅</span>
156
+ <span>Créer la structure Next.js complète</span>
157
+ </div>
158
+ <div className="flex items-start gap-2">
159
+ <span className="text-green-600">✅</span>
160
+ <span>
161
+ Installer automatiquement tous les packages nécessaires (
162
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
163
+ @lastbrain/core
164
+ </code>
165
+ ,{" "}
166
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
167
+ @lastbrain/ui
168
+ </code>
169
+ , modules...)
170
+ </span>
171
+ </div>
172
+ <div className="flex items-start gap-2">
173
+ <span className="text-green-600">✅</span>
174
+ <span>Configurer Supabase et les migrations</span>
175
+ </div>
176
+ <div className="flex items-start gap-2">
177
+ <span className="text-green-600">✅</span>
178
+ <span>Générer les routes des modules sélectionnés</span>
112
179
  </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>
180
+ </div>
181
+ <h3 className="text-lg font-semibold mb-2">
182
+ Création du Compte Admin
183
+ </h3>
184
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
185
+ {`# Promouvoir votre compte en admin via Supabase`}
186
+ </Snippet>
187
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
188
+ {`update auth.users`}
189
+ </Snippet>
190
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
191
+ {`set raw_app_meta_data = jsonb_set(`}
192
+ </Snippet>
193
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
194
+ {` coalesce(raw_app_meta_data, '{}'::jsonb),`}
195
+ </Snippet>
196
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
197
+ {` '{roles}',`}
198
+ </Snippet>
199
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
200
+ {` '["admin"]'::jsonb`}
201
+ </Snippet>
202
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
203
+ {`)`}
204
+ </Snippet>
205
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
206
+ {`where email = 'votre@email.com';`}
207
+ </Snippet>
208
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
209
+ Votre application est maintenant disponible sur{" "}
210
+ <a
211
+ href="http://localhost:3000"
212
+ className="text-blue-600 hover:underline"
213
+ target="_blank"
214
+ rel="noopener noreferrer"
215
+ >
216
+ http://localhost:3000
217
+ </a>{" "}
218
+ ! 🎉
219
+ </p>
139
220
  </CardBody>
140
221
  </Card>
141
222
 
142
-
143
223
  <Card id="section-architecture" className="scroll-mt-32">
144
224
  <CardHeader>
145
225
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -148,19 +228,32 @@ export function DefaultDocumentation() {
148
228
  </h2>
149
229
  </CardHeader>
150
230
  <CardBody className="space-y-4">
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>
231
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
232
+ Le projet est organisé en monorepo avec pnpm workspaces :
233
+ </p>
234
+ <h3 className="text-lg font-semibold mb-2">@lastbrain/app</h3>
235
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
236
+ Framework principal et CLI. Contient les layouts, scripts de build,
237
+ templates et la logique de génération des pages.
238
+ </p>
239
+ <h3 className="text-lg font-semibold mb-2">@lastbrain/core</h3>
240
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
241
+ Utilitaires et types partagés. Contient les helpers Supabase,
242
+ fonctions serveur et types TypeScript communs.
243
+ </p>
244
+ <h3 className="text-lg font-semibold mb-2">@lastbrain/ui</h3>
245
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
246
+ Composants UI réutilisables basés sur NextUI et Tailwind CSS.
247
+ Fournit les composants Card, Button, Input, etc.
248
+ </p>
249
+ <h3 className="text-lg font-semibold mb-2">@lastbrain/module-\*</h3>
250
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
251
+ Modules fonctionnels (auth, ai, etc.). Chaque module contient ses
252
+ pages, APIs, composants, migrations et documentation.
253
+ </p>
160
254
  </CardBody>
161
255
  </Card>
162
256
 
163
-
164
257
  <Card id="section-create-module" className="scroll-mt-32">
165
258
  <CardHeader>
166
259
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -169,13 +262,22 @@ export function DefaultDocumentation() {
169
262
  </h2>
170
263
  </CardHeader>
171
264
  <CardBody className="space-y-4">
172
- <h3 className="text-lg font-semibold mb-2">Commande CLI</h3>
173
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
174
- {`pnpm lastbrain create-module mon-module`}
175
- </Snippet>
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/
265
+ <h3 className="text-lg font-semibold mb-2">Commande CLI</h3>
266
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
267
+ {`pnpm lastbrain create-module mon-module`}
268
+ </Snippet>
269
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
270
+ Crée un nouveau module dans{" "}
271
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
272
+ packages/module-mon-module
273
+ </code>
274
+ </p>
275
+ <h3 className="text-lg font-semibold mb-2">Structure d'un module</h3>
276
+ <Alert
277
+ hideIcon
278
+ color="primary"
279
+ className="p-4 mb-4 whitespace-pre-wrap"
280
+ >{`📁 module-mon-module/
179
281
  ├── 📄 package.json
180
282
  ├── 📄 mon-module.build.config.ts
181
283
  └── 📁 src/
@@ -186,10 +288,18 @@ export function DefaultDocumentation() {
186
288
  ├── 📁 components/
187
289
  └── 📁 supabase/
188
290
  └── 📁 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 {
291
+ <h3 className="text-lg font-semibold mb-2">
292
+ Configuration du module
293
+ </h3>
294
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
295
+ Le fichier{" "}
296
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
297
+ module-name.build.config.ts
298
+ </code>{" "}
299
+ définit les pages et APIs :
300
+ </p>
301
+ <Alert hideIcon color="primary" className="p-4 mb-4">
302
+ <pre className="whitespace-pre-wrap">{`export default {
193
303
  name: "Mon Module",
194
304
  description: "Description du module",
195
305
  pages: [
@@ -206,11 +316,10 @@ export function DefaultDocumentation() {
206
316
  },
207
317
  ],
208
318
  };`}</pre>
209
- </Alert>
319
+ </Alert>
210
320
  </CardBody>
211
321
  </Card>
212
322
 
213
-
214
323
  <Card id="section-database" className="scroll-mt-32">
215
324
  <CardHeader>
216
325
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -219,26 +328,34 @@ export function DefaultDocumentation() {
219
328
  </h2>
220
329
  </CardHeader>
221
330
  <CardBody className="space-y-4">
222
- <h3 className="text-lg font-semibold mb-2">Supabase local</h3>
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>
331
+ <h3 className="text-lg font-semibold mb-2">Supabase local</h3>
332
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
333
+ LastBrain utilise Supabase pour la base de données et
334
+ l'authentification.
335
+ </p>
336
+ <h4 className="font-medium mb-2">Démarrer Supabase</h4>
337
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
338
+ {`pnpm db:init`}
339
+ </Snippet>
340
+ <h4 className="font-medium mb-2">Synchroniser les migrations</h4>
341
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
342
+ {`pnpm db:migrations:sync`}
343
+ </Snippet>
344
+ <h4 className="font-medium mb-2">Créer une migration</h4>
345
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
346
+ {`supabase migration new ma_migration`}
347
+ </Snippet>
348
+ <h3 className="text-lg font-semibold mb-2">Migrations des modules</h3>
349
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
350
+ Les modules peuvent avoir leurs propres migrations dans{" "}
351
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
352
+ supabase/migrations/
353
+ </code>
354
+ . Elles sont automatiquement synchronisées lors du build.
355
+ </p>
238
356
  </CardBody>
239
357
  </Card>
240
358
 
241
-
242
359
  <Card id="section-admin" className="scroll-mt-32">
243
360
  <CardHeader>
244
361
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -247,32 +364,52 @@ export function DefaultDocumentation() {
247
364
  </h2>
248
365
  </CardHeader>
249
366
  <CardBody className="space-y-4">
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
367
+ <h3 className="text-lg font-semibold mb-2">1. Créer un compte</h3>
368
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
369
+ Allez sur{" "}
370
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
371
+ /signup
372
+ </code>{" "}
373
+ et créez votre compte
374
+ </p>
375
+ <h3 className="text-lg font-semibold mb-2">
376
+ 2. Promouvoir en administrateur
377
+ </h3>
378
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
379
+ Exécutez cette requête SQL dans le Studio Supabase (
380
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
381
+ http://localhost:54323
382
+ </code>
383
+ ) ou via psql :
384
+ </p>
385
+ <Snippet hideSymbol color="primary" className="text-sm mb-2">
386
+ <span>{`update auth.users
256
387
  `}</span>
257
- <span>{`set raw_app_meta_data = jsonb_set(
388
+ <span>{`set raw_app_meta_data = jsonb_set(
258
389
  `}</span>
259
- <span>{` coalesce(raw_app_meta_data, '{}'::jsonb),
390
+ <span>{` coalesce(raw_app_meta_data, '{}'::jsonb),
260
391
  `}</span>
261
- <span>{` '{roles}',
392
+ <span>{` '{roles}',
262
393
  `}</span>
263
- <span>{` '["admin"]'::jsonb
394
+ <span>{` '["admin"]'::jsonb
264
395
  `}</span>
265
- <span>{`)
396
+ <span>{`)
266
397
  `}</span>
267
- <span>{`where email = 'votre@email.com';
398
+ <span>{`where email = 'votre@email.com';
268
399
  `}</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>
400
+ </Snippet>
401
+ <h3 className="text-lg font-semibold mb-2">
402
+ 3. Accéder à l'interface admin
403
+ </h3>
404
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
405
+ Vous pouvez maintenant accéder à{" "}
406
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
407
+ /admin
408
+ </code>
409
+ </p>
272
410
  </CardBody>
273
411
  </Card>
274
412
 
275
-
276
413
  <Card id="section-development" className="scroll-mt-32">
277
414
  <CardHeader>
278
415
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -281,30 +418,35 @@ export function DefaultDocumentation() {
281
418
  </h2>
282
419
  </CardHeader>
283
420
  <CardBody className="space-y-4">
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`}
287
- </Snippet>
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`}
292
- </Snippet>
293
- <h3 className="text-lg font-semibold mb-2">Build de production</h3>
294
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
295
- {`pnpm build`}
296
- </Snippet>
297
- <h3 className="text-lg font-semibold mb-2">Développer un module</h3>
298
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
299
- {`cd packages/module-auth`}
300
- </Snippet>
301
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
302
- {`pnpm dev`}
303
- </Snippet>
421
+ <h3 className="text-lg font-semibold mb-2">
422
+ Lancer le serveur de développement
423
+ </h3>
424
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
425
+ {`pnpm dev`}
426
+ </Snippet>
427
+ <h3 className="text-lg font-semibold mb-2">
428
+ Générer les routes des modules
429
+ </h3>
430
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
431
+ À exécuter après avoir ajouté ou modifié des modules
432
+ </p>
433
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
434
+ {`pnpm build:modules`}
435
+ </Snippet>
436
+ <h3 className="text-lg font-semibold mb-2">Build de production</h3>
437
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
438
+ {`pnpm build`}
439
+ </Snippet>
440
+ <h3 className="text-lg font-semibold mb-2">Développer un module</h3>
441
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
442
+ {`cd packages/module-auth`}
443
+ </Snippet>
444
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
445
+ {`pnpm dev`}
446
+ </Snippet>
304
447
  </CardBody>
305
448
  </Card>
306
449
 
307
-
308
450
  <Card id="section-routes" className="scroll-mt-32">
309
451
  <CardHeader>
310
452
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -313,27 +455,48 @@ export function DefaultDocumentation() {
313
455
  </h2>
314
456
  </CardHeader>
315
457
  <CardBody className="space-y-4">
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>
458
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
459
+ Le middleware protège automatiquement vos routes selon ces règles :
460
+ </p>
461
+ <h3 className="text-lg font-semibold mb-2">Routes</h3>
462
+ <div className="space-y-2">
463
+ <div className="flex items-start gap-2">
464
+ <span className="text-green-600">✅</span>
465
+ <span>
466
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
467
+ /auth/*
468
+ </code>{" "}
469
+ Authentification requise
470
+ </span>
471
+ </div>
472
+ <div className="flex items-start gap-2">
473
+ <span className="text-green-600">✅</span>
474
+ <span>
475
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
476
+ /admin/*
477
+ </code>{" "}
478
+ → Superadmin uniquement
479
+ </span>
331
480
  </div>
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>
481
+ <div className="flex items-start gap-2">
482
+ <span className="text-green-600">✅</span>
483
+ <span>
484
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
485
+ /docs/*
486
+ </code>{" "}
487
+ → Accès public
488
+ </span>
489
+ </div>
490
+ </div>
491
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
492
+ Le middleware se trouve dans{" "}
493
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
494
+ middleware.ts
495
+ </code>
496
+ </p>
333
497
  </CardBody>
334
498
  </Card>
335
499
 
336
-
337
500
  <Card id="section-workflow" className="scroll-mt-32">
338
501
  <CardHeader>
339
502
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -342,34 +505,40 @@ export function DefaultDocumentation() {
342
505
  </h2>
343
506
  </CardHeader>
344
507
  <CardBody className="space-y-4">
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>
348
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
349
- {`cd packages/module-auth`}
350
- </Snippet>
351
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
352
- {`pnpm build`}
353
- </Snippet>
354
- <h3 className="text-lg font-semibold mb-2">3. Régénérer les pages</h3>
355
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
356
- {`cd apps/my-app`}
357
- </Snippet>
358
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
359
- {`pnpm build:modules`}
360
- </Snippet>
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`}
364
- </Snippet>
365
- <h3 className="text-lg font-semibold mb-2">5. Tester</h3>
366
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
367
- {`pnpm dev`}
368
- </Snippet>
508
+ <h3 className="text-lg font-semibold mb-2">1. Modifier un module</h3>
509
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
510
+ Éditez les fichiers dans{" "}
511
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
512
+ packages/module-*/src
513
+ </code>
514
+ </p>
515
+ <h3 className="text-lg font-semibold mb-2">2. Compiler le module</h3>
516
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
517
+ {`cd packages/module-auth`}
518
+ </Snippet>
519
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
520
+ {`pnpm build`}
521
+ </Snippet>
522
+ <h3 className="text-lg font-semibold mb-2">3. Régénérer les pages</h3>
523
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
524
+ {`cd apps/my-app`}
525
+ </Snippet>
526
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
527
+ {`pnpm build:modules`}
528
+ </Snippet>
529
+ <h3 className="text-lg font-semibold mb-2">
530
+ 4. Appliquer les migrations
531
+ </h3>
532
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
533
+ {`supabase migration up`}
534
+ </Snippet>
535
+ <h3 className="text-lg font-semibold mb-2">5. Tester</h3>
536
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
537
+ {`pnpm dev`}
538
+ </Snippet>
369
539
  </CardBody>
370
540
  </Card>
371
541
 
372
-
373
542
  <Card id="section-ui" className="scroll-mt-32">
374
543
  <CardHeader>
375
544
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -378,16 +547,35 @@ export function DefaultDocumentation() {
378
547
  </h2>
379
548
  </CardHeader>
380
549
  <CardBody className="space-y-4">
381
- <h3 className="text-lg font-semibold mb-2">Composants NextUI</h3>
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>
383
- <h3 className="text-lg font-semibold mb-2">Thèmes</h3>
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>
385
- <h3 className="text-lg font-semibold mb-2">Tailwind CSS v4</h3>
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>
550
+ <h3 className="text-lg font-semibold mb-2">Composants NextUI</h3>
551
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
552
+ Le package{" "}
553
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
554
+ @lastbrain/ui
555
+ </code>{" "}
556
+ réexporte les composants NextUI avec une configuration Tailwind
557
+ personnalisée.
558
+ </p>
559
+ <h3 className="text-lg font-semibold mb-2">Thèmes</h3>
560
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
561
+ Le mode sombre/clair est géré par{" "}
562
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
563
+ next-themes
564
+ </code>
565
+ . Le switch est disponible dans le header de l'application.
566
+ </p>
567
+ <h3 className="text-lg font-semibold mb-2">Tailwind CSS v4</h3>
568
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
569
+ Le projet utilise Tailwind CSS v4 avec un preset personnalisé
570
+ partagé via{" "}
571
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
572
+ @lastbrain/ui/tailwind.preset
573
+ </code>
574
+ .
575
+ </p>
387
576
  </CardBody>
388
577
  </Card>
389
578
 
390
-
391
579
  <Card id="section-storage" className="scroll-mt-32">
392
580
  <CardHeader>
393
581
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -396,30 +584,49 @@ export function DefaultDocumentation() {
396
584
  </h2>
397
585
  </CardHeader>
398
586
  <CardBody className="space-y-4">
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
587
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
588
+ LastBrain intègre un système de proxy pour les fichiers Supabase
589
+ Storage qui permet d'utiliser des URLs propres avec contrôle d'accès
590
+ granulaire.
591
+ </p>
592
+ <h3 className="text-lg font-semibold mb-2">
593
+ URLs Proxy vs URLs Supabase
594
+ </h3>
595
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
596
+ <strong>❌ URL Supabase classique (longue)</strong>
597
+ </p>
598
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
599
+ {`https://xxx.supabase.co/storage/v1/object/public/avatar/user_128_123456.webp`}
600
+ </Snippet>
601
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
602
+ <strong>✅ URL Proxy (propre)</strong>
603
+ </p>
604
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
605
+ {`/api/storage/avatar/user_128_123456.webp`}
606
+ </Snippet>
607
+ <h3 className="text-lg font-semibold mb-2">
608
+ Configuration des Buckets
609
+ </h3>
610
+ <h4 className="font-medium mb-2">📂 avatar (Public)</h4>
611
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
612
+ Photos de profil et avatars • 10MB max • Types: JPEG, PNG, WebP, GIF
613
+ </p>
614
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
615
+ {`/api/storage/avatar/user_128_123456.webp`}
616
+ </Snippet>
617
+ <h4 className="font-medium mb-2">🔒 app (Privé)</h4>
618
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
619
+ Fichiers privés des utilisateurs • 100MB max • Authentification
620
+ requise
621
+ </p>
622
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
623
+ {`/api/storage/app/user-id/documents/file.pdf`}
624
+ </Snippet>
625
+ <h3 className="text-lg font-semibold mb-2">
626
+ Utilisation dans le code
627
+ </h3>
628
+ <Alert hideIcon color="primary" className="p-4 mb-4">
629
+ <pre className="whitespace-pre-wrap">{`// Upload d'un fichier
423
630
  import { uploadFile } from "@/api/storage";
424
631
 
425
632
  const proxyUrl = await uploadFile(
@@ -435,32 +642,31 @@ import { storagePathToProxyUrl } from "@/lib/storage";
435
642
 
436
643
  const proxyUrl = storagePathToProxyUrl("avatar/user_128_123456.webp");
437
644
  // Retourne: "/api/storage/avatar/user_128_123456.webp"`}</pre>
438
- </Alert>
439
- <h3 className="text-lg font-semibold mb-2">Avantages du système</h3>
440
- <div className="space-y-2">
441
- <div className="flex items-start gap-2">
442
- <span>✅ URLs plus courtes et lisibles</span>
443
- </div>
444
- <div className="flex items-start gap-2">
445
- <span>✅ Contrôle d'accès granulaire</span>
446
- </div>
447
- <div className="flex items-start gap-2">
448
- <span>✅ Cache optimisé (1 an)</span>
449
- </div>
450
- <div className="flex items-start gap-2">
451
- <span>✅ Sécurité améliorée</span>
452
- </div>
453
- <div className="flex items-start gap-2">
454
- <span>✅ Détection auto des types MIME</span>
455
- </div>
456
- <div className="flex items-start gap-2">
457
- <span>✅ Extensible facilement</span>
458
- </div>
645
+ </Alert>
646
+ <h3 className="text-lg font-semibold mb-2">Avantages du système</h3>
647
+ <div className="space-y-2">
648
+ <div className="flex items-start gap-2">
649
+ <span>✅ URLs plus courtes et lisibles</span>
459
650
  </div>
651
+ <div className="flex items-start gap-2">
652
+ <span>✅ Contrôle d'accès granulaire</span>
653
+ </div>
654
+ <div className="flex items-start gap-2">
655
+ <span>✅ Cache optimisé (1 an)</span>
656
+ </div>
657
+ <div className="flex items-start gap-2">
658
+ <span>✅ Sécurité améliorée</span>
659
+ </div>
660
+ <div className="flex items-start gap-2">
661
+ <span>✅ Détection auto des types MIME</span>
662
+ </div>
663
+ <div className="flex items-start gap-2">
664
+ <span>✅ Extensible facilement</span>
665
+ </div>
666
+ </div>
460
667
  </CardBody>
461
668
  </Card>
462
669
 
463
-
464
670
  <Card id="section-realtime" className="scroll-mt-32">
465
671
  <CardHeader>
466
672
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -469,11 +675,23 @@ const proxyUrl = storagePathToProxyUrl("avatar/user_128_123456.webp");
469
675
  </h2>
470
676
  </CardHeader>
471
677
  <CardBody className="space-y-4">
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 {
678
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
679
+ LastBrain intègre un système de notifications et de synchronisation
680
+ en temps réel basé sur Supabase Realtime. Le système est entièrement
681
+ automatisé et scalable.
682
+ </p>
683
+ <h3 className="text-lg font-semibold mb-2">
684
+ Configuration dans les modules
685
+ </h3>
686
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
687
+ Ajoutez la configuration realtime dans votre{" "}
688
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
689
+ build.config.ts
690
+ </code>{" "}
691
+ pour activer la synchronisation en temps réel :
692
+ </p>
693
+ <Alert hideIcon color="primary" className="p-4 mb-4">
694
+ <pre className="whitespace-pre-wrap">{`export default {
477
695
  name: "Module Auth",
478
696
  description: "Gestion de l'authentification",
479
697
 
@@ -502,18 +720,33 @@ const proxyUrl = storagePathToProxyUrl("avatar/user_128_123456.webp");
502
720
  // vos pages...
503
721
  ],
504
722
  };`}</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`}
510
- </Snippet>
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";
723
+ </Alert>
724
+ <h3 className="text-lg font-semibold mb-2">
725
+ Génération automatique de la configuration
726
+ </h3>
727
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
728
+ Lors du build des modules, la configuration realtime est
729
+ automatiquement générée :
730
+ </p>
731
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
732
+ {`pnpm build:modules`}
733
+ </Snippet>
734
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
735
+ Cela génère automatiquement{" "}
736
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
737
+ config/realtime.ts
738
+ </code>{" "}
739
+ avec toutes les configurations des modules.
740
+ </p>
741
+ <h3 className="text-lg font-semibold mb-2">
742
+ Utilisation dans les composants
743
+ </h3>
744
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
745
+ Utilisez les hooks pré-construits pour écouter les changements :
746
+ </p>
747
+ <h4 className="font-medium mb-2">1. Hook générique pour une table</h4>
748
+ <Alert hideIcon color="primary" className="p-4 mb-4">
749
+ <pre className="whitespace-pre-wrap">{`import { useTableRealtime } from "@lastbrain/core";
517
750
 
518
751
  function MonComposant() {
519
752
  const signal = useTableRealtime("user_notifications");
@@ -526,10 +759,12 @@ function MonComposant() {
526
759
  }
527
760
  }, [signal.tick]);
528
761
  }`}</pre>
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";
762
+ </Alert>
763
+ <h4 className="font-medium mb-2">
764
+ 2. Hook spécialisé pour les notifications
765
+ </h4>
766
+ <Alert hideIcon color="primary" className="p-4 mb-4">
767
+ <pre className="whitespace-pre-wrap">{`import { useNotifications } from "../hooks/useNotifications";
533
768
 
534
769
  function NotificationBell() {
535
770
  const { notifications, loading, hasUpdates } = useNotifications();
@@ -541,10 +776,10 @@ function NotificationBell() {
541
776
  </div>
542
777
  );
543
778
  }`}</pre>
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";
779
+ </Alert>
780
+ <h4 className="font-medium mb-2">3. Hook bas niveau avec EventBus</h4>
781
+ <Alert hideIcon color="primary" className="p-4 mb-4">
782
+ <pre className="whitespace-pre-wrap">{`import { useRealtimeSignal } from "@lastbrain/core";
548
783
 
549
784
  function MonComposant() {
550
785
  const signal = useRealtimeSignal("user_notifications_updated");
@@ -557,56 +792,78 @@ function MonComposant() {
557
792
  }
558
793
  }, [signal.tick]);
559
794
  }`}</pre>
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>
574
- </div>
575
- <div className="flex items-start gap-2">
576
- <span>✅ Génération automatique de config</span>
577
- </div>
578
- <div className="flex items-start gap-2">
579
- <span>✅ Hooks React prêts à l'emploi</span>
580
- </div>
581
- <div className="flex items-start gap-2">
582
- <span>✅ Sécurité RLS de Supabase</span>
583
- </div>
584
- <div className="flex items-start gap-2">
585
- <span>✅ Scalable pour n'importe quelle table</span>
586
- </div>
587
- <div className="flex items-start gap-2">
588
- <span>✅ TypeScript avec types générés</span>
589
- </div>
795
+ </Alert>
796
+ <h3 className="text-lg font-semibold mb-2">
797
+ Architecture du système
798
+ </h3>
799
+ <h4 className="font-medium mb-2">🎯 EventBus Global</h4>
800
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
801
+ Système central de coordination des événements realtime à travers
802
+ toute l'application.
803
+ </p>
804
+ <h4 className="font-medium mb-2">🔌 RealtimeProvider</h4>
805
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
806
+ Provider React qui établit les connexions Supabase Realtime basées
807
+ sur la configuration des modules.
808
+ </p>
809
+ <h4 className="font-medium mb-2">⚡ Hooks Scalables</h4>
810
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
811
+ Collection de hooks React pour écouter des tables ou événements
812
+ spécifiques avec auto-refresh.
813
+ </p>
814
+ <h4 className="font-medium mb-2">🛠️ Build intégré</h4>
815
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
816
+ Génération automatique de la configuration TypeScript lors du build
817
+ des modules.
818
+ </p>
819
+ <h3 className="text-lg font-semibold mb-2">Avantages du système</h3>
820
+ <div className="space-y-2">
821
+ <div className="flex items-start gap-2">
822
+ <span>✅ Configuration déclarative dans les modules</span>
590
823
  </div>
591
- <h3 className="text-lg font-semibold mb-2">Exemples d'utilisation</h3>
592
- <div className="space-y-2">
593
- <div className="flex items-start gap-2">
594
- <span className="text-green-600">✅</span>
595
- <span><strong>🔔 Notifications</strong>: Affichage en temps réel des nouvelles notifications avec badge et auto-refresh</span>
596
- </div>
597
- <div className="flex items-start gap-2">
598
- <span className="text-green-600">✅</span>
599
- <span><strong>👥 Utilisateurs en ligne</strong>: Suivi des connexions/déconnexions des utilisateurs en direct</span>
600
- </div>
601
- <div className="flex items-start gap-2">
602
- <span className="text-green-600">✅</span>
603
- <span><strong>📊 Données collaboratives</strong>: Synchronisation automatique des modifications de données entre utilisateurs</span>
604
- </div>
824
+ <div className="flex items-start gap-2">
825
+ <span>✅ Génération automatique de config</span>
826
+ </div>
827
+ <div className="flex items-start gap-2">
828
+ <span>✅ Hooks React prêts à l'emploi</span>
829
+ </div>
830
+ <div className="flex items-start gap-2">
831
+ <span>✅ Sécurité RLS de Supabase</span>
832
+ </div>
833
+ <div className="flex items-start gap-2">
834
+ <span>✅ Scalable pour n'importe quelle table</span>
605
835
  </div>
836
+ <div className="flex items-start gap-2">
837
+ <span>✅ TypeScript avec types générés</span>
838
+ </div>
839
+ </div>
840
+ <h3 className="text-lg font-semibold mb-2">Exemples d'utilisation</h3>
841
+ <div className="space-y-2">
842
+ <div className="flex items-start gap-2">
843
+ <span className="text-green-600">✅</span>
844
+ <span>
845
+ <strong>🔔 Notifications</strong>: Affichage en temps réel des
846
+ nouvelles notifications avec badge et auto-refresh
847
+ </span>
848
+ </div>
849
+ <div className="flex items-start gap-2">
850
+ <span className="text-green-600">✅</span>
851
+ <span>
852
+ <strong>👥 Utilisateurs en ligne</strong>: Suivi des
853
+ connexions/déconnexions des utilisateurs en direct
854
+ </span>
855
+ </div>
856
+ <div className="flex items-start gap-2">
857
+ <span className="text-green-600">✅</span>
858
+ <span>
859
+ <strong>📊 Données collaboratives</strong>: Synchronisation
860
+ automatique des modifications de données entre utilisateurs
861
+ </span>
862
+ </div>
863
+ </div>
606
864
  </CardBody>
607
865
  </Card>
608
866
 
609
-
610
867
  <Card id="section-module-docs" className="scroll-mt-32">
611
868
  <CardHeader>
612
869
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -615,11 +872,277 @@ function MonComposant() {
615
872
  </h2>
616
873
  </CardHeader>
617
874
  <CardBody className="space-y-4">
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() {
875
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
876
+ Chaque module peut exporter un composant de documentation qui sera
877
+ automatiquement intégré dans cette page.
878
+ </p>
879
+ <h3 className="text-lg font-semibold mb-2">
880
+ Documentation auto-générée
881
+ </h3>
882
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
883
+ Lorsque vous créez un module, la documentation de base (
884
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
885
+ Doc.tsx
886
+ </code>
887
+ ) est automatiquement générée à partir du fichier{" "}
888
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
889
+ build.config.ts
890
+ </code>
891
+ . Cette documentation inclut :
892
+ </p>
893
+ <div className="space-y-2">
894
+ <div className="flex items-start gap-2">
895
+ <span className="text-green-600">✅</span>
896
+ <span>Les pages disponibles</span>
897
+ </div>
898
+ <div className="flex items-start gap-2">
899
+ <span className="text-green-600">✅</span>
900
+ <span>Les routes API</span>
901
+ </div>
902
+ <div className="flex items-start gap-2">
903
+ <span className="text-green-600">✅</span>
904
+ <span>Les tables de base de données</span>
905
+ </div>
906
+ <div className="flex items-start gap-2">
907
+ <span className="text-green-600">✅</span>
908
+ <span>Les instructions d'installation</span>
909
+ </div>
910
+ </div>
911
+ <h4 className="font-medium mb-2">Régénérer la documentation</h4>
912
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
913
+ {`pnpm update:module-docs`}
914
+ </Snippet>
915
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
916
+ {`# ou pour un module spécifique`}
917
+ </Snippet>
918
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
919
+ {`pnpm update:module-docs auth`}
920
+ </Snippet>
921
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
922
+ ⚠️ <strong>Important</strong> : Le fichier{" "}
923
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
924
+ Doc.tsx
925
+ </code>{" "}
926
+ est <strong>écrasé</strong> à chaque génération. Ne le modifiez pas
927
+ directement !
928
+ </p>
929
+ <h3 className="text-lg font-semibold mb-2">
930
+ Personnaliser la section "Utilisation"
931
+ </h3>
932
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
933
+ Pour ajouter du contenu personnalisé qui ne sera{" "}
934
+ <strong>jamais écrasé</strong>, créez un fichier{" "}
935
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
936
+ DocUsageCustom.tsx
937
+ </code>{" "}
938
+ :
939
+ </p>
940
+ <h4 className="font-medium mb-2">
941
+ Étape 1 : Créer le composant personnalisé
942
+ </h4>
943
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
944
+ Dans{" "}
945
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
946
+ packages/votre-module/src/components/DocUsageCustom.tsx
947
+ </code>{" "}
948
+ :
949
+ </p>
950
+ <Alert hideIcon color="primary" className="p-4 mb-4">
951
+ <pre className="whitespace-pre-wrap">{`"use client";
952
+
953
+ import { Card, CardBody, CardHeader, Alert, Tabs, Tab } from "@lastbrain/ui";
954
+ import { Lightbulb } from "lucide-react";
955
+ // Importez vos composants à documenter
956
+ import { MonComposant } from "../web/components/MonComposant";
957
+
958
+ export function DocUsageCustom() {
959
+ return (
960
+ <div className="space-y-6">
961
+ <Alert color="primary" className="mb-6">
962
+ <div className="flex items-start gap-2">
963
+ <Lightbulb size={20} className="mt-0.5 flex-shrink-0" />
964
+ <div>
965
+ <p className="font-semibold">Introduction</p>
966
+ <p className="text-sm mt-1">
967
+ Description de votre module et de ses fonctionnalités principales.
968
+ </p>
969
+ </div>
970
+ </div>
971
+ </Alert>
972
+
973
+ <Tabs aria-label="Exemples d'utilisation">
974
+ <Tab key="exemple1" title="Exemple 1">
975
+ <Card className="mt-4">
976
+ <CardHeader>
977
+ <h3 className="text-xl font-semibold">MonComposant</h3>
978
+ </CardHeader>
979
+ <CardBody className="space-y-6">
980
+ <div>
981
+ <h4 className="text-lg font-semibold mb-2">Description</h4>
982
+ <p className="text-slate-600 dark:text-slate-400">
983
+ Décrivez votre composant et son utilisation.
984
+ </p>
985
+ </div>
986
+
987
+ <div>
988
+ <h4 className="text-lg font-semibold mb-3">Exemple interactif</h4>
989
+ <MonComposant />
990
+ </div>
991
+
992
+ <div>
993
+ <h4 className="text-lg font-semibold mb-2">Code d'utilisation</h4>
994
+ <Alert color="default" className="p-4">
995
+ <pre className="whitespace-pre-wrap text-sm">{\`import { MonComposant } from "@lastbrain/votre-module";
996
+
997
+ export function MyApp() {
998
+ return <MonComposant />;
999
+ }\`}</pre>
1000
+ </Alert>
1001
+ </div>
1002
+
1003
+ <div>
1004
+ <h4 className="text-lg font-semibold mb-2">Props disponibles</h4>
1005
+ <div className="overflow-x-auto">
1006
+ <table className="w-full text-sm">
1007
+ <thead className="border-b">
1008
+ <tr>
1009
+ <th className="text-left py-2 px-2">Prop</th>
1010
+ <th className="text-left py-2 px-2">Type</th>
1011
+ <th className="text-left py-2 px-2">Description</th>
1012
+ </tr>
1013
+ </thead>
1014
+ <tbody className="divide-y">
1015
+ <tr>
1016
+ <td className="py-2 px-2 font-mono">prop1</td>
1017
+ <td className="py-2 px-2">string</td>
1018
+ <td className="py-2 px-2">Description de la prop</td>
1019
+ </tr>
1020
+ </tbody>
1021
+ </table>
1022
+ </div>
1023
+ </div>
1024
+ </CardBody>
1025
+ </Card>
1026
+ </Tab>
1027
+
1028
+ <Tab key="exemple2" title="Exemple 2">
1029
+ {/* Autres exemples */}
1030
+ </Tab>
1031
+ </Tabs>
1032
+ </div>
1033
+ );
1034
+ }`}</pre>
1035
+ </Alert>
1036
+ <h4 className="font-medium mb-2">
1037
+ Étape 2 : Le générateur l'intègre automatiquement
1038
+ </h4>
1039
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1040
+ Une fois{" "}
1041
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
1042
+ DocUsageCustom.tsx
1043
+ </code>{" "}
1044
+ créé, lancez la régénération :
1045
+ </p>
1046
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
1047
+ {`pnpm update:module-docs`}
1048
+ </Snippet>
1049
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1050
+ Le script détecte automatiquement l'existence de{" "}
1051
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
1052
+ DocUsageCustom.tsx
1053
+ </code>{" "}
1054
+ et l'importe dans{" "}
1055
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
1056
+ Doc.tsx
1057
+ </code>{" "}
1058
+ :
1059
+ </p>
1060
+ <Alert hideIcon color="primary" className="p-4 mb-4">
1061
+ <pre className="whitespace-pre-wrap">{`// Doc.tsx (généré automatiquement)
1062
+ import { DocUsageCustom } from "./DocUsageCustom";
1063
+
1064
+ // Dans la section Utilisation :
1065
+ <Card>
1066
+ <CardHeader>
1067
+ <h2>Utilisation</h2>
1068
+ </CardHeader>
1069
+ <CardBody>
1070
+ <DocUsageCustom />
1071
+ </CardBody>
1072
+ </Card>`}</pre>
1073
+ </Alert>
1074
+ <h4 className="font-medium mb-2">
1075
+ Étape 3 : Mettre à jour sans perdre vos modifications
1076
+ </h4>
1077
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1078
+ Vous pouvez maintenant régénérer la documentation autant de fois que
1079
+ vous voulez, votre fichier{" "}
1080
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
1081
+ DocUsageCustom.tsx
1082
+ </code>{" "}
1083
+ ne sera <strong>jamais écrasé</strong> :
1084
+ </p>
1085
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
1086
+ {`pnpm update:module-docs`}
1087
+ </Snippet>
1088
+ <h3 className="text-lg font-semibold mb-2">
1089
+ Exemple concret : Module AI
1090
+ </h3>
1091
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1092
+ Le module AI utilise cette approche pour documenter ses composants
1093
+ de génération :
1094
+ </p>
1095
+ <Alert hideIcon color="primary" className="p-4 mb-4">
1096
+ <pre className="whitespace-pre-wrap">{`// packages/module-ai/src/components/DocUsageCustom.tsx
1097
+ import { TextareaGenerative } from "../web/components/TextareaGenerative";
1098
+ import { ImageGenerative } from "../web/components/ImageGenerative";
1099
+
1100
+ export function DocUsageCustom() {
1101
+ return (
1102
+ <Tabs>
1103
+ <Tab key="textarea" title="Génération de Texte">
1104
+ <TextareaGenerative
1105
+ prompt="Écris une courte description..."
1106
+ model="gpt-4o-mini"
1107
+ />
1108
+ </Tab>
1109
+ <Tab key="image" title="Génération d'Images">
1110
+ <ImageGenerative
1111
+ prompt="Un chat astronaute..."
1112
+ model="dall-e-3"
1113
+ />
1114
+ </Tab>
1115
+ </Tabs>
1116
+ );
1117
+ }`}</pre>
1118
+ </Alert>
1119
+ <h3 className="text-lg font-semibold mb-2">Structure recommandée</h3>
1120
+ <Alert
1121
+ hideIcon
1122
+ color="primary"
1123
+ className="p-4 mb-4 whitespace-pre-wrap"
1124
+ >{`packages/votre-module/
1125
+ ├── src/
1126
+ │ ├── components/
1127
+ │ │ ├── Doc.tsx # ⚠️ AUTO-GÉNÉRÉ - Ne pas modifier
1128
+ │ │ └── DocUsageCustom.tsx # ✅ Votre contenu personnalisé
1129
+ │ ├── web/
1130
+ │ │ └── components/
1131
+ │ │ └── MonComposant.tsx # Vos composants à documenter
1132
+ │ └── votre-module.build.config.ts`}</Alert>
1133
+ <h3 className="text-lg font-semibold mb-2">
1134
+ Créer une documentation
1135
+ </h3>
1136
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1137
+ Si vous préférez créer une documentation complètement manuelle,
1138
+ créez{" "}
1139
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
1140
+ src/components/Doc.tsx
1141
+ </code>{" "}
1142
+ :
1143
+ </p>
1144
+ <Alert hideIcon color="primary" className="p-4 mb-4">
1145
+ <pre className="whitespace-pre-wrap">{`export function MonModuleDoc() {
623
1146
  return (
624
1147
  <div>
625
1148
  <h1>Mon Module</h1>
@@ -627,16 +1150,23 @@ function MonComposant() {
627
1150
  </div>
628
1151
  );
629
1152
  }`}</pre>
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>
1153
+ </Alert>
1154
+ <h3 className="text-lg font-semibold mb-2">
1155
+ Exporter la documentation
1156
+ </h3>
1157
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1158
+ Dans{" "}
1159
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
1160
+ src/index.ts
1161
+ </code>{" "}
1162
+ :
1163
+ </p>
1164
+ <Alert hideIcon color="primary" className="p-4 mb-4">
1165
+ <pre className="whitespace-pre-wrap">{`export { MonModuleDoc } from "./components/Doc.js";`}</pre>
1166
+ </Alert>
636
1167
  </CardBody>
637
1168
  </Card>
638
1169
 
639
-
640
1170
  <Card id="section-links" className="scroll-mt-32">
641
1171
  <CardHeader>
642
1172
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -646,53 +1176,118 @@ function MonComposant() {
646
1176
  </CardHeader>
647
1177
  <CardBody>
648
1178
  <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">
1179
+ <Card
1180
+ className="hover:shadow-lg transition-shadow"
1181
+ isPressable
1182
+ as="a"
1183
+ href="https://nextjs.org/docs"
1184
+ target="_blank"
1185
+ rel="noopener noreferrer"
1186
+ >
650
1187
  <CardBody>
651
1188
  <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>
1189
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-3">
1190
+ Documentation officielle
1191
+ </p>
1192
+ <p className="text-xs text-blue-600 dark:text-blue-400 truncate">
1193
+ https://nextjs.org/docs
1194
+ </p>
654
1195
  </CardBody>
655
1196
  </Card>
656
- <Card className="hover:shadow-lg transition-shadow" isPressable as="a" href="https://supabase.com/docs" target="_blank" rel="noopener noreferrer">
1197
+ <Card
1198
+ className="hover:shadow-lg transition-shadow"
1199
+ isPressable
1200
+ as="a"
1201
+ href="https://supabase.com/docs"
1202
+ target="_blank"
1203
+ rel="noopener noreferrer"
1204
+ >
657
1205
  <CardBody>
658
1206
  <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>
1207
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-3">
1208
+ Documentation officielle
1209
+ </p>
1210
+ <p className="text-xs text-blue-600 dark:text-blue-400 truncate">
1211
+ https://supabase.com/docs
1212
+ </p>
661
1213
  </CardBody>
662
1214
  </Card>
663
- <Card className="hover:shadow-lg transition-shadow" isPressable as="a" href="https://www.heroui.com/docs" target="_blank" rel="noopener noreferrer">
1215
+ <Card
1216
+ className="hover:shadow-lg transition-shadow"
1217
+ isPressable
1218
+ as="a"
1219
+ href="https://www.heroui.com/docs"
1220
+ target="_blank"
1221
+ rel="noopener noreferrer"
1222
+ >
664
1223
  <CardBody>
665
1224
  <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>
1225
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-3">
1226
+ Composants UI
1227
+ </p>
1228
+ <p className="text-xs text-blue-600 dark:text-blue-400 truncate">
1229
+ https://www.heroui.com/docs
1230
+ </p>
668
1231
  </CardBody>
669
1232
  </Card>
670
- <Card className="hover:shadow-lg transition-shadow" isPressable as="a" href="https://tailwindcss.com/docs" target="_blank" rel="noopener noreferrer">
1233
+ <Card
1234
+ className="hover:shadow-lg transition-shadow"
1235
+ isPressable
1236
+ as="a"
1237
+ href="https://tailwindcss.com/docs"
1238
+ target="_blank"
1239
+ rel="noopener noreferrer"
1240
+ >
671
1241
  <CardBody>
672
1242
  <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>
1243
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-3">
1244
+ Framework CSS
1245
+ </p>
1246
+ <p className="text-xs text-blue-600 dark:text-blue-400 truncate">
1247
+ https://tailwindcss.com/docs
1248
+ </p>
675
1249
  </CardBody>
676
1250
  </Card>
677
- <Card className="hover:shadow-lg transition-shadow" isPressable as="a" href="https://lucide.dev/" target="_blank" rel="noopener noreferrer">
1251
+ <Card
1252
+ className="hover:shadow-lg transition-shadow"
1253
+ isPressable
1254
+ as="a"
1255
+ href="https://lucide.dev/"
1256
+ target="_blank"
1257
+ rel="noopener noreferrer"
1258
+ >
678
1259
  <CardBody>
679
1260
  <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>
1261
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-3">
1262
+ Icones SVG
1263
+ </p>
1264
+ <p className="text-xs text-blue-600 dark:text-blue-400 truncate">
1265
+ https://lucide.dev/
1266
+ </p>
682
1267
  </CardBody>
683
1268
  </Card>
684
- <Card className="hover:shadow-lg transition-shadow" isPressable as="a" href="https://stripe.com/docs" target="_blank" rel="noopener noreferrer">
1269
+ <Card
1270
+ className="hover:shadow-lg transition-shadow"
1271
+ isPressable
1272
+ as="a"
1273
+ href="https://stripe.com/docs"
1274
+ target="_blank"
1275
+ rel="noopener noreferrer"
1276
+ >
685
1277
  <CardBody>
686
1278
  <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>
1279
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-3">
1280
+ Système de paiement
1281
+ </p>
1282
+ <p className="text-xs text-blue-600 dark:text-blue-400 truncate">
1283
+ https://stripe.com/docs
1284
+ </p>
689
1285
  </CardBody>
690
1286
  </Card>
691
1287
  </div>
692
1288
  </CardBody>
693
1289
  </Card>
694
1290
 
695
-
696
1291
  <Card id="section-modules" className="scroll-mt-32">
697
1292
  <CardHeader>
698
1293
  <h2 className="text-2xl font-semibold flex items-center gap-2">
@@ -701,60 +1296,190 @@ function MonComposant() {
701
1296
  </h2>
702
1297
  </CardHeader>
703
1298
  <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>
1299
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1300
+ Les modules LastBrain permettent d'ajouter des fonctionnalités
1301
+ complètes à votre application de manière modulaire.
1302
+ </p>
1303
+ <h3 className="text-lg font-semibold mb-2">Modules Disponibles</h3>
1304
+ <h4 className="font-medium mb-2">
1305
+ [module-ai](../packages/module-ai/README.md)
1306
+ </h4>
1307
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1308
+ @lastbrain/module-ai
1309
+ </p>
1310
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1311
+ <strong>Pages</strong>: 1 auth, 1 admin
1312
+ </p>
1313
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1314
+ <strong>Tables</strong>: user_token_ledger, user_prompts
1315
+ </p>
1316
+ <h4 className="font-medium mb-2">Installation du module ai</h4>
1317
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
1318
+ {`pnpm lastbrain add-module ai`}
1319
+ </Snippet>
1320
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1321
+ <a
1322
+ href="../packages/module-ai/README.md"
1323
+ className="text-blue-600 hover:underline"
1324
+ target="_blank"
1325
+ rel="noopener noreferrer"
1326
+ >
1327
+ 📖 Documentation complète →
1328
+ </a>
1329
+ </p>
1330
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">---</p>
1331
+ <h4 className="font-medium mb-2">
1332
+ [module-auth](../packages/module-auth/README.md)
1333
+ </h4>
1334
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1335
+ @lastbrain/module-auth
1336
+ </p>
1337
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1338
+ <strong>Pages</strong>: 3 publique(s), 4 auth, 2 admin
1339
+ </p>
1340
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1341
+ <strong>Tables</strong>: user_profil, user_address,
1342
+ user_notifications
1343
+ </p>
1344
+ <h4 className="font-medium mb-2">Installation du module auth</h4>
1345
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
1346
+ {`pnpm lastbrain add-module auth`}
1347
+ </Snippet>
1348
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1349
+ <a
1350
+ href="../packages/module-auth/README.md"
1351
+ className="text-blue-600 hover:underline"
1352
+ target="_blank"
1353
+ rel="noopener noreferrer"
1354
+ >
1355
+ 📖 Documentation complète →
1356
+ </a>
1357
+ </p>
1358
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">---</p>
1359
+ <h4 className="font-medium mb-2">
1360
+ [module-recipes](../packages/module-recipes/README.md)
1361
+ </h4>
1362
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1363
+ @lastbrain/module-recipes
1364
+ </p>
1365
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1366
+ <strong>Pages</strong>: 4 auth
1367
+ </p>
1368
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1369
+ <strong>Tables</strong>: recipes, recipe_favorites, recipe_comments,
1370
+ recipe_image_queue, recipe_embeddings
1371
+ </p>
1372
+ <h4 className="font-medium mb-2">Installation du module recipes</h4>
1373
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
1374
+ {`pnpm lastbrain add-module recipes`}
1375
+ </Snippet>
1376
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1377
+ <a
1378
+ href="../packages/module-recipes/README.md"
1379
+ className="text-blue-600 hover:underline"
1380
+ target="_blank"
1381
+ rel="noopener noreferrer"
1382
+ >
1383
+ 📖 Documentation complète →
1384
+ </a>
1385
+ </p>
1386
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">---</p>
1387
+ <h4 className="font-medium mb-2">
1388
+ [module-tasks](../packages/module-tasks/README.md)
1389
+ </h4>
1390
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1391
+ @lastbrain/module-tasks
1392
+ </p>
1393
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1394
+ <strong>Pages</strong>: 2 auth, 1 admin
1395
+ </p>
1396
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1397
+ <strong>Tables</strong>: tasks, tasks_logs
1398
+ </p>
1399
+ <h4 className="font-medium mb-2">Installation du module tasks</h4>
1400
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
1401
+ {`pnpm lastbrain add-module tasks`}
1402
+ </Snippet>
1403
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1404
+ <a
1405
+ href="../packages/module-tasks/README.md"
1406
+ className="text-blue-600 hover:underline"
1407
+ target="_blank"
1408
+ rel="noopener noreferrer"
1409
+ >
1410
+ 📖 Documentation complète →
1411
+ </a>
1412
+ </p>
1413
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">---</p>
1414
+ <h3 className="text-lg font-semibold mb-2">Commandes</h3>
1415
+ <h4 className="font-medium mb-2">Installer un module</h4>
1416
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
1417
+ {`pnpm lastbrain add-module nom-du-module`}
1418
+ </Snippet>
1419
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
1420
+ {`pnpm build:modules`}
1421
+ </Snippet>
1422
+ <h4 className="font-medium mb-2">Créer un nouveau module</h4>
1423
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
1424
+ {`pnpm lastbrain create-module nom-du-module`}
1425
+ </Snippet>
1426
+ <h4 className="font-medium mb-2">
1427
+ Générer la documentation des modules
1428
+ </h4>
1429
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
1430
+ {`pnpm generate:module-docs`}
1431
+ </Snippet>
1432
+ <h4 className="font-medium mb-2">Supprimer un module</h4>
1433
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
1434
+ {`pnpm lastbrain remove-module nom-du-module`}
1435
+ </Snippet>
1436
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
1437
+ {`pnpm build:modules`}
1438
+ </Snippet>
1439
+ <h3 className="text-lg font-semibold mb-2">
1440
+ Développement de modules
1441
+ </h3>
1442
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1443
+ Pour créer un nouveau module, consultez la{" "}
1444
+ <a
1445
+ href="./004_CREATE_MODULE.md"
1446
+ className="text-blue-600 hover:underline"
1447
+ target="_blank"
1448
+ rel="noopener noreferrer"
1449
+ >
1450
+ documentation de création de modules
1451
+ </a>
1452
+ .
1453
+ </p>
1454
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1455
+ La documentation de chaque module est générée automatiquement depuis
1456
+ :
1457
+ </p>
1458
+ <div className="space-y-2">
1459
+ <div className="flex items-start gap-2">
1460
+ <span className="text-green-600">✅</span>
1461
+ <span>
1462
+ Le fichier{" "}
1463
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
1464
+ module-name.build.config.ts
1465
+ </code>{" "}
1466
+ pour les pages et APIs
1467
+ </span>
757
1468
  </div>
1469
+ <div className="flex items-start gap-2">
1470
+ <span className="text-green-600">✅</span>
1471
+ <span>Les fichiers de migration SQL pour les tables</span>
1472
+ </div>
1473
+ <div className="flex items-start gap-2">
1474
+ <span className="text-green-600">✅</span>
1475
+ <span>
1476
+ Le README.md est auto-généré avec{" "}
1477
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
1478
+ pnpm generate:module-docs
1479
+ </code>
1480
+ </span>
1481
+ </div>
1482
+ </div>
758
1483
  </CardBody>
759
1484
  </Card>
760
1485
  </div>