diff --git a/src/modules/bmm/workflows/4-implementation/retrospective/instructions.md b/src/modules/bmm/workflows/4-implementation/retrospective/instructions.md index 01750312..103c55d3 100644 --- a/src/modules/bmm/workflows/4-implementation/retrospective/instructions.md +++ b/src/modules/bmm/workflows/4-implementation/retrospective/instructions.md @@ -1300,7 +1300,67 @@ Bob (Scrum Master): "See you all when prep work is done. Meeting adjourned!" - + +Check bugs.yaml for bugs/features linked to this epic and close them + +Load {bugs_yaml} if it exists + + + Search for entries with related_epic matching {{epic_number}} + + For bugs section - find bugs with related_epic == {{epic_number}} AND status in ["fixed", "triaged", "routed"]: + + For each matching bug: + - Move entry from "bugs" section to "closed_bugs" section + - Update status: → "closed" + - Set verified_by: "retrospective-workflow" + - Set verified_date: {date} + - Append to notes: "Auto-closed via epic retrospective. Epic {{epic_number}} completed on {date}." + + + For feature_requests section - find features with related_epic == {{epic_number}} AND status in ["implemented", "backlog", "in-progress"]: + + For each matching feature: + - Move entry from "feature_requests" section to "implemented_features" section + - Update status: → "complete" + - Set completed_by: "retrospective-workflow" + - Set completed_date: {date} + - Append to notes: "Auto-closed via epic retrospective. Epic {{epic_number}} completed on {date}." + + + Update statistics section with new counts + Save updated bugs.yaml + + + Also update bugs.md: + - Remove [IMPLEMENTED] tag from closed items + - Move bug entries to "# Fixed Bugs" section if not already there + - Move feature entries to "# Implemented Features" section if not already there + - Add [CLOSED] or [COMPLETE] tag to indicate final status + Save updated bugs.md + + + +Bug/Feature Closure: +{{#if bugs_closed}} +- Bugs closed for Epic {{epic_number}}: {{bugs_closed_list}} +{{/if}} +{{#if features_completed}} +- Features completed for Epic {{epic_number}}: {{features_completed_list}} +{{/if}} +{{#if no_matches}} +- No outstanding bugs/features linked to Epic {{epic_number}} +{{/if}} + + + + + Skip bug tracking sync - no bugs.yaml file present + + + + + Ensure retrospectives folder exists: {retrospectives_folder} Create folder if it doesn't exist @@ -1356,7 +1416,7 @@ Retrospective document was saved successfully, but {sprint_status_file} may need - + **✅ Retrospective Complete, {user_name}!** diff --git a/src/modules/bmm/workflows/4-implementation/retrospective/workflow.yaml b/src/modules/bmm/workflows/4-implementation/retrospective/workflow.yaml index 80d934b2..68c8dd59 100644 --- a/src/modules/bmm/workflows/4-implementation/retrospective/workflow.yaml +++ b/src/modules/bmm/workflows/4-implementation/retrospective/workflow.yaml @@ -54,5 +54,9 @@ sprint_status_file: "{implementation_artifacts}/sprint-status.yaml" story_directory: "{implementation_artifacts}" retrospectives_folder: "{implementation_artifacts}" +# Bug tracking integration (optional) +bugs_yaml: "{planning_artifacts}/bugs.yaml" +bugs_md: "{planning_artifacts}/bugs.md" + standalone: true web_bundle: false diff --git a/src/modules/bmm/workflows/4-implementation/sprint-planning/instructions.md b/src/modules/bmm/workflows/4-implementation/sprint-planning/instructions.md index c4f4bd42..0ebe9e9c 100644 --- a/src/modules/bmm/workflows/4-implementation/sprint-planning/instructions.md +++ b/src/modules/bmm/workflows/4-implementation/sprint-planning/instructions.md @@ -48,6 +48,26 @@ After discovery, these content variables are available: {epics_content} (all epics loaded - uses FULL_LOAD strategy) + +Check if {bugs_yaml} exists in {planning_artifacts} + + Read bugs.yaml using grep to find all bug-NNN and feature-NNN entries + For each bug/feature, extract: + - ID (e.g., bug-001, feature-003) + - Title + - Status (triaged, routed, in-progress, fixed/implemented, verified, closed) + - Recommended workflow (direct-fix, tech-spec, correct-course, backlog) + - Related stories (sprint_stories field for features) + + Build bug/feature inventory for inclusion in sprint status + Track feature-to-story mappings (feature-001 → stories 7-1, 7-2, etc.) + + + Note: No bugs.yaml found - bug tracking not enabled for this project. + Continue without bug integration + + + For each epic found, create entries in this order: @@ -65,6 +85,17 @@ development_status: epic-1-retrospective: optional ``` +If bugs.yaml was loaded, add bug/feature sources header comment: + +```yaml +# STORY SOURCES: +# ============== +# - epics.md: Primary source ({story_count} stories) +# - bugs.yaml: Feature-driven stories ({feature_story_count} stories from sprint_stories) +# - feature-001: 7-1, 7-2, 7-3 (from sprint_stories field) +# - feature-002: 3-7 +``` + diff --git a/src/modules/bmm/workflows/4-implementation/sprint-planning/workflow.yaml b/src/modules/bmm/workflows/4-implementation/sprint-planning/workflow.yaml index 50998f0a..196040fc 100644 --- a/src/modules/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +++ b/src/modules/bmm/workflows/4-implementation/sprint-planning/workflow.yaml @@ -33,6 +33,10 @@ variables: epics_location: "{planning_artifacts}" # Directory containing epic*.md files epics_pattern: "epic*.md" # Pattern to find epic files + # Bug tracking integration (optional) + bugs_yaml: "{planning_artifacts}/bugs.yaml" # Structured bug/feature metadata + bugs_md: "{planning_artifacts}/bugs.md" # Human-readable bug tracking + # Output configuration status_file: "{implementation_artifacts}/sprint-status.yaml" diff --git a/src/modules/bmm/workflows/4-implementation/sprint-status/instructions.md b/src/modules/bmm/workflows/4-implementation/sprint-status/instructions.md index 978b9229..ab6c4279 100644 --- a/src/modules/bmm/workflows/4-implementation/sprint-status/instructions.md +++ b/src/modules/bmm/workflows/4-implementation/sprint-status/instructions.md @@ -88,15 +88,31 @@ Enter corrections (e.g., "1=in-progress, 2=backlog") or "skip" to continue witho - IF any epic has status in-progress but has no associated stories: warn "in-progress epic has no stories" + + Check if {bugs_yaml} exists + + Grep for bug-NNN and feature-NNN entries with status field + Count items by status: triaged, fixed/implemented (pending verify), verified, closed + Identify items needing action: + - Items with [IMPLEMENTED] tag → need verification + - Items with status "triaged" + workflow "direct-fix" → ready for implementation + + Store: bugs_pending_verify, bugs_triaged, features_pending_verify, features_triaged + + + Pick the next recommended workflow using priority: When selecting "first" story: sort by epic number, then story number (e.g., 1-1 before 1-2 before 2-1) - 1. If any story status == in-progress → recommend `dev-story` for the first in-progress story - 2. Else if any story status == review → recommend `code-review` for the first review story - 3. Else if any story status == ready-for-dev → recommend `dev-story` - 4. Else if any story status == backlog → recommend `create-story` - 5. Else if any retrospective status == optional → recommend `retrospective` - 6. Else → All implementation items done; suggest `workflow-status` to plan next phase + Bug verification takes priority over new story work to close the feedback loop + 1. If any bug/feature has [IMPLEMENTED] tag (pending verify) → recommend `verify` for first pending item + 2. If any story status == in-progress → recommend `dev-story` for the first in-progress story + 3. Else if any story status == review → recommend `code-review` for the first review story + 4. Else if any story status == ready-for-dev → recommend `dev-story` + 5. Else if any bug status == triaged with workflow == direct-fix → recommend `implement` for first triaged bug + 6. Else if any story status == backlog → recommend `create-story` + 7. Else if any retrospective status == optional → recommend `retrospective` + 8. Else → All implementation items done; suggest `workflow-status` to plan next phase Store selected recommendation as: next_story_id, next_workflow_id, next_agent (SM/DEV as appropriate) @@ -112,6 +128,11 @@ Enter corrections (e.g., "1=in-progress, 2=backlog") or "skip" to continue witho **Epics:** backlog {{epic_backlog}}, in-progress {{epic_in_progress}}, done {{epic_done}} +{{#if bugs_yaml_exists}} +**Bugs:** triaged {{bugs_triaged}}, pending-verify {{bugs_pending_verify}}, closed {{bugs_closed}} +**Features:** triaged {{features_triaged}}, pending-verify {{features_pending_verify}}, complete {{features_complete}} +{{/if}} + **Next Recommendation:** /bmad:bmm:workflows:{{next_workflow_id}} ({{next_story_id}}) {{#if risks}} diff --git a/src/modules/bmm/workflows/4-implementation/sprint-status/workflow.yaml b/src/modules/bmm/workflows/4-implementation/sprint-status/workflow.yaml index 2dd2f25c..3e1c8180 100644 --- a/src/modules/bmm/workflows/4-implementation/sprint-status/workflow.yaml +++ b/src/modules/bmm/workflows/4-implementation/sprint-status/workflow.yaml @@ -21,6 +21,9 @@ instructions: "{installed_path}/instructions.md" variables: sprint_status_file: "{implementation_artifacts}/sprint-status.yaml || {output_folder}/sprint-status.yaml" tracking_system: "file-system" + # Bug tracking integration (optional) + bugs_yaml: "{planning_artifacts}/bugs.yaml" + bugs_md: "{planning_artifacts}/bugs.md" # Smart input file references input_file_patterns: diff --git a/src/modules/bmm/workflows/4-implementation/story-done/instructions.md b/src/modules/bmm/workflows/4-implementation/story-done/instructions.md new file mode 100644 index 00000000..6653c2e7 --- /dev/null +++ b/src/modules/bmm/workflows/4-implementation/story-done/instructions.md @@ -0,0 +1,180 @@ +# Story Approved Workflow Instructions (DEV Agent) + +The workflow execution engine is governed by: {project-root}/.bmad/core/tasks/workflow.xml +You MUST have already loaded and processed: {installed_path}/workflow.yaml +Communicate all responses in {communication_language} + + + +This workflow is run by DEV agent AFTER user confirms a story is approved (Definition of Done is complete) +Workflow: Update story file status to Done + + + + + Use {story_path} directly + Read COMPLETE story file and parse sections + Extract story_key from filename or story metadata + Verify Status is "review" - if not, HALT with message: "Story status must be 'review' to mark as done" + + + + MUST read COMPLETE sprint-status.yaml file from start to end to preserve order + Load the FULL file: {output_folder}/sprint-status.yaml + Read ALL lines from beginning to end - do not skip any content + Parse the development_status section completely + +Find FIRST story (reading in order from top to bottom) where: - Key matches pattern: number-number-name (e.g., "1-2-user-auth") - NOT an epic key (epic-X) or retrospective (epic-X-retrospective) - Status value equals "review" + + + + No stories with status "review" found + +All stories are either still in development or already done. + +**Next Steps:** + +1. Run `dev-story` to implement stories +2. Run `code-review` if stories need review first +3. Check sprint-status.yaml for current story states + + HALT + + +Use the first reviewed story found +Find matching story file in {story_dir} using story_key pattern +Read the COMPLETE story file + + +Extract story_id and story_title from the story file + +Find the "Status:" line (usually at the top) +Update story file: Change Status to "done" + +Add completion notes to Dev Agent Record section: +Find "## Dev Agent Record" section and add: + +``` +### Completion Notes +**Completed:** {date} +**Definition of Done:** All acceptance criteria met, code reviewed, tests passing +``` + + + +Save the story file + + + +Load the FULL file: {output_folder}/sprint-status.yaml +Find development_status key matching {story_key} +Verify current status is "review" (expected previous state) +Update development_status[{story_key}] = "done" +Save file, preserving ALL comments and structure including STATUS DEFINITIONS + + + Story file updated, but could not update sprint-status: {story_key} not found + +Story is marked Done in file, but sprint-status.yaml may be out of sync. + + + + + + +Check bugs.yaml for bugs/features linked to this story and update their status + +Load {output_folder}/bugs.yaml if it exists + + + Search for entries matching this story using ALL THREE methods: + 1. Check sprint-status.yaml comment for "# Source: bugs.yaml/feature-XXX" or "# Source: bugs.yaml/bug-XXX" on the story line - this is the MOST RELIABLE method + 2. Check related_story field matching {story_id} or {story_key} + 3. Check sprint_stories array containing entries starting with {story_key} + + PRIORITY: Use sprint-status comment source if present - it's explicit and unambiguous + + + For each matching bug: + - Update status: "triaged" or "routed" → "fixed" + - Set fixed_date: {date} + - Set assigned_to: "dev-agent" + - Append to notes: "Auto-closed via story-done workflow. Story {story_key} marked done on {date}." + + + + For each matching feature (via related_story OR sprint_stories): + + MULTI-STORY FEATURE CHECK: If feature has sprint_stories array with multiple entries: + 1. Extract all story keys from sprint_stories (format: "story-key: status") + 2. Load sprint-status.yaml and check development_status for EACH story + 3. Only proceed if ALL stories in sprint_stories have status "done" in sprint-status.yaml + 4. If any story is NOT done, skip this feature and log: "Feature {feature_id} has incomplete stories: {incomplete_list}" + + + - Update status: "backlog" or "in-progress" → "implemented" + - Set implemented_date: {date} + - Update sprint_stories entries to reflect done status + - Append to notes: "Auto-closed via story-done workflow. Story {story_key} marked done on {date}." + + + + Save updated bugs.yaml + + + Also update bugs.md: + - Move bug entries from "# Tracked Bugs" to "# Fixed Bugs" with [IMPLEMENTED] tag + - Move feature entries from "# Tracked Feature Requests" to "# Implemented Features" with [IMPLEMENTED] tag + Save updated bugs.md + + + +Bug/Feature Sync: +{{#if bugs_updated}} +- Bugs marked fixed: {{bugs_updated_list}} +{{/if}} +{{#if features_updated}} +- Features marked implemented: {{features_updated_list}} +{{/if}} +{{#if features_pending}} +- Features with incomplete stories (not yet implemented): {{features_pending_list}} +{{/if}} +{{#if no_matches}} +- No related bugs/features found for story {story_key} +{{/if}} + + + + + Skip bug tracking sync - no bugs.yaml file present + + + + + + +**Story Approved and Marked Done, {user_name}!** + +Story file updated - Status: done +Sprint status updated: review → done + +**Completed Story:** + +- **ID:** {story_id} +- **Key:** {story_key} +- **Title:** {story_title} +- **Completed:** {date} + +**Next Steps:** + +1. Continue with next story in your backlog + - Run `create-story` for next backlog story + - Or run `dev-story` if ready stories exist +2. Check epic completion status + - Run `retrospective` workflow to check if epic is complete + - Epic retrospective will verify all stories are done + + + + + diff --git a/src/modules/bmm/workflows/4-implementation/story-done/workflow.yaml b/src/modules/bmm/workflows/4-implementation/story-done/workflow.yaml new file mode 100644 index 00000000..d7001c95 --- /dev/null +++ b/src/modules/bmm/workflows/4-implementation/story-done/workflow.yaml @@ -0,0 +1,27 @@ +# Story Done Workflow (DEV Agent) +name: story-done +description: 'Marks a story as done (DoD complete), updates sprint-status → DONE, and syncs related bugs/features in bugs.yaml/bugs.md to [IMPLEMENTED] status.' +author: 'BMad' + +# Critical variables from config +config_source: '{project-root}/.bmad/bmm/config.yaml' +output_folder: '{config_source}:output_folder' +user_name: '{config_source}:user_name' +communication_language: '{config_source}:communication_language' +date: system-generated +sprint_status: '{output_folder}/sprint-status.yaml' + +# Workflow components +installed_path: '{project-root}/.bmad/bmm/workflows/4-implementation/story-done' +instructions: '{installed_path}/instructions.md' + +# Variables and inputs +variables: + story_dir: '{config_source}:dev_ephemeral_location/stories' # Directory where stories are stored + bugs_yaml: '{output_folder}/bugs.yaml' # Bug/feature tracking structured data + bugs_md: '{output_folder}/bugs.md' # Bug/feature tracking human-readable log + +# Output configuration - no output file, just status updates +default_output_file: '' + +standalone: true diff --git a/src/modules/bmm/workflows/bug-tracking/instructions.md b/src/modules/bmm/workflows/bug-tracking/instructions.md new file mode 100644 index 00000000..c5395e61 --- /dev/null +++ b/src/modules/bmm/workflows/bug-tracking/instructions.md @@ -0,0 +1,376 @@ +# Bug Tracking Workflow - Triage and Route + +```xml +The workflow execution engine is governed by: {project-root}/.bmad/core/tasks/workflow.xml +You MUST have already loaded and processed: {installed_path}/workflow.yaml +Communicate in {communication_language} with {user_name} +This workflow transforms informal bug reports (bugs.md) into structured metadata (bugs.yaml) with routing recommendations + + + + + **0a. Fetch pending bug reports from the application database:** + GET {project_url}/api/bug-reports/pending + This endpoint returns all bug reports with status 'new' (not yet synced) + Response format: { data: { reports: [...], count: number } } + Each report contains: id, title, description, reporterType, reporterName, platform, browser, pageUrl, screenshotUrl, createdAt + + + No new bug reports from app. Proceeding with manual input check... + Continue to Step 1 + + + + **0b. Format reports as markdown entries:** + For each report, create markdown entry: +```markdown +## Bug: {title} + +{description} + +Reported by: {reporterName} ({reporterType}) +Date: {createdAt formatted as YYYY-MM-DD} +Platform: {platform} / {browser} +Page: {pageUrl} +{if screenshotUrl: Screenshot: {screenshotUrl}} +``` + + + **0c. Insert into bugs.md under "# manual input" section:** + - Read the "# manual input" section location from bugs.md + - Insert the new markdown entries after the "# manual input" header + - Preserve any existing manual input entries + - Write updated bugs.md + + **0d. Mark reports as synced in database:** + POST {project_url}/api/bug-reports/mark-synced + Body: { ids: [array of synced report IDs] } + This updates status to 'synced' so reports won't be fetched again + + **Synced {count} bug report(s) from app:** +{for each report:} +- {title} (from {reporterName}) +{end for} + +Proceeding with triage... + + + + + + Resolve variables from config_source: bugs_input, bugs_output, sprint_status, epics_file + + **1a. Read "# manual input" section from bugs.md (section-based reading):** + - Grep for "# manual input" to find starting line number + - Grep for next section header ("# Tracked Bugs", "# Tracked Feature Requests", "# Fixed Bugs") to find ending line + - Read just that range using offset/limit (do NOT read entire file) + - If no closing section found within initial window, expand read range and retry + + **1b. Search bugs.yaml for existing IDs (do NOT read entire file):** + - Grep for "bug-[0-9]+" pattern to find all existing bug IDs + - Grep for "feature-[0-9]+" pattern to find all existing feature IDs + - This allows duplicate detection and next-ID generation without reading full file + - If bugs.yaml doesn't exist, create it with header/definitions from template + + Load {sprint_status} to understand current sprint context (which stories are in progress) + Load {epics_file} to map bugs to related stories/epics + + + + Parse {bugs_input} (bugs.md) to extract bug reports + CRITICAL: Only triage items from the "# manual input" section + DO NOT triage: + - Items in "# Tracked Bugs" section (already triaged) + - Items in "# Tracked Feature Requests" section (already triaged) + - Items in "# Fixed Bugs" section (already closed) + + Expected format in "# manual input" section (informal, user-written): + - Markdown headers (## Bug: Title) OR bullet lists + - Freeform descriptions + - Optional fields: reported by, date, related story + - May be incomplete (missing severity, complexity, etc.) + + Extract from each bug report in "# manual input": + - Title (required) + - Description (required - may be multi-paragraph) + - Reported by (optional - extract if mentioned) + - Reported date (optional - extract if mentioned) + - Related story (optional - extract story ID if mentioned, e.g. "2-7" or "Story 2.7") + - Platform (optional - extract if mentioned: iOS, Android, all) + - Any reproduction steps + + Compare extracted bugs with existing bugs.yaml entries: + - New bugs: Not in bugs.yaml yet (need full triage) + - Updated bugs: Already in bugs.yaml but description changed (need re-triage) + - Unchanged bugs: Already triaged, skip + If NO new bugs found in "# manual input" section: + No new bugs found in bugs.md + +All bugs have already been triaged and are tracked in bugs.yaml. + +**Options:** +1. Add new bugs to docs/bugs.md (informal format) +2. View bugs.yaml to see structured bug tracking +3. Route existing triaged bugs to workflows + + HALT + + + + For each new/updated bug, perform triage analysis: + + **3a. Generate Bug ID** + - Use grep results from Step 1b to find highest existing bug-NNN + - Assign next sequential ID (e.g., bug-006) + - Format: "bug-" + zero-padded 3-digit number + + **3b. Assess Severity** (critical, high, medium, low) + Analysis questions: + - Does it prevent core functionality? (critical) + - Does it cause crashes or data loss? (critical) + - Does it block major features? (high) + - Does it significantly degrade UX but have workaround? (high) + - Does it affect subset of users with minor impact? (medium) + - Is it cosmetic or edge case? (low) + Reference severity definitions in bugs.yaml header + + **Clarification needed for bug: {bug_title}** + +I need more information to assess severity: + +1. Does this bug prevent users from completing core flows? +2. Does the bug cause crashes or data loss? +3. How many users are affected? (all users, specific platform, edge case) +4. Is there a workaround available? + +Please provide additional context so I can properly triage this bug. + + + + **3c. Assess Complexity** (trivial, small, medium, complex) + Analysis questions: + - Is it a one-line fix? (trivial) + - Single file/component, solution obvious? (small) + - Multiple files OR requires investigation? (medium) + - Architectural change OR affects many stories? (complex) + Reference complexity definitions in bugs.yaml header + + **Clarification needed for bug: {bug_title}** + +To estimate complexity, I need: + +1. Have you identified the root cause, or does it need investigation? +2. Which file(s) or component(s) are affected? +3. Is this an isolated issue or does it affect multiple parts of the app? + +Please provide technical details if available (stack trace, repro steps, affected files). + + + + **3d. Calculate Effort Estimate** (in hours) + Based on complexity: + - trivial: 0.25 - 0.5 hours + - small: 0.5 - 2 hours + - medium: 2 - 8 hours + - complex: 8 - 16+ hours + + **3e. Determine Workflow Path** + Apply routing matrix from bugs.yaml header: + - critical + any complexity -> "correct-course" (need impact analysis) + - high + trivial -> "direct-fix" (urgent, obvious fix) + - high + small -> "tech-spec" (urgent, needs spec) + - high + medium/complex -> "correct-course" (need proper analysis) + - medium + trivial -> "direct-fix" + - medium + small -> "tech-spec" + - medium + medium/complex -> "correct-course" + - low + trivial -> "direct-fix" (defer) + - low + small/medium/complex -> "backlog" (defer) + + **3f. Map to Related Story/Epic** + If bug mentions story ID (e.g., "2-7"), use that + Otherwise, infer from description using epic keywords + Reference epics.md for story matching + + **3g. Determine Affected Platform** + From description, extract: all | ios | android | web + Default to "all" if not specified + + **3h. Set Initial Status** + - New bug -> status: "triaged" + - All other fields: null or empty (to be filled when routed/fixed) + + **3i. Add Triage Notes** + Document reasoning: + - Why this severity? (business impact, user impact) + - Why this complexity? (investigation needed, files affected) + - Why this workflow? (routing logic applied) + - Suggested next steps or investigation areas + + **3j. Assess Documentation Impact** + Evaluate if fix/feature requires updates beyond code: + + **PRD Impact** (doc_impact.prd: true/false) + Set TRUE if issue: + - Conflicts with stated product goals or objectives + - Requires changing MVP scope or feature definitions + - Adds/removes/modifies core user-facing functionality + - Changes success metrics or acceptance criteria at product level + - Affects multiple epics or cross-cutting concerns + + **Architecture Impact** (doc_impact.architecture: true/false) + Set TRUE if issue: + - Requires new system components or services + - Changes data model (new tables, schema modifications) + - Affects API contracts or integration points + - Introduces new dependencies or technology choices + - Changes authentication, authorization, or security model + - Modifies deployment or infrastructure patterns + + **UX Impact** (doc_impact.ux: true/false) + Set TRUE if issue: + - Adds new screens, modals, or navigation paths + - Changes existing user flows or interaction patterns + - Requires new UI components not in design system + - Affects accessibility or responsive behavior requirements + - Changes visual hierarchy or information architecture + - Impacts user onboarding or first-run experience + + **Documentation Notes** (doc_impact.notes) + If any impact is TRUE, briefly describe: + - Which specific sections need updates + - Nature of the change (addition, modification, removal) + - Dependencies between document updates + + + **Override workflow to correct-course** + Documentation impact requires proper change analysis before implementation + Update recommended_workflow: "correct-course" + Add to notes: "Workflow elevated to correct-course due to documentation impact" + + + + + **4a. Update bugs.yaml** + Load existing bugs.yaml structure (if exists) + For each triaged bug: + - If new bug: Add to "bugs:" section with all metadata + - If existing bug: Update metadata fields if changed + Preserve all existing bugs and closed_bugs sections + Update statistics section: + - Count bugs by severity, complexity, status, workflow + - Set last_updated to {date} + Write complete bugs.yaml file + Preserve ALL header comments and definitions + + **4b. Update bugs.md - Move triaged bugs to # Tracked Bugs section** + Use section-based reading to locate relevant sections: + - Grep for "# manual input" and "# Tracked Bugs" line numbers + - Read just those sections with offset/limit (do NOT read entire file) + For each newly triaged bug: + - REMOVE the original entry from "# manual input" section + - ADD formatted entry to "# Tracked Bugs" section (create section if missing) + - Format: "{bug_id}: {title} - {brief_description}. [Severity: {severity}, Complexity: {complexity}, Platform: {affected_platform}, Workflow: {recommended_workflow}]" + - If doc_impact flagged, add: "Doc Impact: {prd|architecture|ux as applicable}" + - Include sub-items with notes if available + For feature requests, use "# Tracked Feature Requests" section instead + Write updated bugs.md + + + + **Bug Triage Complete, {user_name}!** + +**Triaged {triaged_count} bug(s):** + +{for each triaged bug:} +--- +**{bug_id}: {bug_title}** +- **Severity:** {severity} | **Complexity:** {complexity} | **Platform:** {affected_platform} +- **Effort:** ~{effort_estimate} hours +- **Recommended Workflow:** {recommended_workflow} +- **Related:** {related_story} (Epic {related_epic}) +{if doc_impact.prd OR doc_impact.architecture OR doc_impact.ux:} +- **Documentation Impact:** {prd: Y | architecture: Y | ux: Y as applicable} + - {doc_impact.notes} +{end if} + +**Triage Reasoning:** +{triage_notes} + +{end for} + +--- + +**Updated Files:** +- docs/bugs.yaml - Structured metadata for all triaged bugs +- docs/bugs.md - Moved triaged bugs to "# Tracked Bugs" section + +**Summary:** +- Total Active Bugs: {total_active_bugs} +- Critical: {critical_count} | High: {high_count} | Medium: {medium_count} | Low: {low_count} + +{if any doc_impact flagged:} +**Documentation Updates Required:** +- PRD Impact: {prd_impact_count} item(s) +- Architecture Impact: {arch_impact_count} item(s) +- UX Impact: {ux_impact_count} item(s) + +Items with documentation impact have been routed to `correct-course` workflow. +{end if} + +**Workflow Recommendations:** +- Direct Fix ({direct_fix_count}): `/implement bug-NNN` - Quick fixes, no spec needed +- Tech-Spec ({tech_spec_count}): Create tech-spec first, then `/implement` +- Correct-Course ({correct_course_count}): Run correct-course workflow for impact analysis + +--- + +**Next Steps:** + +To implement a bug fix: +``` +/implement bug-NNN +``` + +To verify and close after testing: +``` +/verify bug-NNN +``` + +To verify all implemented bugs: +``` +/verify +``` + + + + +``` + +## Example bugs.md Format (User-Facing) + +Users can write bugs in any freeform markdown format. The workflow parses common patterns: + +**Option 1: Markdown Headers** +```markdown +## Bug: Join button doesn't work on Android + +When I tap the "Join" button, nothing happens. Tested on Samsung Galaxy S21. + +Reported by: Sarah +Date: Nov 19, 2025 +Related: Story 2.7 +``` + +**Option 2: Bullet Lists** +```markdown +- **Join button unresponsive (Android)**: Button doesn't respond to taps. Works on iOS. Probably a touch target issue. +- **App crashes offline**: If I turn off WiFi and try to create something, the app crashes. CRITICAL! +``` + +**Option 3: Numbered Lists** +```markdown +1. Typo in success message - says "sucessfully" instead of "successfully" +2. Times showing in UTC instead of local time - very confusing for users +``` + +The workflow is flexible and extracts whatever information is available, then prompts the user for missing details during triage. diff --git a/src/modules/bmm/workflows/bug-tracking/reference-implementation.md b/src/modules/bmm/workflows/bug-tracking/reference-implementation.md new file mode 100644 index 00000000..2fa43700 --- /dev/null +++ b/src/modules/bmm/workflows/bug-tracking/reference-implementation.md @@ -0,0 +1,542 @@ +# In-App Bug Reporting - Reference Implementation + +This document provides a reference implementation for adding **in-app bug reporting** to your project. The BMAD bug-tracking workflow works without this feature (using manual `bugs.md` input), but in-app reporting provides a better user experience. + +## Overview + +The in-app bug reporting feature allows users to submit bug reports directly from your application. Reports are stored in your database and then synced to `bugs.md` by the triage workflow. + +``` +User -> UI Modal -> API -> Database -> Triage Workflow -> bugs.md/bugs.yaml +``` + +## Components Required + +| Component | Purpose | Stack-Specific | +|-----------|---------|----------------| +| Database table | Store pending bug reports | Yes | +| API: Create report | Accept user submissions | Yes | +| API: Get pending | Fetch unsynced reports | Yes | +| API: Mark synced | Update status after sync | Yes | +| UI Modal | Bug report form | Yes | +| Validation schemas | Input validation | Partially | + +## 1. Database Schema + +### Drizzle ORM (PostgreSQL) + +```typescript +// src/lib/server/db/schema.ts + +import { pgTable, uuid, text, timestamp, index } from 'drizzle-orm/pg-core'; + +export const bugReports = pgTable( + 'bug_reports', + { + id: uuid('id').primaryKey().defaultRandom(), + organizationId: uuid('organization_id').notNull(), // For multi-tenant apps + reporterType: text('reporter_type').notNull(), // 'staff' | 'member' | 'user' + reporterId: uuid('reporter_id').notNull(), + title: text('title').notNull(), + description: text('description').notNull(), + userAgent: text('user_agent'), + pageUrl: text('page_url'), + platform: text('platform'), // 'Windows', 'macOS', 'iOS', etc. + browser: text('browser'), // 'Chrome', 'Safari', 'Firefox' + screenshotUrl: text('screenshot_url'), // Optional: cloud storage URL + status: text('status').notNull().default('new'), // 'new' | 'synced' | 'dismissed' + createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(), + syncedAt: timestamp('synced_at', { withTimezone: true }) + }, + (table) => [ + index('bug_reports_organization_id_idx').on(table.organizationId), + index('bug_reports_status_idx').on(table.status), + index('bug_reports_created_at_idx').on(table.createdAt) + ] +); + +export const BUG_REPORT_STATUS = { + NEW: 'new', + SYNCED: 'synced', + DISMISSED: 'dismissed' +} as const; + +export const REPORTER_TYPE = { + STAFF: 'staff', + MEMBER: 'member', + USER: 'user' +} as const; +``` + +### Prisma Schema + +```prisma +model BugReport { + id String @id @default(uuid()) + organizationId String @map("organization_id") + reporterType String @map("reporter_type") + reporterId String @map("reporter_id") + title String + description String + userAgent String? @map("user_agent") + pageUrl String? @map("page_url") + platform String? + browser String? + screenshotUrl String? @map("screenshot_url") + status String @default("new") + createdAt DateTime @default(now()) @map("created_at") + syncedAt DateTime? @map("synced_at") + + @@index([organizationId]) + @@index([status]) + @@index([createdAt]) + @@map("bug_reports") +} +``` + +## 2. Validation Schemas + +### Zod (TypeScript) + +```typescript +// src/lib/schemas/bug-report.ts + +import { z } from 'zod'; + +export const createBugReportSchema = z.object({ + title: z + .string() + .trim() + .min(5, 'Title must be at least 5 characters') + .max(200, 'Title must be 200 characters or less'), + description: z + .string() + .trim() + .min(10, 'Description must be at least 10 characters') + .max(5000, 'Description must be 5000 characters or less'), + pageUrl: z.string().url().optional(), + userAgent: z.string().max(1000).optional(), + platform: z.string().max(50).optional(), + browser: z.string().max(50).optional() +}); + +export const markSyncedSchema = z.object({ + ids: z.array(z.string().uuid()).min(1, 'At least one ID is required') +}); + +export const SCREENSHOT_CONFIG = { + maxSizeBytes: 5 * 1024 * 1024, // 5MB + maxSizeMB: 5, + allowedTypes: ['image/jpeg', 'image/png', 'image/webp'] as const +} as const; +``` + +## 3. API Endpoints + +### POST /api/bug-reports - Create Report + +```typescript +// SvelteKit: src/routes/api/bug-reports/+server.ts + +import { json } from '@sveltejs/kit'; +import type { RequestHandler } from './$types'; +import { db } from '$lib/server/db'; +import { bugReports } from '$lib/server/db/schema'; +import { createBugReportSchema } from '$lib/schemas/bug-report'; + +export const POST: RequestHandler = async ({ request, locals }) => { + // Determine reporter from auth context + if (!locals.user) { + return json({ error: { code: 'UNAUTHORIZED' } }, { status: 401 }); + } + + const body = await request.json(); + const result = createBugReportSchema.safeParse(body); + + if (!result.success) { + return json({ + error: { code: 'VALIDATION_ERROR', message: result.error.issues[0]?.message } + }, { status: 400 }); + } + + const { title, description, pageUrl, userAgent, platform, browser } = result.data; + + const [newReport] = await db + .insert(bugReports) + .values({ + organizationId: locals.user.organizationId, + reporterType: 'staff', + reporterId: locals.user.id, + title, + description, + pageUrl, + userAgent, + platform, + browser + }) + .returning(); + + return json({ + data: { + bugReport: { + id: newReport.id, + title: newReport.title, + createdAt: newReport.createdAt.toISOString() + } + } + }, { status: 201 }); +}; +``` + +### GET /api/bug-reports/pending - Fetch for Triage + +```typescript +// SvelteKit: src/routes/api/bug-reports/pending/+server.ts + +import { json } from '@sveltejs/kit'; +import type { RequestHandler } from './$types'; +import { db } from '$lib/server/db'; +import { bugReports, BUG_REPORT_STATUS } from '$lib/server/db/schema'; +import { eq } from 'drizzle-orm'; + +export const GET: RequestHandler = async () => { + const reports = await db + .select() + .from(bugReports) + .where(eq(bugReports.status, BUG_REPORT_STATUS.NEW)) + .orderBy(bugReports.createdAt); + + // Map to workflow-expected format + const formatted = reports.map((r) => ({ + id: r.id, + title: r.title, + description: r.description, + reporterType: r.reporterType, + reporterName: 'Unknown', // Join with users table for real name + platform: r.platform, + browser: r.browser, + pageUrl: r.pageUrl, + screenshotUrl: r.screenshotUrl, + createdAt: r.createdAt.toISOString() + })); + + return json({ + data: { + reports: formatted, + count: formatted.length + } + }); +}; +``` + +### POST /api/bug-reports/mark-synced - Update After Sync + +```typescript +// SvelteKit: src/routes/api/bug-reports/mark-synced/+server.ts + +import { json } from '@sveltejs/kit'; +import type { RequestHandler } from './$types'; +import { db } from '$lib/server/db'; +import { bugReports, BUG_REPORT_STATUS } from '$lib/server/db/schema'; +import { inArray } from 'drizzle-orm'; +import { markSyncedSchema } from '$lib/schemas/bug-report'; + +export const POST: RequestHandler = async ({ request }) => { + const body = await request.json(); + const result = markSyncedSchema.safeParse(body); + + if (!result.success) { + return json({ + error: { code: 'VALIDATION_ERROR', message: result.error.issues[0]?.message } + }, { status: 400 }); + } + + const updated = await db + .update(bugReports) + .set({ + status: BUG_REPORT_STATUS.SYNCED, + syncedAt: new Date() + }) + .where(inArray(bugReports.id, result.data.ids)) + .returning({ id: bugReports.id }); + + return json({ + data: { + updatedCount: updated.length, + updatedIds: updated.map((r) => r.id) + } + }); +}; +``` + +## 4. UI Component + +### Svelte 5 (with shadcn-svelte) + +```svelte + + + + !o && onClose()}> + + + + + Report a Bug + + + +
{ e.preventDefault(); handleSubmit(); }} class="space-y-4"> +
+ +
+
+