@etus/bhono-app 0.1.5 → 0.1.6

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 (269) hide show
  1. package/dist/index.js +0 -0
  2. package/package.json +5 -1
  3. package/templates/base/.husky/pre-push +26 -0
  4. package/templates/base/CLAUDE.md +5 -5
  5. package/templates/base/README.md +31 -20
  6. package/templates/base/docs/app_spec.txt +13 -10
  7. package/templates/base/docs/architecture/README.md +3 -0
  8. package/templates/base/docs/architecture/data-requirements.md +4 -3
  9. package/templates/base/docs/architecture/db-bootstrap.md +39 -0
  10. package/templates/base/docs/architecture/drizzle-migration-plan.md +125 -0
  11. package/templates/base/docs/architecture/erd.md +1 -1
  12. package/templates/base/docs/architecture/sql-standards.md +100 -0
  13. package/templates/base/docs/testing.md +36 -29
  14. package/templates/base/package.json +6 -5
  15. package/templates/base/pnpm-lock.yaml +0 -123
  16. package/templates/base/schema.sql +84 -0
  17. package/templates/base/scripts/init.sh +244 -59
  18. package/templates/base/src/client/hooks/use-auth.ts +5 -0
  19. package/templates/base/src/client/routes/_authenticated/dashboard.tsx +1 -1
  20. package/templates/base/src/client/routes/index.tsx +1 -1
  21. package/templates/base/src/server/db/client.ts +3 -5
  22. package/templates/base/src/server/db/records.ts +81 -0
  23. package/templates/base/src/server/db/seed.ts +3 -2
  24. package/templates/base/src/server/db/sql.ts +96 -0
  25. package/templates/base/src/server/index.ts +16 -2
  26. package/templates/base/src/server/lib/audit.ts +74 -26
  27. package/templates/base/src/server/lib/audited-db.ts +219 -109
  28. package/templates/base/src/server/lib/transaction.ts +10 -16
  29. package/templates/base/src/server/middleware/account.ts +8 -15
  30. package/templates/base/src/server/middleware/auth.ts +102 -38
  31. package/templates/base/src/server/middleware/rate-limit.ts +6 -1
  32. package/templates/base/src/server/routes/accounts/handlers.ts +18 -6
  33. package/templates/base/src/server/routes/audits/handlers.ts +3 -1
  34. package/templates/base/src/server/routes/auth/handlers.ts +14 -9
  35. package/templates/base/src/server/routes/auth/test-login.ts +99 -45
  36. package/templates/base/src/server/routes/health/handlers.ts +4 -4
  37. package/templates/base/src/server/routes/invitations/handlers.ts +6 -3
  38. package/templates/base/src/server/routes/users/handlers.ts +21 -14
  39. package/templates/base/src/server/services/accounts.ts +242 -217
  40. package/templates/base/src/server/services/audits.ts +114 -61
  41. package/templates/base/src/server/services/auth.ts +310 -180
  42. package/templates/base/src/server/services/invitations.ts +282 -222
  43. package/templates/base/src/server/services/users.ts +383 -293
  44. package/templates/base/src/server/types/index.ts +1 -2
  45. package/templates/base/{src/server/__tests__/fixtures.ts → tests/fixtures/server.ts} +3 -3
  46. package/templates/base/{src/client/__tests__/setup-browser.ts → tests/helpers/client-setup-browser.ts} +2 -2
  47. package/templates/base/{src/client/__tests__/setup.ts → tests/helpers/client-setup.ts} +1 -1
  48. package/templates/base/{src/client/__tests__/test-utils.tsx → tests/helpers/client-test-utils.tsx} +2 -2
  49. package/templates/base/{src/server/__tests__/setup.ts → tests/helpers/server.ts} +9 -9
  50. package/templates/base/tests/integration/accounts/crud.test.ts +2 -11
  51. package/templates/base/tests/integration/audits/list.test.ts +2 -11
  52. package/templates/base/tests/integration/auth/auth-service.test.ts +1 -10
  53. package/templates/base/tests/integration/auth/invitation-token.test.ts +2 -11
  54. package/templates/base/tests/integration/auth/logout.test.ts +2 -11
  55. package/templates/base/tests/integration/auth/oauth.test.ts +23 -42
  56. package/templates/base/tests/integration/auth/refresh-token.test.ts +1 -9
  57. package/templates/base/tests/integration/auth/session-expiry.test.ts +1 -9
  58. package/templates/base/tests/integration/auth/session.test.ts +2 -11
  59. package/templates/base/tests/integration/auth/super-admin.test.ts +1 -9
  60. package/templates/base/tests/integration/authorization/analytics-role.test.ts +2 -11
  61. package/templates/base/tests/integration/authorization/billing-role.test.ts +2 -11
  62. package/templates/base/tests/integration/authorization/guards-roles.test.ts +1 -9
  63. package/templates/base/tests/integration/authorization/multi-tenancy.test.ts +2 -11
  64. package/templates/base/tests/integration/authorization/roles.test.ts +2 -11
  65. package/templates/base/tests/integration/config/production-behavior.test.ts +2 -11
  66. package/templates/base/tests/integration/health/health.test.ts +25 -44
  67. package/templates/base/tests/integration/invitations/crud.test.ts +2 -11
  68. package/templates/base/tests/integration/invitations/email.test.ts +1 -9
  69. package/templates/base/tests/integration/middleware/auth.test.ts +3 -12
  70. package/templates/base/tests/integration/middleware/request-logger.test.ts +1 -9
  71. package/templates/base/tests/integration/performance/response-times.test.ts +1 -9
  72. package/templates/base/tests/integration/security/cookie-security.test.ts +2 -11
  73. package/templates/base/tests/integration/security/csrf-protection.test.ts +2 -11
  74. package/templates/base/tests/integration/security/log-sanitization.test.ts +1 -9
  75. package/templates/base/tests/integration/security/rate-limiting.test.ts +1 -9
  76. package/templates/base/tests/integration/security/sql-injection.test.ts +7 -18
  77. package/templates/base/tests/integration/security/xss-prevention.test.ts +2 -11
  78. package/templates/base/tests/integration/setup.ts +13 -90
  79. package/templates/base/tests/integration/smoke.test.ts +3 -2
  80. package/templates/base/tests/integration/storage/upload.test.ts +2 -11
  81. package/templates/base/tests/integration/storage/validation.test.ts +2 -11
  82. package/templates/base/tests/integration/users/crud.test.ts +2 -11
  83. package/templates/base/tests/integration/users/list.test.ts +2 -11
  84. package/templates/base/tests/integration/vitest.config.ts +2 -9
  85. package/templates/base/{src/server/__tests__ → tests}/mocks/db.ts +1 -1
  86. package/templates/base/{src/server/__tests__ → tests}/mocks/index.ts +1 -1
  87. package/templates/base/{src/server/__tests__ → tests}/mocks/kv.ts +1 -1
  88. package/templates/base/{src/server/__tests__ → tests}/mocks/r2.ts +1 -1
  89. package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/sidebar.test.tsx +1 -1
  90. package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/avatar.test.tsx +1 -1
  91. package/templates/base/{src/client/__tests__ → tests/unit/client/components/ui}/button.test.tsx +1 -1
  92. package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/card.test.tsx +1 -1
  93. package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/dialog.test.tsx +1 -1
  94. package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/input.test.tsx +1 -1
  95. package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/loading-skeleton.test.tsx +1 -1
  96. package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/skeleton.test.tsx +1 -1
  97. package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/sonner.test.tsx +1 -1
  98. package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/tabs.test.tsx +1 -1
  99. package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/account.test.tsx +1 -1
  100. package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/integrations.test.tsx +1 -1
  101. package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/settings.test.tsx +1 -1
  102. package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/team.test.tsx +1 -1
  103. package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/authenticated-layout.test.tsx +1 -1
  104. package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/dashboard.test.tsx +1 -1
  105. package/templates/base/{src/client/routes/__tests__ → tests/unit/client/routes}/invite.test.tsx +1 -1
  106. package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/login.test.tsx +1 -1
  107. package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/navigation.test.tsx +1 -1
  108. package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/root-layout.test.tsx +1 -1
  109. package/templates/base/{src/server/auth/__tests__ → tests/unit/server/auth}/guards.test.ts +2 -2
  110. package/templates/base/{src → tests/unit}/server/auth/permissions.test.ts +1 -1
  111. package/templates/base/{src → tests/unit}/server/auth/roles.test.ts +1 -1
  112. package/templates/base/tests/unit/server/db/sql.test.ts +68 -0
  113. package/templates/base/{src → tests/unit}/server/env.test.ts +1 -1
  114. package/templates/base/tests/unit/server/lib/audited-db.test.ts +78 -0
  115. package/templates/base/{src → tests/unit}/server/lib/email.test.ts +1 -1
  116. package/templates/base/{src → tests/unit}/server/lib/errors.test.ts +1 -1
  117. package/templates/base/{src → tests/unit}/server/lib/oauth.test.ts +1 -1
  118. package/templates/base/{src → tests/unit}/server/lib/pagination.test.ts +1 -1
  119. package/templates/base/{src → tests/unit}/server/lib/password.test.ts +1 -1
  120. package/templates/base/{src → tests/unit}/server/lib/providers.test.ts +1 -1
  121. package/templates/base/{src → tests/unit}/server/lib/r2-storage.test.ts +2 -2
  122. package/templates/base/{src → tests/unit}/server/lib/session.test.ts +2 -2
  123. package/templates/base/{src → tests/unit}/server/lib/tokens.test.ts +1 -1
  124. package/templates/base/{src → tests/unit}/server/lib/transaction.test.ts +5 -14
  125. package/templates/base/{src → tests/unit}/server/middleware/account.test.ts +16 -24
  126. package/templates/base/{src → tests/unit}/server/middleware/auth.test.ts +71 -42
  127. package/templates/base/{src → tests/unit}/server/middleware/cors.test.ts +1 -1
  128. package/templates/base/{src → tests/unit}/server/middleware/error-handler.test.ts +2 -2
  129. package/templates/base/{src → tests/unit}/server/middleware/rate-limit.test.ts +3 -2
  130. package/templates/base/{src → tests/unit}/server/middleware/request-context.test.ts +1 -1
  131. package/templates/base/{src → tests/unit}/server/middleware/request-logger.test.ts +1 -1
  132. package/templates/base/{src/server/__tests__/mocks/__tests__ → tests/unit/server/mocks}/db.test.ts +1 -1
  133. package/templates/base/{src/server/__tests__/mocks/__tests__ → tests/unit/server/mocks}/kv.test.ts +1 -1
  134. package/templates/base/{src/server/__tests__/mocks/__tests__ → tests/unit/server/mocks}/r2.test.ts +1 -1
  135. package/templates/base/{src/server/routes/accounts/__tests__ → tests/unit/server/routes/accounts}/handlers.test.ts +12 -12
  136. package/templates/base/{src/server/routes/audits/__tests__ → tests/unit/server/routes/audits}/handlers.test.ts +11 -11
  137. package/templates/base/{src/server/routes/auth/__tests__ → tests/unit/server/routes/auth}/handlers.test.ts +13 -13
  138. package/templates/base/{src/server/routes/health/__tests__ → tests/unit/server/routes/health}/handlers.test.ts +27 -23
  139. package/templates/base/{src/server/routes/invitations/__tests__ → tests/unit/server/routes/invitations}/handlers.test.ts +14 -17
  140. package/templates/base/{src/server/routes/storage/__tests__ → tests/unit/server/routes/storage}/handlers.test.ts +6 -6
  141. package/templates/base/{src/server/routes/users/__tests__ → tests/unit/server/routes/users}/handlers.test.ts +12 -12
  142. package/templates/base/tests/unit/server/services/accounts.test.ts +258 -0
  143. package/templates/base/tests/unit/server/services/audits.test.ts +141 -0
  144. package/templates/base/tests/unit/server/services/auth.test.ts +179 -0
  145. package/templates/base/tests/unit/server/services/invitations.test.ts +165 -0
  146. package/templates/base/tests/unit/server/services/users.test.ts +351 -0
  147. package/templates/base/tsconfig.json +2 -1
  148. package/templates/base/vitest.config.browser.ts +3 -2
  149. package/templates/base/vitest.config.frontend.ts +3 -2
  150. package/templates/base/vitest.config.ts +7 -14
  151. package/templates/base/.claude/settings.local.json +0 -11
  152. package/templates/base/config/drizzle.config.ts +0 -10
  153. package/templates/base/src/server/db/schema/accounts.ts +0 -20
  154. package/templates/base/src/server/db/schema/audit-logs.ts +0 -26
  155. package/templates/base/src/server/db/schema/index.ts +0 -7
  156. package/templates/base/src/server/db/schema/invitations.ts +0 -30
  157. package/templates/base/src/server/db/schema/refresh-tokens.ts +0 -22
  158. package/templates/base/src/server/db/schema/user-accounts.ts +0 -25
  159. package/templates/base/src/server/db/schema/users.ts +0 -33
  160. package/templates/base/src/server/lib/audited-db.test.ts +0 -107
  161. package/templates/base/src/server/lib/schema-helpers.ts +0 -16
  162. package/templates/base/src/server/services/__tests__/accounts.test.ts +0 -764
  163. package/templates/base/src/server/services/__tests__/audits.test.ts +0 -235
  164. package/templates/base/src/server/services/__tests__/auth.test.ts +0 -765
  165. package/templates/base/src/server/services/__tests__/invitations.test.ts +0 -704
  166. package/templates/base/src/server/services/__tests__/users.test.ts +0 -755
  167. package/templates/base/tests/integration/lib/schema-helpers.test.ts +0 -129
  168. /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
  169. /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
  170. /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-handles-logout-button-click-1.png +0 -0
  171. /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-handles-navigation-clicks-1.png +0 -0
  172. /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
  173. /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-highlights-active-route-1.png +0 -0
  174. /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-renders-sidebar-navigation-items-1.png +0 -0
  175. /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
  176. /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
  177. /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
  178. /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/error-boundary.test.tsx +0 -0
  179. /package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/error-fallback.test.tsx +0 -0
  180. /package/templates/base/{src/client/hooks/__tests__ → tests/unit/client/hooks}/use-auth.test.tsx +0 -0
  181. /package/templates/base/{src/client/hooks/__tests__ → tests/unit/client/hooks}/use-theme.test.tsx +0 -0
  182. /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
  183. /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
  184. /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
  185. /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
  186. /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
  187. /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
  188. /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
  189. /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
  190. /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
  191. /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
  192. /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
  193. /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
  194. /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
  195. /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
  196. /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
  197. /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
  198. /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
  199. /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
  200. /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
  201. /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
  202. /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
  203. /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
  204. /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
  205. /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
  206. /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
  207. /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
  208. /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
  209. /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
  210. /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
  211. /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
  212. /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
  213. /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
  214. /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
  215. /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
  216. /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
  217. /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
  218. /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
  219. /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
  220. /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
  221. /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
  222. /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
  223. /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
  224. /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
  225. /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
  226. /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
  227. /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
  228. /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
  229. /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
  230. /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
  231. /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
  232. /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
  233. /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
  234. /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
  235. /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
  236. /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
  237. /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
  238. /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
  239. /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
  240. /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
  241. /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
  242. /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
  243. /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
  244. /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
  245. /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
  246. /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
  247. /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
  248. /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
  249. /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
  250. /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
  251. /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
  252. /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
  253. /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
  254. /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
  255. /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
  256. /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
  257. /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
  258. /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
  259. /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
  260. /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
  261. /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
  262. /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
  263. /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
  264. /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
  265. /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
  266. /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
  267. /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
  268. /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/error-components.test.tsx +0 -0
  269. /package/templates/base/{src/shared/schemas/__tests__ → tests/unit/shared}/schemas.test.ts +0 -0
@@ -19,22 +19,22 @@ npm run test:run
19
19
  ## Test Structure
20
20
 
21
21
  ```
22
- src/
23
- ├── server/
24
- │ ├── __tests__/mocks/ # D1, KV, R2 mocks for Cloudflare services
25
- │ ├── services/__tests__/ # Service layer tests
26
- ├── routes/*/__tests__/ # Route handler tests
27
- │ └── middleware/*.test.ts # Middleware tests
28
- ├── client/
29
- │ ├── __tests__/ # Component and route tests
30
- │ ├── components/__tests__/ # UI component tests
31
- └── hooks/__tests__/ # Custom hook tests
32
- e2e/
33
- ├── fixtures.ts # Playwright fixtures
34
- ├── auth.setup.ts # Auth state setup
35
- ├── smoke.unauth.spec.ts # Smoke tests (no auth)
36
- ├── auth/ # Authentication flow tests
37
- └── crud/ # CRUD operation tests
22
+ tests/
23
+ ├── unit/
24
+ │ ├── server/ # Backend unit tests (services/routes/middleware/lib)
25
+ │ ├── client/ # Frontend unit tests (components/routes/hooks)
26
+ └── shared/ # Shared schema/unit tests
27
+ ├── integration/ # Integration tests (D1/KV/R2 + workflows)
28
+ ├── e2e/ # Playwright E2E tests
29
+ │ ├── journeys/ # User journey tests
30
+ │ ├── crud/ # CRUD operation tests
31
+ ├── api/ # API tests
32
+ │ ├── a11y/ # Accessibility tests
33
+ ├── visual/ # Visual regression
34
+ │ └── mobile/ # Responsive tests
35
+ ├── fixtures/ # Test fixtures
36
+ ├── mocks/ # Test mocks (D1/KV/R2)
37
+ └── helpers/ # Test utilities
38
38
  ```
39
39
 
40
40
  ## Backend Tests (Vitest)
@@ -45,7 +45,7 @@ e2e/
45
45
  npm test # Watch mode
46
46
  npm run test:run # Single run
47
47
  npm run test:coverage # With coverage report
48
- vitest run src/server/services # Specific folder
48
+ vitest run tests/unit/server/services # Specific folder
49
49
  ```
50
50
 
51
51
  ### Mock Services
@@ -53,17 +53,17 @@ vitest run src/server/services # Specific folder
53
53
  Import mocks for Cloudflare services:
54
54
 
55
55
  ```typescript
56
- import { createMockD1Database, createMockSession } from '../__tests__/mocks/db'
57
- import { MockKVStore } from '../__tests__/mocks/kv'
58
- import { MockR2Bucket } from '../__tests__/mocks/r2'
56
+ import { createMockD1, setMockQueryResult } from '@tests/mocks/db'
57
+ import { createMockKV, type MockKVNamespace } from '@tests/mocks/kv'
58
+ import { createMockR2, type MockR2Bucket } from '@tests/mocks/r2'
59
59
 
60
60
  describe('MyService', () => {
61
- let db: MockD1Database
61
+ let db: ReturnType<typeof createMockD1>
62
62
 
63
63
  beforeEach(() => {
64
- db = createMockD1Database([
65
- // Seed data for your test
66
- { id: '1', name: 'Test User', ... }
64
+ db = createMockD1()
65
+ setMockQueryResult(db, [1], [
66
+ { id: '1', name: 'Test User' }
67
67
  ])
68
68
  })
69
69
  })
@@ -75,9 +75,17 @@ Use Hono's testClient for type-safe route testing:
75
75
 
76
76
  ```typescript
77
77
  import { testClient } from 'hono/testing'
78
- import { createTestApp } from '../test-helpers'
78
+ import { Hono } from 'hono'
79
+ import { users } from '@server/routes/index'
80
+ import { createMockEnv } from '@tests/helpers/server'
81
+
82
+ const app = new Hono()
83
+ app.use('*', async (c, next) => {
84
+ ;(c as any).env = createMockEnv()
85
+ await next()
86
+ })
87
+ app.route('/users', users)
79
88
 
80
- const { app, db, kv } = createTestApp()
81
89
  const client = testClient(app)
82
90
 
83
91
  it('should create user', async () => {
@@ -114,11 +122,10 @@ it('should handle click', async () => {
114
122
  ### Route Testing
115
123
 
116
124
  ```typescript
117
- import { renderRoute, waitForRouteLoad } from '../__tests__/setup'
125
+ import { renderRouteAsync } from '@tests/helpers/client-test-utils'
118
126
 
119
127
  it('should render dashboard', async () => {
120
- renderRoute('/dashboard', { authenticated: true })
121
- await waitForRouteLoad()
128
+ await renderRouteAsync({ initialEntries: ['/dashboard'] })
122
129
 
123
130
  expect(screen.getByText('Dashboard')).toBeInTheDocument()
124
131
  })
@@ -16,10 +16,13 @@
16
16
  "build": "vite build",
17
17
  "preview": "vite preview",
18
18
  "deploy": "wrangler deploy --config config/wrangler.json",
19
- "db:push": "drizzle-kit push --config config/drizzle.config.ts",
20
- "db:generate": "drizzle-kit generate --config config/drizzle.config.ts",
21
- "db:studio": "drizzle-kit studio --config config/drizzle.config.ts",
22
19
  "db:seed": "pnpm tsx src/server/db/seed.ts",
20
+ "db:schema:local": "wrangler --config config/wrangler.json d1 execute $(node -e \"const c=require('./config/wrangler.json'); console.log((c.d1_databases&&c.d1_databases[0]&&c.d1_databases[0].database_name)||'');\") --local --file=schema.sql",
21
+ "db:schema:remote": "wrangler --config config/wrangler.json d1 execute $(node -e \"const c=require('./config/wrangler.json'); console.log((c.d1_databases&&c.d1_databases[0]&&c.d1_databases[0].database_name)||'');\") --remote --file=schema.sql",
22
+ "db:seed:local": "pnpm db:seed && wrangler --config config/wrangler.json d1 execute $(node -e \"const c=require('./config/wrangler.json'); console.log((c.d1_databases&&c.d1_databases[0]&&c.d1_databases[0].database_name)||'');\") --local --file=seed.sql",
23
+ "db:seed:remote": "pnpm db:seed && wrangler --config config/wrangler.json d1 execute $(node -e \"const c=require('./config/wrangler.json'); console.log((c.d1_databases&&c.d1_databases[0]&&c.d1_databases[0].database_name)||'');\") --remote --file=seed.sql",
24
+ "db:reset:local": "pnpm db:schema:local && pnpm db:seed:local",
25
+ "db:reset:remote": "pnpm db:schema:remote && pnpm db:seed:remote",
23
26
  "api:spec": "pnpm tsx scripts/generate-openapi.ts",
24
27
  "api:types": "pnpm api:spec && openapi-typescript docs/openapi.json -o src/shared/types/api.ts",
25
28
  "cf-typegen": "wrangler types --config config/wrangler.json",
@@ -54,7 +57,6 @@
54
57
  "@tanstack/react-router": "^1.144.0",
55
58
  "class-variance-authority": "^0.7.1",
56
59
  "clsx": "^2.1.1",
57
- "drizzle-orm": "^0.45.1",
58
60
  "hono": "^4.11.3",
59
61
  "lucide-react": "^0.562.0",
60
62
  "react": "^19.2.3",
@@ -91,7 +93,6 @@
91
93
  "@vitest/coverage-istanbul": "^4.0.16",
92
94
  "@vitest/coverage-v8": "^4.0.16",
93
95
  "better-sqlite3": "^12.5.0",
94
- "drizzle-kit": "^0.31.8",
95
96
  "eslint": "^9.39.2",
96
97
  "eslint-plugin-boundaries": "^5.3.1",
97
98
  "eslint-plugin-promise": "^7.2.1",
@@ -35,9 +35,6 @@ importers:
35
35
  clsx:
36
36
  specifier: ^2.1.1
37
37
  version: 2.1.1
38
- drizzle-orm:
39
- specifier: ^0.45.1
40
- version: 0.45.1(@cloudflare/workers-types@4.20260101.0)(@types/better-sqlite3@7.6.13)(better-sqlite3@12.5.0)(gel@2.2.0)
41
38
  hono:
42
39
  specifier: ^4.11.3
43
40
  version: 4.11.3
@@ -141,9 +138,6 @@ importers:
141
138
  better-sqlite3:
142
139
  specifier: ^12.5.0
143
140
  version: 12.5.0
144
- drizzle-kit:
145
- specifier: ^0.31.8
146
- version: 0.31.8
147
141
  eslint:
148
142
  specifier: ^9.39.2
149
143
  version: 9.39.2(jiti@2.6.1)
@@ -419,9 +413,6 @@ packages:
419
413
  resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==}
420
414
  engines: {node: '>=18'}
421
415
 
422
- '@drizzle-team/brocli@0.10.2':
423
- resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==}
424
-
425
416
  '@emnapi/runtime@1.7.1':
426
417
  resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==}
427
418
 
@@ -2425,102 +2416,6 @@ packages:
2425
2416
  dom-accessibility-api@0.6.3:
2426
2417
  resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==}
2427
2418
 
2428
- drizzle-kit@0.31.8:
2429
- resolution: {integrity: sha512-O9EC/miwdnRDY10qRxM8P3Pg8hXe3LyU4ZipReKOgTwn4OqANmftj8XJz1UPUAS6NMHf0E2htjsbQujUTkncCg==}
2430
- hasBin: true
2431
-
2432
- drizzle-orm@0.45.1:
2433
- resolution: {integrity: sha512-Te0FOdKIistGNPMq2jscdqngBRfBpC8uMFVwqjf6gtTVJHIQ/dosgV/CLBU2N4ZJBsXL5savCba9b0YJskKdcA==}
2434
- peerDependencies:
2435
- '@aws-sdk/client-rds-data': '>=3'
2436
- '@cloudflare/workers-types': '>=4'
2437
- '@electric-sql/pglite': '>=0.2.0'
2438
- '@libsql/client': '>=0.10.0'
2439
- '@libsql/client-wasm': '>=0.10.0'
2440
- '@neondatabase/serverless': '>=0.10.0'
2441
- '@op-engineering/op-sqlite': '>=2'
2442
- '@opentelemetry/api': ^1.4.1
2443
- '@planetscale/database': '>=1.13'
2444
- '@prisma/client': '*'
2445
- '@tidbcloud/serverless': '*'
2446
- '@types/better-sqlite3': '*'
2447
- '@types/pg': '*'
2448
- '@types/sql.js': '*'
2449
- '@upstash/redis': '>=1.34.7'
2450
- '@vercel/postgres': '>=0.8.0'
2451
- '@xata.io/client': '*'
2452
- better-sqlite3: '>=7'
2453
- bun-types: '*'
2454
- expo-sqlite: '>=14.0.0'
2455
- gel: '>=2'
2456
- knex: '*'
2457
- kysely: '*'
2458
- mysql2: '>=2'
2459
- pg: '>=8'
2460
- postgres: '>=3'
2461
- prisma: '*'
2462
- sql.js: '>=1'
2463
- sqlite3: '>=5'
2464
- peerDependenciesMeta:
2465
- '@aws-sdk/client-rds-data':
2466
- optional: true
2467
- '@cloudflare/workers-types':
2468
- optional: true
2469
- '@electric-sql/pglite':
2470
- optional: true
2471
- '@libsql/client':
2472
- optional: true
2473
- '@libsql/client-wasm':
2474
- optional: true
2475
- '@neondatabase/serverless':
2476
- optional: true
2477
- '@op-engineering/op-sqlite':
2478
- optional: true
2479
- '@opentelemetry/api':
2480
- optional: true
2481
- '@planetscale/database':
2482
- optional: true
2483
- '@prisma/client':
2484
- optional: true
2485
- '@tidbcloud/serverless':
2486
- optional: true
2487
- '@types/better-sqlite3':
2488
- optional: true
2489
- '@types/pg':
2490
- optional: true
2491
- '@types/sql.js':
2492
- optional: true
2493
- '@upstash/redis':
2494
- optional: true
2495
- '@vercel/postgres':
2496
- optional: true
2497
- '@xata.io/client':
2498
- optional: true
2499
- better-sqlite3:
2500
- optional: true
2501
- bun-types:
2502
- optional: true
2503
- expo-sqlite:
2504
- optional: true
2505
- gel:
2506
- optional: true
2507
- knex:
2508
- optional: true
2509
- kysely:
2510
- optional: true
2511
- mysql2:
2512
- optional: true
2513
- pg:
2514
- optional: true
2515
- postgres:
2516
- optional: true
2517
- prisma:
2518
- optional: true
2519
- sql.js:
2520
- optional: true
2521
- sqlite3:
2522
- optional: true
2523
-
2524
2419
  eastasianwidth@0.2.0:
2525
2420
  resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
2526
2421
 
@@ -4527,8 +4422,6 @@ snapshots:
4527
4422
 
4528
4423
  '@csstools/css-tokenizer@3.0.4': {}
4529
4424
 
4530
- '@drizzle-team/brocli@0.10.2': {}
4531
-
4532
4425
  '@emnapi/runtime@1.7.1':
4533
4426
  dependencies:
4534
4427
  tslib: 2.8.1
@@ -6254,22 +6147,6 @@ snapshots:
6254
6147
 
6255
6148
  dom-accessibility-api@0.6.3: {}
6256
6149
 
6257
- drizzle-kit@0.31.8:
6258
- dependencies:
6259
- '@drizzle-team/brocli': 0.10.2
6260
- '@esbuild-kit/esm-loader': 2.6.5
6261
- esbuild: 0.25.12
6262
- esbuild-register: 3.6.0(esbuild@0.25.12)
6263
- transitivePeerDependencies:
6264
- - supports-color
6265
-
6266
- drizzle-orm@0.45.1(@cloudflare/workers-types@4.20260101.0)(@types/better-sqlite3@7.6.13)(better-sqlite3@12.5.0)(gel@2.2.0):
6267
- optionalDependencies:
6268
- '@cloudflare/workers-types': 4.20260101.0
6269
- '@types/better-sqlite3': 7.6.13
6270
- better-sqlite3: 12.5.0
6271
- gel: 2.2.0
6272
-
6273
6150
  eastasianwidth@0.2.0: {}
6274
6151
 
6275
6152
  electron-to-chromium@1.5.267: {}
@@ -0,0 +1,84 @@
1
+ -- schema.sql
2
+ -- Source of truth for the D1 (SQLite) schema.
3
+ -- Apply locally:
4
+ -- wrangler --config config/wrangler.json d1 execute <db-name> --local --file=schema.sql
5
+ -- Apply remotely:
6
+ -- wrangler --config config/wrangler.json d1 execute <db-name> --remote --file=schema.sql
7
+
8
+ PRAGMA foreign_keys = ON;
9
+
10
+ -- Users table
11
+ CREATE TABLE IF NOT EXISTS users (
12
+ id TEXT PRIMARY KEY,
13
+ google_id TEXT NOT NULL UNIQUE,
14
+ email TEXT NOT NULL,
15
+ name TEXT NOT NULL,
16
+ avatar_url TEXT,
17
+ status TEXT DEFAULT 'active' NOT NULL CHECK (status IN ('active', 'inactive')),
18
+ provider_ids TEXT DEFAULT '[]',
19
+ is_super_admin INTEGER DEFAULT 0 NOT NULL,
20
+ created_at TEXT DEFAULT (datetime('now')) NOT NULL,
21
+ updated_at TEXT DEFAULT (datetime('now')) NOT NULL,
22
+ deleted_at TEXT,
23
+ created_by_id TEXT REFERENCES users(id),
24
+ updated_by_id TEXT REFERENCES users(id),
25
+ deleted_by_id TEXT REFERENCES users(id)
26
+ );
27
+
28
+ -- Accounts table
29
+ CREATE TABLE IF NOT EXISTS accounts (
30
+ id TEXT PRIMARY KEY,
31
+ name TEXT NOT NULL,
32
+ description TEXT,
33
+ domain TEXT UNIQUE,
34
+ created_at TEXT DEFAULT (datetime('now')) NOT NULL,
35
+ updated_at TEXT DEFAULT (datetime('now')) NOT NULL,
36
+ deleted_at TEXT
37
+ );
38
+
39
+ -- User-Accounts junction table
40
+ CREATE TABLE IF NOT EXISTS user_accounts (
41
+ user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
42
+ account_id TEXT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
43
+ role TEXT NOT NULL CHECK (role IN ('ADMIN', 'MANAGER', 'EDITOR', 'AUTHOR', 'VIEWER', 'BILLING', 'ANALYTICS')),
44
+ PRIMARY KEY (user_id, account_id)
45
+ );
46
+
47
+ -- Refresh tokens table
48
+ CREATE TABLE IF NOT EXISTS refresh_tokens (
49
+ id TEXT PRIMARY KEY,
50
+ user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
51
+ token_hash TEXT NOT NULL,
52
+ expires_at INTEGER NOT NULL,
53
+ created_at INTEGER DEFAULT (unixepoch()) NOT NULL,
54
+ revoked_at INTEGER
55
+ );
56
+
57
+ -- Invitations table
58
+ CREATE TABLE IF NOT EXISTS invitations (
59
+ id TEXT PRIMARY KEY,
60
+ account_id TEXT NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
61
+ email TEXT NOT NULL,
62
+ role TEXT NOT NULL CHECK (role IN ('ADMIN', 'MANAGER', 'EDITOR', 'AUTHOR', 'VIEWER', 'BILLING', 'ANALYTICS')),
63
+ token TEXT NOT NULL UNIQUE,
64
+ invited_by_id TEXT NOT NULL REFERENCES users(id),
65
+ expires_at TEXT NOT NULL,
66
+ accepted_at TEXT,
67
+ created_at TEXT DEFAULT (datetime('now')) NOT NULL
68
+ );
69
+ CREATE UNIQUE INDEX IF NOT EXISTS account_email_idx ON invitations(account_id, email);
70
+
71
+ -- Audit logs table
72
+ CREATE TABLE IF NOT EXISTS audit_logs (
73
+ id TEXT PRIMARY KEY,
74
+ transaction_id TEXT NOT NULL,
75
+ account_id TEXT REFERENCES accounts(id),
76
+ user_id TEXT REFERENCES users(id),
77
+ entity TEXT NOT NULL,
78
+ entity_id TEXT NOT NULL,
79
+ action TEXT NOT NULL CHECK (action IN ('INSERT', 'UPDATE', 'DELETE', 'LOGIN', 'LOGOUT', 'SIGNUP', 'TOKEN_REFRESH', 'LOGIN_FAILED')),
80
+ changes TEXT,
81
+ ip_address TEXT,
82
+ user_agent TEXT,
83
+ timestamp TEXT DEFAULT (datetime('now')) NOT NULL
84
+ );