{"openapi":"3.0.3","info":{"title":"TestMart API","description":"Backend API thực hành cho series API Testing Thực Chiến.","version":"0.2.0"},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT trả về từ `POST /auth/login`. Cookie `testmart_sbx` được cấp tự động ở request đầu tiên."},"sandboxCookie":{"type":"apiKey","in":"cookie","name":"testmart_sbx","description":"Cookie HttpOnly do server cấp tự động ở request đầu tiên. Mọi HTTP client phổ biến (Postman, browser) đều tự lưu và gửi lại."}},"schemas":{}},"paths":{"/health":{"get":{"summary":"Kiểm tra service còn hoạt động","tags":["System"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["status","service"],"properties":{"status":{"type":"string"},"service":{"type":"string"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/ready":{"get":{"summary":"Kiểm tra service và storage đã sẵn sàng","tags":["System"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["status","store"],"properties":{"status":{"type":"string"},"store":{"type":"string","enum":["postgres","memory"]}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/sandbox":{"post":{"summary":"Tạo sandbox dữ liệu riêng cho người học","tags":["Sandbox"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"example":"Book lab"}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["sandbox","seedUsers"],"properties":{"sandbox":{"type":"object","required":["id","type","name","createdAt","expiresAt","bugs"],"properties":{"id":{"type":"string","example":"sbx_demo"},"type":{"type":"string","enum":["user","system"],"example":"user"},"name":{"type":"string","example":"Book lab"},"createdAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"bugs":{"type":"object","additionalProperties":{"type":"boolean"}}}},"seedUsers":{"type":"array","items":{"type":"object","required":["id","email","name","role"],"properties":{"id":{"type":"string","example":"usr_sbx_demo_a"},"email":{"type":"string","format":"email","example":"customer.a@testmart.local"},"name":{"type":"string","example":"Khách hàng A"},"role":{"type":"string","enum":["USER","ADMIN"]}}}}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/sandbox/me":{"get":{"summary":"Xem sandbox hiện tại","tags":["Sandbox"],"responses":{"200":{"description":"Default Response"}}}},"/sandbox/reset":{"post":{"summary":"Reset sandbox hiện tại","tags":["Sandbox"],"responses":{"200":{"description":"Default Response"}}}},"/sandbox/bugs":{"patch":{"summary":"Cập nhật intentional bug flags","tags":["Sandbox"],"responses":{"200":{"description":"Default Response"}}}},"/auth/register":{"post":{"summary":"Đăng ký user mới","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password","name"],"properties":{"email":{"type":"string","format":"email","maxLength":255},"password":{"type":"string","minLength":8,"maxLength":72},"name":{"type":"string","minLength":1,"maxLength":100}}}}}},"responses":{"200":{"description":"Default Response"}}}},"/auth/login":{"post":{"summary":"Đăng nhập và nhận access token","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email","example":"customer.a@testmart.local"},"password":{"type":"string","example":"Password123!"}}}}}},"parameters":[{"schema":{"type":"string"},"in":"header","name":"cookie","required":false,"description":"Auto-set testmart_sbx cookie. Usually managed by the client."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["user","accessToken","refreshToken"],"properties":{"user":{"type":"object","required":["id","email","name","role"],"properties":{"id":{"type":"string","example":"usr_sbx_demo_a"},"email":{"type":"string","format":"email","example":"customer.a@testmart.local"},"name":{"type":"string","example":"Khách hàng A"},"role":{"type":"string","enum":["USER","ADMIN"]}}},"accessToken":{"type":"string"},"refreshToken":{"type":"string"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/auth/refresh":{"post":{"summary":"Làm mới access token","tags":["Auth"],"responses":{"200":{"description":"Default Response"}}}},"/auth/logout":{"post":{"summary":"Đăng xuất user hiện tại","tags":["Auth"],"responses":{"200":{"description":"Default Response"}}}},"/auth/change-password":{"post":{"summary":"Đổi mật khẩu cho user hiện tại","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["currentPassword","newPassword"],"properties":{"currentPassword":{"type":"string","minLength":1,"maxLength":72},"newPassword":{"type":"string","minLength":8,"maxLength":72}}}}}},"parameters":[{"schema":{"type":"string","example":"Bearer <accessToken>"},"in":"header","name":"authorization","required":false}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["changed"],"properties":{"changed":{"type":"boolean"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/users/me":{"get":{"summary":"Xem profile của user hiện tại","tags":["Users"],"parameters":[{"schema":{"type":"string","example":"Bearer <accessToken>"},"in":"header","name":"authorization","required":false},{"schema":{"type":"string"},"in":"header","name":"cookie","required":false,"description":"Auto-set testmart_sbx cookie"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["id","email","name","role"],"properties":{"id":{"type":"string","example":"usr_sbx_demo_a"},"email":{"type":"string","format":"email","example":"customer.a@testmart.local"},"name":{"type":"string","example":"Khách hàng A"},"role":{"type":"string","enum":["USER","ADMIN"]}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}},"patch":{"summary":"Cập nhật profile hiện tại","tags":["Users"],"responses":{"200":{"description":"Default Response"}}}},"/users":{"get":{"summary":"Danh sách user trong sandbox","tags":["Users"],"responses":{"200":{"description":"Default Response"}}}},"/admin/users":{"post":{"summary":"Tạo user mới (admin)","tags":["Users"],"responses":{"200":{"description":"Default Response"}}},"get":{"summary":"Danh sách user (admin)","tags":["Users"],"responses":{"200":{"description":"Default Response"}}}},"/admin/users/{userId}":{"get":{"summary":"Xem chi tiết user (admin)","tags":["Users"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"userId","required":true}],"responses":{"200":{"description":"Default Response"}}},"patch":{"summary":"Cập nhật user (admin)","tags":["Users"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"userId","required":true}],"responses":{"200":{"description":"Default Response"}}},"delete":{"summary":"Xóa mềm user (admin)","tags":["Users"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"userId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/users/{userId}/orders":{"get":{"summary":"Danh sách order của một user (admin)","tags":["Users"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"userId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","sandboxId","userId","status","items","subtotal","discount","total","currency","createdAt"],"properties":{"id":{"type":"string","example":"ord_123"},"sandboxId":{"type":"string"},"userId":{"type":"string"},"status":{"type":"string","enum":["CREATED","PAYMENT_PENDING","PAID","PACKED","SHIPPED","CANCELLED","REFUNDED","FAILED"]},"items":{"type":"array","items":{"type":"object","required":["productId","name","quantity","unitPrice","subtotal"],"properties":{"productId":{"type":"string"},"name":{"type":"string"},"quantity":{"type":"integer"},"unitPrice":{"type":"integer"},"subtotal":{"type":"integer"}}}},"subtotal":{"type":"integer"},"discount":{"type":"integer"},"total":{"type":"integer"},"currency":{"type":"string","enum":["VND"]},"couponCode":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/admin/users/{userId}/payments":{"get":{"summary":"Danh sách payment của một user (admin)","tags":["Users"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"userId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","sandboxId","orderId","userId","amount","currency","status","createdAt"],"properties":{"id":{"type":"string","example":"pay_123"},"sandboxId":{"type":"string"},"orderId":{"type":"string"},"userId":{"type":"string"},"amount":{"type":"integer","example":398000},"currency":{"type":"string","enum":["VND"]},"status":{"type":"string","enum":["PENDING","AUTHORIZED","CAPTURED","FAILED","REFUNDED","DUPLICATE"]},"idempotencyKey":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/admin/users/{userId}/cart":{"get":{"summary":"Xem cart của một user bất kỳ (admin)","tags":["Cart"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"userId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["cart","items","subtotal","discount","total"],"properties":{"cart":{"type":"object","required":["sandboxId","userId","items"],"properties":{"sandboxId":{"type":"string"},"userId":{"type":"string"},"couponCode":{"type":"string"},"items":{"type":"array","items":{"type":"object","required":["id","productId","quantity"],"properties":{"id":{"type":"string","example":"ci_123"},"productId":{"type":"string","example":"prod_sbx_demo_tee"},"quantity":{"type":"integer","minimum":1,"maximum":99,"example":2}}}}}},"items":{"type":"array","items":{"type":"object","required":["product","quantity","subtotal"],"properties":{"product":{"type":"object","required":["id","sandboxId","name","category","price","currency","stock","active","featured","description"],"properties":{"id":{"type":"string","example":"prod_sbx_demo_tee"},"sandboxId":{"type":"string","example":"sbx_demo"},"name":{"type":"string","example":"Áo thun TestMart"},"category":{"type":"string","example":"apparel"},"price":{"type":"integer","example":199000},"currency":{"type":"string","enum":["VND"]},"stock":{"type":"integer","example":12},"active":{"type":"boolean","example":true},"featured":{"type":"boolean","example":false},"description":{"type":"string"}}},"quantity":{"type":"integer"},"subtotal":{"type":"integer"}}}},"subtotal":{"type":"integer","example":398000},"discount":{"type":"integer","example":0},"total":{"type":"integer","example":398000}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/admin/carts":{"get":{"summary":"Danh sách cart trong sandbox (admin)","tags":["Cart"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"type":"object","required":["cart","items","subtotal","discount","total"],"properties":{"cart":{"type":"object","required":["sandboxId","userId","items"],"properties":{"sandboxId":{"type":"string"},"userId":{"type":"string"},"couponCode":{"type":"string"},"items":{"type":"array","items":{"type":"object","required":["id","productId","quantity"],"properties":{"id":{"type":"string","example":"ci_123"},"productId":{"type":"string","example":"prod_sbx_demo_tee"},"quantity":{"type":"integer","minimum":1,"maximum":99,"example":2}}}}}},"items":{"type":"array","items":{"type":"object","required":["product","quantity","subtotal"],"properties":{"product":{"type":"object","required":["id","sandboxId","name","category","price","currency","stock","active","featured","description"],"properties":{"id":{"type":"string","example":"prod_sbx_demo_tee"},"sandboxId":{"type":"string","example":"sbx_demo"},"name":{"type":"string","example":"Áo thun TestMart"},"category":{"type":"string","example":"apparel"},"price":{"type":"integer","example":199000},"currency":{"type":"string","enum":["VND"]},"stock":{"type":"integer","example":12},"active":{"type":"boolean","example":true},"featured":{"type":"boolean","example":false},"description":{"type":"string"}}},"quantity":{"type":"integer"},"subtotal":{"type":"integer"}}}},"subtotal":{"type":"integer","example":398000},"discount":{"type":"integer","example":0},"total":{"type":"integer","example":398000}}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/admin/carts/{userId}":{"get":{"summary":"Xem cart của user bất kỳ (admin)","tags":["Cart"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"userId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["cart","items","subtotal","discount","total"],"properties":{"cart":{"type":"object","required":["sandboxId","userId","items"],"properties":{"sandboxId":{"type":"string"},"userId":{"type":"string"},"couponCode":{"type":"string"},"items":{"type":"array","items":{"type":"object","required":["id","productId","quantity"],"properties":{"id":{"type":"string","example":"ci_123"},"productId":{"type":"string","example":"prod_sbx_demo_tee"},"quantity":{"type":"integer","minimum":1,"maximum":99,"example":2}}}}}},"items":{"type":"array","items":{"type":"object","required":["product","quantity","subtotal"],"properties":{"product":{"type":"object","required":["id","sandboxId","name","category","price","currency","stock","active","featured","description"],"properties":{"id":{"type":"string","example":"prod_sbx_demo_tee"},"sandboxId":{"type":"string","example":"sbx_demo"},"name":{"type":"string","example":"Áo thun TestMart"},"category":{"type":"string","example":"apparel"},"price":{"type":"integer","example":199000},"currency":{"type":"string","enum":["VND"]},"stock":{"type":"integer","example":12},"active":{"type":"boolean","example":true},"featured":{"type":"boolean","example":false},"description":{"type":"string"}}},"quantity":{"type":"integer"},"subtotal":{"type":"integer"}}}},"subtotal":{"type":"integer","example":398000},"discount":{"type":"integer","example":0},"total":{"type":"integer","example":398000}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/users/me/balance":{"get":{"summary":"Xem số dư của user hiện tại","tags":["Balances"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["id","sandboxId","userId","currency","available","locked","createdAt","updatedAt"],"properties":{"id":{"type":"string","example":"bal_123"},"sandboxId":{"type":"string"},"userId":{"type":"string"},"currency":{"type":"string","enum":["VND"]},"available":{"type":"integer","example":1000000},"locked":{"type":"integer","example":0},"deletedAt":{"type":["null","string"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/users/me/balance/transactions":{"get":{"summary":"Danh sách giao dịch số dư của user hiện tại","tags":["Balances"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","sandboxId","userId","type","amount","balanceAfter","createdBy","createdAt"],"properties":{"id":{"type":"string","example":"btx_123"},"sandboxId":{"type":"string"},"userId":{"type":"string"},"type":{"type":"string","enum":["TOPUP","PURCHASE","REFUND","ADJUSTMENT"]},"amount":{"type":"integer","example":50000},"balanceAfter":{"type":"integer","example":1050000},"orderId":{"type":"string"},"note":{"type":"string"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/admin/balances":{"get":{"summary":"Danh sách balance (admin)","tags":["Balances"],"responses":{"200":{"description":"Default Response"}}},"post":{"summary":"Tạo balance cho user (admin)","tags":["Balances"],"responses":{"200":{"description":"Default Response"}}}},"/admin/balances/{balanceId}":{"get":{"summary":"Xem chi tiết balance (admin)","tags":["Balances"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"balanceId","required":true}],"responses":{"200":{"description":"Default Response"}}},"patch":{"summary":"Điều chỉnh balance (admin)","tags":["Balances"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"balanceId","required":true}],"responses":{"200":{"description":"Default Response"}}},"delete":{"summary":"Xóa mềm balance (admin)","tags":["Balances"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"balanceId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/users/me/addresses":{"get":{"summary":"Danh sách địa chỉ giao hàng của user hiện tại","tags":["Addresses"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","sandboxId","userId","recipientName","phone","line1","city","country","isDefault","createdAt","updatedAt"],"properties":{"id":{"type":"string","example":"addr_123"},"sandboxId":{"type":"string"},"userId":{"type":"string"},"label":{"type":"string","example":"Home"},"recipientName":{"type":"string","example":"Nguyen Van A"},"phone":{"type":"string","example":"0901234567"},"line1":{"type":"string","example":"12 Nguyen Hue"},"line2":{"type":"string","example":"Floor 5"},"city":{"type":"string","example":"Ho Chi Minh"},"state":{"type":"string","example":"HCMC"},"postalCode":{"type":"string","example":"700000"},"country":{"type":"string","example":"VN"},"isDefault":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}},"post":{"summary":"Tạo địa chỉ giao hàng mới","tags":["Addresses"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["recipientName","phone","line1","city","country"],"properties":{"label":{"type":"string","example":"Home"},"recipientName":{"type":"string","example":"Nguyen Van A"},"phone":{"type":"string","example":"0901234567"},"line1":{"type":"string","example":"12 Nguyen Hue"},"line2":{"type":"string","example":"Floor 5"},"city":{"type":"string","example":"Ho Chi Minh"},"state":{"type":"string","example":"HCMC"},"postalCode":{"type":"string","example":"700000"},"country":{"type":"string","example":"VN"},"isDefault":{"type":"boolean","default":false}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["id","sandboxId","userId","recipientName","phone","line1","city","country","isDefault","createdAt","updatedAt"],"properties":{"id":{"type":"string","example":"addr_123"},"sandboxId":{"type":"string"},"userId":{"type":"string"},"label":{"type":"string","example":"Home"},"recipientName":{"type":"string","example":"Nguyen Van A"},"phone":{"type":"string","example":"0901234567"},"line1":{"type":"string","example":"12 Nguyen Hue"},"line2":{"type":"string","example":"Floor 5"},"city":{"type":"string","example":"Ho Chi Minh"},"state":{"type":"string","example":"HCMC"},"postalCode":{"type":"string","example":"700000"},"country":{"type":"string","example":"VN"},"isDefault":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/users/me/addresses/{addressId}":{"get":{"summary":"Xem chi tiết một địa chỉ của chính mình","tags":["Addresses"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"addressId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["id","sandboxId","userId","recipientName","phone","line1","city","country","isDefault","createdAt","updatedAt"],"properties":{"id":{"type":"string","example":"addr_123"},"sandboxId":{"type":"string"},"userId":{"type":"string"},"label":{"type":"string","example":"Home"},"recipientName":{"type":"string","example":"Nguyen Van A"},"phone":{"type":"string","example":"0901234567"},"line1":{"type":"string","example":"12 Nguyen Hue"},"line2":{"type":"string","example":"Floor 5"},"city":{"type":"string","example":"Ho Chi Minh"},"state":{"type":"string","example":"HCMC"},"postalCode":{"type":"string","example":"700000"},"country":{"type":"string","example":"VN"},"isDefault":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}},"patch":{"summary":"Cập nhật địa chỉ của chính mình","tags":["Addresses"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string"},"recipientName":{"type":"string","minLength":1},"phone":{"type":"string","minLength":6,"maxLength":20},"line1":{"type":"string","minLength":1},"line2":{"type":"string"},"city":{"type":"string","minLength":1},"state":{"type":"string"},"postalCode":{"type":"string"},"country":{"type":"string","minLength":2,"maxLength":2},"isDefault":{"type":"boolean"}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"addressId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["id","sandboxId","userId","recipientName","phone","line1","city","country","isDefault","createdAt","updatedAt"],"properties":{"id":{"type":"string","example":"addr_123"},"sandboxId":{"type":"string"},"userId":{"type":"string"},"label":{"type":"string","example":"Home"},"recipientName":{"type":"string","example":"Nguyen Van A"},"phone":{"type":"string","example":"0901234567"},"line1":{"type":"string","example":"12 Nguyen Hue"},"line2":{"type":"string","example":"Floor 5"},"city":{"type":"string","example":"Ho Chi Minh"},"state":{"type":"string","example":"HCMC"},"postalCode":{"type":"string","example":"700000"},"country":{"type":"string","example":"VN"},"isDefault":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}},"delete":{"summary":"Xóa địa chỉ của chính mình","tags":["Addresses"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"addressId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["deleted"],"properties":{"deleted":{"type":"boolean"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/users/me/addresses/{addressId}/default":{"post":{"summary":"Đặt địa chỉ làm mặc định","tags":["Addresses"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"addressId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["id","sandboxId","userId","recipientName","phone","line1","city","country","isDefault","createdAt","updatedAt"],"properties":{"id":{"type":"string","example":"addr_123"},"sandboxId":{"type":"string"},"userId":{"type":"string"},"label":{"type":"string","example":"Home"},"recipientName":{"type":"string","example":"Nguyen Van A"},"phone":{"type":"string","example":"0901234567"},"line1":{"type":"string","example":"12 Nguyen Hue"},"line2":{"type":"string","example":"Floor 5"},"city":{"type":"string","example":"Ho Chi Minh"},"state":{"type":"string","example":"HCMC"},"postalCode":{"type":"string","example":"700000"},"country":{"type":"string","example":"VN"},"isDefault":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/admin/addresses":{"get":{"summary":"Danh sách address (admin)","tags":["Addresses"],"responses":{"200":{"description":"Default Response"}}}},"/admin/users/{userId}/addresses":{"get":{"summary":"Danh sách address của user (admin)","tags":["Addresses"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"userId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/users/me/wishlist":{"get":{"summary":"Danh sách sản phẩm yêu thích của user hiện tại","tags":["Wishlist"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","pagination","meta"],"properties":{"data":{"type":"array","items":{"type":"object","required":["wishlistItem","product"],"properties":{"wishlistItem":{"type":"object","required":["id","sandboxId","userId","productId","createdAt"],"properties":{"id":{"type":"string","example":"wl_123"},"sandboxId":{"type":"string"},"userId":{"type":"string"},"productId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"product":{"type":"object","required":["id","sandboxId","name","category","price","currency","stock","active","featured","description"],"properties":{"id":{"type":"string","example":"prod_sbx_demo_tee"},"sandboxId":{"type":"string","example":"sbx_demo"},"name":{"type":"string","example":"Áo thun TestMart"},"category":{"type":"string","example":"apparel"},"price":{"type":"integer","example":199000},"currency":{"type":"string","enum":["VND"]},"stock":{"type":"integer","example":12},"active":{"type":"boolean","example":true},"featured":{"type":"boolean","example":false},"description":{"type":"string"}}}}}},"pagination":{"type":"object","required":["page","limit","totalItems","totalPages"],"properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"totalItems":{"type":"integer"},"totalPages":{"type":"integer"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}},"post":{"summary":"Thêm sản phẩm vào wishlist","tags":["Wishlist"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["productId"],"properties":{"productId":{"type":"string","minLength":1,"maxLength":64}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["id","sandboxId","userId","productId","createdAt"],"properties":{"id":{"type":"string","example":"wl_123"},"sandboxId":{"type":"string"},"userId":{"type":"string"},"productId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/users/me/wishlist/{productId}":{"delete":{"summary":"Xóa sản phẩm khỏi wishlist","tags":["Wishlist"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"productId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["deleted"],"properties":{"deleted":{"type":"boolean"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/admin/users/{userId}/wishlist":{"get":{"summary":"Xem wishlist của một user (admin)","tags":["Wishlist"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"userId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","sandboxId","userId","productId","createdAt"],"properties":{"id":{"type":"string","example":"wl_123"},"sandboxId":{"type":"string"},"userId":{"type":"string"},"productId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/products":{"get":{"summary":"Danh sách sản phẩm có pagination, filtering, sorting và search","tags":["Products"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false},{"schema":{"type":"string","minLength":1,"maxLength":50,"example":"apparel"},"in":"query","name":"category","required":false},{"schema":{"type":"string","minLength":1,"maxLength":100,"example":"cà phê"},"in":"query","name":"search","required":false},{"schema":{"type":"string","enum":["name","price","-price","created"]},"in":"query","name":"sort","required":false},{"schema":{"type":"string"},"in":"header","name":"cookie","required":false,"description":"Auto-set testmart_sbx cookie. Usually managed by the client."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","pagination","meta"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","sandboxId","name","category","price","currency","stock","active","featured","description"],"properties":{"id":{"type":"string","example":"prod_sbx_demo_tee"},"sandboxId":{"type":"string","example":"sbx_demo"},"name":{"type":"string","example":"Áo thun TestMart"},"category":{"type":"string","example":"apparel"},"price":{"type":"integer","example":199000},"currency":{"type":"string","enum":["VND"]},"stock":{"type":"integer","example":12},"active":{"type":"boolean","example":true},"featured":{"type":"boolean","example":false},"description":{"type":"string"}}}},"pagination":{"type":"object","required":["page","limit","totalItems","totalPages"],"properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"totalItems":{"type":"integer"},"totalPages":{"type":"integer"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/products/featured":{"get":{"summary":"Danh sách sản phẩm featured (public)","tags":["Products"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","pagination","meta"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","sandboxId","name","category","price","currency","stock","active","featured","description"],"properties":{"id":{"type":"string","example":"prod_sbx_demo_tee"},"sandboxId":{"type":"string","example":"sbx_demo"},"name":{"type":"string","example":"Áo thun TestMart"},"category":{"type":"string","example":"apparel"},"price":{"type":"integer","example":199000},"currency":{"type":"string","enum":["VND"]},"stock":{"type":"integer","example":12},"active":{"type":"boolean","example":true},"featured":{"type":"boolean","example":false},"description":{"type":"string"}}}},"pagination":{"type":"object","required":["page","limit","totalItems","totalPages"],"properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"totalItems":{"type":"integer"},"totalPages":{"type":"integer"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/products/{productId}/availability":{"get":{"summary":"Kiểm tra tồn kho của sản phẩm (public)","tags":["Products"],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":99,"default":1},"in":"query","name":"quantity","required":false},{"schema":{"type":"string"},"in":"path","name":"productId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["productId","available","stock","requested","active"],"properties":{"productId":{"type":"string"},"available":{"type":"boolean","example":true},"stock":{"type":"integer","example":12},"requested":{"type":"integer","example":1},"active":{"type":"boolean","example":true}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/products/{productId}":{"get":{"summary":"Xem chi tiết sản phẩm","tags":["Products"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"productId","required":true},{"schema":{"type":"string"},"in":"header","name":"cookie","required":false,"description":"Auto-set testmart_sbx cookie. Usually managed by the client."}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["id","sandboxId","name","category","price","currency","stock","active","featured","description"],"properties":{"id":{"type":"string","example":"prod_sbx_demo_tee"},"sandboxId":{"type":"string","example":"sbx_demo"},"name":{"type":"string","example":"Áo thun TestMart"},"category":{"type":"string","example":"apparel"},"price":{"type":"integer","example":199000},"currency":{"type":"string","enum":["VND"]},"stock":{"type":"integer","example":12},"active":{"type":"boolean","example":true},"featured":{"type":"boolean","example":false},"description":{"type":"string"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/admin/products":{"get":{"summary":"Danh sách sản phẩm (admin)","tags":["Products"],"responses":{"200":{"description":"Default Response"}}},"post":{"summary":"Tạo sản phẩm mới (admin)","tags":["Products"],"responses":{"200":{"description":"Default Response"}}}},"/admin/products/{productId}":{"get":{"summary":"Xem chi tiết sản phẩm (admin)","tags":["Products"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"productId","required":true}],"responses":{"200":{"description":"Default Response"}}},"patch":{"summary":"Cập nhật sản phẩm (admin)","tags":["Products"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"productId","required":true}],"responses":{"200":{"description":"Default Response"}}},"delete":{"summary":"Xóa mềm sản phẩm (admin)","tags":["Products"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"productId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/products/{productId}/restock":{"post":{"summary":"Bổ sung tồn kho cho sản phẩm (admin)","tags":["Products"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["delta"],"properties":{"delta":{"type":"integer","minimum":1,"example":10}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"productId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["id","sandboxId","name","category","price","currency","stock","active","featured","description"],"properties":{"id":{"type":"string","example":"prod_sbx_demo_tee"},"sandboxId":{"type":"string","example":"sbx_demo"},"name":{"type":"string","example":"Áo thun TestMart"},"category":{"type":"string","example":"apparel"},"price":{"type":"integer","example":199000},"currency":{"type":"string","enum":["VND"]},"stock":{"type":"integer","example":12},"active":{"type":"boolean","example":true},"featured":{"type":"boolean","example":false},"description":{"type":"string"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/categories":{"get":{"summary":"Danh sách category (public)","tags":["Categories"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"query","name":"search","required":false},{"schema":{"type":["string","null"]},"in":"query","name":"parentId","required":false}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","pagination","meta"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","sandboxId","slug","name","active","createdAt","updatedAt"],"properties":{"id":{"type":"string","example":"cat_sbx_demo_apparel"},"sandboxId":{"type":"string","example":"sbx_demo"},"slug":{"type":"string","example":"apparel"},"name":{"type":"string","example":"Apparel"},"description":{"type":"string","example":"Quần áo và phụ kiện thời trang"},"parentId":{"type":["null","string"],"example":null},"active":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}},"pagination":{"type":"object","required":["page","limit","totalItems","totalPages"],"properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"totalItems":{"type":"integer"},"totalPages":{"type":"integer"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/categories/{categoryId}":{"get":{"summary":"Xem chi tiết category (public)","tags":["Categories"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"categoryId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["id","sandboxId","slug","name","active","createdAt","updatedAt"],"properties":{"id":{"type":"string","example":"cat_sbx_demo_apparel"},"sandboxId":{"type":"string","example":"sbx_demo"},"slug":{"type":"string","example":"apparel"},"name":{"type":"string","example":"Apparel"},"description":{"type":"string","example":"Quần áo và phụ kiện thời trang"},"parentId":{"type":["null","string"],"example":null},"active":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/categories/{categoryId}/products":{"get":{"summary":"Danh sách sản phẩm trong category (public)","tags":["Categories"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"path","name":"categoryId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","pagination","meta"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","sandboxId","name","category","price","currency","stock","active","featured","description"],"properties":{"id":{"type":"string","example":"prod_sbx_demo_tee"},"sandboxId":{"type":"string","example":"sbx_demo"},"name":{"type":"string","example":"Áo thun TestMart"},"category":{"type":"string","example":"apparel"},"price":{"type":"integer","example":199000},"currency":{"type":"string","enum":["VND"]},"stock":{"type":"integer","example":12},"active":{"type":"boolean","example":true},"featured":{"type":"boolean","example":false},"description":{"type":"string"}}}},"pagination":{"type":"object","required":["page","limit","totalItems","totalPages"],"properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"totalItems":{"type":"integer"},"totalPages":{"type":"integer"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/admin/categories":{"get":{"summary":"Danh sách category (admin)","tags":["Categories"],"responses":{"200":{"description":"Default Response"}}},"post":{"summary":"Tạo category mới (admin)","tags":["Categories"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["slug","name"],"properties":{"slug":{"type":"string","minLength":1,"example":"apparel"},"name":{"type":"string","minLength":1,"example":"Apparel"},"description":{"type":"string"},"parentId":{"type":["string","null"]},"active":{"type":"boolean","default":true}}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["id","sandboxId","slug","name","active","createdAt","updatedAt"],"properties":{"id":{"type":"string","example":"cat_sbx_demo_apparel"},"sandboxId":{"type":"string","example":"sbx_demo"},"slug":{"type":"string","example":"apparel"},"name":{"type":"string","example":"Apparel"},"description":{"type":"string","example":"Quần áo và phụ kiện thời trang"},"parentId":{"type":["null","string"],"example":null},"active":{"type":"boolean","example":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/admin/categories/{categoryId}":{"get":{"summary":"Xem chi tiết category (admin)","tags":["Categories"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"categoryId","required":true}],"responses":{"200":{"description":"Default Response"}}},"patch":{"summary":"Cập nhật category (admin)","tags":["Categories"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"categoryId","required":true}],"responses":{"200":{"description":"Default Response"}}},"delete":{"summary":"Xóa mềm category (admin)","tags":["Categories"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"categoryId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/products/{productId}/reviews":{"get":{"summary":"Danh sách review cho sản phẩm (public)","tags":["Reviews"],"parameters":[{"schema":{"type":"integer","minimum":1,"default":1},"in":"query","name":"page","required":false},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"in":"query","name":"limit","required":false},{"schema":{"type":"string"},"in":"path","name":"productId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","pagination","meta"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","sandboxId","productId","userId","rating","status","createdAt","updatedAt"],"properties":{"id":{"type":"string","example":"rev_123"},"sandboxId":{"type":"string"},"productId":{"type":"string","example":"prod_sbx_demo_tee"},"userId":{"type":"string"},"rating":{"type":"integer","minimum":1,"maximum":5,"example":5},"title":{"type":"string","example":"Great product"},"comment":{"type":"string","example":"Fits perfectly and arrived quickly."},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED"],"example":"APPROVED"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}},"pagination":{"type":"object","required":["page","limit","totalItems","totalPages"],"properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"totalItems":{"type":"integer"},"totalPages":{"type":"integer"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}},"post":{"summary":"Tạo review cho sản phẩm (user đã đăng nhập)","tags":["Reviews"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["rating"],"properties":{"rating":{"type":"integer","minimum":1,"maximum":5,"example":5},"title":{"type":"string","example":"Great product"},"comment":{"type":"string","example":"Fits perfectly and arrived quickly."}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"productId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["id","sandboxId","productId","userId","rating","status","createdAt","updatedAt"],"properties":{"id":{"type":"string","example":"rev_123"},"sandboxId":{"type":"string"},"productId":{"type":"string","example":"prod_sbx_demo_tee"},"userId":{"type":"string"},"rating":{"type":"integer","minimum":1,"maximum":5,"example":5},"title":{"type":"string","example":"Great product"},"comment":{"type":"string","example":"Fits perfectly and arrived quickly."},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED"],"example":"APPROVED"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/products/{productId}/reviews/{reviewId}":{"patch":{"summary":"Cập nhật review của chính mình","tags":["Reviews"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"rating":{"type":"integer","minimum":1,"maximum":5},"title":{"type":"string"},"comment":{"type":"string"}}}}}},"parameters":[{"schema":{"type":"string"},"in":"path","name":"productId","required":true},{"schema":{"type":"string"},"in":"path","name":"reviewId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["id","sandboxId","productId","userId","rating","status","createdAt","updatedAt"],"properties":{"id":{"type":"string","example":"rev_123"},"sandboxId":{"type":"string"},"productId":{"type":"string","example":"prod_sbx_demo_tee"},"userId":{"type":"string"},"rating":{"type":"integer","minimum":1,"maximum":5,"example":5},"title":{"type":"string","example":"Great product"},"comment":{"type":"string","example":"Fits perfectly and arrived quickly."},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED"],"example":"APPROVED"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}},"delete":{"summary":"Xóa review của chính mình","tags":["Reviews"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"productId","required":true},{"schema":{"type":"string"},"in":"path","name":"reviewId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["deleted"],"properties":{"deleted":{"type":"boolean"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/users/me/reviews":{"get":{"summary":"Danh sách review của user hiện tại","tags":["Reviews"],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","sandboxId","productId","userId","rating","status","createdAt","updatedAt"],"properties":{"id":{"type":"string","example":"rev_123"},"sandboxId":{"type":"string"},"productId":{"type":"string","example":"prod_sbx_demo_tee"},"userId":{"type":"string"},"rating":{"type":"integer","minimum":1,"maximum":5,"example":5},"title":{"type":"string","example":"Great product"},"comment":{"type":"string","example":"Fits perfectly and arrived quickly."},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED"],"example":"APPROVED"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/admin/reviews":{"get":{"summary":"Tất cả review trong sandbox (admin)","tags":["Reviews"],"parameters":[{"schema":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"in":"query","name":"status","required":false},{"schema":{"type":"string"},"in":"query","name":"productId","required":false}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","sandboxId","productId","userId","rating","status","createdAt","updatedAt"],"properties":{"id":{"type":"string","example":"rev_123"},"sandboxId":{"type":"string"},"productId":{"type":"string","example":"prod_sbx_demo_tee"},"userId":{"type":"string"},"rating":{"type":"integer","minimum":1,"maximum":5,"example":5},"title":{"type":"string","example":"Great product"},"comment":{"type":"string","example":"Fits perfectly and arrived quickly."},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED"],"example":"APPROVED"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/admin/reviews/{reviewId}":{"get":{"summary":"Xem chi tiết review (admin)","tags":["Reviews"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"reviewId","required":true}],"responses":{"200":{"description":"Default Response"}}},"patch":{"summary":"Duyệt hoặc từ chối review (admin)","tags":["Reviews"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"reviewId","required":true}],"responses":{"200":{"description":"Default Response"}}},"delete":{"summary":"Xóa mềm review (admin)","tags":["Reviews"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"reviewId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/cart":{"get":{"summary":"Xem cart hiện tại","tags":["Cart"],"parameters":[{"schema":{"type":"string","example":"Bearer <accessToken>"},"in":"header","name":"authorization","required":false},{"schema":{"type":"string"},"in":"header","name":"cookie","required":false,"description":"Auto-set testmart_sbx cookie"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["cart","items","subtotal","discount","total"],"properties":{"cart":{"type":"object","required":["sandboxId","userId","items"],"properties":{"sandboxId":{"type":"string"},"userId":{"type":"string"},"couponCode":{"type":"string"},"items":{"type":"array","items":{"type":"object","required":["id","productId","quantity"],"properties":{"id":{"type":"string","example":"ci_123"},"productId":{"type":"string","example":"prod_sbx_demo_tee"},"quantity":{"type":"integer","minimum":1,"maximum":99,"example":2}}}}}},"items":{"type":"array","items":{"type":"object","required":["product","quantity","subtotal"],"properties":{"product":{"type":"object","required":["id","sandboxId","name","category","price","currency","stock","active","featured","description"],"properties":{"id":{"type":"string","example":"prod_sbx_demo_tee"},"sandboxId":{"type":"string","example":"sbx_demo"},"name":{"type":"string","example":"Áo thun TestMart"},"category":{"type":"string","example":"apparel"},"price":{"type":"integer","example":199000},"currency":{"type":"string","enum":["VND"]},"stock":{"type":"integer","example":12},"active":{"type":"boolean","example":true},"featured":{"type":"boolean","example":false},"description":{"type":"string"}}},"quantity":{"type":"integer"},"subtotal":{"type":"integer"}}}},"subtotal":{"type":"integer","example":398000},"discount":{"type":"integer","example":0},"total":{"type":"integer","example":398000}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}},"delete":{"summary":"Xóa toàn bộ cart hiện tại","tags":["Cart"],"responses":{"200":{"description":"Default Response"}}}},"/cart/items":{"post":{"summary":"Thêm sản phẩm vào cart","tags":["Cart"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["productId","quantity"],"properties":{"productId":{"type":"string"},"quantity":{"type":"integer","minimum":1,"maximum":99,"example":2}}}}}},"parameters":[{"schema":{"type":"string","example":"Bearer <accessToken>"},"in":"header","name":"authorization","required":false},{"schema":{"type":"string"},"in":"header","name":"cookie","required":false,"description":"Auto-set testmart_sbx cookie"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["cart","items","subtotal","discount","total"],"properties":{"cart":{"type":"object","required":["sandboxId","userId","items"],"properties":{"sandboxId":{"type":"string"},"userId":{"type":"string"},"couponCode":{"type":"string"},"items":{"type":"array","items":{"type":"object","required":["id","productId","quantity"],"properties":{"id":{"type":"string","example":"ci_123"},"productId":{"type":"string","example":"prod_sbx_demo_tee"},"quantity":{"type":"integer","minimum":1,"maximum":99,"example":2}}}}}},"items":{"type":"array","items":{"type":"object","required":["product","quantity","subtotal"],"properties":{"product":{"type":"object","required":["id","sandboxId","name","category","price","currency","stock","active","featured","description"],"properties":{"id":{"type":"string","example":"prod_sbx_demo_tee"},"sandboxId":{"type":"string","example":"sbx_demo"},"name":{"type":"string","example":"Áo thun TestMart"},"category":{"type":"string","example":"apparel"},"price":{"type":"integer","example":199000},"currency":{"type":"string","enum":["VND"]},"stock":{"type":"integer","example":12},"active":{"type":"boolean","example":true},"featured":{"type":"boolean","example":false},"description":{"type":"string"}}},"quantity":{"type":"integer"},"subtotal":{"type":"integer"}}}},"subtotal":{"type":"integer","example":398000},"discount":{"type":"integer","example":0},"total":{"type":"integer","example":398000}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/cart/items/{itemId}":{"patch":{"summary":"Cập nhật số lượng cart item","tags":["Cart"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"itemId","required":true}],"responses":{"200":{"description":"Default Response"}}},"delete":{"summary":"Xóa item khỏi cart","tags":["Cart"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"itemId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/coupons/{code}":{"get":{"summary":"Tra cứu coupon public","tags":["Coupons"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"code","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/coupons":{"get":{"summary":"Danh sách coupon (admin)","tags":["Coupons"],"responses":{"200":{"description":"Default Response"}}},"post":{"summary":"Tạo coupon mới (admin)","tags":["Coupons"],"responses":{"200":{"description":"Default Response"}}}},"/admin/coupons/{code}":{"get":{"summary":"Xem chi tiết coupon (admin)","tags":["Coupons"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"code","required":true}],"responses":{"200":{"description":"Default Response"}}},"patch":{"summary":"Cập nhật coupon (admin)","tags":["Coupons"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"code","required":true}],"responses":{"200":{"description":"Default Response"}}},"delete":{"summary":"Xóa mềm coupon (admin)","tags":["Coupons"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"code","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/coupons/{code}/redemptions":{"get":{"summary":"Danh sách user đã dùng coupon (admin)","tags":["Coupons"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"code","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"type":"object","required":["userId","code"],"properties":{"userId":{"type":"string"},"code":{"type":"string"}}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/cart/coupons":{"post":{"summary":"Áp dụng coupon vào cart","tags":["Coupons"],"responses":{"200":{"description":"Default Response"}}}},"/cart/coupons/{code}":{"delete":{"summary":"Gỡ coupon khỏi cart","tags":["Coupons"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"code","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/orders":{"post":{"summary":"Tạo order từ cart hiện tại","tags":["Orders"],"parameters":[{"schema":{"type":"string","example":"Bearer <accessToken>"},"in":"header","name":"authorization","required":false},{"schema":{"type":"string"},"in":"header","name":"cookie","required":false,"description":"Auto-set testmart_sbx cookie"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["id","sandboxId","userId","status","items","subtotal","discount","total","currency","createdAt"],"properties":{"id":{"type":"string","example":"ord_123"},"sandboxId":{"type":"string"},"userId":{"type":"string"},"status":{"type":"string","enum":["CREATED","PAYMENT_PENDING","PAID","PACKED","SHIPPED","CANCELLED","REFUNDED","FAILED"]},"items":{"type":"array","items":{"type":"object","required":["productId","name","quantity","unitPrice","subtotal"],"properties":{"productId":{"type":"string"},"name":{"type":"string"},"quantity":{"type":"integer"},"unitPrice":{"type":"integer"},"subtotal":{"type":"integer"}}}},"subtotal":{"type":"integer"},"discount":{"type":"integer"},"total":{"type":"integer"},"currency":{"type":"string","enum":["VND"]},"couponCode":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}},"get":{"summary":"Danh sách order của user hiện tại","tags":["Orders"],"responses":{"200":{"description":"Default Response"}}}},"/orders/{orderId}":{"get":{"summary":"Xem chi tiết order","tags":["Orders"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"orderId","required":true},{"schema":{"type":"string","example":"Bearer <accessToken>"},"in":"header","name":"authorization","required":false},{"schema":{"type":"string"},"in":"header","name":"cookie","required":false,"description":"Auto-set testmart_sbx cookie"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["id","sandboxId","userId","status","items","subtotal","discount","total","currency","createdAt"],"properties":{"id":{"type":"string","example":"ord_123"},"sandboxId":{"type":"string"},"userId":{"type":"string"},"status":{"type":"string","enum":["CREATED","PAYMENT_PENDING","PAID","PACKED","SHIPPED","CANCELLED","REFUNDED","FAILED"]},"items":{"type":"array","items":{"type":"object","required":["productId","name","quantity","unitPrice","subtotal"],"properties":{"productId":{"type":"string"},"name":{"type":"string"},"quantity":{"type":"integer"},"unitPrice":{"type":"integer"},"subtotal":{"type":"integer"}}}},"subtotal":{"type":"integer"},"discount":{"type":"integer"},"total":{"type":"integer"},"currency":{"type":"string","enum":["VND"]},"couponCode":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/orders/{orderId}/payments":{"get":{"summary":"Danh sách payment của order","tags":["Payments"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"orderId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","sandboxId","orderId","userId","amount","currency","status","createdAt"],"properties":{"id":{"type":"string","example":"pay_123"},"sandboxId":{"type":"string"},"orderId":{"type":"string"},"userId":{"type":"string"},"amount":{"type":"integer","example":398000},"currency":{"type":"string","enum":["VND"]},"status":{"type":"string","enum":["PENDING","AUTHORIZED","CAPTURED","FAILED","REFUNDED","DUPLICATE"]},"idempotencyKey":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/orders/{orderId}/cancel":{"post":{"summary":"Hủy order của user hiện tại","tags":["Orders"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"orderId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/orders":{"get":{"summary":"Danh sách order (admin)","tags":["Orders"],"responses":{"200":{"description":"Default Response"}}},"post":{"summary":"Tạo order mới (admin)","tags":["Orders"],"responses":{"200":{"description":"Default Response"}}}},"/admin/orders/{orderId}":{"get":{"summary":"Xem chi tiết order (admin)","tags":["Orders"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"orderId","required":true}],"responses":{"200":{"description":"Default Response"}}},"patch":{"summary":"Cập nhật trạng thái order (admin)","tags":["Orders"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"orderId","required":true}],"responses":{"200":{"description":"Default Response"}}},"delete":{"summary":"Xóa mềm order (admin)","tags":["Orders"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"orderId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/payments":{"post":{"summary":"Tạo payment cho order","tags":["Payments"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["orderId"],"properties":{"orderId":{"type":"string"},"method":{"type":"string","enum":["CARD","BALANCE"],"default":"CARD"},"idempotencyKey":{"type":"string","example":"payment-001"}}}}}},"parameters":[{"schema":{"type":"string","example":"Bearer <accessToken>"},"in":"header","name":"authorization","required":false},{"schema":{"type":"string"},"in":"header","name":"cookie","required":false,"description":"Auto-set testmart_sbx cookie"},{"schema":{"type":"string","example":"payment-001"},"in":"header","name":"idempotency-key","required":false}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["id","sandboxId","orderId","userId","amount","currency","status","createdAt"],"properties":{"id":{"type":"string","example":"pay_123"},"sandboxId":{"type":"string"},"orderId":{"type":"string"},"userId":{"type":"string"},"amount":{"type":"integer","example":398000},"currency":{"type":"string","enum":["VND"]},"status":{"type":"string","enum":["PENDING","AUTHORIZED","CAPTURED","FAILED","REFUNDED","DUPLICATE"]},"idempotencyKey":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}},"get":{"summary":"Danh sách payment của user hiện tại","tags":["Payments"],"responses":{"200":{"description":"Default Response"}}}},"/payments/{paymentId}":{"get":{"summary":"Xem chi tiết payment","tags":["Payments"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"paymentId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/payments/{paymentId}/capture":{"post":{"summary":"Capture payment","tags":["Payments"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"paymentId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/payments/{paymentId}/refund":{"post":{"summary":"Refund payment","tags":["Payments"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"paymentId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/admin/payments":{"get":{"summary":"Danh sách payment (admin)","tags":["Payments"],"responses":{"200":{"description":"Default Response"}}},"post":{"summary":"Tạo payment mới (admin)","tags":["Payments"],"responses":{"200":{"description":"Default Response"}}}},"/admin/payments/{paymentId}":{"get":{"summary":"Xem chi tiết payment (admin)","tags":["Payments"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"paymentId","required":true}],"responses":{"200":{"description":"Default Response"}}},"patch":{"summary":"Cập nhật trạng thái payment (admin)","tags":["Payments"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"paymentId","required":true}],"responses":{"200":{"description":"Default Response"}}},"delete":{"summary":"Xóa mềm payment (admin)","tags":["Payments"],"parameters":[{"schema":{"type":"string"},"in":"path","name":"paymentId","required":true}],"responses":{"200":{"description":"Default Response"}}}},"/webhooks/payment-provider":{"post":{"summary":"Nhận webhook từ payment provider","tags":["Webhooks"],"responses":{"200":{"description":"Default Response"}}}},"/synthetic/catalog":{"get":{"summary":"Probe catalog public","tags":["Synthetic"],"responses":{"200":{"description":"Default Response"}}}},"/synthetic/checkout":{"get":{"summary":"Probe checkout không ghi dữ liệu","tags":["Synthetic"],"responses":{"200":{"description":"Default Response"}}}},"/admin/stats/overview":{"get":{"summary":"Tổng quan request, user và sandbox theo khoảng thời gian","tags":["Analytics"],"parameters":[{"schema":{"type":"string","format":"date-time"},"in":"query","name":"from","required":false},{"schema":{"type":"string","format":"date-time"},"in":"query","name":"to","required":false},{"schema":{"type":"string","enum":["hour","day"],"default":"hour"},"in":"query","name":"grain","required":false},{"schema":{"type":"string"},"in":"query","name":"sandboxId","required":false}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["from","to","grain","totalRequests","errors","errorRate","avgDurationMs","maxDurationMs","activeUsers","activeSandboxes","authenticatedRequests","anonymousRequests","registeredUserRequests","seedUserRequests","newUsers","totalUsers"],"properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"},"grain":{"type":"string","enum":["hour","day"]},"sandboxId":{"type":"string"},"totalRequests":{"type":"integer","example":500},"errors":{"type":"integer","example":8},"errorRate":{"type":"number","example":0.016},"avgDurationMs":{"type":"number","example":38.4},"maxDurationMs":{"type":"integer","example":260},"activeUsers":{"type":"integer","example":25},"activeSandboxes":{"type":"integer","example":13},"authenticatedRequests":{"type":"integer","example":320},"anonymousRequests":{"type":"integer","example":180},"registeredUserRequests":{"type":"integer","example":270},"seedUserRequests":{"type":"integer","example":50},"newUsers":{"type":"integer","example":4},"totalUsers":{"type":"integer","example":72}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/admin/stats/requests":{"get":{"summary":"Chuỗi thời gian request, lỗi, duration và active users","tags":["Analytics"],"parameters":[{"schema":{"type":"string","format":"date-time"},"in":"query","name":"from","required":false},{"schema":{"type":"string","format":"date-time"},"in":"query","name":"to","required":false},{"schema":{"type":"string","enum":["hour","day"],"default":"hour"},"in":"query","name":"grain","required":false},{"schema":{"type":"string"},"in":"query","name":"sandboxId","required":false},{"schema":{"type":"integer","minimum":1,"maximum":50,"default":10},"in":"query","name":"limit","required":false}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["series","topRoutes","statusCodes"],"properties":{"series":{"type":"array","items":{"type":"object","required":["bucketStart","requests","errors","errorRate","avgDurationMs","maxDurationMs","activeUsers","activeSandboxes","authenticatedRequests","anonymousRequests","registeredUserRequests","seedUserRequests"],"properties":{"bucketStart":{"type":"string","format":"date-time"},"requests":{"type":"integer","example":128},"errors":{"type":"integer","example":3},"errorRate":{"type":"number","example":0.0234},"avgDurationMs":{"type":"number","example":42.5},"maxDurationMs":{"type":"integer","example":201},"activeUsers":{"type":"integer","example":14},"activeSandboxes":{"type":"integer","example":9},"authenticatedRequests":{"type":"integer","example":80},"anonymousRequests":{"type":"integer","example":48},"registeredUserRequests":{"type":"integer","example":64},"seedUserRequests":{"type":"integer","example":16}}}},"topRoutes":{"type":"array","items":{"type":"object","required":["route","method","requests","errors","avgDurationMs"],"properties":{"route":{"type":"string","example":"/products"},"method":{"type":"string","example":"GET"},"requests":{"type":"integer","example":320},"errors":{"type":"integer","example":2},"avgDurationMs":{"type":"number","example":35.2}}}},"statusCodes":{"type":"array","items":{"type":"object","required":["statusCode","requests"],"properties":{"statusCode":{"type":"integer","example":200},"requests":{"type":"integer","example":420}}}}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}},"/admin/stats/users":{"get":{"summary":"Chuỗi thời gian user mới và active users","tags":["Analytics"],"parameters":[{"schema":{"type":"string","format":"date-time"},"in":"query","name":"from","required":false},{"schema":{"type":"string","format":"date-time"},"in":"query","name":"to","required":false},{"schema":{"type":"string","enum":["hour","day"],"default":"hour"},"in":"query","name":"grain","required":false},{"schema":{"type":"string"},"in":"query","name":"sandboxId","required":false}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"object","required":["newUsers","activeUsers"],"properties":{"newUsers":{"type":"array","items":{"type":"object","required":["bucketStart","newUsers"],"properties":{"bucketStart":{"type":"string","format":"date-time"},"newUsers":{"type":"integer","example":7}}}},"activeUsers":{"type":"array","items":{"type":"object","required":["bucketStart","requests","errors","errorRate","avgDurationMs","maxDurationMs","activeUsers","activeSandboxes","authenticatedRequests","anonymousRequests","registeredUserRequests","seedUserRequests"],"properties":{"bucketStart":{"type":"string","format":"date-time"},"requests":{"type":"integer","example":128},"errors":{"type":"integer","example":3},"errorRate":{"type":"number","example":0.0234},"avgDurationMs":{"type":"number","example":42.5},"maxDurationMs":{"type":"integer","example":201},"activeUsers":{"type":"integer","example":14},"activeSandboxes":{"type":"integer","example":9},"authenticatedRequests":{"type":"integer","example":80},"anonymousRequests":{"type":"integer","example":48},"registeredUserRequests":{"type":"integer","example":64},"seedUserRequests":{"type":"integer","example":16}}}}}},"meta":{"type":"object","required":["requestId"],"properties":{"requestId":{"type":"string"}}}}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"409":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}},"415":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Request payload is invalid"},"details":{"type":"array","items":{"type":"object","additionalProperties":true}},"requestId":{"type":"string","example":"req_123"}}}}}}}}}}}},"tags":[{"name":"System","description":"Health checks and service readiness."},{"name":"Sandbox","description":"Sandbox lifecycle and intentional bug flags."},{"name":"Auth","description":"Registration, login, token refresh, and logout."},{"name":"Users","description":"Current user profile and admin user management."},{"name":"Addresses","description":"Shipping address book management."},{"name":"Balances","description":"User balance and balance transaction APIs."},{"name":"Categories","description":"Product category catalog and admin category management."},{"name":"Products","description":"Product catalog and admin product management."},{"name":"Reviews","description":"Product review submission and moderation."},{"name":"Cart","description":"Cart item management."},{"name":"Coupons","description":"Coupon lookup, application, and admin coupon management."},{"name":"Orders","description":"Order checkout and admin order management."},{"name":"Payments","description":"Payment creation, lookup, capture, refund, and admin payment management."},{"name":"Webhooks","description":"Inbound provider callbacks."},{"name":"Wishlist","description":"User wishlist (favorites) management."},{"name":"Cron","description":"Scheduled jobs triggered by Vercel Cron."},{"name":"Analytics","description":"Operational usage statistics for requests, users, and sandboxes."},{"name":"Synthetic","description":"Synthetic monitoring probes."}]}