Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 17:50:56 +08:00
commit f0e7f0e603
9 changed files with 3525 additions and 0 deletions

View File

@@ -0,0 +1,801 @@
#!/usr/bin/env python3
"""
Project Document Generator
Generates structured requirements, design, and task documents for new projects
"""
import json
import argparse
from datetime import datetime
from typing import Dict, List, Optional
import os
class ProjectDocumentGenerator:
def __init__(self, project_name: str, project_type: str = "web-app"):
self.project_name = project_name
self.project_type = project_type
self.timestamp = datetime.now().strftime("%Y-%m-%d")
def generate_requirements_template(self, features: List[str]) -> str:
"""Generate requirements document template"""
template = f"""# Requirements Document
## Introduction
{self.project_name} is a [DESCRIPTION OF SYSTEM PURPOSE]. The system is designed for [TARGET USERS] and will be deployed as [DEPLOYMENT MODEL].
## Glossary
- **[Term]**: [Definition specific to this system]
- **User**: [Define user types]
- **System**: The {self.project_name} platform
## Requirements
"""
for i, feature in enumerate(features, 1):
template += f"""
### Requirement {i}
**User Story:** As a [USER TYPE], I want {feature}, so that [BENEFIT]
#### Acceptance Criteria
1. WHEN [trigger/condition], THE system SHALL [behavior]
2. WHERE [context applies], THE system SHALL [behavior]
3. THE system SHALL [capability] within [time limit]
4. IF [error condition], THEN THE system SHALL [handle gracefully]
5. THE system SHALL persist [data] with [attributes]
"""
return template
def generate_design_template(self, components: List[str]) -> str:
"""Generate design document template with comprehensive architecture"""
template = f"""# Design Document
## Overview
The {self.project_name} system is built as a [ARCHITECTURE PATTERN] with [KEY COMPONENTS]. The design prioritizes [KEY PRIORITIES].
## System Architecture
### Component Map
| Component ID | Name | Type | Responsibility | Interfaces With |
|-------------|------|------|----------------|-----------------|
| COMP-1 | Frontend | UI | User interface and interaction | COMP-2 |
| COMP-2 | API Gateway | Service | Request routing and authentication | COMP-3, COMP-4 |"""
for i, component in enumerate(components, 3):
template += f"""
| COMP-{i} | {component} | Service | [Responsibility] | [Components] |"""
template += """
### High-Level Architecture Diagram
```
┌─────────────────────────────────────────────────────────────┐
│ Frontend Layer │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ [UI Framework] Application │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
API (REST/GraphQL/WebSocket)
┌─────────────────────────────────────────────────────────────┐
│ Backend Layer │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ [Backend Framework] Application │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Service │ │ Service │ │ Service │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Database Access
┌─────────────────────────────────────────────────────────────┐
│ Data Layer │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ [Database Type] │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
## Data Flow Specifications
### Primary Data Flows
#### 1. User Authentication Flow
```
1. User → Frontend: Login credentials
2. Frontend → API Gateway: Encrypted credentials
3. API Gateway → Auth Service: Validation request
4. Auth Service → User Database: Query user record
5. User Database → Auth Service: User data
6. Auth Service → API Gateway: JWT token
7. API Gateway → Frontend: Auth response with token
```
**Data Transformations:**
- Step 2: Credentials encrypted with HTTPS
- Step 3: Rate limiting applied
- Step 6: JWT token generated with claims
[Add other critical data flows]
## Integration Points
### Internal Integration Points
| Source | Target | Protocol | Data Format | Purpose |
|--------|--------|----------|-------------|---------|
| Frontend | API Gateway | HTTPS/REST | JSON | API calls |
| API Gateway | Services | HTTP/gRPC | JSON/Protobuf | Service calls |
| Services | Database | TCP | SQL | Data persistence |
### External Integration Points
#### [External Service Name]
**Type:** REST API / Database / Message Queue
**Purpose:** [What this integration provides]
**Endpoint:** [URL pattern or connection details]
**Authentication:** [OAuth2, API Key, etc.]
**Rate Limits:** [Any constraints]
**Interface Contract:**
```
POST /api/endpoint
Headers: { "Authorization": "Bearer token" }
Body: { "field": "value" }
Response: { "result": "value" }
```
**Error Handling:**
- Retry strategy: Exponential backoff with jitter
- Circuit breaker: Opens after 5 consecutive failures
- Fallback: [Degraded functionality or cached response]
## System Boundaries
### In Scope
- [Core functionality included]
- [Features to be implemented]
### Out of Scope
- [Features not included]
- [Delegated to external systems]
### Assumptions
- [External services available]
- [Infrastructure provided]
## Components and Interfaces
"""
for component in components:
template += f"""
### {component}
**Responsibility:** [Single sentence description of what this component does]
**Key Classes:**
- `{component}Service`: Main service class for {component.lower()} operations
- `{component}Controller`: Handles API requests for {component.lower()}
- `{component}Repository`: Data access layer for {component.lower()}
**Interfaces:**
```python
class {component}Service:
async def create(self, data: Dict) -> {component}
async def get(self, id: str) -> Optional[{component}]
async def update(self, id: str, data: Dict) -> {component}
async def delete(self, id: str) -> bool
async def list(self, filters: Dict) -> List[{component}]
```
**Data Flow:**
- Receives requests from [API layer/other service]
- Validates input using [validation rules]
- Processes business logic
- Persists to database
- Returns response
**Performance:**
- Target response time: <200ms for queries
- Target response time: <500ms for mutations
- Maximum concurrent operations: 100
"""
template += """
## Data Models
### User
```python
@dataclass
class User:
id: str
email: str
name: str
created_at: datetime
updated_at: datetime
```
[Add other data models]
## Error Handling
### API Errors
**Types:**
- 400 Bad Request - Invalid input
- 401 Unauthorized - Missing/invalid authentication
- 403 Forbidden - Insufficient permissions
- 404 Not Found - Resource doesn't exist
- 500 Internal Server Error - Unexpected error
**Handling:**
- Return consistent error format with code, message, and details
- Log all errors with context
- Implement retry logic for transient failures
### Database Errors
**Types:**
- Connection failures
- Query timeouts
- Constraint violations
**Handling:**
- Retry with exponential backoff
- Graceful degradation where possible
- Transaction rollback on failure
## Testing Strategy
### Unit Tests
- Service layer: Test business logic with mocked dependencies
- Repository layer: Test database operations
- API layer: Test request/response handling
- Coverage target: 80%
### Integration Tests
- End-to-end API tests
- Database integration tests
- External service integration tests
### Performance Tests
- Load testing: 100 concurrent users
- Response time: p95 < 500ms
- Throughput: >100 requests/second
## Deployment
### Docker Configuration
```yaml
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- DATABASE_URL=${DATABASE_URL}
depends_on:
- database
database:
image: postgres:15
volumes:
- db_data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=${DB_PASSWORD}
volumes:
db_data:
```
### Environment Variables
```
DATABASE_URL=postgresql://user:pass@localhost/dbname
API_KEY=your-api-key
JWT_SECRET=your-secret-key
NODE_ENV=production
```
## Performance Targets
- API response time: <200ms (p95)
- Database query time: <50ms (p95)
- Frontend load time: <2s
- Time to interactive: <3s
- Memory usage: <512MB per instance
## Security Considerations
- JWT-based authentication
- Rate limiting on all endpoints
- Input validation and sanitization
- SQL injection prevention via parameterized queries
- XSS prevention via output encoding
- HTTPS only in production
"""
return template
def generate_tasks_template(self, phases: List[Dict]) -> str:
"""Generate implementation plan template with boundaries and deliverables"""
template = f"""# Implementation Plan
Generated: {self.timestamp}
Project: {self.project_name}
Type: {self.project_type}
## Project Boundaries
### Must Have (MVP)
- [Core feature 1]
- [Core feature 2]
- [Core feature 3]
### Nice to Have (Enhancements)
- [Enhancement feature 1]
- [Enhancement feature 2]
### Out of Scope
- [Explicitly excluded feature 1]
- [Deferred to future phase]
### Technical Constraints
- [Framework limitations]
- [Resource constraints]
## Deliverables by Phase
| Phase | Deliverables | Success Criteria |
|-------|-------------|------------------|
| 1. Infrastructure | Working development environment | All developers can run locally |
| 2. Data Layer | Database schema, models | CRUD operations functional |
| 3. Business Logic | Core services implemented | All requirements fulfilled |
| 4. API Layer | REST/GraphQL endpoints | API tests passing |
| 5. Frontend | User interface | End-to-end workflows complete |
| 6. Testing | Test coverage >80% | All tests passing |
| 7. Deployment | Production environment | System accessible and stable |
## Task Breakdown
"""
for phase_num, phase in enumerate(phases, 1):
template += f"- [ ] {phase_num}. {phase['name']}\n\n"
for task_num, task in enumerate(phase.get('tasks', []), 1):
template += f" - [ ] {phase_num}.{task_num} {task['name']}\n"
if 'subtasks' in task:
for subtask in task['subtasks']:
template += f" - {subtask}\n"
if 'requirements' in task:
template += f" - _Requirements: {', '.join(task['requirements'])}_\n"
if 'dependencies' in task and task['dependencies']:
template += f" - _Dependencies: {', '.join(task['dependencies'])}_\n"
template += "\n"
return template
def get_default_phases(self) -> List[Dict]:
"""Get default phases based on project type"""
if self.project_type == "web-app":
return [
{
"name": "Infrastructure Setup",
"tasks": [
{
"name": "Initialize project structure",
"subtasks": [
"Create directory structure",
"Initialize package managers",
"Set up version control"
],
"requirements": ["REQ-12.1"]
},
{
"name": "Set up database",
"subtasks": [
"Create database schema",
"Write migrations",
"Set up connection pooling"
],
"requirements": ["REQ-9.1", "REQ-9.2"]
},
{
"name": "Configure Docker",
"subtasks": [
"Create Dockerfiles",
"Write docker-compose.yml",
"Set up volumes and networks"
],
"requirements": ["REQ-12.2", "REQ-12.3"]
}
]
},
{
"name": "Backend Implementation",
"tasks": [
{
"name": "Create data models",
"subtasks": [
"Define entities",
"Create validation schemas",
"Implement serialization"
],
"requirements": ["REQ-3.1"],
"dependencies": ["1.2"]
},
{
"name": "Implement service layer",
"subtasks": [
"Create business logic services",
"Implement validation rules",
"Add error handling"
],
"requirements": ["REQ-4.1"],
"dependencies": ["2.1"]
},
{
"name": "Build API endpoints",
"subtasks": [
"Create REST/GraphQL routes",
"Add authentication middleware",
"Implement request validation"
],
"requirements": ["REQ-5.1"],
"dependencies": ["2.2"]
}
]
},
{
"name": "Frontend Implementation",
"tasks": [
{
"name": "Set up frontend framework",
"subtasks": [
"Initialize React/Vue/Angular app",
"Configure build tools",
"Set up routing"
],
"requirements": ["REQ-7.1"]
},
{
"name": "Create UI components",
"subtasks": [
"Build reusable components",
"Implement responsive design",
"Add styling/theming"
],
"requirements": ["REQ-7.2"],
"dependencies": ["3.1"]
},
{
"name": "Integrate with backend",
"subtasks": [
"Set up API client",
"Implement state management",
"Add error handling"
],
"requirements": ["REQ-7.3"],
"dependencies": ["2.3", "3.2"]
}
]
},
{
"name": "Testing and Quality Assurance",
"tasks": [
{
"name": "Write unit tests",
"subtasks": [
"Test services",
"Test components",
"Test utilities"
],
"requirements": ["REQ-13.1"],
"dependencies": ["2.2", "3.2"]
},
{
"name": "Create integration tests",
"subtasks": [
"Test API endpoints",
"Test database operations",
"Test external integrations"
],
"requirements": ["REQ-13.2"],
"dependencies": ["4.1"]
},
{
"name": "Perform end-to-end testing",
"subtasks": [
"Test user workflows",
"Test error scenarios",
"Performance testing"
],
"requirements": ["REQ-13.3"],
"dependencies": ["4.2"]
}
]
},
{
"name": "Deployment and Documentation",
"tasks": [
{
"name": "Set up CI/CD pipeline",
"subtasks": [
"Configure build automation",
"Set up test automation",
"Configure deployment"
],
"requirements": ["REQ-14.1"],
"dependencies": ["4.3"]
},
{
"name": "Write documentation",
"subtasks": [
"API documentation",
"User guide",
"Deployment guide"
],
"requirements": ["REQ-15.1"],
"dependencies": ["5.1"]
},
{
"name": "Deploy to production",
"subtasks": [
"Set up production environment",
"Configure monitoring",
"Perform deployment"
],
"requirements": ["REQ-14.2"],
"dependencies": ["5.2"]
}
]
}
]
elif self.project_type == "cli-tool":
return [
{
"name": "Project Setup",
"tasks": [
{
"name": "Initialize project",
"subtasks": [
"Set up package structure",
"Configure build system",
"Add dependencies"
]
},
{
"name": "Design command structure",
"subtasks": [
"Define commands and subcommands",
"Plan argument parsing",
"Design configuration schema"
]
}
]
},
{
"name": "Core Implementation",
"tasks": [
{
"name": "Implement command parser",
"subtasks": [
"Create argument parser",
"Add command handlers",
"Implement help system"
],
"dependencies": ["1.2"]
},
{
"name": "Build core logic",
"subtasks": [
"Implement business logic",
"Add validation",
"Handle errors"
],
"dependencies": ["2.1"]
}
]
},
{
"name": "Testing and Packaging",
"tasks": [
{
"name": "Write tests",
"subtasks": [
"Unit tests",
"Integration tests",
"CLI tests"
],
"dependencies": ["2.2"]
},
{
"name": "Package and distribute",
"subtasks": [
"Create package",
"Write documentation",
"Publish"
],
"dependencies": ["3.1"]
}
]
}
]
elif self.project_type == "api-service":
return [
{
"name": "Service Setup",
"tasks": [
{
"name": "Initialize API project",
"subtasks": [
"Set up framework",
"Configure database",
"Add middleware"
]
},
{
"name": "Design API schema",
"subtasks": [
"Define endpoints",
"Create OpenAPI spec",
"Plan authentication"
]
}
]
},
{
"name": "API Implementation",
"tasks": [
{
"name": "Create endpoints",
"subtasks": [
"Implement routes",
"Add validation",
"Handle errors"
],
"dependencies": ["1.2"]
},
{
"name": "Add authentication",
"subtasks": [
"Implement auth middleware",
"Add JWT/OAuth",
"Set up permissions"
],
"dependencies": ["2.1"]
}
]
}
]
else: # Generic project
return [
{
"name": "Project Setup",
"tasks": [
{
"name": "Initialize project",
"subtasks": ["Create structure", "Set up tools"]
}
]
},
{
"name": "Implementation",
"tasks": [
{
"name": "Build core features",
"subtasks": ["Implement logic", "Add tests"]
}
]
},
{
"name": "Deployment",
"tasks": [
{
"name": "Prepare for production",
"subtasks": ["Test", "Document", "Deploy"]
}
]
}
]
def generate_all_documents(self,
features: List[str] = None,
components: List[str] = None,
output_dir: str = ".") -> Dict[str, str]:
"""Generate all three documents"""
# Use defaults if not provided
if not features:
features = [
"to authenticate and manage my account",
"to create and manage resources",
"to view analytics and reports",
"to configure system settings",
"to receive notifications"
]
if not components:
components = [
"Authentication Service",
"User Management",
"Resource Manager",
"Analytics Engine",
"Notification Service"
]
# Generate documents
docs = {
"requirements.md": self.generate_requirements_template(features),
"design.md": self.generate_design_template(components),
"tasks.md": self.generate_tasks_template(self.get_default_phases())
}
# Save to files
os.makedirs(output_dir, exist_ok=True)
for filename, content in docs.items():
filepath = os.path.join(output_dir, filename)
with open(filepath, 'w') as f:
f.write(content)
print(f"Generated: {filepath}")
return docs
def main():
parser = argparse.ArgumentParser(description="Generate project planning documents")
parser.add_argument("project_name", help="Name of the project")
parser.add_argument("--type", default="web-app",
choices=["web-app", "cli-tool", "api-service", "generic"],
help="Type of project")
parser.add_argument("--features", nargs="+",
help="List of features for requirements")
parser.add_argument("--components", nargs="+",
help="List of components for design")
parser.add_argument("--output", default=".",
help="Output directory for documents")
args = parser.parse_args()
generator = ProjectDocumentGenerator(args.project_name, args.type)
generator.generate_all_documents(
features=args.features,
components=args.components,
output_dir=args.output
)
print(f"\n✅ Successfully generated project documents for '{args.project_name}'")
print(f" Type: {args.type}")
print(f" Location: {args.output}/")
print("\nNext steps:")
print("1. Review and customize the generated documents")
print("2. Fill in the [PLACEHOLDER] sections")
print("3. Add project-specific requirements and design details")
print("4. Use these documents as input for AI-assisted implementation")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,325 @@
#!/usr/bin/env python3
"""
Document Validator
Validates project planning documents for completeness and consistency
"""
import re
import argparse
from typing import List, Dict, Tuple
import os
class DocumentValidator:
def __init__(self):
self.errors = []
self.warnings = []
def validate_requirements(self, content: str) -> Tuple[List[str], List[str]]:
"""Validate requirements document structure and content"""
errors = []
warnings = []
# Check required sections
required_sections = [
"## Introduction",
"## Glossary",
"## Requirements"
]
for section in required_sections:
if section not in content:
errors.append(f"Missing required section: {section}")
# Check for user stories
user_story_pattern = r"\*\*User Story:\*\*.*As a.*I want.*so that"
if not re.search(user_story_pattern, content, re.DOTALL):
warnings.append("No user stories found in requirements")
# Check for acceptance criteria
if "Acceptance Criteria" not in content:
errors.append("No acceptance criteria found")
# Check for SHALL statements
shall_count = content.count("SHALL")
if shall_count < 5:
warnings.append(f"Only {shall_count} SHALL statements found (recommend at least 5)")
# Check for requirement numbering
req_pattern = r"### Requirement \d+|### REQ-\d+"
req_matches = re.findall(req_pattern, content)
if len(req_matches) < 3:
warnings.append(f"Only {len(req_matches)} numbered requirements found")
# Check for placeholders
placeholder_pattern = r"\[.*?\]"
placeholders = re.findall(placeholder_pattern, content)
if len(placeholders) > 10:
warnings.append(f"Found {len(placeholders)} placeholders - remember to fill them in")
return errors, warnings
def validate_design(self, content: str) -> Tuple[List[str], List[str]]:
"""Validate design document structure and content"""
errors = []
warnings = []
# Check required sections
required_sections = [
"## Overview",
"## System Architecture",
"## Data Flow",
"## Integration Points",
"## Components",
"## Data Models",
"## Deployment"
]
for section in required_sections:
if section not in content:
errors.append(f"Missing required section: {section}")
# Check for component map
if "Component Map" not in content and "| Component ID |" not in content:
errors.append("Missing Component Map table")
# Check for data flow specifications
if "Data Flow" not in content:
errors.append("Missing Data Flow specifications")
# Check for integration points
if "Integration Points" not in content:
errors.append("Missing Integration Points section")
# Check for system boundaries
if "System Boundaries" not in content and "In Scope" not in content:
warnings.append("Missing System Boundaries definition")
# Check for architecture diagram
if "```" not in content and "" not in content:
warnings.append("No architecture diagram found")
# Check for interfaces
if "class" not in content and "interface" not in content.lower():
warnings.append("No interface definitions found")
# Check for error handling
if "Error Handling" not in content and "error handling" not in content.lower():
warnings.append("No error handling section found")
# Check for performance targets
if "Performance" not in content and "performance" not in content.lower():
warnings.append("No performance targets specified")
# Check for Docker configuration
if "Docker" not in content and "docker" not in content:
warnings.append("No Docker configuration found")
return errors, warnings
def validate_tasks(self, content: str) -> Tuple[List[str], List[str]]:
"""Validate implementation plan structure and content"""
errors = []
warnings = []
# Check for project boundaries
if "## Project Boundaries" not in content:
errors.append("Missing Project Boundaries section")
if "Must Have" not in content:
warnings.append("Missing 'Must Have' scope definition")
if "Out of Scope" not in content:
warnings.append("Missing 'Out of Scope' definition")
# Check for deliverables
if "## Deliverables" not in content and "Deliverables by Phase" not in content:
warnings.append("Missing Deliverables section")
# Check for success criteria
if "Success Criteria" not in content:
warnings.append("Missing Success Criteria for deliverables")
# Check for task structure
phase_pattern = r"- \[[ x]\] \d+\."
phases = re.findall(phase_pattern, content)
if len(phases) == 0:
errors.append("No phases found in task list")
elif len(phases) < 3:
warnings.append(f"Only {len(phases)} phases found (recommend at least 3)")
# Check for subtasks
task_pattern = r" - \[[ x]\] \d+\.\d+"
tasks = re.findall(task_pattern, content)
if len(tasks) == 0:
errors.append("No tasks found in implementation plan")
elif len(tasks) < 10:
warnings.append(f"Only {len(tasks)} tasks found (recommend at least 10)")
# Check for requirement tracing
req_pattern = r"_Requirements:.*REQ-\d+|_Requirements:.*\d+\.\d+"
req_traces = re.findall(req_pattern, content)
if len(req_traces) == 0:
warnings.append("No requirement tracing found in tasks")
elif len(req_traces) < len(tasks) / 2:
warnings.append(f"Only {len(req_traces)} tasks have requirement tracing")
# Check for component involvement
comp_pattern = r"_Components:.*COMP-\d+"
comp_traces = re.findall(comp_pattern, content)
if len(comp_traces) == 0:
warnings.append("No component mapping found in tasks")
# Check for dependencies
dep_pattern = r"_Dependencies:"
dependencies = re.findall(dep_pattern, content)
if len(dependencies) == 0:
warnings.append("No task dependencies defined")
# Check completion status
completed_pattern = r"- \[x\]"
pending_pattern = r"- \[ \]"
completed = len(re.findall(completed_pattern, content))
pending = len(re.findall(pending_pattern, content))
if completed + pending > 0:
completion_rate = (completed / (completed + pending)) * 100
print(f"Task completion: {completed}/{completed + pending} ({completion_rate:.1f}%)")
return errors, warnings
def validate_consistency(self, req_content: str, design_content: str,
task_content: str) -> Tuple[List[str], List[str]]:
"""Check consistency across documents"""
errors = []
warnings = []
# Extract requirement IDs from requirements doc
req_ids = set()
req_pattern = r"### Requirement (\d+)|### REQ-(\d+)"
for match in re.finditer(req_pattern, req_content):
req_id = match.group(1) or match.group(2)
req_ids.add(f"REQ-{req_id}")
# Check if requirements are referenced in tasks
for req_id in req_ids:
if req_id not in task_content:
warnings.append(f"{req_id} not referenced in any tasks")
# Extract components from design
component_pattern = r"### .*(?:Service|Component|Manager|Engine|Handler)"
components = re.findall(component_pattern, design_content)
# Check if major components have corresponding tasks
for component in components:
component_name = component.replace("### ", "").strip()
if component_name.lower() not in task_content.lower():
warnings.append(f"Component '{component_name}' not mentioned in tasks")
return errors, warnings
def validate_all(self, req_file: str, design_file: str,
task_file: str) -> Dict[str, Tuple[List[str], List[str]]]:
"""Validate all three documents"""
results = {}
# Read files
with open(req_file, 'r') as f:
req_content = f.read()
with open(design_file, 'r') as f:
design_content = f.read()
with open(task_file, 'r') as f:
task_content = f.read()
# Validate individual documents
results['requirements'] = self.validate_requirements(req_content)
results['design'] = self.validate_design(design_content)
results['tasks'] = self.validate_tasks(task_content)
# Validate consistency
results['consistency'] = self.validate_consistency(
req_content, design_content, task_content
)
return results
def print_validation_results(results: Dict[str, Tuple[List[str], List[str]]]):
"""Print validation results in a formatted way"""
total_errors = 0
total_warnings = 0
for doc_name, (errors, warnings) in results.items():
print(f"\n{'='*50}")
print(f"Validation Results: {doc_name.upper()}")
print('='*50)
if errors:
print(f"\n❌ Errors ({len(errors)}):")
for error in errors:
print(f" - {error}")
total_errors += len(errors)
else:
print("\n✅ No errors found")
if warnings:
print(f"\n⚠️ Warnings ({len(warnings)}):")
for warning in warnings:
print(f" - {warning}")
total_warnings += len(warnings)
else:
print("\n✅ No warnings found")
# Summary
print(f"\n{'='*50}")
print("SUMMARY")
print('='*50)
if total_errors == 0 and total_warnings == 0:
print("✅ All documents are valid and complete!")
else:
print(f"Total Errors: {total_errors}")
print(f"Total Warnings: {total_warnings}")
if total_errors > 0:
print("\n⚠️ Please fix errors before using these documents")
else:
print("\n📝 Review warnings to improve document quality")
def main():
parser = argparse.ArgumentParser(description="Validate project planning documents")
parser.add_argument("--requirements", "-r", default="requirements.md",
help="Path to requirements document")
parser.add_argument("--design", "-d", default="design.md",
help="Path to design document")
parser.add_argument("--tasks", "-t", default="tasks.md",
help="Path to tasks/implementation plan")
args = parser.parse_args()
# Check if files exist
for filepath, name in [(args.requirements, "Requirements"),
(args.design, "Design"),
(args.tasks, "Tasks")]:
if not os.path.exists(filepath):
print(f"{name} file not found: {filepath}")
return 1
# Validate documents
validator = DocumentValidator()
results = validator.validate_all(args.requirements, args.design, args.tasks)
# Print results
print_validation_results(results)
# Return exit code based on errors
total_errors = sum(len(errors) for errors, _ in results.values())
return 1 if total_errors > 0 else 0
if __name__ == "__main__":
exit(main())