## Autogenerated by Scribe. DO NOT MODIFY. name: Projects description: |- Endpoints for managing projects. endpoints: - custom: [] httpMethods: - GET uri: api/projects/types metadata: custom: [] groupName: Projects groupDescription: |- Endpoints for managing projects. subgroup: '' subgroupDescription: '' title: 'Get all project types' description: '' authenticated: true deprecated: false headers: Content-Type: application/json Accept: application/json urlParameters: [] cleanUrlParameters: [] queryParameters: [] cleanQueryParameters: [] bodyParameters: [] cleanBodyParameters: [] fileParameters: [] responses: - custom: [] status: 200 content: |- { "data": [ {"id": 1, "name": "Project"}, {"id": 2, "name": "Support"}, {"id": 3, "name": "Engagement"} ] } headers: [] description: '' responseFields: [] auth: [] controller: null method: null route: null - custom: [] httpMethods: - GET uri: api/projects/statuses metadata: custom: [] groupName: Projects groupDescription: |- Endpoints for managing projects. subgroup: '' subgroupDescription: '' title: 'Get all project statuses' description: '' authenticated: true deprecated: false headers: Content-Type: application/json Accept: application/json urlParameters: [] cleanUrlParameters: [] queryParameters: [] cleanQueryParameters: [] bodyParameters: [] cleanBodyParameters: [] fileParameters: [] responses: - custom: [] status: 200 content: |- { "data": [ {"id": 1, "name": "Pre-sales", "order": 1}, {"id": 2, "name": "SOW Approval", "order": 2}, {"id": 3, "name": "Gathering Estimates", "order": 3} ] } headers: [] description: '' responseFields: [] auth: [] controller: null method: null route: null - custom: [] httpMethods: - GET uri: api/projects metadata: custom: [] groupName: Projects groupDescription: |- Endpoints for managing projects. subgroup: '' subgroupDescription: '' title: 'List all projects' description: 'Get a list of all projects with optional filtering by status and type.' authenticated: true deprecated: false headers: Content-Type: application/json Accept: application/json urlParameters: [] cleanUrlParameters: [] queryParameters: status_id: custom: [] name: status_id description: 'Filter by status ID.' required: false example: 1 type: integer enumValues: [] exampleWasSpecified: true nullable: false deprecated: false type_id: custom: [] name: type_id description: 'Filter by type ID.' required: false example: 2 type: integer enumValues: [] exampleWasSpecified: true nullable: false deprecated: false cleanQueryParameters: status_id: 1 type_id: 2 bodyParameters: [] cleanBodyParameters: [] fileParameters: [] responses: - custom: [] status: 200 content: |- { "data": [ { "id": "550e8400-e29b-41d4-a716-446655440000", "code": "PROJ-001", "title": "Client Dashboard Redesign", "status": {"id": 1, "name": "Pre-sales"}, "type": {"id": 2, "name": "Support"}, "approved_estimate": "120.00", "forecasted_effort": {"2024-02": 40, "2024-03": 60, "2024-04": 20}, "created_at": "2024-01-15T10:00:00.000000Z", "updated_at": "2024-01-15T10:00:00.000000Z" } ] } headers: [] description: '' responseFields: [] auth: [] controller: null method: null route: null - custom: [] httpMethods: - POST uri: api/projects metadata: custom: [] groupName: Projects groupDescription: |- Endpoints for managing projects. subgroup: '' subgroupDescription: '' title: 'Create a new project' description: 'Create a new project with code, title, and type.' authenticated: true deprecated: false headers: Content-Type: application/json Accept: application/json urlParameters: [] cleanUrlParameters: [] queryParameters: [] cleanQueryParameters: [] bodyParameters: code: custom: [] name: code description: 'Project code (must be unique).' required: true example: PROJ-001 type: string enumValues: [] exampleWasSpecified: true nullable: false deprecated: false title: custom: [] name: title description: 'Project title.' required: true example: 'Client Dashboard Redesign' type: string enumValues: [] exampleWasSpecified: true nullable: false deprecated: false type_id: custom: [] name: type_id description: 'Project type ID.' required: true example: 1 type: integer enumValues: [] exampleWasSpecified: true nullable: false deprecated: false cleanBodyParameters: code: PROJ-001 title: 'Client Dashboard Redesign' type_id: 1 fileParameters: [] responses: - custom: [] status: 201 content: |- { "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "code": "PROJ-001", "title": "Client Dashboard Redesign", "status": {"id": 1, "name": "Pre-sales"}, "type": {"id": 1, "name": "Project"} } } headers: [] description: '' - custom: [] status: 422 content: '{"message":"Validation failed","errors":{"code":["Project code must be unique"],"title":["The title field is required."]}}' headers: [] description: '' responseFields: [] auth: [] controller: null method: null route: null - custom: [] httpMethods: - GET uri: 'api/projects/{id}' metadata: custom: [] groupName: Projects groupDescription: |- Endpoints for managing projects. subgroup: '' subgroupDescription: '' title: 'Get a single project' description: 'Get details of a specific project by ID.' authenticated: true deprecated: false headers: Content-Type: application/json Accept: application/json urlParameters: id: custom: [] name: id description: 'Project UUID.' required: true example: 550e8400-e29b-41d4-a716-446655440000 type: string enumValues: [] exampleWasSpecified: true nullable: false deprecated: false cleanUrlParameters: id: 550e8400-e29b-41d4-a716-446655440000 queryParameters: [] cleanQueryParameters: [] bodyParameters: [] cleanBodyParameters: [] fileParameters: [] responses: - custom: [] status: 200 content: |- { "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "code": "PROJ-001", "title": "Client Dashboard Redesign", "status": {"id": 1, "name": "Pre-sales"}, "type": {"id": 1, "name": "Project"}, "approved_estimate": "120.00", "forecasted_effort": {"2024-02": 40, "2024-03": 60} } } headers: [] description: '' - custom: [] status: 404 content: '{"message":"Project not found"}' headers: [] description: '' responseFields: [] auth: [] controller: null method: null route: null - custom: [] httpMethods: - PUT - PATCH uri: 'api/projects/{id}' metadata: custom: [] groupName: Projects groupDescription: |- Endpoints for managing projects. subgroup: '' subgroupDescription: '' title: 'Update a project' description: 'Update details of an existing project.' authenticated: true deprecated: false headers: Content-Type: application/json Accept: application/json urlParameters: id: custom: [] name: id description: 'Project UUID.' required: true example: 550e8400-e29b-41d4-a716-446655440000 type: string enumValues: [] exampleWasSpecified: true nullable: false deprecated: false cleanUrlParameters: id: 550e8400-e29b-41d4-a716-446655440000 queryParameters: [] cleanQueryParameters: [] bodyParameters: code: custom: [] name: code description: 'Project code (must be unique).' required: false example: PROJ-002 type: string enumValues: [] exampleWasSpecified: true nullable: false deprecated: false title: custom: [] name: title description: 'Project title.' required: false example: 'Updated Title' type: string enumValues: [] exampleWasSpecified: true nullable: false deprecated: false type_id: custom: [] name: type_id description: 'Project type ID.' required: false example: 2 type: integer enumValues: [] exampleWasSpecified: true nullable: false deprecated: false cleanBodyParameters: code: PROJ-002 title: 'Updated Title' type_id: 2 fileParameters: [] responses: - custom: [] status: 200 content: |- { "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "code": "PROJ-002", "title": "Updated Title", "type": {"id": 2, "name": "Support"} } } headers: [] description: '' - custom: [] status: 404 content: '{"message":"Project not found"}' headers: [] description: '' - custom: [] status: 422 content: '{"message":"Validation failed","errors":{"type_id":["The selected type id is invalid."]}}' headers: [] description: '' responseFields: [] auth: [] controller: null method: null route: null - custom: [] httpMethods: - DELETE uri: 'api/projects/{id}' metadata: custom: [] groupName: Projects groupDescription: |- Endpoints for managing projects. subgroup: '' subgroupDescription: '' title: 'Delete a project' description: 'Delete a project. Cannot delete if project has allocations or actuals.' authenticated: true deprecated: false headers: Content-Type: application/json Accept: application/json urlParameters: id: custom: [] name: id description: 'Project UUID.' required: true example: 550e8400-e29b-41d4-a716-446655440000 type: string enumValues: [] exampleWasSpecified: true nullable: false deprecated: false cleanUrlParameters: id: 550e8400-e29b-41d4-a716-446655440000 queryParameters: [] cleanQueryParameters: [] bodyParameters: [] cleanBodyParameters: [] fileParameters: [] responses: - custom: [] status: 200 content: '{"message":"Project deleted successfully"}' headers: [] description: '' - custom: [] status: 404 content: '{"message":"Project not found"}' headers: [] description: '' - custom: [] status: 422 content: '{"message":"Cannot delete project with allocations"}' headers: [] description: '' responseFields: [] auth: [] controller: null method: null route: null - custom: [] httpMethods: - PUT uri: 'api/projects/{project}/status' metadata: custom: [] groupName: Projects groupDescription: |- Endpoints for managing projects. subgroup: '' subgroupDescription: '' title: 'Transition project status' description: 'Transition project to a new status following the state machine rules.' authenticated: true deprecated: false headers: Content-Type: application/json Accept: application/json urlParameters: project: custom: [] name: project description: 'The project.' required: true example: architecto type: string enumValues: [] exampleWasSpecified: false nullable: false deprecated: false id: custom: [] name: id description: 'Project UUID.' required: true example: 550e8400-e29b-41d4-a716-446655440000 type: string enumValues: [] exampleWasSpecified: true nullable: false deprecated: false cleanUrlParameters: project: architecto id: 550e8400-e29b-41d4-a716-446655440000 queryParameters: [] cleanQueryParameters: [] bodyParameters: status_id: custom: [] name: status_id description: 'Target status ID.' required: true example: 2 type: integer enumValues: [] exampleWasSpecified: true nullable: false deprecated: false cleanBodyParameters: status_id: 2 fileParameters: [] responses: - custom: [] status: 200 content: |- { "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "status": {"id": 2, "name": "SOW Approval"} } } headers: [] description: '' - custom: [] status: 404 content: '{"message":"Project not found"}' headers: [] description: '' - custom: [] status: 422 content: '{"message":"Cannot transition from Pre-sales to Done"}' headers: [] description: '' responseFields: [] auth: [] controller: null method: null route: null - custom: [] httpMethods: - PUT uri: 'api/projects/{project}/estimate' metadata: custom: [] groupName: Projects groupDescription: |- Endpoints for managing projects. subgroup: '' subgroupDescription: '' title: 'Set approved estimate' description: 'Set the approved billable hours estimate for a project.' authenticated: true deprecated: false headers: Content-Type: application/json Accept: application/json urlParameters: project: custom: [] name: project description: 'The project.' required: true example: architecto type: string enumValues: [] exampleWasSpecified: false nullable: false deprecated: false id: custom: [] name: id description: 'Project UUID.' required: true example: 550e8400-e29b-41d4-a716-446655440000 type: string enumValues: [] exampleWasSpecified: true nullable: false deprecated: false cleanUrlParameters: project: architecto id: 550e8400-e29b-41d4-a716-446655440000 queryParameters: [] cleanQueryParameters: [] bodyParameters: approved_estimate: custom: [] name: approved_estimate description: 'Approved estimate hours (must be > 0).' required: true example: 120.0 type: number enumValues: [] exampleWasSpecified: true nullable: false deprecated: false cleanBodyParameters: approved_estimate: 120.0 fileParameters: [] responses: - custom: [] status: 200 content: |- { "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "approved_estimate": "120.00" } } headers: [] description: '' - custom: [] status: 404 content: '{"message":"Project not found"}' headers: [] description: '' - custom: [] status: 422 content: '{"message":"Approved estimate must be greater than 0"}' headers: [] description: '' responseFields: [] auth: [] controller: null method: null route: null - custom: [] httpMethods: - PUT uri: 'api/projects/{project}/forecast' metadata: custom: [] groupName: Projects groupDescription: |- Endpoints for managing projects. subgroup: '' subgroupDescription: '' title: 'Set forecasted effort' description: 'Set the month-by-month forecasted effort breakdown.' authenticated: true deprecated: false headers: Content-Type: application/json Accept: application/json urlParameters: project: custom: [] name: project description: 'The project.' required: true example: architecto type: string enumValues: [] exampleWasSpecified: false nullable: false deprecated: false id: custom: [] name: id description: 'Project UUID.' required: true example: 550e8400-e29b-41d4-a716-446655440000 type: string enumValues: [] exampleWasSpecified: true nullable: false deprecated: false cleanUrlParameters: project: architecto id: 550e8400-e29b-41d4-a716-446655440000 queryParameters: [] cleanQueryParameters: [] bodyParameters: forecasted_effort: custom: [] name: forecasted_effort description: 'Monthly effort breakdown.' required: true example: 2024-02: 40 2024-03: 60 type: object enumValues: [] exampleWasSpecified: true nullable: false deprecated: false cleanBodyParameters: forecasted_effort: 2024-02: 40 2024-03: 60 fileParameters: [] responses: - custom: [] status: 200 content: |- { "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "forecasted_effort": {"2024-02": 40, "2024-03": 60} } } headers: [] description: '' - custom: [] status: 404 content: '{"message":"Project not found"}' headers: [] description: '' - custom: [] status: 422 content: '{"message":"Forecasted effort exceeds approved estimate by more than 5%"}' headers: [] description: '' responseFields: [] auth: [] controller: null method: null route: null