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,66 @@
1
+ import { useCallback, useEffect, useRef, useState } from 'react'
2
+ import type { WSClient, WSProtocol, WSStatus } from '@shared/schemas'
3
+
4
+ interface UseWebSocketReturn<T extends WSProtocol> {
5
+ status: WSStatus
6
+ connect: () => void
7
+ disconnect: () => void
8
+ call: WSClient<T>['call']
9
+ emit: WSClient<T>['emit']
10
+ on: WSClient<T>['on']
11
+ client: WSClient<T> | null
12
+ }
13
+
14
+ export function useWebSocket<T extends WSProtocol>(route: {
15
+ $ws: () => WSClient<T>
16
+ }): UseWebSocketReturn<T> {
17
+ const [status, setStatus] = useState<WSStatus>('closed')
18
+ const clientRef = useRef<WSClient<T> | null>(null)
19
+
20
+ const connect = useCallback(() => {
21
+ if (clientRef.current) return
22
+
23
+ const client = route.$ws()
24
+ clientRef.current = client
25
+
26
+ client.onStatusChange(setStatus)
27
+ }, [route])
28
+
29
+ const disconnect = useCallback(() => {
30
+ if (clientRef.current) {
31
+ clientRef.current.close()
32
+ clientRef.current = null
33
+ setStatus('closed')
34
+ }
35
+ }, [])
36
+
37
+ const call = useCallback(async (method: keyof T['rpc'], params: unknown) => {
38
+ if (!clientRef.current) throw new Error('WebSocket not connected')
39
+ return clientRef.current.call(method as never, params as never)
40
+ }, []) as WSClient<T>['call']
41
+
42
+ const emit = useCallback((type: keyof T['events'], payload: unknown) => {
43
+ clientRef.current?.emit(type as never, payload as never)
44
+ }, []) as WSClient<T>['emit']
45
+
46
+ const on = useCallback((type: keyof T['events'], handler: (payload: unknown) => void) => {
47
+ if (!clientRef.current) return () => {}
48
+ return clientRef.current.on(type as never, handler as never)
49
+ }, []) as WSClient<T>['on']
50
+
51
+ useEffect(() => {
52
+ return () => {
53
+ disconnect()
54
+ }
55
+ }, [disconnect])
56
+
57
+ return {
58
+ status,
59
+ connect,
60
+ disconnect,
61
+ call,
62
+ emit,
63
+ on,
64
+ client: clientRef.current,
65
+ }
66
+ }
@@ -0,0 +1,5 @@
1
+ export * from './constants'
2
+ export * from './core'
3
+ export * from './hooks'
4
+ export * from './modules'
5
+ export * from './schemas'
@@ -0,0 +1 @@
1
+ export * from './schemas'
@@ -0,0 +1,100 @@
1
+ import { z } from '@hono/zod-openapi'
2
+ import { RoleEnum, PermissionEnum } from '@shared/modules/permission'
3
+
4
+ export const SystemStatsSchema = z.object({
5
+ totalTodos: z.number(),
6
+ pendingTodos: z.number(),
7
+ completedTodos: z.number(),
8
+ lastUpdated: z.string(),
9
+ })
10
+
11
+ export const HealthCheckSchema = z.object({
12
+ database: z.enum(['connected', 'disconnected']),
13
+ timestamp: z.string(),
14
+ })
15
+
16
+ export const RecentActivityItemSchema = z.object({
17
+ id: z.number(),
18
+ title: z.string(),
19
+ status: z.string(),
20
+ updatedAt: z.string(),
21
+ })
22
+
23
+ export const RecentActivitySchema = z.array(RecentActivityItemSchema)
24
+
25
+ export const AuthUserSchema = z.object({
26
+ id: z.string(),
27
+ username: z.string(),
28
+ email: z.string(),
29
+ role: RoleEnum,
30
+ avatar: z.string().nullish(),
31
+ permissions: z.array(PermissionEnum),
32
+ })
33
+
34
+ export const LoginRequestSchema = z.object({
35
+ username: z.string().min(1),
36
+ password: z.string().min(6),
37
+ })
38
+
39
+ export const LoginResponseSchema = z.object({
40
+ user: AuthUserSchema,
41
+ token: z.string(),
42
+ })
43
+
44
+ export const RegisterRequestSchema = z.object({
45
+ username: z.string().min(1),
46
+ email: z.string().email(),
47
+ password: z.string().min(6),
48
+ })
49
+
50
+ export const UserSchema = z.object({
51
+ id: z.string(),
52
+ username: z.string(),
53
+ email: z.string(),
54
+ role: RoleEnum,
55
+ status: z.enum(['active', 'inactive', 'locked']),
56
+ avatar: z.string().nullish(),
57
+ createdAt: z.string(),
58
+ updatedAt: z.string(),
59
+ })
60
+
61
+ export const UserListSchema = z.array(UserSchema)
62
+
63
+ export const UpdateUserRequestSchema = z.object({
64
+ username: z.string().nullish(),
65
+ email: z.string().email().nullish(),
66
+ role: RoleEnum.nullish(),
67
+ status: z.enum(['active', 'inactive', 'locked']).nullish(),
68
+ })
69
+
70
+ export const CreateUserRequestSchema = z.object({
71
+ username: z.string().min(1),
72
+ email: z.string().email(),
73
+ password: z.string().min(6),
74
+ role: RoleEnum,
75
+ status: z.enum(['active', 'inactive', 'locked']).nullish().default('active'),
76
+ })
77
+
78
+ export const ClearTodosResultSchema = z.object({
79
+ deletedCount: z.number(),
80
+ })
81
+
82
+ export const SuccessSchema = z.object({})
83
+
84
+ export const DownloadTokenSchema = z.object({
85
+ token: z.string(),
86
+ downloadUrl: z.string(),
87
+ expiresIn: z.number(),
88
+ })
89
+
90
+ export type SystemStats = z.infer<typeof SystemStatsSchema>
91
+ export type HealthCheck = z.infer<typeof HealthCheckSchema>
92
+ export type RecentActivityItem = z.infer<typeof RecentActivityItemSchema>
93
+ export type AuthUserResponse = z.infer<typeof AuthUserSchema>
94
+ export type CreateUserRequest = z.infer<typeof CreateUserRequestSchema>
95
+ export type LoginRequest = z.infer<typeof LoginRequestSchema>
96
+ export type LoginResponse = z.infer<typeof LoginResponseSchema>
97
+ export type RegisterRequest = z.infer<typeof RegisterRequestSchema>
98
+ export type User = z.infer<typeof UserSchema>
99
+ export type UpdateUserRequest = z.infer<typeof UpdateUserRequestSchema>
100
+ export type ClearTodosResult = z.infer<typeof ClearTodosResultSchema>
@@ -0,0 +1 @@
1
+ export * from './schemas'
@@ -0,0 +1,24 @@
1
+ import { z } from '@hono/zod-openapi'
2
+ import { RESOURCE_TYPES, ACTION_TYPES, type ResourceType, type ActionType } from '@shared/constants'
3
+
4
+ export const ResourceTypeSchema = z.enum(
5
+ Object.values(RESOURCE_TYPES) as [ResourceType, ...ResourceType[]]
6
+ )
7
+ export const ActionTypeSchema = z.enum(Object.values(ACTION_TYPES) as [ActionType, ...ActionType[]])
8
+
9
+ export const AuditLogSchema = z.object({
10
+ id: z.string(),
11
+ userId: z.string(),
12
+ action: ActionTypeSchema,
13
+ resourceType: ResourceTypeSchema,
14
+ resourceId: z.string().nullable(),
15
+ oldValue: z.string().nullable(),
16
+ newValue: z.string().nullable(),
17
+ ipAddress: z.string().nullable(),
18
+ userAgent: z.string().nullable(),
19
+ createdAt: z
20
+ .union([z.string(), z.date()])
21
+ .transform(v => (v instanceof Date ? v.toISOString() : v)),
22
+ })
23
+
24
+ export type AuditLogType = z.infer<typeof AuditLogSchema>
@@ -0,0 +1 @@
1
+ export * from './schemas'
@@ -0,0 +1,19 @@
1
+ import { z } from '@hono/zod-openapi'
2
+
3
+ export const CaptchaResponseSchema = z.object({
4
+ id: z.string(),
5
+ image: z.string(),
6
+ })
7
+
8
+ export const VerifyCaptchaRequestSchema = z.object({
9
+ id: z.string(),
10
+ code: z.string(),
11
+ })
12
+
13
+ export const CaptchaVerifyResponseSchema = z.object({
14
+ message: z.string(),
15
+ })
16
+
17
+ export type CaptchaResponse = z.infer<typeof CaptchaResponseSchema>
18
+ export type VerifyCaptchaRequest = z.infer<typeof VerifyCaptchaRequestSchema>
19
+ export type CaptchaVerifyResponse = z.infer<typeof CaptchaVerifyResponseSchema>
@@ -0,0 +1,38 @@
1
+ import { z } from '@hono/zod-openapi'
2
+
3
+ export const ChatProtocolSchema = z.object({
4
+ rpc: z.object({
5
+ echo: z.object({
6
+ in: z.object({ message: z.string() }),
7
+ out: z.object({ message: z.string(), timestamp: z.number() }),
8
+ }),
9
+ ping: z.object({
10
+ in: z.object({}),
11
+ out: z.object({ pong: z.boolean(), timestamp: z.number() }),
12
+ }),
13
+ }),
14
+ events: z.object({
15
+ notification: z.object({
16
+ title: z.string(),
17
+ body: z.string(),
18
+ timestamp: z.number(),
19
+ }),
20
+ broadcast: z.object({
21
+ message: z.string(),
22
+ timestamp: z.number(),
23
+ }),
24
+ connected: z.object({
25
+ timestamp: z.number(),
26
+ }),
27
+ disconnected: z.object({
28
+ timestamp: z.number(),
29
+ }),
30
+ }),
31
+ })
32
+
33
+ export const WebSocketStatusSchema = z.object({
34
+ connectedClients: z.number(),
35
+ })
36
+
37
+ export type ChatProtocol = z.infer<typeof ChatProtocolSchema>
38
+ export type WebSocketStatus = z.infer<typeof WebSocketStatusSchema>
@@ -0,0 +1 @@
1
+ export * from './schemas'
@@ -0,0 +1,53 @@
1
+ import { z } from '@hono/zod-openapi'
2
+
3
+ export const ContentCategorySchema = z.enum([
4
+ 'article',
5
+ 'announcement',
6
+ 'tutorial',
7
+ 'news',
8
+ 'policy',
9
+ ])
10
+ export const ContentStatusSchema = z.enum(['draft', 'published', 'archived'])
11
+
12
+ export const ContentSchema = z.object({
13
+ id: z.string(),
14
+ title: z.string(),
15
+ content: z.string(),
16
+ category: ContentCategorySchema,
17
+ status: ContentStatusSchema,
18
+ author: z.string(),
19
+ tags: z.array(z.string()),
20
+ viewCount: z.number(),
21
+ likeCount: z.number(),
22
+ createdAt: z.string(),
23
+ updatedAt: z.string(),
24
+ publishedAt: z.string().nullish(),
25
+ })
26
+
27
+ export const CreateContentSchema = z.object({
28
+ title: z.string(),
29
+ content: z.string(),
30
+ category: ContentCategorySchema,
31
+ tags: z.array(z.string()).nullish(),
32
+ })
33
+
34
+ export const UpdateContentSchema = z.object({
35
+ title: z.string().nullish(),
36
+ content: z.string().nullish(),
37
+ category: ContentCategorySchema.nullish(),
38
+ tags: z.array(z.string()).nullish(),
39
+ status: ContentStatusSchema.nullish(),
40
+ })
41
+
42
+ export const ContentListSchema = z.array(ContentSchema)
43
+
44
+ export const DeleteResultSchema = z.object({
45
+ message: z.string(),
46
+ })
47
+
48
+ export type ContentCategory = z.infer<typeof ContentCategorySchema>
49
+ export type ContentStatus = z.infer<typeof ContentStatusSchema>
50
+ export type Content = z.infer<typeof ContentSchema>
51
+ export type CreateContentInput = z.infer<typeof CreateContentSchema>
52
+ export type UpdateContentInput = z.infer<typeof UpdateContentSchema>
53
+ export type DeleteResult = z.infer<typeof DeleteResultSchema>
@@ -0,0 +1 @@
1
+ export * from './schemas'
@@ -0,0 +1,62 @@
1
+ import { z } from '@hono/zod-openapi'
2
+
3
+ export const DisputeTypeSchema = z.enum([
4
+ 'refund',
5
+ 'product_quality',
6
+ 'service_quality',
7
+ 'delivery',
8
+ 'other',
9
+ ])
10
+ export const DisputeStatusSchema = z.enum(['pending', 'investigating', 'resolved', 'rejected'])
11
+
12
+ export const DisputeSchema = z.object({
13
+ id: z.string(),
14
+ disputeNo: z.string(),
15
+ orderId: z.string(),
16
+ orderNo: z.string(),
17
+ customerName: z.string(),
18
+ customerEmail: z.string(),
19
+ type: DisputeTypeSchema,
20
+ status: DisputeStatusSchema,
21
+ description: z.string(),
22
+ resolution: z.string().nullish(),
23
+ amount: z.number(),
24
+ createdAt: z.string(),
25
+ updatedAt: z.string(),
26
+ resolvedAt: z.string().nullish(),
27
+ resolvedBy: z.string().nullish(),
28
+ })
29
+
30
+ export const CreateDisputeSchema = z.object({
31
+ orderId: z.string(),
32
+ orderNo: z.string(),
33
+ customerName: z.string(),
34
+ customerEmail: z.string().email(),
35
+ type: DisputeTypeSchema,
36
+ description: z.string(),
37
+ amount: z.number().positive(),
38
+ })
39
+
40
+ export const UpdateDisputeSchema = z.object({
41
+ status: DisputeStatusSchema.nullish(),
42
+ resolution: z.string().nullish(),
43
+ })
44
+
45
+ export const ResolveDisputeSchema = z.object({
46
+ resolution: z.string(),
47
+ resolvedBy: z.string(),
48
+ })
49
+
50
+ export const DisputeListSchema = z.array(DisputeSchema)
51
+
52
+ export const DeleteResultSchema = z.object({
53
+ message: z.string(),
54
+ })
55
+
56
+ export type DisputeType = z.infer<typeof DisputeTypeSchema>
57
+ export type DisputeStatus = z.infer<typeof DisputeStatusSchema>
58
+ export type Dispute = z.infer<typeof DisputeSchema>
59
+ export type CreateDisputeInput = z.infer<typeof CreateDisputeSchema>
60
+ export type UpdateDisputeInput = z.infer<typeof UpdateDisputeSchema>
61
+ export type ResolveDisputeInput = z.infer<typeof ResolveDisputeSchema>
62
+ export type DeleteResult = z.infer<typeof DeleteResultSchema>
@@ -0,0 +1,11 @@
1
+ export {
2
+ FileDownloadSchema,
3
+ PrivateFileQuerySchema,
4
+ PublicFileUrlSchema,
5
+ PrivateFileUrlSchema,
6
+ GenerateUrlRequestSchema,
7
+ FileUrlResponseSchema,
8
+ EmptySchema,
9
+ UploadResultSchema,
10
+ UploadFileBodySchema,
11
+ } from './schemas'
@@ -0,0 +1,44 @@
1
+ import { z } from '@hono/zod-openapi'
2
+
3
+ export const FileDownloadSchema = z.object({
4
+ namespace: z.string(),
5
+ filename: z.string(),
6
+ })
7
+
8
+ export const PrivateFileQuerySchema = z.object({
9
+ expiry: z.string().transform(Number),
10
+ signature: z.string(),
11
+ })
12
+
13
+ export const PublicFileUrlSchema = z.object({
14
+ url: z.string(),
15
+ })
16
+
17
+ export const PrivateFileUrlSchema = z.object({
18
+ url: z.string(),
19
+ expiry: z.number(),
20
+ })
21
+
22
+ export const GenerateUrlRequestSchema = z.object({
23
+ namespace: z.string(),
24
+ filename: z.string(),
25
+ isPrivate: z.boolean().nullish().default(false),
26
+ expirySeconds: z.number().nullish(),
27
+ })
28
+
29
+ export const FileUrlResponseSchema = z.union([PublicFileUrlSchema, PrivateFileUrlSchema])
30
+
31
+ export const EmptySchema = z.object({})
32
+
33
+ export const UploadResultSchema = z.object({
34
+ filename: z.string(),
35
+ originalName: z.string(),
36
+ mimeType: z.string(),
37
+ size: z.number(),
38
+ url: z.string(),
39
+ })
40
+
41
+ export const UploadFileBodySchema = z.object({
42
+ file: z.instanceof(File),
43
+ namespace: z.string().nullish().default('uploads'),
44
+ })
@@ -0,0 +1,70 @@
1
+ export { ChatProtocolSchema, type ChatProtocol } from './chat'
2
+ export {
3
+ TodoSchema,
4
+ TodoStatusSchema,
5
+ CreateTodoSchema,
6
+ UpdateTodoSchema,
7
+ TodoIdSchema,
8
+ type Todo,
9
+ type TodoStatus,
10
+ type CreateTodoInput,
11
+ type UpdateTodoInput,
12
+ } from './todos'
13
+ export {
14
+ FileDownloadSchema,
15
+ PrivateFileQuerySchema,
16
+ PublicFileUrlSchema,
17
+ PrivateFileUrlSchema,
18
+ GenerateUrlRequestSchema,
19
+ FileUrlResponseSchema,
20
+ EmptySchema,
21
+ } from './files'
22
+ export {
23
+ NotificationSchema,
24
+ NotificationTypeSchema,
25
+ CreateNotificationSchema,
26
+ NotificationListQuerySchema,
27
+ SSEEventSchema,
28
+ AppSSEProtocolSchema,
29
+ type AppNotification,
30
+ type NotificationType,
31
+ type CreateNotificationInput,
32
+ type NotificationListQuery,
33
+ type SSEEvent,
34
+ type AppSSEProtocol,
35
+ } from './notifications'
36
+ export {
37
+ SystemStatsSchema,
38
+ HealthCheckSchema,
39
+ RecentActivityItemSchema,
40
+ RecentActivitySchema,
41
+ AuthUserSchema,
42
+ ClearTodosResultSchema,
43
+ type SystemStats,
44
+ type HealthCheck,
45
+ type RecentActivityItem,
46
+ type AuthUserResponse,
47
+ type ClearTodosResult,
48
+ } from './admin'
49
+ export {
50
+ RoleEnum,
51
+ RoleInfoSchema,
52
+ PermissionInfoSchema,
53
+ UserPermissionsSchema,
54
+ RoleListSchema,
55
+ PermissionListSchema,
56
+ Role,
57
+ Permission,
58
+ ROLE_PERMISSIONS,
59
+ ROLE_LABELS,
60
+ PERMISSION_LABELS,
61
+ PERMISSION_CATEGORIES,
62
+ getPermissionsByRole,
63
+ hasPermission,
64
+ hasAnyPermission,
65
+ hasAllPermissions,
66
+ type RoleType,
67
+ type RoleInfo,
68
+ type PermissionInfo,
69
+ type UserPermissions,
70
+ } from './permission'
@@ -0,0 +1,26 @@
1
+ export {
2
+ NotificationSchema,
3
+ NotificationTypeSchema,
4
+ CreateNotificationSchema,
5
+ NotificationListQuerySchema,
6
+ SSEEventSchema,
7
+ AppSSEProtocolSchema,
8
+ UnreadCountSchema,
9
+ NotificationIdSchema,
10
+ UnreadCountEventSchema,
11
+ NotificationListSchema,
12
+ MarkAllReadResultSchema,
13
+ TestNotificationRequestSchema,
14
+ type AppNotification,
15
+ type NotificationType,
16
+ type CreateNotificationInput,
17
+ type NotificationListQuery,
18
+ type SSEEvent,
19
+ type AppSSEProtocol,
20
+ type UnreadCount,
21
+ type NotificationId,
22
+ type UnreadCountEvent,
23
+ type NotificationList,
24
+ type MarkAllReadResult,
25
+ type TestNotificationRequest,
26
+ } from './schemas'
@@ -0,0 +1,73 @@
1
+ import { z } from '@hono/zod-openapi'
2
+
3
+ export const NotificationTypeSchema = z.enum(['info', 'warning', 'success', 'error'])
4
+
5
+ export const NotificationSchema = z.object({
6
+ id: z.string().uuid(),
7
+ type: NotificationTypeSchema,
8
+ title: z.string().min(1).max(200),
9
+ message: z.string().max(2000),
10
+ read: z.boolean().default(false),
11
+ createdAt: z.string().datetime(),
12
+ })
13
+
14
+ export const CreateNotificationSchema = z.object({
15
+ type: NotificationTypeSchema,
16
+ title: z.string().min(1, 'Title is required').max(200, 'Title too long'),
17
+ message: z.string().min(1, 'Message is required').max(2000, 'Message too long'),
18
+ })
19
+
20
+ export const NotificationListQuerySchema = z.object({
21
+ unreadOnly: z.coerce.boolean().nullish().default(false),
22
+ limit: z.coerce.number().int().min(1).max(100).nullish().default(20),
23
+ cursor: z.string().nullish(),
24
+ })
25
+
26
+ export const SSEEventSchema = z.object({
27
+ event: z.enum(['notification', 'ping', 'connected']),
28
+ data: z.union([NotificationSchema, z.object({ timestamp: z.number() })]),
29
+ })
30
+
31
+ export const UnreadCountEventSchema = z.object({
32
+ count: z.number(),
33
+ })
34
+
35
+ export const AppSSEProtocolSchema = z.object({
36
+ events: z.object({
37
+ notification: NotificationSchema,
38
+ 'unread-count': UnreadCountEventSchema,
39
+ ping: z.object({ timestamp: z.number() }),
40
+ connected: z.object({ timestamp: z.number() }),
41
+ }),
42
+ })
43
+
44
+ export const UnreadCountSchema = z.object({
45
+ count: z.number(),
46
+ })
47
+
48
+ export const NotificationIdSchema = z.object({
49
+ id: z.string(),
50
+ })
51
+
52
+ export const NotificationListSchema = z.array(NotificationSchema)
53
+
54
+ export const MarkAllReadResultSchema = z.object({
55
+ count: z.number(),
56
+ })
57
+
58
+ export const TestNotificationRequestSchema = z.object({
59
+ type: NotificationTypeSchema.nullish().default('info'),
60
+ })
61
+
62
+ export type NotificationType = z.infer<typeof NotificationTypeSchema>
63
+ export type AppNotification = z.infer<typeof NotificationSchema>
64
+ export type CreateNotificationInput = z.infer<typeof CreateNotificationSchema>
65
+ export type NotificationListQuery = z.infer<typeof NotificationListQuerySchema>
66
+ export type SSEEvent = z.infer<typeof SSEEventSchema>
67
+ export type UnreadCountEvent = z.infer<typeof UnreadCountEventSchema>
68
+ export type AppSSEProtocol = z.infer<typeof AppSSEProtocolSchema>
69
+ export type UnreadCount = z.infer<typeof UnreadCountSchema>
70
+ export type NotificationId = z.infer<typeof NotificationIdSchema>
71
+ export type NotificationList = z.infer<typeof NotificationListSchema>
72
+ export type MarkAllReadResult = z.infer<typeof MarkAllReadResultSchema>
73
+ export type TestNotificationRequest = z.infer<typeof TestNotificationRequestSchema>
@@ -0,0 +1 @@
1
+ export * from './schemas'
@@ -0,0 +1,63 @@
1
+ import { z } from '@hono/zod-openapi'
2
+
3
+ export const OrderStatusSchema = z.enum([
4
+ 'pending',
5
+ 'processing',
6
+ 'completed',
7
+ 'cancelled',
8
+ 'disputed',
9
+ ])
10
+
11
+ export const OrderSchema = z.object({
12
+ id: z.string(),
13
+ orderNo: z.string(),
14
+ customerName: z.string(),
15
+ customerEmail: z.string(),
16
+ productName: z.string(),
17
+ amount: z.number(),
18
+ status: OrderStatusSchema,
19
+ createdAt: z.string(),
20
+ updatedAt: z.string(),
21
+ })
22
+
23
+ export const CreateOrderSchema = z.object({
24
+ customerName: z.string(),
25
+ customerEmail: z.string().email(),
26
+ productName: z.string(),
27
+ amount: z.number().positive(),
28
+ })
29
+
30
+ export const UpdateOrderSchema = z.object({
31
+ status: OrderStatusSchema.nullish(),
32
+ })
33
+
34
+ export const OrderListSchema = z.array(OrderSchema)
35
+
36
+ export const OrderQuerySchema = z.object({
37
+ status: OrderStatusSchema.nullish(),
38
+ customerName: z.string().nullish(),
39
+ limit: z.coerce.number().int().positive().max(100).default(20),
40
+ offset: z.coerce.number().int().min(0).default(0),
41
+ })
42
+
43
+ export const DeleteResultSchema = z.object({
44
+ message: z.string(),
45
+ })
46
+
47
+ export const ProcessOrderSchema = z.object({
48
+ orderId: z.string(),
49
+ })
50
+
51
+ export const CancelOrderSchema = z.object({
52
+ orderId: z.string(),
53
+ reason: z.string().nullish(),
54
+ })
55
+
56
+ export type OrderStatus = z.infer<typeof OrderStatusSchema>
57
+ export type Order = z.infer<typeof OrderSchema>
58
+ export type CreateOrderInput = z.infer<typeof CreateOrderSchema>
59
+ export type UpdateOrderInput = z.infer<typeof UpdateOrderSchema>
60
+ export type DeleteResult = z.infer<typeof DeleteResultSchema>
61
+ export type ProcessOrderInput = z.infer<typeof ProcessOrderSchema>
62
+ export type CancelOrderInput = z.infer<typeof CancelOrderSchema>
63
+ export type OrderQueryInput = z.infer<typeof OrderQuerySchema>