@etus/bhono-app 0.1.1

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 (688) hide show
  1. package/dist/cli.d.ts +13 -0
  2. package/dist/cli.js +46 -0
  3. package/dist/cli.js.map +1 -0
  4. package/dist/cli.test.d.ts +1 -0
  5. package/dist/cli.test.js +26 -0
  6. package/dist/cli.test.js.map +1 -0
  7. package/dist/generator.d.ts +14 -0
  8. package/dist/generator.js +142 -0
  9. package/dist/generator.js.map +1 -0
  10. package/dist/generator.test.d.ts +1 -0
  11. package/dist/generator.test.js +127 -0
  12. package/dist/generator.test.js.map +1 -0
  13. package/dist/index.d.ts +2 -0
  14. package/dist/index.js +97 -0
  15. package/dist/index.js.map +1 -0
  16. package/dist/prompts.d.ts +25 -0
  17. package/dist/prompts.js +83 -0
  18. package/dist/prompts.js.map +1 -0
  19. package/dist/prompts.test.d.ts +1 -0
  20. package/dist/prompts.test.js +24 -0
  21. package/dist/prompts.test.js.map +1 -0
  22. package/dist/providers/cloudflare.d.ts +37 -0
  23. package/dist/providers/cloudflare.js +61 -0
  24. package/dist/providers/cloudflare.js.map +1 -0
  25. package/dist/providers/cloudflare.test.d.ts +1 -0
  26. package/dist/providers/cloudflare.test.js +29 -0
  27. package/dist/providers/cloudflare.test.js.map +1 -0
  28. package/dist/providers/github.d.ts +16 -0
  29. package/dist/providers/github.js +57 -0
  30. package/dist/providers/github.js.map +1 -0
  31. package/dist/providers/github.test.d.ts +1 -0
  32. package/dist/providers/github.test.js +16 -0
  33. package/dist/providers/github.test.js.map +1 -0
  34. package/dist/templates.d.ts +8 -0
  35. package/dist/templates.js +88 -0
  36. package/dist/templates.js.map +1 -0
  37. package/dist/templates.test.d.ts +1 -0
  38. package/dist/templates.test.js +26 -0
  39. package/dist/templates.test.js.map +1 -0
  40. package/package.json +36 -0
  41. package/templates/base/.claude/agents/architect-review.md +160 -0
  42. package/templates/base/.claude/agents/backend-architect.md +308 -0
  43. package/templates/base/.claude/agents/code-reviewer.md +170 -0
  44. package/templates/base/.claude/agents/performance-engineer.md +166 -0
  45. package/templates/base/.claude/agents/test-automator.md +219 -0
  46. package/templates/base/.claude/commands/check-skill-rules.md +53 -0
  47. package/templates/base/.claude/commands/claude-md.md +250 -0
  48. package/templates/base/.claude/commands/code-prompt.md +212 -0
  49. package/templates/base/.claude/commands/explain-code.md +194 -0
  50. package/templates/base/.claude/commands/init-projec.md +89 -0
  51. package/templates/base/.claude/commands/linear/README.md +297 -0
  52. package/templates/base/.claude/commands/linear/create-issue.md +190 -0
  53. package/templates/base/.claude/commands/linear/implement-issue.md +248 -0
  54. package/templates/base/.claude/commands/linear/process-triage.md +399 -0
  55. package/templates/base/.claude/commands/linear/setup.md +180 -0
  56. package/templates/base/.claude/commands/prime.md +9 -0
  57. package/templates/base/.claude/commands/review-gap.md +10 -0
  58. package/templates/base/.claude/commands/setup-aa.md +311 -0
  59. package/templates/base/.claude/commands/ship.md +262 -0
  60. package/templates/base/.claude/commands/tools.md +3 -0
  61. package/templates/base/.claude/docs/claude-progress.txt +107 -0
  62. package/templates/base/.claude/hooks/package-lock.json +556 -0
  63. package/templates/base/.claude/hooks/package.json +16 -0
  64. package/templates/base/.claude/hooks/skill-activation-prompt.sh +7 -0
  65. package/templates/base/.claude/hooks/skill-activation-prompt.ts +142 -0
  66. package/templates/base/.claude/hooks/tsconfig.json +19 -0
  67. package/templates/base/.claude/scripts/check-updates.sh +85 -0
  68. package/templates/base/.claude/scripts/install_pkgs.sh +66 -0
  69. package/templates/base/.claude/scripts/setup-project.sh +177 -0
  70. package/templates/base/.claude/scripts/validate-skill-rules.sh +94 -0
  71. package/templates/base/.claude/settings.json +113 -0
  72. package/templates/base/.claude/settings.local.json +11 -0
  73. package/templates/base/.claude/skills/architecture-analyzer/SKILL.md +531 -0
  74. package/templates/base/.claude/skills/architecture-analyzer/assets/report-template.md +215 -0
  75. package/templates/base/.claude/skills/architecture-analyzer/references/c4-templates.md +234 -0
  76. package/templates/base/.claude/skills/architecture-analyzer/references/confidence-levels.md +203 -0
  77. package/templates/base/.claude/skills/architecture-analyzer/scripts/analyze_structure.py +266 -0
  78. package/templates/base/.claude/skills/architecture-analyzer/scripts/analyze_tech_debt.py +776 -0
  79. package/templates/base/.claude/skills/architecture-analyzer/scripts/extract_apis.py +338 -0
  80. package/templates/base/.claude/skills/architecture-analyzer/scripts/generate_c4.py +283 -0
  81. package/templates/base/.claude/skills/architecture-analyzer/scripts/generate_erd.py +935 -0
  82. package/templates/base/.claude/skills/architecture-analyzer/scripts/map_dependencies.py +555 -0
  83. package/templates/base/.claude/skills/dev-browser/SKILL.md +318 -0
  84. package/templates/base/.claude/skills/dev-browser/bun.lock +443 -0
  85. package/templates/base/.claude/skills/dev-browser/package-lock.json +2927 -0
  86. package/templates/base/.claude/skills/dev-browser/package.json +27 -0
  87. package/templates/base/.claude/skills/dev-browser/scripts/start-server.ts +117 -0
  88. package/templates/base/.claude/skills/dev-browser/server.sh +24 -0
  89. package/templates/base/.claude/skills/dev-browser/src/client.ts +403 -0
  90. package/templates/base/.claude/skills/dev-browser/src/index.ts +281 -0
  91. package/templates/base/.claude/skills/dev-browser/src/snapshot/__tests__/snapshot.test.ts +223 -0
  92. package/templates/base/.claude/skills/dev-browser/src/snapshot/browser-script.ts +877 -0
  93. package/templates/base/.claude/skills/dev-browser/src/snapshot/index.ts +14 -0
  94. package/templates/base/.claude/skills/dev-browser/src/snapshot/inject.ts +13 -0
  95. package/templates/base/.claude/skills/dev-browser/src/types.ts +27 -0
  96. package/templates/base/.claude/skills/dev-browser/tsconfig.json +36 -0
  97. package/templates/base/.claude/skills/dev-browser/vitest.config.ts +12 -0
  98. package/templates/base/.claude/skills/linear/SKILL.md +440 -0
  99. package/templates/base/.claude/skills/linear/examples.md +262 -0
  100. package/templates/base/.claude/skills/linear/lib/client.ts +51 -0
  101. package/templates/base/.claude/skills/linear/lib/config.ts +106 -0
  102. package/templates/base/.claude/skills/linear/lib/output.ts +34 -0
  103. package/templates/base/.claude/skills/linear/package-lock.json +698 -0
  104. package/templates/base/.claude/skills/linear/package.json +27 -0
  105. package/templates/base/.claude/skills/linear/reference.md +263 -0
  106. package/templates/base/.claude/skills/linear/scripts/comments/create.ts +47 -0
  107. package/templates/base/.claude/skills/linear/scripts/comments/list.ts +47 -0
  108. package/templates/base/.claude/skills/linear/scripts/issues/archive.ts +30 -0
  109. package/templates/base/.claude/skills/linear/scripts/issues/create.ts +279 -0
  110. package/templates/base/.claude/skills/linear/scripts/issues/get.ts +68 -0
  111. package/templates/base/.claude/skills/linear/scripts/issues/list.ts +67 -0
  112. package/templates/base/.claude/skills/linear/scripts/issues/update.ts +281 -0
  113. package/templates/base/.claude/skills/linear/scripts/labels/add-to-issue.ts +63 -0
  114. package/templates/base/.claude/skills/linear/scripts/labels/create.ts +45 -0
  115. package/templates/base/.claude/skills/linear/scripts/labels/list.ts +30 -0
  116. package/templates/base/.claude/skills/linear/scripts/list-teams.ts +52 -0
  117. package/templates/base/.claude/skills/linear/scripts/setup/setup-credentials.ts +96 -0
  118. package/templates/base/.claude/skills/linear/scripts/status/list.ts +31 -0
  119. package/templates/base/.claude/skills/linear/scripts/status/set-by-name.ts +78 -0
  120. package/templates/base/.claude/skills/linear/scripts/status/update.ts +44 -0
  121. package/templates/base/.claude/skills/linear/scripts/users/list.ts +59 -0
  122. package/templates/base/.claude/skills/linear/scripts/users/me.ts +20 -0
  123. package/templates/base/.claude/skills/linear/templates/README.md +203 -0
  124. package/templates/base/.claude/skills/linear/templates/api-reference.md +258 -0
  125. package/templates/base/.claude/skills/linear/templates/bug-report.md +99 -0
  126. package/templates/base/.claude/skills/linear/templates/feature-request.md +118 -0
  127. package/templates/base/.claude/skills/linear/templates/security-issue.md +162 -0
  128. package/templates/base/.claude/skills/linear/templates/sprint-task.md +175 -0
  129. package/templates/base/.claude/skills/linear/templates/tech-debt.md +137 -0
  130. package/templates/base/.claude/skills/linear/tsconfig.json +17 -0
  131. package/templates/base/.claude/skills/linear/workflows/issue-lifecycle.md +317 -0
  132. package/templates/base/.claude/skills/playwright-e2e-testing/SKILL.md +113 -0
  133. package/templates/base/.claude/skills/playwright-e2e-testing/assets/global-setup.template.js +97 -0
  134. package/templates/base/.claude/skills/playwright-e2e-testing/assets/playwright.config.template.js +171 -0
  135. package/templates/base/.claude/skills/playwright-e2e-testing/assets/test-template.spec.js +163 -0
  136. package/templates/base/.claude/skills/playwright-e2e-testing/examples/README.md +26 -0
  137. package/templates/base/.claude/skills/playwright-e2e-testing/examples/ads.email-deeplink.spec.ts +12 -0
  138. package/templates/base/.claude/skills/playwright-e2e-testing/examples/mobile.realism.spec.ts +16 -0
  139. package/templates/base/.claude/skills/playwright-e2e-testing/examples/smoke.home.spec.ts +6 -0
  140. package/templates/base/.claude/skills/playwright-e2e-testing/references/architecture.md +578 -0
  141. package/templates/base/.claude/skills/playwright-e2e-testing/references/best-practices.md +260 -0
  142. package/templates/base/.claude/skills/playwright-e2e-testing/references/ci-reporting.md +86 -0
  143. package/templates/base/.claude/skills/playwright-e2e-testing/references/debugging.md +629 -0
  144. package/templates/base/.claude/skills/playwright-e2e-testing/references/mobile-realism.md +50 -0
  145. package/templates/base/.claude/skills/playwright-e2e-testing/references/optimization.md +488 -0
  146. package/templates/base/.claude/skills/playwright-e2e-testing/references/patterns.md +513 -0
  147. package/templates/base/.claude/skills/playwright-e2e-testing/references/resources.md +44 -0
  148. package/templates/base/.claude/skills/playwright-e2e-testing/references/visual-a11y.md +66 -0
  149. package/templates/base/.claude/skills/playwright-e2e-testing/scripts/auth-setup.js +202 -0
  150. package/templates/base/.claude/skills/playwright-e2e-testing/scripts/performance-analyzer.js +240 -0
  151. package/templates/base/.claude/skills/playwright-e2e-testing/scripts/trace-url.js +132 -0
  152. package/templates/base/.claude/skills/playwright-e2e-testing/templates/ci/github-actions.playwright.yml +78 -0
  153. package/templates/base/.claude/skills/playwright-e2e-testing/templates/fixtures.ts +44 -0
  154. package/templates/base/.claude/skills/playwright-e2e-testing/templates/global-setup.template.js +97 -0
  155. package/templates/base/.claude/skills/playwright-e2e-testing/templates/global.setup.ts +35 -0
  156. package/templates/base/.claude/skills/playwright-e2e-testing/templates/helpers/ad-gpt-observer.ts +80 -0
  157. package/templates/base/.claude/skills/playwright-e2e-testing/templates/helpers/chromium-mobile-profile.ts +93 -0
  158. package/templates/base/.claude/skills/playwright-e2e-testing/templates/playwright.config.template.js +171 -0
  159. package/templates/base/.claude/skills/playwright-e2e-testing/templates/playwright.config.ts +126 -0
  160. package/templates/base/.claude/skills/playwright-e2e-testing/templates/test-template.spec.js +163 -0
  161. package/templates/base/.claude/skills/playwright-e2e-testing/templates/tests/email-deeplink.ads.spec.ts +44 -0
  162. package/templates/base/.claude/skills/skill-rules.json +184 -0
  163. package/templates/base/.claude/skills/wrangler/SKILL.md +209 -0
  164. package/templates/base/.claude/skills/wrangler/resources/api.md +494 -0
  165. package/templates/base/.claude/skills/wrangler/resources/bundling.md +83 -0
  166. package/templates/base/.claude/skills/wrangler/resources/commands/cert.md +64 -0
  167. package/templates/base/.claude/skills/wrangler/resources/commands/check.md +66 -0
  168. package/templates/base/.claude/skills/wrangler/resources/commands/containers.md +157 -0
  169. package/templates/base/.claude/skills/wrangler/resources/commands/d1.md +843 -0
  170. package/templates/base/.claude/skills/wrangler/resources/commands/delete.md +27 -0
  171. package/templates/base/.claude/skills/wrangler/resources/commands/deploy.md +139 -0
  172. package/templates/base/.claude/skills/wrangler/resources/commands/deployments.md +56 -0
  173. package/templates/base/.claude/skills/wrangler/resources/commands/dev.md +157 -0
  174. package/templates/base/.claude/skills/wrangler/resources/commands/dispatch-namespace.md +69 -0
  175. package/templates/base/.claude/skills/wrangler/resources/commands/docs.md +61 -0
  176. package/templates/base/.claude/skills/wrangler/resources/commands/how-to-run.md +62 -0
  177. package/templates/base/.claude/skills/wrangler/resources/commands/hyperdrive.md +425 -0
  178. package/templates/base/.claude/skills/wrangler/resources/commands/init.md +31 -0
  179. package/templates/base/.claude/skills/wrangler/resources/commands/kv-bulk.md +265 -0
  180. package/templates/base/.claude/skills/wrangler/resources/commands/kv-key.md +353 -0
  181. package/templates/base/.claude/skills/wrangler/resources/commands/kv-namespace.md +265 -0
  182. package/templates/base/.claude/skills/wrangler/resources/commands/login.md +23 -0
  183. package/templates/base/.claude/skills/wrangler/resources/commands/logout.md +19 -0
  184. package/templates/base/.claude/skills/wrangler/resources/commands/mtls-certificate.md +69 -0
  185. package/templates/base/.claude/skills/wrangler/resources/commands/pages.md +175 -0
  186. package/templates/base/.claude/skills/wrangler/resources/commands/pipelines.md +76 -0
  187. package/templates/base/.claude/skills/wrangler/resources/commands/queues.md +132 -0
  188. package/templates/base/.claude/skills/wrangler/resources/commands/r2-bucket.md +342 -0
  189. package/templates/base/.claude/skills/wrangler/resources/commands/r2-object.md +267 -0
  190. package/templates/base/.claude/skills/wrangler/resources/commands/r2-sql.md +65 -0
  191. package/templates/base/.claude/skills/wrangler/resources/commands/rollback.md +40 -0
  192. package/templates/base/.claude/skills/wrangler/resources/commands/secret.md +308 -0
  193. package/templates/base/.claude/skills/wrangler/resources/commands/secrets-store-secret.md +100 -0
  194. package/templates/base/.claude/skills/wrangler/resources/commands/secrets-store-store.md +60 -0
  195. package/templates/base/.claude/skills/wrangler/resources/commands/setup.md +67 -0
  196. package/templates/base/.claude/skills/wrangler/resources/commands/tail.md +37 -0
  197. package/templates/base/.claude/skills/wrangler/resources/commands/telemetry.md +64 -0
  198. package/templates/base/.claude/skills/wrangler/resources/commands/triggers.md +39 -0
  199. package/templates/base/.claude/skills/wrangler/resources/commands/types.md +73 -0
  200. package/templates/base/.claude/skills/wrangler/resources/commands/vectorize.md +941 -0
  201. package/templates/base/.claude/skills/wrangler/resources/commands/versions.md +95 -0
  202. package/templates/base/.claude/skills/wrangler/resources/commands/whoami.md +49 -0
  203. package/templates/base/.claude/skills/wrangler/resources/commands/workflows.md +117 -0
  204. package/templates/base/.claude/skills/wrangler/resources/commands.md +138 -0
  205. package/templates/base/.claude/skills/wrangler/resources/configuration.md +2176 -0
  206. package/templates/base/.claude/skills/wrangler/resources/custom-builds.md +55 -0
  207. package/templates/base/.claude/skills/wrangler/resources/deprecations.md +279 -0
  208. package/templates/base/.claude/skills/wrangler/resources/enviroments.md +416 -0
  209. package/templates/base/.claude/skills/wrangler/resources/extract_sections.py +119 -0
  210. package/templates/base/.claude/skills/wrangler/resources/process_content.py +94 -0
  211. package/templates/base/.claude/skills/wrangler/resources/system-enviroments-variables.md +120 -0
  212. package/templates/base/.dev.vars.example +15 -0
  213. package/templates/base/.env.example +29 -0
  214. package/templates/base/.github/workflows/test.yml +127 -0
  215. package/templates/base/.nycrc.json +16 -0
  216. package/templates/base/CLAUDE.md +218 -0
  217. package/templates/base/README.md +670 -0
  218. package/templates/base/auth-setup-error.png +0 -0
  219. package/templates/base/config/drizzle.config.ts +10 -0
  220. package/templates/base/config/eslint.config.js +364 -0
  221. package/templates/base/config/wrangler.json +76 -0
  222. package/templates/base/docs/app_spec.txt +879 -0
  223. package/templates/base/docs/app_spec_template.md +681 -0
  224. package/templates/base/docs/architecture/README.md +8 -0
  225. package/templates/base/docs/architecture/data-requirements.md +109 -0
  226. package/templates/base/docs/architecture/erd.md +91 -0
  227. package/templates/base/docs/features/feature_list.json +3128 -0
  228. package/templates/base/docs/hono-boilerplate-plan.md +1774 -0
  229. package/templates/base/docs/test-coverage-gap-analysis.md +242 -0
  230. package/templates/base/docs/testing.md +188 -0
  231. package/templates/base/index.html +16 -0
  232. package/templates/base/package.json +115 -0
  233. package/templates/base/playwright.config.ts +158 -0
  234. package/templates/base/pnpm-lock.yaml +8175 -0
  235. package/templates/base/scripts/capture-prod-session.ts +250 -0
  236. package/templates/base/scripts/generate-openapi.ts +23 -0
  237. package/templates/base/scripts/init.sh +121 -0
  238. package/templates/base/src/client/__tests__/button.test.tsx +30 -0
  239. package/templates/base/src/client/__tests__/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-display-dashboard-stats-cards-1.png +0 -0
  240. package/templates/base/src/client/__tests__/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-display-quick-action-cards-1.png +0 -0
  241. package/templates/base/src/client/__tests__/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-display-recent-activity-section-1.png +0 -0
  242. package/templates/base/src/client/__tests__/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-display-user-first-name-in-welcome-message-1.png +0 -0
  243. package/templates/base/src/client/__tests__/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-display-user-information-in-sidebar-1.png +0 -0
  244. package/templates/base/src/client/__tests__/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-render-dashboard-when-authenticated-1.png +0 -0
  245. package/templates/base/src/client/__tests__/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-show-navigation-sidebar-1.png +0 -0
  246. package/templates/base/src/client/__tests__/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-unauthenticated-should-redirect-to-login-when-not-authenticated-1.png +0 -0
  247. package/templates/base/src/client/__tests__/routes/__screenshots__/login.test.tsx/Login-Page-should-display-Google-OAuth-login-button-1.png +0 -0
  248. package/templates/base/src/client/__tests__/routes/__screenshots__/login.test.tsx/Login-Page-should-have-a-link-back-to-home-page-1.png +0 -0
  249. package/templates/base/src/client/__tests__/routes/__screenshots__/login.test.tsx/Login-Page-should-render-login-content-without-waiting-for-authentication-1.png +0 -0
  250. package/templates/base/src/client/__tests__/routes/__screenshots__/login.test.tsx/Login-Page-should-render-login-page-at--login-route-1.png +0 -0
  251. package/templates/base/src/client/__tests__/routes/__screenshots__/login.test.tsx/Login-Page-should-show-Terms-of-Service-and-Privacy-Policy-links-1.png +0 -0
  252. package/templates/base/src/client/__tests__/routes/__screenshots__/login.test.tsx/Login-Page-should-trigger-OAuth-flow-when-clicking-login-button-1.png +0 -0
  253. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-404-handling-should-display-404-text-on-not-found-page-1.png +0 -0
  254. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-404-handling-should-have-navigation-options-on-404-page-1.png +0 -0
  255. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-404-handling-should-render-404-page-for-unknown-routes-1.png +0 -0
  256. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-authenticated-navigation-should-navigate-from-dashboard-to-account-page-1.png +0 -0
  257. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-authenticated-navigation-should-navigate-from-dashboard-to-integrations-page-1.png +0 -0
  258. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-authenticated-navigation-should-navigate-from-dashboard-to-settings-page-1.png +0 -0
  259. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-authenticated-navigation-should-navigate-from-dashboard-to-team-page-1.png +0 -0
  260. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-home-page-navigation-should-display-navigation-links-on-home-page-1.png +0 -0
  261. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-home-page-navigation-should-have-correct-link-destinations-on-home-page-1.png +0 -0
  262. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-unauthenticated-navigation-should-allow-access-to-home-page-without-authentication-1.png +0 -0
  263. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-unauthenticated-navigation-should-allow-access-to-login-page-without-authentication-1.png +0 -0
  264. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-unauthenticated-navigation-should-redirect-unauthenticated-users-from-dashboard-to-login-1.png +0 -0
  265. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-unauthenticated-navigation-should-redirect-unauthenticated-users-from-settings-to-login-1.png +0 -0
  266. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-unauthenticated-navigation-should-redirect-unauthenticated-users-from-team-to-login-1.png +0 -0
  267. package/templates/base/src/client/__tests__/routes/authenticated-layout.test.tsx +252 -0
  268. package/templates/base/src/client/__tests__/routes/dashboard.test.tsx +136 -0
  269. package/templates/base/src/client/__tests__/routes/error-components.test.tsx +186 -0
  270. package/templates/base/src/client/__tests__/routes/login.test.tsx +112 -0
  271. package/templates/base/src/client/__tests__/routes/navigation.test.tsx +272 -0
  272. package/templates/base/src/client/__tests__/routes/root-layout.test.tsx +65 -0
  273. package/templates/base/src/client/__tests__/setup-browser.ts +15 -0
  274. package/templates/base/src/client/__tests__/setup.ts +32 -0
  275. package/templates/base/src/client/__tests__/test-utils.tsx +135 -0
  276. package/templates/base/src/client/api/.gitkeep +0 -0
  277. package/templates/base/src/client/components/__tests__/__screenshots__/sidebar.test.tsx/Sidebar-can-be-collapsed-by-default-1.png +0 -0
  278. package/templates/base/src/client/components/__tests__/__screenshots__/sidebar.test.tsx/Sidebar-expands-when-collapsed-and-expand-button-is-clicked-1.png +0 -0
  279. package/templates/base/src/client/components/__tests__/__screenshots__/sidebar.test.tsx/Sidebar-handles-logout-button-click-1.png +0 -0
  280. package/templates/base/src/client/components/__tests__/__screenshots__/sidebar.test.tsx/Sidebar-handles-navigation-clicks-1.png +0 -0
  281. package/templates/base/src/client/components/__tests__/__screenshots__/sidebar.test.tsx/Sidebar-hides-navigation-labels-when-collapsed-1.png +0 -0
  282. package/templates/base/src/client/components/__tests__/__screenshots__/sidebar.test.tsx/Sidebar-highlights-active-route-1.png +0 -0
  283. package/templates/base/src/client/components/__tests__/__screenshots__/sidebar.test.tsx/Sidebar-renders-sidebar-navigation-items-1.png +0 -0
  284. package/templates/base/src/client/components/__tests__/__screenshots__/sidebar.test.tsx/Sidebar-shows-keyboard-shortcut-hint-when-expanded-1.png +0 -0
  285. package/templates/base/src/client/components/__tests__/__screenshots__/sidebar.test.tsx/Sidebar-shows-user-info-when-authenticated-1.png +0 -0
  286. package/templates/base/src/client/components/__tests__/__screenshots__/sidebar.test.tsx/Sidebar-shows-user-initials-in-avatar-fallback-1.png +0 -0
  287. package/templates/base/src/client/components/__tests__/error-boundary.test.tsx +97 -0
  288. package/templates/base/src/client/components/__tests__/sidebar.test.tsx +281 -0
  289. package/templates/base/src/client/components/error-boundary.tsx +68 -0
  290. package/templates/base/src/client/components/icons.tsx +106 -0
  291. package/templates/base/src/client/components/layout/.gitkeep +0 -0
  292. package/templates/base/src/client/components/sidebar.tsx +267 -0
  293. package/templates/base/src/client/components/ui/.gitkeep +0 -0
  294. package/templates/base/src/client/components/ui/__tests__/avatar.test.tsx +308 -0
  295. package/templates/base/src/client/components/ui/__tests__/card.test.tsx +214 -0
  296. package/templates/base/src/client/components/ui/__tests__/dialog.test.tsx +297 -0
  297. package/templates/base/src/client/components/ui/__tests__/error-fallback.test.tsx +145 -0
  298. package/templates/base/src/client/components/ui/__tests__/input.test.tsx +98 -0
  299. package/templates/base/src/client/components/ui/__tests__/loading-skeleton.test.tsx +139 -0
  300. package/templates/base/src/client/components/ui/__tests__/skeleton.test.tsx +44 -0
  301. package/templates/base/src/client/components/ui/__tests__/sonner.test.tsx +28 -0
  302. package/templates/base/src/client/components/ui/__tests__/tabs.test.tsx +233 -0
  303. package/templates/base/src/client/components/ui/avatar.tsx +101 -0
  304. package/templates/base/src/client/components/ui/badge.tsx +46 -0
  305. package/templates/base/src/client/components/ui/button.tsx +72 -0
  306. package/templates/base/src/client/components/ui/card.tsx +86 -0
  307. package/templates/base/src/client/components/ui/dialog.tsx +140 -0
  308. package/templates/base/src/client/components/ui/error-fallback.tsx +179 -0
  309. package/templates/base/src/client/components/ui/form.tsx +172 -0
  310. package/templates/base/src/client/components/ui/input.tsx +24 -0
  311. package/templates/base/src/client/components/ui/label.tsx +22 -0
  312. package/templates/base/src/client/components/ui/loading-skeleton.tsx +154 -0
  313. package/templates/base/src/client/components/ui/separator.tsx +33 -0
  314. package/templates/base/src/client/components/ui/skeleton.tsx +16 -0
  315. package/templates/base/src/client/components/ui/sonner.tsx +29 -0
  316. package/templates/base/src/client/components/ui/tabs.tsx +121 -0
  317. package/templates/base/src/client/hooks/.gitkeep +0 -0
  318. package/templates/base/src/client/hooks/__tests__/use-auth.test.tsx +306 -0
  319. package/templates/base/src/client/hooks/__tests__/use-theme.test.tsx +172 -0
  320. package/templates/base/src/client/hooks/use-auth.ts +53 -0
  321. package/templates/base/src/client/hooks/use-theme.tsx +78 -0
  322. package/templates/base/src/client/index.css +881 -0
  323. package/templates/base/src/client/lib/query-client.ts +11 -0
  324. package/templates/base/src/client/lib/utils.ts +7 -0
  325. package/templates/base/src/client/main.tsx +26 -0
  326. package/templates/base/src/client/routeTree.gen.ts +258 -0
  327. package/templates/base/src/client/router.ts +15 -0
  328. package/templates/base/src/client/routes/$.tsx +77 -0
  329. package/templates/base/src/client/routes/.gitkeep +0 -0
  330. package/templates/base/src/client/routes/__root.tsx +34 -0
  331. package/templates/base/src/client/routes/__tests__/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-display-accept-invitation-button-1.png +0 -0
  332. package/templates/base/src/client/routes/__tests__/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-display-decline-button-linking-to-homepage-1.png +0 -0
  333. package/templates/base/src/client/routes/__tests__/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-display-invitation-details--email--workspace--role--1.png +0 -0
  334. package/templates/base/src/client/routes/__tests__/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-have-a-logo-link-to-homepage-1.png +0 -0
  335. package/templates/base/src/client/routes/__tests__/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-render-invitation-page-with-inviter-name-and-workspace-1.png +0 -0
  336. package/templates/base/src/client/routes/__tests__/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-show-terms-of-service-and-privacy-policy-links-1.png +0 -0
  337. package/templates/base/src/client/routes/__tests__/invite.test.tsx +138 -0
  338. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/account.test.tsx/Account-Page-should-render-Active-Sessions-section-with-session-cards-1.png +0 -0
  339. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/account.test.tsx/Account-Page-should-render-page-with-correct-title--Account--1.png +0 -0
  340. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/account.test.tsx/Account-Page-should-show-API-Access-section-1.png +0 -0
  341. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/account.test.tsx/Account-Page-should-show-Connected-Accounts-section-with-Google-connected-1.png +0 -0
  342. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/account.test.tsx/Account-Page-should-show-Danger-Zone-section-with-delete-button-1.png +0 -0
  343. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/account.test.tsx/Account-Page-should-show-Security-section-with-Two-Factor-Authentication-1.png +0 -0
  344. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-API-documentation-section-should-display-API-documentation-link-section-1.png +0 -0
  345. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-Create-Webhook-Dialog-should-have-Add-Webhook-trigger-button-1.png +0 -0
  346. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-category-filters-should-display-all-category-buttons-1.png +0 -0
  347. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-integration-cards-should-display-all-integration-cards-with-names-1.png +0 -0
  348. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-integration-cards-should-display-category-badges-on-cards-1.png +0 -0
  349. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-integration-cards-should-show-Configure-button-for-connected-integrations-1.png +0 -0
  350. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-integration-cards-should-show-Connect-button-for-not-connected-integrations-1.png +0 -0
  351. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-integration-cards-should-show-Connected-badge-for-connected-integrations-1.png +0 -0
  352. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-display-Available-Integrations-section-1.png +0 -0
  353. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-display-Webhooks-section-1.png +0 -0
  354. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-display-connected-count-1.png +0 -0
  355. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-display-page-description-1.png +0 -0
  356. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-display-search-input-1.png +0 -0
  357. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-render-with-correct-title--Integrations--1.png +0 -0
  358. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-search-functionality-should-filter-integrations-based-on-search-query-1.png +0 -0
  359. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-search-functionality-should-search-by-description-1.png +0 -0
  360. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-search-functionality-should-show-no-results-message-when-search-has-no-matches-1.png +0 -0
  361. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-webhooks-section-should-display-existing-webhook-1.png +0 -0
  362. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-webhooks-section-should-display-webhook-events-1.png +0 -0
  363. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-webhooks-section-should-display-webhook-last-delivery-info-1.png +0 -0
  364. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-webhooks-section-should-display-webhook-success-status-1.png +0 -0
  365. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-webhooks-section-should-have-Add-Webhook-button-1.png +0 -0
  366. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Account-tab-should-display-connected-accounts-section-with-Google-provider-1.png +0 -0
  367. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Account-tab-should-display-sessions-and-danger-zone-sections-1.png +0 -0
  368. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Notifications-tab-should-display-all-notification-toggle-options-1.png +0 -0
  369. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Notifications-tab-should-display-email-notifications-section-1.png +0 -0
  370. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Notifications-tab-should-display-toggle-switches-for-notification-options-1.png +0 -0
  371. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Notifications-tab-should-have-toggles-checked-by-default-1.png +0 -0
  372. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display--Save-Changes--button-1.png +0 -0
  373. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display-personal-information-form-1.png +0 -0
  374. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display-profile-picture-section-1.png +0 -0
  375. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display-user-email-in-disabled-email-input-1.png +0 -0
  376. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display-user-initials-in-avatar-1.png +0 -0
  377. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display-user-name-in-the-name-input-1.png +0 -0
  378. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-page-rendering-should-display-all-three-tabs-1.png +0 -0
  379. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-page-rendering-should-display-page-description-1.png +0 -0
  380. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-page-rendering-should-render-with-correct-title--Settings--1.png +0 -0
  381. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-tab-navigation-should-show-Profile-tab-as-default-active-tab-1.png +0 -0
  382. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-tab-navigation-should-switch-to-Account-tab-when-clicked-1.png +0 -0
  383. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-tab-navigation-should-switch-to-Notifications-tab-when-clicked-1.png +0 -0
  384. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/team.test.tsx/Team-Page-should-display-Active-Members-section-with-member-count-1.png +0 -0
  385. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/team.test.tsx/Team-Page-should-display-Pending-Invitations-section-with-invitation-details-1.png +0 -0
  386. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/team.test.tsx/Team-Page-should-have-invite-member-button-that-can-be-clicked-1.png +0 -0
  387. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/team.test.tsx/Team-Page-should-render-page-with-correct-title-and-description-1.png +0 -0
  388. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/team.test.tsx/Team-Page-should-render-search-input-that-filters-team-members-1.png +0 -0
  389. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/team.test.tsx/Team-Page-should-show-current-user-with---you---indicator-and-role-badge-1.png +0 -0
  390. package/templates/base/src/client/routes/_authenticated/__tests__/account.test.tsx +324 -0
  391. package/templates/base/src/client/routes/_authenticated/__tests__/integrations.test.tsx +520 -0
  392. package/templates/base/src/client/routes/_authenticated/__tests__/settings.test.tsx +414 -0
  393. package/templates/base/src/client/routes/_authenticated/__tests__/team.test.tsx +374 -0
  394. package/templates/base/src/client/routes/_authenticated/account.tsx +416 -0
  395. package/templates/base/src/client/routes/_authenticated/dashboard.tsx +151 -0
  396. package/templates/base/src/client/routes/_authenticated/integrations.tsx +553 -0
  397. package/templates/base/src/client/routes/_authenticated/settings.tsx +310 -0
  398. package/templates/base/src/client/routes/_authenticated/team.tsx +395 -0
  399. package/templates/base/src/client/routes/_authenticated.tsx +69 -0
  400. package/templates/base/src/client/routes/index.tsx +155 -0
  401. package/templates/base/src/client/routes/invite.$token.tsx +191 -0
  402. package/templates/base/src/client/routes/login.tsx +92 -0
  403. package/templates/base/src/server/__tests__/fixtures.ts +461 -0
  404. package/templates/base/src/server/__tests__/mocks/__tests__/db.test.ts +239 -0
  405. package/templates/base/src/server/__tests__/mocks/__tests__/kv.test.ts +293 -0
  406. package/templates/base/src/server/__tests__/mocks/__tests__/r2.test.ts +363 -0
  407. package/templates/base/src/server/__tests__/mocks/db.ts +186 -0
  408. package/templates/base/src/server/__tests__/mocks/index.ts +33 -0
  409. package/templates/base/src/server/__tests__/mocks/kv.ts +286 -0
  410. package/templates/base/src/server/__tests__/mocks/r2.ts +397 -0
  411. package/templates/base/src/server/__tests__/setup.ts +281 -0
  412. package/templates/base/src/server/auth/__tests__/guards.test.ts +162 -0
  413. package/templates/base/src/server/auth/guards.ts +92 -0
  414. package/templates/base/src/server/auth/permissions.test.ts +45 -0
  415. package/templates/base/src/server/auth/permissions.ts +139 -0
  416. package/templates/base/src/server/auth/roles.test.ts +169 -0
  417. package/templates/base/src/server/auth/roles.ts +141 -0
  418. package/templates/base/src/server/db/client.ts +12 -0
  419. package/templates/base/src/server/db/schema/accounts.ts +20 -0
  420. package/templates/base/src/server/db/schema/audit-logs.ts +26 -0
  421. package/templates/base/src/server/db/schema/index.ts +7 -0
  422. package/templates/base/src/server/db/schema/invitations.ts +30 -0
  423. package/templates/base/src/server/db/schema/refresh-tokens.ts +22 -0
  424. package/templates/base/src/server/db/schema/user-accounts.ts +25 -0
  425. package/templates/base/src/server/db/schema/users.ts +33 -0
  426. package/templates/base/src/server/db/seed.ts +267 -0
  427. package/templates/base/src/server/env.test.ts +84 -0
  428. package/templates/base/src/server/env.ts +78 -0
  429. package/templates/base/src/server/index.ts +82 -0
  430. package/templates/base/src/server/lib/audit.ts +73 -0
  431. package/templates/base/src/server/lib/audited-db.test.ts +107 -0
  432. package/templates/base/src/server/lib/audited-db.ts +154 -0
  433. package/templates/base/src/server/lib/email.test.ts +116 -0
  434. package/templates/base/src/server/lib/email.ts +82 -0
  435. package/templates/base/src/server/lib/errors.test.ts +49 -0
  436. package/templates/base/src/server/lib/errors.ts +64 -0
  437. package/templates/base/src/server/lib/oauth.test.ts +238 -0
  438. package/templates/base/src/server/lib/oauth.ts +113 -0
  439. package/templates/base/src/server/lib/pagination.test.ts +52 -0
  440. package/templates/base/src/server/lib/pagination.ts +32 -0
  441. package/templates/base/src/server/lib/password.test.ts +151 -0
  442. package/templates/base/src/server/lib/password.ts +151 -0
  443. package/templates/base/src/server/lib/providers.test.ts +105 -0
  444. package/templates/base/src/server/lib/providers.ts +62 -0
  445. package/templates/base/src/server/lib/r2-storage.test.ts +202 -0
  446. package/templates/base/src/server/lib/r2-storage.ts +107 -0
  447. package/templates/base/src/server/lib/schema-helpers.ts +16 -0
  448. package/templates/base/src/server/lib/session.test.ts +758 -0
  449. package/templates/base/src/server/lib/session.ts +267 -0
  450. package/templates/base/src/server/lib/tokens.test.ts +208 -0
  451. package/templates/base/src/server/lib/tokens.ts +65 -0
  452. package/templates/base/src/server/lib/transaction.test.ts +45 -0
  453. package/templates/base/src/server/lib/transaction.ts +24 -0
  454. package/templates/base/src/server/middleware/account.test.ts +201 -0
  455. package/templates/base/src/server/middleware/account.ts +66 -0
  456. package/templates/base/src/server/middleware/auth.test.ts +345 -0
  457. package/templates/base/src/server/middleware/auth.ts +146 -0
  458. package/templates/base/src/server/middleware/cors.test.ts +88 -0
  459. package/templates/base/src/server/middleware/cors.ts +26 -0
  460. package/templates/base/src/server/middleware/error-handler.test.ts +69 -0
  461. package/templates/base/src/server/middleware/error-handler.ts +43 -0
  462. package/templates/base/src/server/middleware/index.ts +8 -0
  463. package/templates/base/src/server/middleware/rate-limit.test.ts +472 -0
  464. package/templates/base/src/server/middleware/rate-limit.ts +294 -0
  465. package/templates/base/src/server/middleware/request-context.test.ts +175 -0
  466. package/templates/base/src/server/middleware/request-context.ts +28 -0
  467. package/templates/base/src/server/middleware/request-logger.test.ts +92 -0
  468. package/templates/base/src/server/middleware/request-logger.ts +50 -0
  469. package/templates/base/src/server/routes/accounts/__tests__/handlers.test.ts +460 -0
  470. package/templates/base/src/server/routes/accounts/handlers.ts +179 -0
  471. package/templates/base/src/server/routes/accounts/index.ts +55 -0
  472. package/templates/base/src/server/routes/accounts/routes.ts +205 -0
  473. package/templates/base/src/server/routes/accounts/schemas.ts +31 -0
  474. package/templates/base/src/server/routes/api.ts +37 -0
  475. package/templates/base/src/server/routes/audits/__tests__/handlers.test.ts +349 -0
  476. package/templates/base/src/server/routes/audits/handlers.ts +37 -0
  477. package/templates/base/src/server/routes/audits/index.ts +14 -0
  478. package/templates/base/src/server/routes/audits/routes.ts +29 -0
  479. package/templates/base/src/server/routes/audits/schemas.ts +43 -0
  480. package/templates/base/src/server/routes/auth/__tests__/handlers.test.ts +381 -0
  481. package/templates/base/src/server/routes/auth/handlers.ts +222 -0
  482. package/templates/base/src/server/routes/auth/index.ts +37 -0
  483. package/templates/base/src/server/routes/auth/routes.ts +136 -0
  484. package/templates/base/src/server/routes/auth/schemas.ts +48 -0
  485. package/templates/base/src/server/routes/auth/test-login.ts +156 -0
  486. package/templates/base/src/server/routes/health/__tests__/handlers.test.ts +237 -0
  487. package/templates/base/src/server/routes/health/handlers.ts +83 -0
  488. package/templates/base/src/server/routes/health/index.ts +13 -0
  489. package/templates/base/src/server/routes/health/routes.ts +90 -0
  490. package/templates/base/src/server/routes/index.ts +53 -0
  491. package/templates/base/src/server/routes/invitations/__tests__/handlers.test.ts +473 -0
  492. package/templates/base/src/server/routes/invitations/handlers.ts +71 -0
  493. package/templates/base/src/server/routes/invitations/index.ts +25 -0
  494. package/templates/base/src/server/routes/invitations/routes.ts +69 -0
  495. package/templates/base/src/server/routes/invitations/schemas.ts +39 -0
  496. package/templates/base/src/server/routes/openapi.ts +14 -0
  497. package/templates/base/src/server/routes/schemas.ts +53 -0
  498. package/templates/base/src/server/routes/storage/__tests__/handlers.test.ts +408 -0
  499. package/templates/base/src/server/routes/storage/handlers.ts +100 -0
  500. package/templates/base/src/server/routes/storage/index.ts +42 -0
  501. package/templates/base/src/server/routes/storage/routes.ts +91 -0
  502. package/templates/base/src/server/routes/storage/schemas.ts +56 -0
  503. package/templates/base/src/server/routes/users/__tests__/handlers.test.ts +526 -0
  504. package/templates/base/src/server/routes/users/handlers.ts +228 -0
  505. package/templates/base/src/server/routes/users/index.ts +67 -0
  506. package/templates/base/src/server/routes/users/routes.ts +265 -0
  507. package/templates/base/src/server/routes/users/schemas.ts +67 -0
  508. package/templates/base/src/server/services/__tests__/accounts.test.ts +764 -0
  509. package/templates/base/src/server/services/__tests__/audits.test.ts +235 -0
  510. package/templates/base/src/server/services/__tests__/auth.test.ts +765 -0
  511. package/templates/base/src/server/services/__tests__/invitations.test.ts +704 -0
  512. package/templates/base/src/server/services/__tests__/users.test.ts +755 -0
  513. package/templates/base/src/server/services/accounts.ts +269 -0
  514. package/templates/base/src/server/services/audits.ts +82 -0
  515. package/templates/base/src/server/services/auth.ts +225 -0
  516. package/templates/base/src/server/services/index.ts +6 -0
  517. package/templates/base/src/server/services/invitations.ts +306 -0
  518. package/templates/base/src/server/services/users.ts +350 -0
  519. package/templates/base/src/server/types/auth.ts +36 -0
  520. package/templates/base/src/server/types/index.ts +117 -0
  521. package/templates/base/src/shared/schemas/.gitkeep +0 -0
  522. package/templates/base/src/shared/schemas/__tests__/schemas.test.ts +547 -0
  523. package/templates/base/src/shared/schemas/account.ts +15 -0
  524. package/templates/base/src/shared/schemas/index.ts +6 -0
  525. package/templates/base/src/shared/schemas/invitation.ts +9 -0
  526. package/templates/base/src/shared/schemas/profile.ts +10 -0
  527. package/templates/base/src/shared/schemas/user.ts +16 -0
  528. package/templates/base/src/shared/schemas/webhook.ts +12 -0
  529. package/templates/base/src/shared/types/.gitkeep +0 -0
  530. package/templates/base/src/shared/types/account.ts +12 -0
  531. package/templates/base/src/shared/types/api.ts +1399 -0
  532. package/templates/base/src/shared/types/auth.ts +24 -0
  533. package/templates/base/src/shared/types/index.ts +5 -0
  534. package/templates/base/src/shared/types/user.ts +31 -0
  535. package/templates/base/src/test/vitest-zod-matcher.ts +37 -0
  536. package/templates/base/src/test/vitest.d.ts +19 -0
  537. package/templates/base/tests/e2e/README.md +141 -0
  538. package/templates/base/tests/e2e/a11y/accessibility.spec.ts +925 -0
  539. package/templates/base/tests/e2e/a11y/keyboard-navigation.spec.ts +610 -0
  540. package/templates/base/tests/e2e/api/accounts.spec.ts +148 -0
  541. package/templates/base/tests/e2e/api/audit-logs.spec.ts +130 -0
  542. package/templates/base/tests/e2e/api/authenticated-api.spec.ts +311 -0
  543. package/templates/base/tests/e2e/api/storage.spec.ts +109 -0
  544. package/templates/base/tests/e2e/auth-flows.unauth.spec.ts +117 -0
  545. package/templates/base/tests/e2e/auth-logout.unauth.spec.ts +103 -0
  546. package/templates/base/tests/e2e/auth.setup.ts +115 -0
  547. package/templates/base/tests/e2e/auth.spec.ts +146 -0
  548. package/templates/base/tests/e2e/compatibility/cross-browser.spec.ts +152 -0
  549. package/templates/base/tests/e2e/compatibility/cross-browser.spec.ts-snapshots/login-chromium-chromium-darwin.png +0 -0
  550. package/templates/base/tests/e2e/crud/account.spec.ts +356 -0
  551. package/templates/base/tests/e2e/crud/integrations.spec.ts +419 -0
  552. package/templates/base/tests/e2e/crud/team.spec.ts +287 -0
  553. package/templates/base/tests/e2e/crud/users.spec.ts +239 -0
  554. package/templates/base/tests/e2e/errors/error-boundary.spec.ts +428 -0
  555. package/templates/base/tests/e2e/errors/error-handling.spec.ts +47 -0
  556. package/templates/base/tests/e2e/errors/error-handling.unauth.spec.ts +205 -0
  557. package/templates/base/tests/e2e/fixtures.ts +266 -0
  558. package/templates/base/tests/e2e/forms/validation.spec.ts +569 -0
  559. package/templates/base/tests/e2e/invitations/invite-flow.unauth.spec.ts +204 -0
  560. package/templates/base/tests/e2e/journeys/account-lifecycle.spec.ts +314 -0
  561. package/templates/base/tests/e2e/journeys/audit-investigation.spec.ts +299 -0
  562. package/templates/base/tests/e2e/journeys/auth-onboarding.spec.ts +232 -0
  563. package/templates/base/tests/e2e/journeys/critical-flows.spec.ts +281 -0
  564. package/templates/base/tests/e2e/journeys/error-recovery.spec.ts +354 -0
  565. package/templates/base/tests/e2e/journeys/file-management.spec.ts +307 -0
  566. package/templates/base/tests/e2e/journeys/integrations.spec.ts +372 -0
  567. package/templates/base/tests/e2e/journeys/multi-account.spec.ts +317 -0
  568. package/templates/base/tests/e2e/journeys/rbac-enforcement.spec.ts +389 -0
  569. package/templates/base/tests/e2e/journeys/settings-profile.spec.ts +400 -0
  570. package/templates/base/tests/e2e/journeys/team-collaboration.spec.ts +410 -0
  571. package/templates/base/tests/e2e/mobile/responsive.spec.ts +178 -0
  572. package/templates/base/tests/e2e/navigation/routing.spec.ts +371 -0
  573. package/templates/base/tests/e2e/navigation/sidebar.spec.ts +425 -0
  574. package/templates/base/tests/e2e/pages/ui-features.spec.ts +393 -0
  575. package/templates/base/tests/e2e/performance/baselines.spec.ts +162 -0
  576. package/templates/base/tests/e2e/performance/benchmarks.spec.ts +371 -0
  577. package/templates/base/tests/e2e/smoke.unauth.spec.ts +196 -0
  578. package/templates/base/tests/e2e/visual/components.spec.ts +650 -0
  579. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/confirmation-dialog-visual-darwin.png +0 -0
  580. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/dark-mode-background-visual-darwin.png +0 -0
  581. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/dark-mode-card-visual-darwin.png +0 -0
  582. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/dark-mode-sidebar-visual-darwin.png +0 -0
  583. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/dashboard-card-single-visual-darwin.png +0 -0
  584. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/dialog-content-visual-darwin.png +0 -0
  585. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/dialog-with-backdrop-visual-darwin.png +0 -0
  586. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/empty-search-results-visual-darwin.png +0 -0
  587. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/input-default-visual-darwin.png +0 -0
  588. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/input-focus-ring-visual-darwin.png +0 -0
  589. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/primary-button-focus-visual-darwin.png +0 -0
  590. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/primary-button-hover-visual-darwin.png +0 -0
  591. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/primary-button-visual-darwin.png +0 -0
  592. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/sidebar-active-nav-item-visual-darwin.png +0 -0
  593. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/sidebar-collapsed-visual-darwin.png +0 -0
  594. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/sidebar-navigation-visual-darwin.png +0 -0
  595. package/templates/base/tests/e2e/visual/core-components.spec.ts +192 -0
  596. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/account-page-visual-darwin.png +0 -0
  597. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/create-webhook-dialog-visual-darwin.png +0 -0
  598. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/dashboard-page-visual-darwin.png +0 -0
  599. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/delete-account-dialog-visual-darwin.png +0 -0
  600. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/integrations-page-visual-darwin.png +0 -0
  601. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/invite-member-dialog-visual-darwin.png +0 -0
  602. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/login-page-visual-darwin.png +0 -0
  603. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/settings-account-tab-visual-darwin.png +0 -0
  604. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/settings-profile-tab-visual-darwin.png +0 -0
  605. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/sidebar-navigation-visual-darwin.png +0 -0
  606. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/team-page-visual-darwin.png +0 -0
  607. package/templates/base/tests/e2e/visual/screenshots.spec.ts +230 -0
  608. package/templates/base/tests/e2e/visual/screenshots.spec.ts-snapshots/404-page-chromium-darwin.png +0 -0
  609. package/templates/base/tests/e2e/visual/screenshots.spec.ts-snapshots/404-page-visual-darwin.png +0 -0
  610. package/templates/base/tests/e2e/visual/screenshots.spec.ts-snapshots/account-page-visual-darwin.png +0 -0
  611. package/templates/base/tests/e2e/visual/screenshots.spec.ts-snapshots/login-page-chromium-darwin.png +0 -0
  612. package/templates/base/tests/e2e/visual/screenshots.spec.ts-snapshots/login-page-visual-darwin.png +0 -0
  613. package/templates/base/tests/e2e/visual/screenshots.spec.ts-snapshots/settings-page-visual-darwin.png +0 -0
  614. package/templates/base/tests/e2e/visual/screenshots.spec.ts-snapshots/team-invite-dialog-visual-darwin.png +0 -0
  615. package/templates/base/tests/e2e/visual/screenshots.spec.ts-snapshots/team-page-visual-darwin.png +0 -0
  616. package/templates/base/tests/e2e/visual/screenshots.spec.ts-snapshots/webhook-create-dialog-visual-darwin.png +0 -0
  617. package/templates/base/tests/e2e/visual/theme-colors.spec.ts +293 -0
  618. package/templates/base/tests/e2e/visual/ui-components.spec.ts +502 -0
  619. package/templates/base/tests/integration/accounts/crud.test.ts +1402 -0
  620. package/templates/base/tests/integration/audits/list.test.ts +1133 -0
  621. package/templates/base/tests/integration/auth/auth-service.test.ts +415 -0
  622. package/templates/base/tests/integration/auth/invitation-token.test.ts +529 -0
  623. package/templates/base/tests/integration/auth/logout.test.ts +524 -0
  624. package/templates/base/tests/integration/auth/oauth.test.ts +768 -0
  625. package/templates/base/tests/integration/auth/refresh-token.test.ts +364 -0
  626. package/templates/base/tests/integration/auth/session-expiry.test.ts +569 -0
  627. package/templates/base/tests/integration/auth/session.test.ts +520 -0
  628. package/templates/base/tests/integration/auth/super-admin.test.ts +451 -0
  629. package/templates/base/tests/integration/authorization/analytics-role.test.ts +1026 -0
  630. package/templates/base/tests/integration/authorization/billing-role.test.ts +776 -0
  631. package/templates/base/tests/integration/authorization/guards-roles.test.ts +539 -0
  632. package/templates/base/tests/integration/authorization/multi-tenancy.test.ts +1112 -0
  633. package/templates/base/tests/integration/authorization/role-hierarchy.test.ts +931 -0
  634. package/templates/base/tests/integration/authorization/roles.test.ts +1347 -0
  635. package/templates/base/tests/integration/config/production-behavior.test.ts +536 -0
  636. package/templates/base/tests/integration/db/constraints.test.ts +695 -0
  637. package/templates/base/tests/integration/fixtures/accounts.ts +136 -0
  638. package/templates/base/tests/integration/fixtures/index.ts +232 -0
  639. package/templates/base/tests/integration/fixtures/invitations.ts +195 -0
  640. package/templates/base/tests/integration/fixtures/users.ts +144 -0
  641. package/templates/base/tests/integration/health/health.test.ts +351 -0
  642. package/templates/base/tests/integration/invitations/crud.test.ts +1457 -0
  643. package/templates/base/tests/integration/invitations/email.test.ts +506 -0
  644. package/templates/base/tests/integration/lib/email.test.ts +174 -0
  645. package/templates/base/tests/integration/lib/oauth.test.ts +368 -0
  646. package/templates/base/tests/integration/lib/password.test.ts +192 -0
  647. package/templates/base/tests/integration/lib/schema-helpers.test.ts +129 -0
  648. package/templates/base/tests/integration/lib/tokens.test.ts +304 -0
  649. package/templates/base/tests/integration/middleware/auth.test.ts +499 -0
  650. package/templates/base/tests/integration/middleware/cors.test.ts +334 -0
  651. package/templates/base/tests/integration/middleware/request-context.test.ts +156 -0
  652. package/templates/base/tests/integration/middleware/request-logger.test.ts +313 -0
  653. package/templates/base/tests/integration/performance/response-times.test.ts +509 -0
  654. package/templates/base/tests/integration/security/cookie-security.test.ts +567 -0
  655. package/templates/base/tests/integration/security/csrf-protection.test.ts +542 -0
  656. package/templates/base/tests/integration/security/jwt-validation.test.ts +209 -0
  657. package/templates/base/tests/integration/security/log-sanitization.test.ts +658 -0
  658. package/templates/base/tests/integration/security/rate-limiting.test.ts +1251 -0
  659. package/templates/base/tests/integration/security/sql-injection.test.ts +663 -0
  660. package/templates/base/tests/integration/security/token-hashing.test.ts +371 -0
  661. package/templates/base/tests/integration/security/xss-prevention.test.ts +541 -0
  662. package/templates/base/tests/integration/setup.ts +834 -0
  663. package/templates/base/tests/integration/smoke.test.ts +288 -0
  664. package/templates/base/tests/integration/storage/upload.test.ts +1162 -0
  665. package/templates/base/tests/integration/storage/validation.test.ts +746 -0
  666. package/templates/base/tests/integration/users/crud.test.ts +1297 -0
  667. package/templates/base/tests/integration/users/list.test.ts +698 -0
  668. package/templates/base/tests/integration/vitest.config.ts +80 -0
  669. package/templates/base/tsconfig.app.json +18 -0
  670. package/templates/base/tsconfig.json +39 -0
  671. package/templates/base/tsconfig.node.json +16 -0
  672. package/templates/base/tsconfig.server.json +26 -0
  673. package/templates/base/tsconfig.tsbuildinfo +1 -0
  674. package/templates/base/vite.config.ts +46 -0
  675. package/templates/base/vitest.config.browser.ts +47 -0
  676. package/templates/base/vitest.config.frontend.ts +47 -0
  677. package/templates/base/vitest.config.ts +82 -0
  678. package/templates/base/vitest.workspace.ts +22 -0
  679. package/templates/modules/audit-logs/.gitkeep +0 -0
  680. package/templates/modules/billing/.gitkeep +0 -0
  681. package/templates/modules/invitations/.gitkeep +0 -0
  682. package/templates/modules/storage/.gitkeep +0 -0
  683. package/templates/modules/webhooks/.gitkeep +0 -0
  684. package/templates/providers/auth-email/.gitkeep +0 -0
  685. package/templates/providers/auth-github/.gitkeep +0 -0
  686. package/templates/providers/auth-google/.gitkeep +0 -0
  687. package/templates/providers/email-resend/.gitkeep +0 -0
  688. package/templates/providers/email-sendgrid/.gitkeep +0 -0
@@ -0,0 +1,879 @@
1
+ <project_specification>
2
+ <project_name>Hono Multi-Tenant SaaS Boilerplate</project_name>
3
+ <version>1.0.0</version>
4
+ <last_updated>2026-01-03</last_updated>
5
+
6
+ <overview>
7
+ Canonical high-level overview for the architecture docs in docs/architecture/.
8
+ Production-ready multi-tenant SaaS boilerplate built with Hono.js on Cloudflare Workers and React.
9
+ Provides a complete foundation for B2B SaaS with team workspaces, RBAC, invitations,
10
+ audit logging, and Google OAuth authentication.
11
+
12
+ The system uses D1 (SQLite) for relational data, KV for sessions, and R2 for object storage.
13
+ Users can belong to multiple accounts (workspaces) with distinct roles and permissions.
14
+ All state changes are logged for compliance and debugging.
15
+ </overview>
16
+
17
+ <goals>
18
+ <primary>
19
+ - Provide a production-ready starting point for SaaS applications
20
+ - Enable rapid development with pre-built auth, multi-tenancy, and RBAC
21
+ - Leverage edge computing for global low-latency performance
22
+ - Maintain strong security practices and audit compliance
23
+ </primary>
24
+ <secondary>
25
+ - Demonstrate best practices for Hono.js + Cloudflare Workers
26
+ - Provide comprehensive testing patterns (unit, integration, E2E)
27
+ - Enable easy customization and extension
28
+ </secondary>
29
+ </goals>
30
+
31
+ <technology_stack>
32
+ <runtime>
33
+ <platform>Cloudflare Workers</platform>
34
+ <database>D1 (SQLite on edge)</database>
35
+ <sessions>KV Namespace</sessions>
36
+ <storage>R2 Object Storage</storage>
37
+ <description>
38
+ Serverless edge runtime with ~50ms cold start, global distribution,
39
+ and integrated storage services. All infrastructure managed via Wrangler CLI.
40
+ </description>
41
+ </runtime>
42
+
43
+ <backend>
44
+ <framework>Hono.js 4.6</framework>
45
+ <orm>Drizzle ORM</orm>
46
+ <validation>Zod</validation>
47
+ <documentation>OpenAPI 3.0 / Swagger UI</documentation>
48
+ <description>
49
+ Type-safe API development with automatic schema generation.
50
+ Drizzle provides compile-time SQL safety with SQLite dialect.
51
+ OpenAPI spec and TypeScript types can be generated locally (api:spec, api:types).
52
+ </description>
53
+ </backend>
54
+
55
+ <frontend>
56
+ <framework>React 19</framework>
57
+ <routing>TanStack Router (file-based)</routing>
58
+ <state>TanStack Query</state>
59
+ <styling>Tailwind CSS 4.0</styling>
60
+ <components>shadcn/ui pattern</components>
61
+ <forms>React Hook Form + Zod</forms>
62
+ <notifications>Sonner (toast)</notifications>
63
+ <description>
64
+ Modern React with file-based routing, optimistic updates,
65
+ and a consistent design system following shadcn/ui patterns.
66
+ </description>
67
+ </frontend>
68
+
69
+ <testing>
70
+ <unit>Vitest</unit>
71
+ <integration>Vitest + Miniflare</integration>
72
+ <e2e>Playwright</e2e>
73
+ <coverage>95% server, 90% client</coverage>
74
+ <description>
75
+ Comprehensive testing strategy with isolated integration tests
76
+ using Miniflare for Cloudflare Workers simulation.
77
+ </description>
78
+ </testing>
79
+
80
+ <authentication>
81
+ <primary>Google OAuth 2.0 with PKCE</primary>
82
+ <sessions>Cloudflare KV (session-based cookies)</sessions>
83
+ <tokens>JWT access tokens (legacy support; sessions preferred)</tokens>
84
+ <description>
85
+ Session-based authentication stored in KV for persistence.
86
+ PKCE flow provides security for browser-based OAuth.
87
+ </description>
88
+ </authentication>
89
+ </technology_stack>
90
+
91
+ <architecture>
92
+ <multi_tenancy>
93
+ <model>Users belong to multiple Accounts (workspaces)</model>
94
+ <relationship>Many-to-many via user_accounts junction table</relationship>
95
+ <isolation>All queries scoped by accountId in context</isolation>
96
+ <roles>
97
+ - ADMIN: Full account management, user administration
98
+ - MANAGER: Team management, invitations
99
+ - EDITOR: Content creation and modification
100
+ - AUTHOR: Limited content creation
101
+ - VIEWER: Read-only access
102
+ - BILLING: Financial operations (non-hierarchical)
103
+ - ANALYTICS: Reporting access (non-hierarchical)
104
+ </roles>
105
+ </multi_tenancy>
106
+
107
+ <request_flow>
108
+ 1. Request arrives at Cloudflare Workers edge
109
+ 2. requestContext middleware attaches transactionId, IP, userAgent
110
+ 3. sessionAuth middleware validates session cookie from KV
111
+ 4. accountMiddleware extracts accountId from query/header
112
+ 5. Route handler executes business logic via services
113
+ 6. auditedDb functions log state changes automatically
114
+ 7. Response returned with proper error handling
115
+ </request_flow>
116
+
117
+ <data_flow>
118
+ Frontend (React)
119
+ → TanStack Query
120
+ → Fetch API
121
+ → Hono Routes
122
+ → Services
123
+ → Drizzle ORM
124
+ → D1 Database
125
+ </data_flow>
126
+ </architecture>
127
+
128
+ <database_schema>
129
+ <tables>
130
+ <users>
131
+ <description>Core user entity, one per person</description>
132
+ <columns>
133
+ - id: UUID (PK)
134
+ - googleId: string (unique, OAuth identifier)
135
+ - email: string (from OAuth provider)
136
+ - name: string (display name)
137
+ - avatarUrl: string | null (profile picture URL)
138
+ - status: enum ['active', 'inactive']
139
+ - providerIds: JSON string[] (future multi-provider support)
140
+ - isSuperAdmin: boolean (system-wide admin flag)
141
+ - createdAt, updatedAt, deletedAt: timestamps
142
+ - createdById, updatedById, deletedById: FK to users
143
+ </columns>
144
+ <indexes>
145
+ - UNIQUE on googleId
146
+ </indexes>
147
+ </users>
148
+
149
+ <accounts>
150
+ <description>Tenant/workspace entity</description>
151
+ <columns>
152
+ - id: UUID (PK)
153
+ - name: string (workspace name)
154
+ - description: string | null
155
+ - domain: string | null (unique, custom domain)
156
+ - createdAt, updatedAt, deletedAt: timestamps
157
+ </columns>
158
+ <indexes>
159
+ - UNIQUE on domain (where not null)
160
+ </indexes>
161
+ </accounts>
162
+
163
+ <user_accounts>
164
+ <description>Junction table for user-account membership</description>
165
+ <columns>
166
+ - userId: UUID (PK, FK to users, CASCADE)
167
+ - accountId: UUID (PK, FK to accounts, CASCADE)
168
+ - role: enum ['ADMIN', 'MANAGER', 'EDITOR', 'AUTHOR', 'VIEWER', 'BILLING', 'ANALYTICS']
169
+ </columns>
170
+ <constraints>
171
+ - PRIMARY KEY (userId, accountId)
172
+ - ON DELETE CASCADE for both FKs
173
+ </constraints>
174
+ </user_accounts>
175
+
176
+ <invitations>
177
+ <description>Pending team invitations</description>
178
+ <columns>
179
+ - id: UUID (PK)
180
+ - accountId: UUID (FK to accounts)
181
+ - email: string (invitee email)
182
+ - role: enum (same as user_accounts)
183
+ - token: string (unique, 64 chars, valid 7 days)
184
+ - invitedById: UUID (FK to users)
185
+ - expiresAt: timestamp
186
+ - acceptedAt: timestamp | null
187
+ - createdAt: timestamp
188
+ </columns>
189
+ <indexes>
190
+ - UNIQUE on token
191
+ - UNIQUE on (accountId, email)
192
+ </indexes>
193
+ </invitations>
194
+
195
+ <audit_logs>
196
+ <description>Complete audit trail for compliance</description>
197
+ <columns>
198
+ - id: UUID (PK)
199
+ - transactionId: string (groups related operations)
200
+ - accountId: UUID | null (FK to accounts)
201
+ - userId: UUID | null (FK to users, who performed)
202
+ - entity: string (e.g., 'User', 'Account', 'Auth')
203
+ - entityId: string (ID of affected entity)
204
+ - action: enum ['INSERT', 'UPDATE', 'DELETE', 'LOGIN', 'LOGOUT', 'SIGNUP', 'TOKEN_REFRESH', 'LOGIN_FAILED']
205
+ - changes: JSON | null (before/after state)
206
+ - ipAddress: string | null
207
+ - userAgent: string | null
208
+ - timestamp: timestamp
209
+ </columns>
210
+ <indexes>
211
+ - INDEX on (accountId, timestamp)
212
+ - INDEX on (entity, entityId)
213
+ - INDEX on action
214
+ </indexes>
215
+ </audit_logs>
216
+
217
+ <refresh_tokens>
218
+ <description>Token storage for session refresh (legacy)</description>
219
+ <columns>
220
+ - id: UUID (PK)
221
+ - userId: UUID (FK to users, CASCADE)
222
+ - tokenHash: string (SHA-256 hash, never plaintext)
223
+ - expiresAt: unix epoch (integer)
224
+ - createdAt: unix epoch (integer)
225
+ - revokedAt: unix epoch (integer) | null
226
+ </columns>
227
+ </refresh_tokens>
228
+ </tables>
229
+
230
+ <relationships>
231
+ users ─────┬───→ user_accounts ←───┬───── accounts
232
+ │ │
233
+ ├───→ refresh_tokens ├───→ invitations
234
+ │ │
235
+ ├───→ invitations (inviter)
236
+ │ │
237
+ └───→ audit_logs ←───────┘
238
+ </relationships>
239
+ </database_schema>
240
+
241
+ <api_endpoints>
242
+ <authentication prefix="/auth">
243
+ <endpoint method="GET" path="/login">
244
+ <description>Initiate Google OAuth flow with PKCE</description>
245
+ <query>redirect: string (optional, post-login redirect)</query>
246
+ <response>302 Redirect to Google</response>
247
+ <auth>None</auth>
248
+ </endpoint>
249
+
250
+ <endpoint method="GET" path="/callback">
251
+ <description>Handle Google OAuth callback</description>
252
+ <query>code: string, state: string</query>
253
+ <response>302 Redirect to app with session cookie</response>
254
+ <auth>None (creates session)</auth>
255
+ </endpoint>
256
+
257
+ <endpoint method="POST" path="/logout">
258
+ <description>Destroy session, clear cookies</description>
259
+ <response>200 { message: "Logged out successfully" }</response>
260
+ <auth>Session required</auth>
261
+ <audit>LOGOUT event logged</audit>
262
+ </endpoint>
263
+
264
+ <endpoint method="GET" path="/me">
265
+ <description>Get current authenticated user</description>
266
+ <response>200 { user: { id, email, name, avatarUrl, isSuperAdmin } }</response>
267
+ <auth>Session required</auth>
268
+ </endpoint>
269
+
270
+ <endpoint method="GET" path="/invite/:token">
271
+ <description>Accept invitation, store token, redirect to login</description>
272
+ <params>token: string (invitation token)</params>
273
+ <response>302 Redirect to /auth/login</response>
274
+ <auth>None</auth>
275
+ </endpoint>
276
+ </authentication>
277
+
278
+ <users prefix="/api/users">
279
+ <endpoint method="GET" path="/">
280
+ <description>List users (paginated, searchable)</description>
281
+ <query>page, limit, query (search email/name)</query>
282
+ <response>200 { data: User[], meta: { total, page, pages, hasMore } }</response>
283
+ <auth>Session + Account member</auth>
284
+ </endpoint>
285
+
286
+ <endpoint method="GET" path="/:id">
287
+ <description>Get user by ID</description>
288
+ <response>200 { user: User }</response>
289
+ <auth>Session + Account member</auth>
290
+ </endpoint>
291
+
292
+ <endpoint method="PATCH" path="/:id">
293
+ <description>Update user (name, status)</description>
294
+ <body>{ name?: string, status?: 'active' | 'inactive' }</body>
295
+ <response>200 { user: User }</response>
296
+ <auth>Session + ADMIN role</auth>
297
+ <audit>UPDATE event logged</audit>
298
+ </endpoint>
299
+
300
+ <endpoint method="DELETE" path="/:id">
301
+ <description>Soft delete user</description>
302
+ <response>204 No Content</response>
303
+ <auth>Session + ADMIN role</auth>
304
+ <audit>DELETE event logged</audit>
305
+ </endpoint>
306
+
307
+ <endpoint method="POST" path="/:id/restore">
308
+ <description>Restore soft-deleted user</description>
309
+ <response>200 { user: User }</response>
310
+ <auth>Session + Super Admin</auth>
311
+ <audit>UPDATE event logged</audit>
312
+ </endpoint>
313
+
314
+ <endpoint method="POST" path="/accounts">
315
+ <description>Bulk assign users to accounts</description>
316
+ <body>{ items: [{ userId, accountId, role }] }</body>
317
+ <response>200 { count: number }</response>
318
+ <auth>Session + MANAGER role</auth>
319
+ </endpoint>
320
+
321
+ <endpoint method="DELETE" path="/accounts">
322
+ <description>Bulk remove users from accounts</description>
323
+ <body>{ items: [{ userId, accountId }] }</body>
324
+ <response>200 { count: number }</response>
325
+ <auth>Session + MANAGER role</auth>
326
+ </endpoint>
327
+ </users>
328
+
329
+ <accounts prefix="/api/accounts">
330
+ <endpoint method="GET" path="/">
331
+ <description>List user's accounts</description>
332
+ <query>page, limit</query>
333
+ <response>200 { data: Account[], meta }</response>
334
+ <auth>Session</auth>
335
+ </endpoint>
336
+
337
+ <endpoint method="GET" path="/:id">
338
+ <description>Get account by ID</description>
339
+ <response>200 { account: Account }</response>
340
+ <auth>Session + Account member</auth>
341
+ </endpoint>
342
+
343
+ <endpoint method="POST" path="/">
344
+ <description>Create new account</description>
345
+ <body>{ name: string, description?: string }</body>
346
+ <response>201 { account: Account }</response>
347
+ <auth>Session + Super Admin</auth>
348
+ <audit>INSERT event logged</audit>
349
+ </endpoint>
350
+
351
+ <endpoint method="PATCH" path="/:id">
352
+ <description>Update account</description>
353
+ <body>{ name?: string, description?: string }</body>
354
+ <response>200 { account: Account }</response>
355
+ <auth>Session + Account ADMIN</auth>
356
+ <audit>UPDATE event logged</audit>
357
+ </endpoint>
358
+
359
+ <endpoint method="DELETE" path="/:id">
360
+ <description>Soft delete account</description>
361
+ <response>204 No Content</response>
362
+ <auth>Session + Super Admin</auth>
363
+ <audit>DELETE event logged</audit>
364
+ </endpoint>
365
+
366
+ <endpoint method="POST" path="/:id/restore">
367
+ <description>Restore soft-deleted account</description>
368
+ <response>200 { account: Account }</response>
369
+ <auth>Session + Super Admin</auth>
370
+ <audit>UPDATE event logged</audit>
371
+ </endpoint>
372
+ </accounts>
373
+
374
+ <invitations prefix="/api/invitations">
375
+ <endpoint method="POST" path="/">
376
+ <description>Create invitation or link existing user</description>
377
+ <body>{ email: string, role: Role }</body>
378
+ <response>201 { invitation } or 200 { linked: true }</response>
379
+ <auth>Session + Account member</auth>
380
+ <notes>
381
+ - If user exists: links immediately to account
382
+ - If user not found: sends email with invitation link
383
+ - Token valid for 7 days
384
+ </notes>
385
+ <audit>INSERT event logged</audit>
386
+ </endpoint>
387
+
388
+ <endpoint method="GET" path="/">
389
+ <description>List pending invitations for current account</description>
390
+ <response>200 { data: Invitation[] }</response>
391
+ <auth>Session + Account member</auth>
392
+ </endpoint>
393
+
394
+ <endpoint method="DELETE" path="/:id">
395
+ <description>Revoke pending invitation</description>
396
+ <response>204 No Content</response>
397
+ <auth>Session + MANAGER role</auth>
398
+ <audit>DELETE event logged</audit>
399
+ </endpoint>
400
+ </invitations>
401
+
402
+ <audits prefix="/api/audits">
403
+ <endpoint method="GET" path="/">
404
+ <description>Query audit logs with filters</description>
405
+ <query>
406
+ - page, limit (pagination)
407
+ - entity (filter by entity type)
408
+ - entityId (filter by entity ID)
409
+ - action (filter by action type)
410
+ </query>
411
+ <response>200 { data: AuditLog[], meta }</response>
412
+ <auth>Session + ADMIN or ANALYTICS role</auth>
413
+ <notes>Super admin sees all accounts, others see only their account</notes>
414
+ </endpoint>
415
+ </audits>
416
+
417
+ <storage prefix="/api/storage">
418
+ <endpoint method="POST" path="/upload-url">
419
+ <description>Generate upload URL for internal API upload endpoint</description>
420
+ <body>{ filename: string, contentType: string }</body>
421
+ <response>200 { url: string, name: string, publicUrl: string }</response>
422
+ <auth>Session</auth>
423
+ <notes>URL points to /api/storage/upload/:key; not a direct R2 presigned URL</notes>
424
+ </endpoint>
425
+
426
+ <endpoint method="PUT" path="/upload/:key">
427
+ <description>Upload file via API and store in R2</description>
428
+ <body>Binary file data</body>
429
+ <response>200 { success: true, key: string, publicUrl: string }</response>
430
+ <auth>Session</auth>
431
+ </endpoint>
432
+
433
+ <endpoint method="DELETE" path="/:key">
434
+ <description>Delete file from R2</description>
435
+ <response>204 No Content</response>
436
+ <auth>Session</auth>
437
+ </endpoint>
438
+ </storage>
439
+
440
+ <health prefix="/health">
441
+ <endpoint method="GET" path="/">
442
+ <description>Health check endpoint</description>
443
+ <response>200 { status: "ok", timestamp, environment }</response>
444
+ <auth>None</auth>
445
+ </endpoint>
446
+ </health>
447
+
448
+ <documentation>
449
+ <endpoint method="GET" path="/api/doc">OpenAPI JSON schema</endpoint>
450
+ <endpoint method="GET" path="/api/swagger">Swagger UI</endpoint>
451
+ </documentation>
452
+ </api_endpoints>
453
+
454
+ <frontend_pages>
455
+ <public_routes>
456
+ <route path="/">
457
+ <name>Landing Page</name>
458
+ <description>Marketing homepage with hero section and feature highlights</description>
459
+ <components>Hero, Features, CTA</components>
460
+ </route>
461
+
462
+ <route path="/login">
463
+ <name>Login Page</name>
464
+ <description>Google OAuth login button, redirects to /auth/login</description>
465
+ <components>LoginCard, GoogleButton</components>
466
+ </route>
467
+
468
+ <route path="/invite/:token">
469
+ <name>Invitation Page</name>
470
+ <description>Accept invitation, validates token, redirects to login</description>
471
+ <components>InvitationCard, AcceptButton</components>
472
+ </route>
473
+ </public_routes>
474
+
475
+ <authenticated_routes layout="_authenticated">
476
+ <route path="/dashboard">
477
+ <name>Dashboard</name>
478
+ <description>Main workspace overview with stats and quick actions</description>
479
+ <sections>
480
+ - Welcome message with user's first name
481
+ - Stats cards (users, accounts, API requests, uptime)
482
+ - Quick action cards (invite team, database, security)
483
+ - Recent activity feed (placeholder)
484
+ </sections>
485
+ </route>
486
+
487
+ <route path="/team">
488
+ <name>Team Management</name>
489
+ <description>Manage team members and invitations</description>
490
+ <sections>
491
+ - Active members list with roles
492
+ - Search/filter members by name/email
493
+ - Invite member dialog (email + role selector)
494
+ - Pending invitations with expiry countdown
495
+ - Resend/revoke invitation buttons
496
+ </sections>
497
+ <dialogs>InviteMemberDialog</dialogs>
498
+ </route>
499
+
500
+ <route path="/settings">
501
+ <name>User Settings</name>
502
+ <description>Personal profile and preferences</description>
503
+ <sections>
504
+ - Profile card (avatar, name, email)
505
+ - Edit profile form
506
+ - Connected accounts (Google, future: GitHub)
507
+ - Notification preferences (toggles)
508
+ - Account deletion
509
+ </sections>
510
+ <dialogs>DeleteAccountDialog</dialogs>
511
+ </route>
512
+
513
+ <route path="/account">
514
+ <name>Account Security</name>
515
+ <description>Security settings and session management</description>
516
+ <sections>
517
+ - Connected OAuth accounts
518
+ - Two-factor authentication (future)
519
+ - Password management (OAuth-only note)
520
+ - Active sessions list with device/location
521
+ - API keys management (future)
522
+ - Danger zone (export data, delete account)
523
+ </sections>
524
+ <dialogs>DeleteAccountDialog</dialogs>
525
+ </route>
526
+
527
+ <route path="/integrations">
528
+ <name>Integrations</name>
529
+ <description>Third-party connections and webhooks</description>
530
+ <sections>
531
+ - Integration grid (Slack, Discord, Stripe, GitHub, Linear, Zapier)
532
+ - Filter by category
533
+ - Search integrations
534
+ - Webhooks configuration
535
+ - Create webhook dialog
536
+ </sections>
537
+ <dialogs>CreateWebhookDialog</dialogs>
538
+ </route>
539
+ </authenticated_routes>
540
+ </frontend_pages>
541
+
542
+ <ui_components>
543
+ <layout>
544
+ <sidebar>
545
+ - Navigation links (Dashboard, Team, Settings, Account, Integrations)
546
+ - User profile card with avatar and name
547
+ - Logout button
548
+ - Collapsible on mobile
549
+ </sidebar>
550
+ <main_content>
551
+ - Container with max-width constraint
552
+ - Responsive padding
553
+ - Page header with title and description
554
+ </main_content>
555
+ </layout>
556
+
557
+ <primitives>
558
+ <button variants="default, secondary, outline, destructive, ghost, link" />
559
+ <input types="text, email, password, search" />
560
+ <badge variants="default, secondary, outline, destructive" />
561
+ <avatar fallback="initials from name" />
562
+ <card sections="header, content, footer" />
563
+ <dialog modal="true, with overlay" />
564
+ <tabs orientation="horizontal" />
565
+ <separator orientation="horizontal, vertical" />
566
+ <skeleton loading_state="true" />
567
+ </primitives>
568
+
569
+ <forms>
570
+ <pattern>React Hook Form + Zod validation</pattern>
571
+ <components>Form, FormField, FormItem, FormLabel, FormControl, FormMessage</components>
572
+ <error_handling>Inline validation messages</error_handling>
573
+ </forms>
574
+
575
+ <feedback>
576
+ <toast provider="Sonner">
577
+ - Success (green)
578
+ - Error (red)
579
+ - Info (blue)
580
+ - Warning (yellow)
581
+ </toast>
582
+ <error_fallback>
583
+ - Error message display
584
+ - Retry button
585
+ - Go back button
586
+ - Go home button
587
+ </error_fallback>
588
+ </feedback>
589
+ </ui_components>
590
+
591
+ <design_system>
592
+ <colors>
593
+ <light_mode>
594
+ - Background: white (#ffffff)
595
+ - Foreground: near-black (#0a0a0a)
596
+ - Card: white (#ffffff)
597
+ - Border: light gray (#e5e5e5)
598
+ - Primary: brand color
599
+ - Muted: gray (#f5f5f5)
600
+ - Destructive: red (#dc2626)
601
+ </light_mode>
602
+ <dark_mode>
603
+ - Background: near-black (#0a0a0a)
604
+ - Foreground: off-white (#fafafa)
605
+ - Card: dark gray (#0a0a0a)
606
+ - Border: dark gray (#262626)
607
+ - Primary: brand color (adjusted)
608
+ - Muted: dark gray (#262626)
609
+ - Destructive: red (#dc2626)
610
+ </dark_mode>
611
+ </colors>
612
+
613
+ <typography>
614
+ <font_family>Inter, system-ui, sans-serif</font_family>
615
+ <font_mono>JetBrains Mono, Consolas, monospace</font_mono>
616
+ <scale>
617
+ - text-xs: 0.75rem
618
+ - text-sm: 0.875rem
619
+ - text-base: 1rem
620
+ - text-lg: 1.125rem
621
+ - text-xl: 1.25rem
622
+ - text-2xl: 1.5rem
623
+ - text-3xl: 1.875rem
624
+ </scale>
625
+ </typography>
626
+
627
+ <spacing>
628
+ <scale>4px base (0.25rem)</scale>
629
+ <common>
630
+ - p-2: 8px
631
+ - p-4: 16px
632
+ - p-6: 24px
633
+ - p-8: 32px
634
+ - gap-2, gap-4, gap-6
635
+ </common>
636
+ </spacing>
637
+
638
+ <borders>
639
+ <radius>
640
+ - rounded-sm: 2px
641
+ - rounded: 4px
642
+ - rounded-md: 6px
643
+ - rounded-lg: 8px
644
+ - rounded-xl: 12px
645
+ - rounded-full: 9999px
646
+ </radius>
647
+ </borders>
648
+
649
+ <shadows>
650
+ <elevation>
651
+ - shadow-sm: subtle depth
652
+ - shadow: default cards
653
+ - shadow-md: elevated elements
654
+ - shadow-lg: modals, dropdowns
655
+ </elevation>
656
+ </shadows>
657
+
658
+ <animations>
659
+ <transitions>150ms ease-in-out default</transitions>
660
+ <patterns>
661
+ - Fade in for page transitions
662
+ - Slide in for sidebars/panels
663
+ - Scale for modals
664
+ - Skeleton pulse for loading
665
+ </patterns>
666
+ </animations>
667
+ </design_system>
668
+
669
+ <security>
670
+ <authentication>
671
+ - OAuth 2.0 with PKCE (no client secret in browser)
672
+ - Session cookies: httpOnly, secure, sameSite=Lax
673
+ - Session stored in KV with expiration
674
+ - Refresh tokens hashed before storage (SHA-256)
675
+ </authentication>
676
+
677
+ <authorization>
678
+ - Role-based access control (RBAC)
679
+ - Hierarchical roles with level comparison
680
+ - Account-scoped permissions
681
+ - Super admin bypass for system operations
682
+ </authorization>
683
+
684
+ <data_protection>
685
+ - Soft deletes preserve data integrity
686
+ - Audit logging for all state changes
687
+ - Request context (IP, User-Agent) captured
688
+ - Transaction IDs for operation correlation
689
+ </data_protection>
690
+
691
+ <api_security>
692
+ - Input validation with Zod schemas
693
+ - CORS configuration per environment
694
+ - Error messages sanitized (no stack traces in prod)
695
+ - Rate limiting (Cloudflare default)
696
+ </api_security>
697
+ </security>
698
+
699
+ <implementation_status>
700
+ <completed>
701
+ - Google OAuth login with PKCE flow
702
+ - Session management (KV + cookies)
703
+ - Multi-tenant user/account system
704
+ - User-account relationships with roles
705
+ - Invitation system with email sending
706
+ - Audit logging (all CRUD + auth events)
707
+ - Soft delete with restore functionality
708
+ - File storage (R2) with presigned URLs
709
+ - OpenAPI/Swagger documentation
710
+ - Error handling + validation
711
+ - Role-based access control
712
+ - Pagination + search
713
+ - Super admin pre-registration
714
+ - Logout with redirect
715
+ - 95% test coverage (server)
716
+ - 90% test coverage (client)
717
+ </completed>
718
+
719
+ <partial>
720
+ - Webhooks (schema exists, storage not implemented)
721
+ - Integrations page (UI mockups only)
722
+ - Dashboard analytics (placeholder data)
723
+ </partial>
724
+
725
+ <planned>
726
+ - Two-factor authentication (TOTP)
727
+ - GitHub OAuth integration
728
+ - API keys management
729
+ - Payment/billing integration (Stripe)
730
+ - Email templates customization
731
+ - Real-time notifications (WebSocket)
732
+ - Activity feed with actual data
733
+ - Export data functionality
734
+ - Account switching UI
735
+ </planned>
736
+ </implementation_status>
737
+
738
+ <environment_variables>
739
+ <required>
740
+ GOOGLE_CLIENT_ID # Google OAuth client ID
741
+ GOOGLE_CLIENT_SECRET # Google OAuth client secret
742
+ GOOGLE_REDIRECT_URI # OAuth callback URL
743
+ APP_URL # Application base URL
744
+ JWT_SECRET # Session signing key (min 32 chars)
745
+ SENDGRID_API_KEY # SendGrid API key for emails
746
+ SENDGRID_FROM_EMAIL # Sender email address
747
+ </required>
748
+
749
+ <optional>
750
+ ENVIRONMENT # production | staging | development
751
+ SUPER_ADMIN_EMAILS # Comma-separated admin emails
752
+ CORS_ORIGINS # Comma-separated allowed origins
753
+ R2_PUBLIC_URL # R2 bucket public URL
754
+ JWT_EXPIRY_MINUTES # Access token expiry (default: 15)
755
+ REFRESH_TOKEN_EXPIRY_DAYS # Refresh token expiry (default: 30)
756
+ </optional>
757
+
758
+ <cloudflare_bindings>
759
+ DB # D1 Database binding
760
+ SESSIONS # KV Namespace for sessions
761
+ R2_BUCKET # R2 Bucket for file storage
762
+ ASSETS # Static assets binding
763
+ </cloudflare_bindings>
764
+ </environment_variables>
765
+
766
+ <development>
767
+ <commands>
768
+ npm run dev # Start dev server (Vite + Wrangler)
769
+ npm run build # Build for production
770
+ npm run deploy # Deploy to Cloudflare Workers
771
+
772
+ npm run db:migrate:local # Apply migrations locally
773
+ npm run db:migrate:remote # Apply migrations to production
774
+ npm run db:seed # Seed test data
775
+
776
+ npm run test:unit:server # Backend unit tests
777
+ npm run test:unit:client # Frontend tests
778
+ npm run test:integration # Integration tests
779
+ npm run test:e2e # Playwright E2E tests
780
+ npm run test:e2e:ui # Playwright interactive UI
781
+
782
+ npm run lint # ESLint
783
+ npm run cf-typegen # Generate Cloudflare types
784
+ </commands>
785
+
786
+ <path_aliases>
787
+ @/ → src/client/
788
+ @shared/ → src/shared/
789
+ @server/ → src/server/
790
+ </path_aliases>
791
+
792
+ <workflow>
793
+ 1. Make changes
794
+ 2. Run unit tests for affected area
795
+ 3. Run lint to check code style
796
+ 4. Run E2E tests for critical paths
797
+ 5. Verify build succeeds
798
+ 6. Deploy with `npm run deploy`
799
+ </workflow>
800
+ </development>
801
+
802
+ <file_structure>
803
+ src/
804
+ ├── server/ # Backend (Hono.js)
805
+ │ ├── routes/ # API endpoints
806
+ │ │ ├── auth/ # OAuth, logout, me
807
+ │ │ ├── users/ # User CRUD
808
+ │ │ ├── accounts/ # Account CRUD
809
+ │ │ ├── invitations/ # Team invites
810
+ │ │ ├── audits/ # Audit log queries
811
+ │ │ ├── storage/ # R2 file operations
812
+ │ │ └── health/ # Health check
813
+ │ ├── services/ # Business logic
814
+ │ ├── middleware/ # Auth, CORS, logging
815
+ │ ├── db/
816
+ │ │ ├── schema/ # Drizzle table definitions
817
+ │ │ └── migrations/ # SQL migrations
818
+ │ ├── lib/ # Utilities
819
+ │ └── auth/ # RBAC guards
820
+
821
+ ├── client/ # Frontend (React)
822
+ │ ├── routes/ # TanStack file-based routing
823
+ │ │ ├── _authenticated/ # Protected pages
824
+ │ │ └── *.tsx # Public pages
825
+ │ ├── components/
826
+ │ │ └── ui/ # Reusable UI components
827
+ │ └── hooks/ # React hooks
828
+
829
+ ├── shared/ # Shared between client/server
830
+ │ ├── schemas/ # Zod validation schemas
831
+ │ └── types/ # TypeScript types
832
+
833
+ └── e2e/ # Playwright E2E tests
834
+ </file_structure>
835
+
836
+ <key_files>
837
+ src/server/index.ts # Hono app entry
838
+ src/server/routes/index.ts # API router
839
+ src/server/db/schema/ # Database schema
840
+ src/client/routes/__root.tsx # React app root
841
+ src/client/routes/_authenticated.tsx # Auth layout
842
+ wrangler.json # Cloudflare config
843
+ drizzle.config.ts # Drizzle ORM config
844
+ playwright.config.ts # E2E test config
845
+ vitest.config.ts # Unit test config
846
+ </key_files>
847
+
848
+ <success_criteria>
849
+ <functionality>
850
+ - OAuth authentication works smoothly
851
+ - Multi-tenant isolation is enforced
852
+ - Role-based access control is accurate
853
+ - Invitation system sends emails correctly
854
+ - Audit logging captures all events
855
+ - File uploads to R2 work reliably
856
+ </functionality>
857
+
858
+ <performance>
859
+ - Page loads under 500ms (edge deployment)
860
+ - API responses under 100ms
861
+ - No blocking operations in critical path
862
+ - Efficient database queries with indexes
863
+ </performance>
864
+
865
+ <reliability>
866
+ - 95%+ test coverage on server
867
+ - 90%+ test coverage on client
868
+ - Error boundaries prevent crashes
869
+ - Graceful degradation for network issues
870
+ </reliability>
871
+
872
+ <security>
873
+ - No sensitive data in logs
874
+ - Proper CORS configuration
875
+ - Session security (httpOnly, secure)
876
+ - Input validation on all endpoints
877
+ </security>
878
+ </success_criteria>
879
+ </project_specification>