@etus/bhono-app 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (688) hide show
  1. package/dist/cli.d.ts +13 -0
  2. package/dist/cli.js +46 -0
  3. package/dist/cli.js.map +1 -0
  4. package/dist/cli.test.d.ts +1 -0
  5. package/dist/cli.test.js +26 -0
  6. package/dist/cli.test.js.map +1 -0
  7. package/dist/generator.d.ts +14 -0
  8. package/dist/generator.js +142 -0
  9. package/dist/generator.js.map +1 -0
  10. package/dist/generator.test.d.ts +1 -0
  11. package/dist/generator.test.js +127 -0
  12. package/dist/generator.test.js.map +1 -0
  13. package/dist/index.d.ts +2 -0
  14. package/dist/index.js +97 -0
  15. package/dist/index.js.map +1 -0
  16. package/dist/prompts.d.ts +25 -0
  17. package/dist/prompts.js +83 -0
  18. package/dist/prompts.js.map +1 -0
  19. package/dist/prompts.test.d.ts +1 -0
  20. package/dist/prompts.test.js +24 -0
  21. package/dist/prompts.test.js.map +1 -0
  22. package/dist/providers/cloudflare.d.ts +37 -0
  23. package/dist/providers/cloudflare.js +61 -0
  24. package/dist/providers/cloudflare.js.map +1 -0
  25. package/dist/providers/cloudflare.test.d.ts +1 -0
  26. package/dist/providers/cloudflare.test.js +29 -0
  27. package/dist/providers/cloudflare.test.js.map +1 -0
  28. package/dist/providers/github.d.ts +16 -0
  29. package/dist/providers/github.js +57 -0
  30. package/dist/providers/github.js.map +1 -0
  31. package/dist/providers/github.test.d.ts +1 -0
  32. package/dist/providers/github.test.js +16 -0
  33. package/dist/providers/github.test.js.map +1 -0
  34. package/dist/templates.d.ts +8 -0
  35. package/dist/templates.js +88 -0
  36. package/dist/templates.js.map +1 -0
  37. package/dist/templates.test.d.ts +1 -0
  38. package/dist/templates.test.js +26 -0
  39. package/dist/templates.test.js.map +1 -0
  40. package/package.json +36 -0
  41. package/templates/base/.claude/agents/architect-review.md +160 -0
  42. package/templates/base/.claude/agents/backend-architect.md +308 -0
  43. package/templates/base/.claude/agents/code-reviewer.md +170 -0
  44. package/templates/base/.claude/agents/performance-engineer.md +166 -0
  45. package/templates/base/.claude/agents/test-automator.md +219 -0
  46. package/templates/base/.claude/commands/check-skill-rules.md +53 -0
  47. package/templates/base/.claude/commands/claude-md.md +250 -0
  48. package/templates/base/.claude/commands/code-prompt.md +212 -0
  49. package/templates/base/.claude/commands/explain-code.md +194 -0
  50. package/templates/base/.claude/commands/init-projec.md +89 -0
  51. package/templates/base/.claude/commands/linear/README.md +297 -0
  52. package/templates/base/.claude/commands/linear/create-issue.md +190 -0
  53. package/templates/base/.claude/commands/linear/implement-issue.md +248 -0
  54. package/templates/base/.claude/commands/linear/process-triage.md +399 -0
  55. package/templates/base/.claude/commands/linear/setup.md +180 -0
  56. package/templates/base/.claude/commands/prime.md +9 -0
  57. package/templates/base/.claude/commands/review-gap.md +10 -0
  58. package/templates/base/.claude/commands/setup-aa.md +311 -0
  59. package/templates/base/.claude/commands/ship.md +262 -0
  60. package/templates/base/.claude/commands/tools.md +3 -0
  61. package/templates/base/.claude/docs/claude-progress.txt +107 -0
  62. package/templates/base/.claude/hooks/package-lock.json +556 -0
  63. package/templates/base/.claude/hooks/package.json +16 -0
  64. package/templates/base/.claude/hooks/skill-activation-prompt.sh +7 -0
  65. package/templates/base/.claude/hooks/skill-activation-prompt.ts +142 -0
  66. package/templates/base/.claude/hooks/tsconfig.json +19 -0
  67. package/templates/base/.claude/scripts/check-updates.sh +85 -0
  68. package/templates/base/.claude/scripts/install_pkgs.sh +66 -0
  69. package/templates/base/.claude/scripts/setup-project.sh +177 -0
  70. package/templates/base/.claude/scripts/validate-skill-rules.sh +94 -0
  71. package/templates/base/.claude/settings.json +113 -0
  72. package/templates/base/.claude/settings.local.json +11 -0
  73. package/templates/base/.claude/skills/architecture-analyzer/SKILL.md +531 -0
  74. package/templates/base/.claude/skills/architecture-analyzer/assets/report-template.md +215 -0
  75. package/templates/base/.claude/skills/architecture-analyzer/references/c4-templates.md +234 -0
  76. package/templates/base/.claude/skills/architecture-analyzer/references/confidence-levels.md +203 -0
  77. package/templates/base/.claude/skills/architecture-analyzer/scripts/analyze_structure.py +266 -0
  78. package/templates/base/.claude/skills/architecture-analyzer/scripts/analyze_tech_debt.py +776 -0
  79. package/templates/base/.claude/skills/architecture-analyzer/scripts/extract_apis.py +338 -0
  80. package/templates/base/.claude/skills/architecture-analyzer/scripts/generate_c4.py +283 -0
  81. package/templates/base/.claude/skills/architecture-analyzer/scripts/generate_erd.py +935 -0
  82. package/templates/base/.claude/skills/architecture-analyzer/scripts/map_dependencies.py +555 -0
  83. package/templates/base/.claude/skills/dev-browser/SKILL.md +318 -0
  84. package/templates/base/.claude/skills/dev-browser/bun.lock +443 -0
  85. package/templates/base/.claude/skills/dev-browser/package-lock.json +2927 -0
  86. package/templates/base/.claude/skills/dev-browser/package.json +27 -0
  87. package/templates/base/.claude/skills/dev-browser/scripts/start-server.ts +117 -0
  88. package/templates/base/.claude/skills/dev-browser/server.sh +24 -0
  89. package/templates/base/.claude/skills/dev-browser/src/client.ts +403 -0
  90. package/templates/base/.claude/skills/dev-browser/src/index.ts +281 -0
  91. package/templates/base/.claude/skills/dev-browser/src/snapshot/__tests__/snapshot.test.ts +223 -0
  92. package/templates/base/.claude/skills/dev-browser/src/snapshot/browser-script.ts +877 -0
  93. package/templates/base/.claude/skills/dev-browser/src/snapshot/index.ts +14 -0
  94. package/templates/base/.claude/skills/dev-browser/src/snapshot/inject.ts +13 -0
  95. package/templates/base/.claude/skills/dev-browser/src/types.ts +27 -0
  96. package/templates/base/.claude/skills/dev-browser/tsconfig.json +36 -0
  97. package/templates/base/.claude/skills/dev-browser/vitest.config.ts +12 -0
  98. package/templates/base/.claude/skills/linear/SKILL.md +440 -0
  99. package/templates/base/.claude/skills/linear/examples.md +262 -0
  100. package/templates/base/.claude/skills/linear/lib/client.ts +51 -0
  101. package/templates/base/.claude/skills/linear/lib/config.ts +106 -0
  102. package/templates/base/.claude/skills/linear/lib/output.ts +34 -0
  103. package/templates/base/.claude/skills/linear/package-lock.json +698 -0
  104. package/templates/base/.claude/skills/linear/package.json +27 -0
  105. package/templates/base/.claude/skills/linear/reference.md +263 -0
  106. package/templates/base/.claude/skills/linear/scripts/comments/create.ts +47 -0
  107. package/templates/base/.claude/skills/linear/scripts/comments/list.ts +47 -0
  108. package/templates/base/.claude/skills/linear/scripts/issues/archive.ts +30 -0
  109. package/templates/base/.claude/skills/linear/scripts/issues/create.ts +279 -0
  110. package/templates/base/.claude/skills/linear/scripts/issues/get.ts +68 -0
  111. package/templates/base/.claude/skills/linear/scripts/issues/list.ts +67 -0
  112. package/templates/base/.claude/skills/linear/scripts/issues/update.ts +281 -0
  113. package/templates/base/.claude/skills/linear/scripts/labels/add-to-issue.ts +63 -0
  114. package/templates/base/.claude/skills/linear/scripts/labels/create.ts +45 -0
  115. package/templates/base/.claude/skills/linear/scripts/labels/list.ts +30 -0
  116. package/templates/base/.claude/skills/linear/scripts/list-teams.ts +52 -0
  117. package/templates/base/.claude/skills/linear/scripts/setup/setup-credentials.ts +96 -0
  118. package/templates/base/.claude/skills/linear/scripts/status/list.ts +31 -0
  119. package/templates/base/.claude/skills/linear/scripts/status/set-by-name.ts +78 -0
  120. package/templates/base/.claude/skills/linear/scripts/status/update.ts +44 -0
  121. package/templates/base/.claude/skills/linear/scripts/users/list.ts +59 -0
  122. package/templates/base/.claude/skills/linear/scripts/users/me.ts +20 -0
  123. package/templates/base/.claude/skills/linear/templates/README.md +203 -0
  124. package/templates/base/.claude/skills/linear/templates/api-reference.md +258 -0
  125. package/templates/base/.claude/skills/linear/templates/bug-report.md +99 -0
  126. package/templates/base/.claude/skills/linear/templates/feature-request.md +118 -0
  127. package/templates/base/.claude/skills/linear/templates/security-issue.md +162 -0
  128. package/templates/base/.claude/skills/linear/templates/sprint-task.md +175 -0
  129. package/templates/base/.claude/skills/linear/templates/tech-debt.md +137 -0
  130. package/templates/base/.claude/skills/linear/tsconfig.json +17 -0
  131. package/templates/base/.claude/skills/linear/workflows/issue-lifecycle.md +317 -0
  132. package/templates/base/.claude/skills/playwright-e2e-testing/SKILL.md +113 -0
  133. package/templates/base/.claude/skills/playwright-e2e-testing/assets/global-setup.template.js +97 -0
  134. package/templates/base/.claude/skills/playwright-e2e-testing/assets/playwright.config.template.js +171 -0
  135. package/templates/base/.claude/skills/playwright-e2e-testing/assets/test-template.spec.js +163 -0
  136. package/templates/base/.claude/skills/playwright-e2e-testing/examples/README.md +26 -0
  137. package/templates/base/.claude/skills/playwright-e2e-testing/examples/ads.email-deeplink.spec.ts +12 -0
  138. package/templates/base/.claude/skills/playwright-e2e-testing/examples/mobile.realism.spec.ts +16 -0
  139. package/templates/base/.claude/skills/playwright-e2e-testing/examples/smoke.home.spec.ts +6 -0
  140. package/templates/base/.claude/skills/playwright-e2e-testing/references/architecture.md +578 -0
  141. package/templates/base/.claude/skills/playwright-e2e-testing/references/best-practices.md +260 -0
  142. package/templates/base/.claude/skills/playwright-e2e-testing/references/ci-reporting.md +86 -0
  143. package/templates/base/.claude/skills/playwright-e2e-testing/references/debugging.md +629 -0
  144. package/templates/base/.claude/skills/playwright-e2e-testing/references/mobile-realism.md +50 -0
  145. package/templates/base/.claude/skills/playwright-e2e-testing/references/optimization.md +488 -0
  146. package/templates/base/.claude/skills/playwright-e2e-testing/references/patterns.md +513 -0
  147. package/templates/base/.claude/skills/playwright-e2e-testing/references/resources.md +44 -0
  148. package/templates/base/.claude/skills/playwright-e2e-testing/references/visual-a11y.md +66 -0
  149. package/templates/base/.claude/skills/playwright-e2e-testing/scripts/auth-setup.js +202 -0
  150. package/templates/base/.claude/skills/playwright-e2e-testing/scripts/performance-analyzer.js +240 -0
  151. package/templates/base/.claude/skills/playwright-e2e-testing/scripts/trace-url.js +132 -0
  152. package/templates/base/.claude/skills/playwright-e2e-testing/templates/ci/github-actions.playwright.yml +78 -0
  153. package/templates/base/.claude/skills/playwright-e2e-testing/templates/fixtures.ts +44 -0
  154. package/templates/base/.claude/skills/playwright-e2e-testing/templates/global-setup.template.js +97 -0
  155. package/templates/base/.claude/skills/playwright-e2e-testing/templates/global.setup.ts +35 -0
  156. package/templates/base/.claude/skills/playwright-e2e-testing/templates/helpers/ad-gpt-observer.ts +80 -0
  157. package/templates/base/.claude/skills/playwright-e2e-testing/templates/helpers/chromium-mobile-profile.ts +93 -0
  158. package/templates/base/.claude/skills/playwright-e2e-testing/templates/playwright.config.template.js +171 -0
  159. package/templates/base/.claude/skills/playwright-e2e-testing/templates/playwright.config.ts +126 -0
  160. package/templates/base/.claude/skills/playwright-e2e-testing/templates/test-template.spec.js +163 -0
  161. package/templates/base/.claude/skills/playwright-e2e-testing/templates/tests/email-deeplink.ads.spec.ts +44 -0
  162. package/templates/base/.claude/skills/skill-rules.json +184 -0
  163. package/templates/base/.claude/skills/wrangler/SKILL.md +209 -0
  164. package/templates/base/.claude/skills/wrangler/resources/api.md +494 -0
  165. package/templates/base/.claude/skills/wrangler/resources/bundling.md +83 -0
  166. package/templates/base/.claude/skills/wrangler/resources/commands/cert.md +64 -0
  167. package/templates/base/.claude/skills/wrangler/resources/commands/check.md +66 -0
  168. package/templates/base/.claude/skills/wrangler/resources/commands/containers.md +157 -0
  169. package/templates/base/.claude/skills/wrangler/resources/commands/d1.md +843 -0
  170. package/templates/base/.claude/skills/wrangler/resources/commands/delete.md +27 -0
  171. package/templates/base/.claude/skills/wrangler/resources/commands/deploy.md +139 -0
  172. package/templates/base/.claude/skills/wrangler/resources/commands/deployments.md +56 -0
  173. package/templates/base/.claude/skills/wrangler/resources/commands/dev.md +157 -0
  174. package/templates/base/.claude/skills/wrangler/resources/commands/dispatch-namespace.md +69 -0
  175. package/templates/base/.claude/skills/wrangler/resources/commands/docs.md +61 -0
  176. package/templates/base/.claude/skills/wrangler/resources/commands/how-to-run.md +62 -0
  177. package/templates/base/.claude/skills/wrangler/resources/commands/hyperdrive.md +425 -0
  178. package/templates/base/.claude/skills/wrangler/resources/commands/init.md +31 -0
  179. package/templates/base/.claude/skills/wrangler/resources/commands/kv-bulk.md +265 -0
  180. package/templates/base/.claude/skills/wrangler/resources/commands/kv-key.md +353 -0
  181. package/templates/base/.claude/skills/wrangler/resources/commands/kv-namespace.md +265 -0
  182. package/templates/base/.claude/skills/wrangler/resources/commands/login.md +23 -0
  183. package/templates/base/.claude/skills/wrangler/resources/commands/logout.md +19 -0
  184. package/templates/base/.claude/skills/wrangler/resources/commands/mtls-certificate.md +69 -0
  185. package/templates/base/.claude/skills/wrangler/resources/commands/pages.md +175 -0
  186. package/templates/base/.claude/skills/wrangler/resources/commands/pipelines.md +76 -0
  187. package/templates/base/.claude/skills/wrangler/resources/commands/queues.md +132 -0
  188. package/templates/base/.claude/skills/wrangler/resources/commands/r2-bucket.md +342 -0
  189. package/templates/base/.claude/skills/wrangler/resources/commands/r2-object.md +267 -0
  190. package/templates/base/.claude/skills/wrangler/resources/commands/r2-sql.md +65 -0
  191. package/templates/base/.claude/skills/wrangler/resources/commands/rollback.md +40 -0
  192. package/templates/base/.claude/skills/wrangler/resources/commands/secret.md +308 -0
  193. package/templates/base/.claude/skills/wrangler/resources/commands/secrets-store-secret.md +100 -0
  194. package/templates/base/.claude/skills/wrangler/resources/commands/secrets-store-store.md +60 -0
  195. package/templates/base/.claude/skills/wrangler/resources/commands/setup.md +67 -0
  196. package/templates/base/.claude/skills/wrangler/resources/commands/tail.md +37 -0
  197. package/templates/base/.claude/skills/wrangler/resources/commands/telemetry.md +64 -0
  198. package/templates/base/.claude/skills/wrangler/resources/commands/triggers.md +39 -0
  199. package/templates/base/.claude/skills/wrangler/resources/commands/types.md +73 -0
  200. package/templates/base/.claude/skills/wrangler/resources/commands/vectorize.md +941 -0
  201. package/templates/base/.claude/skills/wrangler/resources/commands/versions.md +95 -0
  202. package/templates/base/.claude/skills/wrangler/resources/commands/whoami.md +49 -0
  203. package/templates/base/.claude/skills/wrangler/resources/commands/workflows.md +117 -0
  204. package/templates/base/.claude/skills/wrangler/resources/commands.md +138 -0
  205. package/templates/base/.claude/skills/wrangler/resources/configuration.md +2176 -0
  206. package/templates/base/.claude/skills/wrangler/resources/custom-builds.md +55 -0
  207. package/templates/base/.claude/skills/wrangler/resources/deprecations.md +279 -0
  208. package/templates/base/.claude/skills/wrangler/resources/enviroments.md +416 -0
  209. package/templates/base/.claude/skills/wrangler/resources/extract_sections.py +119 -0
  210. package/templates/base/.claude/skills/wrangler/resources/process_content.py +94 -0
  211. package/templates/base/.claude/skills/wrangler/resources/system-enviroments-variables.md +120 -0
  212. package/templates/base/.dev.vars.example +15 -0
  213. package/templates/base/.env.example +29 -0
  214. package/templates/base/.github/workflows/test.yml +127 -0
  215. package/templates/base/.nycrc.json +16 -0
  216. package/templates/base/CLAUDE.md +218 -0
  217. package/templates/base/README.md +670 -0
  218. package/templates/base/auth-setup-error.png +0 -0
  219. package/templates/base/config/drizzle.config.ts +10 -0
  220. package/templates/base/config/eslint.config.js +364 -0
  221. package/templates/base/config/wrangler.json +76 -0
  222. package/templates/base/docs/app_spec.txt +879 -0
  223. package/templates/base/docs/app_spec_template.md +681 -0
  224. package/templates/base/docs/architecture/README.md +8 -0
  225. package/templates/base/docs/architecture/data-requirements.md +109 -0
  226. package/templates/base/docs/architecture/erd.md +91 -0
  227. package/templates/base/docs/features/feature_list.json +3128 -0
  228. package/templates/base/docs/hono-boilerplate-plan.md +1774 -0
  229. package/templates/base/docs/test-coverage-gap-analysis.md +242 -0
  230. package/templates/base/docs/testing.md +188 -0
  231. package/templates/base/index.html +16 -0
  232. package/templates/base/package.json +115 -0
  233. package/templates/base/playwright.config.ts +158 -0
  234. package/templates/base/pnpm-lock.yaml +8175 -0
  235. package/templates/base/scripts/capture-prod-session.ts +250 -0
  236. package/templates/base/scripts/generate-openapi.ts +23 -0
  237. package/templates/base/scripts/init.sh +121 -0
  238. package/templates/base/src/client/__tests__/button.test.tsx +30 -0
  239. package/templates/base/src/client/__tests__/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-display-dashboard-stats-cards-1.png +0 -0
  240. package/templates/base/src/client/__tests__/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-display-quick-action-cards-1.png +0 -0
  241. package/templates/base/src/client/__tests__/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-display-recent-activity-section-1.png +0 -0
  242. package/templates/base/src/client/__tests__/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-display-user-first-name-in-welcome-message-1.png +0 -0
  243. package/templates/base/src/client/__tests__/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-display-user-information-in-sidebar-1.png +0 -0
  244. package/templates/base/src/client/__tests__/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-render-dashboard-when-authenticated-1.png +0 -0
  245. package/templates/base/src/client/__tests__/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-show-navigation-sidebar-1.png +0 -0
  246. package/templates/base/src/client/__tests__/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-unauthenticated-should-redirect-to-login-when-not-authenticated-1.png +0 -0
  247. package/templates/base/src/client/__tests__/routes/__screenshots__/login.test.tsx/Login-Page-should-display-Google-OAuth-login-button-1.png +0 -0
  248. package/templates/base/src/client/__tests__/routes/__screenshots__/login.test.tsx/Login-Page-should-have-a-link-back-to-home-page-1.png +0 -0
  249. package/templates/base/src/client/__tests__/routes/__screenshots__/login.test.tsx/Login-Page-should-render-login-content-without-waiting-for-authentication-1.png +0 -0
  250. package/templates/base/src/client/__tests__/routes/__screenshots__/login.test.tsx/Login-Page-should-render-login-page-at--login-route-1.png +0 -0
  251. package/templates/base/src/client/__tests__/routes/__screenshots__/login.test.tsx/Login-Page-should-show-Terms-of-Service-and-Privacy-Policy-links-1.png +0 -0
  252. package/templates/base/src/client/__tests__/routes/__screenshots__/login.test.tsx/Login-Page-should-trigger-OAuth-flow-when-clicking-login-button-1.png +0 -0
  253. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-404-handling-should-display-404-text-on-not-found-page-1.png +0 -0
  254. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-404-handling-should-have-navigation-options-on-404-page-1.png +0 -0
  255. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-404-handling-should-render-404-page-for-unknown-routes-1.png +0 -0
  256. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-authenticated-navigation-should-navigate-from-dashboard-to-account-page-1.png +0 -0
  257. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-authenticated-navigation-should-navigate-from-dashboard-to-integrations-page-1.png +0 -0
  258. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-authenticated-navigation-should-navigate-from-dashboard-to-settings-page-1.png +0 -0
  259. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-authenticated-navigation-should-navigate-from-dashboard-to-team-page-1.png +0 -0
  260. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-home-page-navigation-should-display-navigation-links-on-home-page-1.png +0 -0
  261. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-home-page-navigation-should-have-correct-link-destinations-on-home-page-1.png +0 -0
  262. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-unauthenticated-navigation-should-allow-access-to-home-page-without-authentication-1.png +0 -0
  263. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-unauthenticated-navigation-should-allow-access-to-login-page-without-authentication-1.png +0 -0
  264. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-unauthenticated-navigation-should-redirect-unauthenticated-users-from-dashboard-to-login-1.png +0 -0
  265. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-unauthenticated-navigation-should-redirect-unauthenticated-users-from-settings-to-login-1.png +0 -0
  266. package/templates/base/src/client/__tests__/routes/__screenshots__/navigation.test.tsx/Navigation-unauthenticated-navigation-should-redirect-unauthenticated-users-from-team-to-login-1.png +0 -0
  267. package/templates/base/src/client/__tests__/routes/authenticated-layout.test.tsx +252 -0
  268. package/templates/base/src/client/__tests__/routes/dashboard.test.tsx +136 -0
  269. package/templates/base/src/client/__tests__/routes/error-components.test.tsx +186 -0
  270. package/templates/base/src/client/__tests__/routes/login.test.tsx +112 -0
  271. package/templates/base/src/client/__tests__/routes/navigation.test.tsx +272 -0
  272. package/templates/base/src/client/__tests__/routes/root-layout.test.tsx +65 -0
  273. package/templates/base/src/client/__tests__/setup-browser.ts +15 -0
  274. package/templates/base/src/client/__tests__/setup.ts +32 -0
  275. package/templates/base/src/client/__tests__/test-utils.tsx +135 -0
  276. package/templates/base/src/client/api/.gitkeep +0 -0
  277. package/templates/base/src/client/components/__tests__/__screenshots__/sidebar.test.tsx/Sidebar-can-be-collapsed-by-default-1.png +0 -0
  278. package/templates/base/src/client/components/__tests__/__screenshots__/sidebar.test.tsx/Sidebar-expands-when-collapsed-and-expand-button-is-clicked-1.png +0 -0
  279. package/templates/base/src/client/components/__tests__/__screenshots__/sidebar.test.tsx/Sidebar-handles-logout-button-click-1.png +0 -0
  280. package/templates/base/src/client/components/__tests__/__screenshots__/sidebar.test.tsx/Sidebar-handles-navigation-clicks-1.png +0 -0
  281. package/templates/base/src/client/components/__tests__/__screenshots__/sidebar.test.tsx/Sidebar-hides-navigation-labels-when-collapsed-1.png +0 -0
  282. package/templates/base/src/client/components/__tests__/__screenshots__/sidebar.test.tsx/Sidebar-highlights-active-route-1.png +0 -0
  283. package/templates/base/src/client/components/__tests__/__screenshots__/sidebar.test.tsx/Sidebar-renders-sidebar-navigation-items-1.png +0 -0
  284. package/templates/base/src/client/components/__tests__/__screenshots__/sidebar.test.tsx/Sidebar-shows-keyboard-shortcut-hint-when-expanded-1.png +0 -0
  285. package/templates/base/src/client/components/__tests__/__screenshots__/sidebar.test.tsx/Sidebar-shows-user-info-when-authenticated-1.png +0 -0
  286. package/templates/base/src/client/components/__tests__/__screenshots__/sidebar.test.tsx/Sidebar-shows-user-initials-in-avatar-fallback-1.png +0 -0
  287. package/templates/base/src/client/components/__tests__/error-boundary.test.tsx +97 -0
  288. package/templates/base/src/client/components/__tests__/sidebar.test.tsx +281 -0
  289. package/templates/base/src/client/components/error-boundary.tsx +68 -0
  290. package/templates/base/src/client/components/icons.tsx +106 -0
  291. package/templates/base/src/client/components/layout/.gitkeep +0 -0
  292. package/templates/base/src/client/components/sidebar.tsx +267 -0
  293. package/templates/base/src/client/components/ui/.gitkeep +0 -0
  294. package/templates/base/src/client/components/ui/__tests__/avatar.test.tsx +308 -0
  295. package/templates/base/src/client/components/ui/__tests__/card.test.tsx +214 -0
  296. package/templates/base/src/client/components/ui/__tests__/dialog.test.tsx +297 -0
  297. package/templates/base/src/client/components/ui/__tests__/error-fallback.test.tsx +145 -0
  298. package/templates/base/src/client/components/ui/__tests__/input.test.tsx +98 -0
  299. package/templates/base/src/client/components/ui/__tests__/loading-skeleton.test.tsx +139 -0
  300. package/templates/base/src/client/components/ui/__tests__/skeleton.test.tsx +44 -0
  301. package/templates/base/src/client/components/ui/__tests__/sonner.test.tsx +28 -0
  302. package/templates/base/src/client/components/ui/__tests__/tabs.test.tsx +233 -0
  303. package/templates/base/src/client/components/ui/avatar.tsx +101 -0
  304. package/templates/base/src/client/components/ui/badge.tsx +46 -0
  305. package/templates/base/src/client/components/ui/button.tsx +72 -0
  306. package/templates/base/src/client/components/ui/card.tsx +86 -0
  307. package/templates/base/src/client/components/ui/dialog.tsx +140 -0
  308. package/templates/base/src/client/components/ui/error-fallback.tsx +179 -0
  309. package/templates/base/src/client/components/ui/form.tsx +172 -0
  310. package/templates/base/src/client/components/ui/input.tsx +24 -0
  311. package/templates/base/src/client/components/ui/label.tsx +22 -0
  312. package/templates/base/src/client/components/ui/loading-skeleton.tsx +154 -0
  313. package/templates/base/src/client/components/ui/separator.tsx +33 -0
  314. package/templates/base/src/client/components/ui/skeleton.tsx +16 -0
  315. package/templates/base/src/client/components/ui/sonner.tsx +29 -0
  316. package/templates/base/src/client/components/ui/tabs.tsx +121 -0
  317. package/templates/base/src/client/hooks/.gitkeep +0 -0
  318. package/templates/base/src/client/hooks/__tests__/use-auth.test.tsx +306 -0
  319. package/templates/base/src/client/hooks/__tests__/use-theme.test.tsx +172 -0
  320. package/templates/base/src/client/hooks/use-auth.ts +53 -0
  321. package/templates/base/src/client/hooks/use-theme.tsx +78 -0
  322. package/templates/base/src/client/index.css +881 -0
  323. package/templates/base/src/client/lib/query-client.ts +11 -0
  324. package/templates/base/src/client/lib/utils.ts +7 -0
  325. package/templates/base/src/client/main.tsx +26 -0
  326. package/templates/base/src/client/routeTree.gen.ts +258 -0
  327. package/templates/base/src/client/router.ts +15 -0
  328. package/templates/base/src/client/routes/$.tsx +77 -0
  329. package/templates/base/src/client/routes/.gitkeep +0 -0
  330. package/templates/base/src/client/routes/__root.tsx +34 -0
  331. package/templates/base/src/client/routes/__tests__/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-display-accept-invitation-button-1.png +0 -0
  332. package/templates/base/src/client/routes/__tests__/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-display-decline-button-linking-to-homepage-1.png +0 -0
  333. package/templates/base/src/client/routes/__tests__/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-display-invitation-details--email--workspace--role--1.png +0 -0
  334. package/templates/base/src/client/routes/__tests__/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-have-a-logo-link-to-homepage-1.png +0 -0
  335. package/templates/base/src/client/routes/__tests__/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-render-invitation-page-with-inviter-name-and-workspace-1.png +0 -0
  336. package/templates/base/src/client/routes/__tests__/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-show-terms-of-service-and-privacy-policy-links-1.png +0 -0
  337. package/templates/base/src/client/routes/__tests__/invite.test.tsx +138 -0
  338. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/account.test.tsx/Account-Page-should-render-Active-Sessions-section-with-session-cards-1.png +0 -0
  339. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/account.test.tsx/Account-Page-should-render-page-with-correct-title--Account--1.png +0 -0
  340. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/account.test.tsx/Account-Page-should-show-API-Access-section-1.png +0 -0
  341. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/account.test.tsx/Account-Page-should-show-Connected-Accounts-section-with-Google-connected-1.png +0 -0
  342. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/account.test.tsx/Account-Page-should-show-Danger-Zone-section-with-delete-button-1.png +0 -0
  343. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/account.test.tsx/Account-Page-should-show-Security-section-with-Two-Factor-Authentication-1.png +0 -0
  344. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-API-documentation-section-should-display-API-documentation-link-section-1.png +0 -0
  345. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-Create-Webhook-Dialog-should-have-Add-Webhook-trigger-button-1.png +0 -0
  346. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-category-filters-should-display-all-category-buttons-1.png +0 -0
  347. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-integration-cards-should-display-all-integration-cards-with-names-1.png +0 -0
  348. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-integration-cards-should-display-category-badges-on-cards-1.png +0 -0
  349. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-integration-cards-should-show-Configure-button-for-connected-integrations-1.png +0 -0
  350. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-integration-cards-should-show-Connect-button-for-not-connected-integrations-1.png +0 -0
  351. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-integration-cards-should-show-Connected-badge-for-connected-integrations-1.png +0 -0
  352. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-display-Available-Integrations-section-1.png +0 -0
  353. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-display-Webhooks-section-1.png +0 -0
  354. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-display-connected-count-1.png +0 -0
  355. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-display-page-description-1.png +0 -0
  356. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-display-search-input-1.png +0 -0
  357. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-render-with-correct-title--Integrations--1.png +0 -0
  358. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-search-functionality-should-filter-integrations-based-on-search-query-1.png +0 -0
  359. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-search-functionality-should-search-by-description-1.png +0 -0
  360. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-search-functionality-should-show-no-results-message-when-search-has-no-matches-1.png +0 -0
  361. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-webhooks-section-should-display-existing-webhook-1.png +0 -0
  362. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-webhooks-section-should-display-webhook-events-1.png +0 -0
  363. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-webhooks-section-should-display-webhook-last-delivery-info-1.png +0 -0
  364. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-webhooks-section-should-display-webhook-success-status-1.png +0 -0
  365. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/integrations.test.tsx/Integrations-Page-webhooks-section-should-have-Add-Webhook-button-1.png +0 -0
  366. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Account-tab-should-display-connected-accounts-section-with-Google-provider-1.png +0 -0
  367. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Account-tab-should-display-sessions-and-danger-zone-sections-1.png +0 -0
  368. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Notifications-tab-should-display-all-notification-toggle-options-1.png +0 -0
  369. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Notifications-tab-should-display-email-notifications-section-1.png +0 -0
  370. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Notifications-tab-should-display-toggle-switches-for-notification-options-1.png +0 -0
  371. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Notifications-tab-should-have-toggles-checked-by-default-1.png +0 -0
  372. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display--Save-Changes--button-1.png +0 -0
  373. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display-personal-information-form-1.png +0 -0
  374. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display-profile-picture-section-1.png +0 -0
  375. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display-user-email-in-disabled-email-input-1.png +0 -0
  376. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display-user-initials-in-avatar-1.png +0 -0
  377. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display-user-name-in-the-name-input-1.png +0 -0
  378. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-page-rendering-should-display-all-three-tabs-1.png +0 -0
  379. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-page-rendering-should-display-page-description-1.png +0 -0
  380. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-page-rendering-should-render-with-correct-title--Settings--1.png +0 -0
  381. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-tab-navigation-should-show-Profile-tab-as-default-active-tab-1.png +0 -0
  382. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-tab-navigation-should-switch-to-Account-tab-when-clicked-1.png +0 -0
  383. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/settings.test.tsx/Settings-Page-tab-navigation-should-switch-to-Notifications-tab-when-clicked-1.png +0 -0
  384. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/team.test.tsx/Team-Page-should-display-Active-Members-section-with-member-count-1.png +0 -0
  385. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/team.test.tsx/Team-Page-should-display-Pending-Invitations-section-with-invitation-details-1.png +0 -0
  386. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/team.test.tsx/Team-Page-should-have-invite-member-button-that-can-be-clicked-1.png +0 -0
  387. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/team.test.tsx/Team-Page-should-render-page-with-correct-title-and-description-1.png +0 -0
  388. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/team.test.tsx/Team-Page-should-render-search-input-that-filters-team-members-1.png +0 -0
  389. package/templates/base/src/client/routes/_authenticated/__tests__/__screenshots__/team.test.tsx/Team-Page-should-show-current-user-with---you---indicator-and-role-badge-1.png +0 -0
  390. package/templates/base/src/client/routes/_authenticated/__tests__/account.test.tsx +324 -0
  391. package/templates/base/src/client/routes/_authenticated/__tests__/integrations.test.tsx +520 -0
  392. package/templates/base/src/client/routes/_authenticated/__tests__/settings.test.tsx +414 -0
  393. package/templates/base/src/client/routes/_authenticated/__tests__/team.test.tsx +374 -0
  394. package/templates/base/src/client/routes/_authenticated/account.tsx +416 -0
  395. package/templates/base/src/client/routes/_authenticated/dashboard.tsx +151 -0
  396. package/templates/base/src/client/routes/_authenticated/integrations.tsx +553 -0
  397. package/templates/base/src/client/routes/_authenticated/settings.tsx +310 -0
  398. package/templates/base/src/client/routes/_authenticated/team.tsx +395 -0
  399. package/templates/base/src/client/routes/_authenticated.tsx +69 -0
  400. package/templates/base/src/client/routes/index.tsx +155 -0
  401. package/templates/base/src/client/routes/invite.$token.tsx +191 -0
  402. package/templates/base/src/client/routes/login.tsx +92 -0
  403. package/templates/base/src/server/__tests__/fixtures.ts +461 -0
  404. package/templates/base/src/server/__tests__/mocks/__tests__/db.test.ts +239 -0
  405. package/templates/base/src/server/__tests__/mocks/__tests__/kv.test.ts +293 -0
  406. package/templates/base/src/server/__tests__/mocks/__tests__/r2.test.ts +363 -0
  407. package/templates/base/src/server/__tests__/mocks/db.ts +186 -0
  408. package/templates/base/src/server/__tests__/mocks/index.ts +33 -0
  409. package/templates/base/src/server/__tests__/mocks/kv.ts +286 -0
  410. package/templates/base/src/server/__tests__/mocks/r2.ts +397 -0
  411. package/templates/base/src/server/__tests__/setup.ts +281 -0
  412. package/templates/base/src/server/auth/__tests__/guards.test.ts +162 -0
  413. package/templates/base/src/server/auth/guards.ts +92 -0
  414. package/templates/base/src/server/auth/permissions.test.ts +45 -0
  415. package/templates/base/src/server/auth/permissions.ts +139 -0
  416. package/templates/base/src/server/auth/roles.test.ts +169 -0
  417. package/templates/base/src/server/auth/roles.ts +141 -0
  418. package/templates/base/src/server/db/client.ts +12 -0
  419. package/templates/base/src/server/db/schema/accounts.ts +20 -0
  420. package/templates/base/src/server/db/schema/audit-logs.ts +26 -0
  421. package/templates/base/src/server/db/schema/index.ts +7 -0
  422. package/templates/base/src/server/db/schema/invitations.ts +30 -0
  423. package/templates/base/src/server/db/schema/refresh-tokens.ts +22 -0
  424. package/templates/base/src/server/db/schema/user-accounts.ts +25 -0
  425. package/templates/base/src/server/db/schema/users.ts +33 -0
  426. package/templates/base/src/server/db/seed.ts +267 -0
  427. package/templates/base/src/server/env.test.ts +84 -0
  428. package/templates/base/src/server/env.ts +78 -0
  429. package/templates/base/src/server/index.ts +82 -0
  430. package/templates/base/src/server/lib/audit.ts +73 -0
  431. package/templates/base/src/server/lib/audited-db.test.ts +107 -0
  432. package/templates/base/src/server/lib/audited-db.ts +154 -0
  433. package/templates/base/src/server/lib/email.test.ts +116 -0
  434. package/templates/base/src/server/lib/email.ts +82 -0
  435. package/templates/base/src/server/lib/errors.test.ts +49 -0
  436. package/templates/base/src/server/lib/errors.ts +64 -0
  437. package/templates/base/src/server/lib/oauth.test.ts +238 -0
  438. package/templates/base/src/server/lib/oauth.ts +113 -0
  439. package/templates/base/src/server/lib/pagination.test.ts +52 -0
  440. package/templates/base/src/server/lib/pagination.ts +32 -0
  441. package/templates/base/src/server/lib/password.test.ts +151 -0
  442. package/templates/base/src/server/lib/password.ts +151 -0
  443. package/templates/base/src/server/lib/providers.test.ts +105 -0
  444. package/templates/base/src/server/lib/providers.ts +62 -0
  445. package/templates/base/src/server/lib/r2-storage.test.ts +202 -0
  446. package/templates/base/src/server/lib/r2-storage.ts +107 -0
  447. package/templates/base/src/server/lib/schema-helpers.ts +16 -0
  448. package/templates/base/src/server/lib/session.test.ts +758 -0
  449. package/templates/base/src/server/lib/session.ts +267 -0
  450. package/templates/base/src/server/lib/tokens.test.ts +208 -0
  451. package/templates/base/src/server/lib/tokens.ts +65 -0
  452. package/templates/base/src/server/lib/transaction.test.ts +45 -0
  453. package/templates/base/src/server/lib/transaction.ts +24 -0
  454. package/templates/base/src/server/middleware/account.test.ts +201 -0
  455. package/templates/base/src/server/middleware/account.ts +66 -0
  456. package/templates/base/src/server/middleware/auth.test.ts +345 -0
  457. package/templates/base/src/server/middleware/auth.ts +146 -0
  458. package/templates/base/src/server/middleware/cors.test.ts +88 -0
  459. package/templates/base/src/server/middleware/cors.ts +26 -0
  460. package/templates/base/src/server/middleware/error-handler.test.ts +69 -0
  461. package/templates/base/src/server/middleware/error-handler.ts +43 -0
  462. package/templates/base/src/server/middleware/index.ts +8 -0
  463. package/templates/base/src/server/middleware/rate-limit.test.ts +472 -0
  464. package/templates/base/src/server/middleware/rate-limit.ts +294 -0
  465. package/templates/base/src/server/middleware/request-context.test.ts +175 -0
  466. package/templates/base/src/server/middleware/request-context.ts +28 -0
  467. package/templates/base/src/server/middleware/request-logger.test.ts +92 -0
  468. package/templates/base/src/server/middleware/request-logger.ts +50 -0
  469. package/templates/base/src/server/routes/accounts/__tests__/handlers.test.ts +460 -0
  470. package/templates/base/src/server/routes/accounts/handlers.ts +179 -0
  471. package/templates/base/src/server/routes/accounts/index.ts +55 -0
  472. package/templates/base/src/server/routes/accounts/routes.ts +205 -0
  473. package/templates/base/src/server/routes/accounts/schemas.ts +31 -0
  474. package/templates/base/src/server/routes/api.ts +37 -0
  475. package/templates/base/src/server/routes/audits/__tests__/handlers.test.ts +349 -0
  476. package/templates/base/src/server/routes/audits/handlers.ts +37 -0
  477. package/templates/base/src/server/routes/audits/index.ts +14 -0
  478. package/templates/base/src/server/routes/audits/routes.ts +29 -0
  479. package/templates/base/src/server/routes/audits/schemas.ts +43 -0
  480. package/templates/base/src/server/routes/auth/__tests__/handlers.test.ts +381 -0
  481. package/templates/base/src/server/routes/auth/handlers.ts +222 -0
  482. package/templates/base/src/server/routes/auth/index.ts +37 -0
  483. package/templates/base/src/server/routes/auth/routes.ts +136 -0
  484. package/templates/base/src/server/routes/auth/schemas.ts +48 -0
  485. package/templates/base/src/server/routes/auth/test-login.ts +156 -0
  486. package/templates/base/src/server/routes/health/__tests__/handlers.test.ts +237 -0
  487. package/templates/base/src/server/routes/health/handlers.ts +83 -0
  488. package/templates/base/src/server/routes/health/index.ts +13 -0
  489. package/templates/base/src/server/routes/health/routes.ts +90 -0
  490. package/templates/base/src/server/routes/index.ts +53 -0
  491. package/templates/base/src/server/routes/invitations/__tests__/handlers.test.ts +473 -0
  492. package/templates/base/src/server/routes/invitations/handlers.ts +71 -0
  493. package/templates/base/src/server/routes/invitations/index.ts +25 -0
  494. package/templates/base/src/server/routes/invitations/routes.ts +69 -0
  495. package/templates/base/src/server/routes/invitations/schemas.ts +39 -0
  496. package/templates/base/src/server/routes/openapi.ts +14 -0
  497. package/templates/base/src/server/routes/schemas.ts +53 -0
  498. package/templates/base/src/server/routes/storage/__tests__/handlers.test.ts +408 -0
  499. package/templates/base/src/server/routes/storage/handlers.ts +100 -0
  500. package/templates/base/src/server/routes/storage/index.ts +42 -0
  501. package/templates/base/src/server/routes/storage/routes.ts +91 -0
  502. package/templates/base/src/server/routes/storage/schemas.ts +56 -0
  503. package/templates/base/src/server/routes/users/__tests__/handlers.test.ts +526 -0
  504. package/templates/base/src/server/routes/users/handlers.ts +228 -0
  505. package/templates/base/src/server/routes/users/index.ts +67 -0
  506. package/templates/base/src/server/routes/users/routes.ts +265 -0
  507. package/templates/base/src/server/routes/users/schemas.ts +67 -0
  508. package/templates/base/src/server/services/__tests__/accounts.test.ts +764 -0
  509. package/templates/base/src/server/services/__tests__/audits.test.ts +235 -0
  510. package/templates/base/src/server/services/__tests__/auth.test.ts +765 -0
  511. package/templates/base/src/server/services/__tests__/invitations.test.ts +704 -0
  512. package/templates/base/src/server/services/__tests__/users.test.ts +755 -0
  513. package/templates/base/src/server/services/accounts.ts +269 -0
  514. package/templates/base/src/server/services/audits.ts +82 -0
  515. package/templates/base/src/server/services/auth.ts +225 -0
  516. package/templates/base/src/server/services/index.ts +6 -0
  517. package/templates/base/src/server/services/invitations.ts +306 -0
  518. package/templates/base/src/server/services/users.ts +350 -0
  519. package/templates/base/src/server/types/auth.ts +36 -0
  520. package/templates/base/src/server/types/index.ts +117 -0
  521. package/templates/base/src/shared/schemas/.gitkeep +0 -0
  522. package/templates/base/src/shared/schemas/__tests__/schemas.test.ts +547 -0
  523. package/templates/base/src/shared/schemas/account.ts +15 -0
  524. package/templates/base/src/shared/schemas/index.ts +6 -0
  525. package/templates/base/src/shared/schemas/invitation.ts +9 -0
  526. package/templates/base/src/shared/schemas/profile.ts +10 -0
  527. package/templates/base/src/shared/schemas/user.ts +16 -0
  528. package/templates/base/src/shared/schemas/webhook.ts +12 -0
  529. package/templates/base/src/shared/types/.gitkeep +0 -0
  530. package/templates/base/src/shared/types/account.ts +12 -0
  531. package/templates/base/src/shared/types/api.ts +1399 -0
  532. package/templates/base/src/shared/types/auth.ts +24 -0
  533. package/templates/base/src/shared/types/index.ts +5 -0
  534. package/templates/base/src/shared/types/user.ts +31 -0
  535. package/templates/base/src/test/vitest-zod-matcher.ts +37 -0
  536. package/templates/base/src/test/vitest.d.ts +19 -0
  537. package/templates/base/tests/e2e/README.md +141 -0
  538. package/templates/base/tests/e2e/a11y/accessibility.spec.ts +925 -0
  539. package/templates/base/tests/e2e/a11y/keyboard-navigation.spec.ts +610 -0
  540. package/templates/base/tests/e2e/api/accounts.spec.ts +148 -0
  541. package/templates/base/tests/e2e/api/audit-logs.spec.ts +130 -0
  542. package/templates/base/tests/e2e/api/authenticated-api.spec.ts +311 -0
  543. package/templates/base/tests/e2e/api/storage.spec.ts +109 -0
  544. package/templates/base/tests/e2e/auth-flows.unauth.spec.ts +117 -0
  545. package/templates/base/tests/e2e/auth-logout.unauth.spec.ts +103 -0
  546. package/templates/base/tests/e2e/auth.setup.ts +115 -0
  547. package/templates/base/tests/e2e/auth.spec.ts +146 -0
  548. package/templates/base/tests/e2e/compatibility/cross-browser.spec.ts +152 -0
  549. package/templates/base/tests/e2e/compatibility/cross-browser.spec.ts-snapshots/login-chromium-chromium-darwin.png +0 -0
  550. package/templates/base/tests/e2e/crud/account.spec.ts +356 -0
  551. package/templates/base/tests/e2e/crud/integrations.spec.ts +419 -0
  552. package/templates/base/tests/e2e/crud/team.spec.ts +287 -0
  553. package/templates/base/tests/e2e/crud/users.spec.ts +239 -0
  554. package/templates/base/tests/e2e/errors/error-boundary.spec.ts +428 -0
  555. package/templates/base/tests/e2e/errors/error-handling.spec.ts +47 -0
  556. package/templates/base/tests/e2e/errors/error-handling.unauth.spec.ts +205 -0
  557. package/templates/base/tests/e2e/fixtures.ts +266 -0
  558. package/templates/base/tests/e2e/forms/validation.spec.ts +569 -0
  559. package/templates/base/tests/e2e/invitations/invite-flow.unauth.spec.ts +204 -0
  560. package/templates/base/tests/e2e/journeys/account-lifecycle.spec.ts +314 -0
  561. package/templates/base/tests/e2e/journeys/audit-investigation.spec.ts +299 -0
  562. package/templates/base/tests/e2e/journeys/auth-onboarding.spec.ts +232 -0
  563. package/templates/base/tests/e2e/journeys/critical-flows.spec.ts +281 -0
  564. package/templates/base/tests/e2e/journeys/error-recovery.spec.ts +354 -0
  565. package/templates/base/tests/e2e/journeys/file-management.spec.ts +307 -0
  566. package/templates/base/tests/e2e/journeys/integrations.spec.ts +372 -0
  567. package/templates/base/tests/e2e/journeys/multi-account.spec.ts +317 -0
  568. package/templates/base/tests/e2e/journeys/rbac-enforcement.spec.ts +389 -0
  569. package/templates/base/tests/e2e/journeys/settings-profile.spec.ts +400 -0
  570. package/templates/base/tests/e2e/journeys/team-collaboration.spec.ts +410 -0
  571. package/templates/base/tests/e2e/mobile/responsive.spec.ts +178 -0
  572. package/templates/base/tests/e2e/navigation/routing.spec.ts +371 -0
  573. package/templates/base/tests/e2e/navigation/sidebar.spec.ts +425 -0
  574. package/templates/base/tests/e2e/pages/ui-features.spec.ts +393 -0
  575. package/templates/base/tests/e2e/performance/baselines.spec.ts +162 -0
  576. package/templates/base/tests/e2e/performance/benchmarks.spec.ts +371 -0
  577. package/templates/base/tests/e2e/smoke.unauth.spec.ts +196 -0
  578. package/templates/base/tests/e2e/visual/components.spec.ts +650 -0
  579. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/confirmation-dialog-visual-darwin.png +0 -0
  580. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/dark-mode-background-visual-darwin.png +0 -0
  581. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/dark-mode-card-visual-darwin.png +0 -0
  582. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/dark-mode-sidebar-visual-darwin.png +0 -0
  583. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/dashboard-card-single-visual-darwin.png +0 -0
  584. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/dialog-content-visual-darwin.png +0 -0
  585. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/dialog-with-backdrop-visual-darwin.png +0 -0
  586. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/empty-search-results-visual-darwin.png +0 -0
  587. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/input-default-visual-darwin.png +0 -0
  588. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/input-focus-ring-visual-darwin.png +0 -0
  589. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/primary-button-focus-visual-darwin.png +0 -0
  590. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/primary-button-hover-visual-darwin.png +0 -0
  591. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/primary-button-visual-darwin.png +0 -0
  592. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/sidebar-active-nav-item-visual-darwin.png +0 -0
  593. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/sidebar-collapsed-visual-darwin.png +0 -0
  594. package/templates/base/tests/e2e/visual/components.spec.ts-snapshots/sidebar-navigation-visual-darwin.png +0 -0
  595. package/templates/base/tests/e2e/visual/core-components.spec.ts +192 -0
  596. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/account-page-visual-darwin.png +0 -0
  597. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/create-webhook-dialog-visual-darwin.png +0 -0
  598. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/dashboard-page-visual-darwin.png +0 -0
  599. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/delete-account-dialog-visual-darwin.png +0 -0
  600. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/integrations-page-visual-darwin.png +0 -0
  601. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/invite-member-dialog-visual-darwin.png +0 -0
  602. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/login-page-visual-darwin.png +0 -0
  603. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/settings-account-tab-visual-darwin.png +0 -0
  604. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/settings-profile-tab-visual-darwin.png +0 -0
  605. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/sidebar-navigation-visual-darwin.png +0 -0
  606. package/templates/base/tests/e2e/visual/core-components.spec.ts-snapshots/team-page-visual-darwin.png +0 -0
  607. package/templates/base/tests/e2e/visual/screenshots.spec.ts +230 -0
  608. package/templates/base/tests/e2e/visual/screenshots.spec.ts-snapshots/404-page-chromium-darwin.png +0 -0
  609. package/templates/base/tests/e2e/visual/screenshots.spec.ts-snapshots/404-page-visual-darwin.png +0 -0
  610. package/templates/base/tests/e2e/visual/screenshots.spec.ts-snapshots/account-page-visual-darwin.png +0 -0
  611. package/templates/base/tests/e2e/visual/screenshots.spec.ts-snapshots/login-page-chromium-darwin.png +0 -0
  612. package/templates/base/tests/e2e/visual/screenshots.spec.ts-snapshots/login-page-visual-darwin.png +0 -0
  613. package/templates/base/tests/e2e/visual/screenshots.spec.ts-snapshots/settings-page-visual-darwin.png +0 -0
  614. package/templates/base/tests/e2e/visual/screenshots.spec.ts-snapshots/team-invite-dialog-visual-darwin.png +0 -0
  615. package/templates/base/tests/e2e/visual/screenshots.spec.ts-snapshots/team-page-visual-darwin.png +0 -0
  616. package/templates/base/tests/e2e/visual/screenshots.spec.ts-snapshots/webhook-create-dialog-visual-darwin.png +0 -0
  617. package/templates/base/tests/e2e/visual/theme-colors.spec.ts +293 -0
  618. package/templates/base/tests/e2e/visual/ui-components.spec.ts +502 -0
  619. package/templates/base/tests/integration/accounts/crud.test.ts +1402 -0
  620. package/templates/base/tests/integration/audits/list.test.ts +1133 -0
  621. package/templates/base/tests/integration/auth/auth-service.test.ts +415 -0
  622. package/templates/base/tests/integration/auth/invitation-token.test.ts +529 -0
  623. package/templates/base/tests/integration/auth/logout.test.ts +524 -0
  624. package/templates/base/tests/integration/auth/oauth.test.ts +768 -0
  625. package/templates/base/tests/integration/auth/refresh-token.test.ts +364 -0
  626. package/templates/base/tests/integration/auth/session-expiry.test.ts +569 -0
  627. package/templates/base/tests/integration/auth/session.test.ts +520 -0
  628. package/templates/base/tests/integration/auth/super-admin.test.ts +451 -0
  629. package/templates/base/tests/integration/authorization/analytics-role.test.ts +1026 -0
  630. package/templates/base/tests/integration/authorization/billing-role.test.ts +776 -0
  631. package/templates/base/tests/integration/authorization/guards-roles.test.ts +539 -0
  632. package/templates/base/tests/integration/authorization/multi-tenancy.test.ts +1112 -0
  633. package/templates/base/tests/integration/authorization/role-hierarchy.test.ts +931 -0
  634. package/templates/base/tests/integration/authorization/roles.test.ts +1347 -0
  635. package/templates/base/tests/integration/config/production-behavior.test.ts +536 -0
  636. package/templates/base/tests/integration/db/constraints.test.ts +695 -0
  637. package/templates/base/tests/integration/fixtures/accounts.ts +136 -0
  638. package/templates/base/tests/integration/fixtures/index.ts +232 -0
  639. package/templates/base/tests/integration/fixtures/invitations.ts +195 -0
  640. package/templates/base/tests/integration/fixtures/users.ts +144 -0
  641. package/templates/base/tests/integration/health/health.test.ts +351 -0
  642. package/templates/base/tests/integration/invitations/crud.test.ts +1457 -0
  643. package/templates/base/tests/integration/invitations/email.test.ts +506 -0
  644. package/templates/base/tests/integration/lib/email.test.ts +174 -0
  645. package/templates/base/tests/integration/lib/oauth.test.ts +368 -0
  646. package/templates/base/tests/integration/lib/password.test.ts +192 -0
  647. package/templates/base/tests/integration/lib/schema-helpers.test.ts +129 -0
  648. package/templates/base/tests/integration/lib/tokens.test.ts +304 -0
  649. package/templates/base/tests/integration/middleware/auth.test.ts +499 -0
  650. package/templates/base/tests/integration/middleware/cors.test.ts +334 -0
  651. package/templates/base/tests/integration/middleware/request-context.test.ts +156 -0
  652. package/templates/base/tests/integration/middleware/request-logger.test.ts +313 -0
  653. package/templates/base/tests/integration/performance/response-times.test.ts +509 -0
  654. package/templates/base/tests/integration/security/cookie-security.test.ts +567 -0
  655. package/templates/base/tests/integration/security/csrf-protection.test.ts +542 -0
  656. package/templates/base/tests/integration/security/jwt-validation.test.ts +209 -0
  657. package/templates/base/tests/integration/security/log-sanitization.test.ts +658 -0
  658. package/templates/base/tests/integration/security/rate-limiting.test.ts +1251 -0
  659. package/templates/base/tests/integration/security/sql-injection.test.ts +663 -0
  660. package/templates/base/tests/integration/security/token-hashing.test.ts +371 -0
  661. package/templates/base/tests/integration/security/xss-prevention.test.ts +541 -0
  662. package/templates/base/tests/integration/setup.ts +834 -0
  663. package/templates/base/tests/integration/smoke.test.ts +288 -0
  664. package/templates/base/tests/integration/storage/upload.test.ts +1162 -0
  665. package/templates/base/tests/integration/storage/validation.test.ts +746 -0
  666. package/templates/base/tests/integration/users/crud.test.ts +1297 -0
  667. package/templates/base/tests/integration/users/list.test.ts +698 -0
  668. package/templates/base/tests/integration/vitest.config.ts +80 -0
  669. package/templates/base/tsconfig.app.json +18 -0
  670. package/templates/base/tsconfig.json +39 -0
  671. package/templates/base/tsconfig.node.json +16 -0
  672. package/templates/base/tsconfig.server.json +26 -0
  673. package/templates/base/tsconfig.tsbuildinfo +1 -0
  674. package/templates/base/vite.config.ts +46 -0
  675. package/templates/base/vitest.config.browser.ts +47 -0
  676. package/templates/base/vitest.config.frontend.ts +47 -0
  677. package/templates/base/vitest.config.ts +82 -0
  678. package/templates/base/vitest.workspace.ts +22 -0
  679. package/templates/modules/audit-logs/.gitkeep +0 -0
  680. package/templates/modules/billing/.gitkeep +0 -0
  681. package/templates/modules/invitations/.gitkeep +0 -0
  682. package/templates/modules/storage/.gitkeep +0 -0
  683. package/templates/modules/webhooks/.gitkeep +0 -0
  684. package/templates/providers/auth-email/.gitkeep +0 -0
  685. package/templates/providers/auth-github/.gitkeep +0 -0
  686. package/templates/providers/auth-google/.gitkeep +0 -0
  687. package/templates/providers/email-resend/.gitkeep +0 -0
  688. package/templates/providers/email-sendgrid/.gitkeep +0 -0
@@ -0,0 +1,3128 @@
1
+ [
2
+ {
3
+ "category": "functional",
4
+ "description": "Google OAuth login initiates redirect to Google authorization page",
5
+ "steps": [
6
+ "Step 1: Navigate to /auth/login",
7
+ "Step 2: Verify redirect to Google OAuth authorization URL",
8
+ "Step 3: Verify state parameter is included for CSRF protection",
9
+ "Step 4: Verify PKCE code_challenge parameter is present"
10
+ ],
11
+ "passes": false
12
+ },
13
+ {
14
+ "category": "functional",
15
+ "description": "OAuth callback creates user session and redirects to dashboard",
16
+ "steps": [
17
+ "Step 1: Complete Google OAuth authorization",
18
+ "Step 2: Redirect to /auth/callback with code and state",
19
+ "Step 3: Verify user session is created in KV store",
20
+ "Step 4: Verify session_id cookie is set with httpOnly flag",
21
+ "Step 5: Verify redirect to /dashboard"
22
+ ],
23
+ "passes": false
24
+ },
25
+ {
26
+ "category": "functional",
27
+ "description": "OAuth callback creates new user if first-time login",
28
+ "steps": [
29
+ "Step 1: Complete Google OAuth with new Google account",
30
+ "Step 2: Redirect to /auth/callback",
31
+ "Step 3: Verify new user record created in database",
32
+ "Step 4: Verify user's googleId is stored",
33
+ "Step 5: Verify email and name from OAuth provider are saved",
34
+ "Step 6: Verify SIGNUP audit event is logged",
35
+ "Step 7: Verify redirect to dashboard"
36
+ ],
37
+ "passes": false
38
+ },
39
+ {
40
+ "category": "functional",
41
+ "description": "OAuth callback links existing user if email matches",
42
+ "steps": [
43
+ "Step 1: Ensure user with matching email exists in database",
44
+ "Step 2: Complete Google OAuth with that email",
45
+ "Step 3: Verify user record is updated with googleId",
46
+ "Step 4: Verify LOGIN audit event is logged",
47
+ "Step 5: Verify session is created for existing user"
48
+ ],
49
+ "passes": false
50
+ },
51
+ {
52
+ "category": "functional",
53
+ "description": "Super admin pre-registration grants isSuperAdmin flag on first login",
54
+ "steps": [
55
+ "Step 1: Configure SUPER_ADMIN_EMAILS environment variable",
56
+ "Step 2: Complete OAuth login with pre-registered email",
57
+ "Step 3: Verify user is created with isSuperAdmin=true",
58
+ "Step 4: Verify user can access super admin only endpoints"
59
+ ],
60
+ "passes": false
61
+ },
62
+ {
63
+ "category": "functional",
64
+ "description": "Logout destroys session and clears cookies",
65
+ "steps": [
66
+ "Step 1: Log in and verify session exists",
67
+ "Step 2: Send POST request to /auth/logout",
68
+ "Step 3: Verify session is deleted from KV store",
69
+ "Step 4: Verify session_id cookie is cleared",
70
+ "Step 5: Verify LOGOUT audit event is logged",
71
+ "Step 6: Verify subsequent requests are unauthenticated"
72
+ ],
73
+ "passes": false
74
+ },
75
+ {
76
+ "category": "functional",
77
+ "description": "Logout redirects to login page",
78
+ "steps": [
79
+ "Step 1: Log in as authenticated user",
80
+ "Step 2: Click logout button",
81
+ "Step 3: Verify redirect to /login page"
82
+ ],
83
+ "passes": false
84
+ },
85
+ {
86
+ "category": "functional",
87
+ "description": "/auth/me returns current user information",
88
+ "steps": [
89
+ "Step 1: Log in as authenticated user",
90
+ "Step 2: Send GET request to /auth/me",
91
+ "Step 3: Verify response contains user id, email, name, avatarUrl",
92
+ "Step 4: Verify response contains isSuperAdmin flag"
93
+ ],
94
+ "passes": false
95
+ },
96
+ {
97
+ "category": "functional",
98
+ "description": "/auth/me returns 401 for unauthenticated requests",
99
+ "steps": [
100
+ "Step 1: Clear all session cookies",
101
+ "Step 2: Send GET request to /auth/me without session",
102
+ "Step 3: Verify 401 Unauthorized response"
103
+ ],
104
+ "passes": false
105
+ },
106
+ {
107
+ "category": "functional",
108
+ "description": "Session expiration requires re-authentication",
109
+ "steps": [
110
+ "Step 1: Log in and note session creation time",
111
+ "Step 2: Wait for session to expire (or manually expire in KV)",
112
+ "Step 3: Attempt to access protected endpoint",
113
+ "Step 4: Verify 401 response",
114
+ "Step 5: Verify redirect to login page"
115
+ ],
116
+ "passes": false
117
+ },
118
+ {
119
+ "category": "functional",
120
+ "description": "Invitation token is stored in cookie during OAuth flow",
121
+ "steps": [
122
+ "Step 1: Navigate to /auth/invite/:token with valid token",
123
+ "Step 2: Verify invitation token is stored in cookie",
124
+ "Step 3: Verify redirect to /auth/login",
125
+ "Step 4: Complete OAuth login",
126
+ "Step 5: Verify user is automatically added to invited account"
127
+ ],
128
+ "passes": false
129
+ },
130
+ {
131
+ "category": "functional",
132
+ "description": "Invalid invitation token shows error message",
133
+ "steps": [
134
+ "Step 1: Navigate to /auth/invite/:token with invalid token",
135
+ "Step 2: Verify error message is displayed",
136
+ "Step 3: Verify user is not added to any account"
137
+ ],
138
+ "passes": false
139
+ },
140
+ {
141
+ "category": "functional",
142
+ "description": "Expired invitation token shows expiration error",
143
+ "steps": [
144
+ "Step 1: Create invitation with expired date",
145
+ "Step 2: Navigate to /auth/invite/:token",
146
+ "Step 3: Verify expiration error message",
147
+ "Step 4: Verify user is not added to account"
148
+ ],
149
+ "passes": false
150
+ },
151
+ {
152
+ "category": "functional",
153
+ "description": "List users returns paginated results",
154
+ "steps": [
155
+ "Step 1: Log in as authenticated user",
156
+ "Step 2: Send GET /api/users?page=1&limit=10",
157
+ "Step 3: Verify response contains data array",
158
+ "Step 4: Verify meta contains total, page, pages, hasMore",
159
+ "Step 5: Verify at most 10 users returned"
160
+ ],
161
+ "passes": false
162
+ },
163
+ {
164
+ "category": "functional",
165
+ "description": "List users supports search by email",
166
+ "steps": [
167
+ "Step 1: Log in as authenticated user",
168
+ "Step 2: Send GET /api/users?query=test@example.com",
169
+ "Step 3: Verify only matching users returned",
170
+ "Step 4: Verify partial email matches work"
171
+ ],
172
+ "passes": false
173
+ },
174
+ {
175
+ "category": "functional",
176
+ "description": "List users supports search by name",
177
+ "steps": [
178
+ "Step 1: Log in as authenticated user",
179
+ "Step 2: Send GET /api/users?query=John",
180
+ "Step 3: Verify users with matching names returned",
181
+ "Step 4: Verify case-insensitive search"
182
+ ],
183
+ "passes": false
184
+ },
185
+ {
186
+ "category": "functional",
187
+ "description": "Get user by ID returns user details",
188
+ "steps": [
189
+ "Step 1: Log in as authenticated user",
190
+ "Step 2: Send GET /api/users/:id with valid user ID",
191
+ "Step 3: Verify response contains complete user object",
192
+ "Step 4: Verify all user fields are present"
193
+ ],
194
+ "passes": false
195
+ },
196
+ {
197
+ "category": "functional",
198
+ "description": "Get user by ID returns 404 for non-existent user",
199
+ "steps": [
200
+ "Step 1: Log in as authenticated user",
201
+ "Step 2: Send GET /api/users/:id with non-existent UUID",
202
+ "Step 3: Verify 404 Not Found response"
203
+ ],
204
+ "passes": false
205
+ },
206
+ {
207
+ "category": "functional",
208
+ "description": "Update user requires ADMIN role",
209
+ "steps": [
210
+ "Step 1: Log in as user with VIEWER role",
211
+ "Step 2: Attempt PATCH /api/users/:id with new name",
212
+ "Step 3: Verify 403 Forbidden response",
213
+ "Step 4: Log in as user with ADMIN role",
214
+ "Step 5: Attempt same PATCH request",
215
+ "Step 6: Verify 200 success response"
216
+ ],
217
+ "passes": false
218
+ },
219
+ {
220
+ "category": "functional",
221
+ "description": "Update user changes name successfully",
222
+ "steps": [
223
+ "Step 1: Log in as ADMIN user",
224
+ "Step 2: Send PATCH /api/users/:id with { name: 'New Name' }",
225
+ "Step 3: Verify user name is updated in response",
226
+ "Step 4: Verify UPDATE audit event is logged",
227
+ "Step 5: Verify GET /api/users/:id returns updated name"
228
+ ],
229
+ "passes": false
230
+ },
231
+ {
232
+ "category": "functional",
233
+ "description": "Update user changes status to inactive",
234
+ "steps": [
235
+ "Step 1: Log in as ADMIN user",
236
+ "Step 2: Send PATCH /api/users/:id with { status: 'inactive' }",
237
+ "Step 3: Verify user status is updated",
238
+ "Step 4: Verify audit event logged with status change"
239
+ ],
240
+ "passes": false
241
+ },
242
+ {
243
+ "category": "functional",
244
+ "description": "Delete user performs soft delete",
245
+ "steps": [
246
+ "Step 1: Log in as ADMIN user",
247
+ "Step 2: Send DELETE /api/users/:id",
248
+ "Step 3: Verify 204 No Content response",
249
+ "Step 4: Verify user has deletedAt timestamp set",
250
+ "Step 5: Verify DELETE audit event is logged",
251
+ "Step 6: Verify user no longer appears in list"
252
+ ],
253
+ "passes": false
254
+ },
255
+ {
256
+ "category": "functional",
257
+ "description": "Delete user requires ADMIN role",
258
+ "steps": [
259
+ "Step 1: Log in as VIEWER user",
260
+ "Step 2: Attempt DELETE /api/users/:id",
261
+ "Step 3: Verify 403 Forbidden response"
262
+ ],
263
+ "passes": false
264
+ },
265
+ {
266
+ "category": "functional",
267
+ "description": "Restore user requires Super Admin",
268
+ "steps": [
269
+ "Step 1: Soft delete a user",
270
+ "Step 2: Log in as regular ADMIN (not super)",
271
+ "Step 3: Attempt POST /api/users/:id/restore",
272
+ "Step 4: Verify 403 Forbidden response",
273
+ "Step 5: Log in as Super Admin",
274
+ "Step 6: Attempt POST /api/users/:id/restore",
275
+ "Step 7: Verify user is restored (deletedAt = null)"
276
+ ],
277
+ "passes": false
278
+ },
279
+ {
280
+ "category": "functional",
281
+ "description": "Bulk assign users to accounts",
282
+ "steps": [
283
+ "Step 1: Log in as MANAGER user",
284
+ "Step 2: Prepare list of user-account-role assignments",
285
+ "Step 3: Send POST /api/users/accounts with items array",
286
+ "Step 4: Verify response contains count of assignments",
287
+ "Step 5: Verify user_accounts records created",
288
+ "Step 6: Verify users can access their new accounts"
289
+ ],
290
+ "passes": false
291
+ },
292
+ {
293
+ "category": "functional",
294
+ "description": "Bulk remove users from accounts",
295
+ "steps": [
296
+ "Step 1: Log in as MANAGER user",
297
+ "Step 2: Prepare list of user-account removals",
298
+ "Step 3: Send DELETE /api/users/accounts with items array",
299
+ "Step 4: Verify response contains count of removals",
300
+ "Step 5: Verify user_accounts records deleted",
301
+ "Step 6: Verify users can no longer access removed accounts"
302
+ ],
303
+ "passes": false
304
+ },
305
+ {
306
+ "category": "functional",
307
+ "description": "List accounts returns user's accounts",
308
+ "steps": [
309
+ "Step 1: Log in as authenticated user",
310
+ "Step 2: Send GET /api/accounts",
311
+ "Step 3: Verify only accounts user belongs to are returned",
312
+ "Step 4: Verify pagination meta is present"
313
+ ],
314
+ "passes": false
315
+ },
316
+ {
317
+ "category": "functional",
318
+ "description": "Get account by ID returns account details",
319
+ "steps": [
320
+ "Step 1: Log in as account member",
321
+ "Step 2: Send GET /api/accounts/:id",
322
+ "Step 3: Verify account details returned",
323
+ "Step 4: Verify all account fields present"
324
+ ],
325
+ "passes": false
326
+ },
327
+ {
328
+ "category": "functional",
329
+ "description": "Get account returns 403 for non-member",
330
+ "steps": [
331
+ "Step 1: Log in as user not in target account",
332
+ "Step 2: Send GET /api/accounts/:id for that account",
333
+ "Step 3: Verify 403 Forbidden response"
334
+ ],
335
+ "passes": false
336
+ },
337
+ {
338
+ "category": "functional",
339
+ "description": "Create account requires Super Admin",
340
+ "steps": [
341
+ "Step 1: Log in as regular user",
342
+ "Step 2: Attempt POST /api/accounts with { name: 'New Account' }",
343
+ "Step 3: Verify 403 Forbidden response",
344
+ "Step 4: Log in as Super Admin",
345
+ "Step 5: Attempt same POST request",
346
+ "Step 6: Verify 201 Created response"
347
+ ],
348
+ "passes": false
349
+ },
350
+ {
351
+ "category": "functional",
352
+ "description": "Create account validates required fields",
353
+ "steps": [
354
+ "Step 1: Log in as Super Admin",
355
+ "Step 2: Send POST /api/accounts with empty body",
356
+ "Step 3: Verify validation error for missing name",
357
+ "Step 4: Send POST /api/accounts with { name: '' }",
358
+ "Step 5: Verify validation error for empty name"
359
+ ],
360
+ "passes": false
361
+ },
362
+ {
363
+ "category": "functional",
364
+ "description": "Update account requires Account ADMIN role",
365
+ "steps": [
366
+ "Step 1: Log in as account VIEWER",
367
+ "Step 2: Attempt PATCH /api/accounts/:id",
368
+ "Step 3: Verify 403 Forbidden",
369
+ "Step 4: Log in as account ADMIN",
370
+ "Step 5: Attempt PATCH /api/accounts/:id with { name: 'Updated' }",
371
+ "Step 6: Verify 200 success"
372
+ ],
373
+ "passes": false
374
+ },
375
+ {
376
+ "category": "functional",
377
+ "description": "Delete account requires Super Admin",
378
+ "steps": [
379
+ "Step 1: Log in as account ADMIN (not super)",
380
+ "Step 2: Attempt DELETE /api/accounts/:id",
381
+ "Step 3: Verify 403 Forbidden",
382
+ "Step 4: Log in as Super Admin",
383
+ "Step 5: Attempt DELETE /api/accounts/:id",
384
+ "Step 6: Verify 204 No Content",
385
+ "Step 7: Verify soft delete with deletedAt set"
386
+ ],
387
+ "passes": false
388
+ },
389
+ {
390
+ "category": "functional",
391
+ "description": "Restore account requires Super Admin",
392
+ "steps": [
393
+ "Step 1: Soft delete an account",
394
+ "Step 2: Log in as regular ADMIN",
395
+ "Step 3: Attempt POST /api/accounts/:id/restore",
396
+ "Step 4: Verify 403 Forbidden",
397
+ "Step 5: Log in as Super Admin",
398
+ "Step 6: Attempt POST /api/accounts/:id/restore",
399
+ "Step 7: Verify account restored"
400
+ ],
401
+ "passes": false
402
+ },
403
+ {
404
+ "category": "functional",
405
+ "description": "Create invitation sends email to new user",
406
+ "steps": [
407
+ "Step 1: Log in as account member",
408
+ "Step 2: Send POST /api/invitations with { email: 'new@example.com', role: 'VIEWER' }",
409
+ "Step 3: Verify 201 Created response",
410
+ "Step 4: Verify invitation record created in database",
411
+ "Step 5: Verify invitation token generated (64 chars)",
412
+ "Step 6: Verify email sent via SendGrid",
413
+ "Step 7: Verify expiration set to 7 days",
414
+ "Step 8: Verify INSERT audit event logged"
415
+ ],
416
+ "passes": false
417
+ },
418
+ {
419
+ "category": "functional",
420
+ "description": "Create invitation links existing user immediately",
421
+ "steps": [
422
+ "Step 1: Ensure target user exists in system",
423
+ "Step 2: Log in as account member",
424
+ "Step 3: Send POST /api/invitations for existing user's email",
425
+ "Step 4: Verify response { linked: true }",
426
+ "Step 5: Verify user_accounts record created",
427
+ "Step 6: Verify no email sent"
428
+ ],
429
+ "passes": false
430
+ },
431
+ {
432
+ "category": "functional",
433
+ "description": "Create invitation prevents duplicate invitations",
434
+ "steps": [
435
+ "Step 1: Send invitation to email@example.com",
436
+ "Step 2: Attempt to send another invitation to same email for same account",
437
+ "Step 3: Verify error response about existing invitation"
438
+ ],
439
+ "passes": false
440
+ },
441
+ {
442
+ "category": "functional",
443
+ "description": "List invitations returns pending invitations for account",
444
+ "steps": [
445
+ "Step 1: Create multiple invitations for account",
446
+ "Step 2: Log in as account member",
447
+ "Step 3: Send GET /api/invitations",
448
+ "Step 4: Verify all pending invitations returned",
449
+ "Step 5: Verify accepted invitations not included"
450
+ ],
451
+ "passes": false
452
+ },
453
+ {
454
+ "category": "functional",
455
+ "description": "Delete invitation revokes pending invitation",
456
+ "steps": [
457
+ "Step 1: Create an invitation",
458
+ "Step 2: Log in as MANAGER user",
459
+ "Step 3: Send DELETE /api/invitations/:id",
460
+ "Step 4: Verify 204 No Content",
461
+ "Step 5: Verify invitation deleted from database",
462
+ "Step 6: Verify DELETE audit event logged",
463
+ "Step 7: Verify token no longer works for acceptance"
464
+ ],
465
+ "passes": false
466
+ },
467
+ {
468
+ "category": "functional",
469
+ "description": "Delete invitation requires MANAGER role",
470
+ "steps": [
471
+ "Step 1: Create an invitation",
472
+ "Step 2: Log in as VIEWER user",
473
+ "Step 3: Attempt DELETE /api/invitations/:id",
474
+ "Step 4: Verify 403 Forbidden"
475
+ ],
476
+ "passes": false
477
+ },
478
+ {
479
+ "category": "functional",
480
+ "description": "Query audit logs returns paginated results",
481
+ "steps": [
482
+ "Step 1: Generate some audit events (login, create, update)",
483
+ "Step 2: Log in as ADMIN user",
484
+ "Step 3: Send GET /api/audits?page=1&limit=10",
485
+ "Step 4: Verify data array with audit logs",
486
+ "Step 5: Verify pagination meta"
487
+ ],
488
+ "passes": false
489
+ },
490
+ {
491
+ "category": "functional",
492
+ "description": "Query audit logs filters by entity type",
493
+ "steps": [
494
+ "Step 1: Generate events for different entities",
495
+ "Step 2: Log in as ADMIN user",
496
+ "Step 3: Send GET /api/audits?entity=User",
497
+ "Step 4: Verify only User entity logs returned"
498
+ ],
499
+ "passes": false
500
+ },
501
+ {
502
+ "category": "functional",
503
+ "description": "Query audit logs filters by action type",
504
+ "steps": [
505
+ "Step 1: Generate INSERT, UPDATE, DELETE events",
506
+ "Step 2: Log in as ADMIN user",
507
+ "Step 3: Send GET /api/audits?action=INSERT",
508
+ "Step 4: Verify only INSERT actions returned"
509
+ ],
510
+ "passes": false
511
+ },
512
+ {
513
+ "category": "functional",
514
+ "description": "Query audit logs filters by entity ID",
515
+ "steps": [
516
+ "Step 1: Generate events for specific entity",
517
+ "Step 2: Log in as ADMIN user",
518
+ "Step 3: Send GET /api/audits?entityId=<uuid>",
519
+ "Step 4: Verify only logs for that entity returned"
520
+ ],
521
+ "passes": false
522
+ },
523
+ {
524
+ "category": "functional",
525
+ "description": "Audit logs require ADMIN or ANALYTICS role",
526
+ "steps": [
527
+ "Step 1: Log in as VIEWER user",
528
+ "Step 2: Attempt GET /api/audits",
529
+ "Step 3: Verify 403 Forbidden",
530
+ "Step 4: Log in as ANALYTICS user",
531
+ "Step 5: Attempt GET /api/audits",
532
+ "Step 6: Verify 200 success"
533
+ ],
534
+ "passes": false
535
+ },
536
+ {
537
+ "category": "functional",
538
+ "description": "Super admin sees audit logs for all accounts",
539
+ "steps": [
540
+ "Step 1: Create events in multiple accounts",
541
+ "Step 2: Log in as Super Admin",
542
+ "Step 3: Send GET /api/audits",
543
+ "Step 4: Verify logs from all accounts visible"
544
+ ],
545
+ "passes": false
546
+ },
547
+ {
548
+ "category": "functional",
549
+ "description": "Regular admin sees only own account's audit logs",
550
+ "steps": [
551
+ "Step 1: Create events in multiple accounts",
552
+ "Step 2: Log in as regular ADMIN",
553
+ "Step 3: Send GET /api/audits",
554
+ "Step 4: Verify only current account's logs visible"
555
+ ],
556
+ "passes": false
557
+ },
558
+ {
559
+ "category": "functional",
560
+ "description": "Generate presigned upload URL for R2",
561
+ "steps": [
562
+ "Step 1: Log in as authenticated user",
563
+ "Step 2: Send POST /api/storage/upload-url with { filename: 'test.jpg', contentType: 'image/jpeg' }",
564
+ "Step 3: Verify response contains uploadUrl",
565
+ "Step 4: Verify response contains key",
566
+ "Step 5: Verify response contains publicUrl"
567
+ ],
568
+ "passes": false
569
+ },
570
+ {
571
+ "category": "functional",
572
+ "description": "Upload file directly to R2",
573
+ "steps": [
574
+ "Step 1: Log in as authenticated user",
575
+ "Step 2: Generate upload URL for file",
576
+ "Step 3: Send PUT /api/storage/upload/:key with file data",
577
+ "Step 4: Verify 200 response with key, url, size",
578
+ "Step 5: Verify file accessible at publicUrl"
579
+ ],
580
+ "passes": false
581
+ },
582
+ {
583
+ "category": "functional",
584
+ "description": "Delete file from R2",
585
+ "steps": [
586
+ "Step 1: Upload a file to R2",
587
+ "Step 2: Log in as authenticated user",
588
+ "Step 3: Send DELETE /api/storage/:key",
589
+ "Step 4: Verify 204 No Content",
590
+ "Step 5: Verify file no longer accessible"
591
+ ],
592
+ "passes": false
593
+ },
594
+ {
595
+ "category": "functional",
596
+ "description": "Storage endpoints require authentication",
597
+ "steps": [
598
+ "Step 1: Clear session cookies",
599
+ "Step 2: Attempt POST /api/storage/upload-url",
600
+ "Step 3: Verify 401 Unauthorized"
601
+ ],
602
+ "passes": false
603
+ },
604
+ {
605
+ "category": "functional",
606
+ "description": "Health check returns status ok",
607
+ "steps": [
608
+ "Step 1: Send GET /health",
609
+ "Step 2: Verify 200 response",
610
+ "Step 3: Verify response contains { status: 'ok' }",
611
+ "Step 4: Verify timestamp is present",
612
+ "Step 5: Verify environment field present"
613
+ ],
614
+ "passes": false
615
+ },
616
+ {
617
+ "category": "functional",
618
+ "description": "OpenAPI documentation is accessible",
619
+ "steps": [
620
+ "Step 1: Send GET /api/doc",
621
+ "Step 2: Verify JSON response with OpenAPI schema",
622
+ "Step 3: Verify paths are documented",
623
+ "Step 4: Verify schemas are defined"
624
+ ],
625
+ "passes": false
626
+ },
627
+ {
628
+ "category": "functional",
629
+ "description": "Swagger UI is accessible",
630
+ "steps": [
631
+ "Step 1: Navigate to /api/swagger",
632
+ "Step 2: Verify Swagger UI loads",
633
+ "Step 3: Verify endpoints are listed",
634
+ "Step 4: Verify Try It Out functionality works"
635
+ ],
636
+ "passes": false
637
+ },
638
+ {
639
+ "category": "functional",
640
+ "description": "Request context includes transactionId for tracing",
641
+ "steps": [
642
+ "Step 1: Make an API request",
643
+ "Step 2: Check response headers for transaction ID",
644
+ "Step 3: Verify audit logs contain matching transactionId",
645
+ "Step 4: Verify related operations share same transactionId"
646
+ ],
647
+ "passes": false
648
+ },
649
+ {
650
+ "category": "functional",
651
+ "description": "Account middleware extracts accountId from query parameter",
652
+ "steps": [
653
+ "Step 1: Log in as user with multiple accounts",
654
+ "Step 2: Send request with ?accountId=<uuid>",
655
+ "Step 3: Verify request is scoped to that account",
656
+ "Step 4: Verify response data from correct account"
657
+ ],
658
+ "passes": false
659
+ },
660
+ {
661
+ "category": "functional",
662
+ "description": "Account middleware extracts accountId from header",
663
+ "steps": [
664
+ "Step 1: Log in as user with multiple accounts",
665
+ "Step 2: Send request with X-Account-Id header",
666
+ "Step 3: Verify request is scoped to that account"
667
+ ],
668
+ "passes": false
669
+ },
670
+ {
671
+ "category": "functional",
672
+ "description": "Role hierarchy enforces permission levels",
673
+ "steps": [
674
+ "Step 1: Verify ADMIN > MANAGER > EDITOR > AUTHOR > VIEWER",
675
+ "Step 2: Test VIEWER cannot perform EDITOR actions",
676
+ "Step 3: Test EDITOR cannot perform MANAGER actions",
677
+ "Step 4: Test MANAGER cannot perform ADMIN actions",
678
+ "Step 5: Verify BILLING is non-hierarchical",
679
+ "Step 6: Verify ANALYTICS is non-hierarchical"
680
+ ],
681
+ "passes": false
682
+ },
683
+ {
684
+ "category": "functional",
685
+ "description": "VIEWER role has read-only access",
686
+ "steps": [
687
+ "Step 1: Log in as VIEWER user",
688
+ "Step 2: Verify GET requests succeed (list, get)",
689
+ "Step 3: Verify POST requests fail (create)",
690
+ "Step 4: Verify PATCH requests fail (update)",
691
+ "Step 5: Verify DELETE requests fail"
692
+ ],
693
+ "passes": false
694
+ },
695
+ {
696
+ "category": "functional",
697
+ "description": "EDITOR role can create and modify content",
698
+ "steps": [
699
+ "Step 1: Log in as EDITOR user",
700
+ "Step 2: Verify can create resources",
701
+ "Step 3: Verify can update resources",
702
+ "Step 4: Verify cannot manage users",
703
+ "Step 5: Verify cannot delete accounts"
704
+ ],
705
+ "passes": false
706
+ },
707
+ {
708
+ "category": "functional",
709
+ "description": "MANAGER role can manage team members",
710
+ "steps": [
711
+ "Step 1: Log in as MANAGER user",
712
+ "Step 2: Verify can create invitations",
713
+ "Step 3: Verify can revoke invitations",
714
+ "Step 4: Verify can assign users to accounts",
715
+ "Step 5: Verify cannot delete accounts"
716
+ ],
717
+ "passes": false
718
+ },
719
+ {
720
+ "category": "functional",
721
+ "description": "ADMIN role has full account management",
722
+ "steps": [
723
+ "Step 1: Log in as ADMIN user",
724
+ "Step 2: Verify can update account settings",
725
+ "Step 3: Verify can manage all users in account",
726
+ "Step 4: Verify can view audit logs",
727
+ "Step 5: Verify cannot create new accounts (super admin only)"
728
+ ],
729
+ "passes": false
730
+ },
731
+ {
732
+ "category": "functional",
733
+ "description": "BILLING role can access financial operations",
734
+ "steps": [
735
+ "Step 1: Log in as BILLING user",
736
+ "Step 2: Verify access to billing endpoints",
737
+ "Step 3: Verify cannot manage users",
738
+ "Step 4: Verify cannot modify account settings"
739
+ ],
740
+ "passes": false
741
+ },
742
+ {
743
+ "category": "functional",
744
+ "description": "ANALYTICS role can access reporting",
745
+ "steps": [
746
+ "Step 1: Log in as ANALYTICS user",
747
+ "Step 2: Verify can access audit logs",
748
+ "Step 3: Verify can access analytics endpoints",
749
+ "Step 4: Verify cannot modify data"
750
+ ],
751
+ "passes": false
752
+ },
753
+ {
754
+ "category": "functional",
755
+ "description": "Landing page loads for unauthenticated users",
756
+ "steps": [
757
+ "Step 1: Clear all cookies",
758
+ "Step 2: Navigate to /",
759
+ "Step 3: Verify landing page displays",
760
+ "Step 4: Verify hero section visible",
761
+ "Step 5: Verify features section visible",
762
+ "Step 6: Verify CTA buttons work"
763
+ ],
764
+ "passes": false
765
+ },
766
+ {
767
+ "category": "functional",
768
+ "description": "Login page displays Google OAuth button",
769
+ "steps": [
770
+ "Step 1: Navigate to /login",
771
+ "Step 2: Verify login card displays",
772
+ "Step 3: Verify Google sign-in button visible",
773
+ "Step 4: Click Google button",
774
+ "Step 5: Verify redirect to /auth/login"
775
+ ],
776
+ "passes": false
777
+ },
778
+ {
779
+ "category": "functional",
780
+ "description": "Login page redirects authenticated users to dashboard",
781
+ "steps": [
782
+ "Step 1: Log in successfully",
783
+ "Step 2: Navigate to /login",
784
+ "Step 3: Verify automatic redirect to /dashboard"
785
+ ],
786
+ "passes": false
787
+ },
788
+ {
789
+ "category": "functional",
790
+ "description": "Invitation page validates token and shows invitation details",
791
+ "steps": [
792
+ "Step 1: Create invitation for account",
793
+ "Step 2: Navigate to /invite/:token",
794
+ "Step 3: Verify invitation details displayed",
795
+ "Step 4: Verify account name shown",
796
+ "Step 5: Verify role shown",
797
+ "Step 6: Verify accept button visible"
798
+ ],
799
+ "passes": false
800
+ },
801
+ {
802
+ "category": "functional",
803
+ "description": "Dashboard displays welcome message with user's name",
804
+ "steps": [
805
+ "Step 1: Log in as 'John Doe'",
806
+ "Step 2: Navigate to /dashboard",
807
+ "Step 3: Verify 'Welcome, John' or similar message displays"
808
+ ],
809
+ "passes": false
810
+ },
811
+ {
812
+ "category": "functional",
813
+ "description": "Dashboard displays stats cards",
814
+ "steps": [
815
+ "Step 1: Log in as authenticated user",
816
+ "Step 2: Navigate to /dashboard",
817
+ "Step 3: Verify users count card visible",
818
+ "Step 4: Verify accounts count card visible",
819
+ "Step 5: Verify API requests card visible",
820
+ "Step 6: Verify uptime card visible"
821
+ ],
822
+ "passes": false
823
+ },
824
+ {
825
+ "category": "functional",
826
+ "description": "Dashboard displays quick action cards",
827
+ "steps": [
828
+ "Step 1: Navigate to /dashboard",
829
+ "Step 2: Verify 'Invite Team' quick action visible",
830
+ "Step 3: Verify 'Database' quick action visible",
831
+ "Step 4: Verify 'Security' quick action visible",
832
+ "Step 5: Verify clicking action navigates correctly"
833
+ ],
834
+ "passes": false
835
+ },
836
+ {
837
+ "category": "functional",
838
+ "description": "Team management page lists active members",
839
+ "steps": [
840
+ "Step 1: Add multiple users to account",
841
+ "Step 2: Navigate to /team",
842
+ "Step 3: Verify all active members listed",
843
+ "Step 4: Verify name, email, role displayed for each",
844
+ "Step 5: Verify avatar displayed for each"
845
+ ],
846
+ "passes": false
847
+ },
848
+ {
849
+ "category": "functional",
850
+ "description": "Team management page supports search/filter",
851
+ "steps": [
852
+ "Step 1: Add multiple team members",
853
+ "Step 2: Navigate to /team",
854
+ "Step 3: Enter search query in search box",
855
+ "Step 4: Verify list filters by name/email",
856
+ "Step 5: Clear search and verify full list returns"
857
+ ],
858
+ "passes": false
859
+ },
860
+ {
861
+ "category": "functional",
862
+ "description": "Team management invite member dialog opens",
863
+ "steps": [
864
+ "Step 1: Navigate to /team",
865
+ "Step 2: Click 'Invite Member' button",
866
+ "Step 3: Verify dialog opens",
867
+ "Step 4: Verify email input field present",
868
+ "Step 5: Verify role selector present",
869
+ "Step 6: Verify send button present"
870
+ ],
871
+ "passes": false
872
+ },
873
+ {
874
+ "category": "functional",
875
+ "description": "Team management creates invitation from dialog",
876
+ "steps": [
877
+ "Step 1: Open invite dialog on /team",
878
+ "Step 2: Enter email address",
879
+ "Step 3: Select role from dropdown",
880
+ "Step 4: Click send button",
881
+ "Step 5: Verify success toast displayed",
882
+ "Step 6: Verify dialog closes",
883
+ "Step 7: Verify invitation appears in pending list"
884
+ ],
885
+ "passes": false
886
+ },
887
+ {
888
+ "category": "functional",
889
+ "description": "Team management shows pending invitations with expiry",
890
+ "steps": [
891
+ "Step 1: Create several invitations",
892
+ "Step 2: Navigate to /team",
893
+ "Step 3: Scroll to pending invitations section",
894
+ "Step 4: Verify each invitation shows email",
895
+ "Step 5: Verify each shows expiry countdown",
896
+ "Step 6: Verify resend button visible",
897
+ "Step 7: Verify revoke button visible"
898
+ ],
899
+ "passes": false
900
+ },
901
+ {
902
+ "category": "functional",
903
+ "description": "Team management can revoke pending invitation",
904
+ "steps": [
905
+ "Step 1: Create an invitation",
906
+ "Step 2: Navigate to /team",
907
+ "Step 3: Click revoke button on invitation",
908
+ "Step 4: Confirm in dialog if prompted",
909
+ "Step 5: Verify success toast",
910
+ "Step 6: Verify invitation removed from list"
911
+ ],
912
+ "passes": false
913
+ },
914
+ {
915
+ "category": "functional",
916
+ "description": "Settings page displays user profile",
917
+ "steps": [
918
+ "Step 1: Navigate to /settings",
919
+ "Step 2: Verify profile card displays avatar",
920
+ "Step 3: Verify name displayed",
921
+ "Step 4: Verify email displayed"
922
+ ],
923
+ "passes": false
924
+ },
925
+ {
926
+ "category": "functional",
927
+ "description": "Settings page allows profile editing",
928
+ "steps": [
929
+ "Step 1: Navigate to /settings",
930
+ "Step 2: Click edit profile button",
931
+ "Step 3: Modify name in form",
932
+ "Step 4: Submit form",
933
+ "Step 5: Verify success toast",
934
+ "Step 6: Verify name updated in display"
935
+ ],
936
+ "passes": false
937
+ },
938
+ {
939
+ "category": "functional",
940
+ "description": "Settings page shows connected accounts",
941
+ "steps": [
942
+ "Step 1: Navigate to /settings",
943
+ "Step 2: Scroll to connected accounts section",
944
+ "Step 3: Verify Google account connection shown",
945
+ "Step 4: Verify connection status indicator"
946
+ ],
947
+ "passes": false
948
+ },
949
+ {
950
+ "category": "functional",
951
+ "description": "Settings page shows notification preferences",
952
+ "steps": [
953
+ "Step 1: Navigate to /settings",
954
+ "Step 2: Find notification preferences section",
955
+ "Step 3: Verify toggle switches present",
956
+ "Step 4: Toggle a preference",
957
+ "Step 5: Verify preference persists on reload"
958
+ ],
959
+ "passes": false
960
+ },
961
+ {
962
+ "category": "functional",
963
+ "description": "Account security page shows active sessions",
964
+ "steps": [
965
+ "Step 1: Navigate to /account",
966
+ "Step 2: Find active sessions section",
967
+ "Step 3: Verify current session listed",
968
+ "Step 4: Verify device/browser info shown",
969
+ "Step 5: Verify location info if available"
970
+ ],
971
+ "passes": false
972
+ },
973
+ {
974
+ "category": "functional",
975
+ "description": "Account security page shows danger zone",
976
+ "steps": [
977
+ "Step 1: Navigate to /account",
978
+ "Step 2: Scroll to danger zone section",
979
+ "Step 3: Verify export data option visible",
980
+ "Step 4: Verify delete account option visible",
981
+ "Step 5: Verify actions require confirmation"
982
+ ],
983
+ "passes": false
984
+ },
985
+ {
986
+ "category": "functional",
987
+ "description": "Account deletion requires confirmation",
988
+ "steps": [
989
+ "Step 1: Navigate to /account",
990
+ "Step 2: Click delete account button",
991
+ "Step 3: Verify confirmation dialog opens",
992
+ "Step 4: Verify warning message displayed",
993
+ "Step 5: Verify must type confirmation text",
994
+ "Step 6: Cancel and verify dialog closes"
995
+ ],
996
+ "passes": false
997
+ },
998
+ {
999
+ "category": "functional",
1000
+ "description": "Integrations page displays integration grid",
1001
+ "steps": [
1002
+ "Step 1: Navigate to /integrations",
1003
+ "Step 2: Verify integration grid displays",
1004
+ "Step 3: Verify Slack integration card",
1005
+ "Step 4: Verify Discord integration card",
1006
+ "Step 5: Verify Stripe integration card",
1007
+ "Step 6: Verify GitHub integration card"
1008
+ ],
1009
+ "passes": false
1010
+ },
1011
+ {
1012
+ "category": "functional",
1013
+ "description": "Integrations page supports category filtering",
1014
+ "steps": [
1015
+ "Step 1: Navigate to /integrations",
1016
+ "Step 2: Find category filter",
1017
+ "Step 3: Select a category",
1018
+ "Step 4: Verify grid filters to show only that category"
1019
+ ],
1020
+ "passes": false
1021
+ },
1022
+ {
1023
+ "category": "functional",
1024
+ "description": "Integrations page supports search",
1025
+ "steps": [
1026
+ "Step 1: Navigate to /integrations",
1027
+ "Step 2: Enter search term (e.g., 'slack')",
1028
+ "Step 3: Verify only matching integrations shown"
1029
+ ],
1030
+ "passes": false
1031
+ },
1032
+ {
1033
+ "category": "functional",
1034
+ "description": "Integrations page webhook configuration section",
1035
+ "steps": [
1036
+ "Step 1: Navigate to /integrations",
1037
+ "Step 2: Find webhooks section",
1038
+ "Step 3: Click create webhook button",
1039
+ "Step 4: Verify dialog opens with URL field",
1040
+ "Step 5: Verify event selection available"
1041
+ ],
1042
+ "passes": false
1043
+ },
1044
+ {
1045
+ "category": "functional",
1046
+ "description": "Sidebar navigation works correctly",
1047
+ "steps": [
1048
+ "Step 1: Log in and view sidebar",
1049
+ "Step 2: Click Dashboard link",
1050
+ "Step 3: Verify navigation to /dashboard",
1051
+ "Step 4: Click Team link",
1052
+ "Step 5: Verify navigation to /team",
1053
+ "Step 6: Repeat for Settings, Account, Integrations"
1054
+ ],
1055
+ "passes": false
1056
+ },
1057
+ {
1058
+ "category": "functional",
1059
+ "description": "Sidebar shows user profile card",
1060
+ "steps": [
1061
+ "Step 1: Log in as authenticated user",
1062
+ "Step 2: View sidebar",
1063
+ "Step 3: Verify avatar displayed",
1064
+ "Step 4: Verify user name displayed",
1065
+ "Step 5: Verify logout button accessible"
1066
+ ],
1067
+ "passes": false
1068
+ },
1069
+ {
1070
+ "category": "functional",
1071
+ "description": "Sidebar logout button logs user out",
1072
+ "steps": [
1073
+ "Step 1: Log in and view sidebar",
1074
+ "Step 2: Click logout button",
1075
+ "Step 3: Verify session destroyed",
1076
+ "Step 4: Verify redirect to login page"
1077
+ ],
1078
+ "passes": false
1079
+ },
1080
+ {
1081
+ "category": "functional",
1082
+ "description": "Protected routes redirect unauthenticated users to login",
1083
+ "steps": [
1084
+ "Step 1: Clear session cookies",
1085
+ "Step 2: Navigate to /dashboard",
1086
+ "Step 3: Verify redirect to /login",
1087
+ "Step 4: Navigate to /team",
1088
+ "Step 5: Verify redirect to /login"
1089
+ ],
1090
+ "passes": false
1091
+ },
1092
+ {
1093
+ "category": "functional",
1094
+ "description": "Form validation shows inline error messages",
1095
+ "steps": [
1096
+ "Step 1: Navigate to form (e.g., invite dialog)",
1097
+ "Step 2: Submit with empty required fields",
1098
+ "Step 3: Verify inline error messages appear",
1099
+ "Step 4: Verify specific field validation messages"
1100
+ ],
1101
+ "passes": false
1102
+ },
1103
+ {
1104
+ "category": "functional",
1105
+ "description": "Form submission shows loading state",
1106
+ "steps": [
1107
+ "Step 1: Fill out a form",
1108
+ "Step 2: Click submit button",
1109
+ "Step 3: Verify button shows loading indicator",
1110
+ "Step 4: Verify button is disabled during submission"
1111
+ ],
1112
+ "passes": false
1113
+ },
1114
+ {
1115
+ "category": "functional",
1116
+ "description": "Toast notifications appear for success actions",
1117
+ "steps": [
1118
+ "Step 1: Perform successful action (e.g., save settings)",
1119
+ "Step 2: Verify success toast appears",
1120
+ "Step 3: Verify toast has green styling",
1121
+ "Step 4: Verify toast auto-dismisses"
1122
+ ],
1123
+ "passes": false
1124
+ },
1125
+ {
1126
+ "category": "functional",
1127
+ "description": "Toast notifications appear for error actions",
1128
+ "steps": [
1129
+ "Step 1: Trigger an error (e.g., invalid form submission)",
1130
+ "Step 2: Verify error toast appears",
1131
+ "Step 3: Verify toast has red styling",
1132
+ "Step 4: Verify error message is descriptive"
1133
+ ],
1134
+ "passes": false
1135
+ },
1136
+ {
1137
+ "category": "functional",
1138
+ "description": "Error boundary catches and displays runtime errors",
1139
+ "steps": [
1140
+ "Step 1: Trigger a runtime error in component",
1141
+ "Step 2: Verify error boundary catches error",
1142
+ "Step 3: Verify error message displayed",
1143
+ "Step 4: Verify retry button available",
1144
+ "Step 5: Verify go home button available"
1145
+ ],
1146
+ "passes": false
1147
+ },
1148
+ {
1149
+ "category": "functional",
1150
+ "description": "404 page displays for unknown routes",
1151
+ "steps": [
1152
+ "Step 1: Navigate to /nonexistent-page",
1153
+ "Step 2: Verify 404 page displays",
1154
+ "Step 3: Verify helpful message shown",
1155
+ "Step 4: Verify link to home page"
1156
+ ],
1157
+ "passes": false
1158
+ },
1159
+ {
1160
+ "category": "functional",
1161
+ "description": "API returns proper 404 for unknown endpoints",
1162
+ "steps": [
1163
+ "Step 1: Send GET /api/unknown-endpoint",
1164
+ "Step 2: Verify 404 response status",
1165
+ "Step 3: Verify error message in response body"
1166
+ ],
1167
+ "passes": false
1168
+ },
1169
+ {
1170
+ "category": "functional",
1171
+ "description": "API returns proper 401 for unauthenticated requests",
1172
+ "steps": [
1173
+ "Step 1: Clear all auth cookies/headers",
1174
+ "Step 2: Send GET to protected endpoint",
1175
+ "Step 3: Verify 401 Unauthorized response",
1176
+ "Step 4: Verify no sensitive data leaked"
1177
+ ],
1178
+ "passes": false
1179
+ },
1180
+ {
1181
+ "category": "functional",
1182
+ "description": "API returns proper 403 for unauthorized actions",
1183
+ "steps": [
1184
+ "Step 1: Log in as VIEWER user",
1185
+ "Step 2: Attempt admin-only action",
1186
+ "Step 3: Verify 403 Forbidden response",
1187
+ "Step 4: Verify meaningful error message"
1188
+ ],
1189
+ "passes": false
1190
+ },
1191
+ {
1192
+ "category": "functional",
1193
+ "description": "API validation returns 400 for invalid input",
1194
+ "steps": [
1195
+ "Step 1: Send POST with invalid JSON",
1196
+ "Step 2: Verify 400 Bad Request response",
1197
+ "Step 3: Verify validation errors listed",
1198
+ "Step 4: Verify field-specific error messages"
1199
+ ],
1200
+ "passes": false
1201
+ },
1202
+ {
1203
+ "category": "functional",
1204
+ "description": "API handles malformed UUIDs gracefully",
1205
+ "steps": [
1206
+ "Step 1: Send GET /api/users/not-a-uuid",
1207
+ "Step 2: Verify proper error response",
1208
+ "Step 3: Verify no stack trace in production"
1209
+ ],
1210
+ "passes": false
1211
+ },
1212
+ {
1213
+ "category": "functional",
1214
+ "description": "CORS allows requests from configured origins",
1215
+ "steps": [
1216
+ "Step 1: Configure CORS_ORIGINS in env",
1217
+ "Step 2: Make request from allowed origin",
1218
+ "Step 3: Verify request succeeds",
1219
+ "Step 4: Verify proper CORS headers in response"
1220
+ ],
1221
+ "passes": false
1222
+ },
1223
+ {
1224
+ "category": "functional",
1225
+ "description": "CORS blocks requests from unknown origins",
1226
+ "steps": [
1227
+ "Step 1: Make request from unlisted origin",
1228
+ "Step 2: Verify CORS headers reject request",
1229
+ "Step 3: Verify no data returned"
1230
+ ],
1231
+ "passes": false
1232
+ },
1233
+ {
1234
+ "category": "functional",
1235
+ "description": "Session cookie has httpOnly flag",
1236
+ "steps": [
1237
+ "Step 1: Log in successfully",
1238
+ "Step 2: Inspect session_id cookie",
1239
+ "Step 3: Verify httpOnly flag is set",
1240
+ "Step 4: Verify cookie not accessible via JavaScript"
1241
+ ],
1242
+ "passes": false
1243
+ },
1244
+ {
1245
+ "category": "functional",
1246
+ "description": "Session cookie has secure flag in production",
1247
+ "steps": [
1248
+ "Step 1: Deploy to production",
1249
+ "Step 2: Log in successfully",
1250
+ "Step 3: Inspect session_id cookie",
1251
+ "Step 4: Verify secure flag is set"
1252
+ ],
1253
+ "passes": false
1254
+ },
1255
+ {
1256
+ "category": "functional",
1257
+ "description": "Session cookie has sameSite=Lax",
1258
+ "steps": [
1259
+ "Step 1: Log in successfully",
1260
+ "Step 2: Inspect session_id cookie",
1261
+ "Step 3: Verify sameSite attribute is Lax"
1262
+ ],
1263
+ "passes": false
1264
+ },
1265
+ {
1266
+ "category": "functional",
1267
+ "description": "Soft deleted records are excluded from list queries",
1268
+ "steps": [
1269
+ "Step 1: Create a user",
1270
+ "Step 2: Soft delete the user",
1271
+ "Step 3: Query GET /api/users",
1272
+ "Step 4: Verify deleted user not in results"
1273
+ ],
1274
+ "passes": false
1275
+ },
1276
+ {
1277
+ "category": "functional",
1278
+ "description": "Soft deleted records preserve data integrity",
1279
+ "steps": [
1280
+ "Step 1: Create user with account relationships",
1281
+ "Step 2: Soft delete the user",
1282
+ "Step 3: Verify user record still in database",
1283
+ "Step 4: Verify relationships intact",
1284
+ "Step 5: Verify audit logs reference user"
1285
+ ],
1286
+ "passes": false
1287
+ },
1288
+ {
1289
+ "category": "functional",
1290
+ "description": "Audit log captures IP address",
1291
+ "steps": [
1292
+ "Step 1: Perform an action that creates audit log",
1293
+ "Step 2: Query audit logs for that action",
1294
+ "Step 3: Verify ipAddress field populated"
1295
+ ],
1296
+ "passes": false
1297
+ },
1298
+ {
1299
+ "category": "functional",
1300
+ "description": "Audit log captures User-Agent",
1301
+ "steps": [
1302
+ "Step 1: Perform an action from browser",
1303
+ "Step 2: Query audit logs",
1304
+ "Step 3: Verify userAgent field contains browser info"
1305
+ ],
1306
+ "passes": false
1307
+ },
1308
+ {
1309
+ "category": "functional",
1310
+ "description": "Audit log captures before/after state for updates",
1311
+ "steps": [
1312
+ "Step 1: Update a user's name",
1313
+ "Step 2: Query audit logs for UPDATE action",
1314
+ "Step 3: Verify changes field contains old value",
1315
+ "Step 4: Verify changes field contains new value"
1316
+ ],
1317
+ "passes": false
1318
+ },
1319
+ {
1320
+ "category": "functional",
1321
+ "description": "Multiple accounts can have same user with different roles",
1322
+ "steps": [
1323
+ "Step 1: Create two accounts",
1324
+ "Step 2: Add same user to both accounts",
1325
+ "Step 3: Assign ADMIN role in account A",
1326
+ "Step 4: Assign VIEWER role in account B",
1327
+ "Step 5: Verify user has correct role in each context"
1328
+ ],
1329
+ "passes": false
1330
+ },
1331
+ {
1332
+ "category": "functional",
1333
+ "description": "User can switch between accounts",
1334
+ "steps": [
1335
+ "Step 1: Log in as user with multiple accounts",
1336
+ "Step 2: Make request to account A",
1337
+ "Step 3: Make request to account B",
1338
+ "Step 4: Verify correct data isolation for each"
1339
+ ],
1340
+ "passes": false
1341
+ },
1342
+ {
1343
+ "category": "functional",
1344
+ "description": "Test login endpoint works in development mode",
1345
+ "steps": [
1346
+ "Step 1: Set environment to development",
1347
+ "Step 2: Send POST to /auth/test-login with user data",
1348
+ "Step 3: Verify session created",
1349
+ "Step 4: Verify can access protected routes"
1350
+ ],
1351
+ "passes": false
1352
+ },
1353
+ {
1354
+ "category": "functional",
1355
+ "description": "Test login endpoint disabled in production",
1356
+ "steps": [
1357
+ "Step 1: Set environment to production",
1358
+ "Step 2: Attempt POST to /auth/test-login",
1359
+ "Step 3: Verify 404 or 403 response"
1360
+ ],
1361
+ "passes": false
1362
+ },
1363
+ {
1364
+ "category": "style",
1365
+ "description": "Landing page hero section has proper layout",
1366
+ "steps": [
1367
+ "Step 1: Navigate to /",
1368
+ "Step 2: Take screenshot of hero section",
1369
+ "Step 3: Verify headline is prominent",
1370
+ "Step 4: Verify subheadline is readable",
1371
+ "Step 5: Verify CTA buttons are prominent"
1372
+ ],
1373
+ "passes": false
1374
+ },
1375
+ {
1376
+ "category": "style",
1377
+ "description": "Login page card is centered on screen",
1378
+ "steps": [
1379
+ "Step 1: Navigate to /login",
1380
+ "Step 2: Take screenshot",
1381
+ "Step 3: Verify card is horizontally centered",
1382
+ "Step 4: Verify card is vertically centered"
1383
+ ],
1384
+ "passes": false
1385
+ },
1386
+ {
1387
+ "category": "style",
1388
+ "description": "Dashboard uses consistent card styling",
1389
+ "steps": [
1390
+ "Step 1: Navigate to /dashboard",
1391
+ "Step 2: Inspect all cards on page",
1392
+ "Step 3: Verify consistent border radius",
1393
+ "Step 4: Verify consistent shadow depth",
1394
+ "Step 5: Verify consistent padding"
1395
+ ],
1396
+ "passes": false
1397
+ },
1398
+ {
1399
+ "category": "style",
1400
+ "description": "Primary buttons use brand color",
1401
+ "steps": [
1402
+ "Step 1: Find primary button on page",
1403
+ "Step 2: Verify background matches brand color",
1404
+ "Step 3: Verify text is readable on background",
1405
+ "Step 4: Verify hover state changes color"
1406
+ ],
1407
+ "passes": false
1408
+ },
1409
+ {
1410
+ "category": "style",
1411
+ "description": "Secondary buttons have outline style",
1412
+ "steps": [
1413
+ "Step 1: Find secondary button on page",
1414
+ "Step 2: Verify outline border visible",
1415
+ "Step 3: Verify background is transparent",
1416
+ "Step 4: Verify hover state fills background"
1417
+ ],
1418
+ "passes": false
1419
+ },
1420
+ {
1421
+ "category": "style",
1422
+ "description": "Destructive buttons use red color",
1423
+ "steps": [
1424
+ "Step 1: Find destructive button (e.g., delete)",
1425
+ "Step 2: Verify red background color (#dc2626)",
1426
+ "Step 3: Verify white text for contrast"
1427
+ ],
1428
+ "passes": false
1429
+ },
1430
+ {
1431
+ "category": "style",
1432
+ "description": "Avatar component shows user initials as fallback",
1433
+ "steps": [
1434
+ "Step 1: Find user without avatar URL",
1435
+ "Step 2: View avatar component",
1436
+ "Step 3: Verify initials displayed",
1437
+ "Step 4: Verify initials derived from name"
1438
+ ],
1439
+ "passes": false
1440
+ },
1441
+ {
1442
+ "category": "style",
1443
+ "description": "Avatar component displays image when URL provided",
1444
+ "steps": [
1445
+ "Step 1: Find user with avatar URL",
1446
+ "Step 2: View avatar component",
1447
+ "Step 3: Verify image displays correctly",
1448
+ "Step 4: Verify image is circular"
1449
+ ],
1450
+ "passes": false
1451
+ },
1452
+ {
1453
+ "category": "style",
1454
+ "description": "Badge component has correct variant styling",
1455
+ "steps": [
1456
+ "Step 1: Find badges on page (e.g., role badges)",
1457
+ "Step 2: Verify default variant styling",
1458
+ "Step 3: Verify secondary variant if present",
1459
+ "Step 4: Verify destructive variant if present"
1460
+ ],
1461
+ "passes": false
1462
+ },
1463
+ {
1464
+ "category": "style",
1465
+ "description": "Input fields have focus ring on focus",
1466
+ "steps": [
1467
+ "Step 1: Find input field",
1468
+ "Step 2: Click to focus input",
1469
+ "Step 3: Verify focus ring appears",
1470
+ "Step 4: Verify ring uses brand color"
1471
+ ],
1472
+ "passes": false
1473
+ },
1474
+ {
1475
+ "category": "style",
1476
+ "description": "Input fields show error state for validation",
1477
+ "steps": [
1478
+ "Step 1: Find input with validation",
1479
+ "Step 2: Trigger validation error",
1480
+ "Step 3: Verify red border appears",
1481
+ "Step 4: Verify error message displays below"
1482
+ ],
1483
+ "passes": false
1484
+ },
1485
+ {
1486
+ "category": "style",
1487
+ "description": "Dialog modal has overlay backdrop",
1488
+ "steps": [
1489
+ "Step 1: Open any dialog",
1490
+ "Step 2: Verify semi-transparent overlay behind",
1491
+ "Step 3: Verify dialog content above overlay",
1492
+ "Step 4: Verify clicking overlay closes dialog"
1493
+ ],
1494
+ "passes": false
1495
+ },
1496
+ {
1497
+ "category": "style",
1498
+ "description": "Dialog animates in with scale effect",
1499
+ "steps": [
1500
+ "Step 1: Open any dialog",
1501
+ "Step 2: Observe animation",
1502
+ "Step 3: Verify scale-in animation",
1503
+ "Step 4: Verify animation is smooth (150ms)"
1504
+ ],
1505
+ "passes": false
1506
+ },
1507
+ {
1508
+ "category": "style",
1509
+ "description": "Skeleton loading states show pulse animation",
1510
+ "steps": [
1511
+ "Step 1: Navigate to page while data loading",
1512
+ "Step 2: Observe skeleton elements",
1513
+ "Step 3: Verify pulse animation active",
1514
+ "Step 4: Verify skeletons match content layout"
1515
+ ],
1516
+ "passes": false
1517
+ },
1518
+ {
1519
+ "category": "style",
1520
+ "description": "Sidebar has correct width and background",
1521
+ "steps": [
1522
+ "Step 1: View sidebar on authenticated page",
1523
+ "Step 2: Verify sidebar width is consistent",
1524
+ "Step 3: Verify background color matches design",
1525
+ "Step 4: Verify border separates from content"
1526
+ ],
1527
+ "passes": false
1528
+ },
1529
+ {
1530
+ "category": "style",
1531
+ "description": "Sidebar navigation links have hover states",
1532
+ "steps": [
1533
+ "Step 1: View sidebar navigation",
1534
+ "Step 2: Hover over navigation link",
1535
+ "Step 3: Verify background color changes",
1536
+ "Step 4: Verify active link has distinct style"
1537
+ ],
1538
+ "passes": false
1539
+ },
1540
+ {
1541
+ "category": "style",
1542
+ "description": "Page headers have consistent typography",
1543
+ "steps": [
1544
+ "Step 1: Navigate through authenticated pages",
1545
+ "Step 2: Compare page header styles",
1546
+ "Step 3: Verify font size is consistent",
1547
+ "Step 4: Verify font weight is consistent",
1548
+ "Step 5: Verify spacing below header is consistent"
1549
+ ],
1550
+ "passes": false
1551
+ },
1552
+ {
1553
+ "category": "style",
1554
+ "description": "Tables have proper styling and hover states",
1555
+ "steps": [
1556
+ "Step 1: Find table on team or users page",
1557
+ "Step 2: Verify header row styling",
1558
+ "Step 3: Verify alternating row colors or borders",
1559
+ "Step 4: Hover over row",
1560
+ "Step 5: Verify hover highlight effect"
1561
+ ],
1562
+ "passes": false
1563
+ },
1564
+ {
1565
+ "category": "style",
1566
+ "description": "Separators use correct border color",
1567
+ "steps": [
1568
+ "Step 1: Find horizontal separator",
1569
+ "Step 2: Verify color matches design system",
1570
+ "Step 3: Verify thickness is 1px"
1571
+ ],
1572
+ "passes": false
1573
+ },
1574
+ {
1575
+ "category": "style",
1576
+ "description": "Dark mode uses correct background colors",
1577
+ "steps": [
1578
+ "Step 1: Enable dark mode",
1579
+ "Step 2: Verify background is near-black (#0a0a0a)",
1580
+ "Step 3: Verify card background matches spec",
1581
+ "Step 4: Verify foreground text is off-white (#fafafa)"
1582
+ ],
1583
+ "passes": false
1584
+ },
1585
+ {
1586
+ "category": "style",
1587
+ "description": "Dark mode uses correct border colors",
1588
+ "steps": [
1589
+ "Step 1: Enable dark mode",
1590
+ "Step 2: Inspect card borders",
1591
+ "Step 3: Verify border color is dark gray (#262626)"
1592
+ ],
1593
+ "passes": false
1594
+ },
1595
+ {
1596
+ "category": "style",
1597
+ "description": "Light mode uses correct background colors",
1598
+ "steps": [
1599
+ "Step 1: Ensure light mode active",
1600
+ "Step 2: Verify background is white (#ffffff)",
1601
+ "Step 3: Verify foreground text is near-black (#0a0a0a)"
1602
+ ],
1603
+ "passes": false
1604
+ },
1605
+ {
1606
+ "category": "style",
1607
+ "description": "Light mode uses correct border colors",
1608
+ "steps": [
1609
+ "Step 1: Ensure light mode active",
1610
+ "Step 2: Inspect card borders",
1611
+ "Step 3: Verify border color is light gray (#e5e5e5)"
1612
+ ],
1613
+ "passes": false
1614
+ },
1615
+ {
1616
+ "category": "style",
1617
+ "description": "Typography uses Inter font family",
1618
+ "steps": [
1619
+ "Step 1: Load any page",
1620
+ "Step 2: Inspect body font-family",
1621
+ "Step 3: Verify Inter is primary font",
1622
+ "Step 4: Verify system-ui as fallback"
1623
+ ],
1624
+ "passes": false
1625
+ },
1626
+ {
1627
+ "category": "style",
1628
+ "description": "Code/monospace uses JetBrains Mono",
1629
+ "steps": [
1630
+ "Step 1: Find code element on page",
1631
+ "Step 2: Inspect font-family",
1632
+ "Step 3: Verify JetBrains Mono is primary",
1633
+ "Step 4: Verify Consolas as fallback"
1634
+ ],
1635
+ "passes": false
1636
+ },
1637
+ {
1638
+ "category": "style",
1639
+ "description": "Text sizing follows scale (xs through 3xl)",
1640
+ "steps": [
1641
+ "Step 1: Find text elements on page",
1642
+ "Step 2: Verify text-sm is 0.875rem",
1643
+ "Step 3: Verify text-base is 1rem",
1644
+ "Step 4: Verify text-lg is 1.125rem"
1645
+ ],
1646
+ "passes": false
1647
+ },
1648
+ {
1649
+ "category": "style",
1650
+ "description": "Spacing uses 4px base scale",
1651
+ "steps": [
1652
+ "Step 1: Inspect padding on various elements",
1653
+ "Step 2: Verify p-2 equals 8px",
1654
+ "Step 3: Verify p-4 equals 16px",
1655
+ "Step 4: Verify gap-4 equals 16px"
1656
+ ],
1657
+ "passes": false
1658
+ },
1659
+ {
1660
+ "category": "style",
1661
+ "description": "Border radius matches design system",
1662
+ "steps": [
1663
+ "Step 1: Find various rounded elements",
1664
+ "Step 2: Verify rounded-md equals 6px",
1665
+ "Step 3: Verify rounded-lg equals 8px",
1666
+ "Step 4: Verify avatars use rounded-full"
1667
+ ],
1668
+ "passes": false
1669
+ },
1670
+ {
1671
+ "category": "style",
1672
+ "description": "Shadows provide appropriate elevation",
1673
+ "steps": [
1674
+ "Step 1: Find elevated cards",
1675
+ "Step 2: Verify shadow provides depth",
1676
+ "Step 3: Verify modals have larger shadow",
1677
+ "Step 4: Verify dropdowns have shadow-lg"
1678
+ ],
1679
+ "passes": false
1680
+ },
1681
+ {
1682
+ "category": "style",
1683
+ "description": "Transitions use 150ms ease-in-out",
1684
+ "steps": [
1685
+ "Step 1: Hover over button",
1686
+ "Step 2: Observe transition smoothness",
1687
+ "Step 3: Verify transition duration is 150ms"
1688
+ ],
1689
+ "passes": false
1690
+ },
1691
+ {
1692
+ "category": "style",
1693
+ "description": "Page transitions use fade-in animation",
1694
+ "steps": [
1695
+ "Step 1: Navigate between pages",
1696
+ "Step 2: Observe page transition",
1697
+ "Step 3: Verify fade effect applied"
1698
+ ],
1699
+ "passes": false
1700
+ },
1701
+ {
1702
+ "category": "style",
1703
+ "description": "Mobile sidebar collapses correctly",
1704
+ "steps": [
1705
+ "Step 1: Resize to mobile viewport (< 768px)",
1706
+ "Step 2: Verify sidebar is hidden",
1707
+ "Step 3: Verify hamburger menu appears",
1708
+ "Step 4: Click hamburger",
1709
+ "Step 5: Verify sidebar slides in"
1710
+ ],
1711
+ "passes": false
1712
+ },
1713
+ {
1714
+ "category": "style",
1715
+ "description": "Mobile layout adjusts padding and margins",
1716
+ "steps": [
1717
+ "Step 1: View page on mobile viewport",
1718
+ "Step 2: Verify reduced padding on edges",
1719
+ "Step 3: Verify content fits screen width",
1720
+ "Step 4: Verify no horizontal scroll needed"
1721
+ ],
1722
+ "passes": false
1723
+ },
1724
+ {
1725
+ "category": "style",
1726
+ "description": "Tablet layout shows intermediate design",
1727
+ "steps": [
1728
+ "Step 1: Resize to tablet viewport (768-1024px)",
1729
+ "Step 2: Verify layout adapts appropriately",
1730
+ "Step 3: Verify cards may stack or reduce columns"
1731
+ ],
1732
+ "passes": false
1733
+ },
1734
+ {
1735
+ "category": "style",
1736
+ "description": "Toast notifications appear in bottom-right",
1737
+ "steps": [
1738
+ "Step 1: Trigger a toast notification",
1739
+ "Step 2: Verify toast appears in bottom-right",
1740
+ "Step 3: Verify toast has proper padding",
1741
+ "Step 4: Verify toast has close button"
1742
+ ],
1743
+ "passes": false
1744
+ },
1745
+ {
1746
+ "category": "style",
1747
+ "description": "Success toast has green styling",
1748
+ "steps": [
1749
+ "Step 1: Trigger success action",
1750
+ "Step 2: Observe success toast",
1751
+ "Step 3: Verify green accent color",
1752
+ "Step 4: Verify checkmark icon if present"
1753
+ ],
1754
+ "passes": false
1755
+ },
1756
+ {
1757
+ "category": "style",
1758
+ "description": "Error toast has red styling",
1759
+ "steps": [
1760
+ "Step 1: Trigger error action",
1761
+ "Step 2: Observe error toast",
1762
+ "Step 3: Verify red accent color",
1763
+ "Step 4: Verify error icon if present"
1764
+ ],
1765
+ "passes": false
1766
+ },
1767
+ {
1768
+ "category": "style",
1769
+ "description": "Main content has max-width constraint",
1770
+ "steps": [
1771
+ "Step 1: View page on wide screen",
1772
+ "Step 2: Verify content has max-width",
1773
+ "Step 3: Verify content is centered",
1774
+ "Step 4: Verify side margins grow on ultra-wide"
1775
+ ],
1776
+ "passes": false
1777
+ },
1778
+ {
1779
+ "category": "style",
1780
+ "description": "Form labels are properly associated with inputs",
1781
+ "steps": [
1782
+ "Step 1: Find form with labels",
1783
+ "Step 2: Verify labels use htmlFor attribute",
1784
+ "Step 3: Click label and verify input focuses"
1785
+ ],
1786
+ "passes": false
1787
+ },
1788
+ {
1789
+ "category": "style",
1790
+ "description": "Loading buttons show spinner icon",
1791
+ "steps": [
1792
+ "Step 1: Submit a form",
1793
+ "Step 2: Observe button during submission",
1794
+ "Step 3: Verify spinner animation visible",
1795
+ "Step 4: Verify button text may change to 'Loading...'"
1796
+ ],
1797
+ "passes": false
1798
+ },
1799
+ {
1800
+ "category": "functional",
1801
+ "description": "Keyboard navigation works for all interactive elements",
1802
+ "steps": [
1803
+ "Step 1: Start at top of page",
1804
+ "Step 2: Press Tab to navigate through elements",
1805
+ "Step 3: Verify all buttons, links, inputs are reachable",
1806
+ "Step 4: Verify focus indicators are visible",
1807
+ "Step 5: Press Enter to activate focused button"
1808
+ ],
1809
+ "passes": false
1810
+ },
1811
+ {
1812
+ "category": "functional",
1813
+ "description": "Escape key closes open dialogs",
1814
+ "steps": [
1815
+ "Step 1: Open any dialog",
1816
+ "Step 2: Press Escape key",
1817
+ "Step 3: Verify dialog closes",
1818
+ "Step 4: Verify focus returns to trigger element"
1819
+ ],
1820
+ "passes": false
1821
+ },
1822
+ {
1823
+ "category": "functional",
1824
+ "description": "Focus trap works in modal dialogs",
1825
+ "steps": [
1826
+ "Step 1: Open modal dialog",
1827
+ "Step 2: Tab through dialog elements",
1828
+ "Step 3: Verify focus stays within dialog",
1829
+ "Step 4: Verify cannot Tab to elements behind modal"
1830
+ ],
1831
+ "passes": false
1832
+ },
1833
+ {
1834
+ "category": "functional",
1835
+ "description": "Form submits on Enter key in text fields",
1836
+ "steps": [
1837
+ "Step 1: Fill out form completely",
1838
+ "Step 2: Focus on text input",
1839
+ "Step 3: Press Enter",
1840
+ "Step 4: Verify form submits"
1841
+ ],
1842
+ "passes": false
1843
+ },
1844
+ {
1845
+ "category": "style",
1846
+ "description": "Color contrast meets WCAG AA standards",
1847
+ "steps": [
1848
+ "Step 1: Run contrast checker on text/background",
1849
+ "Step 2: Verify body text has 4.5:1 ratio",
1850
+ "Step 3: Verify large text has 3:1 ratio",
1851
+ "Step 4: Check both light and dark modes"
1852
+ ],
1853
+ "passes": false
1854
+ },
1855
+ {
1856
+ "category": "functional",
1857
+ "description": "ARIA labels present on icon-only buttons",
1858
+ "steps": [
1859
+ "Step 1: Find icon-only buttons",
1860
+ "Step 2: Verify aria-label attribute present",
1861
+ "Step 3: Verify label describes action"
1862
+ ],
1863
+ "passes": false
1864
+ },
1865
+ {
1866
+ "category": "functional",
1867
+ "description": "Screen reader announces page title changes",
1868
+ "steps": [
1869
+ "Step 1: Enable screen reader",
1870
+ "Step 2: Navigate between pages",
1871
+ "Step 3: Verify page title announced"
1872
+ ],
1873
+ "passes": false
1874
+ },
1875
+ {
1876
+ "category": "functional",
1877
+ "description": "Images have alt text",
1878
+ "steps": [
1879
+ "Step 1: Find images on page",
1880
+ "Step 2: Verify alt attribute present",
1881
+ "Step 3: Verify alt text is descriptive"
1882
+ ],
1883
+ "passes": false
1884
+ },
1885
+ {
1886
+ "category": "functional",
1887
+ "description": "Pagination works correctly with keyboard",
1888
+ "steps": [
1889
+ "Step 1: Navigate to paginated list",
1890
+ "Step 2: Tab to pagination controls",
1891
+ "Step 3: Press Enter on next page",
1892
+ "Step 4: Verify page content updates"
1893
+ ],
1894
+ "passes": false
1895
+ },
1896
+ {
1897
+ "category": "functional",
1898
+ "description": "Page load time under 500ms on edge",
1899
+ "steps": [
1900
+ "Step 1: Clear browser cache",
1901
+ "Step 2: Navigate to dashboard",
1902
+ "Step 3: Measure time to first contentful paint",
1903
+ "Step 4: Verify under 500ms"
1904
+ ],
1905
+ "passes": false
1906
+ },
1907
+ {
1908
+ "category": "functional",
1909
+ "description": "API response time under 100ms",
1910
+ "steps": [
1911
+ "Step 1: Make API request",
1912
+ "Step 2: Measure response time",
1913
+ "Step 3: Verify under 100ms for simple queries"
1914
+ ],
1915
+ "passes": false
1916
+ },
1917
+ {
1918
+ "category": "functional",
1919
+ "description": "Optimistic updates provide instant feedback",
1920
+ "steps": [
1921
+ "Step 1: Perform update action (e.g., toggle)",
1922
+ "Step 2: Verify UI updates immediately",
1923
+ "Step 3: Verify no loading spinner for optimistic actions"
1924
+ ],
1925
+ "passes": false
1926
+ },
1927
+ {
1928
+ "category": "functional",
1929
+ "description": "Failed optimistic updates rollback correctly",
1930
+ "steps": [
1931
+ "Step 1: Trigger optimistic update",
1932
+ "Step 2: Simulate server error",
1933
+ "Step 3: Verify UI rolls back to previous state",
1934
+ "Step 4: Verify error toast displayed"
1935
+ ],
1936
+ "passes": false
1937
+ },
1938
+ {
1939
+ "category": "functional",
1940
+ "description": "Network errors show retry option",
1941
+ "steps": [
1942
+ "Step 1: Disconnect network",
1943
+ "Step 2: Attempt to load data",
1944
+ "Step 3: Verify network error message",
1945
+ "Step 4: Reconnect network",
1946
+ "Step 5: Click retry button",
1947
+ "Step 6: Verify data loads"
1948
+ ],
1949
+ "passes": false
1950
+ },
1951
+ {
1952
+ "category": "functional",
1953
+ "description": "TanStack Query caches data correctly",
1954
+ "steps": [
1955
+ "Step 1: Load page with data",
1956
+ "Step 2: Navigate away",
1957
+ "Step 3: Navigate back",
1958
+ "Step 4: Verify data displays instantly from cache",
1959
+ "Step 5: Verify background refetch occurs"
1960
+ ],
1961
+ "passes": false
1962
+ },
1963
+ {
1964
+ "category": "functional",
1965
+ "description": "Stale data is refetched on window focus",
1966
+ "steps": [
1967
+ "Step 1: Load page with data",
1968
+ "Step 2: Switch to different browser tab",
1969
+ "Step 3: Wait for stale time to pass",
1970
+ "Step 4: Switch back to app tab",
1971
+ "Step 5: Verify data refetch triggered"
1972
+ ],
1973
+ "passes": false
1974
+ },
1975
+ {
1976
+ "category": "functional",
1977
+ "description": "File upload progress shows percentage",
1978
+ "steps": [
1979
+ "Step 1: Upload a large file",
1980
+ "Step 2: Verify progress indicator appears",
1981
+ "Step 3: Verify percentage increases",
1982
+ "Step 4: Verify completion shows 100%"
1983
+ ],
1984
+ "passes": false
1985
+ },
1986
+ {
1987
+ "category": "functional",
1988
+ "description": "File upload cancellation works",
1989
+ "steps": [
1990
+ "Step 1: Start uploading large file",
1991
+ "Step 2: Click cancel button",
1992
+ "Step 3: Verify upload stops",
1993
+ "Step 4: Verify partial file cleaned up"
1994
+ ],
1995
+ "passes": false
1996
+ },
1997
+ {
1998
+ "category": "functional",
1999
+ "description": "Invalid file types rejected on upload",
2000
+ "steps": [
2001
+ "Step 1: Attempt to upload disallowed file type",
2002
+ "Step 2: Verify error message about file type",
2003
+ "Step 3: Verify upload does not proceed"
2004
+ ],
2005
+ "passes": false
2006
+ },
2007
+ {
2008
+ "category": "functional",
2009
+ "description": "File size limits enforced on upload",
2010
+ "steps": [
2011
+ "Step 1: Attempt to upload file exceeding size limit",
2012
+ "Step 2: Verify error message about file size",
2013
+ "Step 3: Verify upload does not proceed"
2014
+ ],
2015
+ "passes": false
2016
+ },
2017
+ {
2018
+ "category": "functional",
2019
+ "description": "Drizzle ORM generates correct SQL for queries",
2020
+ "steps": [
2021
+ "Step 1: Make API request that triggers query",
2022
+ "Step 2: Enable query logging",
2023
+ "Step 3: Verify SQL is efficient",
2024
+ "Step 4: Verify no N+1 queries"
2025
+ ],
2026
+ "passes": false
2027
+ },
2028
+ {
2029
+ "category": "functional",
2030
+ "description": "Database indexes are used for common queries",
2031
+ "steps": [
2032
+ "Step 1: Query users by email",
2033
+ "Step 2: Verify index scan in query plan",
2034
+ "Step 3: Query audit logs by timestamp",
2035
+ "Step 4: Verify index is used"
2036
+ ],
2037
+ "passes": false
2038
+ },
2039
+ {
2040
+ "category": "functional",
2041
+ "description": "Concurrent requests handled correctly",
2042
+ "steps": [
2043
+ "Step 1: Send multiple parallel requests",
2044
+ "Step 2: Verify all complete successfully",
2045
+ "Step 3: Verify no race conditions in data",
2046
+ "Step 4: Verify transaction isolation maintained"
2047
+ ],
2048
+ "passes": false
2049
+ },
2050
+ {
2051
+ "category": "functional",
2052
+ "description": "Long-running operations don't block other requests",
2053
+ "steps": [
2054
+ "Step 1: Start slow operation (e.g., large export)",
2055
+ "Step 2: Make other API requests",
2056
+ "Step 3: Verify other requests complete quickly"
2057
+ ],
2058
+ "passes": false
2059
+ },
2060
+ {
2061
+ "category": "functional",
2062
+ "description": "Email invitation contains correct link",
2063
+ "steps": [
2064
+ "Step 1: Create invitation",
2065
+ "Step 2: Capture sent email content",
2066
+ "Step 3: Verify invitation link format",
2067
+ "Step 4: Verify link includes token",
2068
+ "Step 5: Click link and verify it works"
2069
+ ],
2070
+ "passes": false
2071
+ },
2072
+ {
2073
+ "category": "functional",
2074
+ "description": "Email invitation shows account name",
2075
+ "steps": [
2076
+ "Step 1: Create invitation for 'Acme Corp'",
2077
+ "Step 2: Capture sent email",
2078
+ "Step 3: Verify 'Acme Corp' appears in email",
2079
+ "Step 4: Verify inviter's name appears"
2080
+ ],
2081
+ "passes": false
2082
+ },
2083
+ {
2084
+ "category": "functional",
2085
+ "description": "Invitation email uses correct sender address",
2086
+ "steps": [
2087
+ "Step 1: Configure SENDGRID_FROM_EMAIL",
2088
+ "Step 2: Create invitation",
2089
+ "Step 3: Verify email From matches config"
2090
+ ],
2091
+ "passes": false
2092
+ },
2093
+ {
2094
+ "category": "functional",
2095
+ "description": "URL state preserved for redirect parameter",
2096
+ "steps": [
2097
+ "Step 1: Navigate to /dashboard as unauthenticated",
2098
+ "Step 2: Verify redirect to /login?redirect=/dashboard",
2099
+ "Step 3: Complete login",
2100
+ "Step 4: Verify redirect to /dashboard"
2101
+ ],
2102
+ "passes": false
2103
+ },
2104
+ {
2105
+ "category": "functional",
2106
+ "description": "Browser back button works correctly",
2107
+ "steps": [
2108
+ "Step 1: Navigate dashboard → team → settings",
2109
+ "Step 2: Click browser back button",
2110
+ "Step 3: Verify navigate to team",
2111
+ "Step 4: Click back again",
2112
+ "Step 5: Verify navigate to dashboard"
2113
+ ],
2114
+ "passes": false
2115
+ },
2116
+ {
2117
+ "category": "functional",
2118
+ "description": "TanStack Router file-based routing works",
2119
+ "steps": [
2120
+ "Step 1: Navigate to /dashboard",
2121
+ "Step 2: Verify correct route component loads",
2122
+ "Step 3: Navigate to /team",
2123
+ "Step 4: Verify correct component loads"
2124
+ ],
2125
+ "passes": false
2126
+ },
2127
+ {
2128
+ "category": "functional",
2129
+ "description": "Route params extracted correctly",
2130
+ "steps": [
2131
+ "Step 1: Navigate to /invite/:token",
2132
+ "Step 2: Verify token param extracted",
2133
+ "Step 3: Verify component receives token value"
2134
+ ],
2135
+ "passes": false
2136
+ },
2137
+ {
2138
+ "category": "functional",
2139
+ "description": "Query parameters preserved across navigation",
2140
+ "steps": [
2141
+ "Step 1: Navigate to /team?filter=admin",
2142
+ "Step 2: Verify filter param used",
2143
+ "Step 3: Navigate to subpage and back",
2144
+ "Step 4: Verify filter param retained if appropriate"
2145
+ ],
2146
+ "passes": false
2147
+ },
2148
+ {
2149
+ "category": "functional",
2150
+ "description": "React Hook Form validates on blur",
2151
+ "steps": [
2152
+ "Step 1: Focus form field",
2153
+ "Step 2: Enter invalid value",
2154
+ "Step 3: Blur field (click away)",
2155
+ "Step 4: Verify validation error shows"
2156
+ ],
2157
+ "passes": false
2158
+ },
2159
+ {
2160
+ "category": "functional",
2161
+ "description": "Zod schema validation produces helpful errors",
2162
+ "steps": [
2163
+ "Step 1: Submit form with invalid data",
2164
+ "Step 2: Verify error messages are human-readable",
2165
+ "Step 3: Verify errors point to specific fields"
2166
+ ],
2167
+ "passes": false
2168
+ },
2169
+ {
2170
+ "category": "functional",
2171
+ "description": "Form reset clears all fields and errors",
2172
+ "steps": [
2173
+ "Step 1: Fill form with some errors",
2174
+ "Step 2: Click reset/cancel button",
2175
+ "Step 3: Verify all fields cleared",
2176
+ "Step 4: Verify error messages cleared"
2177
+ ],
2178
+ "passes": false
2179
+ },
2180
+ {
2181
+ "category": "functional",
2182
+ "description": "Select/dropdown keyboard navigation works",
2183
+ "steps": [
2184
+ "Step 1: Focus select field",
2185
+ "Step 2: Press Enter/Space to open",
2186
+ "Step 3: Use arrow keys to navigate options",
2187
+ "Step 4: Press Enter to select",
2188
+ "Step 5: Verify selection applied"
2189
+ ],
2190
+ "passes": false
2191
+ },
2192
+ {
2193
+ "category": "functional",
2194
+ "description": "Build completes without errors",
2195
+ "steps": [
2196
+ "Step 1: Run pnpm build",
2197
+ "Step 2: Verify no TypeScript errors",
2198
+ "Step 3: Verify no build warnings",
2199
+ "Step 4: Verify output files generated"
2200
+ ],
2201
+ "passes": false
2202
+ },
2203
+ {
2204
+ "category": "functional",
2205
+ "description": "TypeScript strict mode passes",
2206
+ "steps": [
2207
+ "Step 1: Run pnpm typecheck",
2208
+ "Step 2: Verify no type errors",
2209
+ "Step 3: Verify strict null checks pass"
2210
+ ],
2211
+ "passes": false
2212
+ },
2213
+ {
2214
+ "category": "functional",
2215
+ "description": "ESLint passes without errors",
2216
+ "steps": [
2217
+ "Step 1: Run pnpm lint",
2218
+ "Step 2: Verify no linting errors",
2219
+ "Step 3: Verify code follows style guide"
2220
+ ],
2221
+ "passes": false
2222
+ },
2223
+ {
2224
+ "category": "functional",
2225
+ "description": "Unit tests achieve 95% coverage on server",
2226
+ "steps": [
2227
+ "Step 1: Run pnpm test:coverage",
2228
+ "Step 2: Verify server code at 95%+ coverage",
2229
+ "Step 3: Verify all services tested",
2230
+ "Step 4: Verify all routes tested"
2231
+ ],
2232
+ "passes": false
2233
+ },
2234
+ {
2235
+ "category": "functional",
2236
+ "description": "Unit tests achieve 90% coverage on client",
2237
+ "steps": [
2238
+ "Step 1: Run pnpm test:client --coverage",
2239
+ "Step 2: Verify client code at 90%+ coverage",
2240
+ "Step 3: Verify components tested"
2241
+ ],
2242
+ "passes": false
2243
+ },
2244
+ {
2245
+ "category": "functional",
2246
+ "description": "E2E tests pass on Chromium",
2247
+ "steps": [
2248
+ "Step 1: Run pnpm test:e2e --project=chromium",
2249
+ "Step 2: Verify all tests pass",
2250
+ "Step 3: Verify no flaky tests"
2251
+ ],
2252
+ "passes": false
2253
+ },
2254
+ {
2255
+ "category": "functional",
2256
+ "description": "E2E tests pass on Firefox",
2257
+ "steps": [
2258
+ "Step 1: Run pnpm test:e2e --project=firefox",
2259
+ "Step 2: Verify all tests pass"
2260
+ ],
2261
+ "passes": false
2262
+ },
2263
+ {
2264
+ "category": "functional",
2265
+ "description": "E2E tests pass on WebKit",
2266
+ "steps": [
2267
+ "Step 1: Run pnpm test:e2e --project=webkit",
2268
+ "Step 2: Verify all tests pass"
2269
+ ],
2270
+ "passes": false
2271
+ },
2272
+ {
2273
+ "category": "functional",
2274
+ "description": "Smoke tests verify basic app functionality",
2275
+ "steps": [
2276
+ "Step 1: Run pnpm test:e2e --grep @smoke",
2277
+ "Step 2: Verify health check passes",
2278
+ "Step 3: Verify login flow works",
2279
+ "Step 4: Verify basic navigation works"
2280
+ ],
2281
+ "passes": false
2282
+ },
2283
+ {
2284
+ "category": "functional",
2285
+ "description": "Critical path tests must all pass",
2286
+ "steps": [
2287
+ "Step 1: Run pnpm test:e2e --grep @critical",
2288
+ "Step 2: Verify auth flow passes",
2289
+ "Step 3: Verify core CRUD operations pass"
2290
+ ],
2291
+ "passes": false
2292
+ },
2293
+ {
2294
+ "category": "functional",
2295
+ "description": "Deployment to Cloudflare Workers succeeds",
2296
+ "steps": [
2297
+ "Step 1: Run pnpm deploy",
2298
+ "Step 2: Verify wrangler deploys successfully",
2299
+ "Step 3: Verify worker URL accessible",
2300
+ "Step 4: Verify D1 migrations applied"
2301
+ ],
2302
+ "passes": false
2303
+ },
2304
+ {
2305
+ "category": "functional",
2306
+ "description": "Environment variables work in production",
2307
+ "steps": [
2308
+ "Step 1: Set secrets via wrangler",
2309
+ "Step 2: Deploy to Cloudflare",
2310
+ "Step 3: Verify OAuth works with secrets",
2311
+ "Step 4: Verify JWT signing works"
2312
+ ],
2313
+ "passes": false
2314
+ },
2315
+ {
2316
+ "category": "functional",
2317
+ "description": "D1 migrations run without errors",
2318
+ "steps": [
2319
+ "Step 1: Run pnpm db:migrate:local",
2320
+ "Step 2: Verify all migrations apply",
2321
+ "Step 3: Verify schema matches expected"
2322
+ ],
2323
+ "passes": false
2324
+ },
2325
+ {
2326
+ "category": "functional",
2327
+ "description": "Database seeding creates test data",
2328
+ "steps": [
2329
+ "Step 1: Run pnpm db:seed",
2330
+ "Step 2: Verify test users created",
2331
+ "Step 3: Verify test accounts created",
2332
+ "Step 4: Verify relationships established"
2333
+ ],
2334
+ "passes": false
2335
+ },
2336
+ {
2337
+ "category": "functional",
2338
+ "description": "Cloudflare type generation works",
2339
+ "steps": [
2340
+ "Step 1: Run pnpm cf-typegen",
2341
+ "Step 2: Verify types generated",
2342
+ "Step 3: Verify bindings typed correctly"
2343
+ ],
2344
+ "passes": false
2345
+ },
2346
+ {
2347
+ "category": "functional",
2348
+ "description": "R2 bucket accessible from worker",
2349
+ "steps": [
2350
+ "Step 1: Deploy worker with R2 binding",
2351
+ "Step 2: Upload file via API",
2352
+ "Step 3: Verify file stored in R2",
2353
+ "Step 4: Verify file accessible via URL"
2354
+ ],
2355
+ "passes": false
2356
+ },
2357
+ {
2358
+ "category": "functional",
2359
+ "description": "KV namespace stores sessions correctly",
2360
+ "steps": [
2361
+ "Step 1: Log in to application",
2362
+ "Step 2: Verify session stored in KV",
2363
+ "Step 3: Read session data from KV",
2364
+ "Step 4: Verify session data is correct"
2365
+ ],
2366
+ "passes": false
2367
+ },
2368
+ {
2369
+ "category": "functional",
2370
+ "description": "Path aliases resolve correctly (@/, @shared/, @server/)",
2371
+ "steps": [
2372
+ "Step 1: Use @/ import in client code",
2373
+ "Step 2: Use @shared/ import",
2374
+ "Step 3: Use @server/ import in server code",
2375
+ "Step 4: Verify all imports resolve",
2376
+ "Step 5: Verify build succeeds"
2377
+ ],
2378
+ "passes": false
2379
+ },
2380
+ {
2381
+ "category": "functional",
2382
+ "description": "Environment-specific configuration loads correctly",
2383
+ "steps": [
2384
+ "Step 1: Set ENVIRONMENT to development",
2385
+ "Step 2: Verify dev-specific features enabled",
2386
+ "Step 3: Set ENVIRONMENT to production",
2387
+ "Step 4: Verify prod-specific features enabled"
2388
+ ],
2389
+ "passes": false
2390
+ },
2391
+ {
2392
+ "category": "functional",
2393
+ "description": "Error messages sanitized in production",
2394
+ "steps": [
2395
+ "Step 1: Trigger error in production mode",
2396
+ "Step 2: Verify no stack trace in response",
2397
+ "Step 3: Verify generic error message shown"
2398
+ ],
2399
+ "passes": false
2400
+ },
2401
+ {
2402
+ "category": "style",
2403
+ "description": "Integration cards have consistent sizing",
2404
+ "steps": [
2405
+ "Step 1: Navigate to /integrations",
2406
+ "Step 2: Verify all cards same size",
2407
+ "Step 3: Verify logo placement consistent",
2408
+ "Step 4: Verify description truncation consistent"
2409
+ ],
2410
+ "passes": false
2411
+ },
2412
+ {
2413
+ "category": "style",
2414
+ "description": "Stats cards on dashboard have icons",
2415
+ "steps": [
2416
+ "Step 1: Navigate to /dashboard",
2417
+ "Step 2: Verify each stat card has icon",
2418
+ "Step 3: Verify icons are appropriately sized"
2419
+ ],
2420
+ "passes": false
2421
+ },
2422
+ {
2423
+ "category": "style",
2424
+ "description": "Empty states have helpful messaging",
2425
+ "steps": [
2426
+ "Step 1: View page with no data (e.g., no team members)",
2427
+ "Step 2: Verify empty state illustration or icon",
2428
+ "Step 3: Verify helpful message explains how to add data"
2429
+ ],
2430
+ "passes": false
2431
+ },
2432
+ {
2433
+ "category": "style",
2434
+ "description": "Dropdown menus align correctly",
2435
+ "steps": [
2436
+ "Step 1: Click dropdown trigger",
2437
+ "Step 2: Verify menu aligns to trigger",
2438
+ "Step 3: Verify menu doesn't overflow viewport"
2439
+ ],
2440
+ "passes": false
2441
+ },
2442
+ {
2443
+ "category": "style",
2444
+ "description": "Tooltips appear on hover for truncated text",
2445
+ "steps": [
2446
+ "Step 1: Find truncated text element",
2447
+ "Step 2: Hover over it",
2448
+ "Step 3: Verify tooltip shows full text"
2449
+ ],
2450
+ "passes": false
2451
+ },
2452
+ {
2453
+ "category": "functional",
2454
+ "description": "Console has no errors in production",
2455
+ "steps": [
2456
+ "Step 1: Load application in production mode",
2457
+ "Step 2: Open browser console",
2458
+ "Step 3: Navigate through all pages",
2459
+ "Step 4: Verify no JavaScript errors"
2460
+ ],
2461
+ "passes": false
2462
+ },
2463
+ {
2464
+ "category": "functional",
2465
+ "description": "Console has no warnings in production",
2466
+ "steps": [
2467
+ "Step 1: Load application in production mode",
2468
+ "Step 2: Open browser console",
2469
+ "Step 3: Navigate through all pages",
2470
+ "Step 4: Verify no React warnings"
2471
+ ],
2472
+ "passes": false
2473
+ },
2474
+ {
2475
+ "category": "functional",
2476
+ "description": "Sensitive data not logged to console",
2477
+ "steps": [
2478
+ "Step 1: Enable console logging",
2479
+ "Step 2: Perform authentication",
2480
+ "Step 3: Verify no passwords in logs",
2481
+ "Step 4: Verify no tokens in logs",
2482
+ "Step 5: Verify no secrets in logs"
2483
+ ],
2484
+ "passes": false
2485
+ },
2486
+ {
2487
+ "category": "functional",
2488
+ "description": "API rate limiting prevents abuse",
2489
+ "steps": [
2490
+ "Step 1: Configure rate limits",
2491
+ "Step 2: Send requests exceeding limit",
2492
+ "Step 3: Verify 429 Too Many Requests",
2493
+ "Step 4: Verify retry-after header"
2494
+ ],
2495
+ "passes": false
2496
+ },
2497
+ {
2498
+ "category": "functional",
2499
+ "description": "Input sanitization prevents XSS",
2500
+ "steps": [
2501
+ "Step 1: Enter script tag in input field",
2502
+ "Step 2: Submit form",
2503
+ "Step 3: Verify script is escaped in display",
2504
+ "Step 4: Verify no XSS execution"
2505
+ ],
2506
+ "passes": false
2507
+ },
2508
+ {
2509
+ "category": "functional",
2510
+ "description": "SQL injection prevented by parameterized queries",
2511
+ "steps": [
2512
+ "Step 1: Enter SQL injection attempt in search",
2513
+ "Step 2: Submit query",
2514
+ "Step 3: Verify query is parameterized",
2515
+ "Step 4: Verify no SQL injection executed"
2516
+ ],
2517
+ "passes": false
2518
+ },
2519
+ {
2520
+ "category": "functional",
2521
+ "description": "CSRF protection via session cookies",
2522
+ "steps": [
2523
+ "Step 1: Verify session cookies have SameSite",
2524
+ "Step 2: Attempt cross-site request",
2525
+ "Step 3: Verify request fails or is rejected"
2526
+ ],
2527
+ "passes": false
2528
+ },
2529
+ {
2530
+ "category": "functional",
2531
+ "description": "Account domain uniqueness enforced",
2532
+ "steps": [
2533
+ "Step 1: Create account with domain 'acme.com'",
2534
+ "Step 2: Attempt to create another with same domain",
2535
+ "Step 3: Verify error about duplicate domain"
2536
+ ],
2537
+ "passes": false
2538
+ },
2539
+ {
2540
+ "category": "functional",
2541
+ "description": "User googleId uniqueness enforced",
2542
+ "steps": [
2543
+ "Step 1: Create user with googleId 'abc123'",
2544
+ "Step 2: Attempt to create another with same googleId",
2545
+ "Step 3: Verify error or existing user returned"
2546
+ ],
2547
+ "passes": false
2548
+ },
2549
+ {
2550
+ "category": "functional",
2551
+ "description": "Invitation (accountId, email) uniqueness enforced",
2552
+ "steps": [
2553
+ "Step 1: Create invitation for email in account",
2554
+ "Step 2: Attempt duplicate invitation",
2555
+ "Step 3: Verify error about existing invitation"
2556
+ ],
2557
+ "passes": false
2558
+ },
2559
+ {
2560
+ "category": "functional",
2561
+ "description": "Primary key constraints work on user_accounts",
2562
+ "steps": [
2563
+ "Step 1: Add user to account",
2564
+ "Step 2: Attempt to add same user-account pair",
2565
+ "Step 3: Verify constraint error"
2566
+ ],
2567
+ "passes": false
2568
+ },
2569
+ {
2570
+ "category": "functional",
2571
+ "description": "CASCADE delete removes user_accounts on user delete",
2572
+ "steps": [
2573
+ "Step 1: Create user with account memberships",
2574
+ "Step 2: Hard delete user (bypass soft delete for test)",
2575
+ "Step 3: Verify user_accounts records deleted"
2576
+ ],
2577
+ "passes": false
2578
+ },
2579
+ {
2580
+ "category": "functional",
2581
+ "description": "CASCADE delete removes user_accounts on account delete",
2582
+ "steps": [
2583
+ "Step 1: Create account with user memberships",
2584
+ "Step 2: Hard delete account (bypass soft delete for test)",
2585
+ "Step 3: Verify user_accounts records deleted"
2586
+ ],
2587
+ "passes": false
2588
+ },
2589
+ {
2590
+ "category": "functional",
2591
+ "description": "Refresh token is hashed before storage",
2592
+ "steps": [
2593
+ "Step 1: Generate refresh token",
2594
+ "Step 2: Store token in database",
2595
+ "Step 3: Query token record",
2596
+ "Step 4: Verify stored value is SHA-256 hash",
2597
+ "Step 5: Verify original token cannot be recovered"
2598
+ ],
2599
+ "passes": false
2600
+ },
2601
+ {
2602
+ "category": "functional",
2603
+ "description": "JWT_SECRET must be at least 32 characters",
2604
+ "steps": [
2605
+ "Step 1: Set JWT_SECRET to short value",
2606
+ "Step 2: Attempt to start application",
2607
+ "Step 3: Verify startup fails with error",
2608
+ "Step 4: Set JWT_SECRET to 32+ chars",
2609
+ "Step 5: Verify startup succeeds"
2610
+ ],
2611
+ "passes": false
2612
+ },
2613
+ {
2614
+ "category": "functional",
2615
+ "description": "Session expiry removes access",
2616
+ "steps": [
2617
+ "Step 1: Create session with short expiry",
2618
+ "Step 2: Wait for expiry",
2619
+ "Step 3: Attempt to use expired session",
2620
+ "Step 4: Verify 401 response"
2621
+ ],
2622
+ "passes": false
2623
+ },
2624
+ {
2625
+ "category": "functional",
2626
+ "description": "Invitation expiry after 7 days",
2627
+ "steps": [
2628
+ "Step 1: Create invitation",
2629
+ "Step 2: Verify expiresAt is 7 days from now",
2630
+ "Step 3: Manually set expiresAt to past",
2631
+ "Step 4: Attempt to accept invitation",
2632
+ "Step 5: Verify expiration error"
2633
+ ],
2634
+ "passes": false
2635
+ },
2636
+ {
2637
+ "category": "functional",
2638
+ "description": "Presigned upload URL expires after 1 hour",
2639
+ "steps": [
2640
+ "Step 1: Generate presigned URL",
2641
+ "Step 2: Wait or manually expire",
2642
+ "Step 3: Attempt to use expired URL",
2643
+ "Step 4: Verify upload fails"
2644
+ ],
2645
+ "passes": false
2646
+ },
2647
+ {
2648
+ "category": "functional",
2649
+ "description": "Complete new user onboarding journey from invitation to dashboard",
2650
+ "steps": [
2651
+ "Step 1: Admin creates invitation for new user email with EDITOR role",
2652
+ "Step 2: Verify invitation email is sent with correct link and account name",
2653
+ "Step 3: New user clicks invitation link in email",
2654
+ "Step 4: Verify invitation page shows account name and role",
2655
+ "Step 5: New user clicks accept and is redirected to Google OAuth",
2656
+ "Step 6: Complete Google OAuth authentication",
2657
+ "Step 7: Verify new user record is created with correct email and name",
2658
+ "Step 8: Verify user is automatically added to invited account with EDITOR role",
2659
+ "Step 9: Verify SIGNUP audit event is logged with transaction ID",
2660
+ "Step 10: Verify redirect to dashboard with welcome message",
2661
+ "Step 11: Verify sidebar shows correct user profile",
2662
+ "Step 12: Verify user can access team page but cannot delete users"
2663
+ ],
2664
+ "passes": false
2665
+ },
2666
+ {
2667
+ "category": "functional",
2668
+ "description": "Complete team member lifecycle from invite to removal",
2669
+ "steps": [
2670
+ "Step 1: Log in as account ADMIN user",
2671
+ "Step 2: Navigate to team management page",
2672
+ "Step 3: Click invite member button",
2673
+ "Step 4: Enter new member email and select VIEWER role",
2674
+ "Step 5: Submit invitation and verify success toast",
2675
+ "Step 6: Verify invitation appears in pending list with 7-day expiry",
2676
+ "Step 7: New member accepts invitation and logs in",
2677
+ "Step 8: Verify new member appears in active members list",
2678
+ "Step 9: Admin changes member role from VIEWER to EDITOR",
2679
+ "Step 10: Verify audit log shows role change with before/after state",
2680
+ "Step 11: Admin removes member from account",
2681
+ "Step 12: Verify member no longer in active list",
2682
+ "Step 13: Verify member can no longer access account resources"
2683
+ ],
2684
+ "passes": false
2685
+ },
2686
+ {
2687
+ "category": "functional",
2688
+ "description": "Complete user profile update journey with all validations",
2689
+ "steps": [
2690
+ "Step 1: Log in as authenticated user",
2691
+ "Step 2: Navigate to settings page",
2692
+ "Step 3: Verify current profile information displayed",
2693
+ "Step 4: Click edit profile button",
2694
+ "Step 5: Clear name field and attempt to save",
2695
+ "Step 6: Verify validation error for empty name",
2696
+ "Step 7: Enter valid new name",
2697
+ "Step 8: Submit form and verify loading state on button",
2698
+ "Step 9: Verify success toast appears",
2699
+ "Step 10: Verify profile card shows updated name",
2700
+ "Step 11: Navigate away and back to settings",
2701
+ "Step 12: Verify updated name persists from database"
2702
+ ],
2703
+ "passes": false
2704
+ },
2705
+ {
2706
+ "category": "functional",
2707
+ "description": "Complete audit log investigation workflow",
2708
+ "steps": [
2709
+ "Step 1: Perform several actions (create user, update user, delete user)",
2710
+ "Step 2: Log in as ADMIN or ANALYTICS user",
2711
+ "Step 3: Navigate to audit logs (or use API)",
2712
+ "Step 4: Verify all recent actions appear in log",
2713
+ "Step 5: Filter by entity type 'User'",
2714
+ "Step 6: Verify only User events shown",
2715
+ "Step 7: Filter by action type 'UPDATE'",
2716
+ "Step 8: Verify only UPDATE actions shown",
2717
+ "Step 9: Click on specific audit entry",
2718
+ "Step 10: Verify changes field shows before/after values",
2719
+ "Step 11: Verify IP address and user agent captured",
2720
+ "Step 12: Verify transaction ID groups related operations"
2721
+ ],
2722
+ "passes": false
2723
+ },
2724
+ {
2725
+ "category": "functional",
2726
+ "description": "Complete file upload and management workflow",
2727
+ "steps": [
2728
+ "Step 1: Log in as authenticated user",
2729
+ "Step 2: Navigate to file storage area",
2730
+ "Step 3: Click upload button",
2731
+ "Step 4: Select file from local system",
2732
+ "Step 5: Verify file type validation (if applicable)",
2733
+ "Step 6: Verify file size validation (if applicable)",
2734
+ "Step 7: Start upload and verify progress indicator",
2735
+ "Step 8: Wait for upload completion (100%)",
2736
+ "Step 9: Verify success message and file appears in list",
2737
+ "Step 10: Click to view/download file",
2738
+ "Step 11: Verify file is accessible via public URL",
2739
+ "Step 12: Delete file and verify removal from list",
2740
+ "Step 13: Verify file no longer accessible via URL"
2741
+ ],
2742
+ "passes": false
2743
+ },
2744
+ {
2745
+ "category": "functional",
2746
+ "description": "Complete multi-account user experience",
2747
+ "steps": [
2748
+ "Step 1: Super admin creates Account A",
2749
+ "Step 2: Super admin creates Account B",
2750
+ "Step 3: Add same user to Account A with ADMIN role",
2751
+ "Step 4: Add same user to Account B with VIEWER role",
2752
+ "Step 5: Log in as that user",
2753
+ "Step 6: Verify user can see both accounts in account list",
2754
+ "Step 7: Switch to Account A context",
2755
+ "Step 8: Verify full ADMIN capabilities (edit account, manage users)",
2756
+ "Step 9: Switch to Account B context",
2757
+ "Step 10: Verify restricted VIEWER capabilities (read-only)",
2758
+ "Step 11: Attempt admin action in Account B",
2759
+ "Step 12: Verify 403 Forbidden response"
2760
+ ],
2761
+ "passes": false
2762
+ },
2763
+ {
2764
+ "category": "functional",
2765
+ "description": "Complete OAuth login flow with PKCE security",
2766
+ "steps": [
2767
+ "Step 1: Navigate to /login page",
2768
+ "Step 2: Click Google sign-in button",
2769
+ "Step 3: Verify redirect to Google with state parameter",
2770
+ "Step 4: Verify PKCE code_challenge in OAuth URL",
2771
+ "Step 5: Complete Google authentication",
2772
+ "Step 6: Verify callback receives authorization code",
2773
+ "Step 7: Verify code_verifier is used to exchange code for tokens",
2774
+ "Step 8: Verify session is created in KV store",
2775
+ "Step 9: Verify session_id cookie is set with httpOnly, secure, sameSite",
2776
+ "Step 10: Verify redirect to dashboard",
2777
+ "Step 11: Verify /auth/me returns correct user info",
2778
+ "Step 12: Verify LOGIN audit event logged with IP and user agent"
2779
+ ],
2780
+ "passes": false
2781
+ },
2782
+ {
2783
+ "category": "functional",
2784
+ "description": "Complete error recovery and retry workflow",
2785
+ "steps": [
2786
+ "Step 1: Log in as authenticated user",
2787
+ "Step 2: Navigate to page that loads data",
2788
+ "Step 3: Disconnect network to simulate failure",
2789
+ "Step 4: Attempt to navigate to another page",
2790
+ "Step 5: Verify network error message displayed",
2791
+ "Step 6: Verify retry button is available",
2792
+ "Step 7: Reconnect network",
2793
+ "Step 8: Click retry button",
2794
+ "Step 9: Verify data loads successfully",
2795
+ "Step 10: Verify no error state remains",
2796
+ "Step 11: Verify TanStack Query cache is updated",
2797
+ "Step 12: Navigate away and back to verify cache works"
2798
+ ],
2799
+ "passes": false
2800
+ },
2801
+ {
2802
+ "category": "functional",
2803
+ "description": "Complete form validation and submission workflow",
2804
+ "steps": [
2805
+ "Step 1: Navigate to form (invite member dialog)",
2806
+ "Step 2: Click submit without filling fields",
2807
+ "Step 3: Verify inline validation errors appear",
2808
+ "Step 4: Enter invalid email format",
2809
+ "Step 5: Verify email validation error",
2810
+ "Step 6: Enter valid email",
2811
+ "Step 7: Verify email validation error clears",
2812
+ "Step 8: Select role from dropdown using keyboard",
2813
+ "Step 9: Press Enter to submit form",
2814
+ "Step 10: Verify loading state on submit button",
2815
+ "Step 11: Verify button is disabled during submission",
2816
+ "Step 12: Verify success toast on completion",
2817
+ "Step 13: Verify form resets for next entry"
2818
+ ],
2819
+ "passes": false
2820
+ },
2821
+ {
2822
+ "category": "functional",
2823
+ "description": "Complete pagination and search workflow",
2824
+ "steps": [
2825
+ "Step 1: Seed database with 50+ users",
2826
+ "Step 2: Navigate to users list page",
2827
+ "Step 3: Verify first page shows 10 users",
2828
+ "Step 4: Verify pagination shows total count",
2829
+ "Step 5: Click next page button",
2830
+ "Step 6: Verify second page of users loads",
2831
+ "Step 7: Verify URL updates with page parameter",
2832
+ "Step 8: Enter search term in search box",
2833
+ "Step 9: Verify list filters to matching users",
2834
+ "Step 10: Verify pagination resets to page 1",
2835
+ "Step 11: Clear search",
2836
+ "Step 12: Verify full list returns with original pagination"
2837
+ ],
2838
+ "passes": false
2839
+ },
2840
+ {
2841
+ "category": "functional",
2842
+ "description": "Complete session lifecycle from login to logout",
2843
+ "steps": [
2844
+ "Step 1: Navigate to login page",
2845
+ "Step 2: Complete Google OAuth login",
2846
+ "Step 3: Verify session cookie is set",
2847
+ "Step 4: Access protected route successfully",
2848
+ "Step 5: Note session creation time",
2849
+ "Step 6: Wait or manually advance time near expiry",
2850
+ "Step 7: Verify session refresh occurs automatically",
2851
+ "Step 8: Click logout button",
2852
+ "Step 9: Verify session is deleted from KV",
2853
+ "Step 10: Verify session cookie is cleared",
2854
+ "Step 11: Verify redirect to login page",
2855
+ "Step 12: Attempt to access protected route",
2856
+ "Step 13: Verify redirect to login with 401"
2857
+ ],
2858
+ "passes": false
2859
+ },
2860
+ {
2861
+ "category": "functional",
2862
+ "description": "Complete account creation and configuration by super admin",
2863
+ "steps": [
2864
+ "Step 1: Log in as Super Admin",
2865
+ "Step 2: Navigate to account management",
2866
+ "Step 3: Click create new account",
2867
+ "Step 4: Enter account name 'Acme Corporation'",
2868
+ "Step 5: Add optional description",
2869
+ "Step 6: Submit and verify 201 Created",
2870
+ "Step 7: Verify INSERT audit event logged",
2871
+ "Step 8: Navigate to new account settings",
2872
+ "Step 9: Update account description",
2873
+ "Step 10: Verify UPDATE audit event with changes",
2874
+ "Step 11: Add first user to account as ADMIN",
2875
+ "Step 12: Verify user can access new account"
2876
+ ],
2877
+ "passes": false
2878
+ },
2879
+ {
2880
+ "category": "functional",
2881
+ "description": "Complete soft delete and restore workflow for user",
2882
+ "steps": [
2883
+ "Step 1: Log in as ADMIN user",
2884
+ "Step 2: Create a new user or select existing user",
2885
+ "Step 3: Verify user appears in active users list",
2886
+ "Step 4: Click delete user button",
2887
+ "Step 5: Confirm deletion in dialog",
2888
+ "Step 6: Verify user removed from active list",
2889
+ "Step 7: Verify DELETE audit event logged",
2890
+ "Step 8: Query database to confirm deletedAt is set",
2891
+ "Step 9: Log in as Super Admin",
2892
+ "Step 10: Navigate to deleted users (or API)",
2893
+ "Step 11: Click restore user",
2894
+ "Step 12: Verify user reappears in active list",
2895
+ "Step 13: Verify user's account relationships preserved"
2896
+ ],
2897
+ "passes": false
2898
+ },
2899
+ {
2900
+ "category": "functional",
2901
+ "description": "Complete RBAC enforcement across all operations",
2902
+ "steps": [
2903
+ "Step 1: Create test account with users in each role",
2904
+ "Step 2: Log in as VIEWER",
2905
+ "Step 3: Verify can list users (GET succeeds)",
2906
+ "Step 4: Attempt to create user (POST fails 403)",
2907
+ "Step 5: Log in as EDITOR",
2908
+ "Step 6: Verify can create resources",
2909
+ "Step 7: Attempt to manage invitations (fails 403)",
2910
+ "Step 8: Log in as MANAGER",
2911
+ "Step 9: Verify can create and revoke invitations",
2912
+ "Step 10: Attempt to update account settings (fails 403)",
2913
+ "Step 11: Log in as ADMIN",
2914
+ "Step 12: Verify full account management capabilities",
2915
+ "Step 13: Attempt to create new account (fails 403, super admin only)"
2916
+ ],
2917
+ "passes": false
2918
+ },
2919
+ {
2920
+ "category": "style",
2921
+ "description": "Complete responsive design verification across breakpoints",
2922
+ "steps": [
2923
+ "Step 1: Load dashboard on desktop (1920px)",
2924
+ "Step 2: Verify full sidebar visible with all navigation",
2925
+ "Step 3: Verify stats cards in grid layout",
2926
+ "Step 4: Resize to laptop (1366px)",
2927
+ "Step 5: Verify layout adjusts appropriately",
2928
+ "Step 6: Resize to tablet (768px)",
2929
+ "Step 7: Verify sidebar collapses or becomes toggleable",
2930
+ "Step 8: Verify cards may stack vertically",
2931
+ "Step 9: Resize to mobile (375px)",
2932
+ "Step 10: Verify hamburger menu appears",
2933
+ "Step 11: Verify content fits without horizontal scroll",
2934
+ "Step 12: Tap hamburger and verify sidebar slides in"
2935
+ ],
2936
+ "passes": false
2937
+ },
2938
+ {
2939
+ "category": "style",
2940
+ "description": "Complete dark mode visual verification",
2941
+ "steps": [
2942
+ "Step 1: Enable dark mode via system preference or toggle",
2943
+ "Step 2: Navigate to landing page",
2944
+ "Step 3: Verify background is near-black (#0a0a0a)",
2945
+ "Step 4: Verify text is off-white (#fafafa)",
2946
+ "Step 5: Navigate to dashboard",
2947
+ "Step 6: Verify card backgrounds match dark theme",
2948
+ "Step 7: Verify borders use dark gray (#262626)",
2949
+ "Step 8: Navigate to form page",
2950
+ "Step 9: Verify input fields have dark styling",
2951
+ "Step 10: Open modal dialog",
2952
+ "Step 11: Verify modal uses dark theme",
2953
+ "Step 12: Verify all interactive elements have visible focus states"
2954
+ ],
2955
+ "passes": false
2956
+ },
2957
+ {
2958
+ "category": "functional",
2959
+ "description": "Complete keyboard accessibility navigation test",
2960
+ "steps": [
2961
+ "Step 1: Navigate to authenticated page",
2962
+ "Step 2: Press Tab and verify focus on first interactive element",
2963
+ "Step 3: Continue Tab through sidebar navigation",
2964
+ "Step 4: Verify all nav links are focusable",
2965
+ "Step 5: Press Enter on Team link",
2966
+ "Step 6: Verify navigation occurs",
2967
+ "Step 7: Tab to Invite button",
2968
+ "Step 8: Press Enter to open dialog",
2969
+ "Step 9: Verify focus moves into dialog",
2970
+ "Step 10: Tab through dialog fields",
2971
+ "Step 11: Press Escape to close dialog",
2972
+ "Step 12: Verify focus returns to trigger button"
2973
+ ],
2974
+ "passes": false
2975
+ },
2976
+ {
2977
+ "category": "functional",
2978
+ "description": "Complete CI/CD pipeline verification",
2979
+ "steps": [
2980
+ "Step 1: Run pnpm lint and verify no errors",
2981
+ "Step 2: Run pnpm typecheck and verify no type errors",
2982
+ "Step 3: Run pnpm test:run and verify all unit tests pass",
2983
+ "Step 4: Check unit test coverage meets thresholds (95% server, 90% client)",
2984
+ "Step 5: Run pnpm test:e2e --grep @smoke",
2985
+ "Step 6: Verify smoke tests pass",
2986
+ "Step 7: Run pnpm test:e2e --grep @critical",
2987
+ "Step 8: Verify critical path tests pass",
2988
+ "Step 9: Run pnpm build",
2989
+ "Step 10: Verify build completes without errors",
2990
+ "Step 11: Run pnpm deploy --dry-run",
2991
+ "Step 12: Verify deployment configuration is valid"
2992
+ ],
2993
+ "passes": false
2994
+ },
2995
+ {
2996
+ "category": "functional",
2997
+ "description": "Complete database migration and seeding workflow",
2998
+ "steps": [
2999
+ "Step 1: Drop local database to start fresh",
3000
+ "Step 2: Run pnpm db:migrate:local",
3001
+ "Step 3: Verify all migrations apply successfully",
3002
+ "Step 4: Verify all tables are created (users, accounts, etc.)",
3003
+ "Step 5: Verify all indexes are created",
3004
+ "Step 6: Verify all foreign keys are established",
3005
+ "Step 7: Run pnpm db:seed",
3006
+ "Step 8: Verify test users are created",
3007
+ "Step 9: Verify test accounts are created",
3008
+ "Step 10: Verify user-account relationships established",
3009
+ "Step 11: Start application and login with seeded user",
3010
+ "Step 12: Verify seeded data accessible through UI"
3011
+ ],
3012
+ "passes": false
3013
+ },
3014
+ {
3015
+ "category": "functional",
3016
+ "description": "Complete invitation expiration and cleanup workflow",
3017
+ "steps": [
3018
+ "Step 1: Create invitation for new email",
3019
+ "Step 2: Verify expiresAt is set to 7 days in future",
3020
+ "Step 3: Verify invitation appears in pending list",
3021
+ "Step 4: Manually update invitation expiresAt to past date",
3022
+ "Step 5: Navigate to invitation link",
3023
+ "Step 6: Verify expiration error message displayed",
3024
+ "Step 7: Verify invitation not listed as valid",
3025
+ "Step 8: Attempt to accept expired invitation",
3026
+ "Step 9: Verify proper error response",
3027
+ "Step 10: Create new invitation for same email",
3028
+ "Step 11: Verify new invitation replaces or coexists with expired",
3029
+ "Step 12: Accept new invitation successfully"
3030
+ ],
3031
+ "passes": false
3032
+ },
3033
+ {
3034
+ "category": "functional",
3035
+ "description": "Complete API documentation and testing workflow",
3036
+ "steps": [
3037
+ "Step 1: Navigate to /api/doc",
3038
+ "Step 2: Verify OpenAPI JSON schema loads",
3039
+ "Step 3: Verify all endpoints documented",
3040
+ "Step 4: Navigate to /api/swagger",
3041
+ "Step 5: Verify Swagger UI renders correctly",
3042
+ "Step 6: Expand auth endpoints",
3043
+ "Step 7: Verify request/response schemas shown",
3044
+ "Step 8: Click 'Try It Out' on /health endpoint",
3045
+ "Step 9: Execute request",
3046
+ "Step 10: Verify response matches schema",
3047
+ "Step 11: Test authenticated endpoint with session cookie",
3048
+ "Step 12: Verify authentication works in Swagger UI"
3049
+ ],
3050
+ "passes": false
3051
+ },
3052
+ {
3053
+ "category": "functional",
3054
+ "description": "Complete security audit checklist verification",
3055
+ "steps": [
3056
+ "Step 1: Verify session cookie has httpOnly flag",
3057
+ "Step 2: Verify session cookie has secure flag (production)",
3058
+ "Step 3: Verify session cookie has sameSite=Lax",
3059
+ "Step 4: Verify refresh tokens are hashed (SHA-256)",
3060
+ "Step 5: Verify passwords/secrets not in any logs",
3061
+ "Step 6: Verify CORS configuration is restrictive",
3062
+ "Step 7: Verify error messages don't leak stack traces",
3063
+ "Step 8: Verify rate limiting is enabled",
3064
+ "Step 9: Test SQL injection prevention",
3065
+ "Step 10: Test XSS prevention in inputs",
3066
+ "Step 11: Verify CSRF protection via cookies",
3067
+ "Step 12: Verify JWT_SECRET length validation"
3068
+ ],
3069
+ "passes": false
3070
+ },
3071
+ {
3072
+ "category": "functional",
3073
+ "description": "Complete Cloudflare Workers deployment verification",
3074
+ "steps": [
3075
+ "Step 1: Run pnpm cf-typegen",
3076
+ "Step 2: Verify Cloudflare types generated",
3077
+ "Step 3: Set required secrets via wrangler",
3078
+ "Step 4: Run pnpm db:migrate:remote",
3079
+ "Step 5: Verify D1 migrations applied",
3080
+ "Step 6: Run pnpm deploy",
3081
+ "Step 7: Verify worker deployment succeeds",
3082
+ "Step 8: Access deployed worker URL",
3083
+ "Step 9: Verify /health endpoint responds",
3084
+ "Step 10: Test OAuth flow on production",
3085
+ "Step 11: Verify KV sessions work",
3086
+ "Step 12: Verify R2 file uploads work"
3087
+ ],
3088
+ "passes": false
3089
+ },
3090
+ {
3091
+ "category": "style",
3092
+ "description": "Complete design system consistency audit",
3093
+ "steps": [
3094
+ "Step 1: Verify Inter font loaded for body text",
3095
+ "Step 2: Verify JetBrains Mono for code elements",
3096
+ "Step 3: Verify text-sm is 0.875rem (14px)",
3097
+ "Step 4: Verify spacing uses 4px base (p-2=8px, p-4=16px)",
3098
+ "Step 5: Verify border-radius: rounded-md=6px, rounded-lg=8px",
3099
+ "Step 6: Verify card shadows match design spec",
3100
+ "Step 7: Verify primary button uses brand color",
3101
+ "Step 8: Verify destructive button uses red (#dc2626)",
3102
+ "Step 9: Verify transitions are 150ms ease-in-out",
3103
+ "Step 10: Verify focus rings use brand color",
3104
+ "Step 11: Verify toast positioning (bottom-right)",
3105
+ "Step 12: Verify modal overlay and scale animation"
3106
+ ],
3107
+ "passes": false
3108
+ },
3109
+ {
3110
+ "category": "functional",
3111
+ "description": "Complete TanStack Query state management verification",
3112
+ "steps": [
3113
+ "Step 1: Navigate to page that fetches data",
3114
+ "Step 2: Verify data is fetched and displayed",
3115
+ "Step 3: Open React DevTools Query tab",
3116
+ "Step 4: Verify query cache contains data",
3117
+ "Step 5: Navigate away from page",
3118
+ "Step 6: Navigate back to page",
3119
+ "Step 7: Verify data displays instantly from cache",
3120
+ "Step 8: Verify background refetch occurs",
3121
+ "Step 9: Switch browser tabs and wait",
3122
+ "Step 10: Return to app tab",
3123
+ "Step 11: Verify refetchOnWindowFocus triggers",
3124
+ "Step 12: Perform mutation and verify cache invalidation"
3125
+ ],
3126
+ "passes": false
3127
+ }
3128
+ ]