# Activity RESTful API 規格書
## 概述
本文檔描述了 Activity 管理系統的 RESTful API 規格,包含活動 (Activities)、活動輸入 (Activity Inputs)、活動結果 (Activity Outcomes)、利害關係人 (Activity Stakeholders)、SROI 計算 (SROI Calculations) 和敏感性分析 (SROI Sensitivity Analyses) 等模組。
**基礎 URL**: `/api`
### 路由結構
| 功能 | HTTP 方法 | 最終路徑 | 說明 |
|------|----------|---------|------|
| **Activities** | | | |
| 建立活動 | POST | `/api/activities/` | ✅ |
| 取得活動 | GET | `/api/activities/:id` | ✅ |
| 更新活動 | PUT | `/api/activities/:id` | ✅ |
| 刪除活動 | DELETE | `/api/activities/:id` | ✅ |
| **Activity Inputs** | | | |
| 建立投入 | POST | `/api/activities/:activityId/inputs` | ✅ |
| 列出活動所有投入 | GET | `/api/activities/{activityId}/inputs/` | ✅ |
| 取得投入 | GET | `/api/activities/inputs/:id` | ✅ |
| 更新投入 | PUT | `/api/activities/inputs/:id` | ✅ |
| 刪除投入 | DELETE | `/api/activities/inputs/:id` | ✅ |
| **Activity Outcome** | | | |
| 建立收益 | POST | `/api/activities/:activityId/outcomes` | ✅ |
| 列出活動所有收益 | GET | `/api/activities/{activityId}/outcome/` | ✅ |
| 取得收益 | GET | `/api/activity-outcomes/:id` | ✅ |
| 更新收益 | PUT | `/api/activity-outcomes/:id` | ✅ |
| 刪除收益 | DELETE | `/api/activity-outcomes/:id` | ✅ |
| **Activity Stakeholders** | | | |
| 建立利害關係人 | POST | `/api/activities/:activityId/stakeholders` | ✅ |
| 列出活動所有關係人 | GET | `/api/activities/{activityId}/stakeholdes/` | ✅ |
| 取得利害關係人 | GET | `/api/activities/stakeholders/:id` | ✅ |
| 更新利害關係人 | PUT | `/api/activities/stakeholders/:id` | ✅ |
| 刪除利害關係人 | DELETE | `/api/activities/stakeholders/:id` | ✅ |
| **Activity Sroi-calculations** | | | |
| 建立SROI計算 | POST | `/api/activities/:activityId/sroi-calculations` | ✅ |
| 列出活動所有SROI計算 | GET | `/api/activities/{activityId}/sroi-calculations/` | ✅ |
| 取得SROI計算 | GET | `/api/sroi-calculations/:id` | ✅ |
| 更新SROI計算 | PUT | `/api/sroi-calculations/:id` | ✅ |
| 刪除SROI計算 | DELETE | `/api/sroi-calculations/:id` | ✅ |
| **SROI Sensitivity Analyses** | | | |
| 建立敏感性分析 | POST | `/api/sroi-calculations/:calculationId/sensitivity-analyses` | ✅ |
| 列出SROI所有敏感性分析 | GET | `/api/sroi-calculations/{sroiCalculationsId}/sroi-calculations/` | ✅ |
| 取得敏感性分析 | GET | `/api/sroi-sensitivity-analyses/:id` | ✅ |
| 更新敏感性分析 | PUT | `/api/sroi-sensitivity-analyses/:id` | ✅ |
| 刪除敏感性分析 | DELETE | `/api/sroi-sensitivity-analyses/:id` | ✅ |
---
## 1. Activities (活動管理)
### 1.1 創建活動
**請求**
- **方法**: `POST`
- **路徑**: `/api/activities`
- **Content-Type**: `application/json`
**請求參數**
```json
{
"organization_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"creator_user_id": "6ba7b811-9dad-11d1-80b4-00c04fd430c8",
"name": "Community Education Program",
"problem_to_solve": "Improving literacy rates in underserved communities",
"location": "Taipei, Taiwan",
"expected_outcome_percentage": 85.5
}
```
**欄位說明**
- `organization_id` (必填): 組織 ID (UUID)
- `creator_user_id` (必填): 創建者用戶 ID (UUID)
- `name` (必填): 活動名稱
- `problem_to_solve` (必填): 要解決的問題描述
- `location` (必填): 活動地點
- `expected_outcome_percentage` (必填): 預期結果百分比
**回應**
```json
{
"activity": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"organization_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"creator_user_id": "6ba7b811-9dad-11d1-80b4-00c04fd430c8",
"name": "Community Education Program",
"problem_to_solve": "Improving literacy rates in underserved communities",
"location": "Taipei, Taiwan",
"expected_outcome_percentage": 85.5,
"created_at": "2025-01-13T10:30:00Z",
"updated_at": "2025-01-13T10:30:00Z"
}
}
```
**狀態碼**
- `200`: 成功創建
- `400`: 缺少必填欄位
- `500`: 伺服器錯誤
### 1.2 獲取活動詳情
**請求**
- **方法**: `GET`
- **路徑**: `/api/activities/{id}`
**路徑參數**
- `id`: 活動 ID (UUID)
**回應**
```json
{
"activity": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"organization_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"creator_user_id": "6ba7b811-9dad-11d1-80b4-00c04fd430c8",
"name": "Community Education Program",
"problem_to_solve": "Improving literacy rates in underserved communities",
"location": "Taipei, Taiwan",
"expected_outcome_percentage": 85.5,
"created_at": "2025-01-13T10:30:00Z",
"updated_at": "2025-01-13T10:30:00Z"
}
}
```
**狀態碼**
- `200`: 成功獲取
- `404`: 活動未找到
- `500`: 伺服器錯誤
### 1.3 更新活動
**請求**
- **方法**: `PUT`
- **路徑**: `/api/activities/{id}`
- **Content-Type**: `application/json`
**路徑參數**
- `id`: 活動 ID (UUID)
**請求參數**
```json
{
"name": "Updated Community Education Program",
"problem_to_solve": "Enhanced literacy improvement program",
"location": "New Taipei, Taiwan",
"expected_outcome_percentage": 90.0
}
```
**欄位說明**
- 所有欄位都是可選的,只傳送要更新的欄位
**回應**
```json
{
"activity": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"organization_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"creator_user_id": "6ba7b811-9dad-11d1-80b4-00c04fd430c8",
"name": "Updated Community Education Program",
"problem_to_solve": "Enhanced literacy improvement program",
"location": "New Taipei, Taiwan",
"expected_outcome_percentage": 90.0,
"created_at": "2025-01-13T10:30:00Z",
"updated_at": "2025-01-13T11:00:00Z"
}
}
```
**狀態碼**
- `200`: 成功更新
- `404`: 活動未找到
- `500`: 伺服器錯誤
### 1.4 刪除活動
**請求**
- **方法**: `DELETE`
- **路徑**: `/api/activities/{id}`
**路徑參數**
- `id`: 活動 ID (UUID)
**回應**
```json
{
"message": "Activity deleted successfully"
}
```
**狀態碼**
- `200`: 成功刪除
- `404`: 活動未找到
- `500`: 伺服器錯誤
---
## 2. Activity Inputs (活動輸入)
### 2.1 創建活動輸入
**請求**
- **方法**: `POST`
- **路徑**: `/api/activities/{activityId}/inputs`
- **Content-Type**: `application/json`
**路徑參數**
- `activityId`: 活動 ID (UUID)
**請求參數**
```json
{
"description": "Staff salaries",
"value": 50000,
"currency": "TWD",
"input_type": "Personnel",
"notes": "Monthly salaries for 5 staff members"
}
```
**欄位說明**
- `description` (必填): 輸入描述
- `value` (必填): 數值
- `currency` (必填): 幣別 (TWD, USD, EUR)
- `input_type` (必填): 輸入類型
- `notes` (選填): 備註
**回應**
```json
{
"activity_input": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"activity_id": "550e8400-e29b-41d4-a716-446655440000",
"description": "Staff salaries",
"value": 50000,
"currency": "TWD",
"input_type": "Personnel",
"notes": "Monthly salaries for 5 staff members",
"created_at": "2025-01-13T10:30:00Z"
}
}
```
**狀態碼**
- `200`: 成功創建
- `400`: 缺少必填欄位或無效幣別
- `500`: 伺服器錯誤
### 2.2 獲取活動輸入詳情
**請求**
- **方法**: `GET`
- **路徑**: `/api/activity-inputs/{id}`
**路徑參數**
- `id`: 活動輸入 ID
**回應**
```json
{
"activity_input": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"activity_id": "550e8400-e29b-41d4-a716-446655440000",
"description": "Staff salaries",
"value": 50000,
"currency": "TWD",
"input_type": "Personnel",
"notes": "Monthly salaries for 5 staff members",
"created_at": "2025-01-13T10:30:00Z"
}
}
```
**狀態碼**
- `200`: 成功獲取
- `404`: 活動輸入未找到
- `500`: 伺服器錯誤
### 2.3 更新活動輸入
**請求**
- **方法**: `PUT`
- **路徑**: `/api/activity-inputs/{id}`
- **Content-Type**: `application/json`
**路徑參數**
- `id`: 活動輸入 ID
**請求參數**
```json
{
"description": "Updated staff salaries",
"value": 60000,
"currency": "USD",
"input_type": "Personnel",
"notes": "Updated monthly salaries for 6 staff members"
}
```
**狀態碼**
- `200`: 成功更新
- `404`: 活動輸入未找到
- `500`: 伺服器錯誤
### 2.4 獲取活動的所有輸入
**請求**
- **方法**: `GET`
- **路徑**: `/api/activities/{activityId}/inputs`
**路徑參數**
- `activityId`: 活動 ID (UUID)
**回應**
```json
{
"inputs": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"activity_id": "550e8400-e29b-41d4-a716-446655440000",
"description": "Staff salaries",
"value": 50000,
"currency": "TWD",
"input_type": "Personnel",
"notes": "Monthly salaries for 5 staff members",
"created_at": "2025-01-13T10:30:00Z"
}
]
}
```
**狀態碼**
- `200`: 成功獲取
- `404`: 活動未找到
- `500`: 伺服器錯誤
### 2.5 刪除活動輸入
**請求**
- **方法**: `DELETE`
- **路徑**: `/api/activity-inputs/{id}`
**路徑參數**
- `id`: 活動輸入 ID
**狀態碼**
- `200`: 成功刪除
- `404`: 活動輸入未找到
- `500`: 伺服器錯誤
---
## 3. Activity Stakeholders (活動利害關係人)
### 3.1 創建活動利害關係人
**請求**
- **方法**: `POST`
- **路徑**: `/api/activities/{activityId}/stakeholders`
- **Content-Type**: `application/json`
**路徑參數**
- `activityId`: 活動 ID (UUID)
**請求參數**
```json
{
"name": "Local Community",
"stakeholder_type": "Beneficiary",
"description": "Residents who benefit from the education program"
}
```
**欄位說明**
- `name` (必填): 利害關係人名稱
- `stakeholder_type` (必填): 利害關係人類型
- `description` (必填): 描述
**回應**
```json
{
"activity_stakeholder": {
"id": "987fcdeb-51a2-43d7-8bc9-876543210abc",
"activity_id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Local Community",
"stakeholder_type": "Beneficiary",
"description": "Residents who benefit from the education program",
"created_at": "2025-01-13T10:30:00Z"
}
}
```
**狀態碼**
- `200`: 成功創建
- `400`: 缺少必填欄位
- `500`: 伺服器錯誤
### 3.2 獲取活動利害關係人詳情
**請求**
- **方法**: `GET`
- **路徑**: `/api/activity-stakeholders/{id}`
**路徑參數**
- `id`: 活動利害關係人 ID
**狀態碼**
- `200`: 成功獲取
- `404`: 活動利害關係人未找到
- `500`: 伺服器錯誤
### 3.3 更新活動利害關係人
**請求**
- **方法**: `PUT`
- **路徑**: `/api/activity-stakeholders/{id}`
- **Content-Type**: `application/json`
**狀態碼**
- `200`: 成功更新
- `404`: 活動利害關係人未找到
- `500`: 伺服器錯誤
### 3.4 獲取活動的所有利害關係人
**請求**
- **方法**: `GET`
- **路徑**: `/api/activities/{activityId}/stakeholders`
**路徑參數**
- `activityId`: 活動 ID (UUID)
**回應**
```json
{
"stakeholders": [
{
"id": "987fcdeb-51a2-43d7-8bc9-876543210abc",
"activity_id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Local Community",
"stakeholder_type": "Beneficiary",
"description": "Residents who benefit from the education program",
"created_at": "2025-01-13T10:30:00Z"
}
]
}
```
**狀態碼**
- `200`: 成功獲取
- `404`: 活動未找到
- `500`: 伺服器錯誤
### 3.5 刪除活動利害關係人
**請求**
- **方法**: `DELETE`
- **路徑**: `/api/activity-stakeholders/{id}`
**狀態碼**
- `200`: 成功刪除
- `404`: 活動利害關係人未找到
- `500`: 伺服器錯誤
---
## 4. Activity Outcomes (活動結果)
### 4.1 創建活動結果
**請求**
- **方法**: `POST`
- **路徑**: `/api/activities/{activityId}/outcomes`
- **Content-Type**: `application/json`
**路徑參數**
- `activityId`: 活動 ID (UUID)
**請求參數**
```json
{
"stakeholder_id": "987fcdeb-51a2-43d7-8bc9-876543210abc",
"outcome_description": "Improved literacy rates",
"indicator_name": "Reading test scores",
"quantity_achieved": 85.5,
"unit_of_measure": "percentage",
"financial_proxy_value": 1000000,
"financial_proxy_currency": "TWD",
"financial_proxy_source": "Government education statistics"
}
```
**欄位說明**
- `stakeholder_id` (必填): 利害關係人 ID (UUID)
- `outcome_description` (必填): 結果描述
- `indicator_name` (必填): 指標名稱
- `quantity_achieved` (必填): 達成數量
- `unit_of_measure` (必填): 計量單位
- `financial_proxy_value` (必填): 財務代理價值
- `financial_proxy_currency` (必填): 財務代理幣別 (TWD, USD, EUR)
- `financial_proxy_source` (必填): 財務代理來源
**回應**
```json
{
"activity_outcome": {
"id": "456e7890-f12a-34b5-c678-901234567def",
"activity_id": "550e8400-e29b-41d4-a716-446655440000",
"stakeholder_id": "987fcdeb-51a2-43d7-8bc9-876543210abc",
"outcome_description": "Improved literacy rates",
"indicator_name": "Reading test scores",
"quantity_achieved": 85.5,
"unit_of_measure": "percentage",
"financial_proxy_value": 1000000,
"financial_proxy_currency": "TWD",
"financial_proxy_source": "Government education statistics",
"created_at": "2025-01-13T10:30:00Z"
}
}
```
**狀態碼**
- `200`: 成功創建
- `400`: 缺少必填欄位或無效幣別
- `500`: 伺服器錯誤
### 4.2 獲取活動結果詳情
**請求**
- **方法**: `GET`
- **路徑**: `/api/activity-outcomes/{id}`
**狀態碼**
- `200`: 成功獲取
- `404`: 活動結果未找到
- `500`: 伺服器錯誤
### 4.3 更新活動結果
**請求**
- **方法**: `PUT`
- **路徑**: `/api/activity-outcomes/{id}`
**狀態碼**
- `200`: 成功更新
- `404`: 活動結果未找到
- `500`: 伺服器錯誤
### 4.4 獲取活動的所有結果
**請求**
- **方法**: `GET`
- **路徑**: `/api/activities/{activityId}/outcomes`
**路徑參數**
- `activityId`: 活動 ID (UUID)
**狀態碼**
- `200`: 成功獲取
- `404`: 活動未找到
- `500`: 伺服器錯誤
### 4.5 刪除活動結果
**請求**
- **方法**: `DELETE`
- **路徑**: `/api/activity-outcomes/{id}`
**狀態碼**
- `200`: 成功刪除
- `404`: 活動結果未找到
- `500`: 伺服器錯誤
---
## 5. SROI Calculations (SROI 計算)
### 5.1 創建 SROI 計算
**請求**
- **方法**: `POST`
- **路徑**: `/api/activities/{activityId}/sroi-calculations`
- **Content-Type**: `application/json`
**路徑參數**
- `activityId`: 活動 ID (UUID)
**請求參數**
```json
{
"sroi_ratio": 1.5,
"total_investment_value": 500000,
"total_investment_currency": "TWD",
"total_social_value": 750000,
"total_social_value_currency": "TWD",
"report_summary": "SROI calculation for education program"
}
```
**欄位說明**
- `sroi_ratio` (必填): SROI 比率
- `total_investment_value` (必填): 總投資價值
- `total_investment_currency` (必填): 總投資幣別 (TWD, USD, EUR)
- `total_social_value` (必填): 總社會價值
- `total_social_value_currency` (必填): 總社會價值幣別 (TWD, USD, EUR)
- `report_summary` (必填): 報告摘要
**回應**
```json
{
"sroi_calculation": {
"id": "789a0123-b456-78c9-d012-345678901234",
"activity_id": "550e8400-e29b-41d4-a716-446655440000",
"sroi_ratio": 1.5,
"total_investment_value": 500000,
"total_investment_currency": "TWD",
"total_social_value": 750000,
"total_social_value_currency": "TWD",
"calculation_date": "2025-01-13T10:30:00Z",
"report_summary": "SROI calculation for education program",
"created_at": "2025-01-13T10:30:00Z"
}
}
```
**狀態碼**
- `200`: 成功創建
- `400`: 缺少必填欄位或無效幣別
- `500`: 伺服器錯誤
### 5.2 獲取 SROI 計算詳情
**請求**
- **方法**: `GET`
- **路徑**: `/api/sroi-calculations/{id}`
**狀態碼**
- `200`: 成功獲取
- `404`: SROI 計算未找到
- `500`: 伺服器錯誤
### 5.3 更新 SROI 計算
**請求**
- **方法**: `PUT`
- **路徑**: `/api/sroi-calculations/{id}`
**狀態碼**
- `200`: 成功更新
- `404`: SROI 計算未找到
- `500`: 伺服器錯誤
### 5.4 獲取活動的所有 SROI 計算
**請求**
- **方法**: `GET`
- **路徑**: `/api/activities/{activityId}/sroi-calculations`
**狀態碼**
- `200`: 成功獲取
- `404`: 活動未找到
- `500`: 伺服器錯誤
### 5.5 刪除 SROI 計算
**請求**
- **方法**: `DELETE`
- **路徑**: `/api/sroi-calculations/{id}`
**狀態碼**
- `200`: 成功刪除
- `404`: SROI 計算未找到
- `500`: 伺服器錯誤
---
## 6. SROI Sensitivity Analyses (SROI 敏感性分析)
### 6.1 創建 SROI 敏感性分析
**請求**
- **方法**: `POST`
- **路徑**: `/api/sroi-calculations/{calculationId}/sensitivity-analyses`
- **Content-Type**: `application/json`
**路徑參數**
- `calculationId`: SROI 計算 ID
**請求參數**
```json
{
"parameter_name": "discount_rate",
"base_value": 0.03,
"test_value": 0.05,
"resulting_sroi_ratio": 1.35,
"impact_percentage": -10.0,
"notes": "Testing discount rate sensitivity"
}
```
**欄位說明**
- `parameter_name` (必填): 參數名稱
- `base_value` (必填): 基礎值
- `test_value` (必填): 測試值
- `resulting_sroi_ratio` (必填): 結果 SROI 比率
- `impact_percentage` (必填): 影響百分比
- `notes` (選填): 備註
**狀態碼**
- `200`: 成功創建
- `400`: 缺少必填欄位
- `500`: 伺服器錯誤
### 6.2 獲取 SROI 敏感性分析詳情
**請求**
- **方法**: `GET`
- **路徑**: `/api/sroi-sensitivity-analyses/{id}`
**狀態碼**
- `200`: 成功獲取
- `404`: SROI 敏感性分析未找到
- `500`: 伺服器錯誤
### 6.3 更新 SROI 敏感性分析
**請求**
- **方法**: `PUT`
- **路徑**: `/api/sroi-sensitivity-analyses/{id}`
**狀態碼**
- `200`: 成功更新
- `404`: SROI 敏感性分析未找到
- `500`: 伺服器錯誤
### 6.4 獲取 SROI 計算的所有敏感性分析
**請求**
- **方法**: `GET`
- **路徑**: `/api/sroi-calculations/{calculationId}/sensitivity-analyses`
**狀態碼**
- `200`: 成功獲取
- `404`: SROI 計算未找到
- `500`: 伺服器錯誤
### 6.5 刪除 SROI 敏感性分析
**請求**
- **方法**: `DELETE`
- **路徑**: `/api/sroi-sensitivity-analyses/{id}`
**狀態碼**
- `200`: 成功刪除
- `404`: SROI 敏感性分析未找到
- `500`: 伺服器錯誤
---
## 通用錯誤回應
### 錯誤格式
所有錯誤回應都遵循以下格式:
```json
{
"error": "錯誤訊息描述"
}
```
### 常見錯誤狀態碼
- **400 Bad Request**: 請求參數無效或缺少必填欄位
- **404 Not Found**: 請求的資源不存在
- **500 Internal Server Error**: 伺服器內部錯誤
---
## 資料模型概覽
### 支援的幣別
系統支援以下三種幣別:
- `TWD`: 新台幣
- `USD`: 美元
- `EUR`: 歐元
### UUID 格式
所有 ID 欄位都使用 UUID v4 格式,例如:`550e8400-e29b-41d4-a716-446655440000`
### 日期時間格式
所有日期時間欄位都使用 ISO 8601 格式,例如:`2025-01-13T10:30:00Z`
---
## 注意事項
1. 所有數值欄位都應該是有效的數字格式
2. UUID 欄位必須符合標準 UUID 格式
3. 幣別欄位只接受預定義的值(TWD, USD, EUR)
4. 建議在生產環境中實作適當的認證和授權機制
5. 所有的關聯關係(如 activity_id, stakeholder_id)都需要確保對應的資源存在
此 API 規格書提供了完整的活動管理系統介面,包含所有主要功能的輸入輸出規格。