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.
- package/README.md +2 -2
- package/package.json +1 -1
- package/src/installer.js +23 -20
- package/.bmad/_cfg/agent-manifest.csv +0 -11
- package/.bmad/_cfg/agent-voice-map.csv +0 -11
- package/.bmad/_cfg/agents/bmm-analyst.customize.yaml +0 -42
- package/.bmad/_cfg/agents/bmm-architect.customize.yaml +0 -42
- package/.bmad/_cfg/agents/bmm-dev.customize.yaml +0 -42
- package/.bmad/_cfg/agents/bmm-frame-expert.customize.yaml +0 -42
- package/.bmad/_cfg/agents/bmm-pm.customize.yaml +0 -42
- package/.bmad/_cfg/agents/bmm-sm.customize.yaml +0 -42
- package/.bmad/_cfg/agents/bmm-tea.customize.yaml +0 -42
- package/.bmad/_cfg/agents/bmm-tech-writer.customize.yaml +0 -42
- package/.bmad/_cfg/agents/bmm-ux-designer.customize.yaml +0 -42
- package/.bmad/_cfg/agents/core-bmad-master.customize.yaml +0 -42
- package/.bmad/_cfg/files-manifest.csv +0 -243
- package/.bmad/_cfg/ides/claude-code.yaml +0 -6
- package/.bmad/_cfg/manifest.yaml +0 -9
- package/.bmad/_cfg/task-manifest.csv +0 -5
- package/.bmad/_cfg/tool-manifest.csv +0 -2
- package/.bmad/_cfg/workflow-manifest.csv +0 -38
- package/.bmad/bmm/README.md +0 -128
- package/.bmad/bmm/agents/analyst.md +0 -79
- package/.bmad/bmm/agents/analyst.md.backup-pre-tts +0 -75
- package/.bmad/bmm/agents/architect.md +0 -80
- package/.bmad/bmm/agents/dev.md +0 -70
- package/.bmad/bmm/agents/frame-expert.md +0 -72
- package/.bmad/bmm/agents/pm.md +0 -84
- package/.bmad/bmm/agents/sm.md +0 -93
- package/.bmad/bmm/agents/tea.md +0 -80
- package/.bmad/bmm/agents/tech-writer.md +0 -84
- package/.bmad/bmm/agents/ux-designer.md +0 -79
- package/.bmad/bmm/config.yaml +0 -17
- package/.bmad/bmm/docs/README.md +0 -236
- package/.bmad/bmm/docs/agents-guide.md +0 -1058
- package/.bmad/bmm/docs/brownfield-guide.md +0 -762
- package/.bmad/bmm/docs/enterprise-agentic-development.md +0 -686
- package/.bmad/bmm/docs/faq.md +0 -588
- package/.bmad/bmm/docs/glossary.md +0 -320
- package/.bmad/bmm/docs/party-mode.md +0 -224
- package/.bmad/bmm/docs/quick-spec-flow.md +0 -652
- package/.bmad/bmm/docs/quick-start.md +0 -376
- package/.bmad/bmm/docs/scale-adaptive-system.md +0 -612
- package/.bmad/bmm/docs/test-architecture.md +0 -396
- package/.bmad/bmm/docs/workflow-architecture-reference.md +0 -366
- package/.bmad/bmm/docs/workflow-document-project-reference.md +0 -489
- package/.bmad/bmm/docs/workflows-analysis.md +0 -370
- package/.bmad/bmm/docs/workflows-implementation.md +0 -286
- package/.bmad/bmm/docs/workflows-planning.md +0 -612
- package/.bmad/bmm/docs/workflows-solutioning.md +0 -554
- package/.bmad/bmm/teams/default-party.csv +0 -20
- package/.bmad/bmm/teams/team-fullstack.yaml +0 -13
- package/.bmad/bmm/testarch/knowledge/ci-burn-in.md +0 -675
- package/.bmad/bmm/testarch/knowledge/component-tdd.md +0 -486
- package/.bmad/bmm/testarch/knowledge/contract-testing.md +0 -957
- package/.bmad/bmm/testarch/knowledge/data-factories.md +0 -500
- package/.bmad/bmm/testarch/knowledge/email-auth.md +0 -721
- package/.bmad/bmm/testarch/knowledge/error-handling.md +0 -725
- package/.bmad/bmm/testarch/knowledge/feature-flags.md +0 -750
- package/.bmad/bmm/testarch/knowledge/fixture-architecture.md +0 -401
- package/.bmad/bmm/testarch/knowledge/network-first.md +0 -486
- package/.bmad/bmm/testarch/knowledge/nfr-criteria.md +0 -670
- package/.bmad/bmm/testarch/knowledge/playwright-config.md +0 -730
- package/.bmad/bmm/testarch/knowledge/probability-impact.md +0 -601
- package/.bmad/bmm/testarch/knowledge/risk-governance.md +0 -615
- package/.bmad/bmm/testarch/knowledge/selective-testing.md +0 -732
- package/.bmad/bmm/testarch/knowledge/selector-resilience.md +0 -527
- package/.bmad/bmm/testarch/knowledge/test-healing-patterns.md +0 -644
- package/.bmad/bmm/testarch/knowledge/test-levels-framework.md +0 -473
- package/.bmad/bmm/testarch/knowledge/test-priorities-matrix.md +0 -373
- package/.bmad/bmm/testarch/knowledge/test-quality.md +0 -664
- package/.bmad/bmm/testarch/knowledge/timing-debugging.md +0 -372
- package/.bmad/bmm/testarch/knowledge/visual-debugging.md +0 -524
- package/.bmad/bmm/testarch/tea-index.csv +0 -22
- package/.bmad/bmm/workflows/1-analysis/brainstorm-project/instructions.md +0 -112
- package/.bmad/bmm/workflows/1-analysis/brainstorm-project/project-context.md +0 -25
- package/.bmad/bmm/workflows/1-analysis/brainstorm-project/workflow.yaml +0 -26
- package/.bmad/bmm/workflows/1-analysis/domain-research/instructions.md +0 -425
- package/.bmad/bmm/workflows/1-analysis/domain-research/template.md +0 -180
- package/.bmad/bmm/workflows/1-analysis/domain-research/workflow.yaml +0 -28
- package/.bmad/bmm/workflows/1-analysis/product-brief/checklist.md +0 -115
- package/.bmad/bmm/workflows/1-analysis/product-brief/instructions.md +0 -524
- package/.bmad/bmm/workflows/1-analysis/product-brief/template.md +0 -181
- package/.bmad/bmm/workflows/1-analysis/product-brief/workflow.yaml +0 -45
- package/.bmad/bmm/workflows/1-analysis/research/checklist-deep-prompt.md +0 -144
- package/.bmad/bmm/workflows/1-analysis/research/checklist-technical.md +0 -249
- package/.bmad/bmm/workflows/1-analysis/research/checklist.md +0 -299
- package/.bmad/bmm/workflows/1-analysis/research/claude-code/injections.yaml +0 -114
- package/.bmad/bmm/workflows/1-analysis/research/instructions-deep-prompt.md +0 -438
- package/.bmad/bmm/workflows/1-analysis/research/instructions-market.md +0 -675
- package/.bmad/bmm/workflows/1-analysis/research/instructions-router.md +0 -134
- package/.bmad/bmm/workflows/1-analysis/research/instructions-technical.md +0 -534
- package/.bmad/bmm/workflows/1-analysis/research/template-deep-prompt.md +0 -94
- package/.bmad/bmm/workflows/1-analysis/research/template-market.md +0 -347
- package/.bmad/bmm/workflows/1-analysis/research/template-technical.md +0 -245
- package/.bmad/bmm/workflows/1-analysis/research/workflow.yaml +0 -44
- package/.bmad/bmm/workflows/2-plan-workflows/create-epics-and-stories/epics-template.md +0 -80
- package/.bmad/bmm/workflows/2-plan-workflows/create-epics-and-stories/instructions.md +0 -616
- package/.bmad/bmm/workflows/2-plan-workflows/create-epics-and-stories/workflow.yaml +0 -53
- package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/checklist.md +0 -310
- package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/instructions.md +0 -1308
- package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/ux-design-template.md +0 -145
- package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/workflow.yaml +0 -61
- package/.bmad/bmm/workflows/2-plan-workflows/prd/checklist.md +0 -346
- package/.bmad/bmm/workflows/2-plan-workflows/prd/domain-complexity.csv +0 -13
- package/.bmad/bmm/workflows/2-plan-workflows/prd/instructions.md +0 -703
- package/.bmad/bmm/workflows/2-plan-workflows/prd/prd-template.md +0 -204
- package/.bmad/bmm/workflows/2-plan-workflows/prd/project-types.csv +0 -11
- package/.bmad/bmm/workflows/2-plan-workflows/prd/workflow.yaml +0 -52
- package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/checklist.md +0 -217
- package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/epics-template.md +0 -74
- package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/instructions-generate-stories.md +0 -436
- package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/instructions.md +0 -980
- package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/tech-spec-template.md +0 -181
- package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/user-story-template.md +0 -90
- package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/workflow.yaml +0 -58
- package/.bmad/bmm/workflows/3-solutioning/architecture/architecture-patterns.yaml +0 -321
- package/.bmad/bmm/workflows/3-solutioning/architecture/architecture-template.md +0 -103
- package/.bmad/bmm/workflows/3-solutioning/architecture/checklist.md +0 -240
- package/.bmad/bmm/workflows/3-solutioning/architecture/decision-catalog.yaml +0 -222
- package/.bmad/bmm/workflows/3-solutioning/architecture/instructions.md +0 -768
- package/.bmad/bmm/workflows/3-solutioning/architecture/pattern-categories.csv +0 -13
- package/.bmad/bmm/workflows/3-solutioning/architecture/workflow.yaml +0 -55
- package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/checklist.md +0 -169
- package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/instructions.md +0 -332
- package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/template.md +0 -146
- package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/workflow.yaml +0 -62
- package/.bmad/bmm/workflows/4-implementation/code-review/backlog_template.md +0 -12
- package/.bmad/bmm/workflows/4-implementation/code-review/checklist.md +0 -22
- package/.bmad/bmm/workflows/4-implementation/code-review/instructions.md +0 -398
- package/.bmad/bmm/workflows/4-implementation/code-review/workflow.yaml +0 -60
- package/.bmad/bmm/workflows/4-implementation/correct-course/checklist.md +0 -279
- package/.bmad/bmm/workflows/4-implementation/correct-course/instructions.md +0 -206
- package/.bmad/bmm/workflows/4-implementation/correct-course/workflow.yaml +0 -56
- package/.bmad/bmm/workflows/4-implementation/create-story/checklist.md +0 -240
- package/.bmad/bmm/workflows/4-implementation/create-story/instructions.md +0 -256
- package/.bmad/bmm/workflows/4-implementation/create-story/template.md +0 -51
- package/.bmad/bmm/workflows/4-implementation/create-story/workflow.yaml +0 -71
- package/.bmad/bmm/workflows/4-implementation/dev-story/checklist.md +0 -38
- package/.bmad/bmm/workflows/4-implementation/dev-story/instructions.md +0 -267
- package/.bmad/bmm/workflows/4-implementation/dev-story/workflow.yaml +0 -56
- package/.bmad/bmm/workflows/4-implementation/epic-tech-context/checklist.md +0 -17
- package/.bmad/bmm/workflows/4-implementation/epic-tech-context/instructions.md +0 -164
- package/.bmad/bmm/workflows/4-implementation/epic-tech-context/template.md +0 -76
- package/.bmad/bmm/workflows/4-implementation/epic-tech-context/workflow.yaml +0 -57
- package/.bmad/bmm/workflows/4-implementation/retrospective/instructions.md +0 -1443
- package/.bmad/bmm/workflows/4-implementation/retrospective/workflow.yaml +0 -56
- package/.bmad/bmm/workflows/4-implementation/sprint-planning/checklist.md +0 -33
- package/.bmad/bmm/workflows/4-implementation/sprint-planning/instructions.md +0 -234
- package/.bmad/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +0 -55
- package/.bmad/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +0 -49
- package/.bmad/bmm/workflows/4-implementation/story-context/checklist.md +0 -16
- package/.bmad/bmm/workflows/4-implementation/story-context/context-template.xml +0 -34
- package/.bmad/bmm/workflows/4-implementation/story-context/instructions.md +0 -209
- package/.bmad/bmm/workflows/4-implementation/story-context/workflow.yaml +0 -61
- package/.bmad/bmm/workflows/4-implementation/story-done/instructions.md +0 -111
- package/.bmad/bmm/workflows/4-implementation/story-done/workflow.yaml +0 -26
- package/.bmad/bmm/workflows/4-implementation/story-ready/instructions.md +0 -117
- package/.bmad/bmm/workflows/4-implementation/story-ready/workflow.yaml +0 -23
- package/.bmad/bmm/workflows/document-project/checklist.md +0 -245
- package/.bmad/bmm/workflows/document-project/documentation-requirements.csv +0 -12
- package/.bmad/bmm/workflows/document-project/instructions.md +0 -222
- package/.bmad/bmm/workflows/document-project/templates/deep-dive-template.md +0 -345
- package/.bmad/bmm/workflows/document-project/templates/index-template.md +0 -169
- package/.bmad/bmm/workflows/document-project/templates/project-overview-template.md +0 -103
- package/.bmad/bmm/workflows/document-project/templates/project-scan-report-schema.json +0 -160
- package/.bmad/bmm/workflows/document-project/templates/source-tree-template.md +0 -135
- package/.bmad/bmm/workflows/document-project/workflow.yaml +0 -29
- package/.bmad/bmm/workflows/document-project/workflows/deep-dive-instructions.md +0 -298
- package/.bmad/bmm/workflows/document-project/workflows/deep-dive.yaml +0 -31
- package/.bmad/bmm/workflows/document-project/workflows/full-scan-instructions.md +0 -1106
- package/.bmad/bmm/workflows/document-project/workflows/full-scan.yaml +0 -31
- package/.bmad/bmm/workflows/frame-expert/_shared/excalidraw-helpers.md +0 -127
- package/.bmad/bmm/workflows/frame-expert/_shared/excalidraw-library.json +0 -90
- package/.bmad/bmm/workflows/frame-expert/_shared/excalidraw-templates.yaml +0 -127
- package/.bmad/bmm/workflows/frame-expert/_shared/validate-json-instructions.md +0 -79
- package/.bmad/bmm/workflows/frame-expert/create-dataflow/checklist.md +0 -39
- package/.bmad/bmm/workflows/frame-expert/create-dataflow/instructions.md +0 -131
- package/.bmad/bmm/workflows/frame-expert/create-dataflow/workflow.yaml +0 -23
- package/.bmad/bmm/workflows/frame-expert/create-diagram/checklist.md +0 -43
- package/.bmad/bmm/workflows/frame-expert/create-diagram/instructions.md +0 -142
- package/.bmad/bmm/workflows/frame-expert/create-diagram/workflow.yaml +0 -24
- package/.bmad/bmm/workflows/frame-expert/create-flowchart/checklist.md +0 -49
- package/.bmad/bmm/workflows/frame-expert/create-flowchart/instructions.md +0 -242
- package/.bmad/bmm/workflows/frame-expert/create-flowchart/workflow.yaml +0 -27
- package/.bmad/bmm/workflows/frame-expert/create-wireframe/checklist.md +0 -38
- package/.bmad/bmm/workflows/frame-expert/create-wireframe/instructions.md +0 -133
- package/.bmad/bmm/workflows/frame-expert/create-wireframe/workflow.yaml +0 -23
- package/.bmad/bmm/workflows/techdoc/documentation-standards.md +0 -262
- package/.bmad/bmm/workflows/testarch/atdd/atdd-checklist-template.md +0 -363
- package/.bmad/bmm/workflows/testarch/atdd/checklist.md +0 -373
- package/.bmad/bmm/workflows/testarch/atdd/instructions.md +0 -785
- package/.bmad/bmm/workflows/testarch/atdd/workflow.yaml +0 -45
- package/.bmad/bmm/workflows/testarch/automate/checklist.md +0 -580
- package/.bmad/bmm/workflows/testarch/automate/instructions.md +0 -1303
- package/.bmad/bmm/workflows/testarch/automate/workflow.yaml +0 -52
- package/.bmad/bmm/workflows/testarch/ci/checklist.md +0 -246
- package/.bmad/bmm/workflows/testarch/ci/github-actions-template.yaml +0 -165
- package/.bmad/bmm/workflows/testarch/ci/gitlab-ci-template.yaml +0 -128
- package/.bmad/bmm/workflows/testarch/ci/instructions.md +0 -517
- package/.bmad/bmm/workflows/testarch/ci/workflow.yaml +0 -45
- package/.bmad/bmm/workflows/testarch/framework/checklist.md +0 -321
- package/.bmad/bmm/workflows/testarch/framework/instructions.md +0 -455
- package/.bmad/bmm/workflows/testarch/framework/workflow.yaml +0 -47
- package/.bmad/bmm/workflows/testarch/nfr-assess/checklist.md +0 -405
- package/.bmad/bmm/workflows/testarch/nfr-assess/instructions.md +0 -722
- package/.bmad/bmm/workflows/testarch/nfr-assess/nfr-report-template.md +0 -443
- package/.bmad/bmm/workflows/testarch/nfr-assess/workflow.yaml +0 -47
- package/.bmad/bmm/workflows/testarch/test-design/checklist.md +0 -234
- package/.bmad/bmm/workflows/testarch/test-design/instructions.md +0 -782
- package/.bmad/bmm/workflows/testarch/test-design/test-design-template.md +0 -285
- package/.bmad/bmm/workflows/testarch/test-design/workflow.yaml +0 -48
- package/.bmad/bmm/workflows/testarch/test-review/checklist.md +0 -470
- package/.bmad/bmm/workflows/testarch/test-review/instructions.md +0 -608
- package/.bmad/bmm/workflows/testarch/test-review/test-review-template.md +0 -388
- package/.bmad/bmm/workflows/testarch/test-review/workflow.yaml +0 -46
- package/.bmad/bmm/workflows/testarch/trace/checklist.md +0 -654
- package/.bmad/bmm/workflows/testarch/trace/instructions.md +0 -1045
- package/.bmad/bmm/workflows/testarch/trace/trace-template.md +0 -673
- package/.bmad/bmm/workflows/testarch/trace/workflow.yaml +0 -55
- package/.bmad/bmm/workflows/workflow-status/init/instructions.md +0 -334
- package/.bmad/bmm/workflows/workflow-status/init/workflow.yaml +0 -28
- package/.bmad/bmm/workflows/workflow-status/instructions.md +0 -388
- package/.bmad/bmm/workflows/workflow-status/paths/enterprise-brownfield.yaml +0 -138
- package/.bmad/bmm/workflows/workflow-status/paths/enterprise-greenfield.yaml +0 -126
- package/.bmad/bmm/workflows/workflow-status/paths/game-design.yaml +0 -52
- package/.bmad/bmm/workflows/workflow-status/paths/method-brownfield.yaml +0 -122
- package/.bmad/bmm/workflows/workflow-status/paths/method-greenfield.yaml +0 -113
- package/.bmad/bmm/workflows/workflow-status/paths/quick-flow-brownfield.yaml +0 -58
- package/.bmad/bmm/workflows/workflow-status/paths/quick-flow-greenfield.yaml +0 -47
- package/.bmad/bmm/workflows/workflow-status/project-levels.yaml +0 -59
- package/.bmad/bmm/workflows/workflow-status/workflow-status-template.yaml +0 -24
- package/.bmad/bmm/workflows/workflow-status/workflow.yaml +0 -28
- package/.bmad/core/agents/bmad-master.md +0 -72
- package/.bmad/core/agents/bmad-web-orchestrator.agent.xml +0 -113
- package/.bmad/core/config.yaml +0 -11
- package/.bmad/core/tasks/adv-elicit-methods.csv +0 -39
- package/.bmad/core/tasks/advanced-elicitation-methods.csv +0 -21
- package/.bmad/core/tasks/advanced-elicitation.xml +0 -106
- package/.bmad/core/tasks/index-docs.xml +0 -65
- package/.bmad/core/tasks/validate-workflow.xml +0 -89
- package/.bmad/core/tasks/workflow.xml +0 -270
- package/.bmad/core/tools/shard-doc.xml +0 -109
- package/.bmad/core/workflows/brainstorming/README.md +0 -261
- package/.bmad/core/workflows/brainstorming/brain-methods.csv +0 -36
- package/.bmad/core/workflows/brainstorming/instructions.md +0 -315
- package/.bmad/core/workflows/brainstorming/template.md +0 -106
- package/.bmad/core/workflows/brainstorming/workflow.yaml +0 -38
- package/.bmad/core/workflows/party-mode/instructions.md +0 -203
- package/.bmad/core/workflows/party-mode/workflow.yaml +0 -28
- package/.bmad/docs/claude-code-instructions.md +0 -25
- package/.claude/commands/BMad/analyst.md +0 -88
- package/.claude/commands/BMad/architect.md +0 -89
- package/.claude/commands/BMad/bmad-master.md +0 -114
- package/.claude/commands/BMad/bmad-orchestrator.md +0 -151
- package/.claude/commands/BMad/dev.md +0 -85
- package/.claude/commands/BMad/pm.md +0 -88
- package/.claude/commands/BMad/po.md +0 -83
- package/.claude/commands/BMad/qa.md +0 -91
- package/.claude/commands/BMad/sm.md +0 -69
- package/.claude/commands/BMad/tasks/advanced-elicitation.md +0 -123
- package/.claude/commands/BMad/tasks/apply-qa-fixes.md +0 -154
- package/.claude/commands/BMad/tasks/brownfield-create-epic.md +0 -166
- package/.claude/commands/BMad/tasks/brownfield-create-story.md +0 -153
- package/.claude/commands/BMad/tasks/correct-course.md +0 -76
- package/.claude/commands/BMad/tasks/create-brownfield-story.md +0 -318
- package/.claude/commands/BMad/tasks/create-deep-research-prompt.md +0 -284
- package/.claude/commands/BMad/tasks/create-doc.md +0 -107
- package/.claude/commands/BMad/tasks/create-next-story.md +0 -118
- package/.claude/commands/BMad/tasks/document-project.md +0 -349
- package/.claude/commands/BMad/tasks/execute-checklist.md +0 -92
- package/.claude/commands/BMad/tasks/facilitate-brainstorming-session.md +0 -142
- package/.claude/commands/BMad/tasks/generate-ai-frontend-prompt.md +0 -57
- package/.claude/commands/BMad/tasks/index-docs.md +0 -179
- package/.claude/commands/BMad/tasks/kb-mode-interaction.md +0 -81
- package/.claude/commands/BMad/tasks/nfr-assess.md +0 -349
- package/.claude/commands/BMad/tasks/qa-gate.md +0 -167
- package/.claude/commands/BMad/tasks/review-story.md +0 -320
- package/.claude/commands/BMad/tasks/risk-profile.md +0 -359
- package/.claude/commands/BMad/tasks/shard-doc.md +0 -191
- package/.claude/commands/BMad/tasks/test-design.md +0 -180
- package/.claude/commands/BMad/tasks/trace-requirements.md +0 -270
- package/.claude/commands/BMad/tasks/validate-next-story.md +0 -140
- package/.claude/commands/BMad/ux-expert.md +0 -73
- package/.claude/commands/bmad/bmm/agents/analyst.md +0 -14
- package/.claude/commands/bmad/bmm/agents/architect.md +0 -14
- package/.claude/commands/bmad/bmm/agents/dev.md +0 -14
- package/.claude/commands/bmad/bmm/agents/frame-expert.md +0 -14
- package/.claude/commands/bmad/bmm/agents/pm.md +0 -14
- package/.claude/commands/bmad/bmm/agents/sm.md +0 -14
- package/.claude/commands/bmad/bmm/agents/tea.md +0 -14
- package/.claude/commands/bmad/bmm/agents/tech-writer.md +0 -14
- package/.claude/commands/bmad/bmm/agents/ux-designer.md +0 -14
- package/.claude/commands/bmad/bmm/workflows/architecture.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/brainstorm-project.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/code-review.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/correct-course.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/create-dataflow.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/create-diagram.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/create-epics-and-stories.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/create-flowchart.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/create-story.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/create-ux-design.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/create-wireframe.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/dev-story.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/document-project.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/domain-research.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/epic-tech-context.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/implementation-readiness.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/prd.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/product-brief.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/research.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/retrospective.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/sprint-planning.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/story-context.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/story-done.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/story-ready.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/tech-spec.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/workflow-init.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/workflow-status.md +0 -13
- package/.claude/commands/bmad/core/agents/bmad-master.md +0 -14
- package/.claude/commands/bmad/core/tasks/advanced-elicitation.md +0 -9
- package/.claude/commands/bmad/core/tasks/index-docs.md +0 -9
- package/.claude/commands/bmad/core/tools/shard-doc.md +0 -9
- package/.claude/commands/bmad/core/workflows/brainstorming.md +0 -13
- package/.claude/commands/bmad/core/workflows/party-mode.md +0 -13
- package/.claude/github-star-reminder.txt +0 -1
- package/.claude/hooks/bmad-party-manager.sh +0 -225
- package/.claude/hooks/stop.sh +0 -221
- package/.claude/piper-voices-dir.txt +0 -1
- package/.mcp.json +0 -88
- package/RELEASE_NOTES_v2.4.0_DRAFT.md +0 -116
- package/RELEASE_NOTES_v2.4.1_DRAFT.md +0 -61
- package/docs/2025-11-15_15-14-33.snagx +0 -0
- package/docs/Screenshot 2025-11-15 151325.png +0 -0
- package/docs/Screenshot 2025-11-15 151432.png +0 -0
- package/docs/macos-piper-issue.md +0 -172
- package/docs/stargazer-cms-prd.md +0 -1918
- package/docs/whatsapp-plugin-github-issue.md +0 -393
- package/docs/whatsapp-tts-plugin-feasibility.md +0 -418
- package/docs/whatsapp-tts-standalone-plugin.md +0 -628
- package/github-profile-draft.md +0 -57
- package/linkedin/vibe-coding-and-pulseaudio.md +0 -121
- package/mcp-server/agentvibes.db +0 -0
- package/scripts/audio-tunnel.config +0 -17
- package/v4-backup/.bmad-core/agent-teams/team-all.yaml +0 -15
- package/v4-backup/.bmad-core/agent-teams/team-fullstack.yaml +0 -19
- package/v4-backup/.bmad-core/agent-teams/team-ide-minimal.yaml +0 -11
- package/v4-backup/.bmad-core/agent-teams/team-no-ui.yaml +0 -14
- package/v4-backup/.bmad-core/agents/analyst.md +0 -84
- package/v4-backup/.bmad-core/agents/architect.md +0 -85
- package/v4-backup/.bmad-core/agents/bmad-master.md +0 -110
- package/v4-backup/.bmad-core/agents/bmad-orchestrator.md +0 -147
- package/v4-backup/.bmad-core/agents/dev.md +0 -81
- package/v4-backup/.bmad-core/agents/pm.md +0 -84
- package/v4-backup/.bmad-core/agents/po.md +0 -79
- package/v4-backup/.bmad-core/agents/qa.md +0 -87
- package/v4-backup/.bmad-core/agents/sm.md +0 -65
- package/v4-backup/.bmad-core/agents/ux-expert.md +0 -69
- package/v4-backup/.bmad-core/checklists/architect-checklist.md +0 -440
- package/v4-backup/.bmad-core/checklists/change-checklist.md +0 -184
- package/v4-backup/.bmad-core/checklists/pm-checklist.md +0 -372
- package/v4-backup/.bmad-core/checklists/po-master-checklist.md +0 -434
- package/v4-backup/.bmad-core/checklists/story-dod-checklist.md +0 -96
- package/v4-backup/.bmad-core/checklists/story-draft-checklist.md +0 -155
- package/v4-backup/.bmad-core/core-config.yaml +0 -22
- package/v4-backup/.bmad-core/data/bmad-kb.md +0 -809
- package/v4-backup/.bmad-core/data/brainstorming-techniques.md +0 -38
- package/v4-backup/.bmad-core/data/elicitation-methods.md +0 -156
- package/v4-backup/.bmad-core/data/technical-preferences.md +0 -5
- package/v4-backup/.bmad-core/data/test-levels-framework.md +0 -148
- package/v4-backup/.bmad-core/data/test-priorities-matrix.md +0 -174
- package/v4-backup/.bmad-core/enhanced-ide-development-workflow.md +0 -248
- package/v4-backup/.bmad-core/install-manifest.yaml +0 -230
- package/v4-backup/.bmad-core/tasks/advanced-elicitation.md +0 -119
- package/v4-backup/.bmad-core/tasks/apply-qa-fixes.md +0 -150
- package/v4-backup/.bmad-core/tasks/brownfield-create-epic.md +0 -162
- package/v4-backup/.bmad-core/tasks/brownfield-create-story.md +0 -149
- package/v4-backup/.bmad-core/tasks/correct-course.md +0 -72
- package/v4-backup/.bmad-core/tasks/create-brownfield-story.md +0 -314
- package/v4-backup/.bmad-core/tasks/create-deep-research-prompt.md +0 -280
- package/v4-backup/.bmad-core/tasks/create-doc.md +0 -103
- package/v4-backup/.bmad-core/tasks/create-next-story.md +0 -114
- package/v4-backup/.bmad-core/tasks/document-project.md +0 -345
- package/v4-backup/.bmad-core/tasks/execute-checklist.md +0 -88
- package/v4-backup/.bmad-core/tasks/facilitate-brainstorming-session.md +0 -138
- package/v4-backup/.bmad-core/tasks/generate-ai-frontend-prompt.md +0 -53
- package/v4-backup/.bmad-core/tasks/index-docs.md +0 -175
- package/v4-backup/.bmad-core/tasks/kb-mode-interaction.md +0 -77
- package/v4-backup/.bmad-core/tasks/nfr-assess.md +0 -345
- package/v4-backup/.bmad-core/tasks/qa-gate.md +0 -163
- package/v4-backup/.bmad-core/tasks/review-story.md +0 -316
- package/v4-backup/.bmad-core/tasks/risk-profile.md +0 -355
- package/v4-backup/.bmad-core/tasks/shard-doc.md +0 -187
- package/v4-backup/.bmad-core/tasks/test-design.md +0 -176
- package/v4-backup/.bmad-core/tasks/trace-requirements.md +0 -266
- package/v4-backup/.bmad-core/tasks/validate-next-story.md +0 -136
- package/v4-backup/.bmad-core/templates/architecture-tmpl.yaml +0 -651
- package/v4-backup/.bmad-core/templates/brainstorming-output-tmpl.yaml +0 -156
- package/v4-backup/.bmad-core/templates/brownfield-architecture-tmpl.yaml +0 -477
- package/v4-backup/.bmad-core/templates/brownfield-prd-tmpl.yaml +0 -281
- package/v4-backup/.bmad-core/templates/competitor-analysis-tmpl.yaml +0 -307
- package/v4-backup/.bmad-core/templates/front-end-architecture-tmpl.yaml +0 -219
- package/v4-backup/.bmad-core/templates/front-end-spec-tmpl.yaml +0 -350
- package/v4-backup/.bmad-core/templates/fullstack-architecture-tmpl.yaml +0 -824
- package/v4-backup/.bmad-core/templates/market-research-tmpl.yaml +0 -253
- package/v4-backup/.bmad-core/templates/prd-tmpl.yaml +0 -203
- package/v4-backup/.bmad-core/templates/project-brief-tmpl.yaml +0 -222
- package/v4-backup/.bmad-core/templates/qa-gate-tmpl.yaml +0 -103
- package/v4-backup/.bmad-core/templates/story-tmpl.yaml +0 -138
- package/v4-backup/.bmad-core/user-guide.md +0 -577
- package/v4-backup/.bmad-core/utils/bmad-doc-template.md +0 -327
- package/v4-backup/.bmad-core/utils/workflow-management.md +0 -71
- package/v4-backup/.bmad-core/workflows/brownfield-fullstack.yaml +0 -298
- package/v4-backup/.bmad-core/workflows/brownfield-service.yaml +0 -188
- package/v4-backup/.bmad-core/workflows/brownfield-ui.yaml +0 -198
- package/v4-backup/.bmad-core/workflows/greenfield-fullstack.yaml +0 -241
- package/v4-backup/.bmad-core/workflows/greenfield-service.yaml +0 -207
- package/v4-backup/.bmad-core/workflows/greenfield-ui.yaml +0 -236
- 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.
|