create-lego-one 2.0.12 → 2.0.13
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/index.cjs +34 -0
- package/dist/index.cjs.map +1 -1
- package/package.json +1 -1
- package/template/.cursor/rules/rules.mdc +639 -0
- package/template/.dockerignore +58 -0
- package/template/.env.example +18 -0
- package/template/.eslintignore +5 -0
- package/template/.eslintrc.js +28 -0
- package/template/.prettierignore +6 -0
- package/template/.prettierrc +11 -0
- package/template/CLAUDE.md +634 -0
- package/template/Dockerfile +67 -0
- package/template/PROMPT.md +457 -0
- package/template/README.md +325 -0
- package/template/docker-compose.yml +48 -0
- package/template/docker-entrypoint.sh +23 -0
- package/template/docs/checkpoints/.template.md +64 -0
- package/template/docs/checkpoints/framework/01-infrastructure-setup.md +132 -0
- package/template/docs/checkpoints/framework/02-pocketbase-setup.md +155 -0
- package/template/docs/checkpoints/framework/03-host-kernel.md +170 -0
- package/template/docs/checkpoints/framework/04-auth-system.md +163 -0
- package/template/docs/checkpoints/framework/phase-05-multitenancy-rbac.md +223 -0
- package/template/docs/checkpoints/framework/phase-06-ui-components.md +260 -0
- package/template/docs/checkpoints/framework/phase-07-communication-system.md +276 -0
- package/template/docs/checkpoints/framework/phase-08-plugin-system.md +91 -0
- package/template/docs/checkpoints/framework/phase-09-dashboard-plugin.md +111 -0
- package/template/docs/checkpoints/framework/phase-10-todo-plugin.md +169 -0
- package/template/docs/checkpoints/framework/phase-11-testing.md +264 -0
- package/template/docs/checkpoints/framework/phase-12-deployment.md +294 -0
- package/template/docs/checkpoints/framework/phase-13-documentation.md +312 -0
- package/template/docs/framework/plans/00-index.md +164 -0
- package/template/docs/framework/plans/01-infrastructure-setup.md +855 -0
- package/template/docs/framework/plans/02-pocketbase-setup.md +1374 -0
- package/template/docs/framework/plans/03-host-kernel.md +1518 -0
- package/template/docs/framework/plans/04-auth-system.md +1466 -0
- package/template/docs/framework/plans/05-multitenancy-rbac.md +1527 -0
- package/template/docs/framework/plans/06-ui-components.md +1478 -0
- package/template/docs/framework/plans/07-communication-system.md +1106 -0
- package/template/docs/framework/plans/08-plugin-system.md +1179 -0
- package/template/docs/framework/plans/09-dashboard-plugin.md +1137 -0
- package/template/docs/framework/plans/10-todo-plugin.md +1343 -0
- package/template/docs/framework/plans/11-testing.md +935 -0
- package/template/docs/framework/plans/12-deployment.md +896 -0
- package/template/docs/framework/prompts/0-boilerplate-modernjs.md +151 -0
- package/template/docs/framework/research/00-modernjs-audit.md +488 -0
- package/template/docs/framework/research/01-system-blueprint.md +721 -0
- package/template/docs/framework/research/02-data-migration-protocol.md +699 -0
- package/template/docs/framework/research/03-host-setup.md +714 -0
- package/template/docs/framework/research/04-plugin-architecture.md +645 -0
- package/template/docs/framework/research/05-slot-injection-pattern.md +671 -0
- package/template/docs/framework/research/06-cli-strategy.md +615 -0
- package/template/docs/framework/research/07-deployment.md +629 -0
- package/template/docs/framework/research/README.md +282 -0
- package/template/docs/framework/setup/00-index.md +210 -0
- package/template/docs/framework/setup/01-framework-structure.md +308 -0
- package/template/docs/framework/setup/02-development-workflow.md +405 -0
- package/template/docs/framework/setup/03-environment-setup.md +215 -0
- package/template/docs/framework/setup/04-kernel-architecture.md +499 -0
- package/template/docs/framework/setup/05-plugin-system.md +620 -0
- package/template/docs/framework/setup/06-communication-patterns.md +451 -0
- package/template/docs/framework/setup/07-plugin-development.md +582 -0
- package/template/docs/framework/setup/08-component-library.md +658 -0
- package/template/docs/framework/setup/09-data-integration.md +609 -0
- package/template/docs/framework/setup/10-auth-rbac.md +497 -0
- package/template/docs/framework/setup/11-hooks-api.md +393 -0
- package/template/docs/framework/setup/12-components-api.md +665 -0
- package/template/docs/framework/setup/13-deployment-guide.md +566 -0
- package/template/docs/framework/setup/README.md +548 -0
- package/template/host/package.json +1 -1
- package/template/nginx.conf +72 -0
- package/template/package.json +1 -1
- package/template/packages/plugins/@lego/plugin-dashboard/package.json +1 -1
- package/template/packages/plugins/@lego/plugin-todo/package.json +1 -1
- package/template/pocketbase/CHANGELOG.md +911 -0
- package/template/pocketbase/LICENSE.md +17 -0
- package/template/scripts/create-plugin.js +221 -0
- package/template/scripts/deploy.sh +56 -0
- package/template/tsconfig.base.json +26 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# Environment Setup
|
|
2
|
+
|
|
3
|
+
**Prerequisites and Configuration**
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
### Required Software
|
|
10
|
+
|
|
11
|
+
| Software | Version | Purpose |
|
|
12
|
+
|----------|---------|---------|
|
|
13
|
+
| **Node.js** | 20+ | Runtime environment |
|
|
14
|
+
| **pnpm** | 9+ | Package manager |
|
|
15
|
+
| **Git** | Latest | Version control |
|
|
16
|
+
| **PocketBase** | 0.22+ | Backend database |
|
|
17
|
+
|
|
18
|
+
### Optional Software
|
|
19
|
+
|
|
20
|
+
| Software | Purpose |
|
|
21
|
+
|----------|---------|
|
|
22
|
+
| **Docker** | Containerized deployment |
|
|
23
|
+
| **Docker Compose** | Multi-container orchestration |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
### Installing Node.js
|
|
30
|
+
|
|
31
|
+
**Download:** https://nodejs.org/
|
|
32
|
+
|
|
33
|
+
**Verify installation:**
|
|
34
|
+
```bash
|
|
35
|
+
node --version # Should be v20+
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Installing pnpm
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install -g pnpm
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Verify installation:**
|
|
45
|
+
```bash
|
|
46
|
+
pnpm --version # Should be 9+
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Installing PocketBase
|
|
50
|
+
|
|
51
|
+
1. **Download:** https://pocketbase.io/docs/
|
|
52
|
+
2. **Extract** to `pocketbase/` directory
|
|
53
|
+
3. **Verify:**
|
|
54
|
+
```bash
|
|
55
|
+
cd pocketbase
|
|
56
|
+
./pocketbase --version
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Project Setup
|
|
62
|
+
|
|
63
|
+
### Clone Repository
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
git clone https://github.com/your-org/lego-one.git
|
|
67
|
+
cd lego-one
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Install Dependencies
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pnpm install
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
This installs dependencies for the host and all plugins.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Environment Variables
|
|
81
|
+
|
|
82
|
+
### Development (.env.development)
|
|
83
|
+
|
|
84
|
+
Create `.env.development`:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# PocketBase (local)
|
|
88
|
+
VITE_POCKETBASE_URL=http://127.0.0.1:8090
|
|
89
|
+
|
|
90
|
+
# Application
|
|
91
|
+
VITE_APP_URL=http://localhost:8080
|
|
92
|
+
VITE_APP_NAME=Lego-One
|
|
93
|
+
|
|
94
|
+
# Features
|
|
95
|
+
VITE_ENABLE_DEV_TOOLS=true
|
|
96
|
+
|
|
97
|
+
# External Services (Optional)
|
|
98
|
+
# VITE_SENTRY_DSN=https://your-sentry-dsn
|
|
99
|
+
# VITE_GA_ID=G-XXXXXXXXXX
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Production (.env.production)
|
|
103
|
+
|
|
104
|
+
Create `.env.production`:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# PocketBase (production)
|
|
108
|
+
VITE_POCKETBASE_URL=https://pb.yourdomain.com
|
|
109
|
+
|
|
110
|
+
# Application
|
|
111
|
+
VITE_APP_URL=https://yourdomain.com
|
|
112
|
+
VITE_APP_NAME=Your App Name
|
|
113
|
+
|
|
114
|
+
# Features
|
|
115
|
+
VITE_ENABLE_DEV_TOOLS=false
|
|
116
|
+
|
|
117
|
+
# External Services (Optional)
|
|
118
|
+
VITE_SENTRY_DSN=https://your-sentry-dsn
|
|
119
|
+
VITE_GA_ID=G-XXXXXXXXXX
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Starting Development
|
|
125
|
+
|
|
126
|
+
### Start PocketBase
|
|
127
|
+
|
|
128
|
+
In a separate terminal:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
cd pocketbase
|
|
132
|
+
./pocketbase serve
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**PocketBase will:**
|
|
136
|
+
- Start on http://127.0.0.1:8090
|
|
137
|
+
- Run migrations automatically
|
|
138
|
+
- Create seed data
|
|
139
|
+
|
|
140
|
+
### Start Application
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Start all services
|
|
144
|
+
pnpm run dev:all
|
|
145
|
+
|
|
146
|
+
# Or start host only
|
|
147
|
+
pnpm run dev:host
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Application URLs:**
|
|
151
|
+
- Host: http://localhost:8080
|
|
152
|
+
- Dashboard: http://localhost:3001
|
|
153
|
+
- Todo: http://localhost:3002
|
|
154
|
+
- PocketBase Admin: http://localhost:8090/_/
|
|
155
|
+
|
|
156
|
+
**Default Credentials:**
|
|
157
|
+
- Email: `admin@example.com`
|
|
158
|
+
- Password: `admin123`
|
|
159
|
+
|
|
160
|
+
⚠️ **Change default credentials in production!**
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## IDE Setup
|
|
165
|
+
|
|
166
|
+
### VS Code
|
|
167
|
+
|
|
168
|
+
**Recommended Extensions:**
|
|
169
|
+
- ESLint
|
|
170
|
+
- Prettier
|
|
171
|
+
- Tailwind CSS IntelliSense
|
|
172
|
+
- TypeScript Vue Plugin (Volar)
|
|
173
|
+
|
|
174
|
+
**Settings (.vscode/settings.json):**
|
|
175
|
+
```json
|
|
176
|
+
{
|
|
177
|
+
"typescript.tsdk": "node_modules/typescript/lib",
|
|
178
|
+
"typescript.enablePromptUseWorkspaceTsdk": true,
|
|
179
|
+
"tailwindCSS.experimental.classRegex": [
|
|
180
|
+
["cn\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
|
|
181
|
+
]
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Troubleshooting
|
|
188
|
+
|
|
189
|
+
### Port Already in Use
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
# Find process on port 8080
|
|
193
|
+
lsof -ti:8080 | xargs kill -9 # macOS/Linux
|
|
194
|
+
netstat -ano | findstr :8080 # Windows
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Dependencies Not Installing
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
# Clear cache and reinstall
|
|
201
|
+
rm -rf node_modules
|
|
202
|
+
rm -rf .cache
|
|
203
|
+
pnpm install
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### PocketBase Not Starting
|
|
207
|
+
|
|
208
|
+
**Solutions:**
|
|
209
|
+
1. Check port 8090 is available
|
|
210
|
+
2. Verify PocketBase binary is executable
|
|
211
|
+
3. Check pocketbase/pb_data/ directory exists
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
**Next:** Read [`04-kernel-architecture.md`](./04-kernel-architecture.md) to understand the kernel system.
|
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
# Kernel Architecture
|
|
2
|
+
|
|
3
|
+
**Host/Kernel System Overview**
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
The Lego-One Host (Kernel) is the core application that provides all shared services, infrastructure, and layout. Plugins load into the host and use its services via the window bridge pattern.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Architecture Diagram
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
┌─────────────────────────────────────────────────────────────────────┐
|
|
17
|
+
│ HOST APPLICATION │
|
|
18
|
+
│ ┌────────────────────────────────────────────────────────────────┐ │
|
|
19
|
+
│ │ LAYER 1: Bootstrap │ │
|
|
20
|
+
│ │ • Garfish initialization │ │
|
|
21
|
+
│ │ • Provider registration (PocketBase, Query, Theme) │ │
|
|
22
|
+
│ │ • Channel bus initialization │ │
|
|
23
|
+
│ │ • Plugin loader initialization │ │
|
|
24
|
+
│ └────────────────────────────────────────────────────────────────┘ │
|
|
25
|
+
│ │ │
|
|
26
|
+
│ ┌────────────────────────────────────────────────────────────────┐ │
|
|
27
|
+
│ │ LAYER 2: Providers │ │
|
|
28
|
+
│ │ • PocketBaseProvider - Backend client │ │
|
|
29
|
+
│ │ • QueryProvider - TanStack Query (server state) │ │
|
|
30
|
+
│ │ • ThemeProvider - Dark mode, CSS variables │ │
|
|
31
|
+
│ │ • SlotProvider - Plugin slot injection system │ │
|
|
32
|
+
│ └────────────────────────────────────────────────────────────────┘ │
|
|
33
|
+
│ │ │
|
|
34
|
+
│ ┌────────────────────────────────────────────────────────────────┐ │
|
|
35
|
+
│ │ LAYER 3: Kernel Services │ │
|
|
36
|
+
│ │ ┌─────────────┬─────────────┬─────────────┬──────────────┐ │ │
|
|
37
|
+
│ │ │ Auth │ RBAC │ Channels │ Plugins │ │ │
|
|
38
|
+
│ │ │ System │ System │ System │ System │ │ │
|
|
39
|
+
│ │ ├─────────────┼─────────────┼─────────────┼──────────────┤ │ │
|
|
40
|
+
│ │ │ Login │ Orgs │ ChannelBus │ PluginStore │ │ │
|
|
41
|
+
│ │ │ Register │ Roles │ Hooks │ PluginLoader │ │ │
|
|
42
|
+
│ │ │ Protected │ Permissions │ Events │ Slots │ │ │
|
|
43
|
+
│ │ │ Routes │ Users │ Integrations│ Registry │ │ │
|
|
44
|
+
│ │ └─────────────┴─────────────┴─────────────┴──────────────┘ │ │
|
|
45
|
+
│ └────────────────────────────────────────────────────────────────┘ │
|
|
46
|
+
│ │ │
|
|
47
|
+
│ ┌────────────────────────────────────────────────────────────────┐ │
|
|
48
|
+
│ │ LAYER 4: Shared State │ │
|
|
49
|
+
│ │ • Zustand store (user, organization, auth state) │ │
|
|
50
|
+
│ │ • Window bridge (for plugin access) │ │
|
|
51
|
+
│ └────────────────────────────────────────────────────────────────┘ │
|
|
52
|
+
│ │ │
|
|
53
|
+
│ ┌────────────────────────────────────────────────────────────────┐ │
|
|
54
|
+
│ │ LAYER 5: Layout Components │ │
|
|
55
|
+
│ │ • Shell (main container) │ │
|
|
56
|
+
│ │ • Sidebar (navigation) │ │
|
|
57
|
+
│ │ • Topbar (header actions) │ │
|
|
58
|
+
│ │ • Slot components (plugin injection points) │ │
|
|
59
|
+
│ └────────────────────────────────────────────────────────────────┘ │
|
|
60
|
+
│ │ │
|
|
61
|
+
│ ┌────────────────────────────────────────────────────────────────┐ │
|
|
62
|
+
│ │ LAYER 6: UI Component Library │ │
|
|
63
|
+
│ │ • Radix UI primitives (Button, Dialog, Dropdown, etc.) │ │
|
|
64
|
+
│ │ • Tailwind CSS styling │ │
|
|
65
|
+
│ │ • Custom components (Toast, Alert, Badge, etc.) │ │
|
|
66
|
+
│ └────────────────────────────────────────────────────────────────┘ │
|
|
67
|
+
│ │ │
|
|
68
|
+
│ ┌────────────────────────────────────────────────────────────────┐ │
|
|
69
|
+
│ │ LAYER 7: Routes (Pages) │ │
|
|
70
|
+
│ │ • Sign in / Sign up │ │
|
|
71
|
+
│ │ • Dashboard │ │
|
|
72
|
+
│ │ • Settings │ │
|
|
73
|
+
│ │ • Plugin routes (injected by plugins) │ │
|
|
74
|
+
│ └────────────────────────────────────────────────────────────────┘ │
|
|
75
|
+
└─────────────────────────────────────────────────────────────────────┘
|
|
76
|
+
│
|
|
77
|
+
═══════════════════════════════
|
|
78
|
+
GARFISH PLUGIN BOUNDARY
|
|
79
|
+
═══════════════════════════════
|
|
80
|
+
│
|
|
81
|
+
┌─────────────────────────────────────────────────────────────────────┐
|
|
82
|
+
│ PLUGINS (Applications) │
|
|
83
|
+
│ ┌──────────────┬──────────────┬──────────────┬──────────────┐ │
|
|
84
|
+
│ │ Dashboard │ Todo │ Plugin C │ Plugin D │ │
|
|
85
|
+
│ │ Plugin │ Plugin │ │ │ │
|
|
86
|
+
│ ├──────────────┼──────────────┼──────────────┼──────────────┤ │
|
|
87
|
+
│ │ Statistics │ CRUD UI │ Custom │ Custom │ │
|
|
88
|
+
│ │ Activity │ Forms │ Feature │ Feature │ │
|
|
89
|
+
│ │ Quick Actions│ Filtering │ │ │ │
|
|
90
|
+
│ └──────────────┴──────────────┴──────────────┴──────────────┘ │
|
|
91
|
+
└─────────────────────────────────────────────────────────────────────┘
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Directory Structure
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
host/src/
|
|
100
|
+
├── bootstrap.tsx # App initialization, provider setup
|
|
101
|
+
├── App.tsx # Root component with routing
|
|
102
|
+
├── modern.config.ts # Modern.js configuration
|
|
103
|
+
├── modern.runtime.ts # Garfish plugin registration
|
|
104
|
+
├── saas.config.ts # Plugin enable/disable config
|
|
105
|
+
│
|
|
106
|
+
├── kernel/ # CORE KERNEL SYSTEMS
|
|
107
|
+
│ ├── index.ts # Kernel exports
|
|
108
|
+
│ │
|
|
109
|
+
│ ├── shared-state/ # Global state management
|
|
110
|
+
│ │ ├── store.ts # Zustand global store
|
|
111
|
+
│ │ └── bridge.ts # Window bridge registration
|
|
112
|
+
│ │
|
|
113
|
+
│ ├── providers/ # React Context providers
|
|
114
|
+
│ │ ├── PocketBaseProvider.tsx
|
|
115
|
+
│ │ ├── QueryProvider.tsx
|
|
116
|
+
│ │ └── ThemeProvider.tsx
|
|
117
|
+
│ │
|
|
118
|
+
│ ├── auth/ # Authentication system
|
|
119
|
+
│ │ ├── types.ts
|
|
120
|
+
│ │ ├── hooks.ts
|
|
121
|
+
│ │ ├── components/
|
|
122
|
+
│ │ └── index.ts
|
|
123
|
+
│ │
|
|
124
|
+
│ ├── rbac/ # Multi-tenancy & RBAC
|
|
125
|
+
│ │ ├── types.ts
|
|
126
|
+
│ │ ├── service.ts
|
|
127
|
+
│ │ ├── hooks.ts
|
|
128
|
+
│ │ ├── components/
|
|
129
|
+
│ │ └── index.ts
|
|
130
|
+
│ │
|
|
131
|
+
│ ├── channels/ # Inter-plugin communication
|
|
132
|
+
│ │ ├── types.ts
|
|
133
|
+
│ │ ├── events.ts
|
|
134
|
+
│ │ ├── ChannelBus.ts
|
|
135
|
+
│ │ ├── hooks.ts
|
|
136
|
+
│ │ ├── ChannelProvider.tsx
|
|
137
|
+
│ │ └── index.ts
|
|
138
|
+
│ │
|
|
139
|
+
│ ├── plugins/ # Plugin system
|
|
140
|
+
│ │ ├── types.ts
|
|
141
|
+
│ │ ├── schemas.ts
|
|
142
|
+
│ │ ├── store.ts
|
|
143
|
+
│ │ ├── loader.ts
|
|
144
|
+
│ │ ├── Slot.tsx
|
|
145
|
+
│ │ ├── SlotProvider.tsx
|
|
146
|
+
│ │ └── index.ts
|
|
147
|
+
│ │
|
|
148
|
+
│ ├── components/ # Shared UI components
|
|
149
|
+
│ │ ├── ui/ # Radix UI primitives
|
|
150
|
+
│ │ └── index.ts
|
|
151
|
+
│ │
|
|
152
|
+
│ └── lib/ # Utilities
|
|
153
|
+
│ ├── utils.ts # Helper functions
|
|
154
|
+
│ └── cn.ts # Class name merger
|
|
155
|
+
│
|
|
156
|
+
├── layout/ # Layout components
|
|
157
|
+
│ ├── Shell.tsx # Main app shell
|
|
158
|
+
│ ├── Sidebar.tsx # Left navigation
|
|
159
|
+
│ └── Topbar.tsx # Header
|
|
160
|
+
│
|
|
161
|
+
├── routes/ # Page components
|
|
162
|
+
│ ├── SignIn.tsx
|
|
163
|
+
│ ├── SignUp.tsx
|
|
164
|
+
│ ├── Dashboard.tsx
|
|
165
|
+
│ └── Settings/
|
|
166
|
+
│
|
|
167
|
+
└── test/ # Test setup
|
|
168
|
+
├── setup.ts
|
|
169
|
+
└── utils.tsx
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Core Systems
|
|
175
|
+
|
|
176
|
+
### 1. Shared State (Zustand)
|
|
177
|
+
|
|
178
|
+
**Location:** `host/src/kernel/shared-state/`
|
|
179
|
+
|
|
180
|
+
**Purpose:** Global state accessible by host and plugins via window bridge
|
|
181
|
+
|
|
182
|
+
**State includes:**
|
|
183
|
+
- `user` - Current authenticated user
|
|
184
|
+
- `organization` - Current selected organization
|
|
185
|
+
- `token` - Authentication token
|
|
186
|
+
- `isAuthenticated` - Auth status flag
|
|
187
|
+
- `sidebarOpen` - Sidebar toggle state
|
|
188
|
+
- `mobileMenuOpen` - Mobile menu state
|
|
189
|
+
|
|
190
|
+
**Window Bridge:**
|
|
191
|
+
```typescript
|
|
192
|
+
// Plugins can access kernel state:
|
|
193
|
+
window.__LEGO_KERNEL_STATE__?.useGlobalKernelState?.getState()
|
|
194
|
+
|
|
195
|
+
// Returns: { user, organization, token, isAuthenticated, ... }
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
### 2. Authentication System
|
|
201
|
+
|
|
202
|
+
**Location:** `host/src/kernel/auth/`
|
|
203
|
+
|
|
204
|
+
**Features:**
|
|
205
|
+
- Email/password authentication via PocketBase
|
|
206
|
+
- Protected routes (redirects if not authenticated)
|
|
207
|
+
- Token persistence (localStorage)
|
|
208
|
+
- Auto-logout on token expiration
|
|
209
|
+
|
|
210
|
+
**Key Hooks:**
|
|
211
|
+
```typescript
|
|
212
|
+
const { user, isAuthenticated, login, logout } = useAuth();
|
|
213
|
+
|
|
214
|
+
// Protected route hook
|
|
215
|
+
useRequireAuth(); // Redirects to /sign-in if not authenticated
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**PocketBase Integration:**
|
|
219
|
+
- Uses PocketBase auth store
|
|
220
|
+
- Collection: `users`
|
|
221
|
+
- Token stored in: `localStorage` key `pocketbase_auth`
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
### 3. RBAC System (Multi-Tenancy)
|
|
226
|
+
|
|
227
|
+
**Location:** `host/src/kernel/rbac/`
|
|
228
|
+
|
|
229
|
+
**PocketBase Collections:**
|
|
230
|
+
- `organizations` - Tenant data isolation
|
|
231
|
+
- `roles` - System and custom roles
|
|
232
|
+
- `permissions` - Granular permissions
|
|
233
|
+
- `user_roles` - User-role assignments for orgs
|
|
234
|
+
|
|
235
|
+
**System Roles:**
|
|
236
|
+
| Role | Permissions |
|
|
237
|
+
|------|-------------|
|
|
238
|
+
| `Owner` | Full access (all:all) |
|
|
239
|
+
| `Admin` | Users, roles, todos, settings |
|
|
240
|
+
| `Member` | Todos, read-only access |
|
|
241
|
+
| `Guest` | Read-only todos |
|
|
242
|
+
|
|
243
|
+
**Key Hooks:**
|
|
244
|
+
```typescript
|
|
245
|
+
// Organization management
|
|
246
|
+
const { organization, setCurrentOrganization } = useCurrentOrganization();
|
|
247
|
+
const { data: organizations } = useOrganizations();
|
|
248
|
+
|
|
249
|
+
// Permission checking
|
|
250
|
+
const checkPermission = useHasPermission();
|
|
251
|
+
const allowed = await checkPermission('todos', 'write');
|
|
252
|
+
|
|
253
|
+
// Get user's permissions
|
|
254
|
+
const { data: permissions } = useUserPermissions();
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**Data Isolation:**
|
|
258
|
+
```typescript
|
|
259
|
+
// All data queries MUST filter by organization
|
|
260
|
+
pb.collection('todos').getList(1, 50, {
|
|
261
|
+
filter: `organizationId = "${orgId}"`,
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
### 4. Channel System (Communication)
|
|
268
|
+
|
|
269
|
+
**Location:** `host/src/kernel/channels/`
|
|
270
|
+
|
|
271
|
+
**Purpose:** Pub/sub messaging between plugins and host
|
|
272
|
+
|
|
273
|
+
**Channels:**
|
|
274
|
+
```typescript
|
|
275
|
+
enum ChannelName {
|
|
276
|
+
TOAST = 'lego:toast', // Show notifications
|
|
277
|
+
NAVIGATION = 'lego:navigation', // Navigate routes
|
|
278
|
+
STATE_UPDATE = 'lego:state:update',
|
|
279
|
+
PLUGIN_READY = 'lego:plugin:ready',
|
|
280
|
+
PLUGIN_ERROR = 'lego:plugin:error',
|
|
281
|
+
AUTH_CHANGE = 'lego:auth:change',
|
|
282
|
+
ORGANIZATION_CHANGE = 'lego:organization:change',
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
**Usage in Plugins:**
|
|
287
|
+
```typescript
|
|
288
|
+
// Publish toast notification
|
|
289
|
+
window.__LEGO_CHANNEL_BUS__?.publish('lego:toast', {
|
|
290
|
+
type: 'success',
|
|
291
|
+
title: 'Saved!',
|
|
292
|
+
description: 'Your changes were saved',
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
// Subscribe to auth changes
|
|
296
|
+
const unsubscribe = window.__LEGO_CHANNEL_BUS__?.subscribe(
|
|
297
|
+
'lego:auth:change',
|
|
298
|
+
(data) => console.log('Auth changed:', data)
|
|
299
|
+
);
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
**Hooks (for host components):**
|
|
303
|
+
```typescript
|
|
304
|
+
const publishToast = useToastChannel();
|
|
305
|
+
publishToast({ type: 'success', title: 'Done!' });
|
|
306
|
+
|
|
307
|
+
const publish = usePublish();
|
|
308
|
+
publish({ channel: ChannelName.TOAST, data: {...} });
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
### 5. Plugin System
|
|
314
|
+
|
|
315
|
+
**Location:** `host/src/kernel/plugins/`
|
|
316
|
+
|
|
317
|
+
**Features:**
|
|
318
|
+
- Dynamic plugin loading via Garfish
|
|
319
|
+
- Slot injection system (inject UI into sidebar, topbar, etc.)
|
|
320
|
+
- Plugin enable/disable via config
|
|
321
|
+
- Plugin state management (Zustand store)
|
|
322
|
+
|
|
323
|
+
**Plugin Config:**
|
|
324
|
+
```typescript
|
|
325
|
+
// In: host/src/saas.config.ts
|
|
326
|
+
export const saasConfig = {
|
|
327
|
+
plugins: [
|
|
328
|
+
{ name: '@lego/plugin-dashboard', enabled: true },
|
|
329
|
+
{ name: '@lego/plugin-todo', enabled: true },
|
|
330
|
+
],
|
|
331
|
+
};
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
**Available Slots:**
|
|
335
|
+
| Slot | Location | Purpose |
|
|
336
|
+
|------|----------|---------|
|
|
337
|
+
| `sidebar:top` | Top of sidebar | Logo, user menu |
|
|
338
|
+
| `sidebar:nav` | Main navigation | Plugin navigation links |
|
|
339
|
+
| `sidebar:bottom` | Bottom of sidebar | Logout, settings |
|
|
340
|
+
| `topbar:left` | Left side | Breadcrumbs |
|
|
341
|
+
| `topbar:center` | Center | Page title |
|
|
342
|
+
| `topbar:right` | Right side | Notifications |
|
|
343
|
+
| `dashboard:widgets` | Dashboard | Statistics cards |
|
|
344
|
+
|
|
345
|
+
**Slot Usage in Plugin:**
|
|
346
|
+
```typescript
|
|
347
|
+
// In plugin.config.ts
|
|
348
|
+
export const pluginConfig = {
|
|
349
|
+
slots: [
|
|
350
|
+
{
|
|
351
|
+
slot: 'sidebar:nav',
|
|
352
|
+
component: () => import('./SidebarWidget').then(m => m.default),
|
|
353
|
+
order: 100,
|
|
354
|
+
},
|
|
355
|
+
],
|
|
356
|
+
};
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
**Plugin Store:**
|
|
360
|
+
```typescript
|
|
361
|
+
// Get all plugins
|
|
362
|
+
const plugins = usePluginStore((state) => state.plugins);
|
|
363
|
+
|
|
364
|
+
// Enable/disable plugin
|
|
365
|
+
const { enablePlugin, disablePlugin } = usePluginStore();
|
|
366
|
+
enablePlugin('@lego/plugin-dashboard');
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## Providers Stack
|
|
372
|
+
|
|
373
|
+
**Order matters!** From outer to inner:
|
|
374
|
+
|
|
375
|
+
```typescript
|
|
376
|
+
<BrowserRouter>
|
|
377
|
+
<ThemeProvider>
|
|
378
|
+
<QueryProvider>
|
|
379
|
+
<PocketBaseProvider>
|
|
380
|
+
<SlotProvider>
|
|
381
|
+
<ChannelProvider>
|
|
382
|
+
<App />
|
|
383
|
+
<Toaster />
|
|
384
|
+
</ChannelProvider>
|
|
385
|
+
</SlotProvider>
|
|
386
|
+
</PocketBaseProvider>
|
|
387
|
+
</QueryProvider>
|
|
388
|
+
</ThemeProvider>
|
|
389
|
+
</BrowserRouter>
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
**Each provider:**
|
|
393
|
+
|
|
394
|
+
| Provider | Purpose |
|
|
395
|
+
|----------|---------|
|
|
396
|
+
| `BrowserRouter` | React Router v6 routing |
|
|
397
|
+
| `ThemeProvider` | Dark mode, CSS variables |
|
|
398
|
+
| `QueryProvider` | TanStack Query for server state |
|
|
399
|
+
| `PocketBaseProvider` | Backend client, auth persistence |
|
|
400
|
+
| `SlotProvider` | Plugin slot injection context |
|
|
401
|
+
| `ChannelProvider` | Channel bus integrations (toast, etc.) |
|
|
402
|
+
| `Toaster` | Shadcn toast notifications |
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
## Development vs Production Mode
|
|
407
|
+
|
|
408
|
+
### Development Mode
|
|
409
|
+
```bash
|
|
410
|
+
pnpm run dev:all
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
- Each plugin runs on **separate dev server**
|
|
414
|
+
- Host: `http://localhost:8080`
|
|
415
|
+
- Dashboard: `http://localhost:3001`
|
|
416
|
+
- Todo: `http://localhost:3002`
|
|
417
|
+
- **Hot Module Replacement (HMR)** enabled
|
|
418
|
+
- Source maps available
|
|
419
|
+
- Independent plugin debugging
|
|
420
|
+
|
|
421
|
+
### Production Mode
|
|
422
|
+
```bash
|
|
423
|
+
pnpm run build
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
- All plugins **bundled into host**
|
|
427
|
+
- Code-split by route
|
|
428
|
+
- Single deployment artifact
|
|
429
|
+
- Minified and optimized
|
|
430
|
+
|
|
431
|
+
---
|
|
432
|
+
|
|
433
|
+
## Garfish Integration
|
|
434
|
+
|
|
435
|
+
**Plugin Registration:** `host/src/modern.runtime.ts`
|
|
436
|
+
|
|
437
|
+
```typescript
|
|
438
|
+
export default defineRuntimeConfig({
|
|
439
|
+
masterApp: {
|
|
440
|
+
apps: [
|
|
441
|
+
{
|
|
442
|
+
name: '@lego/plugin-dashboard',
|
|
443
|
+
entry: isDev
|
|
444
|
+
? 'http://localhost:3001' // Dev: separate server
|
|
445
|
+
: () => import('@lego/plugin-dashboard'), // Prod: bundle
|
|
446
|
+
activeWhen: '/dashboard',
|
|
447
|
+
},
|
|
448
|
+
{
|
|
449
|
+
name: '@lego/plugin-todo',
|
|
450
|
+
entry: isDev
|
|
451
|
+
? 'http://localhost:3002'
|
|
452
|
+
: () => import('@lego/plugin-todo'),
|
|
453
|
+
activeWhen: '/todos',
|
|
454
|
+
},
|
|
455
|
+
],
|
|
456
|
+
},
|
|
457
|
+
});
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
462
|
+
## Best Practices for AI
|
|
463
|
+
|
|
464
|
+
**When working with Kernel code:**
|
|
465
|
+
|
|
466
|
+
1. **DO** modify kernel code when:
|
|
467
|
+
- Adding new shared services
|
|
468
|
+
- Fixing kernel bugs
|
|
469
|
+
- Implementing framework features
|
|
470
|
+
- User explicitly requests kernel changes
|
|
471
|
+
|
|
472
|
+
2. **DO NOT** modify kernel code when:
|
|
473
|
+
- Working on application-specific features
|
|
474
|
+
- Adding plugin business logic
|
|
475
|
+
- Implementing custom UI (use plugins instead)
|
|
476
|
+
|
|
477
|
+
3. **FOLLOW these patterns:**
|
|
478
|
+
- Use Zod for validation schemas
|
|
479
|
+
- Use TanStack Query for data fetching
|
|
480
|
+
- Use Zustand for state management
|
|
481
|
+
- Export barrel index files
|
|
482
|
+
- Add TypeScript types for all interfaces
|
|
483
|
+
|
|
484
|
+
4. **TESTING:**
|
|
485
|
+
- Unit tests in `__tests__/` folders
|
|
486
|
+
- Component tests for UI
|
|
487
|
+
- Mock PocketBase in tests
|
|
488
|
+
- Test multi-tenancy (org isolation)
|
|
489
|
+
|
|
490
|
+
5. **NAMING CONVENTIONS:**
|
|
491
|
+
- Files: `PascalCase.ts` for types/components, `kebab-case` for utilities
|
|
492
|
+
- Hooks: `useXxx.ts`
|
|
493
|
+
- Types: `Xxx`, `XxxType`, `XxxProps`, `XxxData`
|
|
494
|
+
- Constants: `UPPER_SNAKE_CASE`
|
|
495
|
+
- Interfaces: `PascalCase`
|
|
496
|
+
|
|
497
|
+
---
|
|
498
|
+
|
|
499
|
+
**Next:** Read [`05-plugin-system.md`](./05-plugin-system.md) for plugin architecture details.
|