create-lego-one 2.0.10 → 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.
Files changed (242) hide show
  1. package/dist/index.cjs +179 -0
  2. package/dist/index.cjs.map +1 -1
  3. package/package.json +5 -3
  4. package/template/.cursor/rules/rules.mdc +639 -0
  5. package/template/.dockerignore +58 -0
  6. package/template/.env.example +18 -0
  7. package/template/.eslintignore +5 -0
  8. package/template/.eslintrc.js +28 -0
  9. package/template/.prettierignore +6 -0
  10. package/template/.prettierrc +11 -0
  11. package/template/CLAUDE.md +634 -0
  12. package/template/Dockerfile +67 -0
  13. package/template/PROMPT.md +457 -0
  14. package/template/README.md +325 -0
  15. package/template/docker-compose.yml +48 -0
  16. package/template/docker-entrypoint.sh +23 -0
  17. package/template/docs/checkpoints/.template.md +64 -0
  18. package/template/docs/checkpoints/framework/01-infrastructure-setup.md +132 -0
  19. package/template/docs/checkpoints/framework/02-pocketbase-setup.md +155 -0
  20. package/template/docs/checkpoints/framework/03-host-kernel.md +170 -0
  21. package/template/docs/checkpoints/framework/04-auth-system.md +163 -0
  22. package/template/docs/checkpoints/framework/phase-05-multitenancy-rbac.md +223 -0
  23. package/template/docs/checkpoints/framework/phase-06-ui-components.md +260 -0
  24. package/template/docs/checkpoints/framework/phase-07-communication-system.md +276 -0
  25. package/template/docs/checkpoints/framework/phase-08-plugin-system.md +91 -0
  26. package/template/docs/checkpoints/framework/phase-09-dashboard-plugin.md +111 -0
  27. package/template/docs/checkpoints/framework/phase-10-todo-plugin.md +169 -0
  28. package/template/docs/checkpoints/framework/phase-11-testing.md +264 -0
  29. package/template/docs/checkpoints/framework/phase-12-deployment.md +294 -0
  30. package/template/docs/checkpoints/framework/phase-13-documentation.md +312 -0
  31. package/template/docs/framework/plans/00-index.md +164 -0
  32. package/template/docs/framework/plans/01-infrastructure-setup.md +855 -0
  33. package/template/docs/framework/plans/02-pocketbase-setup.md +1374 -0
  34. package/template/docs/framework/plans/03-host-kernel.md +1518 -0
  35. package/template/docs/framework/plans/04-auth-system.md +1466 -0
  36. package/template/docs/framework/plans/05-multitenancy-rbac.md +1527 -0
  37. package/template/docs/framework/plans/06-ui-components.md +1478 -0
  38. package/template/docs/framework/plans/07-communication-system.md +1106 -0
  39. package/template/docs/framework/plans/08-plugin-system.md +1179 -0
  40. package/template/docs/framework/plans/09-dashboard-plugin.md +1137 -0
  41. package/template/docs/framework/plans/10-todo-plugin.md +1343 -0
  42. package/template/docs/framework/plans/11-testing.md +935 -0
  43. package/template/docs/framework/plans/12-deployment.md +896 -0
  44. package/template/docs/framework/prompts/0-boilerplate-modernjs.md +151 -0
  45. package/template/docs/framework/research/00-modernjs-audit.md +488 -0
  46. package/template/docs/framework/research/01-system-blueprint.md +721 -0
  47. package/template/docs/framework/research/02-data-migration-protocol.md +699 -0
  48. package/template/docs/framework/research/03-host-setup.md +714 -0
  49. package/template/docs/framework/research/04-plugin-architecture.md +645 -0
  50. package/template/docs/framework/research/05-slot-injection-pattern.md +671 -0
  51. package/template/docs/framework/research/06-cli-strategy.md +615 -0
  52. package/template/docs/framework/research/07-deployment.md +629 -0
  53. package/template/docs/framework/research/README.md +282 -0
  54. package/template/docs/framework/setup/00-index.md +210 -0
  55. package/template/docs/framework/setup/01-framework-structure.md +308 -0
  56. package/template/docs/framework/setup/02-development-workflow.md +405 -0
  57. package/template/docs/framework/setup/03-environment-setup.md +215 -0
  58. package/template/docs/framework/setup/04-kernel-architecture.md +499 -0
  59. package/template/docs/framework/setup/05-plugin-system.md +620 -0
  60. package/template/docs/framework/setup/06-communication-patterns.md +451 -0
  61. package/template/docs/framework/setup/07-plugin-development.md +582 -0
  62. package/template/docs/framework/setup/08-component-library.md +658 -0
  63. package/template/docs/framework/setup/09-data-integration.md +609 -0
  64. package/template/docs/framework/setup/10-auth-rbac.md +497 -0
  65. package/template/docs/framework/setup/11-hooks-api.md +393 -0
  66. package/template/docs/framework/setup/12-components-api.md +665 -0
  67. package/template/docs/framework/setup/13-deployment-guide.md +566 -0
  68. package/template/docs/framework/setup/README.md +548 -0
  69. package/template/host/e2e/auth.spec.ts +38 -0
  70. package/template/host/e2e/layout.spec.ts +38 -0
  71. package/template/host/modern.config.ts +19 -0
  72. package/template/host/package.json +71 -0
  73. package/template/host/playwright.config.ts +34 -0
  74. package/template/host/postcss.config.mjs +6 -0
  75. package/template/host/src/App.tsx +6 -0
  76. package/template/host/src/bootstrap.tsx +74 -0
  77. package/template/host/src/global.css +59 -0
  78. package/template/host/src/index.ts +2 -0
  79. package/template/host/src/kernel/__tests__/lib-utils.test.ts +32 -0
  80. package/template/host/src/kernel/__tests__/rbac-hooks.test.tsx +114 -0
  81. package/template/host/src/kernel/__tests__/rbac-utils.test.ts +108 -0
  82. package/template/host/src/kernel/auth/ProtectedRoute.tsx +41 -0
  83. package/template/host/src/kernel/auth/components/LoginForm.tsx +97 -0
  84. package/template/host/src/kernel/auth/components/LogoutButton.tsx +79 -0
  85. package/template/host/src/kernel/auth/hooks.ts +174 -0
  86. package/template/host/src/kernel/auth/index.ts +5 -0
  87. package/template/host/src/kernel/auth/schemas.ts +27 -0
  88. package/template/host/src/kernel/auth/service.ts +197 -0
  89. package/template/host/src/kernel/auth/types.ts +36 -0
  90. package/template/host/src/kernel/channels/ChannelBus.ts +181 -0
  91. package/template/host/src/kernel/channels/ChannelProvider.tsx +57 -0
  92. package/template/host/src/kernel/channels/events.ts +27 -0
  93. package/template/host/src/kernel/channels/hooks.ts +168 -0
  94. package/template/host/src/kernel/channels/index.ts +6 -0
  95. package/template/host/src/kernel/channels/integrations/ToastIntegration.tsx +60 -0
  96. package/template/host/src/kernel/channels/plugin-hooks.ts +72 -0
  97. package/template/host/src/kernel/channels/types.ts +112 -0
  98. package/template/host/src/kernel/components/__tests__/Badge.test.tsx +35 -0
  99. package/template/host/src/kernel/components/__tests__/Button.test.tsx +63 -0
  100. package/template/host/src/kernel/components/__tests__/Input.test.tsx +64 -0
  101. package/template/host/src/kernel/components/index.ts +32 -0
  102. package/template/host/src/kernel/components/ui/alert.tsx +58 -0
  103. package/template/host/src/kernel/components/ui/avatar.tsx +47 -0
  104. package/template/host/src/kernel/components/ui/badge.tsx +35 -0
  105. package/template/host/src/kernel/components/ui/button.tsx +50 -0
  106. package/template/host/src/kernel/components/ui/card.tsx +78 -0
  107. package/template/host/src/kernel/components/ui/dialog.tsx +116 -0
  108. package/template/host/src/kernel/components/ui/dropdown-menu.tsx +192 -0
  109. package/template/host/src/kernel/components/ui/index.ts +7 -0
  110. package/template/host/src/kernel/components/ui/input.tsx +24 -0
  111. package/template/host/src/kernel/components/ui/label.tsx +21 -0
  112. package/template/host/src/kernel/components/ui/popover.tsx +28 -0
  113. package/template/host/src/kernel/components/ui/progress.tsx +25 -0
  114. package/template/host/src/kernel/components/ui/scroll-area.tsx +45 -0
  115. package/template/host/src/kernel/components/ui/select.tsx +155 -0
  116. package/template/host/src/kernel/components/ui/separator.tsx +28 -0
  117. package/template/host/src/kernel/components/ui/skeleton.tsx +15 -0
  118. package/template/host/src/kernel/components/ui/switch.tsx +26 -0
  119. package/template/host/src/kernel/components/ui/table.tsx +116 -0
  120. package/template/host/src/kernel/components/ui/tabs.tsx +52 -0
  121. package/template/host/src/kernel/components/ui/toast.tsx +126 -0
  122. package/template/host/src/kernel/components/ui/toaster.tsx +34 -0
  123. package/template/host/src/kernel/components/ui/tooltip.tsx +27 -0
  124. package/template/host/src/kernel/components/ui/use-toast.ts +183 -0
  125. package/template/host/src/kernel/index.ts +48 -0
  126. package/template/host/src/kernel/lib/cn.ts +1 -0
  127. package/template/host/src/kernel/lib/utils.ts +36 -0
  128. package/template/host/src/kernel/plugins/Slot.tsx +41 -0
  129. package/template/host/src/kernel/plugins/SlotProvider.tsx +88 -0
  130. package/template/host/src/kernel/plugins/index.ts +23 -0
  131. package/template/host/src/kernel/plugins/loader.ts +122 -0
  132. package/template/host/src/kernel/plugins/schemas.ts +54 -0
  133. package/template/host/src/kernel/plugins/store.ts +185 -0
  134. package/template/host/src/kernel/plugins/types.ts +103 -0
  135. package/template/host/src/kernel/providers/PocketBaseProvider.tsx +70 -0
  136. package/template/host/src/kernel/providers/QueryProvider.tsx +28 -0
  137. package/template/host/src/kernel/providers/ThemeProvider.tsx +25 -0
  138. package/template/host/src/kernel/providers/index.ts +3 -0
  139. package/template/host/src/kernel/rbac/components/OrganizationSelector.tsx +69 -0
  140. package/template/host/src/kernel/rbac/components/PermissionGate.tsx +43 -0
  141. package/template/host/src/kernel/rbac/hooks.ts +379 -0
  142. package/template/host/src/kernel/rbac/index.ts +6 -0
  143. package/template/host/src/kernel/rbac/service.ts +504 -0
  144. package/template/host/src/kernel/rbac/types.ts +164 -0
  145. package/template/host/src/kernel/rbac/utils.ts +34 -0
  146. package/template/host/src/kernel/shared-state/bridge.ts +31 -0
  147. package/template/host/src/kernel/shared-state/index.ts +3 -0
  148. package/template/host/src/kernel/shared-state/store.ts +62 -0
  149. package/template/host/src/kernel/shared-state/types.ts +60 -0
  150. package/template/host/src/kernel/use-migrations.ts +72 -0
  151. package/template/host/src/layout/MobileMenu.tsx +61 -0
  152. package/template/host/src/layout/Shell.tsx +42 -0
  153. package/template/host/src/layout/Sidebar.tsx +178 -0
  154. package/template/host/src/layout/Topbar.tsx +50 -0
  155. package/template/host/src/layout/index.ts +4 -0
  156. package/template/host/src/lib/pocketbase/client.ts +38 -0
  157. package/template/host/src/lib/pocketbase/collections/audit_logs.ts +87 -0
  158. package/template/host/src/lib/pocketbase/collections/index.ts +19 -0
  159. package/template/host/src/lib/pocketbase/collections/organizations.ts +63 -0
  160. package/template/host/src/lib/pocketbase/collections/permissions.ts +57 -0
  161. package/template/host/src/lib/pocketbase/collections/roles.ts +55 -0
  162. package/template/host/src/lib/pocketbase/collections/todos.ts +74 -0
  163. package/template/host/src/lib/pocketbase/collections/user_roles.ts +57 -0
  164. package/template/host/src/lib/pocketbase/collections/users.ts +43 -0
  165. package/template/host/src/lib/pocketbase/index.ts +5 -0
  166. package/template/host/src/lib/pocketbase/migrations.ts +44 -0
  167. package/template/host/src/lib/pocketbase/seed/permissions.ts +8 -0
  168. package/template/host/src/lib/pocketbase/seed/roles.ts +22 -0
  169. package/template/host/src/lib/pocketbase/seed.ts +113 -0
  170. package/template/host/src/lib/pocketbase/types.ts +102 -0
  171. package/template/host/src/modern.runtime.ts +26 -0
  172. package/template/host/src/plugins.d.ts +9 -0
  173. package/template/host/src/providers/PocketBaseProvider.tsx +30 -0
  174. package/template/host/src/routes/_.tsx +6 -0
  175. package/template/host/src/routes/dashboard._.tsx +41 -0
  176. package/template/host/src/routes/index.tsx +93 -0
  177. package/template/host/src/routes/login.tsx +36 -0
  178. package/template/host/src/saas.config.ts +52 -0
  179. package/template/host/src/test/setup.ts +65 -0
  180. package/template/host/src/test/utils.tsx +69 -0
  181. package/template/host/src/test/vitest-globals.d.ts +19 -0
  182. package/template/host/src/vite-env.d.ts +16 -0
  183. package/template/host/tailwind.config.ts +77 -0
  184. package/template/host/tsconfig.json +19 -0
  185. package/template/host/vitest.config.ts +30 -0
  186. package/template/nginx.conf +72 -0
  187. package/template/package.json +44 -0
  188. package/template/packages/plugins/@lego/plugin-dashboard/modern.config.ts +19 -0
  189. package/template/packages/plugins/@lego/plugin-dashboard/package.json +35 -0
  190. package/template/packages/plugins/@lego/plugin-dashboard/postcss.config.mjs +6 -0
  191. package/template/packages/plugins/@lego/plugin-dashboard/src/App.tsx +27 -0
  192. package/template/packages/plugins/@lego/plugin-dashboard/src/components/ActivityFeed.tsx +63 -0
  193. package/template/packages/plugins/@lego/plugin-dashboard/src/components/QuickActionSlot.tsx +11 -0
  194. package/template/packages/plugins/@lego/plugin-dashboard/src/components/QuickActions.tsx +68 -0
  195. package/template/packages/plugins/@lego/plugin-dashboard/src/components/SidebarWidget.tsx +35 -0
  196. package/template/packages/plugins/@lego/plugin-dashboard/src/components/StatCard.tsx +47 -0
  197. package/template/packages/plugins/@lego/plugin-dashboard/src/global.css +24 -0
  198. package/template/packages/plugins/@lego/plugin-dashboard/src/hooks/useChannelIntegration.ts +43 -0
  199. package/template/packages/plugins/@lego/plugin-dashboard/src/hooks/useDashboardStats.ts +65 -0
  200. package/template/packages/plugins/@lego/plugin-dashboard/src/hooks/usePocketBase.ts +47 -0
  201. package/template/packages/plugins/@lego/plugin-dashboard/src/hooks/useRecentActivity.ts +55 -0
  202. package/template/packages/plugins/@lego/plugin-dashboard/src/lib/utils.ts +6 -0
  203. package/template/packages/plugins/@lego/plugin-dashboard/src/pages/DashboardPage.tsx +105 -0
  204. package/template/packages/plugins/@lego/plugin-dashboard/src/plugin.config.ts +121 -0
  205. package/template/packages/plugins/@lego/plugin-dashboard/src/plugin.ts +18 -0
  206. package/template/packages/plugins/@lego/plugin-dashboard/src/vite-env.d.ts +32 -0
  207. package/template/packages/plugins/@lego/plugin-dashboard/tailwind.config.ts +35 -0
  208. package/template/packages/plugins/@lego/plugin-dashboard/tsconfig.json +18 -0
  209. package/template/packages/plugins/@lego/plugin-todo/modern.config.ts +18 -0
  210. package/template/packages/plugins/@lego/plugin-todo/package.json +41 -0
  211. package/template/packages/plugins/@lego/plugin-todo/postcss.config.mjs +6 -0
  212. package/template/packages/plugins/@lego/plugin-todo/src/App.tsx +12 -0
  213. package/template/packages/plugins/@lego/plugin-todo/src/components/SidebarWidget.tsx +16 -0
  214. package/template/packages/plugins/@lego/plugin-todo/src/components/TodoDialog.tsx +55 -0
  215. package/template/packages/plugins/@lego/plugin-todo/src/components/TodoFilters.tsx +79 -0
  216. package/template/packages/plugins/@lego/plugin-todo/src/components/TodoForm.tsx +94 -0
  217. package/template/packages/plugins/@lego/plugin-todo/src/components/TodoItem.tsx +121 -0
  218. package/template/packages/plugins/@lego/plugin-todo/src/components/TodoList.tsx +41 -0
  219. package/template/packages/plugins/@lego/plugin-todo/src/components/index.ts +6 -0
  220. package/template/packages/plugins/@lego/plugin-todo/src/global.css +59 -0
  221. package/template/packages/plugins/@lego/plugin-todo/src/hooks/useCreateTodo.ts +62 -0
  222. package/template/packages/plugins/@lego/plugin-todo/src/hooks/useDeleteTodo.ts +46 -0
  223. package/template/packages/plugins/@lego/plugin-todo/src/hooks/usePocketBase.ts +38 -0
  224. package/template/packages/plugins/@lego/plugin-todo/src/hooks/useTodos.ts +64 -0
  225. package/template/packages/plugins/@lego/plugin-todo/src/hooks/useUpdateTodo.ts +35 -0
  226. package/template/packages/plugins/@lego/plugin-todo/src/index.tsx +5 -0
  227. package/template/packages/plugins/@lego/plugin-todo/src/lib/utils.ts +20 -0
  228. package/template/packages/plugins/@lego/plugin-todo/src/pages/TodoPage.tsx +89 -0
  229. package/template/packages/plugins/@lego/plugin-todo/src/plugin.config.ts +104 -0
  230. package/template/packages/plugins/@lego/plugin-todo/src/plugin.ts +13 -0
  231. package/template/packages/plugins/@lego/plugin-todo/src/schemas.ts +37 -0
  232. package/template/packages/plugins/@lego/plugin-todo/src/types.ts +42 -0
  233. package/template/packages/plugins/@lego/plugin-todo/src/vite-env.d.ts +31 -0
  234. package/template/packages/plugins/@lego/plugin-todo/tailwind.config.ts +51 -0
  235. package/template/packages/plugins/@lego/plugin-todo/tsconfig.json +18 -0
  236. package/template/pnpm-workspace.yaml +4 -0
  237. package/template/pocketbase/CHANGELOG.md +911 -0
  238. package/template/pocketbase/LICENSE.md +17 -0
  239. package/template/scripts/create-plugin.js +221 -0
  240. package/template/scripts/deploy.sh +56 -0
  241. package/template/tsconfig.base.json +26 -0
  242. package/template/tsconfig.json +8 -0
@@ -0,0 +1,721 @@
1
+ # System Blueprint: Host/Consumer Architecture
2
+
3
+ **Project:** Lego-One (Modern.js SaaS OS)
4
+ **Document:** 01 - System Blueprint
5
+ **Status:** Research Phase
6
+
7
+ ## Executive Summary
8
+
9
+ This document provides the high-level architectural blueprint for the Lego-One Microkernel SaaS OS, defining the relationship between the Host (Kernel) and Consumers (Plugins) using Modern.js + Garfish.
10
+
11
+ ---
12
+
13
+ ## 1. Architecture Overview
14
+
15
+ ### 1.1 The Microkernel Pattern
16
+
17
+ ```
18
+ ┌─────────────────────────────────────────────────────────────────────────┐
19
+ │ Lego-One SaaS OS │
20
+ ├─────────────────────────────────────────────────────────────────────────┤
21
+ │ │
22
+ │ ┌───────────────────────────────────────────────────────────────────┐ │
23
+ │ │ KERNEL (Host App) │ │
24
+ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │
25
+ │ │ │ Core Infrastructure (Never changes per plugin) │ │ │
26
+ │ │ │ - Authentication (PocketBase SDK) │ │ │
27
+ │ │ │ - Global Layout (Sidebar, Topbar, Toasts) │ │ │
28
+ │ │ │ - Router (React Router v6 via Modern.js) │ │ │
29
+ │ │ │ - State Bus (Zustand + Garfish Channel) │ │ │
30
+ │ │ │ - Plugin Loader (saas.config.ts reader) │ │ │
31
+ │ │ └─────────────────────────────────────────────────────────────┘ │ │
32
+ │ │ │ │
33
+ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │
34
+ │ │ │ Shared Dependency Layer │ │ │
35
+ │ │ │ - React, ReactDOM (via Garfish) │ │ │
36
+ │ │ │ - Zustand Store Bridge (__LEGO_KERNEL_STATE__) │ │ │
37
+ │ │ │ - UI Primitives (Radix, Shadcn components) │ │ │
38
+ │ │ │ - TanStack Query v5 (shared QueryClient) │ │ │
39
+ │ │ └─────────────────────────────────────────────────────────────┘ │ │
40
+ │ └───────────────────────────────────────────────────────────────────┘ │
41
+ │ │
42
+ │ ┌───────────────────────────────────────────────────────────────────┐ │
43
+ │ │ PLUGIN BOUNDARY │ │
44
+ │ │ (Garfish.loadApp() - Dynamic Loading Interface) │ │
45
+ │ └───────────────────────────────────────────────────────────────────┘ │
46
+ │ │
47
+ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
48
+ │ │ Plugin A │ │ Plugin B │ │ Plugin C │ │ Plugin N │ │
49
+ │ │ (Dashboard) │ │ (Loan Calc) │ │(Inventory) │ │ (Stripe) │ │
50
+ │ │ │ │ │ │ │ │ │ │
51
+ │ │ - Routes │ │ - Routes │ │ - Routes │ │ - Routes │ │
52
+ │ │ - Features │ │ - Features │ │ - Features │ │ - Features │ │
53
+ │ │ - UI │ │ - UI │ │ - UI │ │ - UI │ │
54
+ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
55
+ │ │ │ │ │ │
56
+ │ └────────────────┴────────────────┴────────────────┘ │
57
+ │ Slot Injection (UI Extension) │
58
+ │ │
59
+ └─────────────────────────────────────────────────────────────────────────┘
60
+ ```
61
+
62
+ ### 1.2 Key Design Principles
63
+
64
+ | Principle | Implementation | Benefit |
65
+ |-----------|----------------|---------|
66
+ | **Kernel Stability** | Core infra never changes per plugin | Predictable updates, no breaking changes |
67
+ | **Plugin Isolation** | Each plugin is a separate Modern.js app | Independent deployment, team autonomy |
68
+ | **Shared Dependencies** | Garfish externals + Zustand bridge | Reduced bundle size, consistent state |
69
+ | **Slot Injection** | Global registry pattern | Plugins extend host UI without modification |
70
+ | **Bus Communication** | Garfish.channel + custom events | Decoupled messaging between apps |
71
+
72
+ ---
73
+
74
+ ## 2. Host (Kernel) Structure
75
+
76
+ ### 2.1 Directory Structure
77
+
78
+ ```
79
+ host/
80
+ ├── modern.config.ts # Host Modern.js config
81
+ ├── modern.runtime.ts # Sub-app registration
82
+ ├── package.json
83
+ ├── tsconfig.json
84
+ ├── tailwind.config.js # Global Tailwind config
85
+ ├── postcss.config.js # Global PostCSS config
86
+ ├── src/
87
+ │ ├── bootstrap.tsx # App entry, shared state initialization
88
+ │ ├── main.tsx # ReactDOM.render
89
+ │ ├── kernel/
90
+ │ │ ├── shared-state-bridge.ts # Zustand store for plugins
91
+ │ │ ├── slot-registry.ts # UI slot injection system
92
+ │ │ ├── communication-bus.ts # Garfish.channel wrapper
93
+ │ │ └── plugin-loader.ts # saas.config.ts reader
94
+ │ ├── providers/
95
+ │ │ ├── QueryProvider.tsx # TanStack Query provider
96
+ │ │ ├── ThemeProvider.tsx # Shadcn theme provider
97
+ │ │ └── PocketBaseProvider.tsx # PocketBase SDK provider
98
+ │ ├── layout/
99
+ │ │ ├── AppLayout.tsx # Main layout shell
100
+ │ │ ├── Sidebar.tsx # Navigation sidebar
101
+ │ │ ├── Topbar.tsx # Header with user menu
102
+ │ │ └── SlotOutlet.tsx # Renders injected plugin UI
103
+ │ ├── routes/
104
+ │ │ ├── layout.tsx # Root layout wrapper
105
+ │ │ ├── page.tsx # Home/landing page
106
+ │ │ ├── login/
107
+ │ │ │ └── page.tsx # Auth pages
108
+ │ │ ├── dashboard/
109
+ │ │ │ └── $.tsx # Fuzzy route for dashboard plugin
110
+ │ │ ├── apps/
111
+ │ │ │ ├── loan/
112
+ │ │ │ │ └── $.tsx # Fuzzy route for loan plugin
113
+ │ │ │ ├── inventory/
114
+ │ │ │ │ └── $.tsx # Fuzzy route for inventory plugin
115
+ │ │ │ └── settings/
116
+ │ │ │ └── page.tsx # Global settings page
117
+ │ │ └── _404.tsx # 404 page
118
+ │ ├── components/
119
+ │ │ ├── ui/ # Shadcn components (shared)
120
+ │ │ ├── auth/
121
+ │ │ └── common/
122
+ │ ├── hooks/
123
+ │ │ ├── useAuth.ts # Authentication hook
124
+ │ │ ├── usePluginLoader.ts # Plugin loading logic
125
+ │ │ └── useSlotRegistry.ts # Slot registration hook
126
+ │ ├── lib/
127
+ │ │ ├── pocketbase.ts # PocketBase client init
128
+ │ │ └── utils.ts
129
+ │ └── types/
130
+ │ ├── kernel.ts # Kernel type definitions
131
+ │ └── plugin.ts # Plugin interface definitions
132
+ └── saas.config.ts # Plugin manifest (user-editable)
133
+ ```
134
+
135
+ ### 2.2 Core Kernel Components
136
+
137
+ #### 2.2.1 Plugin Loader
138
+
139
+ **File:** `src/kernel/plugin-loader.ts`
140
+
141
+ ```typescript
142
+ import { AppsOptions } from '@modern-js/plugin-garfish';
143
+
144
+ interface SaaSConfig {
145
+ plugins: {
146
+ name: string;
147
+ entry: string;
148
+ activeWhen: string;
149
+ enabled: boolean;
150
+ }[];
151
+ }
152
+
153
+ export async function loadSaaSConfig(): Promise<AppsOptions[]> {
154
+ // Import user's saas.config.ts
155
+ const config: SaaSConfig = await import('/saas.config.ts');
156
+
157
+ // Filter enabled plugins and format for Garfish
158
+ return config.plugins
159
+ .filter((plugin) => plugin.enabled)
160
+ .map(({ name, entry, activeWhen }) => ({
161
+ name,
162
+ entry,
163
+ activeWhen,
164
+ }));
165
+ }
166
+ ```
167
+
168
+ #### 2.2.2 Slot Registry
169
+
170
+ **File:** `src/kernel/slot-registry.ts`
171
+
172
+ ```typescript
173
+ import { reactive } from '@modern-js/runtime';
174
+
175
+ export type SlotName = 'sidebar:nav' | 'topbar:actions' | 'topbar:menu';
176
+
177
+ export interface SlotItem {
178
+ id: string;
179
+ pluginName: string;
180
+ component: React.ComponentType;
181
+ order: number;
182
+ isVisible: () => boolean;
183
+ }
184
+
185
+ interface SlotRegistry {
186
+ slots: Record<SlotName, SlotItem[]>;
187
+ register: (slot: SlotName, item: SlotItem) => void;
188
+ unregister: (slot: SlotName, id: string) => void;
189
+ getItems: (slot: SlotName) => SlotItem[];
190
+ }
191
+
192
+ // Global singleton for slot registration
193
+ export const slotRegistry: SlotRegistry = reactive({
194
+ slots: {
195
+ 'sidebar:nav': [],
196
+ 'topbar:actions': [],
197
+ 'topbar:menu': [],
198
+ },
199
+
200
+ register(slot: SlotName, item: SlotItem) {
201
+ this.slots[slot].push(item);
202
+ this.slots[slot].sort((a, b) => a.order - b.order);
203
+ },
204
+
205
+ unregister(slot: SlotName, id: string) {
206
+ this.slots[slot] = this.slots[slot].filter((item) => item.id !== id);
207
+ },
208
+
209
+ getItems(slot: SlotName) {
210
+ return this.slots[slot].filter((item) => item.isVisible());
211
+ },
212
+ });
213
+ ```
214
+
215
+ #### 2.2.3 Communication Bus
216
+
217
+ **File:** `src/kernel/communication-bus.ts`
218
+
219
+ ```typescript
220
+ import { Garfish } from 'garfish';
221
+
222
+ // Event types for inter-app communication
223
+ export type BusEvent =
224
+ | { type: 'auth:login'; payload: { userId: string; email: string } }
225
+ | { type: 'auth:logout' }
226
+ | { type: 'toast:show'; payload: { message: string; variant: 'success' | 'error' } }
227
+ | { type: 'theme:change'; payload: { theme: 'light' | 'dark' } }
228
+ | { type: 'navigation:goto'; payload: { path: string } };
229
+
230
+ // Wrapper around Garfish.channel for type safety
231
+ export class KernelBus {
232
+ private channel = Garfish.channel;
233
+
234
+ // Subscribe to events
235
+ on(eventType: BusEvent['type'], handler: (payload: any) => void) {
236
+ this.channel.on(eventType, handler);
237
+ return () => this.channel.off(eventType, handler);
238
+ }
239
+
240
+ // Emit events
241
+ emit(event: BusEvent) {
242
+ this.channel.emit(event.type, event.payload);
243
+ }
244
+ }
245
+
246
+ export const kernelBus = new KernelBus();
247
+ ```
248
+
249
+ ---
250
+
251
+ ## 3. Plugin (Sub-App) Structure
252
+
253
+ ### 3.1 Directory Structure
254
+
255
+ ```
256
+ packages/plugins/@lego/plugin-loan-calculator/
257
+ ├── modern.config.ts # Plugin Modern.js config
258
+ ├── package.json
259
+ ├── tsconfig.json
260
+ ├── plugin.config.ts # Plugin metadata (exports, slots, etc.)
261
+ ├── src/
262
+ │ ├── App.tsx # Plugin entry (receives basename)
263
+ │ ├── main.tsx # Plugin ReactDOM.render
264
+ │ ├── pages/
265
+ │ │ ├── IndexPage.tsx
266
+ │ │ └── SettingsPage.tsx
267
+ │ ├── components/
268
+ │ │ ├── LoanCalculator.tsx
269
+ │ │ └── ResultDisplay.tsx
270
+ │ ├── hooks/
271
+ │ │ ├── useKernelState.ts # Access shared kernel state
272
+ │ │ └── useKernelBus.ts # Emit/receive bus events
273
+ │ ├── lib/
274
+ │ │ └── pocketbase-helpers.ts
275
+ │ └── types/
276
+ │ └── plugin.ts
277
+ └── migrations/
278
+ └── init.ts # PocketBase collection initialization
279
+ ```
280
+
281
+ ### 3.2 Plugin Configuration
282
+
283
+ **File:** `plugin.config.ts`
284
+
285
+ ```typescript
286
+ import { definePluginConfig } from '@lego/kernel/plugin-config';
287
+
288
+ export default definePluginConfig({
289
+ name: '@lego/plugin-loan-calculator',
290
+ version: '1.0.0',
291
+ displayName: 'Loan Calculator',
292
+ description: 'Calculate loan payments and amortization schedules',
293
+
294
+ // Plugin exports available to host
295
+ exports: {
296
+ components: {
297
+ LoanWidget: './src/components/LoanWidget',
298
+ },
299
+ },
300
+
301
+ // Slot injections
302
+ slots: {
303
+ 'sidebar:nav': {
304
+ component: './src/components/SidebarLink',
305
+ order: 100,
306
+ isVisible: () => {
307
+ const state = window.__LEGO_KERNEL_STATE__;
308
+ return state?.useGlobalKernelState.getState().currentUser?.role === 'admin';
309
+ },
310
+ },
311
+ 'topbar:actions': {
312
+ component: './src/components/QuickCalcButton',
313
+ order: 50,
314
+ },
315
+ },
316
+
317
+ // PocketBase collections required
318
+ collections: [
319
+ {
320
+ name: 'loan_calculations',
321
+ schema: './migrations/init.ts',
322
+ },
323
+ ],
324
+ });
325
+ ```
326
+
327
+ ### 3.3 Plugin Entry Point
328
+
329
+ **File:** `src/App.tsx`
330
+
331
+ ```typescript
332
+ import { BrowserRouter, Routes, Route } from '@modern-js/runtime/router';
333
+ import { useGarfish } from '@garfish/hooks';
334
+ import { useEffect } from 'react';
335
+ import pluginConfig from '../plugin.config';
336
+ import { registerSlots } from './lib/slot-registration';
337
+
338
+ export default function PluginApp({ basename }: { basename: string }) {
339
+ const { appInfo } = useGarfish();
340
+
341
+ useEffect(() => {
342
+ // Register slot injections with host
343
+ registerSlots(pluginConfig.slots);
344
+ }, []);
345
+
346
+ return (
347
+ <BrowserRouter basename={basename}>
348
+ <Routes>
349
+ <Route index element={<IndexPage />} />
350
+ <Route path="settings" element={<SettingsPage />} />
351
+ </Routes>
352
+ </BrowserRouter>
353
+ );
354
+ }
355
+ ```
356
+
357
+ ---
358
+
359
+ ## 4. Communication Patterns
360
+
361
+ ### 4.1 Host → Plugin: Props Passing
362
+
363
+ Modern.js/Garfish automatically passes the `basename` prop to plugins. For custom props:
364
+
365
+ **Host Route Wrapper:**
366
+
367
+ ```typescript
368
+ // src/routes/apps/loan/$.tsx
369
+ import { useModuleApps } from '@modern-js/plugin-garfish/runtime';
370
+ import { useAuth } from '@/hooks/useAuth';
371
+
372
+ export default function LoanRoute() {
373
+ const { LoanCalculator } = useModuleApps();
374
+ const { user } = useAuth();
375
+
376
+ // Pass custom props to plugin
377
+ return (
378
+ <LoanCalculator
379
+ currentUser={user}
380
+ permissions={user.permissions}
381
+ />
382
+ );
383
+ }
384
+ ```
385
+
386
+ ### 4.2 Plugin → Host: Bus Events
387
+
388
+ ```typescript
389
+ // Plugin component
390
+ import { useKernelBus } from './hooks/useKernelBus';
391
+
392
+ export function LoanCalculator() {
393
+ const bus = useKernelBus();
394
+
395
+ const handleCalculation = () => {
396
+ // Trigger toast in host app
397
+ bus.emit({
398
+ type: 'toast:show',
399
+ payload: { message: 'Calculation complete!', variant: 'success' },
400
+ });
401
+ };
402
+
403
+ return <button onClick={handleCalculation}>Calculate</button>;
404
+ }
405
+ ```
406
+
407
+ ### 4.3 Host → Plugin: State Sharing
408
+
409
+ ```typescript
410
+ // Plugin component
411
+ import { useKernelState } from './hooks/useKernelState';
412
+
413
+ export function LoanCalculator() {
414
+ const kernelState = useKernelState();
415
+
416
+ return (
417
+ <div>
418
+ <p>Theme: {kernelState?.theme}</p>
419
+ <p>User: {kernelState?.currentUser?.email}</p>
420
+ </div>
421
+ );
422
+ }
423
+ ```
424
+
425
+ ---
426
+
427
+ ## 5. Data Flow Diagrams
428
+
429
+ ### 5.1 Application Bootstrap Flow
430
+
431
+ ```
432
+ ┌─────────────┐
433
+ │ Browser │
434
+ │ loads host │
435
+ └──────┬──────┘
436
+
437
+
438
+ ┌─────────────────────────────────────────────────────────────┐
439
+ │ 1. host/main.tsx renders App.tsx │
440
+ └──────┬──────────────────────────────────────────────────────┘
441
+
442
+
443
+ ┌─────────────────────────────────────────────────────────────┐
444
+ │ 2. bootstrap.tsx initializes: │
445
+ │ - PocketBase client │
446
+ │ - Zustand store (registers to window) │
447
+ │ - Garfish.setExternal() for shared deps │
448
+ │ - Reads saas.config.ts │
449
+ └──────┬──────────────────────────────────────────────────────┘
450
+
451
+
452
+ ┌─────────────────────────────────────────────────────────────┐
453
+ │ 3. modern.runtime.ts registers plugins with Garfish │
454
+ │ - Each plugin gets name, entry, activeWhen │
455
+ └──────┬──────────────────────────────────────────────────────┘
456
+
457
+
458
+ ┌─────────────────────────────────────────────────────────────┐
459
+ │ 4. Router matches route → Garfish.loadApp() │
460
+ │ - Plugin JavaScript loaded dynamically │
461
+ │ - Plugin ReactDOM.render into its container │
462
+ └──────┬──────────────────────────────────────────────────────┘
463
+
464
+
465
+ ┌─────────────────────────────────────────────────────────────┐
466
+ │ 5. Plugin initializes: │
467
+ │ - Receives basename from host │
468
+ │ - Registers slot injections │
469
+ │ - Subscribes to kernel bus events │
470
+ │ - Accesses shared state via window bridge │
471
+ └─────────────────────────────────────────────────────────────┘
472
+ ```
473
+
474
+ ### 5.2 Inter-Plugin Communication Flow
475
+
476
+ ```
477
+ ┌──────────────────┐ ┌──────────────────┐
478
+ │ Plugin A (Loan) │ │ Plugin B (Inv.) │
479
+ │ │ │ │
480
+ │ User clicks │ │ │
481
+ │ "Sync Data" │ │ │
482
+ └────────┬─────────┘ └────────┬─────────┘
483
+ │ │
484
+ │ kernelBus.emit({ │ kernelBus.on(
485
+ │ type: 'data:sync', │ 'data:sync',
486
+ │ payload: { ... } │ handler
487
+ │ }) │ )
488
+ │ │
489
+ └───────────────┬───────────────────────┘
490
+
491
+
492
+ ┌─────────────────────┐
493
+ │ Garfish.channel │
494
+ │ (Event Bus) │
495
+ └─────────────────────┘
496
+
497
+
498
+ ┌─────────────────────┐
499
+ │ Host (Kernel) │
500
+ │ - Can also listen │
501
+ │ - Can log events │
502
+ │ - Can transform │
503
+ └─────────────────────┘
504
+ ```
505
+
506
+ ---
507
+
508
+ ## 6. Update Strategy (Git Template Approach)
509
+
510
+ Since the user selected **Git Template (Clone & Fork)** approach:
511
+
512
+ ### 6.1 Distribution Model
513
+
514
+ ```
515
+ lego-one/ (Template Repository)
516
+ ├── host/ (Kernel - users fork this)
517
+ ├── packages/
518
+ │ └── plugins/
519
+ │ ├── @lego/ (Official plugins)
520
+ │ │ ├── plugin-dashboard
521
+ │ │ ├── plugin-auth
522
+ │ │ └── plugin-billing
523
+ │ └── @custom/ (User plugins - users create here)
524
+ │ └── my-custom-plugin
525
+ └── docs/
526
+
527
+ user-saas-app/ (User forks/clones lego-one)
528
+ ├── host/ (Modified kernel - can merge updates)
529
+ ├── packages/
530
+ │ └── plugins/
531
+ │ ├── @lego/ (Submodule or git subtree for updates)
532
+ │ └── @custom/ (User's private plugins)
533
+ └── saas.config.ts (User's configuration)
534
+ ```
535
+
536
+ ### 6.2 Update Workflow
537
+
538
+ 1. **Initial Setup:** User clones `lego-one` template
539
+ 2. **Custom Development:** User creates plugins in `@custom/` namespace
540
+ 3. **Kernel Update:** User merges changes from `lego-one` upstream
541
+ 4. **Plugin Update:** User pulls `@lego/*` plugins via git subtree/submodule
542
+
543
+ **Benefits:**
544
+ - Users control when to update
545
+ - No breaking API changes (kernel is stable)
546
+ - Custom plugins isolated from official updates
547
+ - Can cherry-pick specific changes
548
+
549
+ ---
550
+
551
+ ## 7. Development vs Production Deployment
552
+
553
+ ### 7.1 Key Principle
554
+
555
+ **Plugins are features of ONE application, not separate applications.**
556
+
557
+ ```
558
+ ┌─────────────────────────────────────────────────────────────────────────┐
559
+ │ DEVELOPMENT │
560
+ ├─────────────────────────────────────────────────────────────────────────┤
561
+ │ │
562
+ │ Host : http://localhost:8080 │
563
+ │ Plugin A : http://localhost:3001 ← Separate dev server │
564
+ │ Plugin B : http://localhost:3002 ← Separate dev server │
565
+ │ Plugin C : http://localhost:3003 ← Separate dev server │
566
+ │ │
567
+ │ WHY? Developers can work on plugins independently │
568
+ │ │
569
+ └─────────────────────────────────────────────────────────────────────────┘
570
+
571
+ ┌─────────────────────────────────────────────────────────────────────────┐
572
+ │ PRODUCTION │
573
+ ├─────────────────────────────────────────────────────────────────────────┤
574
+ │ │
575
+ │ Single Server: https://app.yourdomain.com │
576
+ │ │
577
+ │ All plugins BUNDLED into host's dist/ │
578
+ │ ├── plugins/dashboard/main.js │
579
+ │ ├── plugins/loan-calculator/main.js │
580
+ │ └── plugins/inventory/main.js │
581
+ │ │
582
+ │ WHY? One app, one deployment, simpler operations │
583
+ │ │
584
+ └─────────────────────────────────────────────────────────────────────────┘
585
+ ```
586
+
587
+ ### 7.2 Runtime Configuration
588
+
589
+ **File:** `host/src/modern.runtime.ts`
590
+
591
+ ```typescript
592
+ import { defineRuntimeConfig } from '@modern-js/runtime';
593
+
594
+ const isDev = import.meta.env.MODE === 'development';
595
+
596
+ export default defineRuntimeConfig({
597
+ masterApp: {
598
+ apps: [
599
+ {
600
+ name: '@lego/plugin-dashboard',
601
+ // Dev: Separate server │ Prod: Bundled in host
602
+ entry: isDev
603
+ ? 'http://localhost:3001'
604
+ : () => import('@lego/plugin-dashboard'),
605
+ activeWhen: '/dashboard',
606
+ },
607
+ {
608
+ name: '@lego/plugin-loan-calculator',
609
+ entry: isDev
610
+ ? 'http://localhost:3002'
611
+ : () => import('@lego/plugin-loan-calculator'),
612
+ activeWhen: '/apps/loan',
613
+ },
614
+ {
615
+ name: '@lego/plugin-inventory',
616
+ entry: isDev
617
+ ? 'http://localhost:3003'
618
+ : () => import('@lego/plugin-inventory'),
619
+ activeWhen: '/apps/inventory',
620
+ },
621
+ ],
622
+ },
623
+ });
624
+ ```
625
+
626
+ ### 7.3 Development Workflow
627
+
628
+ **Terminal 1 - Start Host:**
629
+ ```bash
630
+ cd host
631
+ pnpm run dev
632
+ # Runs on http://localhost:8080
633
+ ```
634
+
635
+ **Terminal 2 - Start Plugin (optional):**
636
+ ```bash
637
+ cd packages/plugins/@lego/plugin-dashboard
638
+ pnpm run dev
639
+ # Runs on http://localhost:8081
640
+
641
+ # OR use root script to start all at once:
642
+ pnpm run dev:all
643
+ ```
644
+
645
+ **Browser:** Navigate to `http://localhost:8080/dashboard`
646
+
647
+ ### 7.4 Production Build
648
+
649
+ ```bash
650
+ # Single build command from root
651
+ pnpm run build
652
+
653
+ # Output:
654
+ host/dist/
655
+ ├── html/
656
+ │ └── index.html
657
+ ├── static/
658
+ │ ├── js/
659
+ │ │ ├── main-[hash].js # Host bundle
660
+ │ │ ├── vendor-[hash].js # Shared deps
661
+ │ │ └── plugins/
662
+ │ │ ├── dashboard-[hash].js # Plugin A bundled
663
+ │ │ ├── loan-calc-[hash].js # Plugin B bundled
664
+ │ │ └── inventory-[hash].js # Plugin C bundled
665
+ │ └── css/
666
+ │ └── main-[hash].css
667
+ ```
668
+
669
+ **Deploy:** Single `host/dist/` folder to any static host (Vercel, Netlify, S3, etc.)
670
+
671
+ ### 7.5 Why This Hybrid Approach?
672
+
673
+ | Aspect | Development | Production |
674
+ |--------|-------------|------------|
675
+ | **Servers** | Separate ports for each plugin | Single server |
676
+ | **Hot Reload** | Plugin changes reload independently | N/A (built) |
677
+ | **Build Time** | Fast (only what changes) | Full build |
678
+ | **Team Workflow** | Work on plugin in isolation | N/A |
679
+ | **Operations** | N/A | Simple (one deploy) |
680
+ | **Cost** | N/A | Lower (one server) |
681
+
682
+ **The Best of Both Worlds:**
683
+ - ✅ Dev experience: Independent plugin development
684
+ - ✅ Production experience: Single app deployment
685
+ - ✅ Build tooling: Modern.js handles bundling automatically
686
+ - ✅ No complexity: No separate deployments for plugins
687
+
688
+ ---
689
+
690
+ ## 8. Technology Stack Mapping
691
+
692
+ | Layer | Technology | Purpose |
693
+ |-------|-----------|---------|
694
+ | **Framework** | Modern.js | Host framework, build tooling |
695
+ | **MFE Engine** | Garfish (via plugin) | Plugin loading, sandboxing |
696
+ | **Bundler** | Rspack | Fast builds, Rust-based |
697
+ | **UI** | React 18 | Component rendering |
698
+ | **Router** | React Router v6 | Routing (integrated in Modern.js) |
699
+ | **State** | Zustand | Global state, shared via bridge |
700
+ | **Server State** | TanStack Query v5 | API caching, mutations |
701
+ | **Styling** | Tailwind CSS | Utility-first CSS |
702
+ | **Components** | Shadcn UI + Radix | Component primitives |
703
+ | **Backend** | PocketBase | BaaS, auth, database |
704
+ | **Language** | TypeScript | Type safety |
705
+
706
+ ---
707
+
708
+ ## 9. Next Steps
709
+
710
+ 1. **`02-data-migration-protocol.md`**: PocketBase auto-schema synchronization
711
+ 2. **`03-host-setup.md`**: Step-by-step host initialization
712
+ 3. **`04-plugin-architecture.md`**: Plugin development patterns
713
+
714
+ ---
715
+
716
+ ## References
717
+
718
+ - [Modern.js Micro Frontend Guide](https://modernjs.dev/guides/topic-detail/micro-frontend/c02-development)
719
+ - [Garfish GitHub Repository](https://github.com/web-infra-dev/garfish)
720
+ - [Garfish.setExternal API](https://www.garfishjs.org/api/setExternal.html)
721
+ - [PocketBase JS Collections](https://pocketbase.io/docs/js-collections/)