Points FAQ
Bối cảnh
Trên Shukah, app đọc các câu hỏi và câu trả lời về điểm bằng GET /maeda/points-faq.
GET /api/v2/client/points-faq của Locate trả về cùng danh sách, và trên dev năm mục giống hệt
của Shukah vào 2026-10-01 và lại vào 2026-10-02, từng key một. Điều duy nhất thay đổi là
token: Locate cần một token, và trên dev hiện nay nó phải là token Shukah, còn route của Shukah trả lời
mà không cần.
Tính năng
FAQ là một danh sách câu hỏi và câu trả lời về điểm: một điểm có giá trị bao nhiêu, cách tích điểm, cách dùng chúng. Đó là cùng một danh sách cho mọi client. Trong snapshot app ngày 2026-02-26 lời gọi xảy ra một lần, khi màn hình Wallet hiển thị phần FAQ của nó. App không hiển thị gì khi danh sách rỗng.
Mỗi mục mang cả hai ngôn ngữ: title_ar, text_ar, title_en và text_en. Server
luôn gửi cả bốn, và app chọn cặp nào để hiển thị. language không được point
service đọc, và order-v2 không forward query trên route này, nên language mà app thêm vào
mọi lời gọi bị bỏ.
Hiện nay trên dev chỉ có token Shukah chạy: một JWT Locate nhận 401 Invalid or expired token trên route
này vào 2026-10-02, dù cả hai token đều chạy trên route balance vào 2026-10-01 (xem
Which tokens work). order-v2 chuyển lời gọi sang point
service và trả câu trả lời không đổi.
GET /api/v2/client/points-faq
GET /maeda/points-faq✅ Đã thay thế- 🟡 Locate cần token; Shukah trả 200 khi không có token; app luôn gửi token.
- 🟡 JWT của Locate nhận 401 trên dev; hãy gửi token của Shukah.
- 🟡 Năm mục giống hệt nhau, kể cả \r\n; nội dung cách tích điểm trong FAQ không khớp bảng tỷ lệ nào.
Năm mục FAQ giống hệt Shukah trên dev, nhưng Locate cần token trong khi Shukah trả lời không cần token.
Request
| Field | Vị trí | Kiểu | Bắt buộc | Ràng buộc | Mô tả |
|---|---|---|---|---|---|
Authorization | header | string | có | Bearer <token>: một token Shukah trên dev hiện nay. Một JWT Locate nhận 401 Invalid or expired token (capture trên dev, 2026-10-02): xem Which tokens work. | Token của chính client. |
language | query | string | không | Được chấp nhận và bỏ qua: cả bốn field luôn được trả về. order-v2 không forward nó. | Giữ lại để query string Shukah cũ vẫn chạy. |
Response
200 với một mảng trần. Các key của mỗi mục đến theo thứ tự: title_ar, text_ar, title_en,
text_en. Mảng theo thứ tự đặt trong cài đặt FAQ và chỉ chứa các mục active. Trên dev nó có năm mục.
| Field | Kiểu | Nullable | Định dạng / ràng buộc | Mô tả |
|---|---|---|---|---|
title_ar | string | không | "" khi thiếu. | Câu hỏi bằng tiếng Ả Rập. |
text_ar | string | không | "" khi thiếu. Có ngắt dòng \r\n. | Câu trả lời bằng tiếng Ả Rập. |
title_en | string | không | "" khi thiếu. | Câu hỏi bằng tiếng Anh. |
text_en | string | không | "" khi thiếu. Có ngắt dòng \r\n. Một mục live kết thúc bằng \t \r\n. | Câu trả lời bằng tiếng Anh. |
[
{
"title_ar": "كم قيمة النقطة في لوكيت؟",
"text_ar": "النقطة الواحدة تساوي 0.25 ريال.\r\nيعني 4 نقاط تساوي ريال واحد.",
"title_en": "How many points are worth in the Locate App?",
"text_en": "each point equal to 0.25 SR\r\nthat means, each 4 points equal to one SR"
}
]
Capture trên dev, 2026-10-01 (client 356259): mục đầu tiên trong năm mục.
Câu trả lời cho "How I can earn points?" nêu một bảng tích điểm với 35–69 SR được 1 điểm, 70–139 SR được 2, 140–250 SR được 4, 251–450 SR được 8 và từ 451 SR trở lên được 16. Bảng đó không khớp với bảng tỷ lệ tích điểm nào trong hai bảng được capture cùng ngày (xem Points wallet). Bảng nào là đúng: Chưa được tài liệu hóa.
Lỗi
| HTTP | Body | Khi nào |
|---|---|---|
401 | {"success":false,"error":{"code":"UNAUTHORIZED","message":"Missing or invalid authorization header"}} | Không có header Authorization, hoặc nó không bắt đầu bằng Bearer . Đã capture trên dev, 2026-10-01, khi không có token. |
401 | Cùng shape, với message là Invalid or expired token, auth service unreachable: <error text> hoặc auth response missing numeric client id. | Auth service từ chối token, không kết nối được (sự cố auth trông giống token xấu), hoặc trả lời mà không có client id. Invalid or expired token đã được capture trên dev, 2026-10-02, với một JWT Locate. |
500 | {"success":false,"error":{"code":"INTERNAL_ERROR","message":"Internal server error"}} | Bất kỳ lỗi không mong đợi nào trong point service, ví dụ lỗi database. Message là AUTH_SERVICE_URL not set khi service bị cấu hình sai. Chưa capture. |
502 | {"success":false,"error":{"code":"POINT_SERVICE_UNAVAILABLE","message":"Point service unavailable: <error text>"}} | order-v2 không kết nối được point service. Body này đến từ order-v2, không phải từ point service. Chưa capture. |
504 | {"success":false,"error":{"code":"POINT_SERVICE_TIMEOUT","message":"Point service did not respond in time; the request outcome is unknown"}} | Point service không trả lời trong 10 giây. Body này đến từ order-v2. Chưa capture. |
Mọi lỗi từ point service đều có envelope {"success":false,"error":{"code":"…","message":"…"}}.
Thử ngay
export ORDER_BASE_URL=https://dev.v2.api.order.locate.sa
export SHUKAH_TOKEN='<shukah-token>' # a Locate JWT gets 401 here today; see "Which tokens work" on Points wallet
curl -s "$ORDER_BASE_URL/api/v2/client/points-faq" -H "Authorization: Bearer $SHUKAH_TOKEN"
Kỳ vọng: 200 và một mảng năm mục như mục được hiển thị ở Response. Hãy dùng token Shukah trên
dev hiện nay: một JWT Locate nhận 401 Invalid or expired token (2026-10-02). Không có token bạn nhận
401 như ở mục Lỗi.
Khác biệt so với Shukah
Hai mảng năm mục deep-equal vào 2026-10-01 và vào 2026-10-02, với cùng thứ tự key
và cùng các ngắt dòng \r\n. Các dòng dưới đây nói về token, URL và body lỗi.
| Khía cạnh | Shukah | Locate | Tác động lên app |
|---|---|---|---|
| URL | GET $SHUKAH_BASE_URL/maeda/points-faq | GET $ORDER_BASE_URL/api/v2/client/points-faq | Đổi base URL và path. |
| Token | Không cần: 200 khi không có token (capture trên dev, 2026-10-01). | Bắt buộc: 401 khi không có token (capture trên dev, 2026-10-01). Chỉ token Shukah trên dev hiện nay: một JWT Locate nhận 401 (2026-10-02). | App đã gửi token của nó trên mọi lời gọi, và phải giữ nó là token Shukah ở đây. Một màn hình hiển thị FAQ trước khi đăng nhập sẽ lỗi. Màn hình như vậy có tồn tại hay không: Chưa được tài liệu hóa. |
| Body lỗi | Chưa được tài liệu hóa. Route này public, nên không có 401 để so sánh. | Envelope của point-service ở mục Lỗi. | Mọi chỗ so khớp theo text lỗi đều phải đổi. |
Content-Type | application/json | application/json; charset=utf-8 | Không có. |
Lưu ý
- Locate cần token trên route này, trong khi route của Shukah trả lời mà không cần.
- Cả bốn field được trả về trong mọi mục, và
languagebị bỏ qua, nên app phải tự chọn cặp tiếng Ả Rập hoặc tiếng Anh. - Bảng tích điểm viết trong text FAQ không khớp với bảng tỷ lệ tích điểm nào trên dev.
Chi tiết (cho backend)
Chỉ kiểm tra dev, qua order-v2 tại https://dev.v2.api.order.locate.sa, prefix /api/v2/client.
Host UAT và production: Chưa được tài liệu hóa. Trong mục này OV2: nghĩa là
locate-order-v2-api@d9e4e5f6 và PS: nghĩa là locate-point-service@2c44ce3. Cách proxy, việc
kiểm tra token và error envelope hoạt động được mô tả một lần, ở
Các lời gọi proxy hoạt động thế nào.
Route và proxy
GET /api/v2/client/points-faq đi tới GET /api/client/points-faq trên point service. order-v2
chỉ forward Authorization, với giới hạn 10 giây, và không có query
(OV2: src/modules/client/point/point.controller.ts:47-59,
PS: services/api/src/routes/client.routes.ts:19,
PS: services/api/src/handlers/client-points-faq.ts:6-9).
Point service đọc gì
Nó đọc các dòng point_faqs với status: 'active', sắp theo ordering từ thấp đến cao, và
làm phẳng mỗi document {title:{en,ar}, text:{en,ar}} thành bốn key phẳng. Giá trị thiếu
thành "" (PS: services/api/src/services/client-points.service.ts:43-50,
PS: services/api/src/services/client-points.mappers.ts:58-71; test
PS: services/api/src/services/client-points.mappers.test.ts:88-107). Danh sách không đặc thù theo
client. ETL của auth service điền point_faqs từ bảng FAQ của Shukah; các route client không thể
ghi nó (PS: docs/integrations/2026-07-16-client-facing-point-apis.md:172-174,
PS: docs/2026-07-10-local-testing.md:53).
Tương đương
Vào 2026-10-01 các mảng của Locate và Shukah được so sánh bằng chương trình và deep-equal, với cùng
thứ tự key. Vào tháng 7 danh sách của Locate là stub rỗng, nên điều này đóng finding đó
(PS: docs/reports/2026-07-17-client-api-parity.md:165-168). Tài liệu của point service đã
ghi nhận sự bằng nhau sau lần implement ngày 2026-07-17
(PS: docs/integrations/2026-07-16-client-facing-point-apis.md:171-174).
App
App biến mỗi mục thành tiêu đề và nội dung bằng tiếng Anh và tiếng Ả Rập, hiển thị cặp khớp với
ngôn ngữ của app, dùng tiêu đề tiếng Anh làm list key, và không hiển thị gì cho danh sách rỗng
(mobile/locate-client@e960c3a: src/entities/points/model/api/dto/points.dto.ts:53-68,
mobile/locate-client@e960c3a: src/features/PointsFaq/ui/FaqItem/FaqItem.tsx:32-37,
mobile/locate-client@e960c3a: src/features/PointsFaq/ui/PointsFaq/PointsFaq.tsx:27-70). Nó gọi
route mà không có query riêng (mobile/locate-client@e960c3a: src/entities/points/model/api/services/points.service.ts:62-76).
Khi tài liệu và code mâu thuẫn (code thắng)
- 2026-10-02: trang này nói một token Shukah và một JWT Locate đều chạy ở đây. Vào 2026-10-02 JWT
nhận
401Invalid or expired token, và mục Thử ngay giờ dùng một token Shukah (PS: services/api/src/services/client-auth.service.ts:22-29; xem Which tokens work).
Sources
locate-order-v2-api@d9e4e5f6:src/modules/client/point/point.controller.ts:47-59locate-point-service@2c44ce3:services/api/src/routes/client.routes.ts:19,services/api/src/handlers/client-points-faq.ts:6-9,services/api/src/services/client-points.service.ts:43-50,services/api/src/services/client-points.mappers.ts:58-71,services/api/src/services/client-points.mappers.test.ts:88-107- Tài liệu của
locate-point-service@2c44ce3:docs/integrations/2026-07-16-client-facing-point-apis.md:171-174,docs/2026-07-10-local-testing.md:53,docs/reports/2026-07-17-client-api-parity.md:165-168 - Snapshot mobile
mobile/locate-client@e960c3a(branchdevelopment, 2026-02-26; code của chính app, không phải Locate):src/entities/points/model/api/services/points.service.ts:62-76,src/entities/points/model/api/dto/points.dto.ts:53-68,src/features/PointsFaq/ui/PointsFaq/PointsFaq.tsx:27-70,src/features/PointsFaq/ui/FaqItem/FaqItem.tsx:32-37,platforms/mobile/products/locate/screens/home/mainInner/Wallet/ui/Wallet/Wallet.tsx:84 - Capture dev, 2026-10-02 (parity audit):
points-faq--shukah,points-faq--locate-st,points-faq--locate-jwt,points-faq-notoken--shukah - Capture dev, 2026-10-01:
locate-points-faq,shukah-points-faq,probe-locate-points-faq,probe-shukah-points-faq