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