UNPKG

@jimmy2822/claude-code-sub-agents-mode

Version:

TypeScript Clean Architecture Multi-Agent Framework for Claude Code CLI Integration

161 lines (140 loc) 4.72 kB
/** * Project Controller - Presentation Layer * Handles HTTP requests for project management */ import { Request, Response } from 'express'; import { CreateProjectUseCase } from '../../application/use-cases/CreateProjectUseCase'; import { ApproveProjectUseCase } from '../../application/use-cases/ApproveProjectUseCase'; import { IProjectRepository } from '../../domain/repositories/IProjectRepository'; export class ProjectController { constructor( private projectRepository: IProjectRepository, private createProjectUseCase: CreateProjectUseCase, private approveProjectUseCase: ApproveProjectUseCase ) {} async getStatus(req: Request, res: Response): Promise<void> { try { const projects = await this.projectRepository.findAll(); res.json({ status: 'running', projects: projects.map(p => this.projectToDTO(p)), port: 3011 }); } catch (error) { res.status(500).json({ error: 'Failed to get status' }); } } async createProject(req: Request, res: Response): Promise<void> { try { const { requirement } = req.body; if (!requirement) { res.status(400).json({ error: 'Requirement is required' }); return; } const result = await this.createProjectUseCase.execute({ requirement }); if (result.success) { res.status(201).json({ success: true, project: this.projectToDTO(result.project), message: result.message }); } else { res.status(400).json({ success: false, error: result.message }); } } catch (error) { res.status(500).json({ error: 'Failed to create project', details: error instanceof Error ? error.message : 'Unknown error' }); } } async approveProject(req: Request, res: Response): Promise<void> { try { const projectId = parseInt(req.params.id); if (isNaN(projectId)) { res.status(400).json({ error: 'Invalid project ID' }); return; } const result = await this.approveProjectUseCase.execute({ projectId }); if (result.success) { res.json({ success: true, message: result.message }); } else { res.status(400).json({ success: false, error: result.message }); } } catch (error) { res.status(500).json({ error: 'Failed to approve project', details: error instanceof Error ? error.message : 'Unknown error' }); } } async deleteProject(req: Request, res: Response): Promise<void> { try { const projectId = parseInt(req.params.id); if (isNaN(projectId)) { res.status(400).json({ error: 'Invalid project ID' }); return; } const project = await this.projectRepository.findById(projectId); if (!project) { res.status(404).json({ error: 'Project not found' }); return; } await this.projectRepository.delete(projectId); res.json({ success: true, message: `Project #${projectId} deleted` }); } catch (error) { res.status(500).json({ error: 'Failed to delete project', details: error instanceof Error ? error.message : 'Unknown error' }); } } async deleteAllProjects(req: Request, res: Response): Promise<void> { try { const projects = await this.projectRepository.findAll(); const projectIds = projects.map(p => p.id); await this.projectRepository.deleteAll(); res.json({ success: true, message: `Deleted ${projectIds.length} projects`, deletedProjects: projectIds }); } catch (error) { res.status(500).json({ error: 'Failed to delete all projects', details: error instanceof Error ? error.message : 'Unknown error' }); } } private projectToDTO(project: any): any { return { id: project.id, originalRequirement: project.originalRequirement, status: project.status, phase: project.phase, requirements: project.requirements, acceptanceCriteria: project.acceptanceCriteria, plan: project.plan, assignedAgents: project.assignedAgents, progress: project.progress, updates: project.updates, createdAt: project.createdAt, lastUpdated: project.lastUpdated, estimatedComplexity: project.plan?.timeline?.estimatedDays <= 3 ? 'low' : project.plan?.timeline?.estimatedDays <= 7 ? 'medium' : 'high', suggestedAgents: project.plan?.resources || [] }; } }