agentvibes 2.12.7 → 2.12.8

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 (420) hide show
  1. package/README.md +2 -2
  2. package/package.json +1 -1
  3. package/src/installer.js +23 -20
  4. package/.bmad/_cfg/agent-manifest.csv +0 -11
  5. package/.bmad/_cfg/agent-voice-map.csv +0 -11
  6. package/.bmad/_cfg/agents/bmm-analyst.customize.yaml +0 -42
  7. package/.bmad/_cfg/agents/bmm-architect.customize.yaml +0 -42
  8. package/.bmad/_cfg/agents/bmm-dev.customize.yaml +0 -42
  9. package/.bmad/_cfg/agents/bmm-frame-expert.customize.yaml +0 -42
  10. package/.bmad/_cfg/agents/bmm-pm.customize.yaml +0 -42
  11. package/.bmad/_cfg/agents/bmm-sm.customize.yaml +0 -42
  12. package/.bmad/_cfg/agents/bmm-tea.customize.yaml +0 -42
  13. package/.bmad/_cfg/agents/bmm-tech-writer.customize.yaml +0 -42
  14. package/.bmad/_cfg/agents/bmm-ux-designer.customize.yaml +0 -42
  15. package/.bmad/_cfg/agents/core-bmad-master.customize.yaml +0 -42
  16. package/.bmad/_cfg/files-manifest.csv +0 -243
  17. package/.bmad/_cfg/ides/claude-code.yaml +0 -6
  18. package/.bmad/_cfg/manifest.yaml +0 -9
  19. package/.bmad/_cfg/task-manifest.csv +0 -5
  20. package/.bmad/_cfg/tool-manifest.csv +0 -2
  21. package/.bmad/_cfg/workflow-manifest.csv +0 -38
  22. package/.bmad/bmm/README.md +0 -128
  23. package/.bmad/bmm/agents/analyst.md +0 -79
  24. package/.bmad/bmm/agents/analyst.md.backup-pre-tts +0 -75
  25. package/.bmad/bmm/agents/architect.md +0 -80
  26. package/.bmad/bmm/agents/dev.md +0 -70
  27. package/.bmad/bmm/agents/frame-expert.md +0 -72
  28. package/.bmad/bmm/agents/pm.md +0 -84
  29. package/.bmad/bmm/agents/sm.md +0 -93
  30. package/.bmad/bmm/agents/tea.md +0 -80
  31. package/.bmad/bmm/agents/tech-writer.md +0 -84
  32. package/.bmad/bmm/agents/ux-designer.md +0 -79
  33. package/.bmad/bmm/config.yaml +0 -17
  34. package/.bmad/bmm/docs/README.md +0 -236
  35. package/.bmad/bmm/docs/agents-guide.md +0 -1058
  36. package/.bmad/bmm/docs/brownfield-guide.md +0 -762
  37. package/.bmad/bmm/docs/enterprise-agentic-development.md +0 -686
  38. package/.bmad/bmm/docs/faq.md +0 -588
  39. package/.bmad/bmm/docs/glossary.md +0 -320
  40. package/.bmad/bmm/docs/party-mode.md +0 -224
  41. package/.bmad/bmm/docs/quick-spec-flow.md +0 -652
  42. package/.bmad/bmm/docs/quick-start.md +0 -376
  43. package/.bmad/bmm/docs/scale-adaptive-system.md +0 -612
  44. package/.bmad/bmm/docs/test-architecture.md +0 -396
  45. package/.bmad/bmm/docs/workflow-architecture-reference.md +0 -366
  46. package/.bmad/bmm/docs/workflow-document-project-reference.md +0 -489
  47. package/.bmad/bmm/docs/workflows-analysis.md +0 -370
  48. package/.bmad/bmm/docs/workflows-implementation.md +0 -286
  49. package/.bmad/bmm/docs/workflows-planning.md +0 -612
  50. package/.bmad/bmm/docs/workflows-solutioning.md +0 -554
  51. package/.bmad/bmm/teams/default-party.csv +0 -20
  52. package/.bmad/bmm/teams/team-fullstack.yaml +0 -13
  53. package/.bmad/bmm/testarch/knowledge/ci-burn-in.md +0 -675
  54. package/.bmad/bmm/testarch/knowledge/component-tdd.md +0 -486
  55. package/.bmad/bmm/testarch/knowledge/contract-testing.md +0 -957
  56. package/.bmad/bmm/testarch/knowledge/data-factories.md +0 -500
  57. package/.bmad/bmm/testarch/knowledge/email-auth.md +0 -721
  58. package/.bmad/bmm/testarch/knowledge/error-handling.md +0 -725
  59. package/.bmad/bmm/testarch/knowledge/feature-flags.md +0 -750
  60. package/.bmad/bmm/testarch/knowledge/fixture-architecture.md +0 -401
  61. package/.bmad/bmm/testarch/knowledge/network-first.md +0 -486
  62. package/.bmad/bmm/testarch/knowledge/nfr-criteria.md +0 -670
  63. package/.bmad/bmm/testarch/knowledge/playwright-config.md +0 -730
  64. package/.bmad/bmm/testarch/knowledge/probability-impact.md +0 -601
  65. package/.bmad/bmm/testarch/knowledge/risk-governance.md +0 -615
  66. package/.bmad/bmm/testarch/knowledge/selective-testing.md +0 -732
  67. package/.bmad/bmm/testarch/knowledge/selector-resilience.md +0 -527
  68. package/.bmad/bmm/testarch/knowledge/test-healing-patterns.md +0 -644
  69. package/.bmad/bmm/testarch/knowledge/test-levels-framework.md +0 -473
  70. package/.bmad/bmm/testarch/knowledge/test-priorities-matrix.md +0 -373
  71. package/.bmad/bmm/testarch/knowledge/test-quality.md +0 -664
  72. package/.bmad/bmm/testarch/knowledge/timing-debugging.md +0 -372
  73. package/.bmad/bmm/testarch/knowledge/visual-debugging.md +0 -524
  74. package/.bmad/bmm/testarch/tea-index.csv +0 -22
  75. package/.bmad/bmm/workflows/1-analysis/brainstorm-project/instructions.md +0 -112
  76. package/.bmad/bmm/workflows/1-analysis/brainstorm-project/project-context.md +0 -25
  77. package/.bmad/bmm/workflows/1-analysis/brainstorm-project/workflow.yaml +0 -26
  78. package/.bmad/bmm/workflows/1-analysis/domain-research/instructions.md +0 -425
  79. package/.bmad/bmm/workflows/1-analysis/domain-research/template.md +0 -180
  80. package/.bmad/bmm/workflows/1-analysis/domain-research/workflow.yaml +0 -28
  81. package/.bmad/bmm/workflows/1-analysis/product-brief/checklist.md +0 -115
  82. package/.bmad/bmm/workflows/1-analysis/product-brief/instructions.md +0 -524
  83. package/.bmad/bmm/workflows/1-analysis/product-brief/template.md +0 -181
  84. package/.bmad/bmm/workflows/1-analysis/product-brief/workflow.yaml +0 -45
  85. package/.bmad/bmm/workflows/1-analysis/research/checklist-deep-prompt.md +0 -144
  86. package/.bmad/bmm/workflows/1-analysis/research/checklist-technical.md +0 -249
  87. package/.bmad/bmm/workflows/1-analysis/research/checklist.md +0 -299
  88. package/.bmad/bmm/workflows/1-analysis/research/claude-code/injections.yaml +0 -114
  89. package/.bmad/bmm/workflows/1-analysis/research/instructions-deep-prompt.md +0 -438
  90. package/.bmad/bmm/workflows/1-analysis/research/instructions-market.md +0 -675
  91. package/.bmad/bmm/workflows/1-analysis/research/instructions-router.md +0 -134
  92. package/.bmad/bmm/workflows/1-analysis/research/instructions-technical.md +0 -534
  93. package/.bmad/bmm/workflows/1-analysis/research/template-deep-prompt.md +0 -94
  94. package/.bmad/bmm/workflows/1-analysis/research/template-market.md +0 -347
  95. package/.bmad/bmm/workflows/1-analysis/research/template-technical.md +0 -245
  96. package/.bmad/bmm/workflows/1-analysis/research/workflow.yaml +0 -44
  97. package/.bmad/bmm/workflows/2-plan-workflows/create-epics-and-stories/epics-template.md +0 -80
  98. package/.bmad/bmm/workflows/2-plan-workflows/create-epics-and-stories/instructions.md +0 -616
  99. package/.bmad/bmm/workflows/2-plan-workflows/create-epics-and-stories/workflow.yaml +0 -53
  100. package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/checklist.md +0 -310
  101. package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/instructions.md +0 -1308
  102. package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/ux-design-template.md +0 -145
  103. package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/workflow.yaml +0 -61
  104. package/.bmad/bmm/workflows/2-plan-workflows/prd/checklist.md +0 -346
  105. package/.bmad/bmm/workflows/2-plan-workflows/prd/domain-complexity.csv +0 -13
  106. package/.bmad/bmm/workflows/2-plan-workflows/prd/instructions.md +0 -703
  107. package/.bmad/bmm/workflows/2-plan-workflows/prd/prd-template.md +0 -204
  108. package/.bmad/bmm/workflows/2-plan-workflows/prd/project-types.csv +0 -11
  109. package/.bmad/bmm/workflows/2-plan-workflows/prd/workflow.yaml +0 -52
  110. package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/checklist.md +0 -217
  111. package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/epics-template.md +0 -74
  112. package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/instructions-generate-stories.md +0 -436
  113. package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/instructions.md +0 -980
  114. package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/tech-spec-template.md +0 -181
  115. package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/user-story-template.md +0 -90
  116. package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/workflow.yaml +0 -58
  117. package/.bmad/bmm/workflows/3-solutioning/architecture/architecture-patterns.yaml +0 -321
  118. package/.bmad/bmm/workflows/3-solutioning/architecture/architecture-template.md +0 -103
  119. package/.bmad/bmm/workflows/3-solutioning/architecture/checklist.md +0 -240
  120. package/.bmad/bmm/workflows/3-solutioning/architecture/decision-catalog.yaml +0 -222
  121. package/.bmad/bmm/workflows/3-solutioning/architecture/instructions.md +0 -768
  122. package/.bmad/bmm/workflows/3-solutioning/architecture/pattern-categories.csv +0 -13
  123. package/.bmad/bmm/workflows/3-solutioning/architecture/workflow.yaml +0 -55
  124. package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/checklist.md +0 -169
  125. package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/instructions.md +0 -332
  126. package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/template.md +0 -146
  127. package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/workflow.yaml +0 -62
  128. package/.bmad/bmm/workflows/4-implementation/code-review/backlog_template.md +0 -12
  129. package/.bmad/bmm/workflows/4-implementation/code-review/checklist.md +0 -22
  130. package/.bmad/bmm/workflows/4-implementation/code-review/instructions.md +0 -398
  131. package/.bmad/bmm/workflows/4-implementation/code-review/workflow.yaml +0 -60
  132. package/.bmad/bmm/workflows/4-implementation/correct-course/checklist.md +0 -279
  133. package/.bmad/bmm/workflows/4-implementation/correct-course/instructions.md +0 -206
  134. package/.bmad/bmm/workflows/4-implementation/correct-course/workflow.yaml +0 -56
  135. package/.bmad/bmm/workflows/4-implementation/create-story/checklist.md +0 -240
  136. package/.bmad/bmm/workflows/4-implementation/create-story/instructions.md +0 -256
  137. package/.bmad/bmm/workflows/4-implementation/create-story/template.md +0 -51
  138. package/.bmad/bmm/workflows/4-implementation/create-story/workflow.yaml +0 -71
  139. package/.bmad/bmm/workflows/4-implementation/dev-story/checklist.md +0 -38
  140. package/.bmad/bmm/workflows/4-implementation/dev-story/instructions.md +0 -267
  141. package/.bmad/bmm/workflows/4-implementation/dev-story/workflow.yaml +0 -56
  142. package/.bmad/bmm/workflows/4-implementation/epic-tech-context/checklist.md +0 -17
  143. package/.bmad/bmm/workflows/4-implementation/epic-tech-context/instructions.md +0 -164
  144. package/.bmad/bmm/workflows/4-implementation/epic-tech-context/template.md +0 -76
  145. package/.bmad/bmm/workflows/4-implementation/epic-tech-context/workflow.yaml +0 -57
  146. package/.bmad/bmm/workflows/4-implementation/retrospective/instructions.md +0 -1443
  147. package/.bmad/bmm/workflows/4-implementation/retrospective/workflow.yaml +0 -56
  148. package/.bmad/bmm/workflows/4-implementation/sprint-planning/checklist.md +0 -33
  149. package/.bmad/bmm/workflows/4-implementation/sprint-planning/instructions.md +0 -234
  150. package/.bmad/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +0 -55
  151. package/.bmad/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +0 -49
  152. package/.bmad/bmm/workflows/4-implementation/story-context/checklist.md +0 -16
  153. package/.bmad/bmm/workflows/4-implementation/story-context/context-template.xml +0 -34
  154. package/.bmad/bmm/workflows/4-implementation/story-context/instructions.md +0 -209
  155. package/.bmad/bmm/workflows/4-implementation/story-context/workflow.yaml +0 -61
  156. package/.bmad/bmm/workflows/4-implementation/story-done/instructions.md +0 -111
  157. package/.bmad/bmm/workflows/4-implementation/story-done/workflow.yaml +0 -26
  158. package/.bmad/bmm/workflows/4-implementation/story-ready/instructions.md +0 -117
  159. package/.bmad/bmm/workflows/4-implementation/story-ready/workflow.yaml +0 -23
  160. package/.bmad/bmm/workflows/document-project/checklist.md +0 -245
  161. package/.bmad/bmm/workflows/document-project/documentation-requirements.csv +0 -12
  162. package/.bmad/bmm/workflows/document-project/instructions.md +0 -222
  163. package/.bmad/bmm/workflows/document-project/templates/deep-dive-template.md +0 -345
  164. package/.bmad/bmm/workflows/document-project/templates/index-template.md +0 -169
  165. package/.bmad/bmm/workflows/document-project/templates/project-overview-template.md +0 -103
  166. package/.bmad/bmm/workflows/document-project/templates/project-scan-report-schema.json +0 -160
  167. package/.bmad/bmm/workflows/document-project/templates/source-tree-template.md +0 -135
  168. package/.bmad/bmm/workflows/document-project/workflow.yaml +0 -29
  169. package/.bmad/bmm/workflows/document-project/workflows/deep-dive-instructions.md +0 -298
  170. package/.bmad/bmm/workflows/document-project/workflows/deep-dive.yaml +0 -31
  171. package/.bmad/bmm/workflows/document-project/workflows/full-scan-instructions.md +0 -1106
  172. package/.bmad/bmm/workflows/document-project/workflows/full-scan.yaml +0 -31
  173. package/.bmad/bmm/workflows/frame-expert/_shared/excalidraw-helpers.md +0 -127
  174. package/.bmad/bmm/workflows/frame-expert/_shared/excalidraw-library.json +0 -90
  175. package/.bmad/bmm/workflows/frame-expert/_shared/excalidraw-templates.yaml +0 -127
  176. package/.bmad/bmm/workflows/frame-expert/_shared/validate-json-instructions.md +0 -79
  177. package/.bmad/bmm/workflows/frame-expert/create-dataflow/checklist.md +0 -39
  178. package/.bmad/bmm/workflows/frame-expert/create-dataflow/instructions.md +0 -131
  179. package/.bmad/bmm/workflows/frame-expert/create-dataflow/workflow.yaml +0 -23
  180. package/.bmad/bmm/workflows/frame-expert/create-diagram/checklist.md +0 -43
  181. package/.bmad/bmm/workflows/frame-expert/create-diagram/instructions.md +0 -142
  182. package/.bmad/bmm/workflows/frame-expert/create-diagram/workflow.yaml +0 -24
  183. package/.bmad/bmm/workflows/frame-expert/create-flowchart/checklist.md +0 -49
  184. package/.bmad/bmm/workflows/frame-expert/create-flowchart/instructions.md +0 -242
  185. package/.bmad/bmm/workflows/frame-expert/create-flowchart/workflow.yaml +0 -27
  186. package/.bmad/bmm/workflows/frame-expert/create-wireframe/checklist.md +0 -38
  187. package/.bmad/bmm/workflows/frame-expert/create-wireframe/instructions.md +0 -133
  188. package/.bmad/bmm/workflows/frame-expert/create-wireframe/workflow.yaml +0 -23
  189. package/.bmad/bmm/workflows/techdoc/documentation-standards.md +0 -262
  190. package/.bmad/bmm/workflows/testarch/atdd/atdd-checklist-template.md +0 -363
  191. package/.bmad/bmm/workflows/testarch/atdd/checklist.md +0 -373
  192. package/.bmad/bmm/workflows/testarch/atdd/instructions.md +0 -785
  193. package/.bmad/bmm/workflows/testarch/atdd/workflow.yaml +0 -45
  194. package/.bmad/bmm/workflows/testarch/automate/checklist.md +0 -580
  195. package/.bmad/bmm/workflows/testarch/automate/instructions.md +0 -1303
  196. package/.bmad/bmm/workflows/testarch/automate/workflow.yaml +0 -52
  197. package/.bmad/bmm/workflows/testarch/ci/checklist.md +0 -246
  198. package/.bmad/bmm/workflows/testarch/ci/github-actions-template.yaml +0 -165
  199. package/.bmad/bmm/workflows/testarch/ci/gitlab-ci-template.yaml +0 -128
  200. package/.bmad/bmm/workflows/testarch/ci/instructions.md +0 -517
  201. package/.bmad/bmm/workflows/testarch/ci/workflow.yaml +0 -45
  202. package/.bmad/bmm/workflows/testarch/framework/checklist.md +0 -321
  203. package/.bmad/bmm/workflows/testarch/framework/instructions.md +0 -455
  204. package/.bmad/bmm/workflows/testarch/framework/workflow.yaml +0 -47
  205. package/.bmad/bmm/workflows/testarch/nfr-assess/checklist.md +0 -405
  206. package/.bmad/bmm/workflows/testarch/nfr-assess/instructions.md +0 -722
  207. package/.bmad/bmm/workflows/testarch/nfr-assess/nfr-report-template.md +0 -443
  208. package/.bmad/bmm/workflows/testarch/nfr-assess/workflow.yaml +0 -47
  209. package/.bmad/bmm/workflows/testarch/test-design/checklist.md +0 -234
  210. package/.bmad/bmm/workflows/testarch/test-design/instructions.md +0 -782
  211. package/.bmad/bmm/workflows/testarch/test-design/test-design-template.md +0 -285
  212. package/.bmad/bmm/workflows/testarch/test-design/workflow.yaml +0 -48
  213. package/.bmad/bmm/workflows/testarch/test-review/checklist.md +0 -470
  214. package/.bmad/bmm/workflows/testarch/test-review/instructions.md +0 -608
  215. package/.bmad/bmm/workflows/testarch/test-review/test-review-template.md +0 -388
  216. package/.bmad/bmm/workflows/testarch/test-review/workflow.yaml +0 -46
  217. package/.bmad/bmm/workflows/testarch/trace/checklist.md +0 -654
  218. package/.bmad/bmm/workflows/testarch/trace/instructions.md +0 -1045
  219. package/.bmad/bmm/workflows/testarch/trace/trace-template.md +0 -673
  220. package/.bmad/bmm/workflows/testarch/trace/workflow.yaml +0 -55
  221. package/.bmad/bmm/workflows/workflow-status/init/instructions.md +0 -334
  222. package/.bmad/bmm/workflows/workflow-status/init/workflow.yaml +0 -28
  223. package/.bmad/bmm/workflows/workflow-status/instructions.md +0 -388
  224. package/.bmad/bmm/workflows/workflow-status/paths/enterprise-brownfield.yaml +0 -138
  225. package/.bmad/bmm/workflows/workflow-status/paths/enterprise-greenfield.yaml +0 -126
  226. package/.bmad/bmm/workflows/workflow-status/paths/game-design.yaml +0 -52
  227. package/.bmad/bmm/workflows/workflow-status/paths/method-brownfield.yaml +0 -122
  228. package/.bmad/bmm/workflows/workflow-status/paths/method-greenfield.yaml +0 -113
  229. package/.bmad/bmm/workflows/workflow-status/paths/quick-flow-brownfield.yaml +0 -58
  230. package/.bmad/bmm/workflows/workflow-status/paths/quick-flow-greenfield.yaml +0 -47
  231. package/.bmad/bmm/workflows/workflow-status/project-levels.yaml +0 -59
  232. package/.bmad/bmm/workflows/workflow-status/workflow-status-template.yaml +0 -24
  233. package/.bmad/bmm/workflows/workflow-status/workflow.yaml +0 -28
  234. package/.bmad/core/agents/bmad-master.md +0 -72
  235. package/.bmad/core/agents/bmad-web-orchestrator.agent.xml +0 -113
  236. package/.bmad/core/config.yaml +0 -11
  237. package/.bmad/core/tasks/adv-elicit-methods.csv +0 -39
  238. package/.bmad/core/tasks/advanced-elicitation-methods.csv +0 -21
  239. package/.bmad/core/tasks/advanced-elicitation.xml +0 -106
  240. package/.bmad/core/tasks/index-docs.xml +0 -65
  241. package/.bmad/core/tasks/validate-workflow.xml +0 -89
  242. package/.bmad/core/tasks/workflow.xml +0 -270
  243. package/.bmad/core/tools/shard-doc.xml +0 -109
  244. package/.bmad/core/workflows/brainstorming/README.md +0 -261
  245. package/.bmad/core/workflows/brainstorming/brain-methods.csv +0 -36
  246. package/.bmad/core/workflows/brainstorming/instructions.md +0 -315
  247. package/.bmad/core/workflows/brainstorming/template.md +0 -106
  248. package/.bmad/core/workflows/brainstorming/workflow.yaml +0 -38
  249. package/.bmad/core/workflows/party-mode/instructions.md +0 -203
  250. package/.bmad/core/workflows/party-mode/workflow.yaml +0 -28
  251. package/.bmad/docs/claude-code-instructions.md +0 -25
  252. package/.claude/commands/BMad/analyst.md +0 -88
  253. package/.claude/commands/BMad/architect.md +0 -89
  254. package/.claude/commands/BMad/bmad-master.md +0 -114
  255. package/.claude/commands/BMad/bmad-orchestrator.md +0 -151
  256. package/.claude/commands/BMad/dev.md +0 -85
  257. package/.claude/commands/BMad/pm.md +0 -88
  258. package/.claude/commands/BMad/po.md +0 -83
  259. package/.claude/commands/BMad/qa.md +0 -91
  260. package/.claude/commands/BMad/sm.md +0 -69
  261. package/.claude/commands/BMad/tasks/advanced-elicitation.md +0 -123
  262. package/.claude/commands/BMad/tasks/apply-qa-fixes.md +0 -154
  263. package/.claude/commands/BMad/tasks/brownfield-create-epic.md +0 -166
  264. package/.claude/commands/BMad/tasks/brownfield-create-story.md +0 -153
  265. package/.claude/commands/BMad/tasks/correct-course.md +0 -76
  266. package/.claude/commands/BMad/tasks/create-brownfield-story.md +0 -318
  267. package/.claude/commands/BMad/tasks/create-deep-research-prompt.md +0 -284
  268. package/.claude/commands/BMad/tasks/create-doc.md +0 -107
  269. package/.claude/commands/BMad/tasks/create-next-story.md +0 -118
  270. package/.claude/commands/BMad/tasks/document-project.md +0 -349
  271. package/.claude/commands/BMad/tasks/execute-checklist.md +0 -92
  272. package/.claude/commands/BMad/tasks/facilitate-brainstorming-session.md +0 -142
  273. package/.claude/commands/BMad/tasks/generate-ai-frontend-prompt.md +0 -57
  274. package/.claude/commands/BMad/tasks/index-docs.md +0 -179
  275. package/.claude/commands/BMad/tasks/kb-mode-interaction.md +0 -81
  276. package/.claude/commands/BMad/tasks/nfr-assess.md +0 -349
  277. package/.claude/commands/BMad/tasks/qa-gate.md +0 -167
  278. package/.claude/commands/BMad/tasks/review-story.md +0 -320
  279. package/.claude/commands/BMad/tasks/risk-profile.md +0 -359
  280. package/.claude/commands/BMad/tasks/shard-doc.md +0 -191
  281. package/.claude/commands/BMad/tasks/test-design.md +0 -180
  282. package/.claude/commands/BMad/tasks/trace-requirements.md +0 -270
  283. package/.claude/commands/BMad/tasks/validate-next-story.md +0 -140
  284. package/.claude/commands/BMad/ux-expert.md +0 -73
  285. package/.claude/commands/bmad/bmm/agents/analyst.md +0 -14
  286. package/.claude/commands/bmad/bmm/agents/architect.md +0 -14
  287. package/.claude/commands/bmad/bmm/agents/dev.md +0 -14
  288. package/.claude/commands/bmad/bmm/agents/frame-expert.md +0 -14
  289. package/.claude/commands/bmad/bmm/agents/pm.md +0 -14
  290. package/.claude/commands/bmad/bmm/agents/sm.md +0 -14
  291. package/.claude/commands/bmad/bmm/agents/tea.md +0 -14
  292. package/.claude/commands/bmad/bmm/agents/tech-writer.md +0 -14
  293. package/.claude/commands/bmad/bmm/agents/ux-designer.md +0 -14
  294. package/.claude/commands/bmad/bmm/workflows/architecture.md +0 -13
  295. package/.claude/commands/bmad/bmm/workflows/brainstorm-project.md +0 -13
  296. package/.claude/commands/bmad/bmm/workflows/code-review.md +0 -13
  297. package/.claude/commands/bmad/bmm/workflows/correct-course.md +0 -13
  298. package/.claude/commands/bmad/bmm/workflows/create-dataflow.md +0 -13
  299. package/.claude/commands/bmad/bmm/workflows/create-diagram.md +0 -13
  300. package/.claude/commands/bmad/bmm/workflows/create-epics-and-stories.md +0 -13
  301. package/.claude/commands/bmad/bmm/workflows/create-flowchart.md +0 -13
  302. package/.claude/commands/bmad/bmm/workflows/create-story.md +0 -13
  303. package/.claude/commands/bmad/bmm/workflows/create-ux-design.md +0 -13
  304. package/.claude/commands/bmad/bmm/workflows/create-wireframe.md +0 -13
  305. package/.claude/commands/bmad/bmm/workflows/dev-story.md +0 -13
  306. package/.claude/commands/bmad/bmm/workflows/document-project.md +0 -13
  307. package/.claude/commands/bmad/bmm/workflows/domain-research.md +0 -13
  308. package/.claude/commands/bmad/bmm/workflows/epic-tech-context.md +0 -13
  309. package/.claude/commands/bmad/bmm/workflows/implementation-readiness.md +0 -13
  310. package/.claude/commands/bmad/bmm/workflows/prd.md +0 -13
  311. package/.claude/commands/bmad/bmm/workflows/product-brief.md +0 -13
  312. package/.claude/commands/bmad/bmm/workflows/research.md +0 -13
  313. package/.claude/commands/bmad/bmm/workflows/retrospective.md +0 -13
  314. package/.claude/commands/bmad/bmm/workflows/sprint-planning.md +0 -13
  315. package/.claude/commands/bmad/bmm/workflows/story-context.md +0 -13
  316. package/.claude/commands/bmad/bmm/workflows/story-done.md +0 -13
  317. package/.claude/commands/bmad/bmm/workflows/story-ready.md +0 -13
  318. package/.claude/commands/bmad/bmm/workflows/tech-spec.md +0 -13
  319. package/.claude/commands/bmad/bmm/workflows/workflow-init.md +0 -13
  320. package/.claude/commands/bmad/bmm/workflows/workflow-status.md +0 -13
  321. package/.claude/commands/bmad/core/agents/bmad-master.md +0 -14
  322. package/.claude/commands/bmad/core/tasks/advanced-elicitation.md +0 -9
  323. package/.claude/commands/bmad/core/tasks/index-docs.md +0 -9
  324. package/.claude/commands/bmad/core/tools/shard-doc.md +0 -9
  325. package/.claude/commands/bmad/core/workflows/brainstorming.md +0 -13
  326. package/.claude/commands/bmad/core/workflows/party-mode.md +0 -13
  327. package/.claude/github-star-reminder.txt +0 -1
  328. package/.claude/hooks/bmad-party-manager.sh +0 -225
  329. package/.claude/hooks/stop.sh +0 -221
  330. package/.claude/piper-voices-dir.txt +0 -1
  331. package/.mcp.json +0 -88
  332. package/RELEASE_NOTES_v2.4.0_DRAFT.md +0 -116
  333. package/RELEASE_NOTES_v2.4.1_DRAFT.md +0 -61
  334. package/docs/2025-11-15_15-14-33.snagx +0 -0
  335. package/docs/Screenshot 2025-11-15 151325.png +0 -0
  336. package/docs/Screenshot 2025-11-15 151432.png +0 -0
  337. package/docs/macos-piper-issue.md +0 -172
  338. package/docs/stargazer-cms-prd.md +0 -1918
  339. package/docs/whatsapp-plugin-github-issue.md +0 -393
  340. package/docs/whatsapp-tts-plugin-feasibility.md +0 -418
  341. package/docs/whatsapp-tts-standalone-plugin.md +0 -628
  342. package/github-profile-draft.md +0 -57
  343. package/linkedin/vibe-coding-and-pulseaudio.md +0 -121
  344. package/mcp-server/agentvibes.db +0 -0
  345. package/scripts/audio-tunnel.config +0 -17
  346. package/v4-backup/.bmad-core/agent-teams/team-all.yaml +0 -15
  347. package/v4-backup/.bmad-core/agent-teams/team-fullstack.yaml +0 -19
  348. package/v4-backup/.bmad-core/agent-teams/team-ide-minimal.yaml +0 -11
  349. package/v4-backup/.bmad-core/agent-teams/team-no-ui.yaml +0 -14
  350. package/v4-backup/.bmad-core/agents/analyst.md +0 -84
  351. package/v4-backup/.bmad-core/agents/architect.md +0 -85
  352. package/v4-backup/.bmad-core/agents/bmad-master.md +0 -110
  353. package/v4-backup/.bmad-core/agents/bmad-orchestrator.md +0 -147
  354. package/v4-backup/.bmad-core/agents/dev.md +0 -81
  355. package/v4-backup/.bmad-core/agents/pm.md +0 -84
  356. package/v4-backup/.bmad-core/agents/po.md +0 -79
  357. package/v4-backup/.bmad-core/agents/qa.md +0 -87
  358. package/v4-backup/.bmad-core/agents/sm.md +0 -65
  359. package/v4-backup/.bmad-core/agents/ux-expert.md +0 -69
  360. package/v4-backup/.bmad-core/checklists/architect-checklist.md +0 -440
  361. package/v4-backup/.bmad-core/checklists/change-checklist.md +0 -184
  362. package/v4-backup/.bmad-core/checklists/pm-checklist.md +0 -372
  363. package/v4-backup/.bmad-core/checklists/po-master-checklist.md +0 -434
  364. package/v4-backup/.bmad-core/checklists/story-dod-checklist.md +0 -96
  365. package/v4-backup/.bmad-core/checklists/story-draft-checklist.md +0 -155
  366. package/v4-backup/.bmad-core/core-config.yaml +0 -22
  367. package/v4-backup/.bmad-core/data/bmad-kb.md +0 -809
  368. package/v4-backup/.bmad-core/data/brainstorming-techniques.md +0 -38
  369. package/v4-backup/.bmad-core/data/elicitation-methods.md +0 -156
  370. package/v4-backup/.bmad-core/data/technical-preferences.md +0 -5
  371. package/v4-backup/.bmad-core/data/test-levels-framework.md +0 -148
  372. package/v4-backup/.bmad-core/data/test-priorities-matrix.md +0 -174
  373. package/v4-backup/.bmad-core/enhanced-ide-development-workflow.md +0 -248
  374. package/v4-backup/.bmad-core/install-manifest.yaml +0 -230
  375. package/v4-backup/.bmad-core/tasks/advanced-elicitation.md +0 -119
  376. package/v4-backup/.bmad-core/tasks/apply-qa-fixes.md +0 -150
  377. package/v4-backup/.bmad-core/tasks/brownfield-create-epic.md +0 -162
  378. package/v4-backup/.bmad-core/tasks/brownfield-create-story.md +0 -149
  379. package/v4-backup/.bmad-core/tasks/correct-course.md +0 -72
  380. package/v4-backup/.bmad-core/tasks/create-brownfield-story.md +0 -314
  381. package/v4-backup/.bmad-core/tasks/create-deep-research-prompt.md +0 -280
  382. package/v4-backup/.bmad-core/tasks/create-doc.md +0 -103
  383. package/v4-backup/.bmad-core/tasks/create-next-story.md +0 -114
  384. package/v4-backup/.bmad-core/tasks/document-project.md +0 -345
  385. package/v4-backup/.bmad-core/tasks/execute-checklist.md +0 -88
  386. package/v4-backup/.bmad-core/tasks/facilitate-brainstorming-session.md +0 -138
  387. package/v4-backup/.bmad-core/tasks/generate-ai-frontend-prompt.md +0 -53
  388. package/v4-backup/.bmad-core/tasks/index-docs.md +0 -175
  389. package/v4-backup/.bmad-core/tasks/kb-mode-interaction.md +0 -77
  390. package/v4-backup/.bmad-core/tasks/nfr-assess.md +0 -345
  391. package/v4-backup/.bmad-core/tasks/qa-gate.md +0 -163
  392. package/v4-backup/.bmad-core/tasks/review-story.md +0 -316
  393. package/v4-backup/.bmad-core/tasks/risk-profile.md +0 -355
  394. package/v4-backup/.bmad-core/tasks/shard-doc.md +0 -187
  395. package/v4-backup/.bmad-core/tasks/test-design.md +0 -176
  396. package/v4-backup/.bmad-core/tasks/trace-requirements.md +0 -266
  397. package/v4-backup/.bmad-core/tasks/validate-next-story.md +0 -136
  398. package/v4-backup/.bmad-core/templates/architecture-tmpl.yaml +0 -651
  399. package/v4-backup/.bmad-core/templates/brainstorming-output-tmpl.yaml +0 -156
  400. package/v4-backup/.bmad-core/templates/brownfield-architecture-tmpl.yaml +0 -477
  401. package/v4-backup/.bmad-core/templates/brownfield-prd-tmpl.yaml +0 -281
  402. package/v4-backup/.bmad-core/templates/competitor-analysis-tmpl.yaml +0 -307
  403. package/v4-backup/.bmad-core/templates/front-end-architecture-tmpl.yaml +0 -219
  404. package/v4-backup/.bmad-core/templates/front-end-spec-tmpl.yaml +0 -350
  405. package/v4-backup/.bmad-core/templates/fullstack-architecture-tmpl.yaml +0 -824
  406. package/v4-backup/.bmad-core/templates/market-research-tmpl.yaml +0 -253
  407. package/v4-backup/.bmad-core/templates/prd-tmpl.yaml +0 -203
  408. package/v4-backup/.bmad-core/templates/project-brief-tmpl.yaml +0 -222
  409. package/v4-backup/.bmad-core/templates/qa-gate-tmpl.yaml +0 -103
  410. package/v4-backup/.bmad-core/templates/story-tmpl.yaml +0 -138
  411. package/v4-backup/.bmad-core/user-guide.md +0 -577
  412. package/v4-backup/.bmad-core/utils/bmad-doc-template.md +0 -327
  413. package/v4-backup/.bmad-core/utils/workflow-management.md +0 -71
  414. package/v4-backup/.bmad-core/workflows/brownfield-fullstack.yaml +0 -298
  415. package/v4-backup/.bmad-core/workflows/brownfield-service.yaml +0 -188
  416. package/v4-backup/.bmad-core/workflows/brownfield-ui.yaml +0 -198
  417. package/v4-backup/.bmad-core/workflows/greenfield-fullstack.yaml +0 -241
  418. package/v4-backup/.bmad-core/workflows/greenfield-service.yaml +0 -207
  419. package/v4-backup/.bmad-core/workflows/greenfield-ui.yaml +0 -236
  420. package/v4-backup/.bmad-core/working-in-the-brownfield.md +0 -606
@@ -1,1918 +0,0 @@
1
- # AgentVibes Stargazer CMS - Product Requirements Document (PRD)
2
-
3
- **Version**: 1.1
4
- **Project**: AgentVibes Stargazer Content Management System
5
- **Repository**: agentvibes-stargazers (Private)
6
- **Created**: 2025-01-10
7
- **Author**: John (PM Agent) with Paul Preibisch
8
-
9
- ---
10
-
11
- ## Goals and Background Context
12
-
13
- ### Goals
14
-
15
- - Enable efficient outreach to GitHub stargazers with personalized thank-you emails and feedback requests
16
- - Track all stargazer interactions, contact status, and engagement history in a centralized system
17
- - Automate GitHub stargazer synchronization with manual, scheduled (daily cron), and real-time webhook options
18
- - Provide geographic visualization of stargazer distribution for analytics insights
19
- - Maintain clean, modular, AI-optimized codebase following strict single-responsibility principles with SonarQube quality gates
20
- - Support local PostgreSQL deployment with automated daily backups and Docker-based infrastructure
21
- - Integrate SpaceMail API for semi-automated email workflows with approval-based sending and scheduled follow-ups
22
- - Enable optional PiperTTS notifications for real-time stargazer events (plugin-based, toggleable with quiet hours)
23
-
24
- ### Background Context
25
-
26
- The AgentVibes project has attracted GitHub stargazers, representing potential users, contributors, and community members. Currently, there's no systematic way to thank these supporters or gather valuable feedback from them.
27
-
28
- This PRD defines a comprehensive Stargazer Content Management System (CMS) that will:
29
-
30
- 1. **Solve the outreach problem**: Provide a professional interface to manage stargazer relationships, compose personalized emails, and track engagement
31
- 2. **Prevent spam issues**: Implement SpaceMail API integration with proper authentication (SPF, DKIM, DMARC), rate limiting (max 10/hour), and approval workflows
32
- 3. **Maintain code quality**: Enforce strict AI-optimized documentation standards from `/home/fire/claude/AgentVibes/docs/ai-optimized-documentation-standards.md`, single-responsibility principles, and automated SonarQube quality gates
33
- 4. **Enable data-driven decisions**: Offer geographic visualization (integrated Track-Stargazers map) and analytics to understand community distribution
34
-
35
- The system will be deployed locally using Docker Compose with management scripts matching the SoraSage pattern (`up`, `down`, `restart`, `health`, `logs`), with a separate private GitHub repository (`agentvibes-stargazers`) to protect sensitive stargazer data and email credentials.
36
-
37
- ### Change Log
38
-
39
- | Date | Version | Description | Author |
40
- |------|---------|-------------|--------|
41
- | 2025-01-10 | 1.0 | Initial PRD creation | John (PM Agent) |
42
- | 2025-01-10 | 1.1 | Updated to use Kysely instead of Prisma | John (PM Agent) |
43
-
44
- ---
45
-
46
- ## Requirements
47
-
48
- ### Functional Requirements
49
-
50
- **FR1**: System shall fetch stargazer data from GitHub API using Octokit, including username, email (if public), name, avatar URL, bio, company, location, and starred timestamp
51
-
52
- **FR2**: System shall display stargazers in a TanStack Table with columns: username, email, starred date, contact status, last contacted date, and action buttons
53
-
54
- **FR3**: System shall allow filtering stargazers by contact status (contacted/not contacted), date range, location/country, and text search
55
-
56
- **FR4**: System shall provide individual stargazer profile view showing: GitHub username, name, email, avatar, bio, company, location, country, starred timestamp, contact history, and notes
57
-
58
- **FR5**: System shall support CRUD operations for email templates with template name, subject, body, and variable placeholders ({{name}}, {{username}}, {{repo}})
59
-
60
- **FR6**: System shall compose draft emails using selected template with variable substitution for specific stargazers
61
-
62
- **FR7**: System shall integrate SpaceMail API to send emails with semi-automated workflow requiring user approval before sending
63
-
64
- **FR8**: System shall support scheduling follow-up emails based on engagement status (no reply after X days)
65
-
66
- **FR9**: System shall open default email client with pre-filled template via `mailto:` links as fallback option
67
-
68
- **FR10**: System shall track email send history including: template used, sent timestamp, approval timestamp, status (draft/pending_approval/sent/failed)
69
-
70
- **FR11**: System shall synchronize GitHub stargazers via three methods: manual trigger (UI button), scheduled cron job (daily at 9am), and GitHub webhook (real-time)
71
-
72
- **FR12**: System shall display geographic map visualization of stargazers using integrated Track-Stargazers library (tab in UI)
73
-
74
- **FR13**: System shall perform automated database backups daily at 2am with 7-day retention policy
75
-
76
- **FR14**: System shall provide Docker management scripts: `up` (start), `down` (stop), `restart` (restart services), `health` (check service status), `logs` (view colored logs)
77
-
78
- **FR15**: System shall optionally trigger PiperTTS notifications when new stargazers are detected (configurable with quiet hours 22:00-08:00)
79
-
80
- **FR16**: System shall log all sync operations (manual/cron/webhook) with sync type, status, new stargazer count, and errors
81
-
82
- **FR17**: System shall prevent duplicate stargazers using GitHub ID as unique identifier
83
-
84
- **FR18**: System shall allow bulk selection of stargazers for batch email operations
85
-
86
- **FR19**: System shall provide sidebar navigation with sections: Stargazers (table view), Templates (CRUD), Map (visualization), Settings
87
-
88
- **FR20**: System shall use Chakra UI v2 for consistent, accessible component styling throughout the application
89
-
90
- ### Non-Functional Requirements
91
-
92
- **NFR1**: All code shall follow AI-optimized documentation standards defined in `/home/fire/claude/AgentVibes/docs/ai-optimized-documentation-standards.md` including file-level context headers, comprehensive function documentation, AI notes, and cross-reference maps
93
-
94
- **NFR2**: All source files shall be max 200 lines; functions shall be max 50 lines to enforce single-responsibility principle
95
-
96
- **NFR3**: No monolithic files permitted; all code shall be componentized with clear separation of concerns
97
-
98
- **NFR4**: All code shall pass SonarQube quality gates: Code Coverage ≥70%, Duplicated Lines ≤3%, Maintainability Rating A, Cognitive Complexity ≤15 per function, Cyclomatic Complexity ≤10 per function
99
-
100
- **NFR5**: Frontend shall use Vite + React (NOT Next.js) for fast dev server and instant HMR
101
-
102
- **NFR6**: Backend shall use Node.js/Express with TypeScript in strict mode for type safety
103
-
104
- **NFR7**: Database shall use PostgreSQL 16 with Kysely query builder for type-safe database access and manual migration control
105
-
106
- **NFR8**: All services shall run in Docker containers orchestrated by Docker Compose
107
-
108
- **NFR9**: Email sending shall implement anti-spam measures: SPF/DKIM/DMARC authentication, rate limiting (max 10 emails/hour), personalized content, unsubscribe links, gradual warmup
109
-
110
- **NFR10**: System shall store sensitive data (API keys, email credentials) in environment variables, never committed to version control
111
-
112
- **NFR11**: Application shall render quickly with optimal performance (Vite chosen over Next.js for faster load times)
113
-
114
- **NFR12**: All Docker health checks shall complete within 10 seconds with 5 retries
115
-
116
- **NFR13**: Database backups shall complete within 60 seconds and verify successful creation
117
-
118
- **NFR14**: Pre-commit hooks shall run ESLint, TypeScript type-check, SonarQube scan, and unit tests before allowing commits
119
-
120
- **NFR15**: System shall handle GitHub API rate limiting gracefully with exponential backoff and user notifications
121
-
122
- ---
123
-
124
- ## User Interface Design Goals
125
-
126
- ### Overall UX Vision
127
-
128
- Clean, efficient content management interface focused on rapid stargazer outreach workflow. Primary user journey: View stargazers → Select individuals → Compose personalized email → Approve and send → Track engagement. Secondary analytics view provides geographic insights via interactive map.
129
-
130
- ### Key Interaction Paradigms
131
-
132
- - **Table-centric workflow**: TanStack Table as primary interaction surface with inline actions, sorting, filtering, and bulk selection
133
- - **Approval-based email flow**: Draft → Preview → Approve → Send (semi-automated, prevents accidental sends)
134
- - **Template-driven composition**: Reusable templates with variable substitution reduce repetitive writing
135
- - **Real-time sync feedback**: Toast notifications and progress indicators for GitHub sync operations
136
-
137
- ### Core Screens and Views
138
-
139
- 1. **Stargazers Table** (Main Screen)
140
- - TanStack Table with columns: Avatar, Username, Email, Starred Date, Contact Status, Actions
141
- - Filters: Contact status, date range, location, text search
142
- - Bulk actions: Select multiple → Compose email
143
- - Inline actions: View profile, Send email, Add notes
144
-
145
- 2. **Stargazer Profile Modal**
146
- - Left panel: Avatar, GitHub link, bio, company, location
147
- - Right panel: Contact history timeline, notes textarea
148
- - Actions: Send email, Edit notes, View on GitHub
149
-
150
- 3. **Email Templates Screen**
151
- - Template list (sidebar): Name, subject preview, last used date
152
- - Template editor: Name, subject, body textarea with variable hints
153
- - Preview mode: Render template with sample data
154
- - CRUD operations: Create, Edit, Delete, Duplicate
155
-
156
- 4. **Email Composer Modal**
157
- - Template selector dropdown
158
- - Rendered email preview with substituted variables
159
- - Recipient list (for bulk sends)
160
- - Schedule options: Send now, Schedule for later
161
- - Approval button (sends to SpaceMail API)
162
-
163
- 5. **Geographic Map Tab**
164
- - Integrated Track-Stargazers interactive world map
165
- - Stargazer distribution by country
166
- - Hover tooltips with country names and counts
167
- - Filter map by contact status
168
-
169
- 6. **Settings Screen**
170
- - GitHub sync configuration: Auto-sync enabled, webhook URL
171
- - SpaceMail API credentials
172
- - PiperTTS settings: Enabled, quiet hours
173
- - Backup schedule configuration
174
-
175
- ### Accessibility
176
-
177
- WCAG AA compliance required:
178
- - Keyboard navigation for all interactive elements
179
- - ARIA labels for screen readers
180
- - Sufficient color contrast ratios (Chakra UI default theme compliant)
181
- - Focus indicators on all focusable elements
182
-
183
- ### Branding
184
-
185
- Minimal, professional aesthetic matching AgentVibes brand:
186
- - Color palette: Chakra UI default with AgentVibes accent colors
187
- - Typography: Clean sans-serif (Chakra UI system fonts)
188
- - Iconography: Consistent icon set (React Icons library)
189
- - No animated effects except loading spinners and toast notifications
190
-
191
- ### Target Device and Platforms
192
-
193
- Web Responsive (desktop-first design):
194
- - Primary: Desktop browsers (Chrome, Firefox, Safari) at 1920x1080
195
- - Secondary: Laptop browsers at 1366x768
196
- - Minimal support for tablets (iPad landscape)
197
- - Not optimized for mobile phones (local deployment, desktop usage expected)
198
-
199
- ---
200
-
201
- ## Technical Assumptions
202
-
203
- ### Repository Structure
204
-
205
- **Monorepo** with clear separation:
206
- ```
207
- agentvibes-stargazers/
208
- ├── frontend/ # Vite + React
209
- ├── backend/ # Express + TypeScript
210
- ├── docker-compose.yml
211
- ├── up, down, restart, health, logs (scripts)
212
- └── scripts/ # Helper scripts
213
- ```
214
-
215
- ### Service Architecture
216
-
217
- **Monolith with modular structure**:
218
- - Single backend API server (Express.js)
219
- - Single frontend SPA (Vite + React)
220
- - PostgreSQL database (single instance)
221
- - Optional: SonarQube container for CI/CD integration
222
-
223
- Not microservices - system is small enough that monolith with clean modules is simpler and more maintainable.
224
-
225
- ### Testing Requirements
226
-
227
- **Comprehensive testing pyramid**:
228
- - **Unit tests**: All services, utilities, helpers (70% coverage minimum)
229
- - **Integration tests**: API endpoints, database operations
230
- - **E2E tests**: Critical user journeys (stargazer sync, email sending)
231
- - **Manual testing convenience**: Seeded test data, mock SpaceMail responses
232
-
233
- **Testing tools**:
234
- - Backend: Jest + Supertest
235
- - Frontend: Vitest + React Testing Library
236
- - E2E: Playwright
237
-
238
- ### Additional Technical Assumptions
239
-
240
- **Tech Stack**:
241
-
242
- *Frontend*:
243
- - Vite 5 (build tool - chosen for fast HMR over Next.js)
244
- - React 18 (UI framework)
245
- - Chakra UI v2 (component library)
246
- - TanStack Table v8 (data tables)
247
- - TanStack Query (data fetching/caching)
248
- - React Router v6 (routing)
249
- - Zustand (lightweight state management)
250
- - Axios (HTTP client)
251
-
252
- *Backend*:
253
- - Node.js 18 (runtime)
254
- - Express.js (API framework)
255
- - TypeScript (strict mode)
256
- - Kysely (type-safe SQL query builder)
257
- - pg (PostgreSQL driver)
258
- - kysely-ctl (migration runner)
259
- - Octokit (@octokit/rest) (GitHub API client)
260
- - node-cron (scheduled jobs)
261
- - Nodemailer or SpaceMail SDK (email sending)
262
-
263
- *Database*:
264
- - PostgreSQL 16 Alpine (relational database)
265
- - Kysely migrations (raw SQL, type-safe)
266
-
267
- *Infrastructure*:
268
- - Docker + Docker Compose (containerization)
269
- - SonarQube Community (code quality)
270
- - GitHub Actions (CI/CD, optional)
271
-
272
- **GitHub Sync Strategy**:
273
- - Rewrite Track-Stargazers Python logic in Node.js/TypeScript for consistency
274
- - Use @octokit/rest for all GitHub API interactions
275
- - Implement pagination for repos with >100 stargazers
276
- - Cache user location → country mapping (reduce geocoding API calls)
277
-
278
- **Map Integration Strategy**:
279
- - Integrate Track-Stargazers' Datamaps + D3.js visualization as React component
280
- - Alternative: Use modern React map library (react-simple-maps) if easier integration
281
- - Map data: JSON export from database (country codes + stargazer counts)
282
-
283
- **SpaceMail Integration**:
284
- - Use SpaceMail REST API (not SMTP) for better tracking and deliverability
285
- - Implement rate limiting: max 10 emails/hour, exponential backoff on errors
286
- - Store email send status: draft, pending_approval, sent, failed
287
- - Track bounces and remove invalid emails automatically
288
-
289
- **PiperTTS Plugin Architecture**:
290
- - Notification service checks `ENABLE_TTS` env var
291
- - Calls `/home/fire/claude/AgentVibes/.claude/hooks/play-tts.sh` for TTS
292
- - Respects `TTS_QUIET_HOURS` env var (default: 22:00-08:00)
293
- - Gracefully degrades if TTS fails (logs error, continues operation)
294
-
295
- **Docker Management Scripts** (matching SoraSage pattern):
296
-
297
- Scripts follow exact pattern from `/home/fire/claude/SoraSage/`:
298
-
299
- 1. **`./up`** (Main startup orchestrator):
300
- - Load environment from `.env`
301
- - Display color-coded startup phases
302
- - Build/start Docker containers with smart rebuild detection
303
- - Run Prisma migrations
304
- - Perform service health checks
305
- - Display service URLs and credentials
306
-
307
- 2. **`./down`** (Clean shutdown):
308
- - Stop all Docker Compose services
309
- - Kill background processes (cron jobs, monitors)
310
- - Clean PID files
311
-
312
- 3. **`./restart`** (Restart specific service):
313
- - Restart Docker container
314
- - Wait for health check
315
- - Curl health endpoint to verify
316
-
317
- 4. **`./health`** (Comprehensive health checker):
318
- - Check each service (frontend, backend, postgres)
319
- - Display HOST:PORT → INTERNAL:PORT mappings
320
- - Color-coded status (green=up, red=down, yellow=warning)
321
- - Service-specific checks (pg_isready, curl /health)
322
- - Show restart commands for failed services
323
- - Summary: X/Y services running
324
-
325
- 5. **`./logs`** (Beautiful log viewer):
326
- - Color-code by log level (ERROR=red, WARN=yellow, INFO=blue)
327
- - Show last 10 lines per service
328
- - Support service filters (`./logs backend`)
329
- - Support follow mode (`./logs -f backend`)
330
-
331
- **Code Quality Standards**:
332
-
333
- All code MUST follow `/home/fire/claude/AgentVibes/docs/ai-optimized-documentation-standards.md`:
334
-
335
- - File-level context headers with 7 fields (@fileoverview, @context, @architecture, @dependencies, @entrypoints, @patterns, @related)
336
- - Function documentation with 9 fields (@function, @intent, @why, @param, @returns, @exitcode, @sideeffects, @edgecases, @calledby, @calls)
337
- - AI NOTE comments for non-obvious logic
338
- - Architecture Decision Records (ADRs) for critical design choices
339
- - Cross-reference maps for complex modules
340
- - Pattern examples for extensibility
341
-
342
- **SonarQube Integration**:
343
- - Pre-commit hook runs `npm run sonar` before allowing commits
344
- - Quality gates block commits if:
345
- - Code coverage <70%
346
- - Duplicated lines >3%
347
- - Maintainability rating <A
348
- - Cognitive complexity >15 per function
349
- - File length >200 lines
350
- - Function length >50 lines
351
-
352
- **Component Structure Examples**:
353
-
354
- ```typescript
355
- // frontend/src/components/stargazers/StargazerTable.tsx (max 150 lines)
356
- // frontend/src/components/stargazers/StargazerRow.tsx (max 100 lines)
357
- // frontend/src/components/stargazers/StargazerFilters.tsx (max 100 lines)
358
- // frontend/src/components/email/EmailComposer.tsx (max 150 lines)
359
- // frontend/src/hooks/useStargazers.ts (max 100 lines)
360
- // frontend/src/services/github.service.ts (max 200 lines)
361
- ```
362
-
363
- **Database Schema** (Kysely with TypeScript types):
364
-
365
- ```typescript
366
- // backend/src/db/types.ts - Generated from SQL schema
367
- export interface Database {
368
- stargazer: StargazerTable
369
- email_template: EmailTemplateTable
370
- email: EmailTable
371
- sync_log: SyncLogTable
372
- }
373
-
374
- export interface StargazerTable {
375
- id: Generated<string> // UUID, auto-generated
376
- github_id: number // Unique
377
- username: string // Unique
378
- email: string | null
379
- name: string | null
380
- avatar_url: string | null
381
- bio: string | null
382
- company: string | null
383
- location: string | null
384
- country: string | null // ISO country code
385
- starred_at: Date
386
- contacted: Generated<boolean> // Default false
387
- contacted_at: Date | null
388
- last_email_sent: Date | null
389
- response_status: string | null // none, pending, replied
390
- notes: string | null
391
- created_at: Generated<Date>
392
- updated_at: Generated<Date>
393
- }
394
-
395
- export interface EmailTemplateTable {
396
- id: Generated<string>
397
- name: string // Unique
398
- subject: string
399
- body: string
400
- variables: string | null // JSON string
401
- created_at: Generated<Date>
402
- updated_at: Generated<Date>
403
- }
404
-
405
- export interface EmailTable {
406
- id: Generated<string>
407
- stargazer_id: string // FK to stargazer
408
- template_id: string
409
- template_name: string
410
- subject: string
411
- body: string
412
- status: string // draft, pending_approval, sent, failed
413
- scheduled_for: Date | null
414
- sent_at: Date | null
415
- approved_by: string | null
416
- approved_at: Date | null
417
- error_message: string | null
418
- created_at: Generated<Date>
419
- }
420
-
421
- export interface SyncLogTable {
422
- id: Generated<string>
423
- sync_type: string // manual, cron, webhook
424
- status: string // success, failed, partial
425
- new_stargazers: Generated<number> // Default 0
426
- total_fetched: Generated<number> // Default 0
427
- errors: string | null // JSON string
428
- duration: number | null // milliseconds
429
- created_at: Generated<Date>
430
- }
431
- ```
432
-
433
- **SQL Schema** (migrations/001_initial_schema.sql):
434
-
435
- ```sql
436
- -- Stargazers table
437
- CREATE TABLE stargazer (
438
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
439
- github_id INTEGER UNIQUE NOT NULL,
440
- username VARCHAR(255) UNIQUE NOT NULL,
441
- email VARCHAR(255),
442
- name VARCHAR(255),
443
- avatar_url TEXT,
444
- bio TEXT,
445
- company VARCHAR(255),
446
- location VARCHAR(255),
447
- country VARCHAR(2),
448
- starred_at TIMESTAMP NOT NULL,
449
- contacted BOOLEAN DEFAULT false,
450
- contacted_at TIMESTAMP,
451
- last_email_sent TIMESTAMP,
452
- response_status VARCHAR(50),
453
- notes TEXT,
454
- created_at TIMESTAMP DEFAULT NOW(),
455
- updated_at TIMESTAMP DEFAULT NOW()
456
- );
457
-
458
- CREATE INDEX idx_stargazer_github_id ON stargazer(github_id);
459
- CREATE INDEX idx_stargazer_username ON stargazer(username);
460
- CREATE INDEX idx_stargazer_contacted ON stargazer(contacted);
461
- CREATE INDEX idx_stargazer_starred_at ON stargazer(starred_at);
462
-
463
- -- Email templates table
464
- CREATE TABLE email_template (
465
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
466
- name VARCHAR(255) UNIQUE NOT NULL,
467
- subject VARCHAR(500) NOT NULL,
468
- body TEXT NOT NULL,
469
- variables JSONB,
470
- created_at TIMESTAMP DEFAULT NOW(),
471
- updated_at TIMESTAMP DEFAULT NOW()
472
- );
473
-
474
- -- Emails table
475
- CREATE TABLE email (
476
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
477
- stargazer_id UUID REFERENCES stargazer(id) ON DELETE CASCADE,
478
- template_id UUID NOT NULL,
479
- template_name VARCHAR(255) NOT NULL,
480
- subject VARCHAR(500) NOT NULL,
481
- body TEXT NOT NULL,
482
- status VARCHAR(50) NOT NULL,
483
- scheduled_for TIMESTAMP,
484
- sent_at TIMESTAMP,
485
- approved_by VARCHAR(255),
486
- approved_at TIMESTAMP,
487
- error_message TEXT,
488
- created_at TIMESTAMP DEFAULT NOW()
489
- );
490
-
491
- CREATE INDEX idx_email_stargazer_id ON email(stargazer_id);
492
- CREATE INDEX idx_email_status ON email(status);
493
- CREATE INDEX idx_email_scheduled_for ON email(scheduled_for);
494
-
495
- -- Sync logs table
496
- CREATE TABLE sync_log (
497
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
498
- sync_type VARCHAR(50) NOT NULL,
499
- status VARCHAR(50) NOT NULL,
500
- new_stargazers INTEGER DEFAULT 0,
501
- total_fetched INTEGER DEFAULT 0,
502
- errors JSONB,
503
- duration INTEGER,
504
- created_at TIMESTAMP DEFAULT NOW()
505
- );
506
-
507
- CREATE INDEX idx_sync_log_created_at ON sync_log(created_at);
508
- CREATE INDEX idx_sync_log_sync_type ON sync_log(sync_type);
509
- ```
510
-
511
- **Environment Variables** (`.env`):
512
-
513
- ```bash
514
- # Project Config
515
- PROJECT_NAME=stargazer-cms
516
- NODE_ENV=development
517
-
518
- # Ports
519
- BACKEND_PORT=3001
520
- VITE_PORT=5173
521
- POSTGRES_PORT=5432
522
- SONAR_PORT=9000
523
-
524
- # Database
525
- DB_NAME=stargazer_cms
526
- DB_USER=admin
527
- DB_PASSWORD=admin
528
- DATABASE_URL=postgresql://${DB_USER}:${DB_PASSWORD}@postgres:5432/${DB_NAME}
529
-
530
- # GitHub
531
- GITHUB_TOKEN=ghp_your_token_here
532
- GITHUB_REPO_OWNER=paulpreibisch
533
- GITHUB_REPO_NAME=AgentVibes
534
-
535
- # SpaceMail API
536
- SPACEMAIL_API_KEY=your_spacemail_key
537
- SPACEMAIL_DOMAIN=your_domain.com
538
- SPACEMAIL_FROM_EMAIL=paul@your_domain.com
539
- SPACEMAIL_FROM_NAME=Paul Preibisch
540
-
541
- # Email Settings
542
- EMAIL_RATE_LIMIT_PER_HOUR=10
543
- EMAIL_WARMUP_DAILY_LIMIT=5 # Start low, increase gradually
544
-
545
- # PiperTTS (Optional)
546
- ENABLE_TTS=true
547
- TTS_QUIET_HOURS=22:00-08:00
548
- TTS_SCRIPT_PATH=/home/fire/claude/AgentVibes/.claude/hooks/play-tts.sh
549
-
550
- # Backup
551
- BACKUP_SCHEDULE=0 2 * * * # Daily at 2am
552
- BACKUP_RETENTION_DAYS=7
553
-
554
- # Cron
555
- SYNC_SCHEDULE=0 9 * * * # Daily at 9am
556
- ```
557
-
558
- **Error Handling Strategy**:
559
- - All async operations wrapped in try-catch with specific error types
560
- - User-friendly error messages in UI (toast notifications)
561
- - Detailed error logging to backend logs
562
- - Failed emails retry automatically (max 3 attempts with exponential backoff)
563
- - GitHub API errors show helpful messages (rate limit, auth failure, network)
564
-
565
- **Security Considerations**:
566
- - No API keys in code or version control
567
- - Environment variables for all secrets
568
- - Input validation on all API endpoints (Zod schemas)
569
- - SQL injection prevention via Prisma (parameterized queries)
570
- - XSS prevention via React (automatic escaping)
571
- - CSRF protection on state-changing operations
572
- - GitHub webhook signature verification (HMAC SHA256)
573
-
574
- ---
575
-
576
- ## Epic List
577
-
578
- ### Epic 1: Foundation & Infrastructure
579
- **Goal**: Establish project foundation with Docker environment, database, and core API scaffolding. Deliver a functional "health check" system demonstrating all services running and communicating.
580
-
581
- ### Epic 2: GitHub Stargazer Sync Engine
582
- **Goal**: Implement automated GitHub stargazer data collection with manual, cron, and webhook sync options. Store stargazers in PostgreSQL with complete profile data.
583
-
584
- ### Epic 3: Stargazer Table & Profile Views
585
- **Goal**: Build primary UI for viewing, filtering, and managing stargazers. Enable users to explore stargazer profiles and add notes.
586
-
587
- ### Epic 4: Email Template Management
588
- **Goal**: Create CRUD interface for email templates with variable substitution support. Provide template preview and reusable composition.
589
-
590
- ### Epic 5: SpaceMail Integration & Email Workflow
591
- **Goal**: Integrate SpaceMail API for semi-automated email sending with approval workflow. Implement rate limiting and deliverability best practices.
592
-
593
- ### Epic 6: Geographic Map Visualization
594
- **Goal**: Integrate Track-Stargazers map visualization as a tab in the UI, displaying stargazer distribution by country.
595
-
596
- ### Epic 7: Automation & Monitoring
597
- **Goal**: Implement scheduled backups, cron-based sync, optional PiperTTS notifications, and comprehensive logging/monitoring.
598
-
599
- ---
600
-
601
- ## Epic 1: Foundation & Infrastructure
602
-
603
- **Epic Goal**: Establish project foundation with Docker environment, PostgreSQL database, core API scaffolding, and Vite frontend. Deliver a functional "health check" system demonstrating all services running, with management scripts (`up`, `down`, `restart`, `health`, `logs`) following SoraSage patterns.
604
-
605
- ### Story 1.1: Project Scaffolding & Repository Setup
606
-
607
- **As a** developer,
608
- **I want** a properly structured monorepo with frontend/backend separation,
609
- **so that** I can start building features with clear boundaries and conventions.
610
-
611
- **Acceptance Criteria**:
612
- 1. Create GitHub private repository `agentvibes-stargazers`
613
- 2. Initialize monorepo structure:
614
- ```
615
- agentvibes-stargazers/
616
- ├── frontend/
617
- ├── backend/
618
- ├── scripts/
619
- ├── docs/
620
- ├── .env.example
621
- ├── .gitignore
622
- ├── docker-compose.yml
623
- ├── README.md
624
- └── up, down, restart, health, logs (scripts)
625
- ```
626
- 3. Add `.gitignore` excluding `.env`, `node_modules`, `dist`, `.sonar`
627
- 4. Create `.env.example` with all required environment variables (no values)
628
- 5. Initialize `frontend/` with Vite + React + TypeScript template
629
- 6. Initialize `backend/` with Express + TypeScript boilerplate
630
- 7. Add `README.md` with project overview and quick start instructions
631
- 8. All code follows AI-optimized documentation standards (file headers with 7 fields)
632
-
633
- ### Story 1.2: Docker Compose Configuration
634
-
635
- **As a** developer,
636
- **I want** Docker Compose orchestrating all services (frontend, backend, postgres, sonarqube),
637
- **so that** the entire stack runs with a single `./up` command.
638
-
639
- **Acceptance Criteria**:
640
- 1. Create `docker-compose.yml` with 4 services: postgres, backend, frontend, sonarqube
641
- 2. PostgreSQL service configuration:
642
- - Image: postgres:16-alpine
643
- - Container name: stargazer-cms-postgres
644
- - Port: ${POSTGRES_PORT:-5432}:5432
645
- - Volumes: postgres_data, ./backups
646
- - Health check: pg_isready every 10s
647
- 3. Backend service configuration:
648
- - Build: ./backend/Dockerfile
649
- - Container name: stargazer-cms-backend
650
- - Port: ${BACKEND_PORT:-3001}:3000
651
- - Depends on postgres (service_healthy condition)
652
- - Volumes: ./backend:/app (cached), backend_node_modules
653
- - Health check: curl /health every 5s
654
- 4. Frontend service configuration:
655
- - Build: ./frontend/Dockerfile
656
- - Container name: stargazer-cms-frontend
657
- - Port: ${VITE_PORT:-5173}:5173
658
- - Depends on backend
659
- - Volumes: ./frontend:/app (cached), frontend_node_modules
660
- - Command: npm run dev -- --host
661
- 5. SonarQube service configuration:
662
- - Image: sonarqube:community
663
- - Container name: stargazer-cms-sonar
664
- - Port: 9000:9000
665
- - Depends on postgres
666
- - Volumes: sonarqube_data, sonarqube_logs
667
- 6. All services connected to shared `app-network` bridge network
668
- 7. All volumes named with `stargazer_cms_` prefix
669
- 8. docker-compose.yml includes comments explaining service purposes
670
-
671
- ### Story 1.3: Docker Management Scripts
672
-
673
- **As a** developer,
674
- **I want** SoraSage-style management scripts (`up`, `down`, `restart`, `health`, `logs`),
675
- **so that** I can easily control the Docker environment with beautiful, color-coded output.
676
-
677
- **Acceptance Criteria**:
678
- 1. Create `./up` script (executable):
679
- - Load environment from `.env`
680
- - Display color-coded startup header with project name
681
- - Check for `--rebuild` flag to force container rebuild
682
- - Build/start Docker Compose services
683
- - Run Prisma migrations after postgres is healthy
684
- - Perform health checks on all services with spinners
685
- - Display success summary with service URLs (frontend, backend, SonarQube)
686
- - Exit code 0 on success, 1 on failure
687
- 2. Create `./down` script (executable):
688
- - Display shutdown header
689
- - Stop all Docker Compose services
690
- - Clean up PID files if any
691
- - Display success message
692
- 3. Create `./restart` script (executable):
693
- - Accept service name as argument (backend, frontend, postgres)
694
- - Restart specific container via `docker restart`
695
- - Wait 5 seconds
696
- - Curl health endpoint to verify (if applicable)
697
- - Display status
698
- 4. Create `./health` script (executable):
699
- - Check status of all services (frontend, backend, postgres)
700
- - Display HOST:PORT → INTERNAL:PORT for each service
701
- - Color-code status: green=up, red=down, yellow=warning
702
- - Show service-specific health info:
703
- - Backend: curl /health endpoint
704
- - Frontend: check Vite dev server logs for "ready"
705
- - PostgreSQL: docker exec pg_isready
706
- - Display restart commands for failed services
707
- - Summary: X/Y services running
708
- - Support `--backend`, `--frontend`, `--db` flags for filtered output
709
- 5. Create `./logs` script (executable):
710
- - Show last 10 lines of logs for all services (default)
711
- - Accept service name as argument for filtered logs
712
- - Color-code log levels: ERROR=red, WARN=yellow, INFO=blue, SUCCESS=green
713
- - Support `-f` flag for follow mode
714
- 6. All scripts follow Bash best practices: error handling, proper quoting, shellcheck clean
715
- 7. Scripts include file-level documentation headers per AI standards
716
-
717
- ### Story 1.4: Backend API Foundation
718
-
719
- **As a** developer,
720
- **I want** a minimal Express API with TypeScript, health endpoint, and Prisma setup,
721
- **so that** I have a solid foundation for building API routes.
722
-
723
- **Acceptance Criteria**:
724
- 1. Initialize TypeScript configuration with strict mode enabled
725
- 2. Install dependencies: express, @types/express, prisma, @prisma/client, dotenv, cors, helmet
726
- 3. Create `backend/src/index.ts`:
727
- - Load environment variables from .env
728
- - Configure Express app with JSON body parser, CORS, Helmet security headers
729
- - Add GET /health endpoint returning: `{status: "ok", timestamp: ISO string, services: {database: "connected"}}`
730
- - Start server on port from env (default 3000)
731
- - Graceful shutdown on SIGTERM/SIGINT
732
- 4. Create `backend/Dockerfile`:
733
- - Base image: node:18-alpine
734
- - Set working directory /app
735
- - Copy package.json, package-lock.json
736
- - Run npm ci
737
- - Copy source code
738
- - Expose port 3000
739
- - Run Prisma generate
740
- - Start with `npm run dev`
741
- 5. Add npm scripts: `dev` (tsx watch), `build` (tsc), `start` (node dist/index.js)
742
- 6. Configure ESLint with TypeScript plugin, Airbnb base style
743
- 7. All code follows AI-optimized documentation standards (function comments with 9 fields)
744
- 8. Health endpoint responds with 200 status when database connection is healthy
745
-
746
- ### Story 1.5: Database Schema & Kysely Setup
747
-
748
- **As a** developer,
749
- **I want** Kysely query builder configured with initial SQL schema and type-safe TypeScript definitions,
750
- **so that** I can perform type-safe database operations with full SQL control.
751
-
752
- **Acceptance Criteria**:
753
- 1. Install Kysely: `npm install kysely pg`
754
- 2. Install dev dependencies: `npm install -D kysely-ctl @types/pg`
755
- 3. Create `backend/src/db/database.ts`:
756
- - Initialize Kysely instance with PostgresDialect
757
- - Use pg Pool with DATABASE_URL from env
758
- - Export singleton db instance
759
- 4. Create `backend/src/db/types.ts`:
760
- - Define Database interface with all table interfaces
761
- - Define StargazerTable with all fields (snake_case column names)
762
- - Define EmailTemplateTable, EmailTable, SyncLogTable
763
- - Use Generated<T> for auto-generated fields (id, timestamps, defaults)
764
- 5. Create `backend/migrations/001_initial_schema.sql`:
765
- - CREATE TABLE stargazer with all columns, indexes, constraints
766
- - CREATE TABLE email_template
767
- - CREATE TABLE email with FK to stargazer (CASCADE on delete)
768
- - CREATE TABLE sync_log
769
- - All tables use UUID primary keys with gen_random_uuid()
770
- - Proper indexes on: github_id, username, contacted, starred_at, status
771
- 6. Create migration runner script `backend/scripts/migrate.ts`:
772
- - Use kysely-ctl or custom migration runner
773
- - Run all .sql files in migrations/ directory alphabetically
774
- - Track applied migrations in migrations table
775
- 7. Add npm scripts:
776
- - `"migrate": "tsx scripts/migrate.ts"`
777
- - `"migrate:create": "kysely-ctl migrate create"`
778
- 8. Create `backend/src/db/index.ts`:
779
- - Export db instance
780
- - Export all table types
781
- - Export helper functions (e.g., selectStargazer, insertEmail)
782
- 9. Update /health endpoint to test database connection using `db.selectFrom('stargazer').limit(1).execute()`
783
- 10. Run migrations in `./up` script after postgres is healthy
784
- 11. All code follows AI-optimized documentation standards
785
- 12. Schema uses snake_case for SQL (database convention), camelCase in TypeScript
786
-
787
- ### Story 1.6: Frontend Foundation with Chakra UI
788
-
789
- **As a** developer,
790
- **I want** a Vite + React app with Chakra UI v2, routing, and basic layout,
791
- **so that** I can start building the UI.
792
-
793
- **Acceptance Criteria**:
794
- 1. Initialize Vite React TypeScript template in `frontend/`
795
- 2. Install dependencies: @chakra-ui/react, @emotion/react, @emotion/styled, framer-motion, react-router-dom, @tanstack/react-query, @tanstack/react-table, axios, zustand, react-icons
796
- 3. Configure Chakra UI provider in `frontend/src/main.tsx`
797
- 4. Create `frontend/src/components/layout/MainLayout.tsx`:
798
- - Chakra Box with Flex layout
799
- - Sidebar (left, 250px width): Navigation links (Stargazers, Templates, Map, Settings)
800
- - Main content area (right, flex-grow): Outlet for nested routes
801
- - Header bar (top): Project title "Stargazer CMS", sync button, user menu
802
- 5. Create `frontend/src/App.tsx` with React Router:
803
- - Routes: / → Stargazers, /templates → Templates (placeholder), /map → Map (placeholder), /settings → Settings (placeholder)
804
- - Wrap routes in MainLayout
805
- 6. Create `frontend/src/pages/StargazersPage.tsx` (placeholder):
806
- - Display heading "Stargazers"
807
- - Show "Coming soon..." text
808
- 7. Create `frontend/Dockerfile`:
809
- - Base image: node:18-alpine
810
- - Set working directory /app
811
- - Copy package.json, package-lock.json
812
- - Run npm ci
813
- - Copy source code
814
- - Expose port 5173
815
- - Start with `npm run dev -- --host`
816
- 8. Add `frontend/vite.config.ts` with proxy to backend API
817
- 9. All components use Chakra UI primitives (Box, Flex, Text, Button, etc.)
818
- 10. All code follows AI-optimized documentation standards (file headers)
819
-
820
- ### Story 1.7: SonarQube Integration & Quality Gates
821
-
822
- **As a** developer,
823
- **I want** SonarQube configured with strict quality gates,
824
- **so that** all code meets maintainability standards before commits.
825
-
826
- **Acceptance Criteria**:
827
- 1. SonarQube service running on port 9000 (from docker-compose.yml)
828
- 2. Create `sonar-project.properties` in project root:
829
- - Project key: agentvibes-stargazers
830
- - Project name: Stargazer CMS
831
- - Sources: frontend/src, backend/src
832
- - Exclusions: node_modules, dist, coverage
833
- - Coverage report paths for Jest/Vitest
834
- 3. Create quality gate profile with thresholds:
835
- - Code Coverage: ≥70%
836
- - Duplicated Lines: ≤3%
837
- - Maintainability Rating: A
838
- - Cognitive Complexity: ≤15 per function
839
- - Cyclomatic Complexity: ≤10 per function
840
- - Lines per File: ≤200
841
- - Lines per Function: ≤50
842
- 4. Install SonarQube scanner: `npm install -g sonarqube-scanner`
843
- 5. Add npm script: `"sonar": "sonar-scanner"`
844
- 6. Create `.husky/pre-commit` hook:
845
- - Run `npm run lint` (ESLint)
846
- - Run `npm run type-check` (TypeScript)
847
- - Run `npm run test` (Jest/Vitest with coverage)
848
- - Run `npm run sonar` (SonarQube scan)
849
- - Block commit if any step fails
850
- 7. Document quality gate rules in `docs/code-quality.md`
851
- 8. Health script shows SonarQube status
852
-
853
- ---
854
-
855
- ## Epic 2: GitHub Stargazer Sync Engine
856
-
857
- **Epic Goal**: Implement automated GitHub stargazer data collection with three sync methods (manual, cron, webhook). Fetch complete stargazer profiles from GitHub API, store in PostgreSQL with country mapping, and log all sync operations.
858
-
859
- ### Story 2.1: GitHub API Service Layer
860
-
861
- **As a** backend developer,
862
- **I want** a GitHub service module using Octokit to fetch stargazers,
863
- **so that** I can retrieve stargazer data with proper authentication and pagination.
864
-
865
- **Acceptance Criteria**:
866
- 1. Create `backend/src/services/github.service.ts`
867
- 2. Initialize Octokit client with GitHub token from env variable
868
- 3. Implement `fetchStargazers(owner, repo, perPage=100)` function:
869
- - Use octokit.rest.activity.listStargazersForRepo
870
- - Accept header: application/vnd.github.v3.star+json (includes starred_at timestamp)
871
- - Implement automatic pagination to fetch all stargazers
872
- - Return array of objects: {githubId, username, starredAt}
873
- 4. Implement `fetchUserDetails(username)` function:
874
- - Use octokit.rest.users.getByUsername
875
- - Return object: {name, email, avatarUrl, bio, company, location}
876
- - Handle rate limiting with exponential backoff
877
- - Return null if user not found (404)
878
- 5. Implement `verifyToken()` function:
879
- - Test GitHub token validity
880
- - Return {valid: boolean, rateLimitRemaining: number}
881
- 6. Add error handling for common GitHub API errors:
882
- - 401 Unauthorized: Invalid token
883
- - 403 Forbidden: Rate limit exceeded
884
- - 404 Not Found: Repo or user not found
885
- - Network errors: Timeout, connection refused
886
- 7. All functions include comprehensive JSDoc comments per AI standards
887
- 8. Unit tests with mocked Octokit responses (Jest)
888
-
889
- ### Story 2.2: Geocoding & Country Mapping
890
-
891
- **As a** backend developer,
892
- **I want** to map stargazer locations to country names,
893
- **so that** I can display geographic distribution on the map.
894
-
895
- **Acceptance Criteria**:
896
- 1. Create `backend/src/services/geocoding.service.ts`
897
- 2. Implement `getCountryFromLocation(location: string)` function:
898
- - Parse common location formats: "City, Country", "Country", "City, State, Country"
899
- - Use simple country name matching first (fast path)
900
- - Fallback: Use geocoding API (OpenStreetMap Nominatim, free tier)
901
- - Cache results in-memory Map (location → country) to reduce API calls
902
- - Return ISO country code (e.g., "US", "CA", "GB") or null if unknown
903
- 3. Implement `batchGeocode(locations: string[])` function:
904
- - Process multiple locations efficiently
905
- - Check cache first
906
- - Batch API requests (max 10 concurrent)
907
- - Return Map<location, countryCode>
908
- 4. Add country code → country name mapping (static JSON file)
909
- 5. Handle edge cases:
910
- - Empty location string → null
911
- - Ambiguous locations (e.g., "London") → best guess or null
912
- - API rate limiting → retry with exponential backoff
913
- 6. Unit tests with sample locations and mocked API responses
914
-
915
- ### Story 2.3: Stargazer Sync Core Logic
916
-
917
- **As a** backend developer,
918
- **I want** core sync logic to fetch stargazers, enrich with user details, and store in database,
919
- **so that** I can keep the stargazer list up-to-date.
920
-
921
- **Acceptance Criteria**:
922
- 1. Create `backend/src/services/sync.service.ts`
923
- 2. Implement `syncStargazers(syncType: 'manual'|'cron'|'webhook')` function:
924
- - Fetch stargazers from GitHub (github.service.fetchStargazers)
925
- - For each stargazer:
926
- - Check if already in database (by githubId)
927
- - If new: Fetch user details (github.service.fetchUserDetails)
928
- - Map location to country (geocoding.service.getCountryFromLocation)
929
- - Upsert to database (Prisma)
930
- - Create SyncLog entry with: syncType, status, newStargazers count, totalFetched, duration
931
- - Return {success: boolean, newCount: number, totalCount: number, errors: string[]}
932
- 3. Implement progress tracking:
933
- - Emit progress events via EventEmitter
934
- - Events: sync_started, user_fetched, user_stored, sync_completed
935
- - Allows real-time UI updates via WebSocket (future story)
936
- 4. Add error resilience:
937
- - Continue processing if individual user fetch fails
938
- - Collect errors in array, log to SyncLog.errors
939
- - Mark sync as "partial" if some users failed
940
- 5. Implement deduplication:
941
- - Use githubId as unique identifier (not username, which can change)
942
- - Update existing stargazers if data changed
943
- 6. Add concurrency control:
944
- - Process user details in batches of 10 concurrent requests
945
- - Prevents overwhelming GitHub API and database
946
- 7. Unit tests with mocked GitHub service and database
947
- 8. Integration test with test database
948
-
949
- ### Story 2.4: Manual Sync API Endpoint
950
-
951
- **As a** user,
952
- **I want** a "Sync Now" button in the UI that triggers manual stargazer sync,
953
- **so that** I can update the list on-demand.
954
-
955
- **Acceptance Criteria**:
956
- 1. Create `backend/src/controllers/sync.controller.ts`
957
- 2. Implement POST /api/sync endpoint:
958
- - Trigger sync.service.syncStargazers('manual')
959
- - Return 202 Accepted immediately (async processing)
960
- - Response body: {syncId: string, message: "Sync started"}
961
- 3. Implement GET /api/sync/status/:syncId endpoint:
962
- - Query SyncLog by ID
963
- - Return {status: 'running'|'completed'|'failed', progress: number, errors: string[]}
964
- 4. Implement GET /api/sync/logs endpoint:
965
- - Query recent SyncLog entries (last 50)
966
- - Return array with: id, syncType, status, newStargazers, totalFetched, createdAt
967
- 5. Add frontend sync button in header:
968
- - Click triggers POST /api/sync
969
- - Show toast notification: "Sync started"
970
- - Poll GET /api/sync/status every 2 seconds until completed
971
- - Show success toast: "Synced X new stargazers"
972
- - Refresh stargazers table
973
- 6. Add loading spinner on sync button during active sync
974
- 7. Prevent concurrent syncs (return 409 Conflict if sync already running)
975
- 8. Integration test: POST /api/sync → verify database updated
976
-
977
- ### Story 2.5: Scheduled Cron Sync
978
-
979
- **As a** system,
980
- **I want** daily automated stargazer sync at 9am,
981
- **so that** the list stays current without manual intervention.
982
-
983
- **Acceptance Criteria**:
984
- 1. Install node-cron: `npm install node-cron @types/node-cron`
985
- 2. Create `backend/src/jobs/sync.job.ts`
986
- 3. Implement cron job:
987
- - Schedule: Load from env variable `SYNC_SCHEDULE` (default: "0 9 * * *")
988
- - Task: Call sync.service.syncStargazers('cron')
989
- - Log start and completion to console
990
- 4. Register cron job in `backend/src/index.ts` after Express app starts
991
- 5. Add graceful shutdown: Stop cron jobs on SIGTERM/SIGINT
992
- 6. Add optional PiperTTS notification on completion (if ENABLE_TTS=true):
993
- - Call notification.service.notifySync(newCount)
994
- - Respect TTS_QUIET_HOURS (skip if within quiet hours)
995
- 7. Log all cron executions to SyncLog table
996
- 8. Add env variable `ENABLE_CRON_SYNC` (default: true) to disable cron if needed
997
- 9. Create `backend/src/services/notification.service.ts`:
998
- - Check ENABLE_TTS env variable
999
- - Check current time against TTS_QUIET_HOURS
1000
- - Execute TTS script with message: "Stargazer sync complete. X new stargazers."
1001
- - Gracefully handle TTS script failures (log error, don't crash)
1002
- 10. Manual test: Set cron to run in 1 minute, verify sync executes and logs created
1003
-
1004
- ### Story 2.6: GitHub Webhook Integration
1005
-
1006
- **As a** system,
1007
- **I want** real-time notifications when someone stars the repo,
1008
- **so that** I can sync immediately without waiting for daily cron.
1009
-
1010
- **Acceptance Criteria**:
1011
- 1. Create `backend/src/controllers/webhook.controller.ts`
1012
- 2. Implement POST /api/webhooks/github endpoint:
1013
- - Verify GitHub signature (HMAC SHA256 using webhook secret)
1014
- - Parse event type from X-GitHub-Event header
1015
- - Handle "star" event (action=created):
1016
- - Extract stargazer username
1017
- - Call sync.service.syncStargazers('webhook')
1018
- - Return 200 OK
1019
- - Ignore other events
1020
- - Return 400 Bad Request if signature invalid
1021
- 3. Add env variable `GITHUB_WEBHOOK_SECRET` for signature verification
1022
- 4. Add optional PiperTTS notification on new star (if ENABLE_TTS=true):
1023
- - Call notification.service.notifyNewStargazer(username)
1024
- - Respect TTS_QUIET_HOURS
1025
- 5. Create SyncLog entry for each webhook-triggered sync
1026
- 6. Add webhook URL to Settings screen in UI
1027
- 7. Document GitHub webhook setup in README.md:
1028
- - Go to GitHub repo settings → Webhooks
1029
- - Add webhook with URL: http://your-domain/api/webhooks/github
1030
- - Content type: application/json
1031
- - Secret: (from GITHUB_WEBHOOK_SECRET env var)
1032
- - Events: Star
1033
- 8. Add rate limiting on webhook endpoint (max 100 requests/minute per IP)
1034
- 9. Unit test with mocked GitHub webhook payload
1035
- 10. Integration test: Send valid webhook payload, verify sync triggered
1036
-
1037
- ---
1038
-
1039
- ## Epic 3: Stargazer Table & Profile Views
1040
-
1041
- **Epic Goal**: Build the primary UI for viewing, filtering, and managing stargazers. Implement TanStack Table with sorting, filtering, pagination, and inline actions. Enable detailed stargazer profile view with contact history and notes.
1042
-
1043
- ### Story 3.1: Stargazer API Endpoints
1044
-
1045
- **As a** frontend developer,
1046
- **I want** REST API endpoints to fetch, filter, and update stargazers,
1047
- **so that** I can build the UI with real data.
1048
-
1049
- **Acceptance Criteria**:
1050
- 1. Create `backend/src/controllers/stargazers.controller.ts`
1051
- 2. Implement GET /api/stargazers endpoint:
1052
- - Query params: page (default 1), limit (default 50), sort (field:order), filter (JSON)
1053
- - Filter support: contacted (boolean), starredAfter (date), starredBefore (date), country (string), search (text search on username/name/email)
1054
- - Return: {data: Stargazer[], total: number, page: number, limit: number}
1055
- - Use Prisma pagination (skip/take) and filtering (where)
1056
- 3. Implement GET /api/stargazers/:id endpoint:
1057
- - Return single stargazer with all fields
1058
- - Include related emails (last 10)
1059
- - Return 404 if not found
1060
- 4. Implement PATCH /api/stargazers/:id endpoint:
1061
- - Accept body: {notes, contacted, responseStatus}
1062
- - Update stargazer in database
1063
- - Return updated stargazer
1064
- - Validate input with Zod schema
1065
- 5. Implement GET /api/stargazers/stats endpoint:
1066
- - Return: {total, contacted, notContacted, countryCounts: {[country]: count}}
1067
- - Use Kysely aggregation queries (selectFrom with count, groupBy)
1068
- 6. Add input validation middleware using Zod
1069
- 7. Add error handling middleware (consistent error responses)
1070
- 8. Unit tests for all endpoints
1071
- 9. Integration tests with test database
1072
-
1073
- ### Story 3.2: Stargazer Table with TanStack Table
1074
-
1075
- **As a** user,
1076
- **I want** a data table showing all stargazers with sorting, filtering, and pagination,
1077
- **so that** I can quickly find and manage stargazers.
1078
-
1079
- **Acceptance Criteria**:
1080
- 1. Create `frontend/src/components/stargazers/StargazerTable.tsx` (<150 lines)
1081
- 2. Install @tanstack/react-table v8
1082
- 3. Configure TanStack Table with columns:
1083
- - Avatar (image, 40px)
1084
- - Username (link to GitHub)
1085
- - Name
1086
- - Email
1087
- - Starred Date (formatted: "Jan 10, 2025")
1088
- - Country (with flag emoji if available)
1089
- - Contacted (badge: green="Yes", gray="No")
1090
- - Actions (buttons: "View", "Email")
1091
- 4. Implement column sorting (click header to toggle asc/desc)
1092
- 5. Implement pagination:
1093
- - Page size selector: 25, 50, 100
1094
- - Previous/Next buttons
1095
- - Page number display: "Page 1 of 10"
1096
- 6. Fetch data using TanStack Query:
1097
- - Query key: ['stargazers', page, limit, sort, filters]
1098
- - Fetch function: axios.get('/api/stargazers')
1099
- - Enable query caching (5 minutes staleTime)
1100
- 7. Add loading skeleton while fetching
1101
- 8. Add empty state: "No stargazers found. Click Sync to fetch from GitHub."
1102
- 9. Use Chakra UI Table components for styling
1103
- 10. All code follows AI-optimized documentation standards
1104
- 11. Component max 150 lines (extract row rendering to StargazerRow.tsx if needed)
1105
-
1106
- ### Story 3.3: Stargazer Filters
1107
-
1108
- **As a** user,
1109
- **I want** filters above the table to narrow down stargazers,
1110
- **so that** I can find specific users quickly.
1111
-
1112
- **Acceptance Criteria**:
1113
- 1. Create `frontend/src/components/stargazers/StargazerFilters.tsx` (<100 lines)
1114
- 2. Render filter bar with Chakra UI components:
1115
- - Search input (placeholder: "Search username, name, or email")
1116
- - Contact status filter (dropdown: All, Contacted, Not Contacted)
1117
- - Date range picker (Starred after, Starred before)
1118
- - Country filter (multi-select dropdown with top 20 countries)
1119
- - Clear filters button
1120
- 3. Implement filter state with Zustand store:
1121
- - Store: {search, contactStatus, starredAfter, starredBefore, countries}
1122
- - Actions: setSearch, setContactStatus, setDateRange, setCountries, clearFilters
1123
- 4. Debounce search input (300ms) to prevent excessive API calls
1124
- 5. Update TanStack Query when filters change
1125
- 6. Persist filters in URL query params (enables sharing filtered views)
1126
- 7. Show active filter count badge: "3 filters active"
1127
- 8. Add "Reset filters" button if any filters active
1128
- 9. All code follows AI standards (<100 lines)
1129
-
1130
- ### Story 3.4: Stargazer Profile Modal
1131
-
1132
- **As a** user,
1133
- **I want** a detailed profile view when clicking on a stargazer,
1134
- **so that** I can see their full information and contact history.
1135
-
1136
- **Acceptance Criteria**:
1137
- 1. Create `frontend/src/components/stargazers/StargazerProfileModal.tsx` (<150 lines)
1138
- 2. Use Chakra UI Modal component (large size)
1139
- 3. Modal layout (two columns):
1140
- - Left column (40%):
1141
- - Avatar (large, 120px)
1142
- - Username (link to GitHub profile in new tab)
1143
- - Name
1144
- - Email (mailto link)
1145
- - Company
1146
- - Location → Country
1147
- - Bio (italic, gray text)
1148
- - Starred date
1149
- - Right column (60%):
1150
- - Contact history section:
1151
- - Heading: "Contact History"
1152
- - Timeline of emails sent (template name, sent date, status)
1153
- - Empty state: "No emails sent yet"
1154
- - Notes section:
1155
- - Heading: "Notes"
1156
- - Textarea (editable, auto-save on blur)
1157
- - Character count: "250/1000"
1158
- 4. Add action buttons in footer:
1159
- - "Send Email" (opens EmailComposerModal)
1160
- - "View on GitHub" (opens new tab)
1161
- - "Close"
1162
- 5. Fetch stargazer details using TanStack Query:
1163
- - Query key: ['stargazer', id]
1164
- - Fetch function: axios.get(`/api/stargazers/${id}`)
1165
- 6. Implement notes auto-save:
1166
- - Debounce textarea changes (1 second)
1167
- - PATCH /api/stargazers/:id with new notes
1168
- - Show subtle "Saving..." indicator
1169
- - Show checkmark on successful save
1170
- 7. Add loading state while fetching
1171
- 8. All code follows AI standards (<150 lines)
1172
-
1173
- ### Story 3.5: Bulk Selection & Actions
1174
-
1175
- **As a** user,
1176
- **I want** to select multiple stargazers and perform bulk actions,
1177
- **so that** I can send emails to multiple people at once.
1178
-
1179
- **Acceptance Criteria**:
1180
- 1. Add checkbox column to StargazerTable (first column)
1181
- 2. Implement TanStack Table row selection:
1182
- - Header checkbox: Select all on current page
1183
- - Row checkboxes: Select individual stargazers
1184
- - Shift+click: Range selection
1185
- 3. Add selection state to Zustand store:
1186
- - Store: {selectedIds: Set<string>}
1187
- - Actions: selectOne, deselectOne, selectAll, deselectAll, toggleSelection
1188
- 4. Display selection count badge above table:
1189
- - "3 stargazers selected"
1190
- - Clear selection button (X icon)
1191
- 5. Add bulk actions dropdown (enabled only when selections exist):
1192
- - "Send Email to Selected" → Opens EmailComposerModal with multiple recipients
1193
- - "Mark as Contacted"
1194
- - "Export Selected (CSV)"
1195
- 6. Implement "Mark as Contacted" action:
1196
- - PATCH /api/stargazers/bulk with {ids: string[], contacted: true}
1197
- - Show success toast: "Marked 5 stargazers as contacted"
1198
- - Refresh table
1199
- 7. Implement "Export Selected (CSV)" action:
1200
- - Generate CSV file with columns: username, name, email, starred_date, country
1201
- - Trigger browser download
1202
- 8. Persist selection across pagination (selection state independent of current page)
1203
- 9. Clear selection when filters change
1204
-
1205
- ---
1206
-
1207
- ## Epic 4: Email Template Management
1208
-
1209
- **Epic Goal**: Create CRUD interface for managing email templates with variable substitution support ({{name}}, {{username}}, {{repo}}). Provide template preview with sample data and enable reusable composition.
1210
-
1211
- ### Story 4.1: Email Template API Endpoints
1212
-
1213
- **As a** frontend developer,
1214
- **I want** REST API endpoints for template CRUD operations,
1215
- **so that** I can build the template management UI.
1216
-
1217
- **Acceptance Criteria**:
1218
- 1. Create `backend/src/controllers/templates.controller.ts`
1219
- 2. Implement GET /api/templates endpoint:
1220
- - Return all templates sorted by name
1221
- - Include: id, name, subject, body, createdAt, updatedAt
1222
- - Pagination optional (most users have <20 templates)
1223
- 3. Implement GET /api/templates/:id endpoint:
1224
- - Return single template
1225
- - Return 404 if not found
1226
- 4. Implement POST /api/templates endpoint:
1227
- - Accept body: {name, subject, body, variables}
1228
- - Validate: name required (unique), subject required, body required
1229
- - Create template in database
1230
- - Return created template with 201 status
1231
- 5. Implement PATCH /api/templates/:id endpoint:
1232
- - Accept body: {name, subject, body, variables}
1233
- - Update template in database
1234
- - Return updated template
1235
- 6. Implement DELETE /api/templates/:id endpoint:
1236
- - Delete template from database
1237
- - Return 204 No Content
1238
- - Prevent deletion if template is referenced in Email table (return 409 Conflict)
1239
- 7. Add input validation using Zod:
1240
- - Name: 1-100 characters, unique
1241
- - Subject: 1-200 characters
1242
- - Body: 1-5000 characters
1243
- - Variables: array of strings (optional)
1244
- 8. Unit tests for all endpoints
1245
- 9. Integration tests with test database
1246
-
1247
- ### Story 4.2: Template List Screen
1248
-
1249
- **As a** user,
1250
- **I want** a screen listing all my email templates,
1251
- **so that** I can view, edit, and delete templates.
1252
-
1253
- **Acceptance Criteria**:
1254
- 1. Create `frontend/src/pages/TemplatesPage.tsx` (<150 lines)
1255
- 2. Layout: Two-column design
1256
- - Left sidebar (30%): Template list
1257
- - Right panel (70%): Template editor or preview
1258
- 3. Template list (sidebar):
1259
- - Each item shows: template name, subject preview (truncated), last updated date
1260
- - Click to select and show in right panel
1261
- - Hover effect (background color change)
1262
- - Active template highlighted (border)
1263
- - "Create New Template" button at top
1264
- 4. Fetch templates using TanStack Query:
1265
- - Query key: ['templates']
1266
- - Fetch function: axios.get('/api/templates')
1267
- - Enable query caching
1268
- 5. Add empty state: "No templates yet. Create your first template to get started."
1269
- 6. Add loading skeleton while fetching
1270
- 7. Use Chakra UI List and ListItem components
1271
- 8. All code follows AI standards (<150 lines)
1272
-
1273
- ### Story 4.3: Template Editor
1274
-
1275
- **As a** user,
1276
- **I want** to create and edit email templates with variable placeholders,
1277
- **so that** I can reuse templates for multiple stargazers.
1278
-
1279
- **Acceptance Criteria**:
1280
- 1. Create `frontend/src/components/templates/TemplateEditor.tsx` (<150 lines)
1281
- 2. Form fields (Chakra UI):
1282
- - Template name input (required)
1283
- - Subject line input (required)
1284
- - Body textarea (required, tall, 300px height)
1285
- - Variable hints below body: "Available variables: {{name}}, {{username}}, {{repo}}"
1286
- 3. Add "Save" and "Cancel" buttons
1287
- 4. Implement create/update logic:
1288
- - If new template: POST /api/templates
1289
- - If editing: PATCH /api/templates/:id
1290
- - Show success toast on save
1291
- - Invalidate templates query cache
1292
- 5. Add form validation:
1293
- - Name required, max 100 characters
1294
- - Subject required, max 200 characters
1295
- - Body required, max 5000 characters
1296
- - Show error messages below fields
1297
- 6. Add "Duplicate Template" button (copies current template with " (Copy)" suffix)
1298
- 7. Add "Delete Template" button (with confirmation dialog):
1299
- - Show warning: "Are you sure? This cannot be undone."
1300
- - DELETE /api/templates/:id
1301
- - Show success toast: "Template deleted"
1302
- - Redirect to template list
1303
- 8. Disable delete if template has been used (check Email table)
1304
- 9. All code follows AI standards (<150 lines)
1305
-
1306
- ### Story 4.4: Template Preview
1307
-
1308
- **As a** user,
1309
- **I want** to preview how an email template looks with sample data,
1310
- **so that** I can verify formatting before sending.
1311
-
1312
- **Acceptance Criteria**:
1313
- 1. Create `frontend/src/components/templates/TemplatePreview.tsx` (<100 lines)
1314
- 2. Render email preview card (Chakra UI):
1315
- - Header section: "Subject: [rendered subject]"
1316
- - Body section: [rendered body with variables replaced]
1317
- - Use sample data: {name: "John Doe", username: "johndoe", repo: "AgentVibes"}
1318
- 3. Implement variable substitution logic:
1319
- - Replace {{name}} with sample name
1320
- - Replace {{username}} with sample username
1321
- - Replace {{repo}} with sample repo name
1322
- - Handle missing variables gracefully (show placeholder)
1323
- 4. Add "Preview Mode" toggle button in template editor
1324
- 5. Show preview in right panel when preview mode active
1325
- 6. Use monospace font for variables in body textarea (syntax highlighting)
1326
- 7. Add "Copy Preview" button (copies rendered text to clipboard)
1327
- 8. All code follows AI standards (<100 lines)
1328
-
1329
- ### Story 4.5: Default Templates Seeding
1330
-
1331
- **As a** developer,
1332
- **I want** default email templates created on first run,
1333
- **so that** users have examples to start with.
1334
-
1335
- **Acceptance Criteria**:
1336
- 1. Create `backend/scripts/seed.ts`
1337
- 2. Use Kysely insertInto to seed default templates
1338
- 3. Define 3 default templates:
1339
- - **"Initial Thank You"**:
1340
- - Subject: "Thanks for starring AgentVibes, {{name}}! 🌟"
1341
- - Body:
1342
- ```
1343
- Hi {{name}},
1344
-
1345
- I noticed you starred AgentVibes on GitHub – thank you!
1346
-
1347
- I'm actively improving it and would love your feedback:
1348
- - What brought you to AgentVibes?
1349
- - Any features you'd like to see?
1350
-
1351
- Feel free to reply or open an issue. Your input shapes the roadmap.
1352
-
1353
- Cheers,
1354
- Paul Preibisch
1355
-
1356
- ---
1357
- Unsubscribe: [link]
1358
- ```
1359
- - **"Feature Feedback Request"**:
1360
- - Subject: "Quick question about AgentVibes"
1361
- - Body:
1362
- ```
1363
- Hey {{username}},
1364
-
1365
- Thanks for being an early supporter of AgentVibes!
1366
-
1367
- I'm planning the next release and curious: which feature would be most valuable to you?
1368
-
1369
- A) More TTS voices
1370
- B) Better customization options
1371
- C) Integration with other tools
1372
- D) Something else (please tell me!)
1373
-
1374
- Reply with your choice or any ideas. Takes 30 seconds and really helps.
1375
-
1376
- Thanks,
1377
- Paul
1378
- ```
1379
- - **"Follow-up (No Response)"**:
1380
- - Subject: "Still interested in AgentVibes?"
1381
- - Body:
1382
- ```
1383
- Hi {{name}},
1384
-
1385
- I reached out a few weeks ago but didn't hear back. No worries!
1386
-
1387
- If you're still interested in AgentVibes, I'd love to stay in touch. We've added [new features] since you starred the repo.
1388
-
1389
- Let me know if you have any questions or feedback.
1390
-
1391
- Best,
1392
- Paul
1393
- ```
1394
- 4. Implement seed logic:
1395
- - Use Kysely selectFrom('email_template').select(count()).execute()
1396
- - If count === 0, insert default templates using insertInto
1397
- - Log: "Seeded 3 default templates"
1398
- 5. Add seed script to package.json: `"seed": "tsx backend/scripts/seed.ts"`
1399
- 6. Run seed automatically in `./up` script after migrations
1400
- 6. All code follows AI standards
1401
-
1402
- ---
1403
-
1404
- ## Epic 5: SpaceMail Integration & Email Workflow
1405
-
1406
- **Epic Goal**: Integrate SpaceMail API for semi-automated email sending with approval workflow, rate limiting, and deliverability best practices. Implement email composer, draft management, scheduled sending, and engagement tracking.
1407
-
1408
- ### Story 5.1: SpaceMail API Service Layer
1409
-
1410
- **As a** backend developer,
1411
- **I want** a SpaceMail service module to send emails via their API,
1412
- **so that** I can send transactional emails with tracking.
1413
-
1414
- **Acceptance Criteria**:
1415
- 1. Create `backend/src/services/spacemail.service.ts`
1416
- 2. Install SpaceMail SDK or use Axios for REST API
1417
- 3. Implement `sendEmail(params)` function:
1418
- - Parameters: {to, subject, body, fromEmail, fromName}
1419
- - Use SpaceMail API: POST /v1/emails
1420
- - Headers: Authorization with SPACEMAIL_API_KEY
1421
- - Body: {from: {email, name}, to: [{email}], subject, html: body}
1422
- - Return: {success: boolean, messageId: string, error?: string}
1423
- 4. Implement rate limiting:
1424
- - Track emails sent in last hour (store in-memory or Redis)
1425
- - Reject if count >= EMAIL_RATE_LIMIT_PER_HOUR (env var, default 10)
1426
- - Return error: "Rate limit exceeded. Try again in X minutes."
1427
- 5. Implement retry logic for transient failures:
1428
- - Retry on 5xx errors (server errors)
1429
- - Max 3 retries with exponential backoff (1s, 2s, 4s)
1430
- - Don't retry on 4xx errors (client errors)
1431
- 6. Implement `verifyCredentials()` function:
1432
- - Test API key validity
1433
- - Return {valid: boolean, domain: string}
1434
- 7. Add comprehensive error handling:
1435
- - Invalid API key → 401 error
1436
- - Invalid domain → 403 error
1437
- - Rate limit exceeded → 429 error
1438
- - Network errors → timeout/connection refused
1439
- 8. All functions include JSDoc comments per AI standards
1440
- 9. Unit tests with mocked SpaceMail API responses
1441
-
1442
- ### Story 5.2: Email Composition & Draft Management
1443
-
1444
- **As a** user,
1445
- **I want** to compose an email to a stargazer using a template,
1446
- **so that** I can personalize the message before sending.
1447
-
1448
- **Acceptance Criteria**:
1449
- 1. Create `frontend/src/components/email/EmailComposer.tsx` (<200 lines)
1450
- 2. Use Chakra UI Modal (large size, full height)
1451
- 3. Modal sections:
1452
- - Header: "Compose Email to [username]" or "Compose Email to X stargazers"
1453
- - Template selector: Dropdown of available templates
1454
- - Subject input: Pre-filled from template, editable
1455
- - Body textarea: Pre-filled from template with variables replaced, editable
1456
- - Recipient list (if bulk send): Chip list of stargazers, removable
1457
- 4. Implement variable substitution:
1458
- - Replace {{name}} with stargazer name (or "there" if null)
1459
- - Replace {{username}} with GitHub username
1460
- - Replace {{repo}} with "AgentVibes"
1461
- - Handle multiple recipients: each gets personalized copy
1462
- 5. Add action buttons:
1463
- - "Save Draft" → POST /api/emails/draft
1464
- - "Send Now" → POST /api/emails/send (approval required)
1465
- - "Schedule Send" → Opens date picker, POST /api/emails/schedule
1466
- - "Cancel" → Close modal with confirmation if changes
1467
- 6. Add character counter for subject (max 200) and body (max 5000)
1468
- 7. Add preview toggle: Switch between edit and preview modes
1469
- 8. Persist draft to database (Email table with status="draft")
1470
- 9. Load draft if reopening composer for same stargazer
1471
- 10. All code follows AI standards (<200 lines, extract sub-components if needed)
1472
-
1473
- ### Story 5.3: Email Approval Workflow
1474
-
1475
- **As a** user,
1476
- **I want** to review and approve emails before they are sent,
1477
- **so that** I don't accidentally send incorrect emails.
1478
-
1479
- **Acceptance Criteria**:
1480
- 1. Create `backend/src/controllers/emails.controller.ts`
1481
- 2. Implement POST /api/emails/draft endpoint:
1482
- - Accept body: {stargazerId, templateId, subject, body}
1483
- - Create Email record with status="draft"
1484
- - Return created email
1485
- 3. Implement POST /api/emails/send endpoint:
1486
- - Accept body: {emailId}
1487
- - Validate email exists and status="draft"
1488
- - Update status to "pending_approval"
1489
- - Return {success: true, message: "Email ready for approval"}
1490
- 4. Create `frontend/src/components/email/EmailApprovalModal.tsx` (<150 lines)
1491
- 5. Modal sections:
1492
- - Header: "Approve Email to [username]"
1493
- - Preview section: Rendered email (subject + body)
1494
- - Recipient info: Avatar, username, email address
1495
- - Warning: "This email will be sent via SpaceMail API. Review carefully."
1496
- 6. Add action buttons:
1497
- - "Approve & Send" → POST /api/emails/approve/:id
1498
- - "Edit" → Reopen EmailComposer
1499
- - "Cancel" → Close modal
1500
- 7. Implement POST /api/emails/approve/:id endpoint:
1501
- - Validate email exists and status="pending_approval"
1502
- - Check rate limit (spacemail.service)
1503
- - Send email via SpaceMail (spacemail.service.sendEmail)
1504
- - Update Email record: status="sent", sentAt=now, approvedBy="user", approvedAt=now
1505
- - Update Stargazer: contacted=true, contactedAt=now, lastEmailSent=now
1506
- - Return {success: boolean, messageId?: string, error?: string}
1507
- 8. Show success toast: "Email sent to [username]"
1508
- 9. Show error toast if send fails: "Failed to send email: [error message]"
1509
- 10. Add loading state during send operation
1510
- 11. All code follows AI standards
1511
-
1512
- ### Story 5.4: Scheduled Email Sending
1513
-
1514
- **As a** user,
1515
- **I want** to schedule emails to be sent at a future time,
1516
- **so that** I can send follow-ups after a delay.
1517
-
1518
- **Acceptance Criteria**:
1519
- 1. Add `scheduledFor` field to Email composer modal
1520
- 2. Implement date/time picker (Chakra UI DatePicker or react-datepicker)
1521
- 3. Validate scheduled time is in the future (at least 5 minutes from now)
1522
- 4. Implement POST /api/emails/schedule endpoint:
1523
- - Accept body: {emailId, scheduledFor}
1524
- - Update Email record: scheduledFor timestamp
1525
- - Return {success: true}
1526
- 5. Create `backend/src/jobs/email.job.ts`
1527
- 6. Implement cron job to send scheduled emails:
1528
- - Schedule: Every 5 minutes ("*/5 * * * *")
1529
- - Query emails where status="pending_approval" and scheduledFor <= now
1530
- - For each email:
1531
- - Check rate limit
1532
- - Send via SpaceMail
1533
- - Update status to "sent" or "failed"
1534
- - Log results
1535
- 7. Register email job in `backend/src/index.ts`
1536
- 8. Add "Cancel Scheduled Send" button in UI:
1537
- - DELETE /api/emails/scheduled/:id
1538
- - Update status back to "draft"
1539
- 9. Show scheduled emails in Settings screen:
1540
- - List of upcoming scheduled sends
1541
- - Columns: Recipient, subject, scheduled time, cancel button
1542
- 10. Add notification on scheduled send completion (optional TTS)
1543
-
1544
- ### Story 5.5: Email History & Engagement Tracking
1545
-
1546
- **As a** user,
1547
- **I want** to see email history for each stargazer,
1548
- **so that** I can track communication and avoid duplicate emails.
1549
-
1550
- **Acceptance Criteria**:
1551
- 1. Implement GET /api/stargazers/:id/emails endpoint:
1552
- - Return all emails sent to stargazer (sorted by sentAt desc)
1553
- - Include: id, templateName, subject, status, sentAt, approvedAt
1554
- 2. Create `frontend/src/components/stargazers/EmailHistory.tsx` (<100 lines)
1555
- 3. Render timeline component (Chakra UI):
1556
- - Each entry: Template name, subject (truncated), sent date, status badge
1557
- - Status colors: sent=green, failed=red, pending_approval=yellow, draft=gray
1558
- - Click to expand: Show full email body
1559
- 4. Add to StargazerProfileModal (right column)
1560
- 5. Show empty state: "No emails sent to this stargazer yet"
1561
- 6. Add filter: "Show only sent" / "Show all"
1562
- 7. Implement GET /api/emails/stats endpoint:
1563
- - Return: {totalSent, totalFailed, averageResponseTime, responseRate}
1564
- - Use Prisma aggregation
1565
- 8. Create `frontend/src/pages/AnalyticsPage.tsx` (placeholder for Epic 6):
1566
- - Display email stats: Total sent, Success rate, Response rate
1567
- - Chart: Emails sent over time (last 30 days)
1568
- 9. All code follows AI standards
1569
-
1570
- ---
1571
-
1572
- ## Epic 6: Geographic Map Visualization
1573
-
1574
- **Epic Goal**: Integrate Track-Stargazers map visualization library to display stargazer distribution by country. Render interactive world map with country hover tooltips, clickable regions, and filter integration.
1575
-
1576
- ### Story 6.1: Map Data API Endpoint
1577
-
1578
- **As a** frontend developer,
1579
- **I want** an API endpoint providing stargazer counts by country,
1580
- **so that** I can render the geographic map.
1581
-
1582
- **Acceptance Criteria**:
1583
- 1. Implement GET /api/stargazers/map-data endpoint in `backend/src/controllers/stargazers.controller.ts`
1584
- 2. Query stargazers grouped by country:
1585
- - Use Kysely selectFrom with count() and groupBy('country')
1586
- - Return: `{country: countryCode, count: number}[]`
1587
- - Example: `[{country: "US", count: 45}, {country: "CA", count: 12}, ...]`
1588
- 3. Filter by contact status (query param: contacted=true/false/all)
1589
- 4. Add country name mapping:
1590
- - Return: `{country: countryCode, countryName: string, count: number}[]`
1591
- - Use static country code → name mapping (ISO 3166-1 alpha-2)
1592
- 5. Handle stargazers with unknown location:
1593
- - Group as `{country: "UNKNOWN", countryName: "Unknown", count: X}`
1594
- 6. Add caching headers: Cache-Control: max-age=300 (5 minutes)
1595
- 7. Unit test with sample data
1596
-
1597
- ### Story 6.2: Integrate Track-Stargazers Map Library
1598
-
1599
- **As a** frontend developer,
1600
- **I want** to integrate Track-Stargazers' Datamaps + D3.js visualization,
1601
- **so that** I can display an interactive world map.
1602
-
1603
- **Acceptance Criteria**:
1604
- 1. Research Track-Stargazers implementation:
1605
- - Clone repo: https://github.com/kiok46/Track-Stargazers
1606
- - Review `index.html`, JavaScript files
1607
- - Identify Datamaps and D3.js dependencies
1608
- 2. Install dependencies:
1609
- - `npm install d3 datamaps`
1610
- - `npm install @types/d3 --save-dev`
1611
- 3. Create `frontend/src/components/map/StargazerMap.tsx` (<150 lines)
1612
- 4. Initialize Datamap in React component:
1613
- - Use useEffect to render map after component mounts
1614
- - Target: `<div ref={mapRef} style={{height: 600px}} />`
1615
- - Configure Datamap with world map projection
1616
- 5. Load map data from API:
1617
- - Fetch using TanStack Query: `useQuery(['map-data', filters])`
1618
- - Transform to Datamaps format: `{USA: {fillKey: 'HIGH'}, ...}`
1619
- 6. Configure color scale based on stargazer count:
1620
- - 0: Light gray
1621
- - 1-5: Light blue
1622
- - 6-20: Medium blue
1623
- - 21-50: Dark blue
1624
- - 51+: Darkest blue
1625
- 7. Add hover tooltips:
1626
- - Show country name and stargazer count
1627
- - Example: "United States: 45 stargazers"
1628
- 8. Add click handler:
1629
- - Click on country → Filter stargazers table by that country
1630
- - Navigate to Stargazers page with country filter applied
1631
- 9. Add legend showing color scale
1632
- 10. All code follows AI standards (<150 lines)
1633
-
1634
- ### Story 6.3: Map Page UI Integration
1635
-
1636
- **As a** user,
1637
- **I want** a dedicated Map tab in the sidebar,
1638
- **so that** I can view geographic distribution of stargazers.
1639
-
1640
- **Acceptance Criteria**:
1641
- 1. Create `frontend/src/pages/MapPage.tsx` (<100 lines)
1642
- 2. Layout:
1643
- - Header: "Stargazer Distribution"
1644
- - Subtitle: "Geographic distribution of AgentVibes stargazers"
1645
- - Filter bar: Contact status filter (All, Contacted, Not Contacted)
1646
- - Map component (StargazerMap)
1647
- - Summary stats below map: "Total: X stargazers across Y countries"
1648
- 3. Add Map link to sidebar navigation
1649
- 4. Fetch map data based on selected filter
1650
- 5. Add loading state while map data loads
1651
- 6. Add empty state: "No stargazers yet. Sync from GitHub to get started."
1652
- 7. Add "Refresh Map" button to refetch data
1653
- 8. Use Chakra UI Box, Heading, Text components
1654
- 9. All code follows AI standards (<100 lines)
1655
-
1656
- ### Story 6.4: Alternative React Map Library (Fallback)
1657
-
1658
- **As a** frontend developer,
1659
- **I want** an alternative map implementation using react-simple-maps,
1660
- **so that** I have a React-native solution if Datamaps integration is difficult.
1661
-
1662
- **Acceptance Criteria**:
1663
- 1. Install react-simple-maps: `npm install react-simple-maps`
1664
- 2. Create `frontend/src/components/map/SimpleStargazerMap.tsx` (<150 lines)
1665
- 3. Use react-simple-maps ComposableMap component:
1666
- - Projection: geoMercator
1667
- - Width: 800, Height: 400
1668
- 4. Render Geography components for each country:
1669
- - Fill color based on stargazer count (same scale as Datamaps)
1670
- - Stroke color: Light gray borders
1671
- 5. Add hover effects:
1672
- - Brighten color on hover
1673
- - Show tooltip with country name and count
1674
- 6. Add click handler (same as Datamaps version)
1675
- 7. Compare performance and UX with Datamaps version
1676
- 8. Decide which to use based on:
1677
- - Ease of integration
1678
- - Visual appeal
1679
- - Performance
1680
- - Bundle size
1681
- 9. Document decision in `docs/architecture.md`
1682
- 10. All code follows AI standards (<150 lines)
1683
-
1684
- ---
1685
-
1686
- ## Epic 7: Automation & Monitoring
1687
-
1688
- **Epic Goal**: Implement automated database backups with 7-day retention, cron-based sync monitoring, optional PiperTTS notifications, comprehensive logging, and health monitoring dashboards.
1689
-
1690
- ### Story 7.1: Automated Database Backups
1691
-
1692
- **As a** system administrator,
1693
- **I want** daily automated PostgreSQL backups,
1694
- **so that** I can recover data if the database is corrupted or deleted.
1695
-
1696
- **Acceptance Criteria**:
1697
- 1. Create `scripts/backup-db.sh` (executable)
1698
- 2. Implement backup logic:
1699
- - Load env variables from .env
1700
- - Create `backups/` directory if not exists
1701
- - Generate timestamp: `YYYYMMDD_HHMMSS`
1702
- - Run: `docker exec stargazer-cms-postgres pg_dump -U ${DB_USER} ${DB_NAME} > backups/stargazer_cms_${TIMESTAMP}.sql`
1703
- - Verify backup file created and non-empty
1704
- - Log success: "Backup created: backups/stargazer_cms_20250110_020000.sql"
1705
- 3. Implement retention policy:
1706
- - Find backups older than 7 days
1707
- - Delete old backups: `find backups/ -name "*.sql" -mtime +7 -delete`
1708
- - Log: "Deleted X old backups"
1709
- 4. Add error handling:
1710
- - Exit 1 if pg_dump fails
1711
- - Log error message
1712
- - Send notification (optional TTS or email)
1713
- 5. Add to crontab (via Docker or host):
1714
- - Schedule: `0 2 * * *` (daily at 2am)
1715
- - Log output to `logs/backup.log`
1716
- 6. Create `scripts/restore-db.sh` (manual):
1717
- - Accept backup file path as argument
1718
- - Run: `docker exec -i stargazer-cms-postgres psql -U ${DB_USER} ${DB_NAME} < $BACKUP_FILE`
1719
- - Confirm before restoring (requires user input)
1720
- 7. Document backup/restore process in README.md
1721
- 8. Test: Run backup script manually, verify file created
1722
- 9. All code follows AI standards (Bash documentation headers)
1723
-
1724
- ### Story 7.2: Cron Job Management
1725
-
1726
- **As a** system administrator,
1727
- **I want** all cron jobs (sync, backups) managed in one place,
1728
- **so that** I can easily enable/disable automation.
1729
-
1730
- **Acceptance Criteria**:
1731
- 1. Create `backend/src/jobs/index.ts` (cron job registry)
1732
- 2. Register all cron jobs:
1733
- - Sync job: `0 9 * * *` (daily at 9am)
1734
- - Email job: `*/5 * * * *` (every 5 minutes)
1735
- 3. Add env variables for enabling/disabling jobs:
1736
- - `ENABLE_CRON_SYNC` (default: true)
1737
- - `ENABLE_CRON_EMAIL` (default: true)
1738
- 4. Log all cron job executions:
1739
- - Start: "Cron job [name] started"
1740
- - End: "Cron job [name] completed in Xms"
1741
- - Errors: "Cron job [name] failed: [error]"
1742
- 5. Add graceful shutdown:
1743
- - Stop all cron jobs on SIGTERM/SIGINT
1744
- - Wait for running jobs to complete (max 30 seconds)
1745
- 6. Add GET /api/cron/status endpoint:
1746
- - Return: `{jobs: [{name, schedule, enabled, lastRun, nextRun, status}]}`
1747
- - Status: idle, running, failed
1748
- 7. Create Settings screen section for cron jobs:
1749
- - List all jobs with enable/disable toggles
1750
- - Show last run time and status
1751
- - "Run Now" button for manual trigger
1752
- 8. Implement PATCH /api/cron/toggle endpoint:
1753
- - Accept: {jobName, enabled}
1754
- - Update env variable (persist to .env file)
1755
- - Restart job if enabled
1756
- 9. All code follows AI standards
1757
-
1758
- ### Story 7.3: PiperTTS Notification Plugin
1759
-
1760
- **As a** user,
1761
- **I want** optional voice notifications when stargazers are synced,
1762
- **so that** I'm alerted to new supporters in real-time.
1763
-
1764
- **Acceptance Criteria**:
1765
- 1. Verify `backend/src/services/notification.service.ts` exists (from Story 2.5)
1766
- 2. Implement `notifyNewStargazer(username: string)` function:
1767
- - Check `ENABLE_TTS` env variable
1768
- - Check current time against `TTS_QUIET_HOURS` (e.g., "22:00-08:00")
1769
- - If within quiet hours, skip notification
1770
- - Construct message: `"New stargazer: ${username}"`
1771
- - Execute TTS script: `exec(process.env.TTS_SCRIPT_PATH + ' "' + message + '"')`
1772
- - Catch errors, log to console, don't crash app
1773
- 3. Implement `notifySyncComplete(newCount: number)` function:
1774
- - Message: `"Stargazer sync complete. ${newCount} new stargazers."`
1775
- - Same TTS logic as above
1776
- 4. Implement quiet hours logic:
1777
- - Parse `TTS_QUIET_HOURS` env var (format: "HH:MM-HH:MM")
1778
- - Get current time, check if within range
1779
- - Return true if quiet, false otherwise
1780
- 5. Add env variables to `.env.example`:
1781
- - `ENABLE_TTS=true`
1782
- - `TTS_QUIET_HOURS=22:00-08:00`
1783
- - `TTS_SCRIPT_PATH=/home/fire/claude/AgentVibes/.claude/hooks/play-tts.sh`
1784
- 6. Add Settings screen toggle:
1785
- - "Enable TTS Notifications"
1786
- - Quiet hours time range picker
1787
- 7. Unit tests with mocked exec
1788
- 8. Manual test: Trigger sync, verify TTS plays (if enabled)
1789
- 9. All code follows AI standards
1790
-
1791
- ### Story 7.4: Comprehensive Logging
1792
-
1793
- **As a** developer,
1794
- **I want** structured logging for all operations (API requests, sync jobs, emails),
1795
- **so that** I can debug issues and monitor system health.
1796
-
1797
- **Acceptance Criteria**:
1798
- 1. Install winston logger: `npm install winston`
1799
- 2. Create `backend/src/utils/logger.ts`
1800
- 3. Configure Winston logger:
1801
- - Transports: Console (dev), File (production: `logs/app.log`)
1802
- - Format: JSON with timestamp, level, message, metadata
1803
- - Log levels: error, warn, info, debug
1804
- 4. Add request logging middleware:
1805
- - Log all incoming requests: method, path, IP, user agent
1806
- - Log response: status code, duration
1807
- 5. Add error logging middleware:
1808
- - Log all errors with stack traces
1809
- - Include request context (method, path, body)
1810
- 6. Update all services to use logger:
1811
- - github.service: Log API calls, rate limit status
1812
- - sync.service: Log sync start/end, new stargazers count
1813
- - email.service: Log email sends, failures
1814
- - spacemail.service: Log API calls, rate limit hits
1815
- 7. Add log rotation (winston-daily-rotate-file):
1816
- - Max file size: 20MB
1817
- - Max files: 14 days
1818
- - Compress old logs
1819
- 8. Add GET /api/logs endpoint (admin only):
1820
- - Return last 100 log entries
1821
- - Filter by level (error, warn, info)
1822
- - Search by keyword
1823
- 9. Create `frontend/src/pages/LogsPage.tsx`:
1824
- - Display logs in table
1825
- - Color-code by level (error=red, warn=yellow)
1826
- - Real-time updates (poll every 5 seconds)
1827
- 10. All code follows AI standards
1828
-
1829
- ### Story 7.5: Health Monitoring Dashboard
1830
-
1831
- **As a** user,
1832
- **I want** a dashboard showing system health and key metrics,
1833
- **so that** I can monitor the application at a glance.
1834
-
1835
- **Acceptance Criteria**:
1836
- 1. Create `frontend/src/pages/DashboardPage.tsx` (<150 lines)
1837
- 2. Implement GET /api/health/full endpoint:
1838
- - Database: connection status, query time
1839
- - GitHub API: token valid, rate limit remaining
1840
- - SpaceMail API: credentials valid, rate limit remaining
1841
- - Disk space: backups folder size, available space
1842
- - Cron jobs: last run times, statuses
1843
- - Return: `{services: {database, github, spacemail, disk, cron}}`
1844
- 3. Dashboard layout (Chakra UI Grid):
1845
- - Row 1: Service status cards (4 columns)
1846
- - Database (green=connected, red=down)
1847
- - GitHub API (green=ok, yellow=rate limited)
1848
- - SpaceMail API (green=ok, red=invalid)
1849
- - Disk Space (green=>1GB, yellow=<1GB, red=<100MB)
1850
- - Row 2: Quick stats (4 columns)
1851
- - Total Stargazers
1852
- - Contacted (%)
1853
- - Emails Sent (last 7 days)
1854
- - Last Sync (time ago)
1855
- - Row 3: Recent activity timeline (full width)
1856
- - Last 10 events: sync completed, email sent, stargazer added
1857
- 4. Add "Refresh" button to refetch health data
1858
- 5. Auto-refresh every 30 seconds
1859
- 6. Show alerts for unhealthy services:
1860
- - Red banner at top: "Database connection failed"
1861
- - Action button: "View Logs" or "Restart Service"
1862
- 7. Add link to Dashboard in sidebar (make it default home page)
1863
- 8. All code follows AI standards (<150 lines)
1864
-
1865
- ---
1866
-
1867
- ## Checklist Results Report
1868
-
1869
- *(Will be populated after running `pm-checklist` validation)*
1870
-
1871
- ---
1872
-
1873
- ## Next Steps
1874
-
1875
- ### UX Expert Prompt
1876
-
1877
- "Please review the Stargazer CMS PRD (`docs/stargazer-cms-prd.md`) and create a UX architecture document that details:
1878
-
1879
- 1. Complete user flow diagrams for primary workflows (sync → view → compose → send)
1880
- 2. Detailed wireframes for each screen (Stargazers table, Profile modal, Email composer, Map, Settings)
1881
- 3. Chakra UI component specifications and design tokens
1882
- 4. Accessibility checklist ensuring WCAG AA compliance
1883
- 5. Responsive breakpoints and mobile considerations
1884
-
1885
- Focus on creating an efficient, professional CMS interface optimized for desktop usage with local deployment."
1886
-
1887
- ### Architect Prompt
1888
-
1889
- "Please review the Stargazer CMS PRD (`docs/stargazer-cms-prd.md`) and create a comprehensive architecture document that specifies:
1890
-
1891
- 1. **System Architecture Diagram**: Docker services, network topology, data flow
1892
- 2. **Database Schema**: Detailed Prisma schema with indexes, constraints, relationships
1893
- 3. **API Specification**: Complete OpenAPI/Swagger documentation for all endpoints
1894
- 4. **Component Architecture**: Frontend component hierarchy, state management, routing
1895
- 5. **Infrastructure Setup**: Docker Compose configuration, environment variables, volume mappings
1896
- 6. **Code Quality Configuration**: SonarQube rules, ESLint config, TypeScript strict settings, pre-commit hooks
1897
- 7. **Testing Strategy**: Unit, integration, E2E test structure and tooling
1898
- 8. **Security Architecture**: Authentication, input validation, API key management
1899
- 9. **Deployment Guide**: Local setup instructions, backup/restore procedures, troubleshooting
1900
-
1901
- Ensure all code follows AI-optimized documentation standards defined in `/home/fire/claude/AgentVibes/docs/ai-optimized-documentation-standards.md`. All components must adhere to single-responsibility principle with max 200 lines per file and max 50 lines per function."
1902
-
1903
- ---
1904
-
1905
- ## Document Information
1906
-
1907
- **AgentVibes Stargazer CMS - Product Requirements Document**
1908
-
1909
- - **Project**: AgentVibes Stargazer Content Management System
1910
- - **Repository**: agentvibes-stargazers (Private)
1911
- - **Co-created by**: John (PM Agent) with Paul Preibisch
1912
- - **Version**: 1.0
1913
- - **Created**: 2025-01-10
1914
- - **License**: Apache-2.0
1915
-
1916
- ---
1917
-
1918
- **DISCLAIMER**: This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND, express or implied. Use at your own risk. See the Apache License for details.