NON-PRODUCTION
Mission — tài liệu ghép client
Nhiệm vụ của user trên lobby (không phải HTTP game). Client gọi POST /api/v2/rpc
trên game-api-gateway, body mã hóa AES giống daily bonus / gold digger.
Có 4 kỳ: ngày, tuần, tháng, và sự kiện (khoảng thời gian cố định).
1. Tổng quan
| Mục | Giá trị |
|---|---|
| Gateway | game-api-gateway · POST /api/v2/rpc |
| Auth | JWT game trong header, middleware GameJWTVerify |
| Prefix method | /mission — /list, /detail, /claim |
| Timezone | Server UTC+7 |
| Claim | 1 lần / snapshot. Thưởng gửi chip mail, không cộng chip ngay trên response. |
Server tự lọc mission theo VIP / country của user. Client không gửi user_id — lấy từ JWT.
description và progress_text đã localize theo country publisher. Client không dịch thêm.
Progress online được flush khi user mở list / detail / claim.
2. Period types
Mỗi mission có period_type. Dùng để chia tab. Không hardcode label — map từ value dưới đây.
| value | Kỳ | Reset / hết hạn |
|---|---|---|
daily | Hàng ngày | from_time = 0h hôm nay UTC+7, to_time = +24h |
weekly | Hàng tuần | Đầu tuần → +7 ngày (UTC+7) |
monthly | Hàng tháng | Đầu tháng → cuối tháng (UTC+7) |
event | Sự kiện đặc biệt | Khoảng cố định CMS chỉ định. Dùng from_time / to_time trên từng mission |
Countdown trên card =
to_time - now (unix seconds). Khi hết hạn, list lần sau sẽ không còn mission đó.
Không giả định mọi mission reset lúc 0h — weekly / monthly / event sống lâu hơn 1 ngày.
3. Auth & envelope
Giống mọi RPC lobby: decrypt data → JSON {"method","data"} → handler → encrypt {"code","msg"}.
POST /api/v2/rpc
Authorization: Bearer <access_token>
Content-Type: application/json
decrypt → {
"method": "/mission/list",
"data": {}
}
success → HTTP 200, encrypted { "code": 0, "msg": { ... } }
error → HTTP 500, encrypted { "code": ..., "msg": ... }
Popup lỗi dùng code = 1000 và msg là chuỗi i18n (khi parse được error từ server).
4. List missions đang chạy
method: /mission/list
data có thể rỗng {} (trả tất cả period) hoặc lọc 1 tab:
data:
{}
// hoặc
{ "period_type": "daily" } // daily | weekly | monthly | event
// sai / lạ → list rỗng cho filter đó, không lỗi
msg:
{
"missions": [
{
"snapshot_id": 1001,
"name": "Play 10 games",
"description": "Chơi 10 ván hôm nay",
"period_type": "daily",
"from_time": 1756227600,
"to_time": 1756314000,
"progress": 4,
"target": 10,
"percent": 40,
"progress_text": "",
"completed": false,
"claimed": false,
"reward_amount": 1000,
"icon_url": "https://cdn.example.com/missions/play-10.png"
}
]
}
| Field | Ý nghĩa |
|---|---|
snapshot_id | ID snapshot đang chạy. Dùng khi detail / claim. Không dùng template id. |
name | Title hiển thị (CMS soạn). |
description | Mô tả đã localize theo country publisher của user. Client không dịch thêm. |
period_type | daily / weekly / monthly / event. Chia tab. |
from_time / to_time | Unix seconds. Kỳ của mission này. Dùng countdown / “còn lại”. |
progress | Tiến độ thô (số ván / chip / giây online / tiền nạp…). |
target | Mốc cần đạt. Hiện progress / target (vd. 4 / 10). |
percent | 0–100, đã cap. Progress bar. |
progress_text | Dòng phụ server đã localize. Rỗng "" với mission thường. Ranking: ngày nhận thưởng tuần sau, kèm tag Unity rich text <color=#e3b602>…</color>. Hiện nguyên chuỗi, không tự ghép ngày. |
completed | true khi đủ target. |
claimed | Đã nhận thưởng. |
reward_amount | Chip sẽ nhận nếu claim bây giờ. Chip cố định hoặc cashback % progress hiện tại. |
icon_url | URL icon mission (CMS soạn, khuyến nghị 50×50, mỗi chiều tối đa 200px). Có thể rỗng "" — khi đó client dùng icon mặc định lưu local, không ẩn card. |
icon_url rỗng / thiếu = không có ảnh CMS. Client luôn có 1 icon default (asset local), chỉ thay bằng URL khi chuỗi không rỗng.
Nút Claim chỉ hiện khi
completed === true và claimed === false. Claim xong set claimed = true local hoặc gọi lại list.
Ranking mission:
progress_text không rỗng, ví dụ
Automatically receive the reward on <color=#e3b602>15-09</color>
(ngày = đầu tuần sau, format DD-MM, đã dịch theo country). Render rich text; không parse tay ngày.
List trả mọi mission đang active (daily hôm nay + weekly tuần này + monthly tháng này + event còn hạn), không chỉ daily.
Muốn 4 tab: gọi 1 lần
data: {} rồi group theo period_type (khuyến nghị), hoặc gọi 4 lần với từng period_type.
5. Mission detail
method: /mission/detail
Một mission theo snapshot_id lấy từ list. Shape mission giống từng phần tử trong list (kèm target, progress_text).
data:
{ "snapshot_id": 1001 }
msg:
{
"mission": {
"snapshot_id": 1001,
"name": "Weekly ranking",
"description": "Top bảng xếp hạng tuần này",
"period_type": "weekly",
"from_time": 1756227600,
"to_time": 1756832400,
"progress": 12000,
"target": 1,
"percent": 100,
"progress_text": "Automatically receive the reward on <color=#e3b602>15-09</color>",
"completed": true,
"claimed": false,
"reward_amount": 5000,
"icon_url": "https://cdn.example.com/missions/ranking.png"
}
}
- Dùng khi user mở màn hình chi tiết / tap card — progress được đọc lại từ DB, không chỉ cache list.
- Bắt buộc
snapshot_idtừ list. Không tự bịa template id. snapshot_id <= 0hoặc snapshot không còn active → lỗi (refresh list).- Không cần gửi
period_type.
6. Claim reward
method: /mission/claim
data:
{ "snapshot_id": 1001 }
msg success:
{ "snapshot_id": 1001, "reward_amount": 1000 }
- Claim 1 lần / snapshot. Gọi lại → lỗi đã nhận.
- Chưa đủ progress → lỗi chưa hoàn thành.
reward_amountlà số chip gửi qua chip mail, không phải số dư ngay. Toast “đã gửi vào hộp thư”.snapshot_id <= 0→ invalid input.- Claim không cần gửi
period_type.
7. Gợi ý UI
- Vào lobby / event → gọi
/mission/listvới{}. - Chia 4 tab theo
period_type: Daily / Weekly / Monthly / Event. Tab không có mission thì ẩn hoặc empty state. - Card: icon =
icon_url(rỗng → icon default local), title =name, sub =description, bar =percent, số =progress / target, chip =reward_amount. - Nếu
progress_textkhông rỗng: hiện dòng đó (rich text) thay vì tự viết “nhận thưởng ngày …”. Ranking thưởng tuần sau, không claim tay. - Tap card →
/mission/detailvớisnapshot_idđể refresh progress trước khi hiện popup chi tiết. - Countdown =
to_time(unix). Weekly / monthly / event nên hiện “còn X ngày/giờ”. - Completed chưa claim: CTA Claim. Đã claim: badge Claimed, disable.
- Sau claim: cập nhật card hoặc list lại. Có thể poll mail / chip nếu UI đang hiện số dư.
- Đừng cache list sang ngày khác — daily đổi mỗi 0h UTC+7; weekly/monthly/event đổi theo
to_time.
Không hardcode target type, tên, hay mốc. CMS đổi nội dung / kỳ / thưởng. Client chỉ tin field list trả về.
8. Error codes
| Tình huống | Hành vi client |
|---|---|
| JWT hết hạn / decrypt fail | code -3 — login lại |
| Thiếu token | code -4 |
| snapshot_id invalid / body list / detail không parse được | code -2 invalid input |
| Đã claim | popup i18n ERROR_EVENT_REWARD_RECEIVED |
| Chưa hoàn thành | popup i18n ERROR_NOT_TIME |
| Snapshot không tồn tại / đã hết hạn (claim) | popup i18n ERROR_DATA_NOT_FOUND |
| Detail snapshot không còn / id lạ | code -1 — đóng popup, gọi lại list |
| Lỗi khác | code -1 unknown |
9. Checklist
- Group hoặc filter theo
period_type— 4 tab, không gộp tất cả thành “nhiệm vụ ngày”. - Hiện countdown từ
to_time. - Số tiến độ =
progress / target. Dòng phụ ranking =progress_text(rich text), không tự dịch / tự ghép ngày. - Màn chi tiết gọi
/mission/detailvớisnapshot_idtừ list. - Claim dùng
snapshot_idtừ list, không tự bịa. - Disable double-tap claim.
- Không cộng chip local từ
reward_amountvào balance (thưởng nằm ở mail). - Empty list / empty tab là hợp lệ (VIP này không có mission kỳ đó).
- Dùng
description/progress_textserver trả về, không tự dịch enum. - Hiện
icon_urltrên card; rỗng thì dùng icon mặc định client, không ẩn mission.