feat(frontend): wire useProjects hook to SDK and enhance MSW handlers

- Regenerate API SDK with 77 endpoints (up from 61)
- Update useProjects hook to use SDK's listProjects function
- Add comprehensive project mock data for demo mode
- Add project CRUD handlers to MSW overrides
- Map API response to frontend ProjectListItem format
- Fix test files with required slug and autonomyLevel properties

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-03 02:22:44 +01:00
parent fe2104822e
commit 731a188a76
8 changed files with 4881 additions and 165 deletions

View File

@@ -0,0 +1,266 @@
/**
* Mock Project Data for Demo Mode
*
* Sample projects used by MSW handlers in demo mode.
*/
import type { ProjectResponse, ProjectStatus } from '@/lib/api/generated';
export interface ProjectListItem extends ProjectResponse {
// Extended UI fields (computed/stored separately in real app)
complexity?: 'script' | 'simple' | 'medium' | 'complex';
progress?: number;
openIssues?: number;
activeAgents?: number;
lastActivity?: string;
tags?: string[];
ownerName?: string;
}
export const sampleProjects: ProjectListItem[] = [
{
id: 'proj-001',
name: 'E-Commerce Platform Redesign',
slug: 'ecommerce-redesign',
description: 'Complete redesign of the e-commerce platform with modern UI/UX',
autonomy_level: 'milestone',
status: 'active',
settings: {},
owner_id: 'user-001',
created_at: '2025-11-15T10:00:00Z',
updated_at: new Date(Date.now() - 2 * 60 * 1000).toISOString(),
agent_count: 5,
issue_count: 70,
active_sprint_name: 'Sprint 3',
// Extended fields
complexity: 'complex',
progress: 67,
openIssues: 12,
activeAgents: 4,
lastActivity: '2 minutes ago',
tags: ['e-commerce', 'frontend', 'ux'],
ownerName: 'Felipe Cardoso',
},
{
id: 'proj-002',
name: 'Mobile Banking App',
slug: 'mobile-banking',
description: 'Native mobile app for banking services with biometric authentication',
autonomy_level: 'full_control',
status: 'active',
settings: {},
owner_id: 'user-001',
created_at: '2025-11-20T09:00:00Z',
updated_at: new Date(Date.now() - 15 * 60 * 1000).toISOString(),
agent_count: 5,
issue_count: 45,
active_sprint_name: 'Sprint 2',
complexity: 'complex',
progress: 45,
openIssues: 8,
activeAgents: 5,
lastActivity: '15 minutes ago',
tags: ['mobile', 'fintech', 'security'],
ownerName: 'Felipe Cardoso',
},
{
id: 'proj-003',
name: 'Internal HR Portal',
slug: 'hr-portal',
description: 'Employee self-service portal for HR operations',
autonomy_level: 'milestone',
status: 'paused',
settings: {},
owner_id: 'user-002',
created_at: '2025-10-01T08:00:00Z',
updated_at: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString(),
agent_count: 3,
issue_count: 25,
active_sprint_name: 'Sprint 1',
complexity: 'medium',
progress: 23,
openIssues: 5,
activeAgents: 0,
lastActivity: '2 days ago',
tags: ['internal', 'hr', 'portal'],
ownerName: 'Maria Santos',
},
{
id: 'proj-004',
name: 'API Gateway Modernization',
slug: 'api-gateway',
description: 'Migrate legacy API gateway to cloud-native architecture',
autonomy_level: 'autonomous',
status: 'active',
settings: {},
owner_id: 'user-001',
created_at: '2025-12-01T11:00:00Z',
updated_at: new Date(Date.now() - 60 * 60 * 1000).toISOString(),
agent_count: 3,
issue_count: 40,
active_sprint_name: 'Sprint 4',
complexity: 'complex',
progress: 82,
openIssues: 3,
activeAgents: 2,
lastActivity: '1 hour ago',
tags: ['api', 'cloud', 'infrastructure'],
ownerName: 'Felipe Cardoso',
},
{
id: 'proj-005',
name: 'Customer Analytics Dashboard',
slug: 'analytics-dashboard',
description: 'Real-time analytics dashboard for customer behavior insights',
autonomy_level: 'milestone',
status: 'completed',
settings: {},
owner_id: 'user-003',
created_at: '2025-09-01T10:00:00Z',
updated_at: new Date(Date.now() - 14 * 24 * 60 * 60 * 1000).toISOString(),
agent_count: 0,
issue_count: 50,
active_sprint_name: null,
complexity: 'medium',
progress: 100,
openIssues: 0,
activeAgents: 0,
lastActivity: '2 weeks ago',
tags: ['analytics', 'ml', 'dashboard'],
ownerName: 'Alex Johnson',
},
{
id: 'proj-006',
name: 'DevOps Pipeline Automation',
slug: 'devops-automation',
description: 'Automate CI/CD pipelines with AI-assisted deployments',
autonomy_level: 'milestone',
status: 'active',
settings: {},
owner_id: 'user-001',
created_at: '2025-12-10T14:00:00Z',
updated_at: new Date(Date.now() - 30 * 60 * 1000).toISOString(),
agent_count: 4,
issue_count: 30,
active_sprint_name: 'Sprint 1',
complexity: 'medium',
progress: 35,
openIssues: 6,
activeAgents: 3,
lastActivity: '30 minutes ago',
tags: ['devops', 'automation', 'ci-cd'],
ownerName: 'Felipe Cardoso',
},
{
id: 'proj-007',
name: 'Inventory Management System',
slug: 'inventory-system',
description: 'Warehouse inventory tracking with barcode scanning',
autonomy_level: 'full_control',
status: 'archived',
settings: {},
owner_id: 'user-002',
created_at: '2025-06-15T08:00:00Z',
updated_at: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString(),
agent_count: 0,
issue_count: 80,
active_sprint_name: null,
complexity: 'simple',
progress: 100,
openIssues: 0,
activeAgents: 0,
lastActivity: '1 month ago',
tags: ['inventory', 'warehouse', 'logistics'],
ownerName: 'Maria Santos',
},
{
id: 'proj-008',
name: 'Customer Support Chatbot',
slug: 'support-chatbot',
description: 'AI-powered chatbot for 24/7 customer support',
autonomy_level: 'autonomous',
status: 'active',
settings: {},
owner_id: 'user-003',
created_at: '2025-12-05T09:00:00Z',
updated_at: new Date(Date.now() - 45 * 60 * 1000).toISOString(),
agent_count: 3,
issue_count: 35,
active_sprint_name: 'Sprint 2',
complexity: 'medium',
progress: 58,
openIssues: 4,
activeAgents: 2,
lastActivity: '45 minutes ago',
tags: ['ai', 'chatbot', 'support'],
ownerName: 'Alex Johnson',
},
];
// In-memory store for demo mode (allows create/update/delete)
let projectsStore = [...sampleProjects];
export function getProjects(): ProjectListItem[] {
return projectsStore;
}
export function getProjectById(id: string): ProjectListItem | undefined {
return projectsStore.find((p) => p.id === id);
}
export function getProjectBySlug(slug: string): ProjectListItem | undefined {
return projectsStore.find((p) => p.slug === slug);
}
export function createProject(data: Partial<ProjectListItem>): ProjectListItem {
const newProject: ProjectListItem = {
id: `proj-${Date.now()}`,
name: data.name || 'New Project',
slug: data.slug || data.name?.toLowerCase().replace(/\s+/g, '-') || `project-${Date.now()}`,
description: data.description || null,
autonomy_level: data.autonomy_level || 'milestone',
status: 'active',
settings: data.settings || {},
owner_id: data.owner_id || 'user-001',
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
agent_count: 0,
issue_count: 0,
active_sprint_name: null,
complexity: data.complexity || 'medium',
progress: 0,
openIssues: 0,
activeAgents: 0,
lastActivity: 'Just now',
tags: data.tags || [],
ownerName: 'Demo User',
};
projectsStore.unshift(newProject);
return newProject;
}
export function updateProject(
id: string,
data: Partial<ProjectListItem>
): ProjectListItem | undefined {
const index = projectsStore.findIndex((p) => p.id === id);
if (index === -1) return undefined;
projectsStore[index] = {
...projectsStore[index],
...data,
updated_at: new Date().toISOString(),
};
return projectsStore[index];
}
export function deleteProject(id: string): boolean {
const index = projectsStore.findIndex((p) => p.id === id);
if (index === -1) return false;
projectsStore.splice(index, 1);
return true;
}
export function resetProjects(): void {
projectsStore = [...sampleProjects];
}

View File

@@ -8,7 +8,7 @@
*
* For custom handler behavior, use src/mocks/handlers/overrides.ts
*
* Generated: 2025-12-30T02:14:59.598Z
* Generated: 2026-01-03T01:13:34.961Z
*/
import { http, HttpResponse, delay } from 'msw';
@@ -603,4 +603,544 @@ export const generatedHandlers = [
message: 'Operation successful'
});
}),
/**
* Create Project
*/
http.post(`${API_BASE_URL}/api/v1/projects`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* List Projects
*/
http.get(`${API_BASE_URL}/api/v1/projects`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Get Project
*/
http.get(`${API_BASE_URL}/api/v1/projects/:project_id`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Update Project
*/
http.patch(`${API_BASE_URL}/api/v1/projects/:project_id`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Archive Project
*/
http.delete(`${API_BASE_URL}/api/v1/projects/:project_id`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Get Project by Slug
*/
http.get(`${API_BASE_URL}/api/v1/projects/slug/:slug`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Pause Project
*/
http.post(`${API_BASE_URL}/api/v1/projects/:project_id/pause`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Resume Project
*/
http.post(`${API_BASE_URL}/api/v1/projects/:project_id/resume`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Create Agent Type
*/
http.post(`${API_BASE_URL}/api/v1/agent-types`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* List Agent Types
*/
http.get(`${API_BASE_URL}/api/v1/agent-types`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Update Agent Type
*/
http.patch(`${API_BASE_URL}/api/v1/agent-types/:agent_type_id`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Deactivate Agent Type
*/
http.delete(`${API_BASE_URL}/api/v1/agent-types/:agent_type_id`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Get Agent Type
*/
http.get(`${API_BASE_URL}/api/v1/agent-types/:agent_type_id`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Get Agent Type by Slug
*/
http.get(`${API_BASE_URL}/api/v1/agent-types/slug/:slug`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Create Issue
*/
http.post(`${API_BASE_URL}/api/v1/projects/:project_id/issues`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* List Issues
*/
http.get(`${API_BASE_URL}/api/v1/projects/:project_id/issues`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Get Issue Statistics
*/
http.get(`${API_BASE_URL}/api/v1/projects/:project_id/issues/stats`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Get Issue
*/
http.get(`${API_BASE_URL}/api/v1/projects/:project_id/issues/:issue_id`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Update Issue
*/
http.patch(`${API_BASE_URL}/api/v1/projects/:project_id/issues/:issue_id`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Delete Issue
*/
http.delete(`${API_BASE_URL}/api/v1/projects/:project_id/issues/:issue_id`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Assign Issue
*/
http.post(`${API_BASE_URL}/api/v1/projects/:project_id/issues/:issue_id/assign`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Unassign Issue
*/
http.delete(`${API_BASE_URL}/api/v1/projects/:project_id/issues/:issue_id/assignment`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Trigger Issue Sync
*/
http.post(`${API_BASE_URL}/api/v1/projects/:project_id/issues/:issue_id/sync`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Spawn Agent Instance
*/
http.post(`${API_BASE_URL}/api/v1/projects/:project_id/agents`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* List Project Agents
*/
http.get(`${API_BASE_URL}/api/v1/projects/:project_id/agents`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Get Project Agent Metrics
*/
http.get(`${API_BASE_URL}/api/v1/projects/:project_id/agents/metrics`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Get Agent Details
*/
http.get(`${API_BASE_URL}/api/v1/projects/:project_id/agents/:agent_id`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Update Agent
*/
http.patch(`${API_BASE_URL}/api/v1/projects/:project_id/agents/:agent_id`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Terminate Agent
*/
http.delete(`${API_BASE_URL}/api/v1/projects/:project_id/agents/:agent_id`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Pause Agent
*/
http.post(`${API_BASE_URL}/api/v1/projects/:project_id/agents/:agent_id/pause`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Resume Agent
*/
http.post(`${API_BASE_URL}/api/v1/projects/:project_id/agents/:agent_id/resume`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Get Agent Metrics
*/
http.get(`${API_BASE_URL}/api/v1/projects/:project_id/agents/:agent_id/metrics`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Create Sprint
*/
http.post(`${API_BASE_URL}/api/v1/projects/:project_id/sprints`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* List Sprints
*/
http.get(`${API_BASE_URL}/api/v1/projects/:project_id/sprints`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Get Active Sprint
*/
http.get(`${API_BASE_URL}/api/v1/projects/:project_id/sprints/active`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Get Project Velocity
*/
http.get(`${API_BASE_URL}/api/v1/projects/:project_id/sprints/velocity`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Get Sprint Details
*/
http.get(`${API_BASE_URL}/api/v1/projects/:project_id/sprints/:sprint_id`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Update Sprint
*/
http.patch(`${API_BASE_URL}/api/v1/projects/:project_id/sprints/:sprint_id`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Delete Sprint
*/
http.delete(`${API_BASE_URL}/api/v1/projects/:project_id/sprints/:sprint_id`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Start Sprint
*/
http.post(`${API_BASE_URL}/api/v1/projects/:project_id/sprints/:sprint_id/start`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Complete Sprint
*/
http.post(`${API_BASE_URL}/api/v1/projects/:project_id/sprints/:sprint_id/complete`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Cancel Sprint
*/
http.post(`${API_BASE_URL}/api/v1/projects/:project_id/sprints/:sprint_id/cancel`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Get Sprint Issues
*/
http.get(`${API_BASE_URL}/api/v1/projects/:project_id/sprints/:sprint_id/issues`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Add Issue to Sprint
*/
http.post(`${API_BASE_URL}/api/v1/projects/:project_id/sprints/:sprint_id/issues`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
/**
* Remove Issue from Sprint
*/
http.delete(`${API_BASE_URL}/api/v1/projects/:project_id/sprints/:sprint_id/issues`, async ({ request, params }) => {
await delay(NETWORK_DELAY);
return HttpResponse.json({
success: true,
message: 'Operation successful'
});
}),
];

View File

@@ -14,6 +14,14 @@
import { http, HttpResponse, delay } from 'msw';
import { generateMockToken } from '../utils/tokens';
import { validateCredentials, setCurrentUser, currentUser } from '../data/users';
import {
getProjects,
getProjectById,
getProjectBySlug,
createProject,
updateProject,
deleteProject,
} from '../data/projects';
import config from '@/config/app.config';
const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:8000';
@@ -182,4 +190,164 @@ export const overrideHandlers = [
accounts: [],
});
}),
// ============================================
// PROJECT HANDLERS
// ============================================
/**
* List Projects
* Returns paginated list of projects with filtering support
*/
http.get(`${API_BASE_URL}/api/v1/projects`, async ({ request }) => {
await delay(NETWORK_DELAY);
const url = new URL(request.url);
const status = url.searchParams.get('status');
const search = url.searchParams.get('search');
const skip = parseInt(url.searchParams.get('skip') || '0');
const limit = parseInt(url.searchParams.get('limit') || '20');
let projects = getProjects();
// Filter by status
if (status && status !== 'all') {
projects = projects.filter((p) => p.status === status);
}
// Filter by search term
if (search) {
const searchLower = search.toLowerCase();
projects = projects.filter(
(p) =>
p.name.toLowerCase().includes(searchLower) ||
p.description?.toLowerCase().includes(searchLower)
);
}
const total = projects.length;
const paginatedProjects = projects.slice(skip, skip + limit);
const totalPages = Math.ceil(total / limit);
return HttpResponse.json({
data: paginatedProjects,
pagination: {
total,
page: Math.floor(skip / limit) + 1,
limit,
total_pages: totalPages,
has_next: skip + limit < total,
has_prev: skip > 0,
},
});
}),
/**
* Create Project
*/
http.post(`${API_BASE_URL}/api/v1/projects`, async ({ request }) => {
await delay(NETWORK_DELAY);
const body = (await request.json()) as any;
const newProject = createProject(body);
return HttpResponse.json(newProject, { status: 201 });
}),
/**
* Get Project by ID
*/
http.get(`${API_BASE_URL}/api/v1/projects/:projectId`, async ({ params }) => {
await delay(NETWORK_DELAY);
const { projectId } = params;
const project = getProjectById(projectId as string);
if (!project) {
return HttpResponse.json({ detail: 'Project not found' }, { status: 404 });
}
return HttpResponse.json(project);
}),
/**
* Get Project by Slug
*/
http.get(`${API_BASE_URL}/api/v1/projects/slug/:slug`, async ({ params }) => {
await delay(NETWORK_DELAY);
const { slug } = params;
const project = getProjectBySlug(slug as string);
if (!project) {
return HttpResponse.json({ detail: 'Project not found' }, { status: 404 });
}
return HttpResponse.json(project);
}),
/**
* Update Project
*/
http.patch(`${API_BASE_URL}/api/v1/projects/:projectId`, async ({ params, request }) => {
await delay(NETWORK_DELAY);
const { projectId } = params;
const body = (await request.json()) as any;
const updated = updateProject(projectId as string, body);
if (!updated) {
return HttpResponse.json({ detail: 'Project not found' }, { status: 404 });
}
return HttpResponse.json(updated);
}),
/**
* Archive (Delete) Project
*/
http.delete(`${API_BASE_URL}/api/v1/projects/:projectId`, async ({ params }) => {
await delay(NETWORK_DELAY);
const { projectId } = params;
const deleted = deleteProject(projectId as string);
if (!deleted) {
return HttpResponse.json({ detail: 'Project not found' }, { status: 404 });
}
return HttpResponse.json({ message: 'Project archived successfully' });
}),
/**
* Pause Project
*/
http.post(`${API_BASE_URL}/api/v1/projects/:projectId/pause`, async ({ params }) => {
await delay(NETWORK_DELAY);
const { projectId } = params;
const updated = updateProject(projectId as string, { status: 'paused' as any });
if (!updated) {
return HttpResponse.json({ detail: 'Project not found' }, { status: 404 });
}
return HttpResponse.json(updated);
}),
/**
* Resume Project
*/
http.post(`${API_BASE_URL}/api/v1/projects/:projectId/resume`, async ({ params }) => {
await delay(NETWORK_DELAY);
const { projectId } = params;
const updated = updateProject(projectId as string, { status: 'active' as any });
if (!updated) {
return HttpResponse.json({ detail: 'Project not found' }, { status: 404 });
}
return HttpResponse.json(updated);
}),
];