@etus/bhono-app 0.1.5 → 0.1.7

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 (300) hide show
  1. package/dist/index.js +0 -0
  2. package/package.json +7 -2
  3. package/templates/base/.claude/commands/check-skill-rules.md +112 -29
  4. package/templates/base/.claude/commands/linear/implement-issue.md +383 -55
  5. package/templates/base/.claude/commands/ship.md +77 -13
  6. package/templates/base/.claude/hooks/package-lock.json +0 -419
  7. package/templates/base/.claude/hooks/skill-activation-prompt.ts +185 -113
  8. package/templates/base/.claude/hooks/skill-tool-guard.sh +6 -0
  9. package/templates/base/.claude/hooks/skill-tool-guard.ts +198 -0
  10. package/templates/base/.claude/scripts/validate-skill-rules.sh +55 -32
  11. package/templates/base/.claude/settings.json +18 -11
  12. package/templates/base/.claude/skills/skill-rules.json +326 -173
  13. package/templates/base/.env.example +3 -0
  14. package/templates/base/CLAUDE.md +5 -5
  15. package/templates/base/README.md +40 -27
  16. package/templates/base/config/eslint.config.js +1 -0
  17. package/templates/base/config/wrangler.json +16 -17
  18. package/templates/base/docs/SETUP-GUIDE.md +566 -0
  19. package/templates/base/docs/app_spec.txt +13 -10
  20. package/templates/base/docs/architecture/README.md +162 -5
  21. package/templates/base/docs/architecture/api-catalog.md +575 -0
  22. package/templates/base/docs/architecture/c4-component.md +309 -0
  23. package/templates/base/docs/architecture/c4-container.md +183 -0
  24. package/templates/base/docs/architecture/c4-context.md +106 -0
  25. package/templates/base/docs/architecture/data-requirements.md +4 -3
  26. package/templates/base/docs/architecture/db-bootstrap.md +39 -0
  27. package/templates/base/docs/architecture/dependencies.md +327 -0
  28. package/templates/base/docs/architecture/drizzle-migration-plan.md +125 -0
  29. package/templates/base/docs/architecture/erd.md +1 -1
  30. package/templates/base/docs/architecture/sql-standards.md +100 -0
  31. package/templates/base/docs/architecture/tech-debt.md +184 -0
  32. package/templates/base/docs/testing.md +36 -29
  33. package/templates/base/package.json +26 -20
  34. package/templates/base/schema.sql +84 -0
  35. package/templates/base/scripts/capture-prod-session.ts +2 -2
  36. package/templates/base/scripts/init.sh +244 -59
  37. package/templates/base/scripts/sync-template.sh +104 -0
  38. package/templates/base/src/client/hooks/use-auth.ts +5 -0
  39. package/templates/base/src/client/routes/_authenticated/dashboard.tsx +1 -1
  40. package/templates/base/src/client/routes/index.tsx +1 -1
  41. package/templates/base/src/server/db/client.ts +3 -5
  42. package/templates/base/src/server/db/records.ts +81 -0
  43. package/templates/base/src/server/db/seed.ts +3 -2
  44. package/templates/base/src/server/db/sql.ts +116 -0
  45. package/templates/base/src/server/index.ts +17 -2
  46. package/templates/base/src/server/lib/audit.ts +74 -26
  47. package/templates/base/src/server/lib/audited-db.ts +219 -109
  48. package/templates/base/src/server/lib/transaction.ts +10 -16
  49. package/templates/base/src/server/middleware/account.ts +9 -16
  50. package/templates/base/src/server/middleware/auth.ts +102 -38
  51. package/templates/base/src/server/middleware/rate-limit.ts +8 -6
  52. package/templates/base/src/server/routes/accounts/handlers.ts +18 -6
  53. package/templates/base/src/server/routes/audits/handlers.ts +3 -1
  54. package/templates/base/src/server/routes/auth/handlers.ts +15 -10
  55. package/templates/base/src/server/routes/auth/test-login.ts +99 -45
  56. package/templates/base/src/server/routes/health/handlers.ts +4 -4
  57. package/templates/base/src/server/routes/index.ts +9 -0
  58. package/templates/base/src/server/routes/invitations/handlers.ts +9 -6
  59. package/templates/base/src/server/routes/openapi.ts +1 -1
  60. package/templates/base/src/server/routes/users/handlers.ts +21 -14
  61. package/templates/base/src/server/services/accounts.ts +242 -217
  62. package/templates/base/src/server/services/audits.ts +114 -61
  63. package/templates/base/src/server/services/auth.ts +310 -180
  64. package/templates/base/src/server/services/invitations.ts +282 -222
  65. package/templates/base/src/server/services/users.ts +383 -293
  66. package/templates/base/src/server/types/index.ts +1 -2
  67. package/templates/base/src/shared/types/api.ts +66 -198
  68. package/templates/base/tests/e2e/auth.setup.ts +1 -1
  69. package/templates/base/{src/server/__tests__/fixtures.ts → tests/fixtures/server.ts} +3 -3
  70. package/templates/base/{src/client/__tests__/setup-browser.ts → tests/helpers/client-setup-browser.ts} +2 -2
  71. package/templates/base/{src/client/__tests__/setup.ts → tests/helpers/client-setup.ts} +1 -1
  72. package/templates/base/{src/client/__tests__/test-utils.tsx → tests/helpers/client-test-utils.tsx} +2 -2
  73. package/templates/base/{src/server/__tests__/setup.ts → tests/helpers/server.ts} +9 -9
  74. package/templates/base/tests/integration/accounts/crud.test.ts +2 -11
  75. package/templates/base/tests/integration/audits/list.test.ts +2 -11
  76. package/templates/base/tests/integration/auth/auth-service.test.ts +1 -10
  77. package/templates/base/tests/integration/auth/invitation-token.test.ts +2 -11
  78. package/templates/base/tests/integration/auth/logout.test.ts +2 -11
  79. package/templates/base/tests/integration/auth/oauth.test.ts +23 -42
  80. package/templates/base/tests/integration/auth/refresh-token.test.ts +1 -9
  81. package/templates/base/tests/integration/auth/session-expiry.test.ts +1 -9
  82. package/templates/base/tests/integration/auth/session.test.ts +2 -11
  83. package/templates/base/tests/integration/auth/super-admin.test.ts +1 -9
  84. package/templates/base/tests/integration/authorization/analytics-role.test.ts +2 -11
  85. package/templates/base/tests/integration/authorization/billing-role.test.ts +2 -11
  86. package/templates/base/tests/integration/authorization/guards-roles.test.ts +1 -9
  87. package/templates/base/tests/integration/authorization/multi-tenancy.test.ts +2 -11
  88. package/templates/base/tests/integration/authorization/roles.test.ts +2 -11
  89. package/templates/base/tests/integration/config/production-behavior.test.ts +2 -11
  90. package/templates/base/tests/integration/health/health.test.ts +25 -44
  91. package/templates/base/tests/integration/invitations/crud.test.ts +2 -11
  92. package/templates/base/tests/integration/invitations/email.test.ts +1 -9
  93. package/templates/base/tests/integration/middleware/auth.test.ts +3 -12
  94. package/templates/base/tests/integration/middleware/request-logger.test.ts +1 -9
  95. package/templates/base/tests/integration/performance/response-times.test.ts +1 -9
  96. package/templates/base/tests/integration/security/cookie-security.test.ts +2 -11
  97. package/templates/base/tests/integration/security/csrf-protection.test.ts +2 -11
  98. package/templates/base/tests/integration/security/log-sanitization.test.ts +1 -9
  99. package/templates/base/tests/integration/security/rate-limiting.test.ts +1 -9
  100. package/templates/base/tests/integration/security/sql-injection.test.ts +7 -18
  101. package/templates/base/tests/integration/security/xss-prevention.test.ts +2 -11
  102. package/templates/base/tests/integration/setup.ts +13 -90
  103. package/templates/base/tests/integration/smoke.test.ts +3 -2
  104. package/templates/base/tests/integration/storage/upload.test.ts +2 -11
  105. package/templates/base/tests/integration/storage/validation.test.ts +2 -11
  106. package/templates/base/tests/integration/users/crud.test.ts +2 -11
  107. package/templates/base/tests/integration/users/list.test.ts +2 -11
  108. package/templates/base/tests/integration/vitest.config.ts +2 -9
  109. package/templates/base/{src/server/__tests__ → tests}/mocks/db.ts +1 -1
  110. package/templates/base/{src/server/__tests__ → tests}/mocks/index.ts +1 -1
  111. package/templates/base/{src/server/__tests__ → tests}/mocks/kv.ts +1 -1
  112. package/templates/base/{src/server/__tests__ → tests}/mocks/r2.ts +1 -1
  113. package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/sidebar.test.tsx +1 -1
  114. package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/avatar.test.tsx +1 -1
  115. package/templates/base/{src/client/__tests__ → tests/unit/client/components/ui}/button.test.tsx +1 -1
  116. package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/card.test.tsx +1 -1
  117. package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/dialog.test.tsx +1 -1
  118. package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/input.test.tsx +1 -1
  119. package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/loading-skeleton.test.tsx +1 -1
  120. package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/skeleton.test.tsx +1 -1
  121. package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/sonner.test.tsx +1 -1
  122. package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/tabs.test.tsx +1 -1
  123. package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/account.test.tsx +1 -1
  124. package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/integrations.test.tsx +1 -1
  125. package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/settings.test.tsx +1 -1
  126. package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/team.test.tsx +1 -1
  127. package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/authenticated-layout.test.tsx +1 -1
  128. package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/dashboard.test.tsx +1 -1
  129. package/templates/base/{src/client/routes/__tests__ → tests/unit/client/routes}/invite.test.tsx +1 -1
  130. package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/login.test.tsx +1 -1
  131. package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/navigation.test.tsx +1 -1
  132. package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/root-layout.test.tsx +1 -1
  133. package/templates/base/{src/server/auth/__tests__ → tests/unit/server/auth}/guards.test.ts +2 -2
  134. package/templates/base/{src → tests/unit}/server/auth/permissions.test.ts +1 -1
  135. package/templates/base/{src → tests/unit}/server/auth/roles.test.ts +1 -1
  136. package/templates/base/tests/unit/server/db/sql.test.ts +68 -0
  137. package/templates/base/{src → tests/unit}/server/env.test.ts +1 -1
  138. package/templates/base/tests/unit/server/lib/audited-db.test.ts +78 -0
  139. package/templates/base/{src → tests/unit}/server/lib/email.test.ts +1 -1
  140. package/templates/base/{src → tests/unit}/server/lib/errors.test.ts +1 -1
  141. package/templates/base/{src → tests/unit}/server/lib/oauth.test.ts +1 -1
  142. package/templates/base/{src → tests/unit}/server/lib/pagination.test.ts +1 -1
  143. package/templates/base/{src → tests/unit}/server/lib/password.test.ts +1 -1
  144. package/templates/base/{src → tests/unit}/server/lib/providers.test.ts +1 -1
  145. package/templates/base/{src → tests/unit}/server/lib/r2-storage.test.ts +2 -2
  146. package/templates/base/{src → tests/unit}/server/lib/session.test.ts +2 -2
  147. package/templates/base/{src → tests/unit}/server/lib/tokens.test.ts +1 -1
  148. package/templates/base/{src → tests/unit}/server/lib/transaction.test.ts +5 -14
  149. package/templates/base/{src → tests/unit}/server/middleware/account.test.ts +16 -24
  150. package/templates/base/tests/unit/server/middleware/auth.test.ts +647 -0
  151. package/templates/base/{src → tests/unit}/server/middleware/cors.test.ts +1 -1
  152. package/templates/base/{src → tests/unit}/server/middleware/error-handler.test.ts +2 -2
  153. package/templates/base/{src → tests/unit}/server/middleware/rate-limit.test.ts +3 -2
  154. package/templates/base/{src → tests/unit}/server/middleware/request-context.test.ts +1 -1
  155. package/templates/base/{src → tests/unit}/server/middleware/request-logger.test.ts +1 -1
  156. package/templates/base/{src/server/__tests__/mocks/__tests__ → tests/unit/server/mocks}/db.test.ts +1 -1
  157. package/templates/base/{src/server/__tests__/mocks/__tests__ → tests/unit/server/mocks}/kv.test.ts +1 -1
  158. package/templates/base/{src/server/__tests__/mocks/__tests__ → tests/unit/server/mocks}/r2.test.ts +1 -1
  159. package/templates/base/{src/server/routes/accounts/__tests__ → tests/unit/server/routes/accounts}/handlers.test.ts +12 -12
  160. package/templates/base/{src/server/routes/audits/__tests__ → tests/unit/server/routes/audits}/handlers.test.ts +11 -11
  161. package/templates/base/{src/server/routes/auth/__tests__ → tests/unit/server/routes/auth}/handlers.test.ts +124 -13
  162. package/templates/base/{src/server/routes/health/__tests__ → tests/unit/server/routes/health}/handlers.test.ts +27 -23
  163. package/templates/base/{src/server/routes/invitations/__tests__ → tests/unit/server/routes/invitations}/handlers.test.ts +14 -17
  164. package/templates/base/{src/server/routes/storage/__tests__ → tests/unit/server/routes/storage}/handlers.test.ts +6 -6
  165. package/templates/base/{src/server/routes/users/__tests__ → tests/unit/server/routes/users}/handlers.test.ts +81 -17
  166. package/templates/base/tests/unit/server/services/accounts.test.ts +406 -0
  167. package/templates/base/tests/unit/server/services/audits.test.ts +360 -0
  168. package/templates/base/tests/unit/server/services/auth.test.ts +656 -0
  169. package/templates/base/tests/unit/server/services/invitations.test.ts +343 -0
  170. package/templates/base/tests/unit/server/services/users.test.ts +706 -0
  171. package/templates/base/{src/shared/schemas/__tests__ → tests/unit/shared}/schemas.test.ts +1 -1
  172. package/templates/base/tsconfig.json +2 -1
  173. package/templates/base/vite.config.ts +3 -1
  174. package/templates/base/vitest.config.browser.ts +3 -2
  175. package/templates/base/vitest.config.frontend.ts +3 -2
  176. package/templates/base/vitest.config.ts +7 -14
  177. package/templates/base/.claude/settings.local.json +0 -11
  178. package/templates/base/.github/workflows/test.yml +0 -127
  179. package/templates/base/auth-setup-error.png +0 -0
  180. package/templates/base/config/drizzle.config.ts +0 -10
  181. package/templates/base/pnpm-lock.yaml +0 -8175
  182. package/templates/base/src/server/db/schema/accounts.ts +0 -20
  183. package/templates/base/src/server/db/schema/audit-logs.ts +0 -26
  184. package/templates/base/src/server/db/schema/index.ts +0 -7
  185. package/templates/base/src/server/db/schema/invitations.ts +0 -30
  186. package/templates/base/src/server/db/schema/refresh-tokens.ts +0 -22
  187. package/templates/base/src/server/db/schema/user-accounts.ts +0 -25
  188. package/templates/base/src/server/db/schema/users.ts +0 -33
  189. package/templates/base/src/server/lib/audited-db.test.ts +0 -107
  190. package/templates/base/src/server/lib/schema-helpers.ts +0 -16
  191. package/templates/base/src/server/middleware/auth.test.ts +0 -345
  192. package/templates/base/src/server/services/__tests__/accounts.test.ts +0 -764
  193. package/templates/base/src/server/services/__tests__/audits.test.ts +0 -235
  194. package/templates/base/src/server/services/__tests__/auth.test.ts +0 -765
  195. package/templates/base/src/server/services/__tests__/invitations.test.ts +0 -704
  196. package/templates/base/src/server/services/__tests__/users.test.ts +0 -755
  197. package/templates/base/tests/e2e/_auth/.gitkeep +0 -0
  198. package/templates/base/tests/integration/lib/schema-helpers.test.ts +0 -129
  199. package/templates/base/tsconfig.tsbuildinfo +0 -1
  200. /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-can-be-collapsed-by-default-1.png +0 -0
  201. /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-expands-when-collapsed-and-expand-button-is-clicked-1.png +0 -0
  202. /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-handles-logout-button-click-1.png +0 -0
  203. /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-handles-navigation-clicks-1.png +0 -0
  204. /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-hides-navigation-labels-when-collapsed-1.png +0 -0
  205. /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-highlights-active-route-1.png +0 -0
  206. /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-renders-sidebar-navigation-items-1.png +0 -0
  207. /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-shows-keyboard-shortcut-hint-when-expanded-1.png +0 -0
  208. /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-shows-user-info-when-authenticated-1.png +0 -0
  209. /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-shows-user-initials-in-avatar-fallback-1.png +0 -0
  210. /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/error-boundary.test.tsx +0 -0
  211. /package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/error-fallback.test.tsx +0 -0
  212. /package/templates/base/{src/client/hooks/__tests__ → tests/unit/client/hooks}/use-auth.test.tsx +0 -0
  213. /package/templates/base/{src/client/hooks/__tests__ → tests/unit/client/hooks}/use-theme.test.tsx +0 -0
  214. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-display-dashboard-stats-cards-1.png +0 -0
  215. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-display-quick-action-cards-1.png +0 -0
  216. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-display-recent-activity-section-1.png +0 -0
  217. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-display-user-first-name-in-welcome-message-1.png +0 -0
  218. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-display-user-information-in-sidebar-1.png +0 -0
  219. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-render-dashboard-when-authenticated-1.png +0 -0
  220. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-show-navigation-sidebar-1.png +0 -0
  221. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-unauthenticated-should-redirect-to-login-when-not-authenticated-1.png +0 -0
  222. /package/templates/base/{src/client/routes/__tests__ → tests/unit/client/routes}/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-display-accept-invitation-button-1.png +0 -0
  223. /package/templates/base/{src/client/routes/__tests__ → tests/unit/client/routes}/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-display-decline-button-linking-to-homepage-1.png +0 -0
  224. /package/templates/base/{src/client/routes/__tests__ → tests/unit/client/routes}/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-display-invitation-details--email--workspace--role--1.png +0 -0
  225. /package/templates/base/{src/client/routes/__tests__ → tests/unit/client/routes}/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-have-a-logo-link-to-homepage-1.png +0 -0
  226. /package/templates/base/{src/client/routes/__tests__ → tests/unit/client/routes}/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-render-invitation-page-with-inviter-name-and-workspace-1.png +0 -0
  227. /package/templates/base/{src/client/routes/__tests__ → tests/unit/client/routes}/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-show-terms-of-service-and-privacy-policy-links-1.png +0 -0
  228. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/login.test.tsx/Login-Page-should-display-Google-OAuth-login-button-1.png +0 -0
  229. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/login.test.tsx/Login-Page-should-have-a-link-back-to-home-page-1.png +0 -0
  230. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/login.test.tsx/Login-Page-should-render-login-content-without-waiting-for-authentication-1.png +0 -0
  231. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/login.test.tsx/Login-Page-should-render-login-page-at--login-route-1.png +0 -0
  232. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/login.test.tsx/Login-Page-should-show-Terms-of-Service-and-Privacy-Policy-links-1.png +0 -0
  233. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/login.test.tsx/Login-Page-should-trigger-OAuth-flow-when-clicking-login-button-1.png +0 -0
  234. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-404-handling-should-display-404-text-on-not-found-page-1.png +0 -0
  235. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-404-handling-should-have-navigation-options-on-404-page-1.png +0 -0
  236. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-404-handling-should-render-404-page-for-unknown-routes-1.png +0 -0
  237. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-authenticated-navigation-should-navigate-from-dashboard-to-account-page-1.png +0 -0
  238. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-authenticated-navigation-should-navigate-from-dashboard-to-integrations-page-1.png +0 -0
  239. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-authenticated-navigation-should-navigate-from-dashboard-to-settings-page-1.png +0 -0
  240. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-authenticated-navigation-should-navigate-from-dashboard-to-team-page-1.png +0 -0
  241. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-home-page-navigation-should-display-navigation-links-on-home-page-1.png +0 -0
  242. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-home-page-navigation-should-have-correct-link-destinations-on-home-page-1.png +0 -0
  243. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-unauthenticated-navigation-should-allow-access-to-home-page-without-authentication-1.png +0 -0
  244. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-unauthenticated-navigation-should-allow-access-to-login-page-without-authentication-1.png +0 -0
  245. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-unauthenticated-navigation-should-redirect-unauthenticated-users-from-dashboard-to-login-1.png +0 -0
  246. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-unauthenticated-navigation-should-redirect-unauthenticated-users-from-settings-to-login-1.png +0 -0
  247. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-unauthenticated-navigation-should-redirect-unauthenticated-users-from-team-to-login-1.png +0 -0
  248. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/account.test.tsx/Account-Page-should-render-Active-Sessions-section-with-session-cards-1.png +0 -0
  249. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/account.test.tsx/Account-Page-should-render-page-with-correct-title--Account--1.png +0 -0
  250. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/account.test.tsx/Account-Page-should-show-API-Access-section-1.png +0 -0
  251. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/account.test.tsx/Account-Page-should-show-Connected-Accounts-section-with-Google-connected-1.png +0 -0
  252. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/account.test.tsx/Account-Page-should-show-Danger-Zone-section-with-delete-button-1.png +0 -0
  253. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/account.test.tsx/Account-Page-should-show-Security-section-with-Two-Factor-Authentication-1.png +0 -0
  254. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-API-documentation-section-should-display-API-documentation-link-section-1.png +0 -0
  255. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-Create-Webhook-Dialog-should-have-Add-Webhook-trigger-button-1.png +0 -0
  256. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-category-filters-should-display-all-category-buttons-1.png +0 -0
  257. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-integration-cards-should-display-all-integration-cards-with-names-1.png +0 -0
  258. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-integration-cards-should-display-category-badges-on-cards-1.png +0 -0
  259. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-integration-cards-should-show-Configure-button-for-connected-integrations-1.png +0 -0
  260. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-integration-cards-should-show-Connect-button-for-not-connected-integrations-1.png +0 -0
  261. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-integration-cards-should-show-Connected-badge-for-connected-integrations-1.png +0 -0
  262. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-display-Available-Integrations-section-1.png +0 -0
  263. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-display-Webhooks-section-1.png +0 -0
  264. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-display-connected-count-1.png +0 -0
  265. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-display-page-description-1.png +0 -0
  266. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-display-search-input-1.png +0 -0
  267. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-render-with-correct-title--Integrations--1.png +0 -0
  268. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-search-functionality-should-filter-integrations-based-on-search-query-1.png +0 -0
  269. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-search-functionality-should-search-by-description-1.png +0 -0
  270. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-search-functionality-should-show-no-results-message-when-search-has-no-matches-1.png +0 -0
  271. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-webhooks-section-should-display-existing-webhook-1.png +0 -0
  272. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-webhooks-section-should-display-webhook-events-1.png +0 -0
  273. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-webhooks-section-should-display-webhook-last-delivery-info-1.png +0 -0
  274. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-webhooks-section-should-display-webhook-success-status-1.png +0 -0
  275. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-webhooks-section-should-have-Add-Webhook-button-1.png +0 -0
  276. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Account-tab-should-display-connected-accounts-section-with-Google-provider-1.png +0 -0
  277. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Account-tab-should-display-sessions-and-danger-zone-sections-1.png +0 -0
  278. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Notifications-tab-should-display-all-notification-toggle-options-1.png +0 -0
  279. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Notifications-tab-should-display-email-notifications-section-1.png +0 -0
  280. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Notifications-tab-should-display-toggle-switches-for-notification-options-1.png +0 -0
  281. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Notifications-tab-should-have-toggles-checked-by-default-1.png +0 -0
  282. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display--Save-Changes--button-1.png +0 -0
  283. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display-personal-information-form-1.png +0 -0
  284. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display-profile-picture-section-1.png +0 -0
  285. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display-user-email-in-disabled-email-input-1.png +0 -0
  286. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display-user-initials-in-avatar-1.png +0 -0
  287. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display-user-name-in-the-name-input-1.png +0 -0
  288. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-page-rendering-should-display-all-three-tabs-1.png +0 -0
  289. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-page-rendering-should-display-page-description-1.png +0 -0
  290. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-page-rendering-should-render-with-correct-title--Settings--1.png +0 -0
  291. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-tab-navigation-should-show-Profile-tab-as-default-active-tab-1.png +0 -0
  292. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-tab-navigation-should-switch-to-Account-tab-when-clicked-1.png +0 -0
  293. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-tab-navigation-should-switch-to-Notifications-tab-when-clicked-1.png +0 -0
  294. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/team.test.tsx/Team-Page-should-display-Active-Members-section-with-member-count-1.png +0 -0
  295. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/team.test.tsx/Team-Page-should-display-Pending-Invitations-section-with-invitation-details-1.png +0 -0
  296. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/team.test.tsx/Team-Page-should-have-invite-member-button-that-can-be-clicked-1.png +0 -0
  297. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/team.test.tsx/Team-Page-should-render-page-with-correct-title-and-description-1.png +0 -0
  298. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/team.test.tsx/Team-Page-should-render-search-input-that-filters-team-members-1.png +0 -0
  299. /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/team.test.tsx/Team-Page-should-show-current-user-with---you---indicator-and-role-badge-1.png +0 -0
  300. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/error-components.test.tsx +0 -0
@@ -0,0 +1,309 @@
1
+ # C4 Model - Level 3: Component Diagrams
2
+
3
+ > Shows how containers are made up of components and their relationships.
4
+
5
+ ## Backend Components (Hono API)
6
+
7
+ ```mermaid
8
+ C4Component
9
+ title Component Diagram - Hono API
10
+
11
+ Container_Boundary(api, "Hono API") {
12
+ Component(middleware, "Middleware Stack", "Hono Middleware", "Request processing pipeline")
13
+ Component(routes, "Route Handlers", "OpenAPI Routes", "HTTP endpoint handlers")
14
+ Component(services, "Service Layer", "TypeScript", "Business logic")
15
+ Component(auth, "Auth Module", "Guards + RBAC", "Authorization checks")
16
+ Component(db, "Database Layer", "SQL Helpers", "D1 data access")
17
+ Component(lib, "Utilities", "TypeScript", "Shared utilities")
18
+ }
19
+
20
+ ContainerDb(d1, "D1", "SQLite")
21
+ ContainerDb(kv, "KV", "Sessions")
22
+ ContainerDb(r2, "R2", "Files")
23
+
24
+ Rel(middleware, routes, "Passes request")
25
+ Rel(routes, services, "Calls")
26
+ Rel(routes, auth, "Checks permissions")
27
+ Rel(services, db, "Queries")
28
+ Rel(services, lib, "Uses")
29
+ Rel(db, d1, "SQL")
30
+ Rel(middleware, kv, "Sessions")
31
+ Rel(services, r2, "Files")
32
+ ```
33
+
34
+ ## Middleware Stack [HIGH]
35
+
36
+ | Order | Middleware | File | Purpose |
37
+ |-------|------------|------|---------|
38
+ | 1 | Error Handler | `middleware/error-handler.ts` | Global error handling |
39
+ | 2 | Request Context | `middleware/request-context.ts` | Transaction ID, timing |
40
+ | 3 | Request Logger | `middleware/request-logger.ts` | Structured logging |
41
+ | 4 | CORS | `middleware/cors.ts` | Cross-origin requests |
42
+ | 5 | Rate Limiter | `middleware/rate-limit.ts` | Throttling protection |
43
+ | 6 | Session Auth | `middleware/auth.ts` | Session validation |
44
+ | 7 | Account Context | `middleware/account.ts` | Multi-tenant context |
45
+
46
+ ### Middleware Flow
47
+
48
+ ```
49
+ Request
50
+
51
+
52
+ ┌──────────────────┐
53
+ │ Error Handler │ ◄── Catches all errors
54
+ └────────┬─────────┘
55
+
56
+
57
+ ┌──────────────────┐
58
+ │ Request Context │ ◄── Adds transactionId, startTime
59
+ └────────┬─────────┘
60
+
61
+
62
+ ┌──────────────────┐
63
+ │ Request Logger │ ◄── Logs request details
64
+ └────────┬─────────┘
65
+
66
+
67
+ ┌──────────────────┐
68
+ │ CORS │ ◄── Handles preflight
69
+ └────────┬─────────┘
70
+
71
+
72
+ ┌──────────────────┐
73
+ │ Rate Limiter │ ◄── Throttles excessive requests
74
+ └────────┬─────────┘
75
+
76
+
77
+ ┌──────────────────┐
78
+ │ Session Auth │ ◄── Validates session cookie
79
+ └────────┬─────────┘
80
+
81
+
82
+ ┌──────────────────┐
83
+ │ Account Context │ ◄── Sets current account
84
+ └────────┬─────────┘
85
+
86
+
87
+ Route Handler
88
+ ```
89
+
90
+ ## Route Handlers [HIGH]
91
+
92
+ | Module | Path | Endpoints | Purpose |
93
+ |--------|------|-----------|---------|
94
+ | Auth | `/auth/*` | 6 | Authentication flows |
95
+ | Users | `/api/users/*` | 8 | User CRUD + bulk |
96
+ | Accounts | `/api/accounts/*` | 6 | Account CRUD |
97
+ | Invitations | `/api/invitations/*` | 3 | Team invitations |
98
+ | Audits | `/api/audits/*` | 1 | Audit log queries |
99
+ | Storage | `/api/storage/*` | 3 | File operations |
100
+ | Health | `/health/*` | 3 | Health probes |
101
+
102
+ ### Route Structure
103
+
104
+ ```
105
+ src/server/routes/
106
+ ├── index.ts # API router composition
107
+ ├── schemas.ts # Shared schemas
108
+ ├── openapi.ts # OpenAPI config
109
+ ├── api.ts # API router export
110
+ ├── auth/
111
+ │ ├── index.ts # Auth router
112
+ │ ├── routes.ts # Route definitions (OpenAPI)
113
+ │ ├── handlers.ts # Request handlers
114
+ │ └── schemas.ts # Auth schemas
115
+ ├── users/
116
+ │ ├── index.ts
117
+ │ ├── routes.ts
118
+ │ ├── handlers.ts
119
+ │ └── schemas.ts
120
+ ├── accounts/
121
+ │ ├── index.ts
122
+ │ ├── routes.ts
123
+ │ ├── handlers.ts
124
+ │ └── schemas.ts
125
+ ├── invitations/
126
+ │ ├── index.ts
127
+ │ ├── routes.ts
128
+ │ ├── handlers.ts
129
+ │ └── schemas.ts
130
+ ├── audits/
131
+ │ ├── index.ts
132
+ │ ├── routes.ts
133
+ │ ├── handlers.ts
134
+ │ └── schemas.ts
135
+ ├── storage/
136
+ │ ├── index.ts
137
+ │ ├── routes.ts
138
+ │ ├── handlers.ts
139
+ │ └── schemas.ts
140
+ └── health/
141
+ ├── index.ts
142
+ ├── routes.ts
143
+ └── handlers.ts
144
+ ```
145
+
146
+ ## Service Layer [HIGH]
147
+
148
+ | Service | File | Responsibilities |
149
+ |---------|------|------------------|
150
+ | AuthService | `services/auth.ts` | OAuth flow, session management, token refresh |
151
+ | UsersService | `services/users.ts` | User CRUD, account memberships |
152
+ | AccountsService | `services/accounts.ts` | Account CRUD, member management |
153
+ | InvitationsService | `services/invitations.ts` | Invitation lifecycle |
154
+ | AuditsService | `services/audits.ts` | Audit log queries |
155
+
156
+ ### Service Pattern
157
+
158
+ ```typescript
159
+ // Each service follows this pattern:
160
+ export class UsersService {
161
+ constructor(
162
+ private db: D1Database,
163
+ private context: RequestContext
164
+ ) {}
165
+
166
+ async list(accountId: string, pagination: Pagination): Promise<PaginatedUsers> {
167
+ // Business logic + DB queries
168
+ }
169
+
170
+ async create(data: CreateUser): Promise<User> {
171
+ // Validation + creation + audit logging
172
+ }
173
+ }
174
+ ```
175
+
176
+ ## Auth Module [HIGH]
177
+
178
+ | Component | File | Purpose |
179
+ |-----------|------|---------|
180
+ | Roles | `auth/roles.ts` | Role definitions and hierarchy |
181
+ | Permissions | `auth/permissions.ts` | Permission constants |
182
+ | Guards | `auth/guards.ts` | Authorization checks |
183
+
184
+ ### Role Hierarchy
185
+
186
+ ```
187
+ ADMIN
188
+ └── MANAGER
189
+ └── EDITOR
190
+ └── AUTHOR
191
+ └── VIEWER
192
+
193
+ BILLING (separate branch)
194
+ ANALYTICS (separate branch)
195
+ ```
196
+
197
+ ### Guard Functions
198
+
199
+ | Guard | Purpose |
200
+ |-------|---------|
201
+ | `requireAuth()` | Ensures user is authenticated |
202
+ | `requireRole(role)` | Checks user has role or higher |
203
+ | `requirePermission(perm)` | Checks specific permission |
204
+ | `requireSuperAdmin()` | Checks super admin flag |
205
+ | `requireAccountMember()` | Verifies account membership |
206
+
207
+ ## Database Layer [HIGH]
208
+
209
+ | Component | File | Purpose |
210
+ |-----------|------|---------|
211
+ | SQL Helpers | `db/sql.ts` | `queryOne`, `queryAll`, `execute` |
212
+ | Record Types | `db/records.ts` | TypeScript types for SQL results |
213
+ | Client | `db/client.ts` | D1 client wrapper |
214
+ | Seed | `db/seed.ts` | Test data generator |
215
+
216
+ ### SQL Helper Pattern
217
+
218
+ ```typescript
219
+ // Type-safe SQL execution
220
+ const user = await queryOne<UserRecord>(db,
221
+ 'SELECT * FROM users WHERE id = ?',
222
+ [userId]
223
+ );
224
+
225
+ const users = await queryAll<UserRecord>(db,
226
+ 'SELECT * FROM users WHERE account_id = ? LIMIT ? OFFSET ?',
227
+ [accountId, limit, offset]
228
+ );
229
+
230
+ await execute(db,
231
+ 'UPDATE users SET name = ? WHERE id = ?',
232
+ [name, userId]
233
+ );
234
+ ```
235
+
236
+ ## Utility Libraries [HIGH]
237
+
238
+ | Library | File | Purpose |
239
+ |---------|------|---------|
240
+ | OAuth | `lib/oauth.ts` | Google OAuth helpers |
241
+ | Session | `lib/session.ts` | Session create/validate/destroy |
242
+ | Tokens | `lib/tokens.ts` | Refresh token management |
243
+ | Audit | `lib/audit.ts` | Audit log creation |
244
+ | Email | `lib/email.ts` | SendGrid integration |
245
+ | Errors | `lib/errors.ts` | Custom error classes |
246
+ | Pagination | `lib/pagination.ts` | Pagination helpers |
247
+ | R2 Storage | `lib/r2-storage.ts` | File storage helpers |
248
+
249
+ ---
250
+
251
+ ## Frontend Components (React SPA)
252
+
253
+ ```mermaid
254
+ C4Component
255
+ title Component Diagram - React SPA
256
+
257
+ Container_Boundary(spa, "React SPA") {
258
+ Component(router, "TanStack Router", "File-based routing", "Client-side navigation")
259
+ Component(auth, "Auth Provider", "React Context", "Authentication state")
260
+ Component(query, "React Query", "Data fetching", "Server state management")
261
+ Component(routes, "Route Components", "React", "Page components")
262
+ Component(ui, "UI Components", "Radix + Tailwind", "Reusable components")
263
+ Component(hooks, "Custom Hooks", "React", "Shared logic")
264
+ }
265
+
266
+ Container(api, "Hono API", "Backend")
267
+
268
+ Rel(router, routes, "Renders")
269
+ Rel(routes, auth, "Uses")
270
+ Rel(routes, query, "Fetches data")
271
+ Rel(routes, ui, "Composes")
272
+ Rel(routes, hooks, "Uses")
273
+ Rel(query, api, "REST calls")
274
+ ```
275
+
276
+ ## Frontend Route Structure [HIGH]
277
+
278
+ ```
279
+ src/client/routes/
280
+ ├── __root.tsx # Root layout
281
+ ├── index.tsx # Landing page (/)
282
+ ├── login.tsx # Login page (/login)
283
+ ├── $.tsx # 404 catch-all
284
+ ├── invite.$token.tsx # Invitation acceptance
285
+ └── _authenticated/ # Protected routes
286
+ ├── dashboard.tsx # Dashboard (/dashboard)
287
+ ├── account.tsx # Account page (/account)
288
+ ├── team.tsx # Team management (/team)
289
+ ├── settings.tsx # User settings (/settings)
290
+ └── integrations.tsx # Integrations (/integrations)
291
+ ```
292
+
293
+ ## UI Component Library [HIGH]
294
+
295
+ | Category | Components |
296
+ |----------|------------|
297
+ | **Layout** | Sidebar |
298
+ | **Feedback** | Sonner (Toasts), Loading Skeleton, Error Fallback |
299
+ | **Forms** | Input, Label, Form, Button |
300
+ | **Display** | Card, Badge, Avatar, Tabs |
301
+ | **Overlay** | Dialog |
302
+ | **Utility** | Separator, Skeleton |
303
+
304
+ ## Custom Hooks [HIGH]
305
+
306
+ | Hook | File | Purpose |
307
+ |------|------|---------|
308
+ | `useAuth` | `hooks/use-auth.ts` | Authentication state + methods |
309
+ | `useTheme` | `hooks/use-theme.tsx` | Theme (dark/light) management |
@@ -0,0 +1,183 @@
1
+ # C4 Model - Level 2: Container Diagram
2
+
3
+ > Shows the high-level shape of the software architecture and how responsibilities are distributed.
4
+
5
+ ## Container Diagram
6
+
7
+ ```mermaid
8
+ C4Container
9
+ title Container Diagram - BHono Platform
10
+
11
+ Person(user, "User", "SaaS platform user")
12
+
13
+ System_Boundary(bhono, "BHono Platform") {
14
+ Container(spa, "React SPA", "React 19, TanStack Router", "Single-page application providing the user interface")
15
+ Container(api, "Hono API", "Hono.js, TypeScript", "REST API handling business logic and data access")
16
+ ContainerDb(d1, "D1 Database", "SQLite at Edge", "Stores users, accounts, invitations, audit logs")
17
+ ContainerDb(kv, "KV Store", "Cloudflare KV", "Stores user sessions")
18
+ ContainerDb(r2, "R2 Storage", "Cloudflare R2", "Stores uploaded files")
19
+ }
20
+
21
+ System_Ext(google, "Google OAuth", "Identity provider")
22
+ System_Ext(sendgrid, "SendGrid", "Email service")
23
+
24
+ Rel(user, spa, "Uses", "HTTPS")
25
+ Rel(spa, api, "API calls", "REST/JSON")
26
+ Rel(api, d1, "Reads/Writes", "SQL")
27
+ Rel(api, kv, "Sessions", "KV API")
28
+ Rel(api, r2, "Files", "R2 API")
29
+ Rel(api, google, "Auth", "OAuth 2.0")
30
+ Rel(api, sendgrid, "Emails", "REST API")
31
+ ```
32
+
33
+ ## Container Details
34
+
35
+ ### React SPA [HIGH]
36
+
37
+ | Attribute | Value |
38
+ |-----------|-------|
39
+ | **Technology** | React 19, TanStack Router, TanStack Query |
40
+ | **Deployment** | Static assets served from Cloudflare R2/Edge |
41
+ | **Purpose** | User interface for the SaaS platform |
42
+ | **Build Output** | `dist/` directory |
43
+
44
+ **Responsibilities:**
45
+ - Render user interface
46
+ - Handle client-side routing
47
+ - Manage client state
48
+ - Call backend API
49
+ - Handle authentication redirects
50
+
51
+ **Key Dependencies:**
52
+ - `react` - UI library
53
+ - `@tanstack/react-router` - File-based routing
54
+ - `@tanstack/react-query` - Data fetching/caching
55
+ - `react-hook-form` - Form handling
56
+ - `tailwindcss` - Styling
57
+ - `radix-ui/*` - Accessible UI primitives
58
+
59
+ ### Hono API [HIGH]
60
+
61
+ | Attribute | Value |
62
+ |-----------|-------|
63
+ | **Technology** | Hono.js 4.x, TypeScript, Zod |
64
+ | **Deployment** | Cloudflare Workers |
65
+ | **Purpose** | REST API for all backend operations |
66
+ | **Entry Point** | `src/server/index.ts` |
67
+
68
+ **Responsibilities:**
69
+ - Handle HTTP requests
70
+ - Authenticate/authorize users
71
+ - Execute business logic
72
+ - Access data stores
73
+ - Generate OpenAPI documentation
74
+
75
+ **Key Dependencies:**
76
+ - `hono` - Web framework
77
+ - `@hono/zod-openapi` - OpenAPI integration
78
+ - `zod` - Request/response validation
79
+ - `uuidv7` - ID generation
80
+
81
+ ### D1 Database [HIGH]
82
+
83
+ | Attribute | Value |
84
+ |-----------|-------|
85
+ | **Technology** | Cloudflare D1 (SQLite) |
86
+ | **Binding** | `DB` |
87
+ | **Schema** | `schema.sql` |
88
+
89
+ **Tables:**
90
+ | Table | Purpose |
91
+ |-------|---------|
92
+ | `users` | User profiles and authentication |
93
+ | `accounts` | Workspaces/organizations |
94
+ | `user_accounts` | User-account memberships with roles |
95
+ | `invitations` | Pending team invitations |
96
+ | `refresh_tokens` | Token storage for session refresh |
97
+ | `audit_logs` | All state change audit trail |
98
+
99
+ ### KV Store [HIGH]
100
+
101
+ | Attribute | Value |
102
+ |-----------|-------|
103
+ | **Technology** | Cloudflare KV |
104
+ | **Binding** | `SESSIONS` |
105
+ | **Purpose** | Session storage |
106
+
107
+ **Data Stored:**
108
+ - Session ID → User session data (JSON)
109
+ - Session expiration via TTL
110
+
111
+ ### R2 Storage [HIGH]
112
+
113
+ | Attribute | Value |
114
+ |-----------|-------|
115
+ | **Technology** | Cloudflare R2 |
116
+ | **Binding** | `R2_BUCKET` |
117
+ | **Purpose** | File storage |
118
+
119
+ **Usage:**
120
+ - User-uploaded files
121
+ - Account-scoped file storage
122
+ - Presigned URL support for secure uploads
123
+
124
+ ## Inter-Container Communication
125
+
126
+ | From | To | Protocol | Purpose |
127
+ |------|-----|----------|---------|
128
+ | React SPA | Hono API | REST/JSON | All data operations |
129
+ | Hono API | D1 | SQL | Data persistence |
130
+ | Hono API | KV | KV API | Session management |
131
+ | Hono API | R2 | R2 API | File operations |
132
+ | Hono API | Google | OAuth 2.0 | Authentication |
133
+ | Hono API | SendGrid | REST | Email delivery |
134
+
135
+ ## Deployment Architecture
136
+
137
+ ```
138
+ ┌─────────────────────────────────────────────────────────┐
139
+ │ Cloudflare Edge Network │
140
+ │ ┌──────────────────────────────────────────────────┐ │
141
+ │ │ Cloudflare Worker │ │
142
+ │ │ ┌─────────────────┐ ┌─────────────────────┐ │ │
143
+ │ │ │ Static Assets │ │ Hono API │ │ │
144
+ │ │ │ (React SPA) │ │ (Server Logic) │ │ │
145
+ │ │ └─────────────────┘ └──────────┬──────────┘ │ │
146
+ │ └──────────────────────────────────┼───────────────┘ │
147
+ │ │ │
148
+ │ ┌───────────┬───────────────────┼───────────────┐ │
149
+ │ │ │ │ │ │
150
+ │ ▼ ▼ ▼ │ │
151
+ │ ┌─────┐ ┌─────┐ ┌─────────┐ │ │
152
+ │ │ D1 │ │ KV │ │ R2 │ │ │
153
+ │ └─────┘ └─────┘ └─────────┘ │ │
154
+ └─────────────────────────────────────────────────────────┘
155
+ ```
156
+
157
+ ## Request Flow
158
+
159
+ ### Authenticated Request
160
+
161
+ ```
162
+ 1. User → React SPA: Navigate to /dashboard
163
+ 2. React SPA → Hono API: GET /api/users (with session cookie)
164
+ 3. Hono API → KV: Validate session
165
+ 4. Hono API → D1: Query users for account
166
+ 5. D1 → Hono API: User data
167
+ 6. Hono API → React SPA: JSON response
168
+ 7. React SPA → User: Render dashboard
169
+ ```
170
+
171
+ ### Authentication Flow
172
+
173
+ ```
174
+ 1. User → React SPA: Click "Login with Google"
175
+ 2. React SPA → Hono API: GET /auth/login
176
+ 3. Hono API → User: Redirect to Google OAuth
177
+ 4. User → Google: Authorize
178
+ 5. Google → Hono API: GET /auth/callback (with code)
179
+ 6. Hono API → Google: Exchange code for tokens
180
+ 7. Hono API → D1: Create/update user
181
+ 8. Hono API → KV: Create session
182
+ 9. Hono API → User: Set cookie, redirect to app
183
+ ```
@@ -0,0 +1,106 @@
1
+ # C4 Model - Level 1: System Context
2
+
3
+ > Shows how BHono fits into the world around it.
4
+
5
+ ## System Context Diagram
6
+
7
+ ```mermaid
8
+ C4Context
9
+ title System Context Diagram - BHono SaaS Platform
10
+
11
+ Person(user, "User", "A person who uses the SaaS application")
12
+ Person(admin, "Admin", "Account administrator managing team members")
13
+
14
+ System(bhono, "BHono Platform", "Multi-tenant SaaS application with user management, team collaboration, and file storage")
15
+
16
+ System_Ext(google, "Google OAuth", "Identity provider for authentication")
17
+ System_Ext(sendgrid, "SendGrid", "Email delivery service for invitations")
18
+
19
+ Rel(user, bhono, "Uses", "HTTPS")
20
+ Rel(admin, bhono, "Manages teams", "HTTPS")
21
+ Rel(bhono, google, "Authenticates users", "OAuth 2.0")
22
+ Rel(bhono, sendgrid, "Sends emails", "REST API")
23
+ ```
24
+
25
+ ## Context Description
26
+
27
+ | Element | Type | Description | Confidence |
28
+ |---------|------|-------------|------------|
29
+ | **User** | Person | End user of the SaaS platform. Can belong to multiple accounts (workspaces). | HIGH |
30
+ | **Admin** | Person | Account administrator with elevated permissions to manage team members and invitations. | HIGH |
31
+ | **BHono Platform** | System | The main application - a multi-tenant SaaS platform deployed on Cloudflare Workers edge. | HIGH |
32
+ | **Google OAuth** | External System | Google's OAuth 2.0 service used for user authentication. | HIGH |
33
+ | **SendGrid** | External System | Email delivery service for sending team invitations. | HIGH |
34
+
35
+ ## System Responsibilities
36
+
37
+ ### BHono Platform
38
+
39
+ The core system provides:
40
+
41
+ | Capability | Description | Confidence |
42
+ |------------|-------------|------------|
43
+ | **User Authentication** | OAuth 2.0 flow with Google, session management via cookies | HIGH |
44
+ | **Multi-tenancy** | Users can belong to multiple Accounts with different roles | HIGH |
45
+ | **Team Collaboration** | Invite team members via email, manage permissions | HIGH |
46
+ | **File Storage** | Upload/download files via R2 storage | HIGH |
47
+ | **Audit Logging** | Track all state changes for compliance | HIGH |
48
+ | **API Access** | REST API with OpenAPI documentation | HIGH |
49
+
50
+ ## External System Dependencies
51
+
52
+ ### Google OAuth [HIGH]
53
+
54
+ - **Purpose**: User authentication
55
+ - **Protocol**: OAuth 2.0 with PKCE
56
+ - **Endpoints Used**:
57
+ - `https://accounts.google.com/o/oauth2/v2/auth` - Authorization
58
+ - `https://oauth2.googleapis.com/token` - Token exchange
59
+ - `https://www.googleapis.com/oauth2/v3/userinfo` - User info
60
+ - **Data Exchanged**: User email, name, avatar URL, Google ID
61
+
62
+ ### SendGrid [HIGH]
63
+
64
+ - **Purpose**: Email delivery for invitations
65
+ - **Protocol**: REST API
66
+ - **Endpoints Used**: SendGrid Mail Send API
67
+ - **Data Exchanged**: Recipient email, invitation details, sender info
68
+
69
+ ## User Roles
70
+
71
+ | Role | Description | Confidence |
72
+ |------|-------------|------------|
73
+ | **ADMIN** | Full account access, can manage all members and settings | HIGH |
74
+ | **MANAGER** | Can manage team members (invite, remove) | HIGH |
75
+ | **EDITOR** | Can edit all content | HIGH |
76
+ | **AUTHOR** | Can create and edit own content | HIGH |
77
+ | **VIEWER** | Read-only access | HIGH |
78
+ | **BILLING** | Access to billing information | HIGH |
79
+ | **ANALYTICS** | Access to analytics and audit logs | HIGH |
80
+
81
+ ## Non-Functional Requirements
82
+
83
+ | Requirement | Target | Implementation | Confidence |
84
+ |-------------|--------|----------------|------------|
85
+ | **Latency** | <100ms globally | Cloudflare Edge deployment | HIGH |
86
+ | **Availability** | 99.9%+ | Cloudflare Workers SLA | HIGH |
87
+ | **Security** | OAuth 2.0, RBAC | Google OAuth + Guards | HIGH |
88
+ | **Compliance** | Audit trail | audit_logs table | HIGH |
89
+ | **Multi-region** | Global | Cloudflare Edge network | HIGH |
90
+
91
+ ## Data Flow Overview
92
+
93
+ ```
94
+ ┌─────────┐ HTTPS ┌──────────────────┐
95
+ │ User │───────────────▶│ BHono Platform │
96
+ └─────────┘ └────────┬─────────┘
97
+
98
+ ┌───────────────┼───────────────┐
99
+ │ │ │
100
+ ▼ ▼ ▼
101
+ ┌───────────┐ ┌───────────┐ ┌───────────┐
102
+ │ Google │ │ SendGrid │ │ Cloudflare│
103
+ │ OAuth │ │ │ │ Services │
104
+ └───────────┘ └───────────┘ └───────────┘
105
+ D1 | KV | R2
106
+ ```
@@ -1,7 +1,7 @@
1
1
  # Data Requirements Document (DRD)
2
2
 
3
3
  ## 1. Objetivo e escopo
4
- Este documento define os requisitos de dados do projeto, cobrindo o modelo relacional (D1/SQLite), armazenamento de sessao (KV) e objetos (R2). Serve como referencia para manutencao, auditoria e eventual migracao para SQL puro.
4
+ Este documento define os requisitos de dados do projeto, cobrindo o modelo relacional (D1/SQLite), armazenamento de sessao (KV) e objetos (R2). Serve como referencia para manutencao, auditoria e evolucao do SQL puro.
5
5
 
6
6
  ## 2. Componentes de armazenamento
7
7
  - D1 (SQLite): armazenamento relacional principal.
@@ -102,8 +102,9 @@ Principais entidades:
102
102
  - Requisito: manter procedimento de backup/restore do D1 (ex.: exportacao periodica) e verificar restauracao.
103
103
  - KV e R2 devem ter estrategia de recuperacao alinhada com RPO/RTO desejados.
104
104
 
105
- ## 12. Consideracoes para migracao para SQL puro
105
+ ## 12. Consideracoes para SQL puro (sem migrations)
106
106
  - Todas as queries devem ser parametrizadas para evitar SQL injection.
107
107
  - Manter mapeadores de resultado (ex.: validacao via Zod) para preservar contratos tipados.
108
108
  - Centralizar SQL em um modulo `db` e reutilizar modelos do ERD.
109
- - Implementar migracoes em SQL (ou manter ferramenta atual apenas para migrar schema).
109
+ - `schema.sql` e a fonte de verdade do schema e deve ser aplicado via `wrangler d1 execute`.
110
+ - `seed.sql` e gerado a partir de `src/server/db/seed.ts` e aplicado apos o bootstrap quando necessario.
@@ -0,0 +1,39 @@
1
+ # Database Bootstrap (schema.sql)
2
+
3
+ ## Objetivo
4
+ O boilerplate nao usa migrations. O schema do D1 e versionado em `schema.sql` e aplicado via `wrangler d1 execute`. O seed e gerado em `seed.sql` a partir de `src/server/db/seed.ts`.
5
+
6
+ ## Arquivos
7
+ - `schema.sql` - fonte de verdade do schema
8
+ - `src/server/db/seed.ts` - gerador de seed
9
+ - `seed.sql` - output do seed (gerado)
10
+
11
+ ## Fluxos recomendados
12
+ ### Local
13
+ ```bash
14
+ # aplicar schema
15
+ pnpm db:schema:local
16
+
17
+ # gerar e aplicar seed
18
+ pnpm db:seed:local
19
+
20
+ # reset completo (schema + seed)
21
+ pnpm db:reset:local
22
+ ```
23
+
24
+ ### Remoto (opcional)
25
+ ```bash
26
+ # aplicar schema
27
+ pnpm db:schema:remote
28
+
29
+ # gerar e aplicar seed
30
+ pnpm db:seed:remote
31
+
32
+ # reset completo (schema + seed)
33
+ pnpm db:reset:remote
34
+ ```
35
+
36
+ ## Notas
37
+ - `schema.sql` deve ser atualizado a cada mudanca estrutural.
38
+ - `seed.sql` deve ser re-gerado apos alteracoes em `seed.ts`.
39
+ - As migrations nao sao usadas neste boilerplate para manter o fluxo simples.