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.
- package/README.md +154 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +439 -0
- package/dist/cli/index.js.map +1 -0
- package/package.json +171 -0
- package/template/.agents/skills/writing-hookify-rules/SKILL.md +408 -0
- package/template/.ai-context.md +368 -0
- package/template/.claude/hookify.block-dangerous-commands.local.md +41 -0
- package/template/.claude/hookify.check-api-types.local.md +111 -0
- package/template/.claude/hookify.check-duplicate-types.local.md +287 -0
- package/template/.claude/hookify.check-test-assertions.local.md +93 -0
- package/template/.claude/hookify.remind-add-tests.local.md +209 -0
- package/template/.claude/hookify.remind-db-migration.local.md +58 -0
- package/template/.claude/hookify.remind-run-tests.local.md +52 -0
- package/template/.claude/hookify.warn-any-type.local.md +203 -0
- package/template/.claude/hookify.warn-console-log.local.md +73 -0
- package/template/.claude/rules/00-project-config.md +147 -0
- package/template/.claude/rules/01-file-types.md +127 -0
- package/template/.claude/rules/02-git-workflow.md +167 -0
- package/template/.claude/rules/10-api-type-inference.md +555 -0
- package/template/.claude/rules/20-server-api.md +349 -0
- package/template/.claude/rules/21-server-entrypoint.md +257 -0
- package/template/.claude/rules/30-client-components.md +314 -0
- package/template/.claude/rules/31-client-services.md +768 -0
- package/template/.claude/rules/32-client-state-zustand.md +324 -0
- package/template/.claude/rules/33-client-app-entry.md +276 -0
- package/template/.claude/rules/34-client-admin-module.md +445 -0
- package/template/.claude/rules/35-cli-module.md +259 -0
- package/template/.claude/rules/40-admin-module.md +495 -0
- package/template/.claude/rules/40-shared-types.md +450 -0
- package/template/.claude/rules/50-websocket.md +245 -0
- package/template/.claude/rules/51-sse.md +372 -0
- package/template/.claude/rules/52-cloudflare-realtime.md +384 -0
- package/template/.claude/rules/60-testing-standards.md +245 -0
- package/template/.claude/rules/61-hono-testing.md +200 -0
- package/template/.claude/scripts/README.md +187 -0
- package/template/.claude/scripts/check-duplicate-types.ts +188 -0
- package/template/.claude/scripts/post-edit-check-incremental.sh +61 -0
- package/template/.claude/scripts/post-edit-check.sh +22 -0
- package/template/.claude/scripts/pre-tool-use-check.sh +86 -0
- package/template/.claude/scripts/test-pre-tool-use.sh +73 -0
- package/template/.claude/scripts/validate-git-changes.sh +38 -0
- package/template/.claude/settings.json +32 -0
- package/template/.claude/skills/writing-hookify-rules/SKILL.md +408 -0
- package/template/.dev-context-compact.md +54 -0
- package/template/.dev-context.md +621 -0
- package/template/.dev-guide.md +243 -0
- package/template/.env.example +60 -0
- package/template/.eslintrc.routes.json +39 -0
- package/template/.husky/_/husky.sh +27 -0
- package/template/.husky/commit-msg +4 -0
- package/template/.husky/post-commit +4 -0
- package/template/.husky/pre-commit +19 -0
- package/template/.husky/pre-push +12 -0
- package/template/.prettierignore +22 -0
- package/template/.prettierrc +8 -0
- package/template/.sessions/3/2026-03-26T05-41-09-154Z_03bb597f-3898-4a2e-8c08-5746bbe8d95e.jsonl +18 -0
- package/template/.sessions/3/2026-03-26T05-48-30-052Z_12de4774-9cb3-494c-9852-bd1e6b0003c3.jsonl +6 -0
- package/template/.vscode/extensions.json +8 -0
- package/template/.vscode/settings.json +4 -0
- package/template/.workspaces/3/hello.py +1 -0
- package/template/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/803c2e37182b913f8857edf6d8776515cef4af6d48fcb25913e457f4b14ffa97.sqlite +0 -0
- package/template/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/803c2e37182b913f8857edf6d8776515cef4af6d48fcb25913e457f4b14ffa97.sqlite-shm +0 -0
- package/template/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/803c2e37182b913f8857edf6d8776515cef4af6d48fcb25913e457f4b14ffa97.sqlite-wal +0 -0
- package/template/CLAUDE.md +296 -0
- package/template/DESIGN.md +260 -0
- package/template/DEV_CONTEXT_GUIDE.md +366 -0
- package/template/DEV_TOOLS_README.md +396 -0
- package/template/FRAMEWORK_HISTORY.md +34 -0
- package/template/PROJECT_SUMMARY.md +325 -0
- package/template/QUICKSTART.md +305 -0
- package/template/README.md +154 -0
- package/template/STRUCTURE.txt +81 -0
- package/template/admin.html +13 -0
- package/template/auth-inject.html +33 -0
- package/template/commitlint.config.js +12 -0
- package/template/docs/PERMISSION_ARCHITECTURE.md +279 -0
- package/template/docs/PERMISSION_EXAMPLES.md +230 -0
- package/template/docs/PERMISSION_SYSTEM.md +301 -0
- package/template/docs/SMART_TEST.md +171 -0
- package/template/docs/runtime-abstract.md +253 -0
- package/template/drizzle/0000_rainy_boomer.sql +101 -0
- package/template/drizzle/0001_add_todo_attachments.sql +12 -0
- package/template/drizzle/0002_chilly_magneto.sql +89 -0
- package/template/drizzle/meta/0000_snapshot.json +652 -0
- package/template/drizzle/meta/0001_snapshot.json +735 -0
- package/template/drizzle/meta/0002_snapshot.json +1198 -0
- package/template/drizzle/meta/_journal.json +27 -0
- package/template/drizzle.config.ts +13 -0
- package/template/eslint-rules/README-no-middleware-in-routes.md +154 -0
- package/template/eslint-rules/__tests__/enforce-valid-method.test.ts +251 -0
- package/template/eslint-rules/__tests__/layer-boundary.test.ts +102 -0
- package/template/eslint-rules/__tests__/module-boundary.test.ts +77 -0
- package/template/eslint-rules/__tests__/no-direct-zod-import-in-file-routes.test.ts +45 -0
- package/template/eslint-rules/__tests__/no-new-old-service-naming.test.ts +76 -0
- package/template/eslint-rules/e2e-test-location.js +153 -0
- package/template/eslint-rules/enforce-valid-method.js +217 -0
- package/template/eslint-rules/flat-routes-services.js +69 -0
- package/template/eslint-rules/framework-protect.js +186 -0
- package/template/eslint-rules/layer-boundary.js +164 -0
- package/template/eslint-rules/limit-type-complexity.js +130 -0
- package/template/eslint-rules/middleware-location.js +162 -0
- package/template/eslint-rules/module-boundary.js +125 -0
- package/template/eslint-rules/no-ambiguous-file-paths.js +64 -0
- package/template/eslint-rules/no-any-on-apiclient.js +173 -0
- package/template/eslint-rules/no-boolean-success.js +43 -0
- package/template/eslint-rules/no-deep-relative-imports.js +69 -0
- package/template/eslint-rules/no-direct-fetch.js +122 -0
- package/template/eslint-rules/no-direct-ws-sse.js +57 -0
- package/template/eslint-rules/no-direct-zod-import-in-file-routes.js +54 -0
- package/template/eslint-rules/no-disable-direct-fetch.js +57 -0
- package/template/eslint-rules/no-disable-type-safe-client.js +58 -0
- package/template/eslint-rules/no-inline-schema.js +220 -0
- package/template/eslint-rules/no-middleware-in-routes.js +81 -0
- package/template/eslint-rules/no-new-old-service-naming.js +123 -0
- package/template/eslint-rules/no-type-assertion-in-rpc.js +99 -0
- package/template/eslint-rules/no-type-assertion-on-shared-types.js +109 -0
- package/template/eslint-rules/no-util-functions-in-service.js +128 -0
- package/template/eslint-rules/prefer-shared-types.js +352 -0
- package/template/eslint-rules/protect-ws-sse-interface.js +66 -0
- package/template/eslint-rules/require-antd-generic-types.js +73 -0
- package/template/eslint-rules/require-file-openapi-props.js +114 -0
- package/template/eslint-rules/require-hono-chain-syntax.js +129 -0
- package/template/eslint-rules/require-nullable-for-optional.js +99 -0
- package/template/eslint-rules/require-response-helpers.js +140 -0
- package/template/eslint-rules/require-type-safe-test-client.js +106 -0
- package/template/eslint-rules/route-location.js +72 -0
- package/template/eslint.config.js +231 -0
- package/template/index.html +17 -0
- package/template/lint-scripts/DIRECTORY_RULES.md +335 -0
- package/template/lint-scripts/README.md +299 -0
- package/template/lint-scripts/TESTING.md +273 -0
- package/template/lint-scripts/ai-context-generator.ts +159 -0
- package/template/lint-scripts/check-framework-modify.sh +8 -0
- package/template/lint-scripts/check-menu-permissions.js +242 -0
- package/template/lint-scripts/check-refs.ts +165 -0
- package/template/lint-scripts/check-route-auth-complete.js +260 -0
- package/template/lint-scripts/check-route-auth.js +212 -0
- package/template/lint-scripts/check-route-permissions.js +210 -0
- package/template/lint-scripts/config/project.config.ts +358 -0
- package/template/lint-scripts/dev-context-analyzer.ts +707 -0
- package/template/lint-scripts/dev-guide-generator.ts +830 -0
- package/template/lint-scripts/dev-server.ts +58 -0
- package/template/lint-scripts/eslint-route-auth.js +158 -0
- package/template/lint-scripts/eslint-routes-permission.js +147 -0
- package/template/lint-scripts/fix-route-auth.js +245 -0
- package/template/lint-scripts/framework/check-modify.ts +152 -0
- package/template/lint-scripts/framework/hash-utils.ts +180 -0
- package/template/lint-scripts/framework/init-baseline.ts +84 -0
- package/template/lint-scripts/framework/update-baseline.ts +148 -0
- package/template/lint-scripts/post-commit-track.ts +66 -0
- package/template/lint-scripts/quick-test.sh +27 -0
- package/template/lint-scripts/smart-test.ts +268 -0
- package/template/lint-scripts/test-history.ts +360 -0
- package/template/lint-scripts/test-tracker.ts +350 -0
- package/template/lint-scripts/validate-all.ts +250 -0
- package/template/lint-scripts/validators/api-coverage.validator.ts +355 -0
- package/template/lint-scripts/validators/client-rpc.validator.ts +190 -0
- package/template/lint-scripts/validators/client-tests.validator.ts +155 -0
- package/template/lint-scripts/validators/console-log.validator.ts +122 -0
- package/template/lint-scripts/validators/directory-structure.validator.ts +181 -0
- package/template/lint-scripts/validators/imports.validator.ts +180 -0
- package/template/lint-scripts/validators/index.ts +271 -0
- package/template/lint-scripts/validators/md-refs.validator.ts +165 -0
- package/template/lint-scripts/validators/module-tests.validator.ts +112 -0
- package/template/lint-scripts/validators/sensitive.validator.ts +185 -0
- package/template/lint-scripts/validators/server-rpc.validator.ts +141 -0
- package/template/lint-scripts/validators/test-quality.validator.ts +257 -0
- package/template/lint-scripts/validators/todos.validator.ts +126 -0
- package/template/lint-scripts/watch-validator.ts +131 -0
- package/template/modules.config.ts +71 -0
- package/template/package-lock.json +14554 -0
- package/template/package.json +158 -0
- package/template/patches/@hono+zod-openapi+1.2.2.patch +67 -0
- package/template/patches/@hono+zod-validator+0.7.6.patch +13 -0
- package/template/patches/hono+4.12.16.patch +246 -0
- package/template/patches/typescript+5.8.3.patch +26 -0
- package/template/playwright.config.ts +60 -0
- package/template/pnpm-lock.yaml +7137 -0
- package/template/postcss.config.js +6 -0
- package/template/scripts/create-template.ts +1724 -0
- package/template/src/admin/App.tsx +59 -0
- package/template/src/admin/components/AccountSwitcher.tsx +104 -0
- package/template/src/admin/components/CaptchaModal.tsx +150 -0
- package/template/src/admin/components/NotificationDrawer.tsx +213 -0
- package/template/src/admin/components/PageHeader.tsx +45 -0
- package/template/src/admin/components/PermissionConfigEditor.tsx +237 -0
- package/template/src/admin/components/PermissionGuard.tsx +108 -0
- package/template/src/admin/components/PermissionTree.tsx +193 -0
- package/template/src/admin/components/ProtectedRoute.tsx +33 -0
- package/template/src/admin/components/StatsCard.tsx +44 -0
- package/template/src/admin/components/UserFormModal.tsx +67 -0
- package/template/src/admin/components/UserTable.tsx +72 -0
- package/template/src/admin/components/__tests__/PageHeader.test.tsx +48 -0
- package/template/src/admin/components/__tests__/PermissionConfigEditor.test.tsx +147 -0
- package/template/src/admin/components/__tests__/PermissionGuard.test.tsx +221 -0
- package/template/src/admin/components/__tests__/PermissionTree.test.tsx +187 -0
- package/template/src/admin/components/__tests__/ProtectedRoute.test.tsx +129 -0
- package/template/src/admin/components/__tests__/StatsCard.test.tsx +44 -0
- package/template/src/admin/components/__tests__/UserFormModal.test.tsx +125 -0
- package/template/src/admin/components/__tests__/UserTable.test.tsx +89 -0
- package/template/src/admin/components/index.ts +7 -0
- package/template/src/admin/hooks/__tests__/useAuditLogs.test.ts +109 -0
- package/template/src/admin/hooks/__tests__/usePermissions.test.tsx +327 -0
- package/template/src/admin/hooks/__tests__/usePermissionsBranches.test.ts +198 -0
- package/template/src/admin/hooks/__tests__/useRoles.test.ts +261 -0
- package/template/src/admin/hooks/useAdminNotifications.ts +156 -0
- package/template/src/admin/hooks/useAuditLogs.ts +44 -0
- package/template/src/admin/hooks/useConfig.ts +168 -0
- package/template/src/admin/hooks/usePermissions.ts +156 -0
- package/template/src/admin/hooks/useRoles.ts +120 -0
- package/template/src/admin/layouts/Header.tsx +93 -0
- package/template/src/admin/layouts/Layout.tsx +23 -0
- package/template/src/admin/layouts/Sidebar.tsx +120 -0
- package/template/src/admin/main.tsx +18 -0
- package/template/src/admin/pages/ContentPage.tsx +252 -0
- package/template/src/admin/pages/DashboardPage.tsx +141 -0
- package/template/src/admin/pages/DisputesPage.tsx +261 -0
- package/template/src/admin/pages/LoginPage.tsx +121 -0
- package/template/src/admin/pages/MediaTestPage.tsx +524 -0
- package/template/src/admin/pages/OrdersPage.tsx +302 -0
- package/template/src/admin/pages/PermissionsPage.tsx +95 -0
- package/template/src/admin/pages/RegisterPage.tsx +103 -0
- package/template/src/admin/pages/RolesPage.tsx +330 -0
- package/template/src/admin/pages/SettingsPage.tsx +73 -0
- package/template/src/admin/pages/SystemLogsPage.tsx +218 -0
- package/template/src/admin/pages/TestCaptchaPage.tsx +120 -0
- package/template/src/admin/pages/TicketsPage.tsx +292 -0
- package/template/src/admin/pages/UsersPage.tsx +282 -0
- package/template/src/admin/pages/__tests__/ContentPage.test.tsx +213 -0
- package/template/src/admin/pages/__tests__/DashboardPage.test.tsx +153 -0
- package/template/src/admin/pages/__tests__/DisputesPage.test.tsx +196 -0
- package/template/src/admin/pages/__tests__/LoginPage.test.tsx +112 -0
- package/template/src/admin/pages/__tests__/OrdersPage.test.tsx +217 -0
- package/template/src/admin/pages/__tests__/PermissionsPage.test.tsx +119 -0
- package/template/src/admin/pages/__tests__/RegisterPage.test.tsx +179 -0
- package/template/src/admin/pages/__tests__/RolesPage.test.tsx +256 -0
- package/template/src/admin/pages/__tests__/SettingsPage.test.tsx +66 -0
- package/template/src/admin/pages/__tests__/SystemLogsPage.test.tsx +125 -0
- package/template/src/admin/pages/__tests__/TicketsPage.test.tsx +202 -0
- package/template/src/admin/pages/__tests__/UsersPage.test.tsx +229 -0
- package/template/src/admin/services/README.md +263 -0
- package/template/src/admin/services/TESTING.md +323 -0
- package/template/src/admin/services/__tests__/skipLoading.test.ts +146 -0
- package/template/src/admin/services/apiClient.ts +66 -0
- package/template/src/admin/services/requestInterceptor.ts +127 -0
- package/template/src/admin/services/types.ts +5 -0
- package/template/src/admin/stores/__tests__/adminStore.test.ts +184 -0
- package/template/src/admin/stores/__tests__/adminStoreBranches.test.ts +148 -0
- package/template/src/admin/stores/__tests__/captchaStore.test.ts +75 -0
- package/template/src/admin/stores/__tests__/captchaStoreBranches.test.ts +37 -0
- package/template/src/admin/stores/__tests__/loadingStore.test.ts +68 -0
- package/template/src/admin/stores/adminStore.ts +88 -0
- package/template/src/admin/stores/captchaStore.ts +47 -0
- package/template/src/admin/stores/loadingStore.ts +27 -0
- package/template/src/cli/index.ts +22 -0
- package/template/src/cli/modules/config/index.ts +132 -0
- package/template/src/cli/modules/index.ts +12 -0
- package/template/src/cli/modules/notification/index.ts +86 -0
- package/template/src/cli/modules/todo/index.ts +60 -0
- package/template/src/cli/rpc/client.ts +23 -0
- package/template/src/cli/rpc/index.ts +1 -0
- package/template/src/cli/utils/api.ts +17 -0
- package/template/src/cli/utils/auto-command.ts +229 -0
- package/template/src/cli/utils/index.ts +8 -0
- package/template/src/cli/utils/logger.ts +79 -0
- package/template/src/client/App.tsx +24 -0
- package/template/src/client/Layout.tsx +27 -0
- package/template/src/client/components/AuthButton.tsx +41 -0
- package/template/src/client/components/ConnectionStatus.tsx +75 -0
- package/template/src/client/components/EmptyState.tsx +26 -0
- package/template/src/client/components/Footer.tsx +17 -0
- package/template/src/client/components/LoadingSpinner.tsx +26 -0
- package/template/src/client/components/MessageCard.tsx +61 -0
- package/template/src/client/components/Navigation.tsx +65 -0
- package/template/src/client/components/StatusBadge.tsx +50 -0
- package/template/src/client/components/__tests__/App.test.tsx +79 -0
- package/template/src/client/components/__tests__/AuthButton.test.tsx +119 -0
- package/template/src/client/components/__tests__/ConnectionStatus.test.tsx +188 -0
- package/template/src/client/components/__tests__/EmptyState.test.tsx +70 -0
- package/template/src/client/components/__tests__/Footer.test.tsx +22 -0
- package/template/src/client/components/__tests__/LoadingSpinner.test.tsx +75 -0
- package/template/src/client/components/__tests__/MessageCard.test.tsx +142 -0
- package/template/src/client/components/__tests__/Navigation.test.tsx +40 -0
- package/template/src/client/components/__tests__/StatusBadge.test.tsx +107 -0
- package/template/src/client/components/index.ts +6 -0
- package/template/src/client/index.css +27 -0
- package/template/src/client/main.tsx +25 -0
- package/template/src/client/pages/ContentDetailPage.tsx +142 -0
- package/template/src/client/pages/ContentListPage.tsx +169 -0
- package/template/src/client/pages/NotificationPage.tsx +288 -0
- package/template/src/client/pages/TodoPage.tsx +389 -0
- package/template/src/client/pages/WebSocketPage.tsx +239 -0
- package/template/src/client/pages/__tests__/ContentDetailPage.test.tsx +176 -0
- package/template/src/client/pages/__tests__/ContentListPage.test.tsx +202 -0
- package/template/src/client/pages/__tests__/NotificationPage.test.tsx +246 -0
- package/template/src/client/pages/__tests__/TodoPage.test.tsx +433 -0
- package/template/src/client/pages/__tests__/WebSocketPage.test.tsx +378 -0
- package/template/src/client/services/apiClient.ts +66 -0
- package/template/src/client/stores/__tests__/authStore.test.ts +139 -0
- package/template/src/client/stores/__tests__/chatWSStore.test.ts +416 -0
- package/template/src/client/stores/__tests__/notificationStore.test.ts +453 -0
- package/template/src/client/stores/__tests__/todoStore.test.ts +509 -0
- package/template/src/client/stores/authStore.ts +51 -0
- package/template/src/client/stores/chatWSStore.ts +122 -0
- package/template/src/client/stores/notificationStore.ts +199 -0
- package/template/src/client/stores/todoStore.ts +207 -0
- package/template/src/server/__tests__/integration/todos-api.test.ts +138 -0
- package/template/src/server/app.ts +105 -0
- package/template/src/server/config.ts +86 -0
- package/template/src/server/core/__tests__/realtime-core.test.ts +329 -0
- package/template/src/server/core/__tests__/realtime-scanner.test.ts +210 -0
- package/template/src/server/core/__tests__/runtime-node.test.ts +330 -0
- package/template/src/server/core/__tests__/runtime.test.ts +219 -0
- package/template/src/server/core/__tests__/typed-runtime.test.ts +178 -0
- package/template/src/server/core/durable-objects/RealtimeDO.ts +206 -0
- package/template/src/server/core/index.ts +83 -0
- package/template/src/server/core/module-loader.ts +281 -0
- package/template/src/server/core/realtime-core.ts +152 -0
- package/template/src/server/core/realtime-scanner.ts +99 -0
- package/template/src/server/core/runtime-cloudflare.ts +207 -0
- package/template/src/server/core/runtime-node.ts +170 -0
- package/template/src/server/core/runtime.ts +129 -0
- package/template/src/server/core/typed-runtime.ts +80 -0
- package/template/src/server/db/__tests__/driver.test.ts +203 -0
- package/template/src/server/db/config.ts +1 -0
- package/template/src/server/db/driver-cloudflare.ts +50 -0
- package/template/src/server/db/driver.ts +116 -0
- package/template/src/server/db/index.ts +3 -0
- package/template/src/server/db/init.ts +412 -0
- package/template/src/server/db/schema/api-endpoints.ts +23 -0
- package/template/src/server/db/schema/contents.ts +31 -0
- package/template/src/server/db/schema/disputes.ts +39 -0
- package/template/src/server/db/schema/index.ts +14 -0
- package/template/src/server/db/schema/notifications.ts +16 -0
- package/template/src/server/db/schema/orders.ts +30 -0
- package/template/src/server/db/schema/permission-audit-logs.ts +17 -0
- package/template/src/server/db/schema/permission-route-mappings.ts +22 -0
- package/template/src/server/db/schema/permissions.ts +17 -0
- package/template/src/server/db/schema/role-permissions.ts +22 -0
- package/template/src/server/db/schema/roles.ts +17 -0
- package/template/src/server/db/schema/tickets.ts +62 -0
- package/template/src/server/db/schema/todo-attachments.ts +22 -0
- package/template/src/server/db/schema/todos.ts +21 -0
- package/template/src/server/db/schema/user-roles.ts +17 -0
- package/template/src/server/db/seeds/index.ts +1 -0
- package/template/src/server/db/seeds/permission-data.ts +354 -0
- package/template/src/server/db/test-setup.ts +647 -0
- package/template/src/server/entries/cloudflare.ts +71 -0
- package/template/src/server/entries/node.ts +190 -0
- package/template/src/server/index.ts +62 -0
- package/template/src/server/middleware/__tests__/auth-simple.test.ts +147 -0
- package/template/src/server/middleware/__tests__/auth.test.ts +276 -0
- package/template/src/server/middleware/__tests__/captcha.test.ts +258 -0
- package/template/src/server/middleware/__tests__/error-handler.test.ts +364 -0
- package/template/src/server/middleware/__tests__/error-response-format.test.ts +80 -0
- package/template/src/server/middleware/__tests__/permission.test.ts +312 -0
- package/template/src/server/middleware/audit-log.ts +101 -0
- package/template/src/server/middleware/auth.ts +235 -0
- package/template/src/server/middleware/captcha.ts +166 -0
- package/template/src/server/middleware/cors.ts +30 -0
- package/template/src/server/middleware/error-handler.ts +135 -0
- package/template/src/server/middleware/index.ts +24 -0
- package/template/src/server/middleware/logger.ts +73 -0
- package/template/src/server/middleware/permission.ts +127 -0
- package/template/src/server/middleware/rate-limit.ts +69 -0
- package/template/src/server/middleware/realtime-env.ts +12 -0
- package/template/src/server/module-admin/__tests__/admin-routes.test.ts +360 -0
- package/template/src/server/module-admin/__tests__/admin-service.test.ts +222 -0
- package/template/src/server/module-admin/__tests__/audit-log-routes.test.ts +261 -0
- package/template/src/server/module-admin/__tests__/export-routes.test.ts +160 -0
- package/template/src/server/module-admin/__tests__/media-routes.test.ts +122 -0
- package/template/src/server/module-admin/module.ts +40 -0
- package/template/src/server/module-admin/routes/admin-notification-routes.ts +197 -0
- package/template/src/server/module-admin/routes/admin-routes.ts +20 -0
- package/template/src/server/module-admin/routes/auth-routes.ts +86 -0
- package/template/src/server/module-admin/routes/export-routes.ts +207 -0
- package/template/src/server/module-admin/routes/media-routes.ts +78 -0
- package/template/src/server/module-admin/routes/system-routes.ts +89 -0
- package/template/src/server/module-admin/routes/user-management-routes.ts +143 -0
- package/template/src/server/module-admin/services/admin-service.ts +268 -0
- package/template/src/server/module-captcha/__tests__/captcha-route.test.ts +35 -0
- package/template/src/server/module-captcha/__tests__/captcha-service.test.ts +53 -0
- package/template/src/server/module-captcha/module.ts +35 -0
- package/template/src/server/module-captcha/routes/captcha-routes.ts +68 -0
- package/template/src/server/module-captcha/services/captcha-service.ts +3 -0
- package/template/src/server/module-chat/__tests__/chat-routes.test.ts +39 -0
- package/template/src/server/module-chat/__tests__/chat-rpc.test.ts +185 -0
- package/template/src/server/module-chat/__tests__/chat-service.test.ts +64 -0
- package/template/src/server/module-chat/module.ts +27 -0
- package/template/src/server/module-chat/routes/chat-routes.ts +46 -0
- package/template/src/server/module-chat/services/chat-service.ts +38 -0
- package/template/src/server/module-content/__tests__/content-route.test.ts +40 -0
- package/template/src/server/module-content/__tests__/content-service.test.ts +107 -0
- package/template/src/server/module-content/module.ts +39 -0
- package/template/src/server/module-content/routes/content-routes.ts +182 -0
- package/template/src/server/module-content/routes/public-content-routes.ts +58 -0
- package/template/src/server/module-content/services/content-service.ts +224 -0
- package/template/src/server/module-dispute/__tests__/dispute-route.test.ts +43 -0
- package/template/src/server/module-dispute/__tests__/dispute-service.test.ts +135 -0
- package/template/src/server/module-dispute/module.ts +30 -0
- package/template/src/server/module-dispute/routes/dispute-routes.ts +153 -0
- package/template/src/server/module-dispute/services/dispute-service.ts +255 -0
- package/template/src/server/module-file/__tests__/file-routes.test.ts +284 -0
- package/template/src/server/module-file/__tests__/file-storage-service.test.ts +323 -0
- package/template/src/server/module-file/module.ts +28 -0
- package/template/src/server/module-file/routes/file-routes.ts +288 -0
- package/template/src/server/module-notifications/__tests__/notification-route-rpc.test.ts +375 -0
- package/template/src/server/module-notifications/__tests__/notification-service.test.ts +241 -0
- package/template/src/server/module-notifications/__tests__/sse-rpc.test.ts +289 -0
- package/template/src/server/module-notifications/module.ts +32 -0
- package/template/src/server/module-notifications/routes/notification-routes.ts +190 -0
- package/template/src/server/module-notifications/services/notification-service.ts +104 -0
- package/template/src/server/module-order/__tests__/order-route.test.ts +258 -0
- package/template/src/server/module-order/__tests__/order-service.test.ts +222 -0
- package/template/src/server/module-order/module.ts +30 -0
- package/template/src/server/module-order/routes/order-routes.ts +202 -0
- package/template/src/server/module-order/services/order-service.ts +268 -0
- package/template/src/server/module-permission/__tests__/permission-middleware.test.ts +90 -0
- package/template/src/server/module-permission/__tests__/permission-routes.test.ts +330 -0
- package/template/src/server/module-permission/__tests__/permission-service-impl.test.ts +388 -0
- package/template/src/server/module-permission/__tests__/permission-service.test.ts +190 -0
- package/template/src/server/module-permission/__tests__/role-routes.test.ts +215 -0
- package/template/src/server/module-permission/module.ts +68 -0
- package/template/src/server/module-permission/routes/audit-log-routes.ts +76 -0
- package/template/src/server/module-permission/routes/permission-routes.ts +184 -0
- package/template/src/server/module-permission/routes/role-routes.ts +263 -0
- package/template/src/server/module-permission/services/audit-log-service.ts +108 -0
- package/template/src/server/module-permission/services/permission-service-impl.ts +233 -0
- package/template/src/server/module-permission/services/permission-service.ts +256 -0
- package/template/src/server/module-permission/services/role-service.ts +122 -0
- package/template/src/server/module-ticket/__tests__/ticket-route.test.ts +173 -0
- package/template/src/server/module-ticket/__tests__/ticket-service.test.ts +201 -0
- package/template/src/server/module-ticket/module.ts +30 -0
- package/template/src/server/module-ticket/routes/ticket-routes.ts +210 -0
- package/template/src/server/module-ticket/services/ticket-service.ts +297 -0
- package/template/src/server/module-todos/__tests__/todo-service.test.ts +196 -0
- package/template/src/server/module-todos/__tests__/todos-file-upload.test.ts +439 -0
- package/template/src/server/module-todos/__tests__/todos-route-rpc.test.ts +575 -0
- package/template/src/server/module-todos/module.ts +30 -0
- package/template/src/server/module-todos/routes/todos-routes.ts +260 -0
- package/template/src/server/module-todos/services/todo-service.ts +202 -0
- package/template/src/server/route-registry.ts +47 -0
- package/template/src/server/test-utils/test-client.ts +66 -0
- package/template/src/server/test-utils/test-server.ts +131 -0
- package/template/src/server/types/bindings.ts +10 -0
- package/template/src/server/utils/__tests__/app-error.test.ts +374 -0
- package/template/src/server/utils/__tests__/auth.test.ts +76 -0
- package/template/src/server/utils/__tests__/captcha.test.ts +80 -0
- package/template/src/server/utils/__tests__/file-storage.test.ts +472 -0
- package/template/src/server/utils/__tests__/logger.test.ts +221 -0
- package/template/src/server/utils/__tests__/route-helpers.test.ts +264 -0
- package/template/src/server/utils/app-error.ts +355 -0
- package/template/src/server/utils/auth.ts +65 -0
- package/template/src/server/utils/captcha.ts +119 -0
- package/template/src/server/utils/date.ts +50 -0
- package/template/src/server/utils/env.ts +4 -0
- package/template/src/server/utils/file-storage.ts +462 -0
- package/template/src/server/utils/generate.ts +26 -0
- package/template/src/server/utils/id-helpers.ts +5 -0
- package/template/src/server/utils/logger.ts +139 -0
- package/template/src/server/utils/permission-utils.ts +6 -0
- package/template/src/server/utils/response.ts +40 -0
- package/template/src/server/utils/route-helpers.ts +200 -0
- package/template/src/server/utils/uuid.ts +8 -0
- package/template/src/server/utils/ws-helper.ts +30 -0
- package/template/src/shared/constants/index.ts +1 -0
- package/template/src/shared/constants/resource-types.ts +72 -0
- package/template/src/shared/core/__tests__/sse-client.test.ts +376 -0
- package/template/src/shared/core/__tests__/ws-client.test.ts +468 -0
- package/template/src/shared/core/api-request.ts +192 -0
- package/template/src/shared/core/api-schemas.ts +41 -0
- package/template/src/shared/core/index.ts +37 -0
- package/template/src/shared/core/module-manifest.ts +120 -0
- package/template/src/shared/core/protocol-types.ts +26 -0
- package/template/src/shared/core/sse-client.ts +185 -0
- package/template/src/shared/core/ws-client.ts +236 -0
- package/template/src/shared/hooks/index.ts +2 -0
- package/template/src/shared/hooks/useSSE.ts +57 -0
- package/template/src/shared/hooks/useWebSocket.ts +66 -0
- package/template/src/shared/index.ts +5 -0
- package/template/src/shared/modules/admin/index.ts +1 -0
- package/template/src/shared/modules/admin/schemas.ts +100 -0
- package/template/src/shared/modules/audit/index.ts +1 -0
- package/template/src/shared/modules/audit/schemas.ts +24 -0
- package/template/src/shared/modules/captcha/index.ts +1 -0
- package/template/src/shared/modules/captcha/schemas.ts +19 -0
- package/template/src/shared/modules/chat/index.ts +38 -0
- package/template/src/shared/modules/content/index.ts +1 -0
- package/template/src/shared/modules/content/schemas.ts +53 -0
- package/template/src/shared/modules/dispute/index.ts +1 -0
- package/template/src/shared/modules/dispute/schemas.ts +62 -0
- package/template/src/shared/modules/files/index.ts +11 -0
- package/template/src/shared/modules/files/schemas.ts +44 -0
- package/template/src/shared/modules/index.ts +70 -0
- package/template/src/shared/modules/notifications/index.ts +26 -0
- package/template/src/shared/modules/notifications/schemas.ts +73 -0
- package/template/src/shared/modules/order/index.ts +1 -0
- package/template/src/shared/modules/order/schemas.ts +63 -0
- package/template/src/shared/modules/permission/index.ts +42 -0
- package/template/src/shared/modules/permission/permission-dependencies.ts +50 -0
- package/template/src/shared/modules/permission/permissions.ts +275 -0
- package/template/src/shared/modules/permission/schemas.ts +92 -0
- package/template/src/shared/modules/permission/types.ts +23 -0
- package/template/src/shared/modules/role/index.ts +1 -0
- package/template/src/shared/modules/role/schemas.ts +46 -0
- package/template/src/shared/modules/ticket/index.ts +1 -0
- package/template/src/shared/modules/ticket/schemas.ts +77 -0
- package/template/src/shared/modules/todos/index.ts +20 -0
- package/template/src/shared/modules/todos/schemas.ts +65 -0
- package/template/src/shared/schemas/index.ts +79 -0
- package/template/src/types/global.d.ts +14 -0
- package/template/src/vite-env.d.ts +21 -0
- package/template/tailwind.config.js +11 -0
- package/template/tests/e2e/admin-crud.spec.ts +81 -0
- package/template/tests/e2e/case-o1.spec.ts +108 -0
- package/template/tests/e2e/global-setup.ts +73 -0
- package/template/tests/e2e/global-teardown.ts +28 -0
- package/template/tests/e2e/notification.spec.ts +458 -0
- package/template/tests/e2e/todo.spec.ts +623 -0
- package/template/tests/e2e/websocket.spec.ts +254 -0
- package/template/tsconfig.json +35 -0
- package/template/tsup.config.ts +95 -0
- package/template/vite-plugins.ts +113 -0
- package/template/vite.config.ts +96 -0
- package/template/vitest.config.ts +53 -0
- package/template/vitest.integration.config.ts +24 -0
- package/template/vitest.integration.setup.ts +22 -0
- package/template/vitest.setup.ts +74 -0
- package/template/wrangler.toml +33 -0
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
# Project Template Summary
|
|
2
|
+
|
|
3
|
+
## Created Project Structure
|
|
4
|
+
|
|
5
|
+
A complete React + Hono full-stack application template following the project-framework architecture.
|
|
6
|
+
|
|
7
|
+
## Directory Structure
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
template/
|
|
11
|
+
├── src/
|
|
12
|
+
│ ├── client/ # React Frontend
|
|
13
|
+
│ │ ├── App.tsx # Main Todo List component
|
|
14
|
+
│ │ ├── main.tsx # React entry point
|
|
15
|
+
│ │ ├── index.css # Global styles
|
|
16
|
+
│ │ ├── components/
|
|
17
|
+
│ │ │ └── __tests__/ # Component tests
|
|
18
|
+
│ │ ├── stores/
|
|
19
|
+
│ │ │ ├── todoStore.ts # Zustand state management
|
|
20
|
+
│ │ │ ├── notificationStore.ts # SSE notifications store
|
|
21
|
+
│ │ │ └── __tests__/
|
|
22
|
+
│ │ ├── services/
|
|
23
|
+
│ │ │ └── apiClient.ts # Hono RPC client
|
|
24
|
+
│ │ ├── hooks/
|
|
25
|
+
│ │ │ └── useWS.ts # WebSocket hook
|
|
26
|
+
│ │ └── pages/
|
|
27
|
+
│ │ └── NotificationPage.tsx
|
|
28
|
+
│ │
|
|
29
|
+
│ ├── server/ # Hono Backend
|
|
30
|
+
│ │ ├── app.ts # Server entry with middleware
|
|
31
|
+
│ │ ├── module-todos/ # Todo feature module
|
|
32
|
+
│ │ │ ├── routes/
|
|
33
|
+
│ │ │ │ └── todos-routes.ts # API endpoints (Hono RPC)
|
|
34
|
+
│ │ │ ├── services/
|
|
35
|
+
│ │ │ │ └── todo-service.ts # Business logic
|
|
36
|
+
│ │ │ └── __tests__/
|
|
37
|
+
│ │ ├── module-chat/ # WebSocket chat module
|
|
38
|
+
│ │ │ ├── routes/
|
|
39
|
+
│ │ │ │ └── chat-routes.ts
|
|
40
|
+
│ │ │ ├── services/
|
|
41
|
+
│ │ │ │ └── chat-service.ts
|
|
42
|
+
│ │ │ └── __tests__/
|
|
43
|
+
│ │ ├── module-notifications/ # SSE notifications module
|
|
44
|
+
│ │ │ ├── routes/
|
|
45
|
+
│ │ │ │ └── notification-routes.ts
|
|
46
|
+
│ │ │ ├── services/
|
|
47
|
+
│ │ │ │ └── notification-service.ts
|
|
48
|
+
│ │ │ └── __tests__/
|
|
49
|
+
│ │ ├── core/ # Core runtime
|
|
50
|
+
│ │ │ ├── runtime.ts # Runtime adapter interface
|
|
51
|
+
│ │ │ ├── runtime-node.ts # Node.js runtime
|
|
52
|
+
│ │ │ ├── runtime-cloudflare.ts # Cloudflare runtime
|
|
53
|
+
│ │ │ ├── realtime-core.ts # Real-time core
|
|
54
|
+
│ │ │ ├── typed-runtime.ts # Type-safe runtime
|
|
55
|
+
│ │ │ └── realtime-scanner.ts # Auto-register realtime
|
|
56
|
+
│ │ ├── middleware/ # Express middleware
|
|
57
|
+
│ │ │ ├── cors.ts
|
|
58
|
+
│ │ │ ├── logger.ts
|
|
59
|
+
│ │ │ ├── error-handler.ts
|
|
60
|
+
│ │ │ └── realtime-env.ts # Realtime env middleware
|
|
61
|
+
│ │ ├── test-utils/
|
|
62
|
+
│ │ │ ├── test-client.ts # Test client factory
|
|
63
|
+
│ │ │ └── test-server.ts # Test server (WebSocket)
|
|
64
|
+
│ │ ├── entries/
|
|
65
|
+
│ │ │ ├── node.ts # Node.js entry point
|
|
66
|
+
│ │ │ └── cloudflare.ts # Cloudflare entry point
|
|
67
|
+
│ │ └── integration/
|
|
68
|
+
│ │ └── todos-api.test.ts # Integration tests
|
|
69
|
+
│ │
|
|
70
|
+
│ └── shared/ # Shared Types
|
|
71
|
+
│ ├── core/ # Framework Layer
|
|
72
|
+
│ │ ├── ws-client.ts # WebSocket client
|
|
73
|
+
│ │ ├── sse-client.ts # SSE client
|
|
74
|
+
│ │ ├── api-schemas.ts # API response schemas
|
|
75
|
+
│ │ ├── protocol-types.ts # Protocol type utilities
|
|
76
|
+
│ │ └── index.ts # Framework exports
|
|
77
|
+
│ ├── modules/ # Business Layer
|
|
78
|
+
│ │ ├── chat/
|
|
79
|
+
│ │ │ └── index.ts # Chat protocol schema
|
|
80
|
+
│ │ ├── todos/
|
|
81
|
+
│ │ │ ├── schemas.ts # Todo schemas
|
|
82
|
+
│ │ │ └── index.ts
|
|
83
|
+
│ │ └── notifications/
|
|
84
|
+
│ │ ├── schemas.ts # Notification + SSE schemas
|
|
85
|
+
│ │ └── index.ts
|
|
86
|
+
│ └── schemas/ # Unified exports
|
|
87
|
+
│ └── index.ts
|
|
88
|
+
│
|
|
89
|
+
├── lint-scripts/
|
|
90
|
+
│ ├── config/
|
|
91
|
+
│ │ └── project.config.ts # Validation config
|
|
92
|
+
│ ├── validators/
|
|
93
|
+
│ │ ├── client-rpc.validator.ts
|
|
94
|
+
│ │ ├── server-rpc.validator.ts
|
|
95
|
+
│ │ ├── imports.validator.ts
|
|
96
|
+
│ │ └── index.ts
|
|
97
|
+
│ └── validate-all.ts # Pre-commit validation
|
|
98
|
+
│
|
|
99
|
+
├── eslint-rules/
|
|
100
|
+
│ ├── layer-boundary.js # Framework/Business layer separation
|
|
101
|
+
│ ├── no-direct-ws-sse.js # WebSocket/SSE protection
|
|
102
|
+
│ ├── protect-ws-sse-interface.js
|
|
103
|
+
│ ├── require-type-safe-test-client.js
|
|
104
|
+
│ ├── require-hono-chain-syntax.js
|
|
105
|
+
│ ├── no-ambiguous-file-paths.js
|
|
106
|
+
│ └── no-util-functions-in-service.js
|
|
107
|
+
│
|
|
108
|
+
├── .claude/
|
|
109
|
+
│ └── rules/
|
|
110
|
+
│ ├── project-rules.md
|
|
111
|
+
│ ├── client-component-rules.md
|
|
112
|
+
│ ├── client-service-rules.md
|
|
113
|
+
│ ├── zustand-rules.md
|
|
114
|
+
│ ├── websocket-rules.md
|
|
115
|
+
│ ├── sse-rules.md
|
|
116
|
+
│ ├── shared-types-rules.md
|
|
117
|
+
│ ├── layer-boundary-rules.md
|
|
118
|
+
│ ├── testing-standards.md
|
|
119
|
+
│ └── hono-testing-best-practices.md
|
|
120
|
+
│
|
|
121
|
+
└── Documentation
|
|
122
|
+
├── README.md # User-facing documentation
|
|
123
|
+
├── QUICKSTART.md # Quick start guide
|
|
124
|
+
├── DESIGN.md # Architecture documentation
|
|
125
|
+
└── CLAUDE.md # Claude Code guidelines
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Framework Layer vs Business Layer
|
|
129
|
+
|
|
130
|
+
The project has clear separation between framework and business layers:
|
|
131
|
+
|
|
132
|
+
### Framework Layer (`src/shared/core/`)
|
|
133
|
+
|
|
134
|
+
- Generic, reusable infrastructure code
|
|
135
|
+
- Examples: `ws-client.ts`, `sse-client.ts`, `api-schemas.ts`
|
|
136
|
+
- Should not be modified by business code directly
|
|
137
|
+
|
|
138
|
+
### Business Layer (`src/shared/modules/`)
|
|
139
|
+
|
|
140
|
+
- Business-specific schemas and protocols
|
|
141
|
+
- Examples: `chat/`, `todos/`, `notifications/`
|
|
142
|
+
- Organized by feature modules
|
|
143
|
+
|
|
144
|
+
## Key Features Implemented
|
|
145
|
+
|
|
146
|
+
### 1. Architecture
|
|
147
|
+
|
|
148
|
+
- ✅ Monorepo-style structure with client/server separation
|
|
149
|
+
- ✅ Shared types for end-to-end type safety
|
|
150
|
+
- ✅ Single-port development (3010) using @hono/vite-dev-server
|
|
151
|
+
- ✅ Modular backend with feature-based organization
|
|
152
|
+
- ✅ Framework layer vs Business layer separation
|
|
153
|
+
|
|
154
|
+
### 2. Frontend (React + Vite)
|
|
155
|
+
|
|
156
|
+
- ✅ React 18 with TypeScript
|
|
157
|
+
- ✅ Zustand state management
|
|
158
|
+
- ✅ Hono RPC for type-safe API calls
|
|
159
|
+
- ✅ Todo List UI with CRUD operations
|
|
160
|
+
- ✅ Error handling and loading states
|
|
161
|
+
|
|
162
|
+
### 3. Backend (Hono)
|
|
163
|
+
|
|
164
|
+
- ✅ Hono with OpenAPI/Swagger support
|
|
165
|
+
- ✅ Zod validation for all endpoints
|
|
166
|
+
- ✅ CORS and error handling middleware
|
|
167
|
+
- ✅ Module-based route organization
|
|
168
|
+
- ✅ Health check endpoint
|
|
169
|
+
- ✅ Middleware for realtime env
|
|
170
|
+
|
|
171
|
+
### 4. Real-time Features
|
|
172
|
+
|
|
173
|
+
- ✅ WebSocket support with `$ws()` method
|
|
174
|
+
- ✅ SSE support with `$sse()` method
|
|
175
|
+
- ✅ Type-safe real-time communication
|
|
176
|
+
- ✅ Runtime abstraction (Node.js / Cloudflare Workers)
|
|
177
|
+
- ✅ Auto-register realtime via scanner
|
|
178
|
+
|
|
179
|
+
### 5. Testing
|
|
180
|
+
|
|
181
|
+
- ✅ Vitest configuration for unit tests
|
|
182
|
+
- ✅ Integration tests for API endpoints
|
|
183
|
+
- ✅ WebSocket tests (requires server)
|
|
184
|
+
- ✅ SSE tests (no server needed)
|
|
185
|
+
- ✅ jsdom environment for client tests
|
|
186
|
+
- ✅ Node environment for server tests
|
|
187
|
+
|
|
188
|
+
### 6. Code Quality
|
|
189
|
+
|
|
190
|
+
- ✅ ESLint with TypeScript support
|
|
191
|
+
- ✅ Custom ESLint rules for WebSocket/SSE
|
|
192
|
+
- ✅ Layer boundary rules for framework/business separation
|
|
193
|
+
- ✅ Prettier for code formatting
|
|
194
|
+
- ✅ Pre-commit hooks with Husky
|
|
195
|
+
- ✅ Validation script for common issues
|
|
196
|
+
- ✅ lint-staged for efficient formatting
|
|
197
|
+
|
|
198
|
+
## API Endpoints
|
|
199
|
+
|
|
200
|
+
### Todos
|
|
201
|
+
|
|
202
|
+
- `GET /api/todos` - List all todos
|
|
203
|
+
- `GET /api/todos/:id` - Get todo by ID
|
|
204
|
+
- `POST /api/todos` - Create new todo
|
|
205
|
+
- `PUT /api/todos/:id` - Update todo
|
|
206
|
+
- `DELETE /api/todos/:id` - Delete todo
|
|
207
|
+
|
|
208
|
+
### WebSocket
|
|
209
|
+
|
|
210
|
+
- `GET /api/chat/ws` - WebSocket chat endpoint
|
|
211
|
+
- RPC methods: `echo`, `ping`
|
|
212
|
+
- Events: `notification`
|
|
213
|
+
|
|
214
|
+
### SSE
|
|
215
|
+
|
|
216
|
+
- `GET /api/notifications/stream` - SSE notifications endpoint
|
|
217
|
+
- Events: `notification`, `ping`, `connected`
|
|
218
|
+
|
|
219
|
+
### Health
|
|
220
|
+
|
|
221
|
+
- `GET /health` - Health check
|
|
222
|
+
- `GET /` - Root endpoint with HTML
|
|
223
|
+
- `GET /docs` - OpenAPI documentation
|
|
224
|
+
|
|
225
|
+
## Data Models
|
|
226
|
+
|
|
227
|
+
### Todo
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
interface Todo {
|
|
231
|
+
id: number
|
|
232
|
+
title: string
|
|
233
|
+
description?: string
|
|
234
|
+
status: 'pending' | 'in_progress' | 'completed'
|
|
235
|
+
createdAt: string
|
|
236
|
+
updatedAt: string
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Notification
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
interface AppNotification {
|
|
244
|
+
id: string
|
|
245
|
+
type: 'info' | 'warning' | 'success' | 'error'
|
|
246
|
+
title: string
|
|
247
|
+
message: string
|
|
248
|
+
read: boolean
|
|
249
|
+
createdAt: string
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Usage
|
|
254
|
+
|
|
255
|
+
### Installation
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
npm install
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Development
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
npm run dev # Starts on http://localhost:3010
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Testing
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
npm test # Run all tests
|
|
271
|
+
npm run test:unit # Unit tests only
|
|
272
|
+
npm run test:integration # Integration tests only
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Build
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
npm run build
|
|
279
|
+
npm run preview
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Technical Highlights
|
|
283
|
+
|
|
284
|
+
### 1. Type Safety
|
|
285
|
+
|
|
286
|
+
- End-to-end type safety from database to UI
|
|
287
|
+
- Hono RPC provides compile-time validation
|
|
288
|
+
- Zod schemas for runtime validation
|
|
289
|
+
- Type-safe WebSocket and SSE
|
|
290
|
+
|
|
291
|
+
### 2. Real-time Features
|
|
292
|
+
|
|
293
|
+
- WebSocket: Bidirectional communication with RPC
|
|
294
|
+
- SSE: Unidirectional server-to-client streaming
|
|
295
|
+
- Type-safe protocols with Zod schemas
|
|
296
|
+
|
|
297
|
+
### 3. Framework/Business Layer Separation
|
|
298
|
+
|
|
299
|
+
- Clear boundaries enforced by ESLint
|
|
300
|
+
- Framework layer: reusable infrastructure
|
|
301
|
+
- Business layer: feature-specific code
|
|
302
|
+
|
|
303
|
+
### 4. Scalability
|
|
304
|
+
|
|
305
|
+
- Modular architecture easy to extend
|
|
306
|
+
- Feature-based organization
|
|
307
|
+
- Clear separation of concerns
|
|
308
|
+
|
|
309
|
+
### 5. Developer Experience
|
|
310
|
+
|
|
311
|
+
- Clear project structure
|
|
312
|
+
- Comprehensive documentation
|
|
313
|
+
- Automated code quality checks
|
|
314
|
+
- Easy onboarding for new developers
|
|
315
|
+
|
|
316
|
+
## Next Steps
|
|
317
|
+
|
|
318
|
+
To use this template for a new project:
|
|
319
|
+
|
|
320
|
+
1. Copy the template directory
|
|
321
|
+
2. Customize package.json (name, description)
|
|
322
|
+
3. Update environment variables
|
|
323
|
+
4. Modify the Todo module or create new modules
|
|
324
|
+
5. Add your own features following the established patterns
|
|
325
|
+
6. Update documentation as needed
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
# Quick Start Guide
|
|
2
|
+
|
|
3
|
+
## Prerequisites
|
|
4
|
+
|
|
5
|
+
- Node.js 18+
|
|
6
|
+
- npm or yarn
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
# Install dependencies
|
|
12
|
+
npm install
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Development
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Start development server (port 3010)
|
|
19
|
+
npm run dev
|
|
20
|
+
|
|
21
|
+
# The app will be available at http://localhost:3010
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Project Structure
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
template/
|
|
28
|
+
├── src/
|
|
29
|
+
│ ├── client/ # React frontend
|
|
30
|
+
│ │ ├── App.tsx # Main component
|
|
31
|
+
│ │ ├── stores/ # Zustand state management
|
|
32
|
+
│ │ ├── services/ # API clients (apiClient)
|
|
33
|
+
│ │ ├── hooks/ # Custom hooks
|
|
34
|
+
│ │ ├── pages/ # Page components
|
|
35
|
+
│ │ └── components/ # UI components
|
|
36
|
+
│ ├── server/ # Hono backend
|
|
37
|
+
│ │ ├── module-todos/ # Todo feature 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)
|
|
46
|
+
│ ├── modules/ # Business layer (chat, todos, notifications)
|
|
47
|
+
│ └── schemas/ # Unified exports
|
|
48
|
+
├── lint-scripts/ # Validation scripts
|
|
49
|
+
├── .husky/ # Git hooks
|
|
50
|
+
└── [config files]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Key Files to Understand
|
|
54
|
+
|
|
55
|
+
1. **src/shared/modules/** - Business schemas (chat, todos, notifications)
|
|
56
|
+
2. **src/server/app.ts** - Hono server with RPC
|
|
57
|
+
3. **src/server/module-todos/routes/todos-routes.ts** - API endpoints
|
|
58
|
+
4. **src/client/App.tsx** - React UI component
|
|
59
|
+
5. **src/client/stores/todoStore.ts** - Zustand state management
|
|
60
|
+
6. **src/client/services/apiClient.ts** - Type-safe API client
|
|
61
|
+
|
|
62
|
+
## Testing
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Run all tests
|
|
66
|
+
npm test
|
|
67
|
+
|
|
68
|
+
# Run unit tests only
|
|
69
|
+
npm run test:unit
|
|
70
|
+
|
|
71
|
+
# Run integration tests only
|
|
72
|
+
npm run test:integration
|
|
73
|
+
|
|
74
|
+
# Run tests with coverage
|
|
75
|
+
npm test -- --coverage
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Testing Real-time Features
|
|
79
|
+
|
|
80
|
+
| Feature | Requires Server | Test Method |
|
|
81
|
+
| --------- | --------------- | --------------------------- |
|
|
82
|
+
| HTTP API | ❌ No | `createTestClient()` |
|
|
83
|
+
| SSE | ❌ No | `$sse()` with `app.fetch()` |
|
|
84
|
+
| WebSocket | ✅ Yes | `createTestServer()` |
|
|
85
|
+
|
|
86
|
+
## Adding a New Feature
|
|
87
|
+
|
|
88
|
+
### 1. Create Server Module
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
mkdir -p src/server/module-{feature}/routes
|
|
92
|
+
mkdir -p src/server/module-{feature}/services
|
|
93
|
+
mkdir -p src/server/module-{feature}/__tests__
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 2. Define Types
|
|
97
|
+
|
|
98
|
+
Add to `src/shared/modules/{feature}/schemas.ts`:
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import { z } from '@hono/zod-openapi'
|
|
102
|
+
|
|
103
|
+
export const NewFeatureSchema = z.object({
|
|
104
|
+
id: z.string().uuid(),
|
|
105
|
+
name: z.string().min(1),
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
export type NewFeature = z.infer<typeof NewFeatureSchema>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### 3. Create Service
|
|
112
|
+
|
|
113
|
+
`src/server/module-{feature}/services/feature-service.ts`:
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
export async function listFeatures() {
|
|
117
|
+
// Business logic
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 4. Create Routes
|
|
122
|
+
|
|
123
|
+
`src/server/module-{feature}/routes/feature-routes.ts`:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import { createRoute } from '@hono/zod-openapi'
|
|
127
|
+
import { OpenAPIHono } from '@hono/zod-openapi'
|
|
128
|
+
|
|
129
|
+
const app = new OpenAPIHono()
|
|
130
|
+
|
|
131
|
+
const listRoute = createRoute({
|
|
132
|
+
method: 'get',
|
|
133
|
+
path: '/features',
|
|
134
|
+
// ... route definition
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
app.openapi(listRoute, async c => {
|
|
138
|
+
const features = await featureService.listFeatures()
|
|
139
|
+
return c.json({ success: true, data: features })
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
export const featureRoutes = app
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 5. Register Routes
|
|
146
|
+
|
|
147
|
+
Add to `src/server/app.ts`:
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
import { featureRoutes } from './module-features/routes/feature-routes'
|
|
151
|
+
|
|
152
|
+
app.route('/api', featureRoutes)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### 6. Create Client Store
|
|
156
|
+
|
|
157
|
+
`src/client/stores/todoStore.ts`:
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
import { create } from 'zustand'
|
|
161
|
+
import { apiClient } from '@client/services/apiClient'
|
|
162
|
+
|
|
163
|
+
export const useTodoStore = create(set => ({
|
|
164
|
+
todos: [],
|
|
165
|
+
fetchTodos: async () => {
|
|
166
|
+
const response = await apiClient.api.todos.$get()
|
|
167
|
+
const result = await response.json()
|
|
168
|
+
set({ todos: result.data })
|
|
169
|
+
},
|
|
170
|
+
}))
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### 7. Create UI Component
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
import { useTodoStore } from '@client/stores/todoStore';
|
|
177
|
+
|
|
178
|
+
export function TodoList() {
|
|
179
|
+
const todos = useTodoStore((state) => state.todos);
|
|
180
|
+
|
|
181
|
+
return (
|
|
182
|
+
<div>
|
|
183
|
+
{todos.map((todo) => (
|
|
184
|
+
<div key={todo.id}>{todo.title}</div>
|
|
185
|
+
))}
|
|
186
|
+
</div>
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Real-time Features
|
|
192
|
+
|
|
193
|
+
### WebSocket
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
// Server: Define protocol in src/shared/modules/chat/
|
|
197
|
+
import { ChatProtocolSchema } from '@shared/modules/chat'
|
|
198
|
+
|
|
199
|
+
// Client: Use $ws()
|
|
200
|
+
const ws = apiClient.api.chat.ws.$ws()
|
|
201
|
+
const result = await ws.call('echo', { message: 'hello' })
|
|
202
|
+
ws.on('notification', n => console.log(n))
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### SSE
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
// Server: Define protocol in src/shared/modules/notifications/
|
|
209
|
+
import { AppSSEProtocolSchema } from '@shared/schemas'
|
|
210
|
+
|
|
211
|
+
// Client: Use $sse()
|
|
212
|
+
const conn = await apiClient.api.notifications.stream.$sse()
|
|
213
|
+
conn.on('notification', n => console.log(n))
|
|
214
|
+
conn.on('ping', p => console.log(p.timestamp))
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### SSE Broadcast Pattern
|
|
218
|
+
|
|
219
|
+
When creating notifications, use the broadcast function in service layer:
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
// In service layer - use createNotificationAndBroadcast
|
|
223
|
+
import { createNotificationAndBroadcast } from '@server/module-notifications/services/notification-service'
|
|
224
|
+
|
|
225
|
+
// The service automatically handles broadcasting
|
|
226
|
+
const notification = await createNotificationAndBroadcast(input)
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Framework Layer vs Business Layer
|
|
230
|
+
|
|
231
|
+
The project has clear separation between framework and business layers:
|
|
232
|
+
|
|
233
|
+
**Framework Layer** (`src/shared/core/`):
|
|
234
|
+
|
|
235
|
+
- Generic, reusable infrastructure code
|
|
236
|
+
- Examples: `ws-client.ts`, `sse-client.ts`, `api-schemas.ts`
|
|
237
|
+
- Should not be modified by business code directly
|
|
238
|
+
|
|
239
|
+
**Business Layer** (`src/shared/modules/`):
|
|
240
|
+
|
|
241
|
+
- Business-specific schemas and protocols
|
|
242
|
+
- Examples: `chat/`, `todos/`, `notifications/`
|
|
243
|
+
|
|
244
|
+
## Code Quality
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
# Format code
|
|
248
|
+
npm run format
|
|
249
|
+
|
|
250
|
+
# Lint code
|
|
251
|
+
npm run lint
|
|
252
|
+
|
|
253
|
+
# Type check
|
|
254
|
+
npm run typecheck
|
|
255
|
+
|
|
256
|
+
# Run validation script
|
|
257
|
+
node --import tsx/esm lint-scripts/validate-all.ts
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## Pre-commit Hooks
|
|
261
|
+
|
|
262
|
+
The project uses Husky for Git hooks:
|
|
263
|
+
|
|
264
|
+
- **lint-staged**: Format staged files
|
|
265
|
+
- **npm test**: Run test suite
|
|
266
|
+
- **validate-all**: Custom validation
|
|
267
|
+
|
|
268
|
+
To skip hooks (not recommended):
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
git commit --no-verify -m "message"
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## Troubleshooting
|
|
275
|
+
|
|
276
|
+
### Port Already in Use
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
# Kill process on port 3010
|
|
280
|
+
lsof -ti:3010 | xargs kill -9
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Database Errors
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
# Remove database and restart
|
|
287
|
+
rm -f data/todos.db
|
|
288
|
+
npm run dev
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Type Errors
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
# Clean and rebuild
|
|
295
|
+
rm -rf dist node_modules
|
|
296
|
+
npm install
|
|
297
|
+
npm run dev
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Next Steps
|
|
301
|
+
|
|
302
|
+
- Read `DESIGN.md` for architecture details
|
|
303
|
+
- Check `CLAUDE.md` for development guidelines
|
|
304
|
+
- Explore test files for examples
|
|
305
|
+
- Add your own features!
|