diff options
Diffstat (limited to 'makima/src/llm/templates.rs')
| -rw-r--r-- | makima/src/llm/templates.rs | 1013 |
1 files changed, 2 insertions, 1011 deletions
diff --git a/makima/src/llm/templates.rs b/makima/src/llm/templates.rs index 8d3c04d..48b7515 100644 --- a/makima/src/llm/templates.rs +++ b/makima/src/llm/templates.rs @@ -1,13 +1,10 @@ -//! Template definitions for phase-appropriate file structures. +//! Contract type template definitions. //! -//! Templates provide starting structures for files based on the contract phase. -//! Each phase has templates suited for that stage of work. +//! Defines the available contract types and their workflow phases. use serde::{Deserialize, Serialize}; use utoipa::ToSchema; -use crate::db::models::BodyElement; - // ============================================================================= // Contract Type Templates (Workflow Definitions) // ============================================================================= @@ -81,1009 +78,3 @@ fn execute_contract_type() -> ContractTypeTemplate { is_builtin: true, } } - -// ============================================================================= -// File Templates -// ============================================================================= - -/// A file template with suggested structure -#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] -pub struct FileTemplate { - /// Template identifier - pub id: String, - /// Display name - pub name: String, - /// Contract phase this template is designed for - pub phase: String, - /// Brief description of what this template is for - pub description: String, - /// Suggested body elements (structure only - content to be filled by LLM) - pub suggested_body: Vec<BodyElement>, -} - -/// Get templates appropriate for a given contract phase -pub fn templates_for_phase(phase: &str) -> Vec<FileTemplate> { - match phase { - "research" => vec![ - research_notes_template(), - competitor_analysis_template(), - user_research_template(), - ], - "specify" => vec![ - requirements_template(), - user_stories_template(), - acceptance_criteria_template(), - ], - "plan" => vec![ - architecture_template(), - technical_design_template(), - task_breakdown_template(), - ], - "execute" => vec![ - dev_notes_template(), - test_plan_template(), - implementation_log_template(), - ], - "review" => vec![ - review_checklist_template(), - release_notes_template(), - retrospective_template(), - ], - _ => vec![], - } -} - -/// Get all available templates across all phases -pub fn all_templates() -> Vec<FileTemplate> { - vec![ - // Research phase - research_notes_template(), - competitor_analysis_template(), - user_research_template(), - // Specify phase - requirements_template(), - user_stories_template(), - acceptance_criteria_template(), - // Plan phase - architecture_template(), - technical_design_template(), - task_breakdown_template(), - // Execute phase - dev_notes_template(), - test_plan_template(), - implementation_log_template(), - // Review phase - review_checklist_template(), - release_notes_template(), - retrospective_template(), - ] -} - -// ============================================================================= -// Research Phase Templates -// ============================================================================= - -fn research_notes_template() -> FileTemplate { - FileTemplate { - id: "research-notes".to_string(), - name: "Research Notes".to_string(), - phase: "research".to_string(), - description: "Document findings, insights, and questions during research".to_string(), - suggested_body: vec![ - BodyElement::Heading { - level: 1, - text: "Research Notes".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Context".to_string(), - }, - BodyElement::Paragraph { - text: "Describe the research objective and scope...".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Key Findings".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "Finding 1...".to_string(), - "Finding 2...".to_string(), - "Finding 3...".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Open Questions".to_string(), - }, - BodyElement::List { - ordered: true, - items: vec![ - "Question to investigate...".to_string(), - "Area needing more research...".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Next Steps".to_string(), - }, - BodyElement::Paragraph { - text: "Outline follow-up actions...".to_string(), - }, - ], - } -} - -fn competitor_analysis_template() -> FileTemplate { - FileTemplate { - id: "competitor-analysis".to_string(), - name: "Competitor Analysis".to_string(), - phase: "research".to_string(), - description: "Analyze competitors and market positioning".to_string(), - suggested_body: vec![ - BodyElement::Heading { - level: 1, - text: "Competitor Analysis".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Market Overview".to_string(), - }, - BodyElement::Paragraph { - text: "Describe the market landscape...".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Competitor 1: [Name]".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "Strengths: ...".to_string(), - "Weaknesses: ...".to_string(), - "Key Features: ...".to_string(), - "Pricing: ...".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Competitive Advantages".to_string(), - }, - BodyElement::Paragraph { - text: "Our differentiation strategy...".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Gaps & Opportunities".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec!["Opportunity 1...".to_string(), "Opportunity 2...".to_string()], - }, - ], - } -} - -fn user_research_template() -> FileTemplate { - FileTemplate { - id: "user-research".to_string(), - name: "User Research".to_string(), - phase: "research".to_string(), - description: "Document user interviews, surveys, and persona insights".to_string(), - suggested_body: vec![ - BodyElement::Heading { - level: 1, - text: "User Research".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Research Method".to_string(), - }, - BodyElement::Paragraph { - text: "Describe the research methodology used...".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "User Personas".to_string(), - }, - BodyElement::Heading { - level: 3, - text: "Persona 1: [Name]".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "Role: ...".to_string(), - "Goals: ...".to_string(), - "Pain Points: ...".to_string(), - "Behaviors: ...".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Key Insights".to_string(), - }, - BodyElement::List { - ordered: true, - items: vec!["Insight from research...".to_string()], - }, - BodyElement::Heading { - level: 2, - text: "Recommendations".to_string(), - }, - BodyElement::Paragraph { - text: "Based on research findings...".to_string(), - }, - ], - } -} - -// ============================================================================= -// Specify Phase Templates -// ============================================================================= - -fn requirements_template() -> FileTemplate { - FileTemplate { - id: "requirements".to_string(), - name: "Requirements Document".to_string(), - phase: "specify".to_string(), - description: "Define functional and non-functional requirements".to_string(), - suggested_body: vec![ - BodyElement::Heading { - level: 1, - text: "Requirements Document".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Overview".to_string(), - }, - BodyElement::Paragraph { - text: "Brief description of the feature/project...".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Functional Requirements".to_string(), - }, - BodyElement::List { - ordered: true, - items: vec![ - "FR-001: The system shall...".to_string(), - "FR-002: Users must be able to...".to_string(), - "FR-003: ...".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Non-Functional Requirements".to_string(), - }, - BodyElement::List { - ordered: true, - items: vec![ - "NFR-001: Performance - ...".to_string(), - "NFR-002: Security - ...".to_string(), - "NFR-003: Scalability - ...".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Constraints".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "Technical constraints...".to_string(), - "Business constraints...".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Dependencies".to_string(), - }, - BodyElement::Paragraph { - text: "External dependencies and integrations...".to_string(), - }, - ], - } -} - -fn user_stories_template() -> FileTemplate { - FileTemplate { - id: "user-stories".to_string(), - name: "User Stories".to_string(), - phase: "specify".to_string(), - description: "Define features from the user's perspective".to_string(), - suggested_body: vec![ - BodyElement::Heading { - level: 1, - text: "User Stories".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Epic: [Feature Name]".to_string(), - }, - BodyElement::Paragraph { - text: "High-level description of the epic...".to_string(), - }, - BodyElement::Heading { - level: 3, - text: "US-001: [Story Title]".to_string(), - }, - BodyElement::Paragraph { - text: "As a [user type], I want to [action], so that [benefit].".to_string(), - }, - BodyElement::Heading { - level: 4, - text: "Acceptance Criteria".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "Given... When... Then...".to_string(), - "Given... When... Then...".to_string(), - ], - }, - BodyElement::Heading { - level: 3, - text: "US-002: [Story Title]".to_string(), - }, - BodyElement::Paragraph { - text: "As a [user type], I want to [action], so that [benefit].".to_string(), - }, - ], - } -} - -fn acceptance_criteria_template() -> FileTemplate { - FileTemplate { - id: "acceptance-criteria".to_string(), - name: "Acceptance Criteria".to_string(), - phase: "specify".to_string(), - description: "Define testable conditions for feature completion".to_string(), - suggested_body: vec![ - BodyElement::Heading { - level: 1, - text: "Acceptance Criteria".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Feature: [Name]".to_string(), - }, - BodyElement::Paragraph { - text: "Description of the feature being specified...".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Scenarios".to_string(), - }, - BodyElement::Heading { - level: 3, - text: "Scenario 1: [Happy Path]".to_string(), - }, - BodyElement::Code { - language: Some("gherkin".to_string()), - content: "Given [precondition]\nWhen [action]\nThen [expected result]".to_string(), - }, - BodyElement::Heading { - level: 3, - text: "Scenario 2: [Edge Case]".to_string(), - }, - BodyElement::Code { - language: Some("gherkin".to_string()), - content: "Given [precondition]\nWhen [action]\nThen [expected result]".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Out of Scope".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec!["Items explicitly not included...".to_string()], - }, - ], - } -} - -// ============================================================================= -// Plan Phase Templates -// ============================================================================= - -fn architecture_template() -> FileTemplate { - FileTemplate { - id: "architecture".to_string(), - name: "Architecture Document".to_string(), - phase: "plan".to_string(), - description: "Document system architecture and design decisions".to_string(), - suggested_body: vec![ - BodyElement::Heading { - level: 1, - text: "Architecture Document".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Overview".to_string(), - }, - BodyElement::Paragraph { - text: "High-level architecture description...".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "System Components".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "Component A: Description and responsibility".to_string(), - "Component B: Description and responsibility".to_string(), - "Component C: Description and responsibility".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Data Flow".to_string(), - }, - BodyElement::Paragraph { - text: "Describe how data flows through the system...".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Technology Stack".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "Frontend: ...".to_string(), - "Backend: ...".to_string(), - "Database: ...".to_string(), - "Infrastructure: ...".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Design Decisions".to_string(), - }, - BodyElement::Heading { - level: 3, - text: "ADR-001: [Decision Title]".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "Context: ...".to_string(), - "Decision: ...".to_string(), - "Consequences: ...".to_string(), - ], - }, - ], - } -} - -fn technical_design_template() -> FileTemplate { - FileTemplate { - id: "technical-design".to_string(), - name: "Technical Design".to_string(), - phase: "plan".to_string(), - description: "Detailed technical specification for implementation".to_string(), - suggested_body: vec![ - BodyElement::Heading { - level: 1, - text: "Technical Design".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Purpose".to_string(), - }, - BodyElement::Paragraph { - text: "What this design document covers...".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "API Design".to_string(), - }, - BodyElement::Code { - language: Some("typescript".to_string()), - content: "// Interface definitions\ninterface Example {\n // ...\n}".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Database Schema".to_string(), - }, - BodyElement::Code { - language: Some("sql".to_string()), - content: "-- Table definitions\nCREATE TABLE example (\n -- ...\n);".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Implementation Notes".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "Key implementation consideration...".to_string(), - "Performance consideration...".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Migration Strategy".to_string(), - }, - BodyElement::Paragraph { - text: "How to migrate from current state...".to_string(), - }, - ], - } -} - -fn task_breakdown_template() -> FileTemplate { - FileTemplate { - id: "task-breakdown".to_string(), - name: "Task Breakdown".to_string(), - phase: "plan".to_string(), - description: "Break down work into implementable tasks".to_string(), - suggested_body: vec![ - BodyElement::Heading { - level: 1, - text: "Task Breakdown".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Overview".to_string(), - }, - BodyElement::Paragraph { - text: "Summary of the work to be done...".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Phase 1: Foundation".to_string(), - }, - BodyElement::List { - ordered: true, - items: vec![ - "[ ] Task 1: Set up project structure".to_string(), - "[ ] Task 2: Configure development environment".to_string(), - "[ ] Task 3: Create base components".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Phase 2: Core Features".to_string(), - }, - BodyElement::List { - ordered: true, - items: vec![ - "[ ] Task 4: Implement feature A".to_string(), - "[ ] Task 5: Implement feature B".to_string(), - "[ ] Task 6: Add tests".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Phase 3: Polish & Deploy".to_string(), - }, - BodyElement::List { - ordered: true, - items: vec![ - "[ ] Task 7: Error handling".to_string(), - "[ ] Task 8: Documentation".to_string(), - "[ ] Task 9: Deployment".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Dependencies".to_string(), - }, - BodyElement::Paragraph { - text: "Task dependencies and blockers...".to_string(), - }, - ], - } -} - -// ============================================================================= -// Execute Phase Templates -// ============================================================================= - -fn dev_notes_template() -> FileTemplate { - FileTemplate { - id: "dev-notes".to_string(), - name: "Development Notes".to_string(), - phase: "execute".to_string(), - description: "Track implementation details, decisions, and learnings".to_string(), - suggested_body: vec![ - BodyElement::Heading { - level: 1, - text: "Development Notes".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Current Status".to_string(), - }, - BodyElement::Paragraph { - text: "Brief summary of implementation progress...".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Implementation Details".to_string(), - }, - BodyElement::Heading { - level: 3, - text: "[Component/Feature Name]".to_string(), - }, - BodyElement::Paragraph { - text: "How this was implemented and why...".to_string(), - }, - BodyElement::Code { - language: Some("typescript".to_string()), - content: "// Key code snippet or example".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Challenges & Solutions".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "Challenge: ... | Solution: ...".to_string(), - "Challenge: ... | Solution: ...".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "TODOs".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "[ ] Remaining item...".to_string(), - "[ ] Follow-up task...".to_string(), - ], - }, - ], - } -} - -fn test_plan_template() -> FileTemplate { - FileTemplate { - id: "test-plan".to_string(), - name: "Test Plan".to_string(), - phase: "execute".to_string(), - description: "Document testing strategy and test cases".to_string(), - suggested_body: vec![ - BodyElement::Heading { - level: 1, - text: "Test Plan".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Test Scope".to_string(), - }, - BodyElement::Paragraph { - text: "What is being tested and the testing approach...".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Test Types".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "Unit Tests: Component-level testing".to_string(), - "Integration Tests: API and service integration".to_string(), - "E2E Tests: User flow testing".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Test Cases".to_string(), - }, - BodyElement::Heading { - level: 3, - text: "TC-001: [Test Name]".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "Preconditions: ...".to_string(), - "Steps: ...".to_string(), - "Expected Result: ...".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Test Data".to_string(), - }, - BodyElement::Paragraph { - text: "Required test data and fixtures...".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Test Results".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "[ ] TC-001: Pending".to_string(), - "[ ] TC-002: Pending".to_string(), - ], - }, - ], - } -} - -fn implementation_log_template() -> FileTemplate { - FileTemplate { - id: "implementation-log".to_string(), - name: "Implementation Log".to_string(), - phase: "execute".to_string(), - description: "Chronological log of implementation progress".to_string(), - suggested_body: vec![ - BodyElement::Heading { - level: 1, - text: "Implementation Log".to_string(), - }, - BodyElement::Paragraph { - text: "Tracking daily progress and decisions...".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "[Date]".to_string(), - }, - BodyElement::Heading { - level: 3, - text: "Completed".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec!["What was accomplished...".to_string()], - }, - BodyElement::Heading { - level: 3, - text: "In Progress".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec!["Current work...".to_string()], - }, - BodyElement::Heading { - level: 3, - text: "Blockers".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec!["Any blockers or issues...".to_string()], - }, - BodyElement::Heading { - level: 3, - text: "Notes".to_string(), - }, - BodyElement::Paragraph { - text: "Additional context or decisions made...".to_string(), - }, - ], - } -} - -// ============================================================================= -// Review Phase Templates -// ============================================================================= - -fn review_checklist_template() -> FileTemplate { - FileTemplate { - id: "review-checklist".to_string(), - name: "Review Checklist".to_string(), - phase: "review".to_string(), - description: "Comprehensive checklist for code and feature review".to_string(), - suggested_body: vec![ - BodyElement::Heading { - level: 1, - text: "Review Checklist".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Code Quality".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "[ ] Code follows style guidelines".to_string(), - "[ ] No unnecessary complexity".to_string(), - "[ ] Functions are well-named and focused".to_string(), - "[ ] No dead code or commented-out code".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Testing".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "[ ] Unit tests pass".to_string(), - "[ ] Integration tests pass".to_string(), - "[ ] Edge cases covered".to_string(), - "[ ] Test coverage acceptable".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Security".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "[ ] No hardcoded credentials".to_string(), - "[ ] Input validation in place".to_string(), - "[ ] Authentication/authorization correct".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Documentation".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "[ ] README updated".to_string(), - "[ ] API documentation complete".to_string(), - "[ ] Inline comments where needed".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Review Notes".to_string(), - }, - BodyElement::Paragraph { - text: "Additional review comments and feedback...".to_string(), - }, - ], - } -} - -fn release_notes_template() -> FileTemplate { - FileTemplate { - id: "release-notes".to_string(), - name: "Release Notes".to_string(), - phase: "review".to_string(), - description: "Document changes for release communication".to_string(), - suggested_body: vec![ - BodyElement::Heading { - level: 1, - text: "Release Notes - v[X.Y.Z]".to_string(), - }, - BodyElement::Paragraph { - text: "Release date: [DATE]".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "Highlights".to_string(), - }, - BodyElement::Paragraph { - text: "Key features and improvements in this release...".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "New Features".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "Feature 1: Description".to_string(), - "Feature 2: Description".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Improvements".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "Improvement 1: Description".to_string(), - "Improvement 2: Description".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Bug Fixes".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "Fixed: Issue description".to_string(), - "Fixed: Issue description".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Breaking Changes".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec!["Breaking change description (if any)...".to_string()], - }, - BodyElement::Heading { - level: 2, - text: "Known Issues".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec!["Known issue (if any)...".to_string()], - }, - ], - } -} - -fn retrospective_template() -> FileTemplate { - FileTemplate { - id: "retrospective".to_string(), - name: "Retrospective".to_string(), - phase: "review".to_string(), - description: "Reflect on the project and capture learnings".to_string(), - suggested_body: vec![ - BodyElement::Heading { - level: 1, - text: "Retrospective".to_string(), - }, - BodyElement::Paragraph { - text: "Project: [Name] | Date: [DATE]".to_string(), - }, - BodyElement::Heading { - level: 2, - text: "What Went Well".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "Success 1...".to_string(), - "Success 2...".to_string(), - "Success 3...".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "What Could Be Improved".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "Area for improvement 1...".to_string(), - "Area for improvement 2...".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Lessons Learned".to_string(), - }, - BodyElement::List { - ordered: true, - items: vec![ - "Key lesson from this project...".to_string(), - "Technical insight gained...".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Action Items".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "[ ] Action to improve future projects...".to_string(), - "[ ] Process change to implement...".to_string(), - ], - }, - BodyElement::Heading { - level: 2, - text: "Metrics".to_string(), - }, - BodyElement::List { - ordered: false, - items: vec![ - "Timeline: Planned vs Actual".to_string(), - "Scope: Delivered vs Planned".to_string(), - "Quality: Bug count, test coverage".to_string(), - ], - }, - ], - } -} |
