#ee981
Back
2026/03/19
5 min read

任務紀錄 - 個人任務完成明細(右)

任務紀錄 - 個人任務完成明細(右).md
208 additions, 0 deletions
... ... @@ -1 +1,209 @@
1 +# 任務牆記錄 - 取得用戶任務記錄列表
2 +### SUMMARY
3 +取得指定用戶在特定主任務和子任務下的所有任務記錄。此 API 會返回 `USER_MISSION_LOG` 和對應的 `USER_EVENT_LOG`(如果有)。
4 +
5 +**資料關聯**:
6 +* 主要查詢 `USER_MISSION_LOG`
7 +* LEFT JOIN `USER_EVENT_LOG`(透過 `event_id` 關聯)
8 +* 若 `event_id` 為 NULL,則 `event_log` 欄位為 null
9 +
10 +### BUSINESS LOGIC
11 +1. 查詢 `USER_MISSION_LOG` 表
12 +2. LEFT JOIN `USER_EVENT_LOG`(ON `USER_EVENT_LOG.ID = USER_MISSION_LOG.EVENT_ID`)
13 +3. 篩選條件:
14 + * `user_id = {user_id}`
15 + * `master_id = {mission_master_id}`
16 + * `sub_id = {mission_sub_id}`
17 +4. 返回所有符合條件的任務記錄和事件記錄
18 +
19 +### NOTES
20 +* `event_log` 可能為 null(若該任務記錄未關聯事件)
21 +* `source` 欄位標記記錄來源(如 `CMS`, `SYSTEM` 等)
22 +* `count` 欄位表示該次任務完成的次數
23 +
24 +### REFERENCE TABLE
25 +
26 +**核心表**
27 +* `USER_MISSION_LOG` - 用戶任務記錄表
28 +
29 +**關聯表**
30 +* `USER_EVENT_LOG` - 用戶事件記錄表
31 +
32 +### ATTRIBUTES
33 +* METHOD: **GET**
34 +* PATH: `/api/features/mission-board/record/user-mission-logs/<string:user_id>/<int:mission_master_id>/<int:mission_sub_id>`
35 +* LOGIN REQUIRED: **TRUE**
36 +* FEATURE: `MISSION_BOARD_RECORD`
37 +* PERMISSION: `READ`
38 +* CRYPTO: **None**
39 +
40 +### REQUEST
41 +#### HEADERS
42 +
43 +| Name | Type/Len | Required(*) | Desc |
44 +| ---| ---| ---| --- |
45 +| Authorization | String | * | JWT Token |
46 +| X-Request-Id | String | | X-Request-Id for api flow tracing |
47 +
48 +```json
49 +// Example:
50 +{
51 + "Authorization": "Bearer jwt-token",
52 + "x-request-id": "78f91284-d9df-43e6-a8d2-d557273c10bb"
53 +}
54 +```
55 +
56 +#### PATH PARAMETERS
57 +
58 +| Name | Type/Len | Required(*) | Desc |
59 +| ---| ---| ---| --- |
60 +| user_id | String | * | 用戶 ID |
61 +| mission_master_id | Integer | * | 主任務 ID |
62 +| mission_sub_id | Integer | * | 子任務 ID |
63 +
64 +```sql
65 +// Example
66 +GET /api/features/mission-board/record/user-mission-logs/U123456789/1/10
67 +```
68 +
69 +### RESPONSE
70 +#### STATUS CODE
71 +* 200 OK
72 +
73 +#### HEADERS
74 +
75 +| Name | Type/Len | Desc |
76 +| ---| ---| --- |
77 +| Authorization | String | JWT Token |
78 +| X-Request-Id | String | Returning Request-Id |
79 +
80 +```json
81 +// Example:
82 +{
83 + "Authorization": "Bearer jwt-token",
84 + "x-request-id": "78f91284-d9df-43e6-a8d2-d557273c10bb"
85 +}
86 +```
87 +
88 +#### BODY
89 +
90 +| Level | Name | Type/Len | Nullable(*) | Desc |
91 +| ---| ---| ---| ---| --- |
92 +| 1 | status | String | | 回應狀態 (SUCCESS, FAILURE) |
93 +| 1 | data | Dict | | 回應資料 |
94 +
95 +#### Data
96 +
97 +| Level | Name | Type/Len | Nullable(*) | Desc |
98 +| ---| ---| ---| ---| --- |
99 +| 2 | items | List | | 任務記錄列表 |
100 +
101 +#### items
102 +
103 +| Level | Name | Type/Len | Nullable(*) | Desc |
104 +| ---| ---| ---| ---| --- |
105 +| 3 | mission_log | Dict | | 任務記錄 |
106 +| 3 | event_log | Dict | * | 事件記錄(可能為 null) |
107 +
108 +#### mission_log
109 +
110 +| Level | Name | Type/Len | Nullable(*) | Desc | Source |
111 +| ---| ---| ---| ---| ---| --- |
112 +| 4 | id | Integer | | 任務記錄 ID | `USER_MISSION_LOG.ID` |
113 +| 4 | user_id | String | | 用戶 ID | `USER_MISSION_LOG.USER_ID` |
114 +| 4 | sub_id | Integer | | 子任務 ID | `USER_MISSION_LOG.SUB_ID` |
115 +| 4 | master_id | Integer | | 主任務 ID | `USER_MISSION_LOG.MASTER_ID` |
116 +| 4 | count | Integer | * | 完成次數 | `USER_MISSION_LOG.COUNT` |
117 +| 4 | event_id | Integer | * | 事件 ID | `USER_MISSION_LOG.EVENT_ID` |
118 +| 4 | batch_id | Integer | * | 批次異動來源 CMS | `USER_MISSION_LOG_BATCH.ID` |
119 +| 4 | source | String | * | 記錄來源(如 CMS, SYSTEM) | `USER_MISSION_LOG.SOURCE` |
120 +| 4 | create_time | DateTime | | 建立時間 | `USER_MISSION_LOG.CREATE_TIME` |
121 +
122 +#### event_log
123 +
124 +| Level | Name | Type/Len | Nullable(*) | Desc | Source |
125 +| ---| ---| ---| ---| ---| --- |
126 +| 4 | id | Integer | | 事件 ID | `USER_EVENT_LOG.ID` |
127 +| 4 | user_id | String | | 用戶 ID | `USER_EVENT_LOG.USER_ID` |
128 +| 4 | producer_id | String | * | 產生者 ID | `USER_EVENT_LOG.PRODUCER_ID` |
129 +| 4 | activity_type | Enum | * | 活動類型 | `USER_EVENT_LOG.ACTIVITY_TYPE` |
130 +| 4 | content | Dict | | 事件內容(JSON) | `USER_EVENT_LOG.CONTENT` |
131 +| 4 | create_time | DateTime | | 建立時間 | `USER_EVENT_LOG.CREATE_TIME` |
132 +
133 +```json
134 +// Example:
135 +{
136 + "status": "SUCCESS",
137 + "data": {
138 + "items": [
139 + {
140 + "mission_log": {
141 + "id": 10001,
142 + "user_id": "U123456789",
143 + "master_id": 1,
144 + "sub_id": 10,
145 + "count": 1,
146 + "event_id": 50001,
147 + "source": "SYSTEM",
148 + "create_time": "2026-03-19T10:30:00"
149 + },
150 + "event_log": {
151 + "id": 50001,
152 + "user_id": "U123456789",
153 + "producer_id": "DEPOSIT_SERVICE",
154 + "activity_type": "DEPOSIT",
155 + "content": {
156 + "amount": 1000,
157 + "currency": "TWD"
158 + },
159 + "create_time": "2026-03-19T10:29:55"
160 + }
161 + },
162 + {
163 + "mission_log": {
164 + "id": 10002,
165 + "user_id": "U123456789",
166 + "master_id": 1,
167 + "sub_id": 10,
168 + "count": 2,
169 + "event_id": null,
170 + "source": "CMS",
171 + "create_time": "2026-03-19T11:00:00"
172 + },
173 + "event_log": null
174 + }
175 + ]
176 + }
177 +}
178 +```
179 +
180 +#### ERROR CODE
181 +
182 +| HTTP Status | ErrorCode | Message | Desc |
183 +| ---| ---| ---| --- |
184 +| 400 | ValidationError.INVALID_INPUT | Invalid input data | 輸入資料格式錯誤 |
185 +| 422 | ValidationError.SCHEMA_VALIDATION_FAILED | Schema validation failed | Schema 驗證失敗 |
186 +
187 +### CODE REFERENCE
188 +
189 +**Route**: [route.py](http://../route.py#L59-L72)
190 +
191 +```python
192 +@bp.get('/user-mission-logs/<string:user_id>/<int:mission_master_id>/<int:mission_sub_id>')
193 +@bp.doc(summary='取得 USER_MISSION_LOG 列表')
194 +@bp.auth_required(auth)
195 +@read_permission_required(Feature.MISSION_BOARD_RECORD)
196 +@bp.output(GetUserMissionLogJoinedEventLogsOutSchema, status_code=200)
197 +```
198 +
199 +**Schema**: [schema.py](http://../schema.py)
200 +* Output: `GetUserMissionLogJoinedEventLogsOutSchema` (lines 143-144)
201 +* Item: `GetUserMissionLogJoinedEventLogOutSchema` (lines 139-141)
202 +* Nested: `GetUserMissionLogOutSchema` (lines 110-118), `GetUserEventLogOutSchema` (lines 120-137)
203 +
204 +**Service**: [service.py](http://../service.py)
205 +* `get_user_mission_logs()` (lines 227-245)
206 +
207 +**Presenter**: [presenter.py](http://../presenter.py)
208 +* `display_user_mission_logs()` (lines 150-172)