@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.
- package/dist/__tests__/module-registry.test.js +5 -16
- package/dist/layouts/AdminLayoutWithSidebar.d.ts.map +1 -1
- package/dist/layouts/AdminLayoutWithSidebar.js +36 -1
- package/dist/layouts/AuthLayoutWithSidebar.d.ts.map +1 -1
- package/dist/layouts/AuthLayoutWithSidebar.js +36 -1
- package/dist/layouts/PublicLayout.js +1 -1
- package/dist/layouts/PublicLayoutWithSidebar.d.ts.map +1 -1
- package/dist/layouts/PublicLayoutWithSidebar.js +36 -1
- package/dist/scripts/init-app.d.ts.map +1 -1
- package/dist/scripts/init-app.js +2 -2
- package/dist/scripts/module-add.d.ts +0 -11
- package/dist/scripts/module-add.d.ts.map +1 -1
- package/dist/scripts/module-add.js +45 -22
- package/dist/scripts/module-build.d.ts.map +1 -1
- package/dist/scripts/module-build.js +90 -1
- package/dist/scripts/module-create.d.ts +23 -0
- package/dist/scripts/module-create.d.ts.map +1 -1
- package/dist/scripts/module-create.js +289 -56
- package/dist/scripts/module-delete.d.ts +6 -0
- package/dist/scripts/module-delete.d.ts.map +1 -0
- package/dist/scripts/module-delete.js +143 -0
- package/dist/scripts/module-list.d.ts.map +1 -1
- package/dist/scripts/module-list.js +2 -2
- package/dist/scripts/module-remove.d.ts.map +1 -1
- package/dist/scripts/module-remove.js +20 -4
- package/dist/styles.css +1 -1
- package/dist/templates/DefaultDoc.d.ts.map +1 -1
- package/dist/templates/DefaultDoc.js +132 -9
- package/dist/templates/DocPage.d.ts.map +1 -1
- package/dist/templates/DocPage.js +24 -7
- package/package.json +4 -4
- package/src/__tests__/module-registry.test.ts +5 -17
- package/src/layouts/AdminLayoutWithSidebar.tsx +51 -1
- package/src/layouts/AuthLayoutWithSidebar.tsx +51 -1
- package/src/layouts/PublicLayout.tsx +1 -1
- package/src/layouts/PublicLayoutWithSidebar.tsx +51 -1
- package/src/scripts/init-app.ts +5 -2
- package/src/scripts/module-add.ts +55 -23
- package/src/scripts/module-build.ts +109 -1
- package/src/scripts/module-create.ts +392 -69
- package/src/scripts/module-delete.ts +202 -0
- package/src/scripts/module-list.ts +9 -2
- package/src/scripts/module-remove.ts +36 -4
- package/src/templates/DefaultDoc.tsx +1149 -424
- 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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
48
|
-
<
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
<
|
|
52
|
-
|
|
53
|
-
</
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
</
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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
|
-
<
|
|
95
|
-
|
|
96
|
-
<
|
|
97
|
-
<
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
</
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
<
|
|
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
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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
|
-
|
|
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
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
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
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
<
|
|
254
|
-
|
|
255
|
-
|
|
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
|
-
|
|
388
|
+
<span>{`set raw_app_meta_data = jsonb_set(
|
|
258
389
|
`}</span>
|
|
259
|
-
|
|
390
|
+
<span>{` coalesce(raw_app_meta_data, '{}'::jsonb),
|
|
260
391
|
`}</span>
|
|
261
|
-
|
|
392
|
+
<span>{` '{roles}',
|
|
262
393
|
`}</span>
|
|
263
|
-
|
|
394
|
+
<span>{` '["admin"]'::jsonb
|
|
264
395
|
`}</span>
|
|
265
|
-
|
|
396
|
+
<span>{`)
|
|
266
397
|
`}</span>
|
|
267
|
-
|
|
398
|
+
<span>{`where email = 'votre@email.com';
|
|
268
399
|
`}</span>
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
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
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
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
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
<
|
|
324
|
-
<
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
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
|
-
<
|
|
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
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
<
|
|
349
|
-
|
|
350
|
-
</
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
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
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
<
|
|
385
|
-
|
|
386
|
-
|
|
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
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
</
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
</
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
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
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
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
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
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
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
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
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
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
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
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
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
<
|
|
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
|
-
<
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
<
|
|
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
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
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
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
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
|
|
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">
|
|
653
|
-
|
|
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
|
|
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">
|
|
660
|
-
|
|
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
|
|
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">
|
|
667
|
-
|
|
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
|
|
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">
|
|
674
|
-
|
|
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
|
|
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">
|
|
681
|
-
|
|
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
|
|
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">
|
|
688
|
-
|
|
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
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
<
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
<
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
<
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
</
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
<
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
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>
|