404 lines
12 KiB
TypeScript
404 lines
12 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
|
import { getApiUrl } from '@/lib/utils/api-url';
|
|
|
|
/**
|
|
* Simulates AI-powered V1 Launch Planning
|
|
* Uses complete project context to generate actionable plan
|
|
*/
|
|
export async function GET(
|
|
request: NextRequest,
|
|
{ params }: { params: Promise<{ projectId: string }> }
|
|
) {
|
|
try {
|
|
const { projectId } = await params;
|
|
|
|
// 1. Load complete project context
|
|
const contextResponse = await fetch(
|
|
getApiUrl(`/api/projects/${projectId}/context`, request)
|
|
);
|
|
|
|
if (!contextResponse.ok) {
|
|
return NextResponse.json(
|
|
{ error: 'Failed to load project context' },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
|
|
const context = await contextResponse.json();
|
|
|
|
// 2. Simulate AI Analysis
|
|
const aiAnalysis = analyzeProjectForV1Launch(context);
|
|
|
|
// 3. Generate V1 Launch Plan
|
|
const launchPlan = generateV1LaunchPlan(context, aiAnalysis);
|
|
|
|
return NextResponse.json({
|
|
projectContext: {
|
|
name: context.project.name,
|
|
vision: context.project.vision,
|
|
historicalData: {
|
|
totalDays: context.timeline.dateRange.totalDays,
|
|
activeDays: context.timeline.dateRange.activeDays,
|
|
commits: context.codebase.totalCommits,
|
|
sessions: context.activity.totalSessions,
|
|
messages: context.timeline.dataSources.cursor.totalMessages
|
|
}
|
|
},
|
|
aiAnalysis,
|
|
launchPlan,
|
|
nextSteps: generateNextSteps(launchPlan)
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('Error simulating launch plan:', error);
|
|
return NextResponse.json(
|
|
{
|
|
error: 'Failed to simulate launch plan',
|
|
details: error instanceof Error ? error.message : String(error)
|
|
},
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|
|
|
|
// Analyze project state for V1 launch readiness
|
|
function analyzeProjectForV1Launch(context: any) {
|
|
const analysis = {
|
|
currentState: determineCurrentState(context),
|
|
strengths: [],
|
|
gaps: [],
|
|
estimatedCompleteness: 0,
|
|
recommendations: []
|
|
};
|
|
|
|
// Analyze codebase maturity
|
|
if (context.codebase.totalCommits > 50) {
|
|
analysis.strengths.push('Active development with 63 commits');
|
|
}
|
|
|
|
if (context.codebase.totalLinesAdded > 100000) {
|
|
analysis.strengths.push('Substantial codebase (~104k lines added)');
|
|
}
|
|
|
|
// Analyze development activity
|
|
if (context.activity.totalSessions > 100) {
|
|
analysis.strengths.push(`Consistent development (${context.activity.totalSessions} sessions)`);
|
|
}
|
|
|
|
// Check for gaps
|
|
if (!context.project.vision) {
|
|
analysis.gaps.push('Product vision not documented');
|
|
} else {
|
|
analysis.strengths.push('Clear product vision defined');
|
|
}
|
|
|
|
if (context.documents.length === 0) {
|
|
analysis.gaps.push('No documentation uploaded (specs, PRDs, designs)');
|
|
}
|
|
|
|
// Check Git history span
|
|
const daysSinceStart = context.timeline.dateRange.totalDays;
|
|
if (daysSinceStart < 30) {
|
|
analysis.gaps.push('Project is in early stages (< 30 days old)');
|
|
} else if (daysSinceStart > 90) {
|
|
analysis.strengths.push('Mature project (90+ days of development)');
|
|
}
|
|
|
|
// Estimate completeness
|
|
const hasVision = context.project.vision ? 20 : 0;
|
|
const hasCode = context.codebase.totalCommits > 20 ? 40 : 20;
|
|
const hasActivity = context.activity.totalSessions > 50 ? 20 : 10;
|
|
const hasDocs = context.documents.length > 0 ? 20 : 0;
|
|
|
|
analysis.estimatedCompleteness = hasVision + hasCode + hasActivity + hasDocs;
|
|
|
|
// Generate recommendations
|
|
if (analysis.estimatedCompleteness < 60) {
|
|
analysis.recommendations.push('Focus on core functionality before launch');
|
|
analysis.recommendations.push('Document key features and user flows');
|
|
} else if (analysis.estimatedCompleteness < 80) {
|
|
analysis.recommendations.push('Prepare for beta testing');
|
|
analysis.recommendations.push('Set up monitoring and analytics');
|
|
} else {
|
|
analysis.recommendations.push('Ready for soft launch preparation');
|
|
}
|
|
|
|
return analysis;
|
|
}
|
|
|
|
// Determine current project state
|
|
function determineCurrentState(context: any): string {
|
|
const commits = context.codebase.totalCommits;
|
|
const days = context.timeline.dateRange.totalDays;
|
|
|
|
if (commits < 20) return 'Initial Development';
|
|
if (commits < 50) return 'Alpha Stage';
|
|
if (commits < 100 && days < 60) return 'Active Development';
|
|
return 'Pre-Launch';
|
|
}
|
|
|
|
// Generate V1 launch checklist
|
|
function generateV1LaunchPlan(context: any, analysis: any) {
|
|
const plan = {
|
|
phase: analysis.currentState,
|
|
estimatedCompletion: `${analysis.estimatedCompleteness}%`,
|
|
categories: [
|
|
{
|
|
name: 'Product Development',
|
|
status: analysis.estimatedCompleteness > 60 ? 'in_progress' : 'pending',
|
|
tasks: [
|
|
{
|
|
id: 'pd-1',
|
|
title: 'Core Feature Implementation',
|
|
status: context.codebase.totalCommits > 40 ? 'complete' : 'in_progress',
|
|
description: 'Build primary user-facing features',
|
|
dependencies: []
|
|
},
|
|
{
|
|
id: 'pd-2',
|
|
title: 'User Authentication & Authorization',
|
|
status: 'in_progress',
|
|
description: 'Secure login, signup, and permission system',
|
|
dependencies: ['pd-1']
|
|
},
|
|
{
|
|
id: 'pd-3',
|
|
title: 'Database Schema & Models',
|
|
status: context.codebase.totalLinesAdded > 50000 ? 'complete' : 'in_progress',
|
|
description: 'Define data structures and relationships',
|
|
dependencies: []
|
|
},
|
|
{
|
|
id: 'pd-4',
|
|
title: 'API Endpoints',
|
|
status: 'in_progress',
|
|
description: 'REST/GraphQL APIs for frontend communication',
|
|
dependencies: ['pd-3']
|
|
},
|
|
{
|
|
id: 'pd-5',
|
|
title: 'Error Handling & Logging',
|
|
status: 'pending',
|
|
description: 'Comprehensive error management and monitoring',
|
|
dependencies: ['pd-4']
|
|
}
|
|
]
|
|
},
|
|
{
|
|
name: 'Testing & Quality',
|
|
status: 'pending',
|
|
tasks: [
|
|
{
|
|
id: 'tq-1',
|
|
title: 'Unit Tests',
|
|
status: 'pending',
|
|
description: 'Test individual components and functions',
|
|
dependencies: ['pd-1']
|
|
},
|
|
{
|
|
id: 'tq-2',
|
|
title: 'Integration Tests',
|
|
status: 'pending',
|
|
description: 'Test system interactions',
|
|
dependencies: ['pd-4']
|
|
},
|
|
{
|
|
id: 'tq-3',
|
|
title: 'User Acceptance Testing',
|
|
status: 'pending',
|
|
description: 'Beta testing with real users',
|
|
dependencies: ['tq-1', 'tq-2']
|
|
},
|
|
{
|
|
id: 'tq-4',
|
|
title: 'Performance Testing',
|
|
status: 'pending',
|
|
description: 'Load testing and optimization',
|
|
dependencies: ['tq-2']
|
|
}
|
|
]
|
|
},
|
|
{
|
|
name: 'Documentation',
|
|
status: context.documents.length > 0 ? 'in_progress' : 'pending',
|
|
tasks: [
|
|
{
|
|
id: 'doc-1',
|
|
title: 'User Guide',
|
|
status: 'pending',
|
|
description: 'End-user documentation',
|
|
dependencies: ['pd-1']
|
|
},
|
|
{
|
|
id: 'doc-2',
|
|
title: 'API Documentation',
|
|
status: 'pending',
|
|
description: 'Developer-facing API docs',
|
|
dependencies: ['pd-4']
|
|
},
|
|
{
|
|
id: 'doc-3',
|
|
title: 'Onboarding Flow',
|
|
status: 'pending',
|
|
description: 'New user tutorial and setup',
|
|
dependencies: ['doc-1']
|
|
}
|
|
]
|
|
},
|
|
{
|
|
name: 'Infrastructure',
|
|
status: 'in_progress',
|
|
tasks: [
|
|
{
|
|
id: 'infra-1',
|
|
title: 'Production Environment Setup',
|
|
status: context.codebase.totalCommits > 30 ? 'complete' : 'in_progress',
|
|
description: 'Deploy to production servers',
|
|
dependencies: []
|
|
},
|
|
{
|
|
id: 'infra-2',
|
|
title: 'CI/CD Pipeline',
|
|
status: 'pending',
|
|
description: 'Automated testing and deployment',
|
|
dependencies: ['infra-1']
|
|
},
|
|
{
|
|
id: 'infra-3',
|
|
title: 'Monitoring & Alerts',
|
|
status: 'pending',
|
|
description: 'System health monitoring',
|
|
dependencies: ['infra-1']
|
|
},
|
|
{
|
|
id: 'infra-4',
|
|
title: 'Backup & Recovery',
|
|
status: 'pending',
|
|
description: 'Data backup strategy',
|
|
dependencies: ['infra-1']
|
|
}
|
|
]
|
|
},
|
|
{
|
|
name: 'Marketing & Launch',
|
|
status: 'pending',
|
|
tasks: [
|
|
{
|
|
id: 'mkt-1',
|
|
title: 'Landing Page',
|
|
status: 'pending',
|
|
description: 'Public-facing marketing site',
|
|
dependencies: []
|
|
},
|
|
{
|
|
id: 'mkt-2',
|
|
title: 'Email Marketing Setup',
|
|
status: 'pending',
|
|
description: 'Email campaigns and automation',
|
|
dependencies: ['mkt-1']
|
|
},
|
|
{
|
|
id: 'mkt-3',
|
|
title: 'Analytics Integration',
|
|
status: 'pending',
|
|
description: 'Track user behavior and metrics',
|
|
dependencies: ['pd-1']
|
|
},
|
|
{
|
|
id: 'mkt-4',
|
|
title: 'Launch Strategy',
|
|
status: 'pending',
|
|
description: 'Product Hunt, social media, PR',
|
|
dependencies: ['mkt-1', 'doc-1']
|
|
}
|
|
]
|
|
},
|
|
{
|
|
name: 'Legal & Compliance',
|
|
status: 'pending',
|
|
tasks: [
|
|
{
|
|
id: 'legal-1',
|
|
title: 'Privacy Policy',
|
|
status: 'pending',
|
|
description: 'GDPR/CCPA compliant privacy policy',
|
|
dependencies: []
|
|
},
|
|
{
|
|
id: 'legal-2',
|
|
title: 'Terms of Service',
|
|
status: 'pending',
|
|
description: 'User agreement and terms',
|
|
dependencies: []
|
|
},
|
|
{
|
|
id: 'legal-3',
|
|
title: 'Security Audit',
|
|
status: 'pending',
|
|
description: 'Third-party security review',
|
|
dependencies: ['pd-5']
|
|
}
|
|
]
|
|
}
|
|
],
|
|
timeline: {
|
|
estimated_days_to_v1: calculateEstimatedDays(analysis),
|
|
recommended_milestones: [
|
|
{
|
|
name: 'Alpha Release',
|
|
description: 'Internal testing with core features',
|
|
target: 'Week 1-2'
|
|
},
|
|
{
|
|
name: 'Beta Release',
|
|
description: 'Limited external user testing',
|
|
target: 'Week 3-4'
|
|
},
|
|
{
|
|
name: 'Soft Launch',
|
|
description: 'Public but limited announcement',
|
|
target: 'Week 5-6'
|
|
},
|
|
{
|
|
name: 'V1 Launch',
|
|
description: 'Full public launch',
|
|
target: 'Week 7-8'
|
|
}
|
|
]
|
|
}
|
|
};
|
|
|
|
return plan;
|
|
}
|
|
|
|
// Calculate estimated days to V1
|
|
function calculateEstimatedDays(analysis: any): number {
|
|
const completeness = analysis.estimatedCompleteness;
|
|
|
|
if (completeness > 80) return 14; // ~2 weeks
|
|
if (completeness > 60) return 30; // ~1 month
|
|
if (completeness > 40) return 60; // ~2 months
|
|
return 90; // ~3 months
|
|
}
|
|
|
|
// Generate immediate next steps
|
|
function generateNextSteps(plan: any) {
|
|
const nextSteps = [];
|
|
|
|
// Find first pending task in each category
|
|
for (const category of plan.categories) {
|
|
const pendingTask = category.tasks.find((t: any) => t.status === 'pending' || t.status === 'in_progress');
|
|
if (pendingTask && nextSteps.length < 5) {
|
|
nextSteps.push({
|
|
category: category.name,
|
|
task: pendingTask.title,
|
|
priority: nextSteps.length + 1,
|
|
description: pendingTask.description
|
|
});
|
|
}
|
|
}
|
|
|
|
return nextSteps;
|
|
}
|
|
|