Files
gh-jamesrochabrun-skills-al…/skills/prd-generator/scripts/validate_prd.sh
2025-11-29 18:48:58 +08:00

299 lines
8.7 KiB
Bash
Executable File

#!/bin/bash
# PRD Validation Script
# Checks PRD completeness and quality
set -e
# Colors for output
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# Default values
VERBOSE=false
SECTIONS="all"
# Usage function
usage() {
echo "Usage: $0 <prd_file.md> [options]"
echo ""
echo "Options:"
echo " --verbose Show detailed suggestions"
echo " --sections <list> Check specific sections only (comma-separated)"
echo " e.g., --sections user-stories,metrics"
echo ""
echo "Example:"
echo " $0 my_prd.md"
echo " $0 my_prd.md --verbose"
echo " $0 my_prd.md --sections user-stories,metrics"
exit 1
}
# Parse arguments
if [ $# -lt 1 ]; then
usage
fi
PRD_FILE="$1"
shift
while [[ $# -gt 0 ]]; do
case $1 in
--verbose)
VERBOSE=true
shift
;;
--sections)
SECTIONS="$2"
shift 2
;;
*)
echo -e "${RED}Unknown option: $1${NC}"
usage
;;
esac
done
# Check if file exists
if [ ! -f "$PRD_FILE" ]; then
echo -e "${RED}✗ Error: File not found: $PRD_FILE${NC}"
exit 1
fi
echo -e "${BLUE}╔════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║ PRD Validation Report ║${NC}"
echo -e "${BLUE}╚════════════════════════════════════════╝${NC}"
echo ""
echo -e "File: ${BLUE}$PRD_FILE${NC}"
echo ""
# Counters
ISSUES_FOUND=0
WARNINGS=0
CHECKS_PASSED=0
# Function to check section exists
check_section() {
local section_name="$1"
local section_pattern="$2"
local required="$3"
if grep -q "$section_pattern" "$PRD_FILE"; then
echo -e "${GREEN}${NC} $section_name section found"
((CHECKS_PASSED++))
return 0
else
if [ "$required" = "true" ]; then
echo -e "${RED}${NC} $section_name section missing (REQUIRED)"
((ISSUES_FOUND++))
else
echo -e "${YELLOW}${NC} $section_name section missing (recommended)"
((WARNINGS++))
fi
return 1
fi
}
# Function to check content quality
check_content() {
local check_name="$1"
local pattern="$2"
local error_msg="$3"
if grep -q "$pattern" "$PRD_FILE"; then
echo -e "${YELLOW}${NC} $check_name: $error_msg"
((WARNINGS++))
return 1
else
echo -e "${GREEN}${NC} $check_name passed"
((CHECKS_PASSED++))
return 0
fi
}
echo -e "${BLUE}━━━ Section Completeness ━━━${NC}"
echo ""
# Required sections
check_section "Problem Statement" "##.*Problem Statement" true
check_section "Goals & Objectives" "##.*Goals.*Objectives" true
check_section "User Stories" "##.*User Stories" true
check_section "Success Metrics" "##.*Success Metrics" true
check_section "Scope" "##.*Scope" true
echo ""
echo -e "${BLUE}━━━ Recommended Sections ━━━${NC}"
echo ""
# Recommended sections
check_section "Executive Summary" "##.*Executive Summary" false
check_section "User Personas" "##.*User Personas" false
check_section "Technical Considerations" "##.*Technical Considerations" false
check_section "Design & UX Requirements" "##.*Design.*UX" false
check_section "Timeline & Milestones" "##.*Timeline.*Milestones" false
check_section "Risks & Mitigation" "##.*Risks.*Mitigation" false
echo ""
echo -e "${BLUE}━━━ Content Quality Checks ━━━${NC}"
echo ""
# Check for placeholder text
check_content "Placeholder text" "\[.*\]" "Contains placeholder brackets - fill in all placeholders"
# Check for TBD/TODO
check_content "TBD markers" "TBD\|TODO" "Contains TBD/TODO markers - resolve all open items"
# Check for empty sections
if grep -q "^##.*\n\n##" "$PRD_FILE"; then
echo -e "${YELLOW}${NC} Empty sections detected"
((WARNINGS++))
else
echo -e "${GREEN}${NC} No empty sections"
((CHECKS_PASSED++))
fi
# Check for user story format
echo ""
echo -e "${BLUE}━━━ User Story Validation ━━━${NC}"
echo ""
USER_STORY_COUNT=$(grep -c "As a.*I want.*So that" "$PRD_FILE" || true)
if [ "$USER_STORY_COUNT" -gt 0 ]; then
echo -e "${GREEN}${NC} Found $USER_STORY_COUNT properly formatted user stories"
((CHECKS_PASSED++))
# Check for acceptance criteria
AC_COUNT=$(grep -c "Acceptance Criteria" "$PRD_FILE" || true)
if [ "$AC_COUNT" -ge "$USER_STORY_COUNT" ]; then
echo -e "${GREEN}${NC} All user stories have acceptance criteria"
((CHECKS_PASSED++))
else
echo -e "${YELLOW}${NC} Some user stories may be missing acceptance criteria"
((WARNINGS++))
fi
else
echo -e "${RED}${NC} No properly formatted user stories found"
echo -e " Expected format: 'As a [user], I want [action], So that [benefit]'"
((ISSUES_FOUND++))
fi
# Check for success metrics
echo ""
echo -e "${BLUE}━━━ Metrics Validation ━━━${NC}"
echo ""
if grep -q "KPI\|metric\|measure" "$PRD_FILE"; then
echo -e "${GREEN}${NC} Success metrics mentioned"
((CHECKS_PASSED++))
# Check for quantifiable metrics
if grep -q "[0-9]\+%" "$PRD_FILE"; then
echo -e "${GREEN}${NC} Contains quantifiable metrics (percentages found)"
((CHECKS_PASSED++))
else
echo -e "${YELLOW}${NC} Consider adding quantifiable targets (%, numbers, etc.)"
((WARNINGS++))
fi
else
echo -e "${RED}${NC} Success metrics not clearly defined"
((ISSUES_FOUND++))
fi
# Check for scope definition
echo ""
echo -e "${BLUE}━━━ Scope Validation ━━━${NC}"
echo ""
IN_SCOPE=false
OUT_SCOPE=false
if grep -qi "in scope\|in-scope" "$PRD_FILE"; then
echo -e "${GREEN}${NC} In-scope section defined"
IN_SCOPE=true
((CHECKS_PASSED++))
else
echo -e "${YELLOW}${NC} In-scope section not clearly defined"
((WARNINGS++))
fi
if grep -qi "out of scope\|out-of-scope" "$PRD_FILE"; then
echo -e "${GREEN}${NC} Out-of-scope section defined"
OUT_SCOPE=true
((CHECKS_PASSED++))
else
echo -e "${YELLOW}${NC} Out-of-scope section not defined (prevents scope creep)"
((WARNINGS++))
fi
# Document quality checks
echo ""
echo -e "${BLUE}━━━ Document Quality ━━━${NC}"
echo ""
# Check word count
WORD_COUNT=$(wc -w < "$PRD_FILE")
echo -e "Word count: $WORD_COUNT"
if [ "$WORD_COUNT" -lt 500 ]; then
echo -e "${YELLOW}${NC} Document seems short for a PRD (< 500 words)"
((WARNINGS++))
elif [ "$WORD_COUNT" -gt 5000 ]; then
echo -e "${YELLOW}${NC} Document is very long (> 5000 words) - consider splitting"
((WARNINGS++))
else
echo -e "${GREEN}${NC} Document length appropriate"
((CHECKS_PASSED++))
fi
# Check for headers hierarchy
if grep -q "^#\s" "$PRD_FILE"; then
echo -e "${GREEN}${NC} Proper heading structure"
((CHECKS_PASSED++))
else
echo -e "${YELLOW}${NC} Check heading hierarchy (should start with # not ##)"
((WARNINGS++))
fi
# Final Summary
echo ""
echo -e "${BLUE}╔════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║ Validation Summary ║${NC}"
echo -e "${BLUE}╚════════════════════════════════════════╝${NC}"
echo ""
echo -e "Checks passed: ${GREEN}$CHECKS_PASSED${NC}"
echo -e "Warnings: ${YELLOW}$WARNINGS${NC}"
echo -e "Issues found: ${RED}$ISSUES_FOUND${NC}"
echo ""
# Recommendations
if [ "$VERBOSE" = true ]; then
echo -e "${BLUE}━━━ Recommendations ━━━${NC}"
echo ""
echo "1. Ensure all required sections are present"
echo "2. Fill in all placeholder text marked with [brackets]"
echo "3. Use the user story format: 'As a [user], I want [action], So that [benefit]'"
echo "4. Include specific, measurable success metrics"
echo "5. Clearly define what's in and out of scope"
echo "6. Add acceptance criteria for all user stories"
echo "7. Review with stakeholders before finalizing"
echo ""
fi
# Exit code
if [ "$ISSUES_FOUND" -gt 0 ]; then
echo -e "${RED}❌ PRD validation failed${NC}"
echo -e " Address $ISSUES_FOUND critical issue(s) before proceeding"
exit 1
elif [ "$WARNINGS" -gt 0 ]; then
echo -e "${YELLOW}⚠ PRD validation passed with warnings${NC}"
echo -e " Consider addressing $WARNINGS warning(s) to improve quality"
exit 0
else
echo -e "${GREEN}✅ PRD validation passed!${NC}"
echo -e " Document looks ready for stakeholder review"
exit 0
fi