UNPKG

context-forge

Version:

AI orchestration platform with autonomous teams, enhancement planning, migration tools, 25+ slash commands, checkpoints & hooks. Multi-IDE: Claude, Cursor, Windsurf, Cline, Copilot

1,358 lines (1,343 loc) 70.5 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.generatePRP = generatePRP; /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/ban-ts-comment */ // @ts-nocheck const handlebars_1 = __importDefault(require("handlebars")); const fs_extra_1 = __importDefault(require("fs-extra")); const path_1 = __importDefault(require("path")); const validationCommands_1 = require("../data/validationCommands"); async function generatePRP(config, type = 'base') { const templatePath = path_1.default.join(__dirname, '../../templates/prp', `${type}.md`); const templateContent = await fs_extra_1.default.readFile(templatePath, 'utf-8'); // Register custom Handlebars helpers registerHandlebarsHelpers(); const template = handlebars_1.default.compile(templateContent); const context = createPRPContext(config, type); return template(context); } function registerHandlebarsHelpers() { // Helper to increment index for display handlebars_1.default.registerHelper('inc', function (value) { return value + 1; }); // Helper for conditional rendering handlebars_1.default.registerHelper('if_eq', function (a, b, options) { if (a === b) { return options.fn(this); } return options.inverse(this); }); } function createPRPContext(config, type) { const primaryFeature = config.features.find((f) => f.priority === 'must-have') || config.features[0]; const language = getLanguageFromTechStack(config.techStack); const testLanguage = getTestLanguageFromTechStack(config.techStack); const baseContext = { projectName: config.projectName, featureName: primaryFeature?.name || 'Core Feature', goal: `Implement ${primaryFeature?.name || 'core functionality'} for ${config.projectName}`, reasons: [ primaryFeature?.description || 'Enable core functionality', 'Provide value to end users', 'Establish foundation for future features', ], description: config.description, successCriteria: generateSuccessCriteria(config.features), documentation: generateDocumentation(config.techStack), projectStructure: generateProjectStructure(config.techStack), desiredStructure: generateDesiredStructure(config.techStack, config.features), language, testLanguage, gotchas: generateGotchas(config.techStack), tasks: generatePRPTasks(config.features, config.techStack), validationCommands: generateValidationCommands(config.techStack), integrationTests: generateIntegrationTests(config.features, config.techStack), expectedResult: 'All tests passing, feature working as expected', customValidation: [ 'Load testing with realistic data', 'End-to-end user journey testing', 'Performance benchmarking', 'Security scanning', ], checklist: generateChecklist(config.techStack), antiPatterns: generateAntiPatterns(config.techStack), }; if (type === 'base-enhanced') { return { ...baseContext, // Enhanced base template with AI docs and validation loops hasAiDocs: false, // Will be true when AI docs are added aiDocs: [], versionNotes: generateVersionNotes(config.techStack), modelPath: getModelPath(config.techStack), database: generateDatabaseIntegration(config.techStack), config: generateConfigIntegration(config.techStack), routes: generateRoutesIntegration(config.features, config.techStack), environment: generateEnvironmentVariables(config), testCases: generateDetailedTestCases(config.features, config.techStack), edgeCases: generateEdgeCases(config.features), logPath: getLogPath(config.techStack), creativeValidation: generateCreativeValidation(config), commonFixes: { syntax: generateCommonFixes(config.techStack, 'syntax'), tests: generateCommonFixes(config.techStack, 'tests'), }, }; } if (type === 'planning') { return { ...baseContext, featureName: primaryFeature?.name || config.projectName, executiveSummary: `Deep architectural planning for ${config.projectName} - ${config.description}`, problemStatement: generateProblemStatement(config), subProblems: generateSubProblems(config.features), constraints: generateConstraints(config), architectureDiagram: generateDetailedArchitectureDiagram(config), components: generateDetailedComponents(config), dataFlowDiagram: generateDetailedDataFlowDiagram(config), decisions: generateDetailedTechnicalDecisions(config), phase1Duration: '1 week', phase1Tasks: generatePhaseTasks(config, 1), phase2Duration: '2-3 weeks', phase2Tasks: generatePhaseTasks(config, 2), phase3Duration: '1-2 weeks', phase3Tasks: generatePhaseTasks(config, 3), risks: generateDetailedRisks(config), expectedUsers: '1000+ concurrent', expectedRPS: '100-500', dataVolume: '10GB initial, 1TB growth/year', optimizations: generateOptimizationStrategies(config), benchmarks: generateBenchmarks(config), attackVectors: generateAttackVectors(config), securityMeasures: generateSecurityMeasures(config), coverageTarget: 90, unitTestAreas: generateUnitTestAreas(config), performanceTests: generateDetailedPerformanceTests(config), securityTests: generateSecurityTests(config), metrics: generateMetrics(config), loggingPoints: generateLoggingPoints(config), traces: generateTraces(config.features), apiDocFormat: 'OpenAPI 3.0', apiDocLocation: '/docs/api', userDocs: generateUserDocumentation(config), devDocs: generateDeveloperDocumentation(config), externalResources: generateExternalResources(config), codeExamples: generateCodeExamples(config), proofOfConcepts: [], successMetrics: generateSuccessMetrics(config), milestones: generateMilestones(config), openQuestions: generateOpenQuestions(config), researchNotes: '', }; } if (type === 'spec') { const now = new Date(); return { ...baseContext, featureName: primaryFeature?.name || 'Core Feature', version: '1.0.0', status: 'Draft', author: 'Context Forge', createdDate: now.toISOString().split('T')[0], lastUpdated: now.toISOString().split('T')[0], reviewers: 'TBD', executiveSummary: `Technical specification for implementing ${primaryFeature?.name} in ${config.projectName}`, primaryObjectives: generatePrimaryObjectives(config.features), secondaryObjectives: generateSecondaryObjectives(config.features), inScope: config.features.filter((f) => f.priority === 'must-have').map((f) => f.name), outOfScope: config.features.filter((f) => f.priority === 'nice-to-have').map((f) => f.name), futureConsiderations: generateFutureConsiderations(config), systemContextDiagram: generateSystemContextDiagram(config), componentDiagram: generateComponentDiagram(config), techStack: generateTechStackDetails(config.techStack), functionalRequirements: generateDetailedFunctionalRequirements(config.features), nfrs: generateDetailedNFRs(config), endpoints: generateDetailedAPIEndpoints(config.features, config.techStack), hasGraphQL: false, hasWebSocket: config.features.some((f) => f.id === 'realtime'), websocketEvents: generateWebSocketEvents(config.features), domainModels: generateDetailedDomainModels(config.features, config.techStack), databaseSchema: generateDetailedDatabaseSchema(config.features, config.techStack), indexes: generateIndexes(config.features, config.techStack), hasMigration: true, migrationScript: generateMigrationScript(config.features, config.techStack), rollbackScript: generateRollbackScript(config.features, config.techStack), algorithms: generateAlgorithms(config.features), stateDiagram: generateStateDiagram(config), businessRules: generateDetailedBusinessRules(config.features), integrations: generateIntegrations(config), hasMessageQueue: false, authMethod: config.techStack.auth || 'JWT', roles: generateRoles(config), resources: generateResources(config.features), securityControls: generateSecurityControls(config), dataProtection: generateDataProtection(config), performanceTargets: generatePerformanceTargets(config), optimizations: generateOptimizations(config), cachingLayers: generateCachingLayers(config.techStack), testPyramid: generateTestPyramid(), coverageTarget: 90, unitTestSuites: generateUnitTestSuites(config), integrationTests: generateDetailedIntegrationTests(config.features), performanceTests: generateDetailedPerformanceTests(config), securityTests: generateSecurityTests(config), deploymentDiagram: generateDeploymentDiagram(config), environments: generateEnvironments(config), pipelineDiagram: generatePipelineDiagram(), pipelineStages: generatePipelineStages(), metrics: generateDetailedMetrics(config), logLevels: generateLogLevels(), healthChecks: generateHealthChecks(config), risks: generateDetailedRisks(config), dependencies: generateDetailedDependencies(config.techStack), constraints: generateDetailedConstraints(config), documentationDeliverables: generateDocumentationDeliverables(config), training: generateTrainingRequirements(config), techLead: 'TBD', productOwner: 'TBD', securityLead: 'TBD', architect: 'TBD', glossary: generateGlossary(config), references: generateReferences(config.techStack), changelog: [`v1.0.0 (${now.toISOString().split('T')[0]}) - Initial draft by Context Forge`], }; } if (type === 'task') { return { ...baseContext, taskName: primaryFeature?.name || 'Task', taskType: 'feature', priority: 'P1', estimatedTime: '4-8 hours', assignee: 'Developer', problemDescription: primaryFeature?.description || 'Task description', currentBehavior: 'N/A', expectedBehavior: generateExpectedBehavior(primaryFeature), usersAffected: 'All users', severity: 'Medium', businessImpact: 'Feature delivery', solutionSummary: `Implement ${primaryFeature?.name} following project patterns`, implementationSteps: generateImplementationSteps(primaryFeature, config.techStack), keyFiles: generateKeyFiles(config.techStack, primaryFeature), patterns: generatePatterns(config.techStack), unitTests: generateTaskUnitTests(primaryFeature, config.techStack), integrationTests: generateTaskIntegrationTests(primaryFeature), manualTests: generateManualTests(primaryFeature), syntaxCommand: (0, validationCommands_1.getValidationCommands)(config.techStack).syntax?.[0] || 'npm run lint', testCommand: (0, validationCommands_1.getValidationCommands)(config.techStack).tests?.[0] || 'npm test', integrationCommand: (0, validationCommands_1.getValidationCommands)(config.techStack).start || 'npm run dev', verificationSteps: generateVerificationSteps(primaryFeature), rollbackSteps: ['Revert commit', 'Deploy previous version', 'Verify rollback successful'], documentationNeeded: false, relatedItems: [], resources: generateTaskResources(config.techStack), notes: '', lintCommand: (0, validationCommands_1.getValidationCommands)(config.techStack).lint || 'npm run lint', devCommand: (0, validationCommands_1.getValidationCommands)(config.techStack).start || 'npm run dev', buildCommand: (0, validationCommands_1.getValidationCommands)(config.techStack).build || 'npm run build', }; } // Add planning-specific context if (type === 'planning') { baseContext.architectureDiagram = generateArchitectureDiagram(config); baseContext.dataFlowDiagram = generateDataFlowDiagram(config); baseContext.technicalDecisions = generateTechnicalDecisions(config); baseContext.implementationPhases = generateImplementationPhases(config); baseContext.risks = generateRisks(config); baseContext.securityConsiderations = generateSecurityConsiderations(config); baseContext.performanceRequirements = generatePerformanceRequirements(config); baseContext.monitoringStrategy = generateMonitoringStrategy(config); baseContext.futureConsiderations = generateFutureConsiderations(config); } // Add spec-specific context if (type === 'spec') { baseContext.functionalRequirements = generateFunctionalRequirements(config.features); baseContext.nonFunctionalRequirements = generateNonFunctionalRequirements(config); baseContext.apiEndpoints = generateAPIEndpoints(config.features, config.techStack); baseContext.dataEntities = generateDataEntities(config.features, config.techStack); baseContext.databaseSchema = generateDatabaseSchema(config.features, config.techStack); baseContext.businessRules = generateBusinessRules(config.features); baseContext.errorScenarios = generateErrorScenarios(config.features); baseContext.unitTestStrategy = generateUnitTestStrategy(config); baseContext.integrationTestScenarios = generateIntegrationTestScenarios(config.features); baseContext.performanceTests = generatePerformanceTests(config); baseContext.securityRequirements = generateSecurityRequirements(config); baseContext.externalDependencies = generateExternalDependencies(config.techStack); } return baseContext; } function getLanguageFromTechStack(techStack) { if (techStack.backend === 'fastapi' || techStack.backend === 'django' || techStack.backend === 'flask') { return 'python'; } if (techStack.backend === 'spring-boot') { return 'java'; } if (techStack.backend === 'rails') { return 'ruby'; } if (techStack.backend === 'aspnet') { return 'csharp'; } if (techStack.backend === 'go') { return 'go'; } return 'typescript'; } function getTestLanguageFromTechStack(techStack) { const language = getLanguageFromTechStack(techStack); if (language === 'python') return 'python'; if (language === 'java') return 'java'; if (language === 'ruby') return 'ruby'; if (language === 'csharp') return 'csharp'; if (language === 'go') return 'go'; return 'typescript'; } function generateSuccessCriteria(features) { const criteria = []; features .filter((f) => f.priority === 'must-have') .forEach((feature) => { if (feature.id === 'auth') { criteria.push('Users can register and login successfully'); criteria.push('JWT tokens are properly validated'); criteria.push('Protected routes require authentication'); } else if (feature.id === 'crud') { criteria.push('All CRUD operations work correctly'); criteria.push('Data validation is enforced'); criteria.push('Error handling provides meaningful feedback'); } else if (feature.id === 'api-docs') { criteria.push('API documentation is auto-generated and accurate'); criteria.push('All endpoints are documented with examples'); } else { criteria.push(`${feature.name} is fully functional`); } }); return criteria; } function generateDocumentation(techStack) { const docs = []; if (techStack.frontend === 'nextjs') { docs.push({ type: 'url', url: 'https://nextjs.org/docs', reason: 'Next.js 15 documentation for App Router and Server Components', }); } if (techStack.backend === 'fastapi') { docs.push({ type: 'url', url: 'https://fastapi.tiangolo.com/', reason: 'FastAPI documentation for async endpoints and Pydantic models', }); } if (techStack.database === 'postgresql') { docs.push({ type: 'url', url: 'https://www.postgresql.org/docs/', reason: 'PostgreSQL documentation for advanced queries and optimization', }); } return docs; } function generateProjectStructure(techStack) { if (techStack.frontend === 'nextjs') { return `project-root/ ├── src/ │ ├── app/ │ ├── components/ │ ├── lib/ │ └── types/ ├── public/ ├── tests/ └── package.json`; } if (techStack.backend === 'fastapi') { return `project-root/ ├── app/ │ ├── api/ │ ├── models/ │ ├── schemas/ │ └── services/ ├── tests/ └── requirements.txt`; } return `project-root/ ├── src/ ├── tests/ └── config/`; } function generateDesiredStructure(techStack, features) { // Generate structure based on features const structure = ['project-root/']; if (techStack.frontend) { structure.push('├── src/'); if (features.some((f) => f.id === 'auth')) { structure.push('│ ├── features/auth/'); } if (features.some((f) => f.id === 'dashboard')) { structure.push('│ ├── features/dashboard/'); } } return structure.join('\n'); } function generateGotchas(techStack) { const gotchas = []; if (techStack.frontend === 'nextjs') { gotchas.push('Next.js 15 requires "use client" directive for interactive components'); gotchas.push('Server Components cannot use browser APIs or event handlers'); } if (techStack.backend === 'fastapi') { gotchas.push('FastAPI requires async functions for endpoints to enable concurrency'); gotchas.push('Pydantic v2 has breaking changes from v1 - use v2 syntax'); } if (techStack.auth === 'jwt') { gotchas.push('Use RS256 algorithm for production JWT tokens, not HS256'); gotchas.push('Store refresh tokens in httpOnly cookies for security'); } return gotchas; } function generatePRPTasks(features, techStack) { const tasks = []; // Foundation task tasks.push({ name: 'Set up project foundation', action: 'CREATE', file: 'project structure', steps: [ 'Initialize project with package manager', 'Set up TypeScript/language configuration', 'Configure linting and formatting', 'Set up testing framework', ], }); // Feature-specific tasks features .filter((f) => f.priority === 'must-have') .forEach((feature) => { tasks.push({ name: `Implement ${feature.name}`, action: 'CREATE', file: `features/${feature.id}`, steps: feature.subtasks || [`Implement ${feature.name} functionality`], pseudocode: generatePseudocode(feature, techStack), }); }); return tasks; } function generatePseudocode(feature, techStack) { if (feature.id === 'auth' && techStack.backend === 'fastapi') { return `# Authentication endpoint @router.post("/login") async def login(credentials: LoginSchema): # Validate credentials user = await authenticate_user(credentials) if not user: raise HTTPException(401, "Invalid credentials") # Generate tokens access_token = create_access_token(user.id) refresh_token = create_refresh_token(user.id) # Return tokens return TokenResponse( access_token=access_token, refresh_token=refresh_token )`; } return '# TODO: Implement feature logic'; } function generateValidationCommands(techStack) { const validationSet = (0, validationCommands_1.getValidationCommands)(techStack); const commands = { syntax: validationSet.syntax || [], tests: validationSet.tests || [], start: validationSet.start || '', deployment: [ `${validationSet.build || 'npm run build'} # Build production version`, 'Run integration tests against staging', 'Deploy to staging environment', 'Run smoke tests on staging', 'Deploy to production with rollback plan', ], }; // Add type checking if available if (validationSet.typeCheck) { commands.syntax.push(validationSet.typeCheck); } // Add linting if available and not already in syntax if (validationSet.lint && !commands.syntax.includes(validationSet.lint)) { commands.syntax.push(validationSet.lint); } // Add security checks to deployment if available if (validationSet.security) { validationSet.security.forEach((secCmd) => { commands.deployment.push(`${secCmd} # Security scan`); }); } return commands; } function generateIntegrationTests(features, techStack) { const tests = []; if (features.some((f) => f.id === 'auth')) { if (techStack.backend === 'fastapi') { tests.push({ name: 'Authentication API Test', type: 'integration', description: 'Test user authentication endpoint', file: 'tests/integration/auth.test.js', assertions: ['Returns JWT token on successful login'], }); } } if (features.some((f) => f.id === 'crud')) { tests.push({ name: 'CRUD Operations Test', type: 'integration', description: 'Test basic CRUD operations', file: 'tests/integration/crud.test.js', assertions: [ 'Create: POST /api/items', 'Read: GET /api/items', 'Update: PUT /api/items/:id', 'Delete: DELETE /api/items/:id', ], }); } return tests; } function generateChecklist(techStack) { const checklist = [ 'All tests pass', 'No linting errors', 'No type errors', 'Manual test successful', 'Error cases handled gracefully', 'Logs are informative but not verbose', ]; if (techStack.frontend) { checklist.push('UI is responsive on mobile'); checklist.push('Accessibility requirements met'); } if (techStack.backend) { checklist.push('API endpoints return correct status codes'); checklist.push('Input validation is comprehensive'); } return checklist; } function generateAntiPatterns(techStack) { const antiPatterns = [ "Don't create new patterns when existing ones work", "Don't skip validation because 'it should work'", "Don't ignore failing tests - fix them", "Don't hardcode values that should be config", "Don't catch all exceptions - be specific", ]; if (techStack.frontend === 'nextjs') { antiPatterns.push("Don't use client components for static content"); antiPatterns.push("Don't fetch data in client components when server components can do it"); } if (techStack.backend === 'fastapi') { antiPatterns.push("Don't use sync functions in async context"); antiPatterns.push("Don't skip Pydantic validation"); } return antiPatterns; } // Planning-specific functions function generateArchitectureDiagram(_config) { return `graph TB A[Client] --> B[Frontend] B --> C[API Gateway] C --> D[Backend Services] D --> E[Database] D --> F[Cache]`; } function generateComponents(_config) { const components = []; if (_config.techStack.frontend) { components.push({ name: 'Frontend Application', purpose: 'User interface and client-side logic', responsibilities: ['Render UI', 'Handle user interactions', 'Make API calls'], dependencies: ['API Gateway', 'Authentication Service'], }); } if (_config.techStack.backend) { components.push({ name: 'Backend API', purpose: 'Business logic and data processing', responsibilities: ['Process requests', 'Validate data', 'Handle business rules'], dependencies: ['Database', 'Cache', 'External Services'], }); } return components; } function generateDataFlowDiagram(_config) { return `sequenceDiagram participant U as User participant F as Frontend participant A as API participant D as Database U->>F: Request F->>A: API Call A->>D: Query D-->>A: Data A-->>F: Response F-->>U: Display`; } function generateTechnicalDecisions(_config) { return [ { decision: 'Frontend Framework', options: [ { name: 'Next.js', description: 'Full-stack React framework' }, { name: 'React SPA', description: 'Single-page application' }, ], chosen: _config.techStack.frontend || 'Next.js', rationale: 'Provides SSR, routing, and optimization out of the box', }, ]; } function generateImplementationPhases(_config) { return [ { name: 'Foundation', duration: '1 week', goals: ['Set up project', 'Configure tools', 'Create base structure'], deliverables: ['Project skeleton', 'CI/CD pipeline', 'Development environment'], dependencies: undefined, }, { name: 'Core Features', duration: '2-3 weeks', goals: ['Implement must-have features', 'Create API endpoints', 'Build UI components'], deliverables: ['Working features', 'API documentation', 'Test coverage'], dependencies: ['Foundation'], }, ]; } function generateRisks(_config) { return [ { risk: 'Technical Complexity', probability: 'medium', impact: 'high', mitigation: 'Break down complex features, use proven patterns', }, ]; } function generateSecurityConsiderations(_config) { return [ 'Implement proper authentication and authorization', 'Validate all user inputs', 'Use HTTPS for all communications', 'Implement rate limiting', 'Regular security updates', ]; } function generatePerformanceRequirements(_config) { return [ { metric: 'Response Time', requirement: '< 200ms for API calls' }, { metric: 'Page Load', requirement: '< 3s initial load' }, { metric: 'Concurrent Users', requirement: 'Support 1000+ concurrent users' }, ]; } function generateMonitoringStrategy(_config) { return [ { area: 'Application Performance', metrics: ['Response times', 'Error rates', 'Throughput'], alerts: ['Response time > 500ms', 'Error rate > 1%'], }, ]; } function generateFutureConsiderations(_config) { return [ 'Microservices architecture for scaling', 'Multi-region deployment', 'Advanced caching strategies', 'Machine learning integration', ]; } // Spec-specific functions function generateFunctionalRequirements(features) { return features.map((feature, index) => ({ id: `FR${index + 1}`, title: feature.name, description: feature.description, criteria: feature.subtasks || [], })); } function generateNonFunctionalRequirements(_config) { return [ { category: 'Performance', requirements: [ { name: 'Response Time', value: '< 200ms' }, { name: 'Throughput', value: '1000 req/s' }, ], }, { category: 'Security', requirements: [ { name: 'Authentication', value: 'JWT-based' }, { name: 'Encryption', value: 'TLS 1.3' }, ], }, ]; } function generateAPIEndpoints(features, _techStack) { const endpoints = []; if (features.some((f) => f.id === 'auth')) { endpoints.push({ method: 'POST', path: '/api/auth/login', description: 'User login', requestExample: JSON.stringify({ email: 'user@example.com', password: 'password' }, null, 2), responseExample: JSON.stringify({ access_token: 'jwt...', refresh_token: 'jwt...' }, null, 2), statusCodes: [ { code: 200, description: 'Login successful' }, { code: 401, description: 'Invalid credentials' }, ], }); } return endpoints; } function generateDataEntities(features, _techStack) { const entities = []; if (features.some((f) => f.id === 'auth')) { entities.push({ name: 'User', schema: `interface User { id: string; email: string; password: string; // hashed createdAt: Date; updatedAt: Date; }`, relationships: ['Has many Sessions', 'Has many Tokens'], }); } return entities; } function generateDatabaseSchema(features, techStack) { if (techStack.database === 'postgresql' && features.some((f) => f.id === 'auth')) { return `CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), email VARCHAR(255) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX idx_users_email ON users(email);`; } return '-- Database schema to be defined'; } function generateBusinessRules(features) { const rules = []; if (features.some((f) => f.id === 'auth')) { rules.push({ rule: 'Password Requirements', condition: 'User sets password', action: 'Validate minimum 8 characters, 1 uppercase, 1 number', validation: 'Reject if requirements not met', }); } return rules; } function generateErrorScenarios(_features) { return [ { scenario: 'Invalid Input', code: 'VALIDATION_ERROR', message: 'The provided input is invalid', recovery: 'Return detailed validation errors', }, { scenario: 'Unauthorized Access', code: 'UNAUTHORIZED', message: 'Authentication required', recovery: 'Redirect to login', }, ]; } function generateUnitTestStrategy(_config) { return [ { component: 'API Endpoints', coverage: 90 }, { component: 'Business Logic', coverage: 95 }, { component: 'Data Models', coverage: 100 }, ]; } function generateIntegrationTestScenarios(features) { return features .filter((f) => f.priority === 'must-have') .map((f) => `End-to-end test for ${f.name}`); } function generatePerformanceTests(_config) { return [ { test: 'Load Test', criteria: 'Handle 1000 concurrent users' }, { test: 'Stress Test', criteria: 'Graceful degradation under load' }, ]; } function generateSecurityRequirements(_config) { return [ { requirement: 'Input Validation', implementation: 'Validate all inputs with Zod/Pydantic', validation: 'Penetration testing', }, { requirement: 'Authentication', implementation: 'JWT with refresh tokens', validation: 'Security audit', }, ]; } function generateExternalDependencies(techStack) { const deps = []; if (techStack.database === 'postgresql') { deps.push({ service: 'PostgreSQL', purpose: 'Primary database' }); } if (techStack.database?.includes('redis')) { deps.push({ service: 'Redis', purpose: 'Caching and sessions' }); } return deps; } function generateLibraryDependencies(techStack) { const libs = []; if (techStack.frontend === 'nextjs') { libs.push({ name: 'next', version: '^15.0.0', purpose: 'React framework' }); libs.push({ name: 'react', version: '^19.0.0', purpose: 'UI library' }); } if (techStack.backend === 'fastapi') { libs.push({ name: 'fastapi', version: '^0.100.0', purpose: 'Web framework' }); libs.push({ name: 'pydantic', version: '^2.0.0', purpose: 'Data validation' }); } return libs; } // Enhanced template generator functions function generateVersionNotes(techStack) { const notes = []; if (techStack.frontend === 'nextjs') { notes.push('Next.js 15 uses React 19 with new features'); notes.push('App Router is the recommended approach'); } if (techStack.backend === 'fastapi') { notes.push('FastAPI 0.100+ with Pydantic v2 support'); notes.push('Use async/await for all endpoints'); } return notes; } function getModelPath(techStack) { if (techStack.backend === 'fastapi') return 'app/models/'; if (techStack.backend === 'django') return 'apps/*/models.py'; if (techStack.backend === 'express') return 'src/models/'; return 'src/models/'; } function generateDatabaseIntegration(techStack) { const integration = []; if (techStack.database === 'postgresql') { integration.push({ name: 'PostgreSQL Migration', type: 'migration', description: 'Database schema migration', schema: 'public', operations: ['CREATE TABLE', 'ALTER TABLE', 'CREATE INDEX'], }); } return integration; } function generateConfigIntegration(techStack) { return [ { name: 'Environment Configuration', type: 'environment', description: 'Application configuration settings', file: techStack.frontend === 'nextjs' ? '.env.local' : '.env', values: { DATABASE_URL: 'Connection string for database', JWT_SECRET: 'Secret key for JWT tokens', API_URL: 'Base URL for API endpoints', }, }, ]; } function generateRoutesIntegration(features, techStack) { const routes = []; features.forEach((feature) => { if (feature.id === 'auth') { const file = techStack.backend === 'fastapi' ? 'app/api/auth.py' : 'routes/auth.js'; routes.push({ name: 'Authentication Route', path: '/auth/login', method: 'POST', description: 'User authentication endpoint', file, middleware: ['cors', 'helmet'], }); } }); return routes; } function generateEnvironmentVariables(_config) { const vars = [ { name: 'DATABASE_URL', type: 'string', description: 'Database connection string', value: 'postgresql://localhost/db', required: true, }, ]; if (_config.techStack.auth === 'jwt') { vars.push({ name: 'JWT_SECRET', type: 'string', description: 'JWT signing secret', value: 'dev-secret', required: true, }); } return vars; } function generateDetailedTestCases(features, _techStack) { const testCases = []; features.forEach((feature) => { if (feature.id === 'auth') { testCases.push({ name: 'login_success', description: 'User can login with valid credentials', implementation: ` # Arrange user = create_test_user() # Act response = client.post("/auth/login", { "email": user.email, "password": "testpass" }) # Assert assert response.status_code == 200 assert "access_token" in response.json()`, }); } }); return testCases; } function generateEdgeCases(features) { const edgeCases = ['Empty input handling', 'Maximum length validation']; if (features.some((f) => f.id === 'auth')) { edgeCases.push('SQL injection attempts'); edgeCases.push('Concurrent login attempts'); } return edgeCases; } function getLogPath(techStack) { if (techStack.backend === 'fastapi') return 'logs/app.log'; if (techStack.backend === 'express') return 'logs/combined.log'; return 'logs/application.log'; } function generateCreativeValidation(_config) { return [ { name: 'Load Testing', type: 'performance', description: 'Test with 1000 concurrent users', criteria: 'Response time < 500ms', tools: ['k6', 'artillery'], }, { name: 'Security Scan', type: 'security', description: 'Run OWASP ZAP scan', criteria: 'No high or critical vulnerabilities', tools: ['OWASP ZAP', 'Snyk'], }, ]; } function generateCommonFixes(techStack, type) { if (type === 'syntax') { if (techStack.frontend === 'nextjs') { return [ 'Missing "use client" directive', 'Import path issues - use @ alias', 'TypeScript strict mode errors', ]; } } if (type === 'tests') { return ['Mock external API calls', 'Set up test database', 'Clear test data between runs']; } return []; } // Planning template functions function generateProblemStatement(_config) { return `Build a ${_config.projectType} application that ${_config.description}. The system needs to handle ${_config.features.length} core features while maintaining scalability and performance.`; } function generateSubProblems(features) { return features.map((feature) => ({ name: feature.name, description: feature.description, complexity: feature.complexity || 'medium', dependencies: feature.dependencies || [], })); } function generateConstraints(_config) { return [ { type: 'Timeline', description: `${_config.timeline} delivery` }, { type: 'Team Size', description: `${_config.teamSize} team` }, { type: 'Budget', description: 'Cost-effective solution required' }, ]; } function generateDetailedArchitectureDiagram(_config) { return `graph TB subgraph "Client Layer" A[Web Browser] B[Mobile App] end subgraph "Application Layer" C[Load Balancer] D[Web Server] E[API Gateway] end subgraph "Service Layer" F[Auth Service] G[Business Logic] H[Background Jobs] end subgraph "Data Layer" I[(Database)] J[(Cache)] K[(File Storage)] end A --> C B --> C C --> D C --> E E --> F E --> G G --> I G --> J G --> H H --> I`; } function generateDetailedComponents(_config) { const components = generateComponents(_config); // Add more detail to each component return components.map((comp) => ({ ...comp, interfaces: ['REST API', 'WebSocket', 'GraphQL'], responsibilities: [...comp.responsibilities, 'Monitoring', 'Logging'], })); } function generateDetailedDataFlowDiagram(_config) { return `sequenceDiagram participant U as User participant C as Client participant LB as Load Balancer participant API as API Gateway participant Auth as Auth Service participant BL as Business Logic participant DB as Database participant Cache as Redis Cache U->>C: User Action C->>LB: HTTPS Request LB->>API: Route Request API->>Auth: Validate Token Auth->>Cache: Check Session Cache-->>Auth: Session Data Auth-->>API: Valid/Invalid API->>BL: Process Request BL->>DB: Query Data DB-->>BL: Result Set BL->>Cache: Cache Result BL-->>API: Response Data API-->>C: JSON Response C-->>U: Update UI`; } function generateDetailedTechnicalDecisions(_config) { return [ { title: 'Architecture Pattern', options: [ { name: 'Microservices', description: 'Distributed services', pros: 'Scalable', cons: 'Complex', }, { name: 'Monolith', description: 'Single application', pros: 'Simple', cons: 'Less scalable', }, ], decision: 'Modular Monolith', rationale: 'Balance between simplicity and future scalability', }, { title: 'Database Strategy', options: [ { name: 'Single DB', description: 'One database for all', pros: 'Simple', cons: 'Bottleneck', }, { name: 'Read Replicas', description: 'Master-slave setup', pros: 'Read scaling', cons: 'Complexity', }, ], decision: 'Single DB with read replicas', rationale: 'Start simple, add replicas as needed', }, ]; } function generatePhaseTasks(config, phase) { if (phase === 1) { return [ 'Set up development environment', 'Initialize project structure', 'Configure CI/CD pipeline', 'Set up database and migrations', 'Implement authentication foundation', ]; } if (phase === 2) { return config.features .filter((f) => f.priority === 'must-have') .map((f) => `Implement ${f.name}`); } return [ 'Performance optimization', 'Security hardening', 'Documentation completion', 'Deployment preparation', ]; } function generateDetailedRisks(_config) { return [ { title: 'Technical Debt', probability: 'high', impact: 'medium', mitigation: 'Regular refactoring sprints', contingency: 'Allocate 20% time for debt reduction', }, { title: 'Scalability Issues', probability: 'medium', impact: 'high', detection: 'Load testing metrics', mitigation: 'Design for horizontal scaling', contingency: 'Cloud auto-scaling', owner: 'Tech Lead', }, ]; } function generateOptimizationStrategies(_config) { return [ { area: 'Database', strategy: 'Query optimization and indexing' }, { area: 'Caching', strategy: 'Redis for session and API responses' }, { area: 'Frontend', strategy: 'Code splitting and lazy loading' }, ]; } function generateBenchmarks(_config) { return [ { metric: 'API Response Time', target: '< 100ms p95' }, { metric: 'Page Load Time', target: '< 2s' }, { metric: 'Database Query Time', target: '< 50ms' }, ]; } function generateAttackVectors(_config) { return [ { vector: 'SQL Injection', description: 'Malicious SQL in inputs', prevention: 'Parameterized queries', }, { vector: 'XSS', description: 'Script injection', prevention: 'Input sanitization' }, { vector: 'CSRF', description: 'Cross-site requests', prevention: 'CSRF tokens' }, ]; } function generateSecurityMeasures(_config) { return [ 'Implement rate limiting on all endpoints', 'Use HTTPS everywhere with HSTS', 'Regular security dependency updates', 'Input validation on all user data', 'Secure session management', ]; } function generateUnitTestAreas(_config) { return [ 'Authentication logic', 'Data validation', 'Business rules', 'Error handling', 'Utility functions', ]; } function generateDetailedPerformanceTests(_config) { return [ { scenario: 'Normal Load', description: '100 concurrent users', expected: 'All requests < 200ms', testName: 'Normal Load Test', type: 'Load', loadProfile: '100 users over 10 minutes', duration: '10 minutes', }, { scenario: 'Peak Load', description: '1000 concurrent users', expected: '95% requests < 500ms', testName: 'Peak Load Test', type: 'Stress', loadProfile: 'Ramp to 1000 users', duration: '30 minutes', }, ]; } function generateSecurityTests(_config) { return [ { test: 'OWASP ZAP Scan', description: 'Automated security testing', tool: 'OWASP ZAP', frequency: 'Weekly', }, { test: 'Dependency Scan', description: 'Check for vulnerabilities', tool: 'npm audit', frequency: 'Daily', }, ]; } function generateMetrics(_config) { return [ { name: 'Request Rate', description: 'Requests per second', threshold: '> 1000 RPS alert' }, { name: 'Error Rate', description: 'Failed requests percentage', threshold: '> 1% alert' }, { name: 'Response Time', description: 'Average response time', threshold: '> 500ms alert' }, ]; } function generateLoggingPoints(_config) { return [ { event: 'Authentication', details: 'Login attempts, failures, token generation' }, { event: 'API Requests', details: 'Method, path, user, duration, status' }, { event: 'Errors', details: 'Stack trace, context, user info' }, ]; } function generateTraces(features) { return features.filter((f) => f.priority === 'must-have').map((f) => `${f.name} complete flow`); } function generateUserDocumentation(_config) { return [ { type: 'User Guide', description: 'How to use the application' }, { type: 'API Reference', description: 'Endpoint documentation' }, ]; } function generateDeveloperDocumentation(_config) { return [ { type: 'Architecture Guide', description: 'System design and patterns' }, { type: 'Setup Guide', description: 'Development environment setup' }, ]; } function generateExternalResources(_config) { const resources = []; if (_config.techStack.frontend === 'nextjs') { resources.push({ title: 'Next.js 15 Documentation', url: 'https://nextjs.org/docs', insight: 'App Router patterns and best practices', }); } return resources; } function generateCodeExamples(_config) { return [ { title: 'Authentication Flow', language: getLanguageFromTechStack(_config.techStack), code: generatePseudocode({ id: 'auth', name: 'Authentication' }, _config.techStack), }, ]; } function generateSuccessMetrics(_config) { return [ { metric: 'User Adoption', target: '1000 active users in 3 months', howToMeasure: 'Analytics dashboard', }, { metric: 'Performance', target: '< 200ms average response', howToMeasure: 'APM monitoring' }, ]; } function generateMilestones(_config) { return [ { name: 'MVP Launch', date: '4 weeks', deliverables: ['Core features', 'Basic UI', 'Authentication'], criteria: ['All tests pass', 'Security review complete'], }, ]; } function generateOpenQuestions(_config) { return [ { question: 'Preferred cloud provider?', whoToAsk: 'DevOps team', deadline: 'Week 1' }, { question: 'Compliance requirements?', whoToAsk: 'Legal team', deadline: 'Week 2' }, ]; } // Spec template functions function generatePrimaryObjectives(features) { return features .filter((f) => f.priority === 'must-have') .map((f, i) => ({ id: `PO-${i + 1}`, description: f.description, metric: `${f.name} fully functional`, })); } function generateSecondaryObjectives(features) { return features.filter((f) => f.priority === 'should-have').map((f) => f.description); } function generateSystemContextDiagram(_config) { return `graph TB subgraph "External Systems" EXT1[Payment Gateway] EXT2[Email Service] EXT3[Analytics] end subgraph "Our System" SYS[${_config.projectName}] end subgraph "Users" U1[End Users] U2[Admins] U3[API Consumers] end U1 --> SYS U2 --> SYS