feat(project): Complete Project Lifecycle capability with full TDD workflow
- Implement ProjectController with CRUD, status transitions, estimate/forecast - Add ProjectService with state machine validation - Extract ProjectStatusService for reusable state machine logic - Add ProjectPolicy for role-based authorization - Create ProjectSeeder with test data - Implement frontend project management UI with modal forms - Add projectService API client - Complete all 9 incomplete unit tests (ProjectModelTest, ProjectForecastTest, ProjectPolicyTest) - Fix E2E test timing issues with loading state waits - Add Scribe API documentation annotations - Improve forecasted effort validation messages with detailed feedback Test Results: - Backend: 49 passed (182 assertions) - Frontend Unit: 32 passed - E2E: 134 passed (Chromium + Firefox) Phase 3 Refactor: - Extract ProjectStatusService for state machine - Optimize project list query with status joins - Improve forecasted effort validation messages Phase 4 Document: - Add Scribe annotations to ProjectController - Generate API documentation
This commit is contained in:
102
frontend/src/lib/services/projectService.ts
Normal file
102
frontend/src/lib/services/projectService.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import { api } from './api';
|
||||
|
||||
export interface ProjectType {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface ProjectStatus {
|
||||
id: number;
|
||||
name: string;
|
||||
order?: number;
|
||||
}
|
||||
|
||||
export interface Project {
|
||||
id: string;
|
||||
code: string;
|
||||
title: string;
|
||||
type_id: number;
|
||||
status_id: number;
|
||||
type?: ProjectType;
|
||||
status?: ProjectStatus;
|
||||
approved_estimate?: string | number | null;
|
||||
forecasted_effort?: Record<string, number> | null;
|
||||
created_at?: string;
|
||||
updated_at?: string;
|
||||
}
|
||||
|
||||
export interface CreateProjectRequest {
|
||||
code: string;
|
||||
title: string;
|
||||
type_id: number;
|
||||
}
|
||||
|
||||
export interface UpdateProjectRequest {
|
||||
code?: string;
|
||||
title?: string;
|
||||
type_id?: number;
|
||||
}
|
||||
|
||||
export const projectService = {
|
||||
/**
|
||||
* Get all projects
|
||||
*/
|
||||
getAll: (statusId?: number, typeId?: number) => {
|
||||
const params = new URLSearchParams();
|
||||
if (statusId) params.append('status_id', String(statusId));
|
||||
if (typeId) params.append('type_id', String(typeId));
|
||||
const query = params.toString() ? `?${params.toString()}` : '';
|
||||
return api.get<Project[]>(`/projects${query}`);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a single project by ID
|
||||
*/
|
||||
getById: (id: string) => api.get<Project>(`/projects/${id}`),
|
||||
|
||||
/**
|
||||
* Create a new project
|
||||
*/
|
||||
create: (data: CreateProjectRequest) => api.post<Project>('/projects', data),
|
||||
|
||||
/**
|
||||
* Update project basic info (code, title, type)
|
||||
*/
|
||||
update: (id: string, data: UpdateProjectRequest) =>
|
||||
api.put<Project>(`/projects/${id}`, data),
|
||||
|
||||
/**
|
||||
* Delete a project
|
||||
*/
|
||||
delete: (id: string) => api.delete<{ message: string }>(`/projects/${id}`),
|
||||
|
||||
/**
|
||||
* Transition project status
|
||||
*/
|
||||
updateStatus: (id: string, statusId: number) =>
|
||||
api.put<Project>(`/projects/${id}/status`, { status_id: statusId }),
|
||||
|
||||
/**
|
||||
* Set approved estimate
|
||||
*/
|
||||
setEstimate: (id: string, estimate: number) =>
|
||||
api.put<Project>(`/projects/${id}/estimate`, { approved_estimate: estimate }),
|
||||
|
||||
/**
|
||||
* Set forecasted effort
|
||||
*/
|
||||
setForecast: (id: string, forecast: Record<string, number>) =>
|
||||
api.put<Project>(`/projects/${id}/forecast`, { forecasted_effort: forecast }),
|
||||
|
||||
/**
|
||||
* Get all project types
|
||||
*/
|
||||
getTypes: () => api.get<ProjectType[]>('/projects/types'),
|
||||
|
||||
/**
|
||||
* Get all project statuses
|
||||
*/
|
||||
getStatuses: () => api.get<ProjectStatus[]>('/projects/statuses'),
|
||||
};
|
||||
|
||||
export default projectService;
|
||||
Reference in New Issue
Block a user