@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,776 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Technical Debt Analyzer
4
+ Detects technical debt indicators in microservices codebases.
5
+
6
+ Detection categories:
7
+ - Outdated dependencies
8
+ - Code complexity (cyclomatic complexity estimation)
9
+ - Code duplication patterns
10
+ - TODO/FIXME/HACK comments
11
+ - Large files and functions
12
+ - Missing tests
13
+ - Deprecated APIs and patterns
14
+ - Security indicators
15
+ - Code smells and anti-patterns
16
+
17
+ Based on best practices from:
18
+ - SonarQube's technical debt calculation
19
+ - Pattern-based analysis for anti-patterns
20
+ - AI-driven commit message analysis
21
+ """
22
+
23
+ import os
24
+ import re
25
+ import json
26
+ import argparse
27
+ import subprocess
28
+ from pathlib import Path
29
+ from typing import Dict, List, Set, Tuple, Optional
30
+ from dataclasses import dataclass, field, asdict
31
+ from collections import defaultdict
32
+ from datetime import datetime
33
+ import hashlib
34
+
35
+
36
+ @dataclass
37
+ class TechDebtItem:
38
+ """Represents a technical debt item"""
39
+ id: str
40
+ category: str
41
+ severity: str # critical, high, medium, low
42
+ service: str
43
+ file: str
44
+ line: Optional[int]
45
+ description: str
46
+ evidence: str
47
+ recommendation: str
48
+ effort: str # hours estimate
49
+ confidence: str = "HIGH"
50
+
51
+ def to_dict(self):
52
+ return asdict(self)
53
+
54
+
55
+ class TechDebtAnalyzer:
56
+ """Analyzes codebases for technical debt indicators"""
57
+
58
+ # TODO/FIXME patterns with context extraction
59
+ DEBT_COMMENT_PATTERNS = [
60
+ (r"(?://|#|/\*)\s*(TODO|FIXME|HACK|XXX|KLUDGE|TEMP|TEMPORARY)\s*:?\s*(.{0,100})", "comment"),
61
+ (r"(?://|#|/\*)\s*(BUG|BROKEN|REFACTOR|OPTIMIZE|DEPRECATED)\s*:?\s*(.{0,100})", "comment"),
62
+ (r"['\"](?:temporary|hack|workaround|quick.?fix)['\"]", "string"),
63
+ ]
64
+
65
+ # Deprecated/outdated patterns by language
66
+ DEPRECATED_PATTERNS = {
67
+ 'javascript': [
68
+ (r"var\s+\w+\s*=", "Use 'const' or 'let' instead of 'var'", "medium"),
69
+ (r"new\s+Promise\s*\(\s*function", "Use arrow functions in Promise", "low"),
70
+ (r"\.then\s*\(\s*function", "Use arrow functions in callbacks", "low"),
71
+ (r"componentWillMount|componentWillReceiveProps|componentWillUpdate",
72
+ "Deprecated React lifecycle methods", "high"),
73
+ (r"require\s*\(['\"]", "Consider using ES modules (import)", "low"),
74
+ (r"@angular/http", "Use @angular/common/http instead", "high"),
75
+ (r"moment\(", "Consider date-fns or dayjs instead of moment.js", "medium"),
76
+ ],
77
+ 'python': [
78
+ (r"print\s+['\"]", "Use print() function (Python 3)", "high"),
79
+ (r"except\s*:", "Use explicit exception types", "medium"),
80
+ (r"from __future__", "Python 2 compatibility - may be removable", "low"),
81
+ (r"\.encode\(['\"]utf-?8['\"]\)", "UTF-8 is default in Python 3", "low"),
82
+ (r"asyncio\.get_event_loop\(\)", "Use asyncio.get_running_loop() in Python 3.10+", "medium"),
83
+ (r"typing\.Optional\[", "Use X | None syntax in Python 3.10+", "low"),
84
+ ],
85
+ 'java': [
86
+ (r"new\s+Date\(\)", "Use java.time API instead of Date", "medium"),
87
+ (r"StringBuffer", "Use StringBuilder in single-threaded contexts", "low"),
88
+ (r"Vector|Hashtable", "Use ArrayList/HashMap instead", "medium"),
89
+ (r"@SuppressWarnings", "Investigate suppressed warnings", "medium"),
90
+ (r"synchronized\s*\(this\)", "Use explicit lock objects", "medium"),
91
+ ],
92
+ }
93
+
94
+ # Security anti-patterns
95
+ SECURITY_PATTERNS = [
96
+ (r"password\s*=\s*['\"][^'\"]+['\"]", "Hardcoded password", "critical"),
97
+ (r"api[_-]?key\s*=\s*['\"][^'\"]+['\"]", "Hardcoded API key", "critical"),
98
+ (r"secret\s*=\s*['\"][^'\"]+['\"]", "Hardcoded secret", "critical"),
99
+ (r"eval\s*\(", "Use of eval() - potential code injection", "high"),
100
+ (r"exec\s*\(", "Use of exec() - potential code injection", "high"),
101
+ (r"innerHTML\s*=", "innerHTML assignment - potential XSS", "high"),
102
+ (r"dangerouslySetInnerHTML", "React dangerous HTML - review carefully", "high"),
103
+ (r"subprocess\.call\s*\([^)]*shell\s*=\s*True", "Shell=True in subprocess - injection risk", "high"),
104
+ (r"os\.system\s*\(", "os.system() - use subprocess instead", "high"),
105
+ (r"pickle\.load", "Pickle deserialization - potential RCE", "high"),
106
+ (r"yaml\.load\s*\([^)]*\)", "Unsafe YAML load - use safe_load()", "high"),
107
+ (r"Math\.random\s*\(", "Math.random() for security - use crypto", "medium"),
108
+ (r"md5|sha1\s*\(", "Weak hash algorithm", "medium"),
109
+ (r"verify\s*=\s*False", "SSL verification disabled", "critical"),
110
+ (r"CORS\s*\(\s*\*\s*\)|allow_origins\s*=\s*\[\s*['\"]?\*", "CORS allows all origins", "high"),
111
+ ]
112
+
113
+ # Complexity indicators
114
+ COMPLEXITY_PATTERNS = [
115
+ (r"if\s*\(", 1),
116
+ (r"else\s+if|elif", 1),
117
+ (r"while\s*\(|while\s+", 1),
118
+ (r"for\s*\(|for\s+\w+\s+in", 1),
119
+ (r"case\s+", 1),
120
+ (r"\?\s*[^:]+\s*:", 1), # ternary
121
+ (r"catch\s*\(|except\s+", 1),
122
+ (r"\&\&|\|\||\band\b|\bor\b", 1),
123
+ ]
124
+
125
+ # Code smell patterns
126
+ CODE_SMELLS = [
127
+ (r"function\s+\w+\s*\([^)]{100,}\)", "Too many parameters", "medium"),
128
+ (r"def\s+\w+\s*\([^)]{100,}\)", "Too many parameters", "medium"),
129
+ (r"(console\.log|print|System\.out\.print)", "Debug output left in code", "low"),
130
+ (r"//.*disabled|#.*disabled|/\*.*disabled", "Disabled code comments", "medium"),
131
+ (r"if\s*\(\s*true\s*\)|if\s+True\s*:", "Always-true condition", "medium"),
132
+ (r"if\s*\(\s*false\s*\)|if\s+False\s*:", "Always-false condition (dead code)", "medium"),
133
+ (r"return\s+null|return\s+None", "Null return - consider Optional/Maybe", "low"),
134
+ (r"throw\s+new\s+Error\s*\(\s*\)", "Empty error message", "medium"),
135
+ (r"catch\s*\([^)]*\)\s*\{\s*\}", "Empty catch block", "high"),
136
+ (r"except\s*:\s*pass", "Silent exception swallowing", "high"),
137
+ (r"\bmagic\b|\bhardcode", "Magic number/hardcoded value indicator", "low"),
138
+ ]
139
+
140
+ # File size thresholds (lines)
141
+ FILE_SIZE_THRESHOLDS = {
142
+ 'warning': 300,
143
+ 'critical': 500,
144
+ }
145
+
146
+ # Function size thresholds (lines)
147
+ FUNCTION_SIZE_THRESHOLDS = {
148
+ 'warning': 50,
149
+ 'critical': 100,
150
+ }
151
+
152
+ def __init__(self, root_path: str, services: List[Dict] = None, threshold: str = "medium"):
153
+ self.root_path = Path(root_path).resolve()
154
+ self.services = services or []
155
+ self.threshold = threshold
156
+ self.debt_items: List[TechDebtItem] = []
157
+ self.item_counter = 0
158
+
159
+ def _generate_id(self) -> str:
160
+ """Generate unique debt item ID"""
161
+ self.item_counter += 1
162
+ return f"TD-{self.item_counter:04d}"
163
+
164
+ def _get_severity_level(self, severity: str) -> int:
165
+ """Convert severity to numeric level"""
166
+ levels = {'critical': 4, 'high': 3, 'medium': 2, 'low': 1}
167
+ return levels.get(severity, 0)
168
+
169
+ def _passes_threshold(self, severity: str) -> bool:
170
+ """Check if severity passes the threshold filter"""
171
+ threshold_level = self._get_severity_level(self.threshold)
172
+ item_level = self._get_severity_level(severity)
173
+ return item_level >= threshold_level
174
+
175
+ def analyze_debt_comments(self, service_path: Path, service_name: str) -> List[TechDebtItem]:
176
+ """Find TODO/FIXME/HACK comments"""
177
+ items = []
178
+
179
+ for file_path in service_path.rglob('*'):
180
+ if not file_path.is_file() or 'node_modules' in str(file_path):
181
+ continue
182
+ if file_path.suffix not in ['.js', '.ts', '.jsx', '.tsx', '.py', '.java', '.go', '.rb']:
183
+ continue
184
+
185
+ try:
186
+ content = file_path.read_text(errors='ignore')
187
+ lines = content.split('\n')
188
+
189
+ for i, line in enumerate(lines, 1):
190
+ for pattern, _ in self.DEBT_COMMENT_PATTERNS:
191
+ match = re.search(pattern, line, re.IGNORECASE)
192
+ if match:
193
+ debt_type = match.group(1).upper() if match.lastindex >= 1 else "DEBT"
194
+ description = match.group(2).strip() if match.lastindex >= 2 else ""
195
+
196
+ severity = "high" if debt_type in ["FIXME", "BUG", "BROKEN"] else "medium"
197
+
198
+ if self._passes_threshold(severity):
199
+ items.append(TechDebtItem(
200
+ id=self._generate_id(),
201
+ category="debt-comment",
202
+ severity=severity,
203
+ service=service_name,
204
+ file=str(file_path.relative_to(service_path)),
205
+ line=i,
206
+ description=f"{debt_type}: {description}" if description else debt_type,
207
+ evidence=line.strip()[:150],
208
+ recommendation="Address the noted issue and remove comment",
209
+ effort="1-4h",
210
+ confidence="HIGH"
211
+ ))
212
+ break # Only match once per line
213
+
214
+ except Exception:
215
+ continue
216
+
217
+ return items
218
+
219
+ def analyze_deprecated_patterns(self, service_path: Path, service_name: str) -> List[TechDebtItem]:
220
+ """Find deprecated APIs and outdated patterns"""
221
+ items = []
222
+
223
+ # Detect language
224
+ language = None
225
+ if list(service_path.glob('*.py')) or list(service_path.glob('**/*.py')):
226
+ language = 'python'
227
+ elif list(service_path.glob('package.json')):
228
+ language = 'javascript'
229
+ elif list(service_path.glob('**/*.java')):
230
+ language = 'java'
231
+
232
+ if not language:
233
+ return items
234
+
235
+ patterns = self.DEPRECATED_PATTERNS.get(language, [])
236
+
237
+ for file_path in service_path.rglob('*'):
238
+ if not file_path.is_file() or 'node_modules' in str(file_path):
239
+ continue
240
+
241
+ ext_map = {'python': ['.py'], 'javascript': ['.js', '.ts', '.jsx', '.tsx'], 'java': ['.java']}
242
+ if file_path.suffix not in ext_map.get(language, []):
243
+ continue
244
+
245
+ try:
246
+ content = file_path.read_text(errors='ignore')
247
+ lines = content.split('\n')
248
+
249
+ for i, line in enumerate(lines, 1):
250
+ for pattern, message, severity in patterns:
251
+ if re.search(pattern, line):
252
+ if self._passes_threshold(severity):
253
+ items.append(TechDebtItem(
254
+ id=self._generate_id(),
255
+ category="deprecated-pattern",
256
+ severity=severity,
257
+ service=service_name,
258
+ file=str(file_path.relative_to(service_path)),
259
+ line=i,
260
+ description=message,
261
+ evidence=line.strip()[:150],
262
+ recommendation=f"Update to modern pattern: {message}",
263
+ effort="0.5-2h",
264
+ confidence="HIGH"
265
+ ))
266
+ break
267
+
268
+ except Exception:
269
+ continue
270
+
271
+ return items
272
+
273
+ def analyze_security_patterns(self, service_path: Path, service_name: str) -> List[TechDebtItem]:
274
+ """Find security anti-patterns"""
275
+ items = []
276
+
277
+ for file_path in service_path.rglob('*'):
278
+ if not file_path.is_file() or 'node_modules' in str(file_path):
279
+ continue
280
+ if file_path.suffix not in ['.js', '.ts', '.py', '.java', '.go', '.rb', '.php']:
281
+ continue
282
+
283
+ try:
284
+ content = file_path.read_text(errors='ignore')
285
+ lines = content.split('\n')
286
+
287
+ for i, line in enumerate(lines, 1):
288
+ for pattern, message, severity in self.SECURITY_PATTERNS:
289
+ if re.search(pattern, line, re.IGNORECASE):
290
+ if self._passes_threshold(severity):
291
+ items.append(TechDebtItem(
292
+ id=self._generate_id(),
293
+ category="security",
294
+ severity=severity,
295
+ service=service_name,
296
+ file=str(file_path.relative_to(service_path)),
297
+ line=i,
298
+ description=message,
299
+ evidence=line.strip()[:100] + "..." if len(line) > 100 else line.strip(),
300
+ recommendation=f"Security: {message} - review and fix immediately",
301
+ effort="1-4h",
302
+ confidence="HIGH"
303
+ ))
304
+ break
305
+
306
+ except Exception:
307
+ continue
308
+
309
+ return items
310
+
311
+ def analyze_code_smells(self, service_path: Path, service_name: str) -> List[TechDebtItem]:
312
+ """Find code smells and anti-patterns"""
313
+ items = []
314
+
315
+ for file_path in service_path.rglob('*'):
316
+ if not file_path.is_file() or 'node_modules' in str(file_path):
317
+ continue
318
+ if file_path.suffix not in ['.js', '.ts', '.py', '.java', '.go']:
319
+ continue
320
+
321
+ try:
322
+ content = file_path.read_text(errors='ignore')
323
+ lines = content.split('\n')
324
+
325
+ for i, line in enumerate(lines, 1):
326
+ for pattern, message, severity in self.CODE_SMELLS:
327
+ if re.search(pattern, line, re.IGNORECASE):
328
+ if self._passes_threshold(severity):
329
+ items.append(TechDebtItem(
330
+ id=self._generate_id(),
331
+ category="code-smell",
332
+ severity=severity,
333
+ service=service_name,
334
+ file=str(file_path.relative_to(service_path)),
335
+ line=i,
336
+ description=message,
337
+ evidence=line.strip()[:150],
338
+ recommendation=f"Refactor: {message}",
339
+ effort="0.5-2h",
340
+ confidence="MEDIUM"
341
+ ))
342
+ break
343
+
344
+ except Exception:
345
+ continue
346
+
347
+ return items
348
+
349
+ def analyze_file_complexity(self, service_path: Path, service_name: str) -> List[TechDebtItem]:
350
+ """Analyze file sizes and estimated complexity"""
351
+ items = []
352
+
353
+ for file_path in service_path.rglob('*'):
354
+ if not file_path.is_file() or 'node_modules' in str(file_path):
355
+ continue
356
+ if file_path.suffix not in ['.js', '.ts', '.py', '.java', '.go']:
357
+ continue
358
+ if 'test' in str(file_path).lower() or 'spec' in str(file_path).lower():
359
+ continue
360
+
361
+ try:
362
+ content = file_path.read_text(errors='ignore')
363
+ lines = content.split('\n')
364
+ line_count = len(lines)
365
+
366
+ # Check file size
367
+ if line_count >= self.FILE_SIZE_THRESHOLDS['critical']:
368
+ severity = "high"
369
+ elif line_count >= self.FILE_SIZE_THRESHOLDS['warning']:
370
+ severity = "medium"
371
+ else:
372
+ severity = None
373
+
374
+ if severity and self._passes_threshold(severity):
375
+ items.append(TechDebtItem(
376
+ id=self._generate_id(),
377
+ category="large-file",
378
+ severity=severity,
379
+ service=service_name,
380
+ file=str(file_path.relative_to(service_path)),
381
+ line=None,
382
+ description=f"File has {line_count} lines - consider splitting",
383
+ evidence=f"Line count: {line_count}",
384
+ recommendation="Split into smaller, focused modules",
385
+ effort="2-8h",
386
+ confidence="HIGH"
387
+ ))
388
+
389
+ # Estimate cyclomatic complexity
390
+ complexity = 1 # Base complexity
391
+ for pattern, weight in self.COMPLEXITY_PATTERNS:
392
+ matches = re.findall(pattern, content)
393
+ complexity += len(matches) * weight
394
+
395
+ # Complexity per 100 lines (normalized)
396
+ if line_count > 0:
397
+ complexity_ratio = complexity / (line_count / 100)
398
+ if complexity_ratio > 30:
399
+ severity = "high"
400
+ elif complexity_ratio > 20:
401
+ severity = "medium"
402
+ else:
403
+ severity = None
404
+
405
+ if severity and self._passes_threshold(severity) and line_count > 50:
406
+ items.append(TechDebtItem(
407
+ id=self._generate_id(),
408
+ category="high-complexity",
409
+ severity=severity,
410
+ service=service_name,
411
+ file=str(file_path.relative_to(service_path)),
412
+ line=None,
413
+ description=f"High complexity ratio: {complexity_ratio:.1f} per 100 lines",
414
+ evidence=f"Estimated complexity: {complexity}, Lines: {line_count}",
415
+ recommendation="Refactor complex logic, extract methods",
416
+ effort="4-16h",
417
+ confidence="MEDIUM"
418
+ ))
419
+
420
+ except Exception:
421
+ continue
422
+
423
+ return items
424
+
425
+ def analyze_outdated_dependencies(self, service_path: Path, service_name: str) -> List[TechDebtItem]:
426
+ """Check for outdated dependencies (basic version check)"""
427
+ items = []
428
+
429
+ # Known outdated versions (major version behind)
430
+ outdated_packages = {
431
+ # JavaScript
432
+ 'react': ('18', 'React 18 has concurrent features'),
433
+ 'webpack': ('5', 'Webpack 5 has better tree-shaking'),
434
+ 'typescript': ('5', 'TypeScript 5 has decorators'),
435
+ 'eslint': ('8', 'ESLint 8 has flat config'),
436
+ 'jest': ('29', 'Jest 29 has improved speed'),
437
+ 'express': ('4', 'Express 5 coming soon'),
438
+ 'mongoose': ('8', 'Mongoose 8 has better typing'),
439
+ 'axios': ('1', 'Axios 1 is stable'),
440
+ # Python (from requirements.txt patterns)
441
+ 'django': ('4', 'Django 4 has async support'),
442
+ 'flask': ('2', 'Flask 2 has async support'),
443
+ 'fastapi': ('0.100', 'Latest FastAPI has improvements'),
444
+ 'sqlalchemy': ('2', 'SQLAlchemy 2 has better typing'),
445
+ 'pydantic': ('2', 'Pydantic 2 has better performance'),
446
+ }
447
+
448
+ # Check package.json
449
+ pkg_file = service_path / 'package.json'
450
+ if pkg_file.exists():
451
+ try:
452
+ with open(pkg_file) as f:
453
+ data = json.load(f)
454
+ all_deps = {**data.get('dependencies', {}), **data.get('devDependencies', {})}
455
+
456
+ for pkg, version in all_deps.items():
457
+ if pkg in outdated_packages:
458
+ min_version, message = outdated_packages[pkg]
459
+ # Extract major version from semver
460
+ current = re.search(r'[\^~]?(\d+)', version)
461
+ if current:
462
+ current_major = current.group(1)
463
+ if int(current_major) < int(min_version.split('.')[0]):
464
+ items.append(TechDebtItem(
465
+ id=self._generate_id(),
466
+ category="outdated-dependency",
467
+ severity="medium",
468
+ service=service_name,
469
+ file="package.json",
470
+ line=None,
471
+ description=f"{pkg}@{version} is outdated - {message}",
472
+ evidence=f"Current: {version}, Recommended: {min_version}+",
473
+ recommendation=f"Update {pkg} to latest major version",
474
+ effort="1-4h",
475
+ confidence="HIGH"
476
+ ))
477
+ except Exception:
478
+ pass
479
+
480
+ # Check requirements.txt
481
+ for req_file in ['requirements.txt', 'requirements-dev.txt', 'requirements.in']:
482
+ req_path = service_path / req_file
483
+ if req_path.exists():
484
+ try:
485
+ content = req_path.read_text()
486
+ for line in content.split('\n'):
487
+ for pkg, (min_version, message) in outdated_packages.items():
488
+ if line.lower().startswith(pkg):
489
+ match = re.search(r'[=<>]=?(\d+\.?\d*)', line)
490
+ if match:
491
+ current = match.group(1)
492
+ if float(current.split('.')[0]) < float(min_version.split('.')[0]):
493
+ items.append(TechDebtItem(
494
+ id=self._generate_id(),
495
+ category="outdated-dependency",
496
+ severity="medium",
497
+ service=service_name,
498
+ file=req_file,
499
+ line=None,
500
+ description=f"{pkg} {current} is outdated - {message}",
501
+ evidence=f"Current: {current}, Recommended: {min_version}+",
502
+ recommendation=f"Update {pkg} to latest version",
503
+ effort="1-4h",
504
+ confidence="HIGH"
505
+ ))
506
+ except Exception:
507
+ pass
508
+
509
+ return items
510
+
511
+ def analyze_missing_tests(self, service_path: Path, service_name: str) -> List[TechDebtItem]:
512
+ """Identify source files without corresponding tests"""
513
+ items = []
514
+
515
+ # Find all source files
516
+ source_files = []
517
+ for ext in ['.js', '.ts', '.py', '.java', '.go']:
518
+ for f in service_path.rglob(f'*{ext}'):
519
+ if 'node_modules' not in str(f) and 'test' not in str(f).lower() and 'spec' not in str(f).lower():
520
+ if '__pycache__' not in str(f) and '.d.ts' not in str(f):
521
+ source_files.append(f)
522
+
523
+ # Find all test files
524
+ test_patterns = ['test', 'spec', '_test', '.test', '.spec']
525
+ test_files = set()
526
+ for f in service_path.rglob('*'):
527
+ if f.is_file():
528
+ name_lower = f.stem.lower()
529
+ if any(p in name_lower for p in test_patterns):
530
+ # Extract the base name being tested
531
+ for p in test_patterns:
532
+ name_lower = name_lower.replace(p, '')
533
+ test_files.add(name_lower)
534
+
535
+ # Check for source files without tests
536
+ untested_count = 0
537
+ for source in source_files:
538
+ base_name = source.stem.lower()
539
+ if base_name not in ['index', 'main', '__init__', 'setup', 'config']:
540
+ if base_name not in test_files:
541
+ untested_count += 1
542
+
543
+ if untested_count > 0:
544
+ coverage_estimate = 100 - (untested_count / max(len(source_files), 1) * 100)
545
+ severity = "high" if coverage_estimate < 50 else "medium" if coverage_estimate < 70 else "low"
546
+
547
+ if self._passes_threshold(severity):
548
+ items.append(TechDebtItem(
549
+ id=self._generate_id(),
550
+ category="missing-tests",
551
+ severity=severity,
552
+ service=service_name,
553
+ file="(multiple)",
554
+ line=None,
555
+ description=f"{untested_count} source files without apparent tests (~{coverage_estimate:.0f}% estimated coverage)",
556
+ evidence=f"Source files: {len(source_files)}, Test files found: {len(test_files)}",
557
+ recommendation="Add unit tests for untested modules",
558
+ effort=f"{untested_count * 2}-{untested_count * 4}h",
559
+ confidence="MEDIUM"
560
+ ))
561
+
562
+ return items
563
+
564
+ def analyze_all(self) -> Dict:
565
+ """Run all analyzers on all services"""
566
+ all_items = []
567
+
568
+ for service in self.services:
569
+ service_name = service.get('name', '')
570
+ service_path = self.root_path / service.get('path', '')
571
+
572
+ if not service_path.exists():
573
+ continue
574
+
575
+ print(f"Analyzing technical debt for: {service_name}")
576
+
577
+ all_items.extend(self.analyze_debt_comments(service_path, service_name))
578
+ all_items.extend(self.analyze_deprecated_patterns(service_path, service_name))
579
+ all_items.extend(self.analyze_security_patterns(service_path, service_name))
580
+ all_items.extend(self.analyze_code_smells(service_path, service_name))
581
+ all_items.extend(self.analyze_file_complexity(service_path, service_name))
582
+ all_items.extend(self.analyze_outdated_dependencies(service_path, service_name))
583
+ all_items.extend(self.analyze_missing_tests(service_path, service_name))
584
+
585
+ # Sort by severity
586
+ severity_order = {'critical': 0, 'high': 1, 'medium': 2, 'low': 3}
587
+ all_items.sort(key=lambda x: severity_order.get(x.severity, 4))
588
+
589
+ return {
590
+ 'total_items': len(all_items),
591
+ 'items': [item.to_dict() for item in all_items],
592
+ 'by_category': self._group_by_category(all_items),
593
+ 'by_severity': self._group_by_severity(all_items),
594
+ 'by_service': self._group_by_service(all_items),
595
+ 'summary': self._generate_summary(all_items),
596
+ }
597
+
598
+ def _group_by_category(self, items: List[TechDebtItem]) -> Dict[str, int]:
599
+ grouped = defaultdict(int)
600
+ for item in items:
601
+ grouped[item.category] += 1
602
+ return dict(grouped)
603
+
604
+ def _group_by_severity(self, items: List[TechDebtItem]) -> Dict[str, int]:
605
+ grouped = defaultdict(int)
606
+ for item in items:
607
+ grouped[item.severity] += 1
608
+ return dict(grouped)
609
+
610
+ def _group_by_service(self, items: List[TechDebtItem]) -> Dict[str, int]:
611
+ grouped = defaultdict(int)
612
+ for item in items:
613
+ grouped[item.service] += 1
614
+ return dict(grouped)
615
+
616
+ def _generate_summary(self, items: List[TechDebtItem]) -> Dict:
617
+ """Generate summary statistics"""
618
+ total_effort_low = 0
619
+ total_effort_high = 0
620
+
621
+ for item in items:
622
+ effort = item.effort
623
+ match = re.search(r'(\d+)-(\d+)', effort)
624
+ if match:
625
+ total_effort_low += int(match.group(1))
626
+ total_effort_high += int(match.group(2))
627
+
628
+ return {
629
+ 'total_items': len(items),
630
+ 'critical_count': sum(1 for i in items if i.severity == 'critical'),
631
+ 'high_count': sum(1 for i in items if i.severity == 'high'),
632
+ 'medium_count': sum(1 for i in items if i.severity == 'medium'),
633
+ 'low_count': sum(1 for i in items if i.severity == 'low'),
634
+ 'estimated_effort_hours': f"{total_effort_low}-{total_effort_high}",
635
+ 'estimated_effort_days': f"{total_effort_low/8:.1f}-{total_effort_high/8:.1f}",
636
+ }
637
+
638
+
639
+ def format_markdown(data: Dict) -> str:
640
+ """Format technical debt data as markdown"""
641
+ summary = data['summary']
642
+
643
+ output = f"""# Technical Debt Analysis Report
644
+
645
+ **Generated**: {datetime.now().strftime('%Y-%m-%d %H:%M')}
646
+
647
+ ## Executive Summary
648
+
649
+ | Metric | Value |
650
+ |--------|-------|
651
+ | **Total Debt Items** | {summary['total_items']} |
652
+ | **Critical** | 🔴 {summary['critical_count']} |
653
+ | **High** | 🟠 {summary['high_count']} |
654
+ | **Medium** | 🟡 {summary['medium_count']} |
655
+ | **Low** | 🟢 {summary['low_count']} |
656
+ | **Estimated Effort** | {summary['estimated_effort_hours']} hours ({summary['estimated_effort_days']} days) |
657
+
658
+ ## By Category
659
+
660
+ | Category | Count |
661
+ |----------|-------|
662
+ """
663
+
664
+ for category, count in data['by_category'].items():
665
+ output += f"| {category} | {count} |\n"
666
+
667
+ output += "\n## By Service\n\n| Service | Debt Items |\n|---------|------------|\n"
668
+
669
+ for service, count in data['by_service'].items():
670
+ output += f"| {service} | {count} |\n"
671
+
672
+ output += "\n## Debt Register\n\n"
673
+
674
+ # Group by severity for the register
675
+ for severity in ['critical', 'high', 'medium', 'low']:
676
+ items = [i for i in data['items'] if i['severity'] == severity]
677
+ if items:
678
+ emoji = {'critical': '🔴', 'high': '🟠', 'medium': '🟡', 'low': '🟢'}[severity]
679
+ output += f"\n### {emoji} {severity.upper()} ({len(items)})\n\n"
680
+ output += "| ID | Service | File | Description | Recommendation |\n"
681
+ output += "|----|---------|------|-------------|----------------|\n"
682
+
683
+ for item in items[:20]: # Limit per severity
684
+ file_loc = f"{item['file']}:{item['line']}" if item['line'] else item['file']
685
+ desc = item['description'][:50] + "..." if len(item['description']) > 50 else item['description']
686
+ rec = item['recommendation'][:40] + "..." if len(item['recommendation']) > 40 else item['recommendation']
687
+ output += f"| {item['id']} | {item['service']} | `{file_loc}` | {desc} | {rec} |\n"
688
+
689
+ if len(items) > 20:
690
+ output += f"\n*...and {len(items) - 20} more {severity} items*\n"
691
+
692
+ output += """
693
+ ## Recommendations
694
+
695
+ ### Immediate Actions (Critical/High)
696
+ """
697
+
698
+ critical_high = [i for i in data['items'] if i['severity'] in ['critical', 'high']][:5]
699
+ for i, item in enumerate(critical_high, 1):
700
+ output += f"\n{i}. **{item['id']}**: {item['description']}\n"
701
+ output += f" - File: `{item['file']}`\n"
702
+ output += f" - Action: {item['recommendation']}\n"
703
+ output += f" - Effort: {item['effort']}\n"
704
+
705
+ output += """
706
+ ## Methodology
707
+
708
+ This analysis uses static code analysis to detect:
709
+ - TODO/FIXME/HACK comments indicating known issues
710
+ - Deprecated patterns and outdated APIs
711
+ - Security anti-patterns and hardcoded secrets
712
+ - Code complexity and large files
713
+ - Code smells and anti-patterns
714
+ - Outdated dependencies
715
+ - Missing test coverage
716
+
717
+ **Confidence Levels**:
718
+ - HIGH: Pattern directly matched in code
719
+ - MEDIUM: Inferred from code patterns
720
+ """
721
+
722
+ return output
723
+
724
+
725
+ def main():
726
+ parser = argparse.ArgumentParser(description='Analyze technical debt in microservices')
727
+ parser.add_argument('path', nargs='?', default='.', help='Repository path to analyze')
728
+ parser.add_argument('--services', '-s', help='Services JSON file from analyze_structure.py')
729
+ parser.add_argument('--output', '-o', help='Output file')
730
+ parser.add_argument('--format', '-f', choices=['json', 'markdown'], default='markdown')
731
+ parser.add_argument('--threshold', '-t', choices=['low', 'medium', 'high', 'critical'],
732
+ default='medium', help='Minimum severity to report')
733
+
734
+ args = parser.parse_args()
735
+
736
+ # Load services if provided
737
+ services = []
738
+ if args.services and Path(args.services).exists():
739
+ with open(args.services) as f:
740
+ data = json.load(f)
741
+ services = data.get('services', [])
742
+ else:
743
+ # Try to auto-discover services
744
+ try:
745
+ from analyze_structure import ServiceDiscoverer
746
+ discoverer = ServiceDiscoverer(args.path)
747
+ inventory = discoverer.generate_inventory()
748
+ services = inventory.get('services', [])
749
+ except ImportError:
750
+ # Analyze current directory as single service
751
+ services = [{'name': Path(args.path).name, 'path': '.'}]
752
+
753
+ if not services:
754
+ print("No services found. Analyzing current directory...")
755
+ services = [{'name': Path(args.path).name, 'path': '.'}]
756
+
757
+ # Analyze technical debt
758
+ analyzer = TechDebtAnalyzer(args.path, services, threshold=args.threshold)
759
+ result = analyzer.analyze_all()
760
+
761
+ # Format output
762
+ if args.format == 'json':
763
+ output = json.dumps(result, indent=2)
764
+ else:
765
+ output = format_markdown(result)
766
+
767
+ if args.output:
768
+ with open(args.output, 'w') as f:
769
+ f.write(output)
770
+ print(f"Technical debt report written to {args.output}")
771
+ else:
772
+ print(output)
773
+
774
+
775
+ if __name__ == '__main__':
776
+ main()