@lastbrain/app 0.1.34 → 0.1.37

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 (38) hide show
  1. package/README.md +23 -5
  2. package/dist/__tests__/module-registry.test.js +5 -16
  3. package/dist/scripts/init-app.d.ts.map +1 -1
  4. package/dist/scripts/init-app.js +2 -2
  5. package/dist/scripts/module-add.d.ts +0 -11
  6. package/dist/scripts/module-add.d.ts.map +1 -1
  7. package/dist/scripts/module-add.js +45 -22
  8. package/dist/scripts/module-build.d.ts.map +1 -1
  9. package/dist/scripts/module-build.js +90 -1
  10. package/dist/scripts/module-create.d.ts +23 -0
  11. package/dist/scripts/module-create.d.ts.map +1 -1
  12. package/dist/scripts/module-create.js +737 -52
  13. package/dist/scripts/module-delete.d.ts +6 -0
  14. package/dist/scripts/module-delete.d.ts.map +1 -0
  15. package/dist/scripts/module-delete.js +143 -0
  16. package/dist/scripts/module-list.d.ts.map +1 -1
  17. package/dist/scripts/module-list.js +2 -2
  18. package/dist/scripts/module-remove.d.ts.map +1 -1
  19. package/dist/scripts/module-remove.js +20 -4
  20. package/dist/styles.css +1 -1
  21. package/dist/templates/DefaultDoc.d.ts.map +1 -1
  22. package/dist/templates/DefaultDoc.js +170 -30
  23. package/dist/templates/DocPage.d.ts.map +1 -1
  24. package/dist/templates/DocPage.js +25 -8
  25. package/dist/templates/migrations/20201010100000_app_base.sql +23 -24
  26. package/package.json +4 -4
  27. package/src/__tests__/module-registry.test.ts +5 -17
  28. package/src/scripts/db-init.ts +2 -2
  29. package/src/scripts/init-app.ts +5 -2
  30. package/src/scripts/module-add.ts +55 -23
  31. package/src/scripts/module-build.ts +109 -1
  32. package/src/scripts/module-create.ts +885 -63
  33. package/src/scripts/module-delete.ts +202 -0
  34. package/src/scripts/module-list.ts +9 -2
  35. package/src/scripts/module-remove.ts +36 -4
  36. package/src/templates/DefaultDoc.tsx +1163 -753
  37. package/src/templates/DocPage.tsx +28 -11
  38. package/src/templates/migrations/20201010100000_app_base.sql +23 -24
@@ -1,14 +1,20 @@
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() {
@@ -16,20 +22,23 @@ export function DefaultDocumentation() {
16
22
  <div className="space-y-6">
17
23
  <Card id="section-welcome" className="scroll-mt-32">
18
24
  <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>
25
+ <h2 className="text-2xl font-semibold flex items-center gap-2">
26
+ <FileText size={24} />
27
+ Documentation LastBrain
28
+ </h2>
25
29
  </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>
30
+ <CardBody className="space-y-4">
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>
33
42
  </CardBody>
34
43
  </Card>
35
44
 
@@ -41,65 +50,173 @@ export function DefaultDocumentation() {
41
50
  </h2>
42
51
  </CardHeader>
43
52
  <CardBody className="space-y-4">
44
- <div>
45
- <h3 className="text-lg font-semibold mb-2">Installation</h3>
46
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
47
- pnpm install
48
- </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
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
56
- pnpm db:init
57
- </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
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
66
- pnpm lastbrain list-modules
67
- </Snippet>
68
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
69
- pnpm lastbrain add-module auth
70
- </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
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
82
- pnpm build:modules
83
- </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>
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>
115
+ </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>
87
149
  </div>
88
-
89
- <div>
90
- <h3 className="text-lg font-semibold mb-2">
91
- Lancer le serveur de développement
92
- </h3>
93
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
94
- pnpm dev
95
- </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>
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>
179
+ </div>
102
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>
103
220
  </CardBody>
104
221
  </Card>
105
222
 
@@ -111,59 +228,29 @@ export function DefaultDocumentation() {
111
228
  </h2>
112
229
  </CardHeader>
113
230
  <CardBody className="space-y-4">
114
- <p className="text-slate-600 dark:text-slate-400">
231
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
115
232
  Le projet est organisé en monorepo avec pnpm workspaces :
116
233
  </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>
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>
167
254
  </CardBody>
168
255
  </Card>
169
256
 
@@ -175,71 +262,61 @@ export function DefaultDocumentation() {
175
262
  </h2>
176
263
  </CardHeader>
177
264
  <CardBody className="space-y-4">
178
- <div>
179
- <h3 className="text-lg font-semibold mb-2">Commande CLI</h3>
180
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
181
- pnpm lastbrain create-module mon-module
182
- </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 {
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/
281
+ ├── 📄 package.json
282
+ ├── 📄 mon-module.build.config.ts
283
+ └── 📁 src/
284
+ ├── 📄 index.ts
285
+ ├── 📄 server.ts
286
+ ├── 📁 web/
287
+ ├── 📁 api/
288
+ ├── 📁 components/
289
+ └── 📁 supabase/
290
+ └── 📁 migrations/`}</Alert>
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 {
225
303
  name: "Mon Module",
226
304
  description: "Description du module",
227
305
  pages: [
228
306
  {
229
307
  path: "/ma-page",
230
308
  component: "./web/MaPage",
231
- layout: "auth"
232
- }
309
+ layout: "auth",
310
+ },
233
311
  ],
234
312
  apis: [
235
313
  {
236
314
  path: "/api/mon-api",
237
- handler: "./api/mon-api"
238
- }
239
- ]
240
- }`}</pre>
241
- </div>
242
- </div>
315
+ handler: "./api/mon-api",
316
+ },
317
+ ],
318
+ };`}</pre>
319
+ </Alert>
243
320
  </CardBody>
244
321
  </Card>
245
322
 
@@ -251,105 +328,85 @@ export function DefaultDocumentation() {
251
328
  </h2>
252
329
  </CardHeader>
253
330
  <CardBody className="space-y-4">
254
- <div>
255
- <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>
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>
301
356
  </CardBody>
302
357
  </Card>
303
358
 
304
359
  <Card id="section-admin" className="scroll-mt-32">
305
360
  <CardHeader>
306
- <h2 className="text-2xl font-semibold">
307
- 👤 Créer un Compte Administrateur
361
+ <h2 className="text-2xl font-semibold flex items-center gap-2">
362
+ <User size={24} />
363
+ Créer un Compte Administrateur
308
364
  </h2>
309
365
  </CardHeader>
310
366
  <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>
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
387
+ `}</span>
388
+ <span>{`set raw_app_meta_data = jsonb_set(
389
+ `}</span>
390
+ <span>{` coalesce(raw_app_meta_data, '{}'::jsonb),
391
+ `}</span>
392
+ <span>{` '{roles}',
393
+ `}</span>
394
+ <span>{` '["admin"]'::jsonb
395
+ `}</span>
396
+ <span>{`)
397
+ `}</span>
398
+ <span>{`where email = 'votre@email.com';
399
+ `}</span>
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>
353
410
  </CardBody>
354
411
  </Card>
355
412
 
@@ -361,40 +418,32 @@ export function DefaultDocumentation() {
361
418
  </h2>
362
419
  </CardHeader>
363
420
  <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
370
- </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
381
- </Snippet>
382
- </div>
383
- <div>
384
- <h3 className="text-lg font-semibold mb-2">Build de production</h3>
385
- <Snippet symbol="" hideSymbol className="text-sm">
386
- pnpm build
387
- </Snippet>
388
- </div>
389
- <div>
390
- <h3 className="text-lg font-semibold mb-2">Développer un module</h3>
391
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
392
- cd packages/module-auth
393
- </Snippet>
394
- <Snippet symbol="" hideSymbol className="text-sm">
395
- pnpm dev
396
- </Snippet>
397
- </div>
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>
398
447
  </CardBody>
399
448
  </Card>
400
449
 
@@ -406,30 +455,42 @@ export function DefaultDocumentation() {
406
455
  </h2>
407
456
  </CardHeader>
408
457
  <CardBody className="space-y-4">
409
- <p className="text-slate-600 dark:text-slate-400 mb-4">
458
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
410
459
  Le middleware protège automatiquement vos routes selon ces règles :
411
460
  </p>
461
+ <h3 className="text-lg font-semibold mb-2">Routes</h3>
412
462
  <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>
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>
416
471
  </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>
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>
422
480
  </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>
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>
428
489
  </div>
429
490
  </div>
430
- <p className="text-sm text-slate-600 dark:text-slate-400 mt-4">
491
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
431
492
  Le middleware se trouve dans{" "}
432
- <code className="px-2 py-1 bg-slate-100 dark:bg-slate-800 rounded">
493
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
433
494
  middleware.ts
434
495
  </code>
435
496
  </p>
@@ -444,53 +505,37 @@ export function DefaultDocumentation() {
444
505
  </h2>
445
506
  </CardHeader>
446
507
  <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>
462
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
463
- cd packages/module-auth
464
- </Snippet>
465
- <Snippet symbol="" hideSymbol className="text-sm">
466
- pnpm build
467
- </Snippet>
468
- </div>
469
- <div>
470
- <h3 className="text-lg font-semibold mb-2">
471
- 3. Régénérer les pages
472
- </h3>
473
- <Snippet symbol="" hideSymbol className="text-sm mb-2">
474
- cd apps/my-app
475
- </Snippet>
476
- <Snippet symbol="" hideSymbol className="text-sm">
477
- pnpm build:modules
478
- </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
486
- </Snippet>
487
- </div>
488
- <div>
489
- <h3 className="text-lg font-semibold mb-2">5. Tester</h3>
490
- <Snippet symbol="" hideSymbol className="text-sm">
491
- pnpm dev
492
- </Snippet>
493
- </div>
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>
494
539
  </CardBody>
495
540
  </Card>
496
541
 
@@ -502,127 +547,93 @@ export function DefaultDocumentation() {
502
547
  </h2>
503
548
  </CardHeader>
504
549
  <CardBody className="space-y-4">
505
- <div>
506
- <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>
518
- <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>
529
- <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>
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>
539
576
  </CardBody>
540
577
  </Card>
541
578
 
542
579
  <Card id="section-storage" className="scroll-mt-32">
543
580
  <CardHeader>
544
581
  <h2 className="text-2xl font-semibold flex items-center gap-2">
545
- <Database size={24} />
582
+ <HardDrive size={24} />
546
583
  Système de Proxy Storage
547
584
  </h2>
548
585
  </CardHeader>
549
586
  <CardBody className="space-y-4">
550
- <p className="text-slate-600 dark:text-slate-400">
587
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
551
588
  LastBrain intègre un système de proxy pour les fichiers Supabase
552
589
  Storage qui permet d'utiliser des URLs propres avec contrôle d'accès
553
590
  granulaire.
554
591
  </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
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
619
630
  import { uploadFile } from "@/api/storage";
620
631
 
621
632
  const proxyUrl = await uploadFile(
622
- "avatar",
623
- "user_128_123456.webp",
624
- file,
625
- "image/webp"
633
+ "avatar",
634
+ "user_128_123456.webp",
635
+ file,
636
+ "image/webp",
626
637
  );
627
638
  // Retourne: "/api/storage/avatar/user_128_123456.webp"
628
639
 
@@ -631,36 +642,26 @@ import { storagePathToProxyUrl } from "@/lib/storage";
631
642
 
632
643
  const proxyUrl = storagePathToProxyUrl("avatar/user_128_123456.webp");
633
644
  // Retourne: "/api/storage/avatar/user_128_123456.webp"`}</pre>
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>
634
650
  </div>
635
- </div>
636
-
637
- <div>
638
- <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">
640
- <div className="flex items-start gap-2">
641
- <span className="text-green-600">✅</span>
642
- <span>URLs plus courtes et lisibles</span>
643
- </div>
644
- <div className="flex items-start gap-2">
645
- <span className="text-green-600">✅</span>
646
- <span>Contrôle d'accès granulaire</span>
647
- </div>
648
- <div className="flex items-start gap-2">
649
- <span className="text-green-600">✅</span>
650
- <span>Cache optimisé (1 an)</span>
651
- </div>
652
- <div className="flex items-start gap-2">
653
- <span className="text-green-600">✅</span>
654
- <span>Sécurité améliorée</span>
655
- </div>
656
- <div className="flex items-start gap-2">
657
- <span className="text-green-600">✅</span>
658
- <span>Détection auto des types MIME</span>
659
- </div>
660
- <div className="flex items-start gap-2">
661
- <span className="text-green-600">✅</span>
662
- <span>Extensible facilement</span>
663
- </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>
664
665
  </div>
665
666
  </div>
666
667
  </CardBody>
@@ -674,28 +675,26 @@ const proxyUrl = storagePathToProxyUrl("avatar/user_128_123456.webp");
674
675
  </h2>
675
676
  </CardHeader>
676
677
  <CardBody className="space-y-4">
677
- <p className="text-slate-600 dark:text-slate-400">
678
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
678
679
  LastBrain intègre un système de notifications et de synchronisation
679
680
  en temps réel basé sur Supabase Realtime. Le système est entièrement
680
681
  automatisé et scalable.
681
682
  </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 {
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 {
696
695
  name: "Module Auth",
697
696
  description: "Gestion de l'authentification",
698
-
697
+
699
698
  // Configuration realtime
700
699
  realtime: {
701
700
  moduleId: "module-auth",
@@ -705,63 +704,53 @@ const proxyUrl = storagePathToProxyUrl("avatar/user_128_123456.webp");
705
704
  table: "user_notifications",
706
705
  event: "*", // INSERT, UPDATE, DELETE ou *
707
706
  filter: "owner_id=eq.\${USER_ID}",
708
- broadcast: "user_notifications_updated"
707
+ broadcast: "user_notifications_updated",
709
708
  },
710
709
  {
711
- schema: "public",
710
+ schema: "public",
712
711
  table: "user_profiles",
713
712
  event: "*",
714
713
  filter: "owner_id=eq.\${USER_ID}",
715
- broadcast: "user_profile_updated"
716
- }
717
- ]
714
+ broadcast: "user_profile_updated",
715
+ },
716
+ ],
718
717
  },
719
-
718
+
720
719
  pages: [
721
720
  // 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
737
- </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";
721
+ ],
722
+ };`}</pre>
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";
761
750
 
762
751
  function MonComposant() {
763
752
  const signal = useTableRealtime("user_notifications");
764
-
753
+
765
754
  useEffect(() => {
766
755
  if (signal.hasUpdates) {
767
756
  console.log("Nouvelle notification!");
@@ -770,19 +759,16 @@ function MonComposant() {
770
759
  }
771
760
  }, [signal.tick]);
772
761
  }`}</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";
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";
782
768
 
783
769
  function NotificationBell() {
784
770
  const { notifications, loading, hasUpdates } = useNotifications();
785
-
771
+
786
772
  return (
787
773
  <div>
788
774
  🔔 {notifications.length}
@@ -790,19 +776,14 @@ function NotificationBell() {
790
776
  </div>
791
777
  );
792
778
  }`}</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";
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";
802
783
 
803
784
  function MonComposant() {
804
785
  const signal = useRealtimeSignal("user_notifications_updated");
805
-
786
+
806
787
  useEffect(() => {
807
788
  if (signal.hasUpdates) {
808
789
  // Événement spécifique reçu
@@ -811,121 +792,73 @@ function MonComposant() {
811
792
  }
812
793
  }, [signal.tick]);
813
794
  }`}</pre>
814
- </div>
815
- </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>
816
823
  </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>
842
- </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>
852
- </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>
862
- </div>
824
+ <div className="flex items-start gap-2">
825
+ <span>✅ Génération automatique de config</span>
863
826
  </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
- <div className="flex items-start gap-2">
870
- <span className="text-green-600">✅</span>
871
- <span>Configuration déclarative dans les modules</span>
872
- </div>
873
- <div className="flex items-start gap-2">
874
- <span className="text-green-600">✅</span>
875
- <span>Génération automatique de config</span>
876
- </div>
877
- <div className="flex items-start gap-2">
878
- <span className="text-green-600">✅</span>
879
- <span>Hooks React prêts à l'emploi</span>
880
- </div>
881
- <div className="flex items-start gap-2">
882
- <span className="text-green-600">✅</span>
883
- <span>Sécurité RLS de Supabase</span>
884
- </div>
885
- <div className="flex items-start gap-2">
886
- <span className="text-green-600">✅</span>
887
- <span>Scalable pour n'importe quelle table</span>
888
- </div>
889
- <div className="flex items-start gap-2">
890
- <span className="text-green-600">✅</span>
891
- <span>TypeScript avec types générés</span>
892
- </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>
835
+ </div>
836
+ <div className="flex items-start gap-2">
837
+ <span>✅ TypeScript avec types générés</span>
893
838
  </div>
894
839
  </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>
928
- </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>
929
862
  </div>
930
863
  </div>
931
864
  </CardBody>
@@ -939,24 +872,277 @@ function MonComposant() {
939
872
  </h2>
940
873
  </CardHeader>
941
874
  <CardBody className="space-y-4">
942
- <p className="text-slate-600 dark:text-slate-400">
875
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
943
876
  Chaque module peut exporter un composant de documentation qui sera
944
877
  automatiquement intégré dans cette page.
945
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";
946
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" />
947
964
  <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
- :
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.
957
968
  </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() {
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() {
960
1146
  return (
961
1147
  <div>
962
1148
  <h1>Mon Module</h1>
@@ -964,83 +1150,307 @@ function MonComposant() {
964
1150
  </div>
965
1151
  );
966
1152
  }`}</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>
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>
985
1167
  </CardBody>
986
1168
  </Card>
987
1169
 
988
1170
  <Card id="section-links" className="scroll-mt-32">
989
1171
  <CardHeader>
990
1172
  <h2 className="text-2xl font-semibold flex items-center gap-2">
991
- <LinkIcon size={24} />
992
- Liens utiles
1173
+ <Link size={24} />
1174
+ Liens utiles & remerciements 🙏
993
1175
  </h2>
994
1176
  </CardHeader>
995
1177
  <CardBody>
996
- <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
997
- <a
1178
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
1179
+ <Card
1180
+ className="hover:shadow-lg transition-shadow"
1181
+ isPressable
1182
+ as="a"
998
1183
  href="https://nextjs.org/docs"
999
1184
  target="_blank"
1000
1185
  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
1186
  >
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>
1187
+ <CardBody>
1188
+ <h3 className="text-lg font-semibold mb-2">Next.js</h3>
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>
1195
+ </CardBody>
1196
+ </Card>
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
+ >
1205
+ <CardBody>
1206
+ <h3 className="text-lg font-semibold mb-2">Supabase</h3>
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>
1213
+ </CardBody>
1214
+ </Card>
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
+ >
1223
+ <CardBody>
1224
+ <h3 className="text-lg font-semibold mb-2">Heroui</h3>
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>
1231
+ </CardBody>
1232
+ </Card>
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
+ >
1241
+ <CardBody>
1242
+ <h3 className="text-lg font-semibold mb-2">Tailwind CSS</h3>
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>
1249
+ </CardBody>
1250
+ </Card>
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
+ >
1259
+ <CardBody>
1260
+ <h3 className="text-lg font-semibold mb-2">Lucide Icons</h3>
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>
1267
+ </CardBody>
1268
+ </Card>
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
+ >
1277
+ <CardBody>
1278
+ <h3 className="text-lg font-semibold mb-2">Stripe</h3>
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>
1285
+ </CardBody>
1286
+ </Card>
1287
+ </div>
1288
+ </CardBody>
1289
+ </Card>
1008
1290
 
1291
+ <Card id="section-modules" className="scroll-mt-32">
1292
+ <CardHeader>
1293
+ <h2 className="text-2xl font-semibold flex items-center gap-2">
1294
+ <FileText size={24} />
1295
+ Modules
1296
+ </h2>
1297
+ </CardHeader>
1298
+ <CardBody className="space-y-4">
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">
1009
1321
  <a
1010
- href="https://supabase.com/docs"
1322
+ href="../packages/module-ai/README.md"
1323
+ className="text-blue-600 hover:underline"
1011
1324
  target="_blank"
1012
1325
  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
1326
  >
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>
1327
+ 📖 Documentation complète →
1019
1328
  </a>
1020
-
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">
1021
1349
  <a
1022
- href="https://nextui.org/docs"
1350
+ href="../packages/module-auth/README.md"
1351
+ className="text-blue-600 hover:underline"
1023
1352
  target="_blank"
1024
1353
  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
1354
  >
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>
1355
+ 📖 Documentation complète →
1031
1356
  </a>
1032
-
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-tasks](../packages/module-tasks/README.md)
1361
+ </h4>
1362
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1363
+ @lastbrain/module-tasks
1364
+ </p>
1365
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1366
+ <strong>Pages</strong>: 2 auth, 1 admin
1367
+ </p>
1368
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1369
+ <strong>Tables</strong>: tasks, tasks_logs
1370
+ </p>
1371
+ <h4 className="font-medium mb-2">Installation du module tasks</h4>
1372
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
1373
+ {`pnpm lastbrain add-module tasks`}
1374
+ </Snippet>
1375
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1033
1376
  <a
1034
- href="https://tailwindcss.com/docs"
1377
+ href="../packages/module-tasks/README.md"
1378
+ className="text-blue-600 hover:underline"
1379
+ target="_blank"
1380
+ rel="noopener noreferrer"
1381
+ >
1382
+ 📖 Documentation complète →
1383
+ </a>
1384
+ </p>
1385
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">---</p>
1386
+ <h3 className="text-lg font-semibold mb-2">Commandes</h3>
1387
+ <h4 className="font-medium mb-2">Installer un module</h4>
1388
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
1389
+ {`pnpm lastbrain add-module nom-du-module`}
1390
+ </Snippet>
1391
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
1392
+ {`pnpm build:modules`}
1393
+ </Snippet>
1394
+ <h4 className="font-medium mb-2">Créer un nouveau module</h4>
1395
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
1396
+ {`pnpm lastbrain create-module nom-du-module`}
1397
+ </Snippet>
1398
+ <h4 className="font-medium mb-2">
1399
+ Générer la documentation des modules
1400
+ </h4>
1401
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
1402
+ {`pnpm generate:module-docs`}
1403
+ </Snippet>
1404
+ <h4 className="font-medium mb-2">Supprimer un module</h4>
1405
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
1406
+ {`pnpm lastbrain remove-module nom-du-module`}
1407
+ </Snippet>
1408
+ <Snippet symbol="" hideSymbol className="text-sm mb-2">
1409
+ {`pnpm build:modules`}
1410
+ </Snippet>
1411
+ <h3 className="text-lg font-semibold mb-2">
1412
+ Développement de modules
1413
+ </h3>
1414
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1415
+ Pour créer un nouveau module, consultez la{" "}
1416
+ <a
1417
+ href="./004_CREATE_MODULE.md"
1418
+ className="text-blue-600 hover:underline"
1035
1419
  target="_blank"
1036
1420
  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
1421
  >
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>
1422
+ documentation de création de modules
1043
1423
  </a>
1424
+ .
1425
+ </p>
1426
+ <p className="text-sm text-slate-600 dark:text-slate-400 mb-2">
1427
+ La documentation de chaque module est générée automatiquement depuis
1428
+ :
1429
+ </p>
1430
+ <div className="space-y-2">
1431
+ <div className="flex items-start gap-2">
1432
+ <span className="text-green-600">✅</span>
1433
+ <span>
1434
+ Le fichier{" "}
1435
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
1436
+ module-name.build.config.ts
1437
+ </code>{" "}
1438
+ pour les pages et APIs
1439
+ </span>
1440
+ </div>
1441
+ <div className="flex items-start gap-2">
1442
+ <span className="text-green-600">✅</span>
1443
+ <span>Les fichiers de migration SQL pour les tables</span>
1444
+ </div>
1445
+ <div className="flex items-start gap-2">
1446
+ <span className="text-green-600">✅</span>
1447
+ <span>
1448
+ Le README.md est auto-généré avec{" "}
1449
+ <code className="text-sm bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">
1450
+ pnpm generate:module-docs
1451
+ </code>
1452
+ </span>
1453
+ </div>
1044
1454
  </div>
1045
1455
  </CardBody>
1046
1456
  </Card>