@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
@@ -1,6 +1,6 @@
1
- // src/server/__tests__/fixtures.ts
2
- import type { User, Account, SessionData } from '../types'
3
- import type { Role } from '../auth/roles'
1
+ // tests/fixtures/server.ts
2
+ import type { User, Account, SessionData } from '@server/types'
3
+ import type { Role } from '@server/auth/roles'
4
4
 
5
5
  /**
6
6
  * Counter for generating unique IDs
@@ -1,7 +1,7 @@
1
- // src/client/__tests__/setup-browser.ts
1
+ // tests/helpers/client-setup-browser.ts
2
2
  // Setup file for Vitest Browser Mode (real browser, no mocks needed)
3
3
  import "@testing-library/jest-dom/vitest"
4
- import "../../test/vitest-zod-matcher"
4
+ import "../../src/test/vitest-zod-matcher"
5
5
  import { cleanup } from "@testing-library/react"
6
6
  import { afterEach, vi } from "vitest"
7
7
 
@@ -1,5 +1,5 @@
1
1
  import "@testing-library/jest-dom/vitest"
2
- import "../../test/vitest-zod-matcher"
2
+ import "../../src/test/vitest-zod-matcher"
3
3
  import { cleanup } from "@testing-library/react"
4
4
  import { afterEach, vi } from "vitest"
5
5
 
@@ -6,8 +6,8 @@ import {
6
6
  createMemoryHistory,
7
7
  createRouter,
8
8
  } from "@tanstack/react-router"
9
- import { routeTree } from "../routeTree.gen"
10
- import { ThemeProvider } from "../hooks/use-theme"
9
+ import { routeTree } from "@/routeTree.gen"
10
+ import { ThemeProvider } from "@/hooks/use-theme"
11
11
  import type { ReactElement, ReactNode } from "react"
12
12
 
13
13
  // Create a fresh QueryClient for each test
@@ -1,20 +1,20 @@
1
- // src/server/__tests__/setup.ts
1
+ // tests/helpers/server.ts
2
2
  import { vi, beforeEach, afterEach } from 'vitest'
3
- import type { Env } from '../env'
4
- import type { SessionData } from '../types'
5
- import { createMockD1, createMockD1AsD1Database, type MockD1Database } from './mocks/db'
3
+ import type { Env } from '@server/env'
4
+ import type { SessionData } from '@server/types'
5
+ import { createMockD1, createMockD1AsD1Database, type MockD1Database } from '@tests/mocks/db'
6
6
  import {
7
7
  createMockKV,
8
8
  createMockKVAsKVNamespace,
9
9
  seedMockKV,
10
10
  type MockKVNamespace,
11
- } from './mocks/kv'
12
- import { createMockR2, createMockR2AsR2Bucket, type MockR2Bucket } from './mocks/r2'
11
+ } from '@tests/mocks/kv'
12
+ import { createMockR2, createMockR2AsR2Bucket, type MockR2Bucket } from '@tests/mocks/r2'
13
13
 
14
14
  // Re-export mocks for convenience
15
- export * from './mocks/db'
16
- export * from './mocks/kv'
17
- export * from './mocks/r2'
15
+ export * from '@tests/mocks/db'
16
+ export * from '@tests/mocks/kv'
17
+ export * from '@tests/mocks/r2'
18
18
 
19
19
  /**
20
20
  * Default environment configuration for tests
@@ -30,19 +30,10 @@ import { errorHandler } from '../../../src/server/middleware/error-handler'
30
30
  import { sessionMiddleware } from '../../../src/server/lib/session'
31
31
 
32
32
  /**
33
- * Creates a database wrapper that adds the `execute` method
34
- * The better-sqlite3 drizzle doesn't have execute, but D1 does
33
+ * Creates a D1-compatible database instance for tests
35
34
  */
36
35
  function createTestDb() {
37
- const db = getDb()
38
- return new Proxy(db, {
39
- get(target, prop) {
40
- if (prop === 'execute') {
41
- return target.run.bind(target)
42
- }
43
- return (target as any)[prop]
44
- },
45
- })
36
+ return getDb()
46
37
  }
47
38
 
48
39
  describe('Accounts CRUD Integration', () => {
@@ -22,19 +22,10 @@ import { errorHandler } from '../../../src/server/middleware/error-handler'
22
22
  import { sessionMiddleware } from '../../../src/server/lib/session'
23
23
 
24
24
  /**
25
- * Creates a database wrapper that adds the `execute` method
26
- * The better-sqlite3 drizzle doesn't have execute, but D1 does
25
+ * Creates a D1-compatible database instance for tests
27
26
  */
28
27
  function createTestDb() {
29
- const db = getDb()
30
- return new Proxy(db, {
31
- get(target, prop) {
32
- if (prop === 'execute') {
33
- return target.run.bind(target)
34
- }
35
- return (target as any)[prop]
36
- },
37
- })
28
+ return getDb()
38
29
  }
39
30
 
40
31
  /**
@@ -15,21 +15,12 @@ import { createUser } from '../fixtures'
15
15
  import { authService } from '../../../src/server/services/auth'
16
16
  import { generateRefreshToken, hashToken } from '../../../src/server/lib/tokens'
17
17
  import type { GoogleUserInfo, AuthEventContext } from '../../../src/server/types/auth'
18
- import * as schema from '../../../src/server/db/schema'
19
18
 
20
19
  /**
21
20
  * Creates a database wrapper
22
21
  */
23
22
  function createTestDb() {
24
- const db = getDb()
25
- return new Proxy(db, {
26
- get(target, prop) {
27
- if (prop === 'execute') {
28
- return target.run.bind(target)
29
- }
30
- return (target as any)[prop]
31
- },
32
- }) as any
23
+ return getDb()
33
24
  }
34
25
 
35
26
  describe('Auth Service Integration', () => {
@@ -34,19 +34,10 @@ import { sessionMiddleware } from '../../../src/server/lib/session'
34
34
  import { errorHandler } from '../../../src/server/middleware/error-handler'
35
35
 
36
36
  /**
37
- * Creates a database wrapper that adds the `execute` method
38
- * The better-sqlite3 drizzle doesn't have execute, but D1 does
37
+ * Creates a D1-compatible database instance for tests
39
38
  */
40
39
  function createTestDb() {
41
- const db = getDb()
42
- return new Proxy(db, {
43
- get(target, prop) {
44
- if (prop === 'execute') {
45
- return target.run.bind(target)
46
- }
47
- return (target as any)[prop]
48
- },
49
- })
40
+ return getDb()
50
41
  }
51
42
 
52
43
  describe('Invitation Token Authentication Integration', () => {
@@ -24,19 +24,10 @@ import { sessionMiddleware } from '../../../src/server/lib/session'
24
24
  import { errorHandler } from '../../../src/server/middleware/error-handler'
25
25
 
26
26
  /**
27
- * Creates a database wrapper that adds the `execute` method
28
- * The better-sqlite3 drizzle doesn't have execute, but D1 does
27
+ * Creates a D1-compatible database instance for tests
29
28
  */
30
29
  function createTestDb() {
31
- const db = getDb()
32
- return new Proxy(db, {
33
- get(target, prop) {
34
- if (prop === 'execute') {
35
- return target.run.bind(target)
36
- }
37
- return (target as any)[prop]
38
- },
39
- })
30
+ return getDb()
40
31
  }
41
32
 
42
33
  describe('Logout Integration', () => {
@@ -9,15 +9,13 @@
9
9
 
10
10
  import { describe, it, expect, beforeAll, vi, beforeEach } from 'vitest'
11
11
  import { Hono } from 'hono'
12
- import { eq } from 'drizzle-orm'
13
- import { getEnv, getDb, getKV, type TestEnv } from '../setup'
12
+ import { getEnv, getDb, getKV, getSqlite, type TestEnv } from '../setup'
14
13
  import { createUser, createUserSession } from '../fixtures'
15
14
  import type { HonoEnv } from '../../../src/server/types'
16
15
  import { auth } from '../../../src/server/routes/auth'
17
16
  import { sessionMiddleware } from '../../../src/server/lib/session'
18
17
  import { errorHandler } from '../../../src/server/middleware/error-handler'
19
18
  import { createAccount, addUserToAccount } from '../fixtures'
20
- import { users } from '../../../src/server/db/schema'
21
19
 
22
20
  // Mock ID token for testing (base64url encoded)
23
21
  function createMockIdToken(payload: Record<string, unknown>): string {
@@ -32,15 +30,7 @@ function createMockIdToken(payload: Record<string, unknown>): string {
32
30
  * Creates a database wrapper that adds the `execute` method
33
31
  */
34
32
  function createTestDb() {
35
- const db = getDb()
36
- return new Proxy(db, {
37
- get(target, prop) {
38
- if (prop === 'execute') {
39
- return target.run.bind(target)
40
- }
41
- return (target as any)[prop]
42
- },
43
- })
33
+ return getDb()
44
34
  }
45
35
 
46
36
  describe('OAuth Authentication Integration', () => {
@@ -353,16 +343,14 @@ describe('OAuth Authentication Integration', () => {
353
343
  expect(res.status).toBe(302)
354
344
 
355
345
  // Verify user was updated in database
356
- const db = createTestDb()
357
- const result = await (db as any)
358
- .select()
359
- .from(users)
360
- .where(eq(users.id, existingUser.id))
361
- .limit(1)
346
+ const sqlite = getSqlite()
347
+ const result = sqlite.prepare(
348
+ 'SELECT name, email, avatar_url as avatarUrl FROM users WHERE id = ?'
349
+ ).get(existingUser.id) as { name: string; email: string; avatarUrl: string } | undefined
362
350
 
363
- expect(result[0].name).toBe('New Updated Name')
364
- expect(result[0].email).toBe('newemail@gmail.com')
365
- expect(result[0].avatarUrl).toBe('https://new-avatar.jpg')
351
+ expect(result?.name).toBe('New Updated Name')
352
+ expect(result?.email).toBe('newemail@gmail.com')
353
+ expect(result?.avatarUrl).toBe('https://new-avatar.jpg')
366
354
 
367
355
  globalThis.fetch = originalFetch
368
356
  })
@@ -374,18 +362,16 @@ describe('OAuth Authentication Integration', () => {
374
362
  await addUserToAccount(inviter.id, account.id, 'ADMIN')
375
363
 
376
364
  // Create an invitation in the database
377
- const db = createTestDb()
365
+ const sqlite = getSqlite()
378
366
  const invitationId = crypto.randomUUID()
379
367
  const invitationToken = crypto.randomUUID()
380
368
  const expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString()
381
369
  const inviteeEmail = `pending-invitee-${crypto.randomUUID().slice(0, 8)}@gmail.com`
382
370
 
383
- ;(db as any).run(
384
- require('drizzle-orm').sql`
385
- INSERT INTO invitations (id, account_id, email, role, token, invited_by_id, expires_at)
386
- VALUES (${invitationId}, ${account.id}, ${inviteeEmail}, ${'EDITOR'}, ${invitationToken}, ${inviter.id}, ${expiresAt})
387
- `
388
- )
371
+ sqlite.prepare(
372
+ `INSERT INTO invitations (id, account_id, email, role, token, invited_by_id, expires_at)
373
+ VALUES (?, ?, ?, ?, ?, ?, ?)`
374
+ ).run(invitationId, account.id, inviteeEmail, 'EDITOR', invitationToken, inviter.id, expiresAt)
389
375
 
390
376
  // Mock Google OAuth response
391
377
  const mockIdToken = createMockIdToken({
@@ -433,14 +419,11 @@ describe('OAuth Authentication Integration', () => {
433
419
  expect(location).toContain('/dashboard')
434
420
 
435
421
  // Verify the invitation was accepted (accepted_at should be set)
436
- const { invitations } = await import('../../../src/server/db/schema')
437
- const invitationResult = await (db as any)
438
- .select()
439
- .from(invitations)
440
- .where(eq(invitations.id, invitationId))
441
- .limit(1)
422
+ const invitationResult = sqlite.prepare(
423
+ 'SELECT accepted_at as acceptedAt FROM invitations WHERE id = ?'
424
+ ).get(invitationId) as { acceptedAt: string | null } | undefined
442
425
 
443
- expect(invitationResult[0].acceptedAt).not.toBeNull()
426
+ expect(invitationResult?.acceptedAt).not.toBeNull()
444
427
 
445
428
  globalThis.fetch = originalFetch
446
429
  })
@@ -567,17 +550,15 @@ describe('OAuth Authentication Integration', () => {
567
550
  await addUserToAccount(inviter.id, account.id, 'ADMIN')
568
551
 
569
552
  // Create invitation directly in the database
570
- const db = createTestDb()
553
+ const sqlite = getSqlite()
571
554
  const invitationId = crypto.randomUUID()
572
555
  const token = crypto.randomUUID()
573
556
  const expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString()
574
557
 
575
- ;(db as any).run(
576
- require('drizzle-orm').sql`
577
- INSERT INTO invitations (id, account_id, email, role, token, invited_by_id, expires_at)
578
- VALUES (${invitationId}, ${account.id}, ${'invitee@example.com'}, ${'EDITOR'}, ${token}, ${inviter.id}, ${expiresAt})
579
- `
580
- )
558
+ sqlite.prepare(
559
+ `INSERT INTO invitations (id, account_id, email, role, token, invited_by_id, expires_at)
560
+ VALUES (?, ?, ?, ?, ?, ?, ?)`
561
+ ).run(invitationId, account.id, 'invitee@example.com', 'EDITOR', token, inviter.id, expiresAt)
581
562
 
582
563
  const res = await app.request(`/auth/invite/${token}`, {
583
564
  method: 'GET',
@@ -22,15 +22,7 @@ import { hashToken, generateRefreshToken, getRefreshTokenExpiry } from '../../..
22
22
  * Creates a database wrapper
23
23
  */
24
24
  function createTestDb() {
25
- const db = getDb()
26
- return new Proxy(db, {
27
- get(target, prop) {
28
- if (prop === 'execute') {
29
- return target.run.bind(target)
30
- }
31
- return (target as any)[prop]
32
- },
33
- })
25
+ return getDb()
34
26
  }
35
27
 
36
28
  describe('Refresh Token Integration', () => {
@@ -23,15 +23,7 @@ import { hashToken, generateRefreshToken } from '../../../src/server/lib/tokens'
23
23
  // ============================================================================
24
24
 
25
25
  function createTestDb() {
26
- const db = getDb()
27
- return new Proxy(db, {
28
- get(target, prop) {
29
- if (prop === 'execute') {
30
- return target.run.bind(target)
31
- }
32
- return (target as any)[prop]
33
- },
34
- })
26
+ return getDb()
35
27
  }
36
28
 
37
29
  describe('Session Expiry Integration Tests', () => {
@@ -24,19 +24,10 @@ import { sessionMiddleware } from '../../../src/server/lib/session'
24
24
  import { errorHandler } from '../../../src/server/middleware/error-handler'
25
25
 
26
26
  /**
27
- * Creates a database wrapper that adds the `execute` method
28
- * The better-sqlite3 drizzle doesn't have execute, but D1 does
27
+ * Creates a D1-compatible database instance for tests
29
28
  */
30
29
  function createTestDb() {
31
- const db = getDb()
32
- return new Proxy(db, {
33
- get(target, prop) {
34
- if (prop === 'execute') {
35
- return target.run.bind(target)
36
- }
37
- return (target as any)[prop]
38
- },
39
- })
30
+ return getDb()
40
31
  }
41
32
 
42
33
  describe('Session Authentication Integration', () => {
@@ -30,15 +30,7 @@ import { isSuperAdminEmail } from '../../../src/server/env'
30
30
  // ============================================================================
31
31
 
32
32
  function createTestDb() {
33
- const db = getDb()
34
- return new Proxy(db, {
35
- get(target, prop) {
36
- if (prop === 'execute') {
37
- return target.run.bind(target)
38
- }
39
- return (target as any)[prop]
40
- },
41
- })
33
+ return getDb()
42
34
  }
43
35
 
44
36
  describe('Super Admin Integration Tests', () => {
@@ -38,19 +38,10 @@ import { hasMinimumRole, isHierarchicalRole, ROLE_HIERARCHY } from '../../../src
38
38
  // ============================================================================
39
39
 
40
40
  /**
41
- * Creates a database wrapper that adds the `execute` method
42
- * The better-sqlite3 drizzle doesn't have execute, but D1 does
41
+ * Creates a D1-compatible database instance for tests
43
42
  */
44
43
  function createTestDb() {
45
- const db = getDb()
46
- return new Proxy(db, {
47
- get(target, prop) {
48
- if (prop === 'execute') {
49
- return target.run.bind(target)
50
- }
51
- return (target as any)[prop]
52
- },
53
- })
44
+ return getDb()
54
45
  }
55
46
 
56
47
  /**
@@ -38,19 +38,10 @@ import { hasMinimumRole, isHierarchicalRole, ROLE_HIERARCHY } from '../../../src
38
38
  // ============================================================================
39
39
 
40
40
  /**
41
- * Creates a database wrapper that adds the `execute` method
42
- * The better-sqlite3 drizzle doesn't have execute, but D1 does
41
+ * Creates a D1-compatible database instance for tests
43
42
  */
44
43
  function createTestDb() {
45
- const db = getDb()
46
- return new Proxy(db, {
47
- get(target, prop) {
48
- if (prop === 'execute') {
49
- return target.run.bind(target)
50
- }
51
- return (target as any)[prop]
52
- },
53
- })
44
+ return getDb()
54
45
  }
55
46
 
56
47
  /**
@@ -40,15 +40,7 @@ import {
40
40
  * Creates a database wrapper
41
41
  */
42
42
  function createTestDb() {
43
- const db = getDb()
44
- return new Proxy(db, {
45
- get(target, prop) {
46
- if (prop === 'execute') {
47
- return target.run.bind(target)
48
- }
49
- return (target as any)[prop]
50
- },
51
- })
43
+ return getDb()
52
44
  }
53
45
 
54
46
  describe('Role Utility Functions', () => {
@@ -35,19 +35,10 @@ import { sessionMiddleware } from '../../../src/server/lib/session'
35
35
  // ============================================================================
36
36
 
37
37
  /**
38
- * Creates a database wrapper that adds the `execute` method
39
- * The better-sqlite3 drizzle doesn't have execute, but D1 does
38
+ * Creates a D1-compatible database instance for tests
40
39
  */
41
40
  function createTestDb() {
42
- const db = getDb()
43
- return new Proxy(db, {
44
- get(target, prop) {
45
- if (prop === 'execute') {
46
- return target.run.bind(target)
47
- }
48
- return (target as any)[prop]
49
- },
50
- })
41
+ return getDb()
51
42
  }
52
43
 
53
44
  /**
@@ -49,19 +49,10 @@ import { sessionMiddleware } from '../../../src/server/lib/session'
49
49
  // ============================================================================
50
50
 
51
51
  /**
52
- * Creates a database wrapper that adds the `execute` method
53
- * The better-sqlite3 drizzle doesn't have execute, but D1 does
52
+ * Creates a D1-compatible database instance for tests
54
53
  */
55
54
  function createTestDb() {
56
- const db = getDb()
57
- return new Proxy(db, {
58
- get(target, prop) {
59
- if (prop === 'execute') {
60
- return target.run.bind(target)
61
- }
62
- return (target as any)[prop]
63
- },
64
- })
55
+ return getDb()
65
56
  }
66
57
 
67
58
  /**
@@ -22,19 +22,10 @@ import { secureHeaders } from 'hono/secure-headers'
22
22
  import { uuidv7 } from 'uuidv7'
23
23
 
24
24
  /**
25
- * Creates a database wrapper that adds the `execute` method
26
- * The better-sqlite3 drizzle doesn't have execute, but D1 does
25
+ * Creates a D1-compatible database instance for tests
27
26
  */
28
27
  function createTestDb() {
29
- const db = getDb()
30
- return new Proxy(db, {
31
- get(target, prop) {
32
- if (prop === 'execute') {
33
- return target.run.bind(target)
34
- }
35
- return (target as any)[prop]
36
- },
37
- })
28
+ return getDb()
38
29
  }
39
30
 
40
31
  /**
@@ -13,28 +13,10 @@
13
13
 
14
14
  import { describe, it, expect, beforeAll } from 'vitest'
15
15
  import { Hono } from 'hono'
16
- import { getEnv, getDb, type TestEnv } from '../setup'
16
+ import { getEnv, type TestEnv } from '../setup'
17
17
  import type { HonoEnv } from '../../../src/server/types'
18
18
  import { health } from '../../../src/server/routes/health'
19
19
 
20
- /**
21
- * Creates a database wrapper that adds the `execute` method
22
- * The better-sqlite3 drizzle doesn't have execute, but D1 does
23
- * We add it as an alias to `run` for test compatibility
24
- */
25
- function createTestDb() {
26
- const db = getDb()
27
- // Add execute method that delegates to run (both execute statements)
28
- return new Proxy(db, {
29
- get(target, prop) {
30
- if (prop === 'execute') {
31
- return target.run.bind(target)
32
- }
33
- return (target as any)[prop]
34
- },
35
- })
36
- }
37
-
38
20
  describe('Health Check Integration', () => {
39
21
  let app: Hono<HonoEnv>
40
22
  let env: TestEnv
@@ -47,11 +29,6 @@ describe('Health Check Integration', () => {
47
29
  app.use('*', async (c, next) => {
48
30
  // Inject environment bindings (cast to any to allow assignment)
49
31
  ;(c as any).env = env
50
-
51
- // Use a wrapped drizzle instance that has execute method for D1 compatibility
52
- const db = createTestDb()
53
- c.set('db', db)
54
-
55
32
  await next()
56
33
  })
57
34
 
@@ -225,8 +202,10 @@ describe('Health Check Integration', () => {
225
202
  // Create an app without db set
226
203
  const appWithoutDb = new Hono<HonoEnv>()
227
204
  appWithoutDb.use('*', async (c, next) => {
228
- ;(c as any).env = env
229
- // Note: NOT setting db to test line 9
205
+ const modifiedEnv = { ...env }
206
+ // @ts-expect-error - Removing DB to test database down
207
+ delete modifiedEnv.DB
208
+ ;(c as any).env = modifiedEnv
230
209
  await next()
231
210
  })
232
211
  appWithoutDb.route('/health', health)
@@ -247,7 +226,6 @@ describe('Health Check Integration', () => {
247
226
  // @ts-expect-error - Removing R2_BUCKET to test line 24
248
227
  delete modifiedEnv.R2_BUCKET
249
228
  ;(c as any).env = modifiedEnv
250
- c.set('db', createTestDb())
251
229
  await next()
252
230
  })
253
231
  appWithoutR2.route('/health', health)
@@ -264,14 +242,15 @@ describe('Health Check Integration', () => {
264
242
  // Create an app with a broken database
265
243
  const appWithBrokenDb = new Hono<HonoEnv>()
266
244
  appWithBrokenDb.use('*', async (c, next) => {
267
- ;(c as any).env = env
268
- // Create a mock db that throws on run()
269
- const brokenDb = {
270
- run: () => {
271
- throw new Error('Database connection failed')
272
- },
245
+ const modifiedEnv = {
246
+ ...env,
247
+ DB: {
248
+ prepare: () => {
249
+ throw new Error('Database connection failed')
250
+ },
251
+ } as D1Database,
273
252
  }
274
- c.set('db', brokenDb as any)
253
+ ;(c as any).env = modifiedEnv
275
254
  await next()
276
255
  })
277
256
  appWithBrokenDb.route('/health', health)
@@ -297,7 +276,6 @@ describe('Health Check Integration', () => {
297
276
  },
298
277
  }
299
278
  ;(c as any).env = modifiedEnv
300
- c.set('db', createTestDb())
301
279
  await next()
302
280
  })
303
281
  appWithBrokenR2.route('/health', health)
@@ -313,8 +291,10 @@ describe('Health Check Integration', () => {
313
291
  it('should return 503 when readiness check fails due to db being down', async () => {
314
292
  const appWithoutDb = new Hono<HonoEnv>()
315
293
  appWithoutDb.use('*', async (c, next) => {
316
- ;(c as any).env = env
317
- // Note: NOT setting db
294
+ const modifiedEnv = { ...env }
295
+ // @ts-expect-error - Removing DB to test database down
296
+ delete modifiedEnv.DB
297
+ ;(c as any).env = modifiedEnv
318
298
  await next()
319
299
  })
320
300
  appWithoutDb.route('/health', health)
@@ -329,14 +309,15 @@ describe('Health Check Integration', () => {
329
309
  it('should return 503 when readiness check throws an error', async () => {
330
310
  const appWithBrokenDb = new Hono<HonoEnv>()
331
311
  appWithBrokenDb.use('*', async (c, next) => {
332
- ;(c as any).env = env
333
- // Create a mock db that throws on run()
334
- const brokenDb = {
335
- run: () => {
336
- throw new Error('Database connection failed')
337
- },
312
+ const modifiedEnv = {
313
+ ...env,
314
+ DB: {
315
+ prepare: () => {
316
+ throw new Error('Database connection failed')
317
+ },
318
+ } as D1Database,
338
319
  }
339
- c.set('db', brokenDb as any)
320
+ ;(c as any).env = modifiedEnv
340
321
  await next()
341
322
  })
342
323
  appWithBrokenDb.route('/health', health)