create-fullstack-scaffold 0.1.0

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 (530) hide show
  1. package/README.md +154 -0
  2. package/dist/cli/index.d.ts +2 -0
  3. package/dist/cli/index.js +439 -0
  4. package/dist/cli/index.js.map +1 -0
  5. package/package.json +171 -0
  6. package/template/.agents/skills/writing-hookify-rules/SKILL.md +408 -0
  7. package/template/.ai-context.md +368 -0
  8. package/template/.claude/hookify.block-dangerous-commands.local.md +41 -0
  9. package/template/.claude/hookify.check-api-types.local.md +111 -0
  10. package/template/.claude/hookify.check-duplicate-types.local.md +287 -0
  11. package/template/.claude/hookify.check-test-assertions.local.md +93 -0
  12. package/template/.claude/hookify.remind-add-tests.local.md +209 -0
  13. package/template/.claude/hookify.remind-db-migration.local.md +58 -0
  14. package/template/.claude/hookify.remind-run-tests.local.md +52 -0
  15. package/template/.claude/hookify.warn-any-type.local.md +203 -0
  16. package/template/.claude/hookify.warn-console-log.local.md +73 -0
  17. package/template/.claude/rules/00-project-config.md +147 -0
  18. package/template/.claude/rules/01-file-types.md +127 -0
  19. package/template/.claude/rules/02-git-workflow.md +167 -0
  20. package/template/.claude/rules/10-api-type-inference.md +555 -0
  21. package/template/.claude/rules/20-server-api.md +349 -0
  22. package/template/.claude/rules/21-server-entrypoint.md +257 -0
  23. package/template/.claude/rules/30-client-components.md +314 -0
  24. package/template/.claude/rules/31-client-services.md +768 -0
  25. package/template/.claude/rules/32-client-state-zustand.md +324 -0
  26. package/template/.claude/rules/33-client-app-entry.md +276 -0
  27. package/template/.claude/rules/34-client-admin-module.md +445 -0
  28. package/template/.claude/rules/35-cli-module.md +259 -0
  29. package/template/.claude/rules/40-admin-module.md +495 -0
  30. package/template/.claude/rules/40-shared-types.md +450 -0
  31. package/template/.claude/rules/50-websocket.md +245 -0
  32. package/template/.claude/rules/51-sse.md +372 -0
  33. package/template/.claude/rules/52-cloudflare-realtime.md +384 -0
  34. package/template/.claude/rules/60-testing-standards.md +245 -0
  35. package/template/.claude/rules/61-hono-testing.md +200 -0
  36. package/template/.claude/scripts/README.md +187 -0
  37. package/template/.claude/scripts/check-duplicate-types.ts +188 -0
  38. package/template/.claude/scripts/post-edit-check-incremental.sh +61 -0
  39. package/template/.claude/scripts/post-edit-check.sh +22 -0
  40. package/template/.claude/scripts/pre-tool-use-check.sh +86 -0
  41. package/template/.claude/scripts/test-pre-tool-use.sh +73 -0
  42. package/template/.claude/scripts/validate-git-changes.sh +38 -0
  43. package/template/.claude/settings.json +32 -0
  44. package/template/.claude/skills/writing-hookify-rules/SKILL.md +408 -0
  45. package/template/.dev-context-compact.md +54 -0
  46. package/template/.dev-context.md +621 -0
  47. package/template/.dev-guide.md +243 -0
  48. package/template/.env.example +60 -0
  49. package/template/.eslintrc.routes.json +39 -0
  50. package/template/.husky/_/husky.sh +27 -0
  51. package/template/.husky/commit-msg +4 -0
  52. package/template/.husky/post-commit +4 -0
  53. package/template/.husky/pre-commit +19 -0
  54. package/template/.husky/pre-push +12 -0
  55. package/template/.prettierignore +22 -0
  56. package/template/.prettierrc +8 -0
  57. package/template/.sessions/3/2026-03-26T05-41-09-154Z_03bb597f-3898-4a2e-8c08-5746bbe8d95e.jsonl +18 -0
  58. package/template/.sessions/3/2026-03-26T05-48-30-052Z_12de4774-9cb3-494c-9852-bd1e6b0003c3.jsonl +6 -0
  59. package/template/.vscode/extensions.json +8 -0
  60. package/template/.vscode/settings.json +4 -0
  61. package/template/.workspaces/3/hello.py +1 -0
  62. package/template/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/803c2e37182b913f8857edf6d8776515cef4af6d48fcb25913e457f4b14ffa97.sqlite +0 -0
  63. package/template/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/803c2e37182b913f8857edf6d8776515cef4af6d48fcb25913e457f4b14ffa97.sqlite-shm +0 -0
  64. package/template/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/803c2e37182b913f8857edf6d8776515cef4af6d48fcb25913e457f4b14ffa97.sqlite-wal +0 -0
  65. package/template/CLAUDE.md +296 -0
  66. package/template/DESIGN.md +260 -0
  67. package/template/DEV_CONTEXT_GUIDE.md +366 -0
  68. package/template/DEV_TOOLS_README.md +396 -0
  69. package/template/FRAMEWORK_HISTORY.md +34 -0
  70. package/template/PROJECT_SUMMARY.md +325 -0
  71. package/template/QUICKSTART.md +305 -0
  72. package/template/README.md +154 -0
  73. package/template/STRUCTURE.txt +81 -0
  74. package/template/admin.html +13 -0
  75. package/template/auth-inject.html +33 -0
  76. package/template/commitlint.config.js +12 -0
  77. package/template/docs/PERMISSION_ARCHITECTURE.md +279 -0
  78. package/template/docs/PERMISSION_EXAMPLES.md +230 -0
  79. package/template/docs/PERMISSION_SYSTEM.md +301 -0
  80. package/template/docs/SMART_TEST.md +171 -0
  81. package/template/docs/runtime-abstract.md +253 -0
  82. package/template/drizzle/0000_rainy_boomer.sql +101 -0
  83. package/template/drizzle/0001_add_todo_attachments.sql +12 -0
  84. package/template/drizzle/0002_chilly_magneto.sql +89 -0
  85. package/template/drizzle/meta/0000_snapshot.json +652 -0
  86. package/template/drizzle/meta/0001_snapshot.json +735 -0
  87. package/template/drizzle/meta/0002_snapshot.json +1198 -0
  88. package/template/drizzle/meta/_journal.json +27 -0
  89. package/template/drizzle.config.ts +13 -0
  90. package/template/eslint-rules/README-no-middleware-in-routes.md +154 -0
  91. package/template/eslint-rules/__tests__/enforce-valid-method.test.ts +251 -0
  92. package/template/eslint-rules/__tests__/layer-boundary.test.ts +102 -0
  93. package/template/eslint-rules/__tests__/module-boundary.test.ts +77 -0
  94. package/template/eslint-rules/__tests__/no-direct-zod-import-in-file-routes.test.ts +45 -0
  95. package/template/eslint-rules/__tests__/no-new-old-service-naming.test.ts +76 -0
  96. package/template/eslint-rules/e2e-test-location.js +153 -0
  97. package/template/eslint-rules/enforce-valid-method.js +217 -0
  98. package/template/eslint-rules/flat-routes-services.js +69 -0
  99. package/template/eslint-rules/framework-protect.js +186 -0
  100. package/template/eslint-rules/layer-boundary.js +164 -0
  101. package/template/eslint-rules/limit-type-complexity.js +130 -0
  102. package/template/eslint-rules/middleware-location.js +162 -0
  103. package/template/eslint-rules/module-boundary.js +125 -0
  104. package/template/eslint-rules/no-ambiguous-file-paths.js +64 -0
  105. package/template/eslint-rules/no-any-on-apiclient.js +173 -0
  106. package/template/eslint-rules/no-boolean-success.js +43 -0
  107. package/template/eslint-rules/no-deep-relative-imports.js +69 -0
  108. package/template/eslint-rules/no-direct-fetch.js +122 -0
  109. package/template/eslint-rules/no-direct-ws-sse.js +57 -0
  110. package/template/eslint-rules/no-direct-zod-import-in-file-routes.js +54 -0
  111. package/template/eslint-rules/no-disable-direct-fetch.js +57 -0
  112. package/template/eslint-rules/no-disable-type-safe-client.js +58 -0
  113. package/template/eslint-rules/no-inline-schema.js +220 -0
  114. package/template/eslint-rules/no-middleware-in-routes.js +81 -0
  115. package/template/eslint-rules/no-new-old-service-naming.js +123 -0
  116. package/template/eslint-rules/no-type-assertion-in-rpc.js +99 -0
  117. package/template/eslint-rules/no-type-assertion-on-shared-types.js +109 -0
  118. package/template/eslint-rules/no-util-functions-in-service.js +128 -0
  119. package/template/eslint-rules/prefer-shared-types.js +352 -0
  120. package/template/eslint-rules/protect-ws-sse-interface.js +66 -0
  121. package/template/eslint-rules/require-antd-generic-types.js +73 -0
  122. package/template/eslint-rules/require-file-openapi-props.js +114 -0
  123. package/template/eslint-rules/require-hono-chain-syntax.js +129 -0
  124. package/template/eslint-rules/require-nullable-for-optional.js +99 -0
  125. package/template/eslint-rules/require-response-helpers.js +140 -0
  126. package/template/eslint-rules/require-type-safe-test-client.js +106 -0
  127. package/template/eslint-rules/route-location.js +72 -0
  128. package/template/eslint.config.js +231 -0
  129. package/template/index.html +17 -0
  130. package/template/lint-scripts/DIRECTORY_RULES.md +335 -0
  131. package/template/lint-scripts/README.md +299 -0
  132. package/template/lint-scripts/TESTING.md +273 -0
  133. package/template/lint-scripts/ai-context-generator.ts +159 -0
  134. package/template/lint-scripts/check-framework-modify.sh +8 -0
  135. package/template/lint-scripts/check-menu-permissions.js +242 -0
  136. package/template/lint-scripts/check-refs.ts +165 -0
  137. package/template/lint-scripts/check-route-auth-complete.js +260 -0
  138. package/template/lint-scripts/check-route-auth.js +212 -0
  139. package/template/lint-scripts/check-route-permissions.js +210 -0
  140. package/template/lint-scripts/config/project.config.ts +358 -0
  141. package/template/lint-scripts/dev-context-analyzer.ts +707 -0
  142. package/template/lint-scripts/dev-guide-generator.ts +830 -0
  143. package/template/lint-scripts/dev-server.ts +58 -0
  144. package/template/lint-scripts/eslint-route-auth.js +158 -0
  145. package/template/lint-scripts/eslint-routes-permission.js +147 -0
  146. package/template/lint-scripts/fix-route-auth.js +245 -0
  147. package/template/lint-scripts/framework/check-modify.ts +152 -0
  148. package/template/lint-scripts/framework/hash-utils.ts +180 -0
  149. package/template/lint-scripts/framework/init-baseline.ts +84 -0
  150. package/template/lint-scripts/framework/update-baseline.ts +148 -0
  151. package/template/lint-scripts/post-commit-track.ts +66 -0
  152. package/template/lint-scripts/quick-test.sh +27 -0
  153. package/template/lint-scripts/smart-test.ts +268 -0
  154. package/template/lint-scripts/test-history.ts +360 -0
  155. package/template/lint-scripts/test-tracker.ts +350 -0
  156. package/template/lint-scripts/validate-all.ts +250 -0
  157. package/template/lint-scripts/validators/api-coverage.validator.ts +355 -0
  158. package/template/lint-scripts/validators/client-rpc.validator.ts +190 -0
  159. package/template/lint-scripts/validators/client-tests.validator.ts +155 -0
  160. package/template/lint-scripts/validators/console-log.validator.ts +122 -0
  161. package/template/lint-scripts/validators/directory-structure.validator.ts +181 -0
  162. package/template/lint-scripts/validators/imports.validator.ts +180 -0
  163. package/template/lint-scripts/validators/index.ts +271 -0
  164. package/template/lint-scripts/validators/md-refs.validator.ts +165 -0
  165. package/template/lint-scripts/validators/module-tests.validator.ts +112 -0
  166. package/template/lint-scripts/validators/sensitive.validator.ts +185 -0
  167. package/template/lint-scripts/validators/server-rpc.validator.ts +141 -0
  168. package/template/lint-scripts/validators/test-quality.validator.ts +257 -0
  169. package/template/lint-scripts/validators/todos.validator.ts +126 -0
  170. package/template/lint-scripts/watch-validator.ts +131 -0
  171. package/template/modules.config.ts +71 -0
  172. package/template/package-lock.json +14554 -0
  173. package/template/package.json +158 -0
  174. package/template/patches/@hono+zod-openapi+1.2.2.patch +67 -0
  175. package/template/patches/@hono+zod-validator+0.7.6.patch +13 -0
  176. package/template/patches/hono+4.12.16.patch +246 -0
  177. package/template/patches/typescript+5.8.3.patch +26 -0
  178. package/template/playwright.config.ts +60 -0
  179. package/template/pnpm-lock.yaml +7137 -0
  180. package/template/postcss.config.js +6 -0
  181. package/template/scripts/create-template.ts +1724 -0
  182. package/template/src/admin/App.tsx +59 -0
  183. package/template/src/admin/components/AccountSwitcher.tsx +104 -0
  184. package/template/src/admin/components/CaptchaModal.tsx +150 -0
  185. package/template/src/admin/components/NotificationDrawer.tsx +213 -0
  186. package/template/src/admin/components/PageHeader.tsx +45 -0
  187. package/template/src/admin/components/PermissionConfigEditor.tsx +237 -0
  188. package/template/src/admin/components/PermissionGuard.tsx +108 -0
  189. package/template/src/admin/components/PermissionTree.tsx +193 -0
  190. package/template/src/admin/components/ProtectedRoute.tsx +33 -0
  191. package/template/src/admin/components/StatsCard.tsx +44 -0
  192. package/template/src/admin/components/UserFormModal.tsx +67 -0
  193. package/template/src/admin/components/UserTable.tsx +72 -0
  194. package/template/src/admin/components/__tests__/PageHeader.test.tsx +48 -0
  195. package/template/src/admin/components/__tests__/PermissionConfigEditor.test.tsx +147 -0
  196. package/template/src/admin/components/__tests__/PermissionGuard.test.tsx +221 -0
  197. package/template/src/admin/components/__tests__/PermissionTree.test.tsx +187 -0
  198. package/template/src/admin/components/__tests__/ProtectedRoute.test.tsx +129 -0
  199. package/template/src/admin/components/__tests__/StatsCard.test.tsx +44 -0
  200. package/template/src/admin/components/__tests__/UserFormModal.test.tsx +125 -0
  201. package/template/src/admin/components/__tests__/UserTable.test.tsx +89 -0
  202. package/template/src/admin/components/index.ts +7 -0
  203. package/template/src/admin/hooks/__tests__/useAuditLogs.test.ts +109 -0
  204. package/template/src/admin/hooks/__tests__/usePermissions.test.tsx +327 -0
  205. package/template/src/admin/hooks/__tests__/usePermissionsBranches.test.ts +198 -0
  206. package/template/src/admin/hooks/__tests__/useRoles.test.ts +261 -0
  207. package/template/src/admin/hooks/useAdminNotifications.ts +156 -0
  208. package/template/src/admin/hooks/useAuditLogs.ts +44 -0
  209. package/template/src/admin/hooks/useConfig.ts +168 -0
  210. package/template/src/admin/hooks/usePermissions.ts +156 -0
  211. package/template/src/admin/hooks/useRoles.ts +120 -0
  212. package/template/src/admin/layouts/Header.tsx +93 -0
  213. package/template/src/admin/layouts/Layout.tsx +23 -0
  214. package/template/src/admin/layouts/Sidebar.tsx +120 -0
  215. package/template/src/admin/main.tsx +18 -0
  216. package/template/src/admin/pages/ContentPage.tsx +252 -0
  217. package/template/src/admin/pages/DashboardPage.tsx +141 -0
  218. package/template/src/admin/pages/DisputesPage.tsx +261 -0
  219. package/template/src/admin/pages/LoginPage.tsx +121 -0
  220. package/template/src/admin/pages/MediaTestPage.tsx +524 -0
  221. package/template/src/admin/pages/OrdersPage.tsx +302 -0
  222. package/template/src/admin/pages/PermissionsPage.tsx +95 -0
  223. package/template/src/admin/pages/RegisterPage.tsx +103 -0
  224. package/template/src/admin/pages/RolesPage.tsx +330 -0
  225. package/template/src/admin/pages/SettingsPage.tsx +73 -0
  226. package/template/src/admin/pages/SystemLogsPage.tsx +218 -0
  227. package/template/src/admin/pages/TestCaptchaPage.tsx +120 -0
  228. package/template/src/admin/pages/TicketsPage.tsx +292 -0
  229. package/template/src/admin/pages/UsersPage.tsx +282 -0
  230. package/template/src/admin/pages/__tests__/ContentPage.test.tsx +213 -0
  231. package/template/src/admin/pages/__tests__/DashboardPage.test.tsx +153 -0
  232. package/template/src/admin/pages/__tests__/DisputesPage.test.tsx +196 -0
  233. package/template/src/admin/pages/__tests__/LoginPage.test.tsx +112 -0
  234. package/template/src/admin/pages/__tests__/OrdersPage.test.tsx +217 -0
  235. package/template/src/admin/pages/__tests__/PermissionsPage.test.tsx +119 -0
  236. package/template/src/admin/pages/__tests__/RegisterPage.test.tsx +179 -0
  237. package/template/src/admin/pages/__tests__/RolesPage.test.tsx +256 -0
  238. package/template/src/admin/pages/__tests__/SettingsPage.test.tsx +66 -0
  239. package/template/src/admin/pages/__tests__/SystemLogsPage.test.tsx +125 -0
  240. package/template/src/admin/pages/__tests__/TicketsPage.test.tsx +202 -0
  241. package/template/src/admin/pages/__tests__/UsersPage.test.tsx +229 -0
  242. package/template/src/admin/services/README.md +263 -0
  243. package/template/src/admin/services/TESTING.md +323 -0
  244. package/template/src/admin/services/__tests__/skipLoading.test.ts +146 -0
  245. package/template/src/admin/services/apiClient.ts +66 -0
  246. package/template/src/admin/services/requestInterceptor.ts +127 -0
  247. package/template/src/admin/services/types.ts +5 -0
  248. package/template/src/admin/stores/__tests__/adminStore.test.ts +184 -0
  249. package/template/src/admin/stores/__tests__/adminStoreBranches.test.ts +148 -0
  250. package/template/src/admin/stores/__tests__/captchaStore.test.ts +75 -0
  251. package/template/src/admin/stores/__tests__/captchaStoreBranches.test.ts +37 -0
  252. package/template/src/admin/stores/__tests__/loadingStore.test.ts +68 -0
  253. package/template/src/admin/stores/adminStore.ts +88 -0
  254. package/template/src/admin/stores/captchaStore.ts +47 -0
  255. package/template/src/admin/stores/loadingStore.ts +27 -0
  256. package/template/src/cli/index.ts +22 -0
  257. package/template/src/cli/modules/config/index.ts +132 -0
  258. package/template/src/cli/modules/index.ts +12 -0
  259. package/template/src/cli/modules/notification/index.ts +86 -0
  260. package/template/src/cli/modules/todo/index.ts +60 -0
  261. package/template/src/cli/rpc/client.ts +23 -0
  262. package/template/src/cli/rpc/index.ts +1 -0
  263. package/template/src/cli/utils/api.ts +17 -0
  264. package/template/src/cli/utils/auto-command.ts +229 -0
  265. package/template/src/cli/utils/index.ts +8 -0
  266. package/template/src/cli/utils/logger.ts +79 -0
  267. package/template/src/client/App.tsx +24 -0
  268. package/template/src/client/Layout.tsx +27 -0
  269. package/template/src/client/components/AuthButton.tsx +41 -0
  270. package/template/src/client/components/ConnectionStatus.tsx +75 -0
  271. package/template/src/client/components/EmptyState.tsx +26 -0
  272. package/template/src/client/components/Footer.tsx +17 -0
  273. package/template/src/client/components/LoadingSpinner.tsx +26 -0
  274. package/template/src/client/components/MessageCard.tsx +61 -0
  275. package/template/src/client/components/Navigation.tsx +65 -0
  276. package/template/src/client/components/StatusBadge.tsx +50 -0
  277. package/template/src/client/components/__tests__/App.test.tsx +79 -0
  278. package/template/src/client/components/__tests__/AuthButton.test.tsx +119 -0
  279. package/template/src/client/components/__tests__/ConnectionStatus.test.tsx +188 -0
  280. package/template/src/client/components/__tests__/EmptyState.test.tsx +70 -0
  281. package/template/src/client/components/__tests__/Footer.test.tsx +22 -0
  282. package/template/src/client/components/__tests__/LoadingSpinner.test.tsx +75 -0
  283. package/template/src/client/components/__tests__/MessageCard.test.tsx +142 -0
  284. package/template/src/client/components/__tests__/Navigation.test.tsx +40 -0
  285. package/template/src/client/components/__tests__/StatusBadge.test.tsx +107 -0
  286. package/template/src/client/components/index.ts +6 -0
  287. package/template/src/client/index.css +27 -0
  288. package/template/src/client/main.tsx +25 -0
  289. package/template/src/client/pages/ContentDetailPage.tsx +142 -0
  290. package/template/src/client/pages/ContentListPage.tsx +169 -0
  291. package/template/src/client/pages/NotificationPage.tsx +288 -0
  292. package/template/src/client/pages/TodoPage.tsx +389 -0
  293. package/template/src/client/pages/WebSocketPage.tsx +239 -0
  294. package/template/src/client/pages/__tests__/ContentDetailPage.test.tsx +176 -0
  295. package/template/src/client/pages/__tests__/ContentListPage.test.tsx +202 -0
  296. package/template/src/client/pages/__tests__/NotificationPage.test.tsx +246 -0
  297. package/template/src/client/pages/__tests__/TodoPage.test.tsx +433 -0
  298. package/template/src/client/pages/__tests__/WebSocketPage.test.tsx +378 -0
  299. package/template/src/client/services/apiClient.ts +66 -0
  300. package/template/src/client/stores/__tests__/authStore.test.ts +139 -0
  301. package/template/src/client/stores/__tests__/chatWSStore.test.ts +416 -0
  302. package/template/src/client/stores/__tests__/notificationStore.test.ts +453 -0
  303. package/template/src/client/stores/__tests__/todoStore.test.ts +509 -0
  304. package/template/src/client/stores/authStore.ts +51 -0
  305. package/template/src/client/stores/chatWSStore.ts +122 -0
  306. package/template/src/client/stores/notificationStore.ts +199 -0
  307. package/template/src/client/stores/todoStore.ts +207 -0
  308. package/template/src/server/__tests__/integration/todos-api.test.ts +138 -0
  309. package/template/src/server/app.ts +105 -0
  310. package/template/src/server/config.ts +86 -0
  311. package/template/src/server/core/__tests__/realtime-core.test.ts +329 -0
  312. package/template/src/server/core/__tests__/realtime-scanner.test.ts +210 -0
  313. package/template/src/server/core/__tests__/runtime-node.test.ts +330 -0
  314. package/template/src/server/core/__tests__/runtime.test.ts +219 -0
  315. package/template/src/server/core/__tests__/typed-runtime.test.ts +178 -0
  316. package/template/src/server/core/durable-objects/RealtimeDO.ts +206 -0
  317. package/template/src/server/core/index.ts +83 -0
  318. package/template/src/server/core/module-loader.ts +281 -0
  319. package/template/src/server/core/realtime-core.ts +152 -0
  320. package/template/src/server/core/realtime-scanner.ts +99 -0
  321. package/template/src/server/core/runtime-cloudflare.ts +207 -0
  322. package/template/src/server/core/runtime-node.ts +170 -0
  323. package/template/src/server/core/runtime.ts +129 -0
  324. package/template/src/server/core/typed-runtime.ts +80 -0
  325. package/template/src/server/db/__tests__/driver.test.ts +203 -0
  326. package/template/src/server/db/config.ts +1 -0
  327. package/template/src/server/db/driver-cloudflare.ts +50 -0
  328. package/template/src/server/db/driver.ts +116 -0
  329. package/template/src/server/db/index.ts +3 -0
  330. package/template/src/server/db/init.ts +412 -0
  331. package/template/src/server/db/schema/api-endpoints.ts +23 -0
  332. package/template/src/server/db/schema/contents.ts +31 -0
  333. package/template/src/server/db/schema/disputes.ts +39 -0
  334. package/template/src/server/db/schema/index.ts +14 -0
  335. package/template/src/server/db/schema/notifications.ts +16 -0
  336. package/template/src/server/db/schema/orders.ts +30 -0
  337. package/template/src/server/db/schema/permission-audit-logs.ts +17 -0
  338. package/template/src/server/db/schema/permission-route-mappings.ts +22 -0
  339. package/template/src/server/db/schema/permissions.ts +17 -0
  340. package/template/src/server/db/schema/role-permissions.ts +22 -0
  341. package/template/src/server/db/schema/roles.ts +17 -0
  342. package/template/src/server/db/schema/tickets.ts +62 -0
  343. package/template/src/server/db/schema/todo-attachments.ts +22 -0
  344. package/template/src/server/db/schema/todos.ts +21 -0
  345. package/template/src/server/db/schema/user-roles.ts +17 -0
  346. package/template/src/server/db/seeds/index.ts +1 -0
  347. package/template/src/server/db/seeds/permission-data.ts +354 -0
  348. package/template/src/server/db/test-setup.ts +647 -0
  349. package/template/src/server/entries/cloudflare.ts +71 -0
  350. package/template/src/server/entries/node.ts +190 -0
  351. package/template/src/server/index.ts +62 -0
  352. package/template/src/server/middleware/__tests__/auth-simple.test.ts +147 -0
  353. package/template/src/server/middleware/__tests__/auth.test.ts +276 -0
  354. package/template/src/server/middleware/__tests__/captcha.test.ts +258 -0
  355. package/template/src/server/middleware/__tests__/error-handler.test.ts +364 -0
  356. package/template/src/server/middleware/__tests__/error-response-format.test.ts +80 -0
  357. package/template/src/server/middleware/__tests__/permission.test.ts +312 -0
  358. package/template/src/server/middleware/audit-log.ts +101 -0
  359. package/template/src/server/middleware/auth.ts +235 -0
  360. package/template/src/server/middleware/captcha.ts +166 -0
  361. package/template/src/server/middleware/cors.ts +30 -0
  362. package/template/src/server/middleware/error-handler.ts +135 -0
  363. package/template/src/server/middleware/index.ts +24 -0
  364. package/template/src/server/middleware/logger.ts +73 -0
  365. package/template/src/server/middleware/permission.ts +127 -0
  366. package/template/src/server/middleware/rate-limit.ts +69 -0
  367. package/template/src/server/middleware/realtime-env.ts +12 -0
  368. package/template/src/server/module-admin/__tests__/admin-routes.test.ts +360 -0
  369. package/template/src/server/module-admin/__tests__/admin-service.test.ts +222 -0
  370. package/template/src/server/module-admin/__tests__/audit-log-routes.test.ts +261 -0
  371. package/template/src/server/module-admin/__tests__/export-routes.test.ts +160 -0
  372. package/template/src/server/module-admin/__tests__/media-routes.test.ts +122 -0
  373. package/template/src/server/module-admin/module.ts +40 -0
  374. package/template/src/server/module-admin/routes/admin-notification-routes.ts +197 -0
  375. package/template/src/server/module-admin/routes/admin-routes.ts +20 -0
  376. package/template/src/server/module-admin/routes/auth-routes.ts +86 -0
  377. package/template/src/server/module-admin/routes/export-routes.ts +207 -0
  378. package/template/src/server/module-admin/routes/media-routes.ts +78 -0
  379. package/template/src/server/module-admin/routes/system-routes.ts +89 -0
  380. package/template/src/server/module-admin/routes/user-management-routes.ts +143 -0
  381. package/template/src/server/module-admin/services/admin-service.ts +268 -0
  382. package/template/src/server/module-captcha/__tests__/captcha-route.test.ts +35 -0
  383. package/template/src/server/module-captcha/__tests__/captcha-service.test.ts +53 -0
  384. package/template/src/server/module-captcha/module.ts +35 -0
  385. package/template/src/server/module-captcha/routes/captcha-routes.ts +68 -0
  386. package/template/src/server/module-captcha/services/captcha-service.ts +3 -0
  387. package/template/src/server/module-chat/__tests__/chat-routes.test.ts +39 -0
  388. package/template/src/server/module-chat/__tests__/chat-rpc.test.ts +185 -0
  389. package/template/src/server/module-chat/__tests__/chat-service.test.ts +64 -0
  390. package/template/src/server/module-chat/module.ts +27 -0
  391. package/template/src/server/module-chat/routes/chat-routes.ts +46 -0
  392. package/template/src/server/module-chat/services/chat-service.ts +38 -0
  393. package/template/src/server/module-content/__tests__/content-route.test.ts +40 -0
  394. package/template/src/server/module-content/__tests__/content-service.test.ts +107 -0
  395. package/template/src/server/module-content/module.ts +39 -0
  396. package/template/src/server/module-content/routes/content-routes.ts +182 -0
  397. package/template/src/server/module-content/routes/public-content-routes.ts +58 -0
  398. package/template/src/server/module-content/services/content-service.ts +224 -0
  399. package/template/src/server/module-dispute/__tests__/dispute-route.test.ts +43 -0
  400. package/template/src/server/module-dispute/__tests__/dispute-service.test.ts +135 -0
  401. package/template/src/server/module-dispute/module.ts +30 -0
  402. package/template/src/server/module-dispute/routes/dispute-routes.ts +153 -0
  403. package/template/src/server/module-dispute/services/dispute-service.ts +255 -0
  404. package/template/src/server/module-file/__tests__/file-routes.test.ts +284 -0
  405. package/template/src/server/module-file/__tests__/file-storage-service.test.ts +323 -0
  406. package/template/src/server/module-file/module.ts +28 -0
  407. package/template/src/server/module-file/routes/file-routes.ts +288 -0
  408. package/template/src/server/module-notifications/__tests__/notification-route-rpc.test.ts +375 -0
  409. package/template/src/server/module-notifications/__tests__/notification-service.test.ts +241 -0
  410. package/template/src/server/module-notifications/__tests__/sse-rpc.test.ts +289 -0
  411. package/template/src/server/module-notifications/module.ts +32 -0
  412. package/template/src/server/module-notifications/routes/notification-routes.ts +190 -0
  413. package/template/src/server/module-notifications/services/notification-service.ts +104 -0
  414. package/template/src/server/module-order/__tests__/order-route.test.ts +258 -0
  415. package/template/src/server/module-order/__tests__/order-service.test.ts +222 -0
  416. package/template/src/server/module-order/module.ts +30 -0
  417. package/template/src/server/module-order/routes/order-routes.ts +202 -0
  418. package/template/src/server/module-order/services/order-service.ts +268 -0
  419. package/template/src/server/module-permission/__tests__/permission-middleware.test.ts +90 -0
  420. package/template/src/server/module-permission/__tests__/permission-routes.test.ts +330 -0
  421. package/template/src/server/module-permission/__tests__/permission-service-impl.test.ts +388 -0
  422. package/template/src/server/module-permission/__tests__/permission-service.test.ts +190 -0
  423. package/template/src/server/module-permission/__tests__/role-routes.test.ts +215 -0
  424. package/template/src/server/module-permission/module.ts +68 -0
  425. package/template/src/server/module-permission/routes/audit-log-routes.ts +76 -0
  426. package/template/src/server/module-permission/routes/permission-routes.ts +184 -0
  427. package/template/src/server/module-permission/routes/role-routes.ts +263 -0
  428. package/template/src/server/module-permission/services/audit-log-service.ts +108 -0
  429. package/template/src/server/module-permission/services/permission-service-impl.ts +233 -0
  430. package/template/src/server/module-permission/services/permission-service.ts +256 -0
  431. package/template/src/server/module-permission/services/role-service.ts +122 -0
  432. package/template/src/server/module-ticket/__tests__/ticket-route.test.ts +173 -0
  433. package/template/src/server/module-ticket/__tests__/ticket-service.test.ts +201 -0
  434. package/template/src/server/module-ticket/module.ts +30 -0
  435. package/template/src/server/module-ticket/routes/ticket-routes.ts +210 -0
  436. package/template/src/server/module-ticket/services/ticket-service.ts +297 -0
  437. package/template/src/server/module-todos/__tests__/todo-service.test.ts +196 -0
  438. package/template/src/server/module-todos/__tests__/todos-file-upload.test.ts +439 -0
  439. package/template/src/server/module-todos/__tests__/todos-route-rpc.test.ts +575 -0
  440. package/template/src/server/module-todos/module.ts +30 -0
  441. package/template/src/server/module-todos/routes/todos-routes.ts +260 -0
  442. package/template/src/server/module-todos/services/todo-service.ts +202 -0
  443. package/template/src/server/route-registry.ts +47 -0
  444. package/template/src/server/test-utils/test-client.ts +66 -0
  445. package/template/src/server/test-utils/test-server.ts +131 -0
  446. package/template/src/server/types/bindings.ts +10 -0
  447. package/template/src/server/utils/__tests__/app-error.test.ts +374 -0
  448. package/template/src/server/utils/__tests__/auth.test.ts +76 -0
  449. package/template/src/server/utils/__tests__/captcha.test.ts +80 -0
  450. package/template/src/server/utils/__tests__/file-storage.test.ts +472 -0
  451. package/template/src/server/utils/__tests__/logger.test.ts +221 -0
  452. package/template/src/server/utils/__tests__/route-helpers.test.ts +264 -0
  453. package/template/src/server/utils/app-error.ts +355 -0
  454. package/template/src/server/utils/auth.ts +65 -0
  455. package/template/src/server/utils/captcha.ts +119 -0
  456. package/template/src/server/utils/date.ts +50 -0
  457. package/template/src/server/utils/env.ts +4 -0
  458. package/template/src/server/utils/file-storage.ts +462 -0
  459. package/template/src/server/utils/generate.ts +26 -0
  460. package/template/src/server/utils/id-helpers.ts +5 -0
  461. package/template/src/server/utils/logger.ts +139 -0
  462. package/template/src/server/utils/permission-utils.ts +6 -0
  463. package/template/src/server/utils/response.ts +40 -0
  464. package/template/src/server/utils/route-helpers.ts +200 -0
  465. package/template/src/server/utils/uuid.ts +8 -0
  466. package/template/src/server/utils/ws-helper.ts +30 -0
  467. package/template/src/shared/constants/index.ts +1 -0
  468. package/template/src/shared/constants/resource-types.ts +72 -0
  469. package/template/src/shared/core/__tests__/sse-client.test.ts +376 -0
  470. package/template/src/shared/core/__tests__/ws-client.test.ts +468 -0
  471. package/template/src/shared/core/api-request.ts +192 -0
  472. package/template/src/shared/core/api-schemas.ts +41 -0
  473. package/template/src/shared/core/index.ts +37 -0
  474. package/template/src/shared/core/module-manifest.ts +120 -0
  475. package/template/src/shared/core/protocol-types.ts +26 -0
  476. package/template/src/shared/core/sse-client.ts +185 -0
  477. package/template/src/shared/core/ws-client.ts +236 -0
  478. package/template/src/shared/hooks/index.ts +2 -0
  479. package/template/src/shared/hooks/useSSE.ts +57 -0
  480. package/template/src/shared/hooks/useWebSocket.ts +66 -0
  481. package/template/src/shared/index.ts +5 -0
  482. package/template/src/shared/modules/admin/index.ts +1 -0
  483. package/template/src/shared/modules/admin/schemas.ts +100 -0
  484. package/template/src/shared/modules/audit/index.ts +1 -0
  485. package/template/src/shared/modules/audit/schemas.ts +24 -0
  486. package/template/src/shared/modules/captcha/index.ts +1 -0
  487. package/template/src/shared/modules/captcha/schemas.ts +19 -0
  488. package/template/src/shared/modules/chat/index.ts +38 -0
  489. package/template/src/shared/modules/content/index.ts +1 -0
  490. package/template/src/shared/modules/content/schemas.ts +53 -0
  491. package/template/src/shared/modules/dispute/index.ts +1 -0
  492. package/template/src/shared/modules/dispute/schemas.ts +62 -0
  493. package/template/src/shared/modules/files/index.ts +11 -0
  494. package/template/src/shared/modules/files/schemas.ts +44 -0
  495. package/template/src/shared/modules/index.ts +70 -0
  496. package/template/src/shared/modules/notifications/index.ts +26 -0
  497. package/template/src/shared/modules/notifications/schemas.ts +73 -0
  498. package/template/src/shared/modules/order/index.ts +1 -0
  499. package/template/src/shared/modules/order/schemas.ts +63 -0
  500. package/template/src/shared/modules/permission/index.ts +42 -0
  501. package/template/src/shared/modules/permission/permission-dependencies.ts +50 -0
  502. package/template/src/shared/modules/permission/permissions.ts +275 -0
  503. package/template/src/shared/modules/permission/schemas.ts +92 -0
  504. package/template/src/shared/modules/permission/types.ts +23 -0
  505. package/template/src/shared/modules/role/index.ts +1 -0
  506. package/template/src/shared/modules/role/schemas.ts +46 -0
  507. package/template/src/shared/modules/ticket/index.ts +1 -0
  508. package/template/src/shared/modules/ticket/schemas.ts +77 -0
  509. package/template/src/shared/modules/todos/index.ts +20 -0
  510. package/template/src/shared/modules/todos/schemas.ts +65 -0
  511. package/template/src/shared/schemas/index.ts +79 -0
  512. package/template/src/types/global.d.ts +14 -0
  513. package/template/src/vite-env.d.ts +21 -0
  514. package/template/tailwind.config.js +11 -0
  515. package/template/tests/e2e/admin-crud.spec.ts +81 -0
  516. package/template/tests/e2e/case-o1.spec.ts +108 -0
  517. package/template/tests/e2e/global-setup.ts +73 -0
  518. package/template/tests/e2e/global-teardown.ts +28 -0
  519. package/template/tests/e2e/notification.spec.ts +458 -0
  520. package/template/tests/e2e/todo.spec.ts +623 -0
  521. package/template/tests/e2e/websocket.spec.ts +254 -0
  522. package/template/tsconfig.json +35 -0
  523. package/template/tsup.config.ts +95 -0
  524. package/template/vite-plugins.ts +113 -0
  525. package/template/vite.config.ts +96 -0
  526. package/template/vitest.config.ts +53 -0
  527. package/template/vitest.integration.config.ts +24 -0
  528. package/template/vitest.integration.setup.ts +22 -0
  529. package/template/vitest.setup.ts +74 -0
  530. package/template/wrangler.toml +33 -0
@@ -0,0 +1,296 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project
6
+
7
+ Todo Application Template - A full-stack React + Hono application demonstrating best practices for monorepo-style architecture with single-port development.
8
+
9
+ ## Commands
10
+
11
+ ```bash
12
+ npm run dev # Start Vite dev server on port 3010 with Hono backend
13
+ npm run build # Production build
14
+ npm run preview # Preview production build
15
+ npm run test # Run all Vitest tests
16
+ npm run test:unit # Run unit tests only
17
+ npm run test:integration # Run integration tests only
18
+ npm run lint # Run ESLint
19
+ npm run format # Run Prettier format
20
+ npm run typecheck # Run TypeScript type check
21
+ ```
22
+
23
+ ## Architecture Overview
24
+
25
+ **Monorepo-style structure** with client/server separation and shared types:
26
+
27
+ ```
28
+ src/
29
+ ├── client/ # React frontend
30
+ │ ├── components/ # UI components
31
+ │ ├── stores/ # Zustand state management
32
+ │ ├── services/ # API clients (apiClient)
33
+ │ ├── hooks/ # Custom hooks
34
+ │ ├── pages/ # Page components
35
+ │ └── App.tsx
36
+ ├── server/ # Hono backend
37
+ │ ├── module-todos/ # Todo module
38
+ │ ├── module-chat/ # WebSocket chat module
39
+ │ ├── module-notifications/ # SSE notifications module
40
+ │ ├── core/ # Core services (runtime, realtime)
41
+ │ ├── middleware/ # Express middleware
42
+ │ ├── test-utils/ # Test utilities
43
+ │ └── entries/ # Entry points (node.ts, cloudflare.ts)
44
+ └── shared/ # Shared types
45
+ ├── core/ # Framework layer (ws-client, sse-client, api-schemas)
46
+ ├── modules/ # Business layer (chat, todos, notifications schemas)
47
+ └── schemas/ # Unified exports
48
+ ```
49
+
50
+ **Path Aliases** (configured in vite.config.ts and tsconfig.json):
51
+
52
+ - `@shared/*` → src/shared/\*
53
+ - `@client/*` → src/client/\*
54
+ - `@server/*` → src/server/\*
55
+
56
+ ## Key Technical Concepts
57
+
58
+ ### Single-Port Development
59
+
60
+ Uses "@hono/vite-dev-server" to run both frontend and backend on port 3010:
61
+
62
+ - No CORS issues in development
63
+ - Type safety across the boundary
64
+ - Simplified developer experience
65
+
66
+ ### Hono RPC
67
+
68
+ Type-safe API calls from frontend to backend:
69
+
70
+ ```typescript
71
+ import { apiClient } from '@client/services/apiClient'
72
+
73
+ // HTTP API
74
+ const response = await apiClient.api.todos.$get()
75
+ const result = await response.json()
76
+
77
+ // WebSocket
78
+ const ws = apiClient.api.chat.ws.$ws()
79
+ const result = await ws.call('echo', { message: 'hello' })
80
+
81
+ // SSE
82
+ const conn = await apiClient.api.notifications.stream.$sse()
83
+ conn.on('notification', n => console.log(n))
84
+ ```
85
+
86
+ ### Real-time Features
87
+
88
+ | Feature | Method | Type Safety | Testing |
89
+ | --------- | ------------------- | ----------- | ---------------- |
90
+ | HTTP API | `$get()`, `$post()` | ✅ | No server needed |
91
+ | WebSocket | `$ws()` | ✅ | Requires server |
92
+ | SSE | `$sse()` | ✅ | No server needed |
93
+
94
+ ### Module Pattern
95
+
96
+ Backend organized by feature modules:
97
+
98
+ ```
99
+ module-{feature}/
100
+ ├── routes/ # API endpoints (Hono RPC)
101
+ ├── services/ # Business logic
102
+ └── __tests__/ # Unit tests
103
+ ```
104
+
105
+ ### Framework Layer vs Business Layer
106
+
107
+ The project has clear separation between framework and business layers:
108
+
109
+ **Framework Layer** (`src/shared/core/`):
110
+
111
+ - Generic, reusable infrastructure code
112
+ - Examples: `ws-client.ts`, `sse-client.ts`, `api-schemas.ts`
113
+ - Should not be modified by business code directly
114
+
115
+ **Business Layer** (`src/shared/modules/`):
116
+
117
+ - Business-specific schemas and protocols
118
+ - Examples: `chat/`, `todos/`, `notifications/`
119
+ - Organized by feature modules
120
+
121
+ ### Layer Boundary Rules (ESLint)
122
+
123
+ The project enforces layer boundaries with `layer-boundary` rule:
124
+
125
+ - Business code cannot directly modify framework layer code
126
+ - Business code importing framework code needs `@framework-import` comment
127
+ - Framework code modification needs `@framework-allow-modification` comment
128
+
129
+ ### State Management with Zustand
130
+
131
+ Global application state in `src/client/stores/`:
132
+
133
+ - **Minimal Re-renders**: Use precise selector hooks
134
+ - **Selector Pattern**: `const todos = useTodoStore((state) => state.todos)`
135
+ - **Action Selectors**: Stable function references
136
+
137
+ ### Testing Strategy
138
+
139
+ - **Unit Tests**: `__tests__/*.test.ts` (jsdom for client, node for server)
140
+ - **Integration Tests**: `src/server/__tests__/integration/*.test.ts`
141
+ - **E2E Tests**: `tests/e2e/*.spec.ts` (Playwright)
142
+ - **WebSocket Tests**: Require real server (`createTestServer`)
143
+ - **SSE Tests**: No server needed (`$sse()` works with `app.fetch()`)
144
+
145
+ ## Important Conventions
146
+
147
+ ### Import Path Aliases
148
+
149
+ Always use path aliases instead of relative imports:
150
+
151
+ ```typescript
152
+ import { Todo } from '@shared/schemas'
153
+ import { useTodoStore } from '@client/stores/todoStore'
154
+ ```
155
+
156
+ ### Environment Variables
157
+
158
+ Required variables (see `.env.example`):
159
+
160
+ ```bash
161
+ API_BASE_URL=http://localhost:3010
162
+ ```
163
+
164
+ ### Module Manifest System
165
+
166
+ Each module under `src/server/module-*/` has a `module.ts` manifest declaring:
167
+
168
+ - Dependencies on other modules
169
+ - Route registrations (client, admin, standalone)
170
+ - Shared schemas, DB schemas, client/admin pages
171
+ - Middleware it provides
172
+ - Whether it has SSE or WebSocket
173
+
174
+ #### Module Categories
175
+
176
+ | Category | Modules |
177
+ | ------------- | -------------------------------- |
178
+ | core | todos |
179
+ | communication | chat, notifications |
180
+ | business | order, ticket, dispute, content |
181
+ | system | permission, admin, captcha, file |
182
+
183
+ #### Dependency Graph
184
+
185
+ ```
186
+ todos ──── (standalone)
187
+ chat ──── (standalone)
188
+ notifications ── (standalone)
189
+ file ──── (standalone)
190
+ captcha ── (standalone)
191
+ permission ── (standalone, foundational)
192
+ admin ──→ permission + notifications
193
+ order ──→ permission
194
+ ticket ──→ permission
195
+ dispute ──→ permission
196
+ content ──→ permission
197
+ ```
198
+
199
+ #### Validation
200
+
201
+ ```bash
202
+ npm run validate:modules
203
+ ```
204
+
205
+ #### Template Presets
206
+
207
+ Defined in `modules.config.ts`:
208
+
209
+ - `fullstack-admin` — All modules (default)
210
+ - `todo-app` — todos + chat + notifications
211
+ - `minimal` — todos only
212
+
213
+ ### Module Creation
214
+
215
+ To add a new feature module:
216
+
217
+ 1. Create `src/server/module-{feature}/` with routes, services, tests
218
+ 2. Create shared schemas in `src/shared/modules/{feature}/`
219
+ 3. Add `module.ts` manifest in the module directory
220
+ 4. Register routes in `route-registry.ts`
221
+ 5. Add DB schemas to `server/db/schema/`
222
+ 6. Add client store if needed
223
+ 7. Add integration tests
224
+ 8. Run `npm run validate:modules` to verify
225
+
226
+ ### API Route Pattern
227
+
228
+ Use Hono RPC with chain syntax:
229
+
230
+ ```typescript
231
+ app.openapi(listRoute, async c => {
232
+ const todos = await todoService.listTodos()
233
+ return c.json({ success: true, data: todos })
234
+ })
235
+ ```
236
+
237
+ ### WebSocket Pattern
238
+
239
+ Use `$ws()` method for type-safe WebSocket:
240
+
241
+ ```typescript
242
+ // Server: Define protocol in src/shared/modules/chat/
243
+ import { ChatProtocolSchema } from '@shared/modules/chat'
244
+
245
+ // Client: Use $ws()
246
+ const ws = apiClient.api.chat.ws.$ws()
247
+ const result = await ws.call('echo', { message: 'hello' })
248
+ ws.on('notification', n => console.log(n))
249
+ ```
250
+
251
+ ### SSE Pattern
252
+
253
+ Use `$sse()` method for type-safe SSE:
254
+
255
+ ```typescript
256
+ // Server: Define protocol in src/shared/modules/notifications/
257
+ import { AppSSEProtocolSchema } from '@shared/schemas'
258
+
259
+ // Client: Use $sse()
260
+ const conn = await apiClient.api.notifications.stream.$sse()
261
+ conn.on('notification', n => console.log(n))
262
+ conn.on('ping', p => console.log(p.timestamp))
263
+ ```
264
+
265
+ ### SSE Broadcast Pattern
266
+
267
+ When creating notifications, broadcast to all connected SSE clients:
268
+
269
+ ```typescript
270
+ // In service layer - use createNotificationAndBroadcast
271
+ import { createNotificationAndBroadcast } from '@server/module-notifications/services/notification-service'
272
+
273
+ // The service automatically handles broadcasting via realtime middleware
274
+ const notification = await createNotificationAndBroadcast(input)
275
+ ```
276
+
277
+ ## Project Rules
278
+
279
+ See `.claude/rules/` for detailed development constraints:
280
+
281
+ - `project-rules.md` - Environment & constants management
282
+ - `client-component-rules.md` - React component patterns
283
+ - `client-service-rules.md` - Service layer patterns
284
+ - `zustand-rules.md` - Zustand store patterns
285
+ - `websocket-rules.md` - WebSocket development patterns
286
+ - `sse-rules.md` - SSE development patterns
287
+ - `shared-types-rules.md` - Shared types organization
288
+ - `layer-boundary-rules.md` - Framework/Business layer separation
289
+ - `testing-standards.md` - Testing conventions
290
+ - `hono-testing-best-practices.md` - Hono testing patterns
291
+
292
+ ## Documentation
293
+
294
+ - `README.md` - User-facing feature overview
295
+ - `DESIGN.md` - Technical architecture
296
+ - `QUICKSTART.md` - Quick start guide
@@ -0,0 +1,260 @@
1
+ # Design Document
2
+
3
+ ## Architecture Overview
4
+
5
+ This template implements a **monorepo-style architecture** with client/server separation while maintaining a single development port.
6
+
7
+ ### Key Design Decisions
8
+
9
+ #### 1. Single-Port Development
10
+
11
+ - **Why**: Simplifies local development, no CORS issues
12
+ - **How**: `@hono/vite-dev-server` serves both React and Hono
13
+ - **Benefit**: Developer experience, type safety across boundary
14
+
15
+ #### 2. Hono RPC
16
+
17
+ - **Why**: End-to-end type safety between frontend and backend
18
+ - **How**: Shared types exported from `src/server/index.ts`
19
+ - **Benefit**: Compile-time error detection, better DX
20
+
21
+ #### 3. Modular Backend
22
+
23
+ - **Why**: Scalability, clear separation of concerns
24
+ - **How**: Feature-based modules (`module-todos/`, `module-chat/`, etc.)
25
+ - **Benefit**: Easy to add new features, maintainable codebase
26
+
27
+ #### 4. Zustand for State
28
+
29
+ - **Why**: Minimal boilerplate, no context provider hell
30
+ - **How**: Global store with selector hooks
31
+ - **Benefit**: Performance (minimal re-renders), simplicity
32
+
33
+ #### 5. Real-time Support
34
+
35
+ - **Why**: Modern apps need real-time features
36
+ - **How**: WebSocket (`$ws()`) and SSE (`$sse()`) with type safety
37
+ - **Benefit**: Type-safe real-time communication
38
+
39
+ ## Module Pattern
40
+
41
+ Each backend module follows this structure:
42
+
43
+ ```
44
+ module-{feature}/
45
+ ├── routes/ # API endpoints (Hono RPC)
46
+ ├── services/ # Business logic
47
+ └── __tests__/ # Unit tests
48
+ ```
49
+
50
+ ### Example: Adding a New Module
51
+
52
+ 1. Create directory: `src/server/module-features/`
53
+ 2. Add routes: `src/server/module-features/routes/features-routes.ts`
54
+ 3. Add service: `src/server/module-features/services/feature-service.ts`
55
+ 4. Add tests: `src/server/module-features/__tests__/feature-service.test.ts`
56
+ 5. Register in `src/server/app.ts`:
57
+
58
+ ```typescript
59
+ import { featureRoutes } from './module-features/routes/features-routes'
60
+ app.route('/api', featureRoutes)
61
+ ```
62
+
63
+ **参考现有模块**:
64
+
65
+ - `src/server/module-todos/` - Todo 模块
66
+ - `src/server/module-admin/` - Admin 模块
67
+
68
+ ## Real-time Architecture
69
+
70
+ ### WebSocket (`$ws()`)
71
+
72
+ **Type Safety Flow**:
73
+
74
+ ```
75
+ Server: WSProtocol Schema
76
+
77
+ @hono/zod-openapi: TypedResponse
78
+
79
+ Hono: ToSchemaOutput
80
+
81
+ Client: $ws() → WSClient<Protocol>
82
+
83
+ Developer: ws.call('method', params) // Type-safe!
84
+ ```
85
+
86
+ **Testing**: Requires real server (`createTestServer`)
87
+
88
+ ### SSE (`$sse()`)
89
+
90
+ **Type Safety Flow**:
91
+
92
+ ```
93
+ Server: SSEProtocol Schema
94
+
95
+ @hono/zod-openapi: TypedResponse
96
+
97
+ Hono: ToSchemaOutput
98
+
99
+ Client: $sse() → SSEClient<Protocol>
100
+
101
+ Developer: conn.on('event', handler) // Type-safe!
102
+ ```
103
+
104
+ **Testing**: No server needed, works with `app.fetch()`
105
+
106
+ ### Comparison
107
+
108
+ | Feature | WebSocket | SSE |
109
+ | --------- | -------------------------- | -------------------------------- |
110
+ | Direction | Bidirectional | Unidirectional (server → client) |
111
+ | Methods | `call()`, `emit()`, `on()` | `on()`, `onStatusChange()` |
112
+ | Protocol | `WSProtocol` | `SSEProtocol` |
113
+ | Testing | Requires server | No server needed |
114
+ | Use Case | Chat, gaming | Notifications, feeds |
115
+
116
+ ## Testing Strategy
117
+
118
+ ### Unit Tests
119
+
120
+ - Location: `src/**/__tests__/*.test.ts`
121
+ - Framework: Vitest
122
+ - Environment: `jsdom` (client), `node` (server)
123
+ - Coverage: Services, stores, utilities
124
+
125
+ ### Integration Tests
126
+
127
+ - Location: `src/server/integration/*.test.ts`
128
+ - Framework: Vitest
129
+ - Environment: `node`
130
+ - Coverage: API endpoints
131
+
132
+ ### WebSocket Tests
133
+
134
+ - Location: `src/server/module-chat/__tests__/*.test.ts`
135
+ - Framework: Vitest
136
+ - Environment: `node`
137
+ - Requires: `createTestServer()`
138
+
139
+ ### SSE Tests
140
+
141
+ - Location: `src/server/module-notifications/__tests__/*.test.ts`
142
+ - Framework: Vitest
143
+ - Environment: `node`
144
+ - Requires: No server needed
145
+
146
+ ### E2E Tests
147
+
148
+ - Location: `tests/e2e/*.spec.ts`
149
+ - Framework: Playwright
150
+ - Environment: Browser
151
+ - Coverage: User workflows
152
+
153
+ ## Type Safety Flow
154
+
155
+ ### HTTP API
156
+
157
+ ```
158
+ ┌─────────────────┐
159
+ │ Server Routes │ ──export──> AppType
160
+ └─────────────────┘ │
161
+
162
+ ┌─────────────────┐ ▼
163
+ │ RPC Client │ <──import── AppType
164
+ │ (Frontend) │
165
+ └─────────────────┘
166
+ ```
167
+
168
+ ### WebSocket
169
+
170
+ ```
171
+ ┌─────────────────┐
172
+ │ WSProtocol │ ──schema──> TypedResponse
173
+ └─────────────────┘ │
174
+
175
+ ┌─────────────────┐ ▼
176
+ │ $ws() Method │ <──type inference──
177
+ │ (Frontend) │
178
+ └─────────────────┘
179
+ ```
180
+
181
+ ### SSE
182
+
183
+ ```
184
+ ┌─────────────────┐
185
+ │ SSEProtocol │ ──schema──> TypedResponse
186
+ └─────────────────┘ │
187
+
188
+ ┌─────────────────┐ ▼
189
+ │ $sse() Method │ <──type inference──
190
+ │ (Frontend) │
191
+ └─────────────────┘
192
+ ```
193
+
194
+ ## Database Schema
195
+
196
+ Using Drizzle ORM with SQLite:
197
+
198
+ ```typescript
199
+ export const todos = sqliteTable('todos', {
200
+ id: integer('id').primaryKey({ autoIncrement: true }),
201
+ title: text('title').notNull(),
202
+ description: text('description'),
203
+ status: text('status').notNull().default('pending'),
204
+ createdAt: integer('created_at', { mode: 'timestamp' }),
205
+ updatedAt: integer('updated_at', { mode: 'timestamp' }),
206
+ })
207
+ ```
208
+
209
+ ## Performance Considerations
210
+
211
+ ### Frontend
212
+
213
+ - **Selector Hooks**: Use precise selectors to minimize re-renders
214
+ - **Code Splitting**: Lazy load routes/components
215
+ - **Bundle Size**: Tree-shaking with Vite
216
+
217
+ ### Backend
218
+
219
+ - **Connection Pooling**: Reuse database connections
220
+ - **Query Optimization**: Index frequently queried columns
221
+ - **Caching**: Consider Redis for production
222
+
223
+ ### Real-time
224
+
225
+ - **WebSocket**: Connection pooling, message batching
226
+ - **SSE**: Automatic reconnection, event buffering
227
+
228
+ ## Security Best Practices
229
+
230
+ 1. **Input Validation**: Zod schemas on all endpoints
231
+ 2. **SQL Injection**: Drizzle ORM parameterized queries
232
+ 3. **CORS**: Whitelist origins in production
233
+ 4. **Environment Variables**: Never commit `.env` files
234
+ 5. **Error Messages**: Don't leak sensitive info
235
+ 6. **WebSocket**: Validate all incoming messages
236
+ 7. **SSE**: Rate limiting on event streams
237
+
238
+ ## Migration Path
239
+
240
+ ### From Mock to Real Backend
241
+
242
+ 1. Set `USE_MOCK_SERVER = false` in `apiClient.ts`
243
+ 2. Configure production API base URL
244
+ 3. Deploy backend separately
245
+ 4. Update CORS configuration
246
+
247
+ ### From SQLite to PostgreSQL
248
+
249
+ 1. Update `drizzle.config.ts`
250
+ 2. Change `sqliteTable` to `pgTable`
251
+ 3. Update column types
252
+ 4. Run `drizzle-kit push`
253
+
254
+ ### Adding Real-time Features
255
+
256
+ 1. Define protocol schema (`WSProtocol` or `SSEProtocol`)
257
+ 2. Create route with schema
258
+ 3. Implement server-side logic
259
+ 4. Use `$ws()` or `$sse()` on client
260
+ 5. Add tests (with or without server)