1061 lines
21 KiB
Markdown
1061 lines
21 KiB
Markdown
# Work Management Service API Documentation
|
|
|
|
**Base URL:** `/api/work` (via gateway) or `http://localhost:8083` (direct)
|
|
|
|
**Service Port:** 8083
|
|
|
|
## Overview
|
|
|
|
The Work Management Service handles all project, task, and work order management for the Coppertone.tech platform. It provides:
|
|
|
|
- Project management with approval workflow
|
|
- Task tracking with assignments and time tracking
|
|
- Work orders with IPFS document integration
|
|
- Role-based access control (RBAC)
|
|
|
|
## Authentication
|
|
|
|
All endpoints require a valid JWT token in the Authorization header:
|
|
|
|
```
|
|
Authorization: Bearer <jwt_token>
|
|
```
|
|
|
|
The token is validated against the auth-service and must contain:
|
|
- `user_id` / `userId`: User identifier
|
|
- `roles`: Array of user roles
|
|
|
|
## Role-Based Access
|
|
|
|
| Role | Projects | Tasks | Work Orders |
|
|
|------|----------|-------|-------------|
|
|
| `SUPERUSER` | Full access | Full access | Full access |
|
|
| `ADMIN` | Full access | Full access | Full access |
|
|
| `STAFF` | Full access | Full access | Full access |
|
|
| `CLIENT` | Own projects only | Tasks on own projects | No access |
|
|
|
|
**Note:** `SUPERUSER` role automatically grants full access to all endpoints.
|
|
|
|
---
|
|
|
|
## Health Check
|
|
|
|
```
|
|
GET /healthz
|
|
```
|
|
|
|
**Response:**
|
|
```
|
|
200 OK
|
|
ok
|
|
```
|
|
|
|
---
|
|
|
|
## Projects
|
|
|
|
### List Projects
|
|
|
|
Retrieve a list of approved projects. CLIENTs see only their own projects.
|
|
|
|
```
|
|
GET /projects
|
|
```
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Required Role:** Any authenticated user
|
|
|
|
**Response (200 OK):**
|
|
```json
|
|
[
|
|
{
|
|
"id": 1,
|
|
"name": "Website Redesign",
|
|
"description": "Complete redesign of corporate website",
|
|
"status": "IN_PROGRESS",
|
|
"clientId": 5,
|
|
"ipfsMetadataCid": "QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco",
|
|
"startDate": "2024-01-15",
|
|
"endDate": "2024-03-15",
|
|
"requestedBy": 5,
|
|
"approvedBy": 2,
|
|
"approvalStatus": "APPROVED",
|
|
"approvalDate": "2024-01-10T14:30:00Z",
|
|
"rejectionReason": null,
|
|
"createdAt": "2024-01-05T10:00:00Z",
|
|
"updatedAt": "2024-01-20T09:15:00Z"
|
|
}
|
|
]
|
|
```
|
|
|
|
**Authorization Logic:**
|
|
- `STAFF/ADMIN/SUPERUSER`: See all approved projects
|
|
- `CLIENT`: See only projects where `client_id` matches their user ID
|
|
|
|
---
|
|
|
|
### Get Project by ID
|
|
|
|
Retrieve a single project by ID.
|
|
|
|
```
|
|
GET /projects/{id}
|
|
```
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Required Role:** Any authenticated user (with access)
|
|
|
|
**Path Parameters:**
|
|
| Parameter | Type | Description |
|
|
|-----------|------|-------------|
|
|
| `id` | integer | Project ID |
|
|
|
|
**Response (200 OK):**
|
|
```json
|
|
{
|
|
"id": 1,
|
|
"name": "Website Redesign",
|
|
"description": "Complete redesign of corporate website",
|
|
"status": "IN_PROGRESS",
|
|
"clientId": 5,
|
|
"ipfsMetadataCid": "QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco",
|
|
"startDate": "2024-01-15",
|
|
"endDate": "2024-03-15",
|
|
"requestedBy": 5,
|
|
"approvedBy": 2,
|
|
"approvalStatus": "APPROVED",
|
|
"approvalDate": "2024-01-10T14:30:00Z",
|
|
"rejectionReason": null,
|
|
"createdAt": "2024-01-05T10:00:00Z",
|
|
"updatedAt": "2024-01-20T09:15:00Z"
|
|
}
|
|
```
|
|
|
|
**Error Responses:**
|
|
|
|
| Status | Condition | Response |
|
|
|--------|-----------|----------|
|
|
| 400 | Invalid ID | `Invalid project ID` |
|
|
| 403 | No access | `Forbidden: you do not have access to this project` |
|
|
| 404 | Not found | `Project not found` |
|
|
|
|
**Authorization Logic:**
|
|
- User must be: project owner (`client_id`), requester (`requested_by`), or `STAFF/ADMIN/SUPERUSER`
|
|
|
|
---
|
|
|
|
### Create Project
|
|
|
|
Create a new project. Projects created by STAFF/ADMIN are auto-approved.
|
|
|
|
```
|
|
POST /projects
|
|
```
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Required Role:** `STAFF`, `ADMIN`, or `SUPERUSER`
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"name": "New Mobile App",
|
|
"description": "iOS and Android app development",
|
|
"status": "PLANNING",
|
|
"clientId": 5,
|
|
"ipfsMetadataCid": "QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco",
|
|
"startDate": "2024-02-01",
|
|
"endDate": "2024-06-30"
|
|
}
|
|
```
|
|
|
|
| Field | Type | Required | Default | Description |
|
|
|-------|------|----------|---------|-------------|
|
|
| `name` | string | Yes | - | Project name |
|
|
| `description` | string | No | - | Project description |
|
|
| `status` | string | No | `PLANNING` | Project status |
|
|
| `clientId` | integer | No | - | Assigned client user ID |
|
|
| `ipfsMetadataCid` | string | No | - | IPFS CID for metadata |
|
|
| `startDate` | string | No | - | Planned start date (YYYY-MM-DD) |
|
|
| `endDate` | string | No | - | Planned end date (YYYY-MM-DD) |
|
|
|
|
**Valid Status Values:**
|
|
- `PLANNING`
|
|
- `IN_PROGRESS`
|
|
- `ON_HOLD`
|
|
- `COMPLETED`
|
|
- `CANCELLED`
|
|
|
|
**Response (201 Created):**
|
|
```json
|
|
{
|
|
"id": 2,
|
|
"name": "New Mobile App",
|
|
"description": "iOS and Android app development",
|
|
"status": "PLANNING",
|
|
"clientId": 5,
|
|
"ipfsMetadataCid": "QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco",
|
|
"startDate": "2024-02-01",
|
|
"endDate": "2024-06-30",
|
|
"requestedBy": 2,
|
|
"approvedBy": 2,
|
|
"approvalStatus": "APPROVED",
|
|
"approvalDate": "2024-01-25T12:00:00Z",
|
|
"rejectionReason": null,
|
|
"createdAt": "2024-01-25T12:00:00Z",
|
|
"updatedAt": "2024-01-25T12:00:00Z"
|
|
}
|
|
```
|
|
|
|
**Error Responses:**
|
|
|
|
| Status | Condition | Response |
|
|
|--------|-----------|----------|
|
|
| 400 | Missing name | `Project name is required` |
|
|
| 403 | Insufficient role | `Insufficient permissions` |
|
|
|
|
---
|
|
|
|
### Update Project
|
|
|
|
Update an existing project.
|
|
|
|
```
|
|
PUT /projects/{id}
|
|
```
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Required Role:** `STAFF`, `ADMIN`, or `SUPERUSER` (or project owner)
|
|
|
|
**Path Parameters:**
|
|
| Parameter | Type | Description |
|
|
|-----------|------|-------------|
|
|
| `id` | integer | Project ID |
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"name": "Updated Project Name",
|
|
"description": "Updated description",
|
|
"status": "IN_PROGRESS",
|
|
"clientId": 5,
|
|
"ipfsMetadataCid": "QmNewCid...",
|
|
"startDate": "2024-02-01",
|
|
"endDate": "2024-07-31"
|
|
}
|
|
```
|
|
|
|
**Response (200 OK):**
|
|
```json
|
|
{
|
|
"id": 1,
|
|
"name": "Updated Project Name",
|
|
...
|
|
}
|
|
```
|
|
|
|
**Error Responses:**
|
|
|
|
| Status | Condition | Response |
|
|
|--------|-----------|----------|
|
|
| 403 | No permission | `Forbidden: you do not have permission to update this project` |
|
|
| 404 | Not found | `Project not found` |
|
|
|
|
---
|
|
|
|
### Delete Project
|
|
|
|
Delete a project. Only STAFF/ADMIN can delete projects.
|
|
|
|
```
|
|
DELETE /projects/{id}
|
|
```
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Required Role:** `STAFF`, `ADMIN`, or `SUPERUSER`
|
|
|
|
**Path Parameters:**
|
|
| Parameter | Type | Description |
|
|
|-----------|------|-------------|
|
|
| `id` | integer | Project ID |
|
|
|
|
**Response (204 No Content)**
|
|
|
|
**Error Responses:**
|
|
|
|
| Status | Condition | Response |
|
|
|--------|-----------|----------|
|
|
| 403 | No permission | `Forbidden: only STAFF or ADMIN can delete projects` |
|
|
| 404 | Not found | `Project not found` |
|
|
|
|
---
|
|
|
|
## Project Requests (Client Workflow)
|
|
|
|
CLIENTs can request new projects, which require STAFF/ADMIN approval.
|
|
|
|
### List My Project Requests
|
|
|
|
Retrieve all project requests made by the current user.
|
|
|
|
```
|
|
GET /project-requests
|
|
```
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Required Role:** Any authenticated user
|
|
|
|
**Response (200 OK):**
|
|
```json
|
|
[
|
|
{
|
|
"id": 3,
|
|
"name": "New Feature Request",
|
|
"description": "We need a new dashboard feature",
|
|
"status": "PENDING_APPROVAL",
|
|
"clientId": 5,
|
|
"requestedBy": 5,
|
|
"approvedBy": null,
|
|
"approvalStatus": "PENDING",
|
|
"approvalDate": null,
|
|
"rejectionReason": null,
|
|
"createdAt": "2024-01-25T10:00:00Z",
|
|
"updatedAt": "2024-01-25T10:00:00Z"
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
### Create Project Request
|
|
|
|
Submit a new project request for approval.
|
|
|
|
```
|
|
POST /project-requests
|
|
```
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Required Role:** Any authenticated user
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"name": "Custom Integration Project",
|
|
"description": "We need to integrate our CRM with the platform. This should include bidirectional sync and real-time updates."
|
|
}
|
|
```
|
|
|
|
| Field | Type | Required | Description |
|
|
|-------|------|----------|-------------|
|
|
| `name` | string | Yes | Project name |
|
|
| `description` | string | Yes | Detailed description of the project request |
|
|
|
|
**Response (201 Created):**
|
|
```json
|
|
{
|
|
"id": 4,
|
|
"name": "Custom Integration Project",
|
|
"description": "We need to integrate our CRM with the platform...",
|
|
"status": "PENDING_APPROVAL",
|
|
"clientId": 5,
|
|
"requestedBy": 5,
|
|
"approvalStatus": "PENDING",
|
|
"createdAt": "2024-01-25T14:30:00Z",
|
|
"updatedAt": "2024-01-25T14:30:00Z"
|
|
}
|
|
```
|
|
|
|
**Error Responses:**
|
|
|
|
| Status | Condition | Response |
|
|
|--------|-----------|----------|
|
|
| 400 | Missing name | `Project name is required` |
|
|
| 400 | Missing description | `Project description is required to help us understand your needs` |
|
|
|
|
---
|
|
|
|
### Get Project Request
|
|
|
|
Retrieve a specific project request.
|
|
|
|
```
|
|
GET /project-requests/{id}
|
|
```
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Required Role:** Request owner, or `STAFF/ADMIN/SUPERUSER`
|
|
|
|
**Response (200 OK):**
|
|
```json
|
|
{
|
|
"id": 4,
|
|
"name": "Custom Integration Project",
|
|
"description": "...",
|
|
"status": "PENDING_APPROVAL",
|
|
"approvalStatus": "PENDING",
|
|
...
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Cancel Project Request
|
|
|
|
Cancel a pending project request.
|
|
|
|
```
|
|
DELETE /project-requests/{id}
|
|
```
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Required Role:** Request owner only (cannot cancel after approval)
|
|
|
|
**Response (204 No Content)**
|
|
|
|
**Error Responses:**
|
|
|
|
| Status | Condition | Response |
|
|
|--------|-----------|----------|
|
|
| 403 | Not owner | `Forbidden: you can only cancel your own requests` |
|
|
| 403 | Already processed | `Cannot cancel: request has already been processed` |
|
|
| 404 | Not found | `Project request not found` |
|
|
|
|
---
|
|
|
|
## Project Approval (Admin Workflow)
|
|
|
|
### List Pending Projects
|
|
|
|
Retrieve all projects pending approval.
|
|
|
|
```
|
|
GET /projects/pending
|
|
```
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Required Role:** `STAFF`, `ADMIN`, or `SUPERUSER`
|
|
|
|
**Response (200 OK):**
|
|
```json
|
|
[
|
|
{
|
|
"id": 4,
|
|
"name": "Custom Integration Project",
|
|
"description": "...",
|
|
"status": "PENDING_APPROVAL",
|
|
"clientId": 5,
|
|
"requestedBy": 5,
|
|
"approvalStatus": "PENDING",
|
|
"createdAt": "2024-01-25T14:30:00Z",
|
|
"updatedAt": "2024-01-25T14:30:00Z"
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
### Approve or Reject Project
|
|
|
|
Approve or reject a pending project request.
|
|
|
|
```
|
|
POST /projects/approve/{id}
|
|
```
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Required Role:** `STAFF`, `ADMIN`, or `SUPERUSER`
|
|
|
|
**Path Parameters:**
|
|
| Parameter | Type | Description |
|
|
|-----------|------|-------------|
|
|
| `id` | integer | Project ID |
|
|
|
|
**Request Body (Approve):**
|
|
```json
|
|
{
|
|
"action": "approve"
|
|
}
|
|
```
|
|
|
|
**Request Body (Reject):**
|
|
```json
|
|
{
|
|
"action": "reject",
|
|
"reason": "The requested scope is too broad. Please break this into smaller projects."
|
|
}
|
|
```
|
|
|
|
| Field | Type | Required | Description |
|
|
|-------|------|----------|-------------|
|
|
| `action` | string | Yes | `approve` or `reject` |
|
|
| `reason` | string | If rejecting | Reason for rejection |
|
|
|
|
**Response (200 OK - Approved):**
|
|
```json
|
|
{
|
|
"message": "Project approved successfully",
|
|
"project": {
|
|
"id": 4,
|
|
"name": "Custom Integration Project",
|
|
"status": "PLANNING",
|
|
"approvalStatus": "APPROVED",
|
|
"approvedBy": 2,
|
|
"approvalDate": "2024-01-26T09:00:00Z",
|
|
...
|
|
}
|
|
}
|
|
```
|
|
|
|
**Response (200 OK - Rejected):**
|
|
```json
|
|
{
|
|
"message": "Project rejected",
|
|
"project": {
|
|
"id": 4,
|
|
"name": "Custom Integration Project",
|
|
"status": "CANCELLED",
|
|
"approvalStatus": "REJECTED",
|
|
"rejectionReason": "The requested scope is too broad...",
|
|
...
|
|
}
|
|
}
|
|
```
|
|
|
|
**Error Responses:**
|
|
|
|
| Status | Condition | Response |
|
|
|--------|-----------|----------|
|
|
| 400 | Invalid action | `Invalid action. Must be 'approve' or 'reject'` |
|
|
| 400 | Missing reason | `Rejection reason is required` |
|
|
| 400 | Not pending | `Project is not pending approval` |
|
|
| 404 | Not found | `Project not found` |
|
|
|
|
---
|
|
|
|
## Tasks
|
|
|
|
### List Tasks
|
|
|
|
Retrieve tasks, optionally filtered by project.
|
|
|
|
```
|
|
GET /tasks
|
|
GET /tasks?project_id=1
|
|
```
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Required Role:** Any authenticated user
|
|
|
|
**Query Parameters:**
|
|
| Parameter | Type | Description |
|
|
|-----------|------|-------------|
|
|
| `project_id` | integer | Optional. Filter tasks by project |
|
|
|
|
**Response (200 OK):**
|
|
```json
|
|
[
|
|
{
|
|
"id": 1,
|
|
"projectId": 1,
|
|
"title": "Design Homepage Mockup",
|
|
"description": "Create wireframes and visual design for homepage",
|
|
"status": "IN_PROGRESS",
|
|
"assigneeId": 3,
|
|
"dueDate": "2024-02-01",
|
|
"completedAt": null,
|
|
"priority": 2,
|
|
"estimatedHours": 8.0,
|
|
"actualHours": 3.5,
|
|
"createdAt": "2024-01-20T10:00:00Z",
|
|
"updatedAt": "2024-01-25T14:00:00Z"
|
|
}
|
|
]
|
|
```
|
|
|
|
**Authorization Logic:**
|
|
- `STAFF/ADMIN/SUPERUSER`: See all tasks (optionally filtered)
|
|
- `CLIENT`: See only tasks for projects they own
|
|
|
|
---
|
|
|
|
### Get Task by ID
|
|
|
|
Retrieve a single task.
|
|
|
|
```
|
|
GET /tasks/{id}
|
|
```
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Required Role:** Any authenticated user (with access to parent project)
|
|
|
|
**Response (200 OK):**
|
|
```json
|
|
{
|
|
"id": 1,
|
|
"projectId": 1,
|
|
"title": "Design Homepage Mockup",
|
|
"description": "Create wireframes and visual design for homepage",
|
|
"status": "IN_PROGRESS",
|
|
"assigneeId": 3,
|
|
"dueDate": "2024-02-01",
|
|
"completedAt": null,
|
|
"priority": 2,
|
|
"estimatedHours": 8.0,
|
|
"actualHours": 3.5,
|
|
"createdAt": "2024-01-20T10:00:00Z",
|
|
"updatedAt": "2024-01-25T14:00:00Z"
|
|
}
|
|
```
|
|
|
|
**Error Responses:**
|
|
|
|
| Status | Condition | Response |
|
|
|--------|-----------|----------|
|
|
| 403 | No access | `Forbidden: you do not have access to this task` |
|
|
| 404 | Not found | `Task not found` |
|
|
|
|
---
|
|
|
|
### Create Task
|
|
|
|
Create a new task for a project.
|
|
|
|
```
|
|
POST /tasks
|
|
```
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Required Role:** `STAFF`, `ADMIN`, or `SUPERUSER`
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"projectId": 1,
|
|
"title": "Implement API Endpoints",
|
|
"description": "Create REST endpoints for user management",
|
|
"status": "TODO",
|
|
"assigneeId": 3,
|
|
"dueDate": "2024-02-15",
|
|
"priority": 1,
|
|
"estimatedHours": 16.0
|
|
}
|
|
```
|
|
|
|
| Field | Type | Required | Default | Description |
|
|
|-------|------|----------|---------|-------------|
|
|
| `projectId` | integer | Yes | - | Parent project ID |
|
|
| `title` | string | Yes | - | Task title |
|
|
| `description` | string | No | - | Task description |
|
|
| `status` | string | No | `TODO` | Task status |
|
|
| `assigneeId` | integer | No | - | Assigned user ID |
|
|
| `dueDate` | string | No | - | Due date (YYYY-MM-DD) |
|
|
| `priority` | integer | No | 0 | Priority (higher = more important) |
|
|
| `estimatedHours` | float | No | - | Estimated hours to complete |
|
|
|
|
**Valid Status Values:**
|
|
- `TODO`
|
|
- `IN_PROGRESS`
|
|
- `REVIEW`
|
|
- `COMPLETED`
|
|
- `BLOCKED`
|
|
|
|
**Response (201 Created):**
|
|
```json
|
|
{
|
|
"id": 5,
|
|
"projectId": 1,
|
|
"title": "Implement API Endpoints",
|
|
"status": "TODO",
|
|
...
|
|
}
|
|
```
|
|
|
|
**Error Responses:**
|
|
|
|
| Status | Condition | Response |
|
|
|--------|-----------|----------|
|
|
| 400 | Missing fields | `Task title and project_id are required` |
|
|
| 403 | No permission | `Insufficient permissions` |
|
|
|
|
---
|
|
|
|
### Update Task
|
|
|
|
Update an existing task.
|
|
|
|
```
|
|
PUT /tasks/{id}
|
|
```
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Required Role:** `STAFF`, `ADMIN`, or `SUPERUSER`
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"title": "Implement API Endpoints",
|
|
"description": "Updated description",
|
|
"status": "COMPLETED",
|
|
"assigneeId": 3,
|
|
"dueDate": "2024-02-15",
|
|
"priority": 1,
|
|
"estimatedHours": 16.0,
|
|
"actualHours": 14.5
|
|
}
|
|
```
|
|
|
|
**Special Behavior:**
|
|
- Setting `status` to `COMPLETED` automatically sets `completedAt` timestamp
|
|
- Setting `status` to anything else clears `completedAt`
|
|
|
|
**Response (200 OK):**
|
|
```json
|
|
{
|
|
"id": 5,
|
|
"projectId": 1,
|
|
"title": "Implement API Endpoints",
|
|
"status": "COMPLETED",
|
|
"completedAt": "2024-02-14T16:30:00Z",
|
|
...
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Delete Task
|
|
|
|
Delete a task.
|
|
|
|
```
|
|
DELETE /tasks/{id}
|
|
```
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Required Role:** `STAFF`, `ADMIN`, or `SUPERUSER`
|
|
|
|
**Response (204 No Content)**
|
|
|
|
---
|
|
|
|
## Work Orders
|
|
|
|
Work orders are internal documents for tracking billable work. **STAFF/ADMIN only.**
|
|
|
|
### List Work Orders
|
|
|
|
Retrieve work orders, optionally filtered by project.
|
|
|
|
```
|
|
GET /workorders
|
|
GET /workorders?project_id=1
|
|
```
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Required Role:** `STAFF`, `ADMIN`, or `SUPERUSER`
|
|
|
|
**Query Parameters:**
|
|
| Parameter | Type | Description |
|
|
|-----------|------|-------------|
|
|
| `project_id` | integer | Optional. Filter by project |
|
|
|
|
**Response (200 OK):**
|
|
```json
|
|
[
|
|
{
|
|
"id": 1,
|
|
"projectId": 1,
|
|
"title": "Initial Setup and Configuration",
|
|
"description": "Server setup, environment configuration, CI/CD pipeline",
|
|
"orderNumber": "WO-2024-001",
|
|
"ipfsDocumentCid": "QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco",
|
|
"createdBy": 2,
|
|
"createdAt": "2024-01-20T10:00:00Z",
|
|
"updatedAt": "2024-01-20T10:00:00Z"
|
|
}
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
### Get Work Order by ID
|
|
|
|
```
|
|
GET /workorders/{id}
|
|
```
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Required Role:** `STAFF`, `ADMIN`, or `SUPERUSER`
|
|
|
|
**Response (200 OK):**
|
|
```json
|
|
{
|
|
"id": 1,
|
|
"projectId": 1,
|
|
"title": "Initial Setup and Configuration",
|
|
"description": "Server setup, environment configuration, CI/CD pipeline",
|
|
"orderNumber": "WO-2024-001",
|
|
"ipfsDocumentCid": "QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco",
|
|
"createdBy": 2,
|
|
"createdAt": "2024-01-20T10:00:00Z",
|
|
"updatedAt": "2024-01-20T10:00:00Z"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Create Work Order
|
|
|
|
```
|
|
POST /workorders
|
|
```
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Required Role:** `STAFF`, `ADMIN`, or `SUPERUSER`
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"projectId": 1,
|
|
"title": "Database Migration",
|
|
"description": "Migrate from PostgreSQL 14 to 16",
|
|
"orderNumber": "WO-2024-002",
|
|
"ipfsDocumentCid": "QmNewCid...",
|
|
"createdBy": 2
|
|
}
|
|
```
|
|
|
|
| Field | Type | Required | Description |
|
|
|-------|------|----------|-------------|
|
|
| `projectId` | integer | Yes | Parent project ID |
|
|
| `title` | string | Yes | Work order title |
|
|
| `orderNumber` | string | Yes | Unique order number |
|
|
| `description` | string | No | Work order description |
|
|
| `ipfsDocumentCid` | string | No | IPFS CID for attached document |
|
|
| `createdBy` | integer | No | User ID who created the work order |
|
|
|
|
**Response (201 Created):**
|
|
```json
|
|
{
|
|
"id": 2,
|
|
"projectId": 1,
|
|
"title": "Database Migration",
|
|
"orderNumber": "WO-2024-002",
|
|
...
|
|
}
|
|
```
|
|
|
|
**Error Responses:**
|
|
|
|
| Status | Condition | Response |
|
|
|--------|-----------|----------|
|
|
| 400 | Missing fields | `Work order title, project_id, and order_number are required` |
|
|
| 409 | Duplicate order number | `Work order number already exists` |
|
|
|
|
---
|
|
|
|
### Update Work Order
|
|
|
|
```
|
|
PUT /workorders/{id}
|
|
```
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Required Role:** `STAFF`, `ADMIN`, or `SUPERUSER`
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"title": "Updated Title",
|
|
"description": "Updated description",
|
|
"orderNumber": "WO-2024-002",
|
|
"ipfsDocumentCid": "QmUpdatedCid..."
|
|
}
|
|
```
|
|
|
|
**Response (200 OK)**
|
|
|
|
---
|
|
|
|
### Delete Work Order
|
|
|
|
```
|
|
DELETE /workorders/{id}
|
|
```
|
|
|
|
**Headers:**
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Required Role:** `STAFF`, `ADMIN`, or `SUPERUSER`
|
|
|
|
**Response (204 No Content)**
|
|
|
|
---
|
|
|
|
## CORS Configuration
|
|
|
|
Same as auth-service:
|
|
|
|
| Header | Value |
|
|
|--------|-------|
|
|
| `Access-Control-Allow-Origin` | Configured via `CORS_ALLOW_ORIGIN` env var |
|
|
| `Access-Control-Allow-Methods` | `GET, POST, PUT, DELETE, OPTIONS` |
|
|
| `Access-Control-Allow-Headers` | `Content-Type, Authorization` |
|
|
| `Access-Control-Allow-Credentials` | `true` |
|
|
|
|
---
|
|
|
|
## Environment Variables
|
|
|
|
| Variable | Required | Default | Description |
|
|
|----------|----------|---------|-------------|
|
|
| `JWT_SECRET` | Yes | - | Secret key for JWT validation (must match auth-service) |
|
|
| `DB_HOST` | Yes | - | PostgreSQL host |
|
|
| `DB_USER` | Yes | - | PostgreSQL user |
|
|
| `DB_PASSWORD` | Yes | - | PostgreSQL password |
|
|
| `DB_NAME` | Yes | - | PostgreSQL database name |
|
|
| `DB_SSL_MODE` | No | `require` | SSL mode |
|
|
| `DB_SCHEMA` | No | `public` | Schema: `dev`, `testing`, `prod` |
|
|
| `CORS_ALLOW_ORIGIN` | No | `http://localhost:8090` | Allowed CORS origin |
|
|
|
|
---
|
|
|
|
## Database Tables
|
|
|
|
### projects
|
|
```sql
|
|
CREATE TABLE projects (
|
|
id SERIAL PRIMARY KEY,
|
|
name VARCHAR(255) NOT NULL,
|
|
description TEXT,
|
|
status VARCHAR(50) DEFAULT 'PLANNING',
|
|
client_id INTEGER REFERENCES users(id),
|
|
ipfs_metadata_cid VARCHAR(100),
|
|
start_date DATE,
|
|
end_date DATE,
|
|
requested_by INTEGER REFERENCES users(id),
|
|
approved_by INTEGER REFERENCES users(id),
|
|
approval_status VARCHAR(20) DEFAULT 'APPROVED',
|
|
approval_date TIMESTAMP,
|
|
rejection_reason TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
```
|
|
|
|
### tasks
|
|
```sql
|
|
CREATE TABLE tasks (
|
|
id SERIAL PRIMARY KEY,
|
|
project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
title VARCHAR(255) NOT NULL,
|
|
description TEXT,
|
|
status VARCHAR(50) DEFAULT 'TODO',
|
|
assignee_id INTEGER REFERENCES users(id),
|
|
due_date DATE,
|
|
completed_at TIMESTAMP,
|
|
priority INTEGER DEFAULT 0,
|
|
estimated_hours DECIMAL(5,2),
|
|
actual_hours DECIMAL(5,2),
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
```
|
|
|
|
### work_orders
|
|
```sql
|
|
CREATE TABLE work_orders (
|
|
id SERIAL PRIMARY KEY,
|
|
project_id INTEGER NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
title VARCHAR(255) NOT NULL,
|
|
description TEXT,
|
|
order_number VARCHAR(50) NOT NULL UNIQUE,
|
|
ipfs_document_cid VARCHAR(100),
|
|
created_by INTEGER REFERENCES users(id),
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
```
|