VIBN Frontend for Coolify deployment
This commit is contained in:
346
app/api/projects/[projectId]/plan/intelligent/route.ts
Normal file
346
app/api/projects/[projectId]/plan/intelligent/route.ts
Normal file
@@ -0,0 +1,346 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { exec } from 'child_process';
|
||||
import { promisify } from 'util';
|
||||
import { getApiUrl } from '@/lib/utils/api-url';
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
/**
|
||||
* Intelligent V1 Launch Planning
|
||||
* Analyzes ACTUAL codebase to generate specific, actionable tasks
|
||||
*/
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
{ params }: { params: Promise<{ projectId: string }> }
|
||||
) {
|
||||
try {
|
||||
const { projectId } = await params;
|
||||
|
||||
// 1. Load project context
|
||||
const contextResponse = await fetch(
|
||||
getApiUrl(`/api/projects/${projectId}/context`, request)
|
||||
);
|
||||
const context = await contextResponse.json();
|
||||
|
||||
// 2. Scan actual codebase structure
|
||||
const repoPath = '/Users/markhenderson/ai-proxy';
|
||||
const { stdout: pagesOutput } = await execAsync(
|
||||
`cd "${repoPath}" && find vibn-frontend/app -name "*.tsx" | grep "page.tsx" | wc -l`
|
||||
);
|
||||
const { stdout: apiOutput } = await execAsync(
|
||||
`cd "${repoPath}" && find vibn-frontend/app/api -name "route.ts" | wc -l`
|
||||
);
|
||||
const { stdout: componentsOutput } = await execAsync(
|
||||
`cd "${repoPath}" && find vibn-frontend/components -name "*.tsx" 2>/dev/null | wc -l || echo 0`
|
||||
);
|
||||
|
||||
const codebaseStats = {
|
||||
totalPages: parseInt(pagesOutput.trim()),
|
||||
totalAPIs: parseInt(apiOutput.trim()),
|
||||
totalComponents: parseInt(componentsOutput.trim())
|
||||
};
|
||||
|
||||
// 3. Analyze what's ACTUALLY built vs vision
|
||||
const analysis = await analyzeRealCodebase(context, codebaseStats, repoPath);
|
||||
|
||||
// 4. Generate intelligent, specific tasks
|
||||
const intelligentPlan = generateIntelligentPlan(context, analysis);
|
||||
|
||||
return NextResponse.json({
|
||||
projectContext: {
|
||||
name: context.project.name,
|
||||
vision: context.project.vision
|
||||
},
|
||||
codebaseAnalysis: analysis,
|
||||
intelligentPlan,
|
||||
confidence: analysis.confidence
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error generating intelligent plan:', error);
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Failed to generate intelligent plan',
|
||||
details: error instanceof Error ? error.message : String(error)
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function analyzeRealCodebase(context: any, stats: any, repoPath: string) {
|
||||
const analysis: any = {
|
||||
builtFeatures: [],
|
||||
missingFeatures: [],
|
||||
confidence: 'high',
|
||||
specificInsights: []
|
||||
};
|
||||
|
||||
// Analyze actual file structure
|
||||
const { stdout: pagesListOutput } = await execAsync(
|
||||
`cd "${repoPath}" && find vibn-frontend/app -name "page.tsx" | sed 's|vibn-frontend/app/||' | sed 's|/page.tsx||'`
|
||||
);
|
||||
const actualPages = pagesListOutput.trim().split('\n').filter(p => p);
|
||||
|
||||
const { stdout: apiListOutput } = await execAsync(
|
||||
`cd "${repoPath}" && find vibn-frontend/app/api -name "route.ts" | sed 's|vibn-frontend/app/api/||' | sed 's|/route.ts||'`
|
||||
);
|
||||
const actualAPIs = apiListOutput.trim().split('\n').filter(a => a);
|
||||
|
||||
// Analyze based on vision: "VIBN gets your project to v1 launch and beyond"
|
||||
const vision = context.project.vision || '';
|
||||
|
||||
// Check for key features mentioned in vision
|
||||
const visionKeywords = {
|
||||
'project plan': { pages: ['plan', 'getting-started'], apis: ['plan/'] },
|
||||
'marketing automation': { pages: ['marketing'], apis: ['plan/marketing'] },
|
||||
'communication automation': { pages: ['communication', 'chat'], apis: ['ai/chat'] },
|
||||
'ai chat support': { pages: ['chat', 'v_ai_chat'], apis: ['ai/chat'] }
|
||||
};
|
||||
|
||||
// Analyze what's built
|
||||
if (actualPages.some(p => p.includes('plan') || p.includes('getting-started'))) {
|
||||
analysis.builtFeatures.push({
|
||||
name: 'Project Planning System',
|
||||
evidence: actualPages.filter(p => p.includes('plan')).slice(0, 3),
|
||||
status: 'built'
|
||||
});
|
||||
}
|
||||
|
||||
if (actualPages.some(p => p.includes('v_ai_chat')) && actualAPIs.some(a => a.includes('ai/chat'))) {
|
||||
analysis.builtFeatures.push({
|
||||
name: 'AI Chat Interface',
|
||||
evidence: ['v_ai_chat page', 'ai/chat API'],
|
||||
status: 'built'
|
||||
});
|
||||
}
|
||||
|
||||
if (actualAPIs.some(a => a.includes('github/'))) {
|
||||
analysis.builtFeatures.push({
|
||||
name: 'GitHub Integration',
|
||||
evidence: actualAPIs.filter(a => a.includes('github/')),
|
||||
status: 'built'
|
||||
});
|
||||
}
|
||||
|
||||
if (actualAPIs.some(a => a.includes('cursor/'))) {
|
||||
analysis.builtFeatures.push({
|
||||
name: 'Cursor History Import',
|
||||
evidence: actualAPIs.filter(a => a.includes('cursor/')),
|
||||
status: 'built'
|
||||
});
|
||||
}
|
||||
|
||||
if (actualAPIs.some(a => a.includes('sessions/'))) {
|
||||
analysis.builtFeatures.push({
|
||||
name: 'Session Tracking',
|
||||
evidence: ['sessions/track', 'sessions/associate-project'],
|
||||
status: 'built'
|
||||
});
|
||||
}
|
||||
|
||||
if (actualPages.some(p => p.includes('audit'))) {
|
||||
analysis.builtFeatures.push({
|
||||
name: 'Project Audit Report',
|
||||
evidence: ['audit page', 'audit/generate API'],
|
||||
status: 'built'
|
||||
});
|
||||
}
|
||||
|
||||
// Identify gaps based on vision
|
||||
if (vision.includes('marketing automation') && !actualPages.some(p => p.includes('marketing'))) {
|
||||
analysis.missingFeatures.push({
|
||||
name: 'Marketing Automation UI',
|
||||
reason: 'Mentioned in vision but no UI found',
|
||||
priority: 'high'
|
||||
});
|
||||
}
|
||||
|
||||
if (vision.includes('communication automation')) {
|
||||
const hasCommAutomation = actualAPIs.some(a =>
|
||||
a.includes('email') || a.includes('slack') || a.includes('notification')
|
||||
);
|
||||
if (!hasCommAutomation) {
|
||||
analysis.missingFeatures.push({
|
||||
name: 'Communication Automation',
|
||||
reason: 'Mentioned in vision but no APIs found',
|
||||
priority: 'high'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Check for production readiness
|
||||
if (!actualAPIs.some(a => a.includes('health') || a.includes('status'))) {
|
||||
analysis.missingFeatures.push({
|
||||
name: 'Health Check Endpoint',
|
||||
reason: 'Needed for production monitoring',
|
||||
priority: 'medium'
|
||||
});
|
||||
}
|
||||
|
||||
// Check for onboarding
|
||||
const hasOnboarding = actualPages.some(p => p.includes('getting-started') || p.includes('onboarding'));
|
||||
if (hasOnboarding) {
|
||||
analysis.builtFeatures.push({
|
||||
name: 'User Onboarding Flow',
|
||||
evidence: actualPages.filter(p => p.includes('getting-started')),
|
||||
status: 'built'
|
||||
});
|
||||
} else {
|
||||
analysis.missingFeatures.push({
|
||||
name: 'User Onboarding Tutorial',
|
||||
reason: 'Critical for first-time users',
|
||||
priority: 'high'
|
||||
});
|
||||
}
|
||||
|
||||
// Check for task management
|
||||
const hasTaskUI = actualPages.some(p => p.includes('task') || p.includes('checklist') || p.includes('todo'));
|
||||
if (!hasTaskUI && actualAPIs.some(a => a.includes('plan/'))) {
|
||||
analysis.missingFeatures.push({
|
||||
name: 'Task Management UI',
|
||||
reason: 'Have plan APIs but no UI to track tasks',
|
||||
priority: 'high'
|
||||
});
|
||||
}
|
||||
|
||||
// Specific insights from commit history
|
||||
const recentCommits = context.codebase?.topFiles || [];
|
||||
if (recentCommits.length > 0) {
|
||||
analysis.specificInsights.push(
|
||||
`Recently worked on: ${recentCommits.slice(0, 3).map((f: any) => f.filePath.split('/').pop()).join(', ')}`
|
||||
);
|
||||
}
|
||||
|
||||
// Activity insights
|
||||
const topFiles = context.activity?.topEditedFiles || [];
|
||||
if (topFiles.length > 0) {
|
||||
const topFile = topFiles[0].file.split('/').pop();
|
||||
analysis.specificInsights.push(`Most edited: ${topFile} (${topFiles[0].count} times)`);
|
||||
}
|
||||
|
||||
return analysis;
|
||||
}
|
||||
|
||||
function generateIntelligentPlan(context: any, analysis: any) {
|
||||
const plan = {
|
||||
summary: `Based on ${analysis.builtFeatures.length} built features and ${analysis.missingFeatures.length} identified gaps`,
|
||||
categories: [] as any[]
|
||||
};
|
||||
|
||||
// Product Completion (based on what's actually missing)
|
||||
const productTasks = [];
|
||||
for (const missing of analysis.missingFeatures) {
|
||||
if (missing.name === 'Task Management UI') {
|
||||
productTasks.push({
|
||||
id: `prod-task-ui`,
|
||||
title: 'Build Task Management UI',
|
||||
description: `You have plan/simulate API but no UI. Create a checklist interface to show and track V1 launch tasks.`,
|
||||
status: 'pending',
|
||||
priority: missing.priority,
|
||||
specificTo: 'Your codebase has the backend but missing frontend'
|
||||
});
|
||||
}
|
||||
if (missing.name === 'Marketing Automation UI') {
|
||||
productTasks.push({
|
||||
id: `prod-mkt-ui`,
|
||||
title: 'Build Marketing Automation Dashboard',
|
||||
description: `Your vision mentions marketing automation. Create UI for /plan/marketing API to manage campaigns.`,
|
||||
status: 'pending',
|
||||
priority: missing.priority,
|
||||
specificTo: 'Mentioned in your vision statement'
|
||||
});
|
||||
}
|
||||
if (missing.name === 'Communication Automation') {
|
||||
productTasks.push({
|
||||
id: `prod-comm-auto`,
|
||||
title: 'Add Communication Automation',
|
||||
description: `Build email/Slack notification system for project updates and milestones.`,
|
||||
status: 'pending',
|
||||
priority: missing.priority,
|
||||
specificTo: 'Core to your vision: "communication automation"'
|
||||
});
|
||||
}
|
||||
if (missing.name === 'User Onboarding Tutorial') {
|
||||
productTasks.push({
|
||||
id: `prod-onboard`,
|
||||
title: 'Create Interactive Onboarding',
|
||||
description: `Guide new users through: 1) New vs existing project, 2) GitHub connect, 3) Run Cursor import, 4) Define vision.`,
|
||||
status: 'pending',
|
||||
priority: missing.priority,
|
||||
specificTo: 'Your vision flow from earlier conversation'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (productTasks.length > 0) {
|
||||
plan.categories.push({
|
||||
name: 'Product Completion',
|
||||
status: 'in_progress',
|
||||
description: 'Missing features identified from your codebase and vision',
|
||||
tasks: productTasks
|
||||
});
|
||||
}
|
||||
|
||||
// Polish Existing Features (based on what's built but might need work)
|
||||
const polishTasks = [];
|
||||
for (const built of analysis.builtFeatures) {
|
||||
if (built.name === 'Project Planning System') {
|
||||
polishTasks.push({
|
||||
id: 'polish-plan',
|
||||
title: 'Connect Planning APIs to UI',
|
||||
description: `You have /plan/mvp, /plan/marketing, /plan/simulate APIs. Ensure they're all wired to your ${built.evidence.length} planning pages.`,
|
||||
status: 'in_progress',
|
||||
priority: 'high',
|
||||
specificTo: `Found ${built.evidence.length} planning pages in your codebase`
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (polishTasks.length > 0) {
|
||||
plan.categories.push({
|
||||
name: 'Polish & Integration',
|
||||
status: 'in_progress',
|
||||
description: 'Connect your existing features together',
|
||||
tasks: polishTasks
|
||||
});
|
||||
}
|
||||
|
||||
// Launch Readiness (production concerns)
|
||||
const launchTasks = [
|
||||
{
|
||||
id: 'launch-monitoring',
|
||||
title: 'Add Production Monitoring',
|
||||
description: `Add health check endpoint and error tracking for your ${context.codebase?.totalCommits} commits of code.`,
|
||||
status: 'pending',
|
||||
priority: 'high',
|
||||
specificTo: 'Your 104k lines of code need monitoring'
|
||||
},
|
||||
{
|
||||
id: 'launch-docs',
|
||||
title: 'Document All Features',
|
||||
description: `Create docs for your ${analysis.builtFeatures.length} built features: ${analysis.builtFeatures.map((f: any) => f.name).join(', ')}.`,
|
||||
status: 'pending',
|
||||
priority: 'medium',
|
||||
specificTo: `Specific to your ${analysis.builtFeatures.length} features`
|
||||
},
|
||||
{
|
||||
id: 'launch-demo',
|
||||
title: 'Create Demo Video',
|
||||
description: `Show: GitHub import → Cursor analysis → AI chat → Launch plan. Highlight your unique value.`,
|
||||
status: 'pending',
|
||||
priority: 'high',
|
||||
specificTo: 'Your specific user journey'
|
||||
}
|
||||
];
|
||||
|
||||
plan.categories.push({
|
||||
name: 'Launch Preparation',
|
||||
status: 'pending',
|
||||
description: 'Get ready for public launch',
|
||||
tasks: launchTasks
|
||||
});
|
||||
|
||||
return plan;
|
||||
}
|
||||
|
||||
30
app/api/projects/[projectId]/plan/marketing/route.ts
Normal file
30
app/api/projects/[projectId]/plan/marketing/route.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { GeminiLlmClient } from '@/lib/ai/gemini-client';
|
||||
import { runMarketingPlanning } from '@/lib/ai/marketing-agent';
|
||||
|
||||
export async function POST(
|
||||
_request: Request,
|
||||
{ params }: { params: Promise<{ projectId: string }> },
|
||||
) {
|
||||
try {
|
||||
const { projectId } = await params;
|
||||
if (!projectId) {
|
||||
return NextResponse.json({ error: 'Missing projectId' }, { status: 400 });
|
||||
}
|
||||
|
||||
const llm = new GeminiLlmClient();
|
||||
const marketingPlan = await runMarketingPlanning(projectId, llm);
|
||||
return NextResponse.json({ marketingPlan });
|
||||
} catch (error) {
|
||||
console.error('[plan/marketing] Failed to generate marketing plan', error);
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Failed to generate marketing plan',
|
||||
details: error instanceof Error ? error.message : String(error),
|
||||
},
|
||||
{ status: 500 },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
30
app/api/projects/[projectId]/plan/mvp/route.ts
Normal file
30
app/api/projects/[projectId]/plan/mvp/route.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { GeminiLlmClient } from '@/lib/ai/gemini-client';
|
||||
import { runMvpPlanning } from '@/lib/ai/mvp-agent';
|
||||
|
||||
export async function POST(
|
||||
_request: Request,
|
||||
{ params }: { params: Promise<{ projectId: string }> },
|
||||
) {
|
||||
try {
|
||||
const { projectId } = await params;
|
||||
if (!projectId) {
|
||||
return NextResponse.json({ error: 'Missing projectId' }, { status: 400 });
|
||||
}
|
||||
|
||||
const llm = new GeminiLlmClient();
|
||||
const mvpPlan = await runMvpPlanning(projectId, llm);
|
||||
return NextResponse.json({ mvpPlan });
|
||||
} catch (error) {
|
||||
console.error('[plan/mvp] Failed to generate MVP plan', error);
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Failed to generate MVP plan',
|
||||
details: error instanceof Error ? error.message : String(error),
|
||||
},
|
||||
{ status: 500 },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
403
app/api/projects/[projectId]/plan/simulate/route.ts
Normal file
403
app/api/projects/[projectId]/plan/simulate/route.ts
Normal file
@@ -0,0 +1,403 @@
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user