---
# System prepended metadata

title: 活動資料收集表單設計與資料處理模組

---

# 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 規格書提供了完整的活動管理系統介面，包含所有主要功能的輸入輸出規格。
