{"openapi":"3.0.3","info":{"title":"T5Edu SQL Lab Playground API","version":"1.1.0","description":"REST API thực hành trên PostgreSQL SQL Lab dùng chung. CRUD body được sinh từ Prisma SQL Lab schema; action nghiệp vụ có contract riêng. Dữ liệu được làm mới hằng ngày."},"servers":[{"url":"/"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Danh tính","description":"Quản lý user, profile và portfolio như super admin."},{"name":"Học tập","description":"Quản lý khóa học, bài học, đăng ký và kết quả học tập."},{"name":"Thương mại","description":"Quản lý đơn hàng, thanh toán, ví và Spend XP."},{"name":"Nội dung","description":"Quản lý blog, tag, bình luận và lượt xem."},{"name":"Báo cáo","description":"Các read model tổng hợp theo nghiệp vụ."},{"name":"Hệ thống","description":"Action nghiệp vụ và thông tin vận hành SQL Lab."}],"paths":{"/playground/api/v1/users":{"get":{"operationId":"list_users","tags":["Danh tính"],"summary":"Danh sách Tài khoản người dùng demo","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'users'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Tìm gần đúng trong: name, email.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","name","email","role","wallet_balance","real_balance","bonus_balance","spend_xp","created_at","updated_at"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"email","in":"query","description":"Lọc chính xác theo cột 'email'.","schema":{"type":"string"}},{"name":"role","in":"query","description":"Lọc chính xác theo cột 'role'.","schema":{"type":"string","enum":["STUDENT","ADMIN"]}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"post":{"operationId":"create_users","tags":["Danh tính"],"summary":"Tạo Tài khoản người dùng demo","description":"Body chỉ nhận các trường được phép trong schema bên dưới; id và trường hệ thống được server tạo.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserInput"}}}},"responses":{"200":{"description":"Thành công"},"201":{"description":"Đã tạo dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/users/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Tài khoản người dùng demo.","schema":{"type":"string"}}],"get":{"operationId":"get_users","tags":["Danh tính"],"summary":"Chi tiết Tài khoản người dùng demo","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"patch":{"operationId":"update_users","tags":["Danh tính"],"summary":"Cập nhật Tài khoản người dùng demo","description":"PATCH chỉ cần gửi những trường muốn thay đổi. Khóa ngoại bất biến và trường nghiệp vụ không xuất hiện trong body.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserInput"}}}},"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"delete":{"operationId":"delete_users","tags":["Danh tính"],"summary":"Xóa Tài khoản người dùng demo","responses":{"200":{"description":"Thành công"},"204":{"description":"Đã xóa dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/users/{id}/profile":{"get":{"operationId":"get_users_profile","tags":["Danh tính"],"summary":"Xem profile của Tài khoản người dùng demo","parameters":[{"name":"id","in":"path","required":true,"description":"ID của Tài khoản người dùng demo.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/users/{id}/enrollments":{"get":{"operationId":"get_users_enrollments","tags":["Danh tính"],"summary":"Xem enrollments của Tài khoản người dùng demo","parameters":[{"name":"id","in":"path","required":true,"description":"ID của Tài khoản người dùng demo.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/users/{id}/orders":{"get":{"operationId":"get_users_orders","tags":["Danh tính"],"summary":"Xem orders của Tài khoản người dùng demo","parameters":[{"name":"id","in":"path","required":true,"description":"ID của Tài khoản người dùng demo.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/users/{id}/wallet-transactions":{"get":{"operationId":"get_users_wallet_transactions","tags":["Danh tính"],"summary":"Xem wallet-transactions của Tài khoản người dùng demo","parameters":[{"name":"id","in":"path","required":true,"description":"ID của Tài khoản người dùng demo.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/profiles":{"get":{"operationId":"list_profiles","tags":["Danh tính"],"summary":"Danh sách Hồ sơ nghề nghiệp","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'profiles'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Tìm gần đúng trong: slug, headline, bio.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","user_id","slug","tier","headline","bio","is_public"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"user_id","in":"query","description":"Lọc chính xác theo cột 'user_id'.","schema":{"type":"string"}},{"name":"slug","in":"query","description":"Lọc chính xác theo cột 'slug'.","schema":{"type":"string"}},{"name":"tier","in":"query","description":"Lọc chính xác theo cột 'tier'.","schema":{"type":"string","enum":["FREE","PRO"]}},{"name":"is_public","in":"query","description":"Lọc chính xác theo cột 'is_public'.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"post":{"operationId":"create_profiles","tags":["Danh tính"],"summary":"Tạo Hồ sơ nghề nghiệp","description":"Body chỉ nhận các trường được phép trong schema bên dưới; id và trường hệ thống được server tạo.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProfileInput"}}}},"responses":{"200":{"description":"Thành công"},"201":{"description":"Đã tạo dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/profiles/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Hồ sơ nghề nghiệp.","schema":{"type":"string"}}],"get":{"operationId":"get_profiles","tags":["Danh tính"],"summary":"Chi tiết Hồ sơ nghề nghiệp","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"patch":{"operationId":"update_profiles","tags":["Danh tính"],"summary":"Cập nhật Hồ sơ nghề nghiệp","description":"PATCH chỉ cần gửi những trường muốn thay đổi. Khóa ngoại bất biến và trường nghiệp vụ không xuất hiện trong body.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProfileInput"}}}},"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"delete":{"operationId":"delete_profiles","tags":["Danh tính"],"summary":"Xóa Hồ sơ nghề nghiệp","responses":{"200":{"description":"Thành công"},"204":{"description":"Đã xóa dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/profiles/{id}/skills":{"get":{"operationId":"get_profiles_skills","tags":["Danh tính"],"summary":"Xem skills của Hồ sơ nghề nghiệp","parameters":[{"name":"id","in":"path","required":true,"description":"ID của Hồ sơ nghề nghiệp.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/profiles/{id}/projects":{"get":{"operationId":"get_profiles_projects","tags":["Danh tính"],"summary":"Xem projects của Hồ sơ nghề nghiệp","parameters":[{"name":"id","in":"path","required":true,"description":"ID của Hồ sơ nghề nghiệp.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/profiles/{id}/experiences":{"get":{"operationId":"get_profiles_experiences","tags":["Danh tính"],"summary":"Xem experiences của Hồ sơ nghề nghiệp","parameters":[{"name":"id","in":"path","required":true,"description":"ID của Hồ sơ nghề nghiệp.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/user-skills":{"get":{"operationId":"list_user_skills","tags":["Danh tính"],"summary":"Danh sách Kỹ năng hồ sơ","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'user_skills'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Tìm gần đúng trong: name.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","profile_id","name","level","verified","order"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"profile_id","in":"query","description":"Lọc chính xác theo cột 'profile_id'.","schema":{"type":"string"}},{"name":"level","in":"query","description":"Lọc chính xác theo cột 'level'.","schema":{"type":"string","enum":["BEGINNER","INTERMEDIATE","ADVANCED","EXPERT"]}},{"name":"verified","in":"query","description":"Lọc chính xác theo cột 'verified'.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"post":{"operationId":"create_user_skills","tags":["Danh tính"],"summary":"Tạo Kỹ năng hồ sơ","description":"Body chỉ nhận các trường được phép trong schema bên dưới; id và trường hệ thống được server tạo.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserSkillInput"}}}},"responses":{"200":{"description":"Thành công"},"201":{"description":"Đã tạo dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/user-skills/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Kỹ năng hồ sơ.","schema":{"type":"string"}}],"get":{"operationId":"get_user_skills","tags":["Danh tính"],"summary":"Chi tiết Kỹ năng hồ sơ","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"patch":{"operationId":"update_user_skills","tags":["Danh tính"],"summary":"Cập nhật Kỹ năng hồ sơ","description":"PATCH chỉ cần gửi những trường muốn thay đổi. Khóa ngoại bất biến và trường nghiệp vụ không xuất hiện trong body.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserSkillInput"}}}},"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"delete":{"operationId":"delete_user_skills","tags":["Danh tính"],"summary":"Xóa Kỹ năng hồ sơ","responses":{"200":{"description":"Thành công"},"204":{"description":"Đã xóa dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/portfolio-projects":{"get":{"operationId":"list_portfolio_projects","tags":["Danh tính"],"summary":"Danh sách Dự án portfolio","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'portfolio_projects'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Tìm gần đúng trong: title, description, technologies.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","profile_id","title","description","technologies","order"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"profile_id","in":"query","description":"Lọc chính xác theo cột 'profile_id'.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"post":{"operationId":"create_portfolio_projects","tags":["Danh tính"],"summary":"Tạo Dự án portfolio","description":"Body chỉ nhận các trường được phép trong schema bên dưới; id và trường hệ thống được server tạo.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePortfolioProjectInput"}}}},"responses":{"200":{"description":"Thành công"},"201":{"description":"Đã tạo dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/portfolio-projects/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Dự án portfolio.","schema":{"type":"string"}}],"get":{"operationId":"get_portfolio_projects","tags":["Danh tính"],"summary":"Chi tiết Dự án portfolio","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"patch":{"operationId":"update_portfolio_projects","tags":["Danh tính"],"summary":"Cập nhật Dự án portfolio","description":"PATCH chỉ cần gửi những trường muốn thay đổi. Khóa ngoại bất biến và trường nghiệp vụ không xuất hiện trong body.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePortfolioProjectInput"}}}},"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"delete":{"operationId":"delete_portfolio_projects","tags":["Danh tính"],"summary":"Xóa Dự án portfolio","responses":{"200":{"description":"Thành công"},"204":{"description":"Đã xóa dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/user-experiences":{"get":{"operationId":"list_user_experiences","tags":["Danh tính"],"summary":"Danh sách Kinh nghiệm làm việc","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'user_experiences'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Tìm gần đúng trong: company, role, period, technologies.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","profile_id","company","role","period","technologies","order"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"profile_id","in":"query","description":"Lọc chính xác theo cột 'profile_id'.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"post":{"operationId":"create_user_experiences","tags":["Danh tính"],"summary":"Tạo Kinh nghiệm làm việc","description":"Body chỉ nhận các trường được phép trong schema bên dưới; id và trường hệ thống được server tạo.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserExperienceInput"}}}},"responses":{"200":{"description":"Thành công"},"201":{"description":"Đã tạo dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/user-experiences/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Kinh nghiệm làm việc.","schema":{"type":"string"}}],"get":{"operationId":"get_user_experiences","tags":["Danh tính"],"summary":"Chi tiết Kinh nghiệm làm việc","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"patch":{"operationId":"update_user_experiences","tags":["Danh tính"],"summary":"Cập nhật Kinh nghiệm làm việc","description":"PATCH chỉ cần gửi những trường muốn thay đổi. Khóa ngoại bất biến và trường nghiệp vụ không xuất hiện trong body.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserExperienceInput"}}}},"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"delete":{"operationId":"delete_user_experiences","tags":["Danh tính"],"summary":"Xóa Kinh nghiệm làm việc","responses":{"200":{"description":"Thành công"},"204":{"description":"Đã xóa dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/courses":{"get":{"operationId":"list_courses","tags":["Học tập"],"summary":"Danh sách Khóa học","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'courses'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Tìm gần đúng trong: title, slug, description.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","title","slug","description","price","free_lesson_count","published"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"slug","in":"query","description":"Lọc chính xác theo cột 'slug'.","schema":{"type":"string"}},{"name":"published","in":"query","description":"Lọc chính xác theo cột 'published'.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"post":{"operationId":"create_courses","tags":["Học tập"],"summary":"Tạo Khóa học","description":"Body chỉ nhận các trường được phép trong schema bên dưới; id và trường hệ thống được server tạo.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCourseInput"}}}},"responses":{"200":{"description":"Thành công"},"201":{"description":"Đã tạo dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/courses/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Khóa học.","schema":{"type":"string"}}],"get":{"operationId":"get_courses","tags":["Học tập"],"summary":"Chi tiết Khóa học","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"patch":{"operationId":"update_courses","tags":["Học tập"],"summary":"Cập nhật Khóa học","description":"PATCH chỉ cần gửi những trường muốn thay đổi. Khóa ngoại bất biến và trường nghiệp vụ không xuất hiện trong body.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCourseInput"}}}},"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"delete":{"operationId":"delete_courses","tags":["Học tập"],"summary":"Xóa Khóa học","responses":{"200":{"description":"Thành công"},"204":{"description":"Đã xóa dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/courses/{id}/chapters":{"get":{"operationId":"get_courses_chapters","tags":["Học tập"],"summary":"Xem chapters của Khóa học","parameters":[{"name":"id","in":"path","required":true,"description":"ID của Khóa học.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/courses/{id}/lessons":{"get":{"operationId":"get_courses_lessons","tags":["Học tập"],"summary":"Xem lessons của Khóa học","parameters":[{"name":"id","in":"path","required":true,"description":"ID của Khóa học.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/courses/{id}/enrollments":{"get":{"operationId":"get_courses_enrollments","tags":["Học tập"],"summary":"Xem enrollments của Khóa học","parameters":[{"name":"id","in":"path","required":true,"description":"ID của Khóa học.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/chapters":{"get":{"operationId":"list_chapters","tags":["Học tập"],"summary":"Danh sách Chương học","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'chapters'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Tìm gần đúng trong: title.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","course_id","title","order"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"course_id","in":"query","description":"Lọc chính xác theo cột 'course_id'.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"post":{"operationId":"create_chapters","tags":["Học tập"],"summary":"Tạo Chương học","description":"Body chỉ nhận các trường được phép trong schema bên dưới; id và trường hệ thống được server tạo.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateChapterInput"}}}},"responses":{"200":{"description":"Thành công"},"201":{"description":"Đã tạo dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/chapters/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Chương học.","schema":{"type":"string"}}],"get":{"operationId":"get_chapters","tags":["Học tập"],"summary":"Chi tiết Chương học","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"patch":{"operationId":"update_chapters","tags":["Học tập"],"summary":"Cập nhật Chương học","description":"PATCH chỉ cần gửi những trường muốn thay đổi. Khóa ngoại bất biến và trường nghiệp vụ không xuất hiện trong body.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateChapterInput"}}}},"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"delete":{"operationId":"delete_chapters","tags":["Học tập"],"summary":"Xóa Chương học","responses":{"200":{"description":"Thành công"},"204":{"description":"Đã xóa dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/chapters/{id}/lessons":{"get":{"operationId":"get_chapters_lessons","tags":["Học tập"],"summary":"Xem lessons của Chương học","parameters":[{"name":"id","in":"path","required":true,"description":"ID của Chương học.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/lessons":{"get":{"operationId":"list_lessons","tags":["Học tập"],"summary":"Danh sách Bài học","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'lessons'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Tìm gần đúng trong: title, content.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","chapter_id","title","content","type","order","status"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"chapter_id","in":"query","description":"Lọc chính xác theo cột 'chapter_id'.","schema":{"type":"string"}},{"name":"type","in":"query","description":"Lọc chính xác theo cột 'type'.","schema":{"type":"string","enum":["THEORY","EXERCISE","QUIZ","TESTCASE"]}},{"name":"status","in":"query","description":"Lọc chính xác theo cột 'status'.","schema":{"type":"string","enum":["DRAFT","PUBLISHED"]}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"post":{"operationId":"create_lessons","tags":["Học tập"],"summary":"Tạo Bài học","description":"Body chỉ nhận các trường được phép trong schema bên dưới; id và trường hệ thống được server tạo.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLessonInput"}}}},"responses":{"200":{"description":"Thành công"},"201":{"description":"Đã tạo dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/lessons/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Bài học.","schema":{"type":"string"}}],"get":{"operationId":"get_lessons","tags":["Học tập"],"summary":"Chi tiết Bài học","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"patch":{"operationId":"update_lessons","tags":["Học tập"],"summary":"Cập nhật Bài học","description":"PATCH chỉ cần gửi những trường muốn thay đổi. Khóa ngoại bất biến và trường nghiệp vụ không xuất hiện trong body.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLessonInput"}}}},"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"delete":{"operationId":"delete_lessons","tags":["Học tập"],"summary":"Xóa Bài học","responses":{"200":{"description":"Thành công"},"204":{"description":"Đã xóa dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/lessons/{id}/submissions":{"get":{"operationId":"get_lessons_submissions","tags":["Học tập"],"summary":"Xem submissions của Bài học","parameters":[{"name":"id","in":"path","required":true,"description":"ID của Bài học.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/lessons/{id}/progress":{"get":{"operationId":"get_lessons_progress","tags":["Học tập"],"summary":"Xem progress của Bài học","parameters":[{"name":"id","in":"path","required":true,"description":"ID của Bài học.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/enrollments":{"get":{"operationId":"list_enrollments","tags":["Học tập"],"summary":"Danh sách Đăng ký khóa học","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'enrollments'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Tìm gần đúng trong: unlocked_chapters, unlocked_lessons.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","user_id","course_id","unlock_scope","unlocked_chapters","unlocked_lessons","progress"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"user_id","in":"query","description":"Lọc chính xác theo cột 'user_id'.","schema":{"type":"string"}},{"name":"course_id","in":"query","description":"Lọc chính xác theo cột 'course_id'.","schema":{"type":"string"}},{"name":"unlock_scope","in":"query","description":"Lọc chính xác theo cột 'unlock_scope'.","schema":{"type":"string","enum":["LESSON","CHAPTER","FULL"]}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/enrollments/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Đăng ký khóa học.","schema":{"type":"string"}}],"get":{"operationId":"get_enrollments","tags":["Học tập"],"summary":"Chi tiết Đăng ký khóa học","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/submissions":{"get":{"operationId":"list_submissions","tags":["Học tập"],"summary":"Danh sách Bài nộp","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'submissions'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Tìm gần đúng trong: content.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","user_id","lesson_id","content","status"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"user_id","in":"query","description":"Lọc chính xác theo cột 'user_id'.","schema":{"type":"string"}},{"name":"lesson_id","in":"query","description":"Lọc chính xác theo cột 'lesson_id'.","schema":{"type":"string"}},{"name":"status","in":"query","description":"Lọc chính xác theo cột 'status'.","schema":{"type":"string","enum":["PENDING","APPROVED","WRONG","MISSING"]}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"post":{"operationId":"create_submissions","tags":["Học tập"],"summary":"Tạo Bài nộp","description":"Body chỉ nhận các trường được phép trong schema bên dưới; id và trường hệ thống được server tạo.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSubmissionInput"}}}},"responses":{"200":{"description":"Thành công"},"201":{"description":"Đã tạo dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/submissions/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Bài nộp.","schema":{"type":"string"}}],"get":{"operationId":"get_submissions","tags":["Học tập"],"summary":"Chi tiết Bài nộp","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"delete":{"operationId":"delete_submissions","tags":["Học tập"],"summary":"Xóa Bài nộp","responses":{"200":{"description":"Thành công"},"204":{"description":"Đã xóa dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/lesson-progress":{"get":{"operationId":"list_lesson_progress","tags":["Học tập"],"summary":"Danh sách Tiến độ bài học","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'lesson_progress'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Resource này không có cột text để tìm kiếm.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","user_id","lesson_id","course_id","completed_at"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"user_id","in":"query","description":"Lọc chính xác theo cột 'user_id'.","schema":{"type":"string"}},{"name":"lesson_id","in":"query","description":"Lọc chính xác theo cột 'lesson_id'.","schema":{"type":"string"}},{"name":"course_id","in":"query","description":"Lọc chính xác theo cột 'course_id'.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/lesson-progress/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Tiến độ bài học.","schema":{"type":"string"}}],"get":{"operationId":"get_lesson_progress","tags":["Học tập"],"summary":"Chi tiết Tiến độ bài học","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/course-certificates":{"get":{"operationId":"list_course_certificates","tags":["Học tập"],"summary":"Danh sách Chứng chỉ","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'course_certificates'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Tìm gần đúng trong: certificate_number, recipient_name_at_issue, course_title_at_issue.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","certificate_number","user_id","course_id","recipient_name_at_issue","course_title_at_issue","issued_at"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"certificate_number","in":"query","description":"Lọc chính xác theo cột 'certificate_number'.","schema":{"type":"string"}},{"name":"user_id","in":"query","description":"Lọc chính xác theo cột 'user_id'.","schema":{"type":"string"}},{"name":"course_id","in":"query","description":"Lọc chính xác theo cột 'course_id'.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/course-certificates/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Chứng chỉ.","schema":{"type":"string"}}],"get":{"operationId":"get_course_certificates","tags":["Học tập"],"summary":"Chi tiết Chứng chỉ","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/orders":{"get":{"operationId":"list_orders","tags":["Thương mại"],"summary":"Danh sách Đơn hàng","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'orders'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Tìm gần đúng trong: sepay_ref.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","user_id","amount","status","sepay_ref","created_at","paid_at"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"user_id","in":"query","description":"Lọc chính xác theo cột 'user_id'.","schema":{"type":"string"}},{"name":"status","in":"query","description":"Lọc chính xác theo cột 'status'.","schema":{"type":"string","enum":["PENDING","PAID","FAILED"]}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"post":{"operationId":"create_orders","tags":["Thương mại"],"summary":"Tạo Đơn hàng","description":"Body chỉ nhận các trường được phép trong schema bên dưới; id và trường hệ thống được server tạo.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrderInput"}}}},"responses":{"200":{"description":"Thành công"},"201":{"description":"Đã tạo dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/orders/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Đơn hàng.","schema":{"type":"string"}}],"get":{"operationId":"get_orders","tags":["Thương mại"],"summary":"Chi tiết Đơn hàng","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/orders/{id}/items":{"get":{"operationId":"get_orders_items","tags":["Thương mại"],"summary":"Xem items của Đơn hàng","parameters":[{"name":"id","in":"path","required":true,"description":"ID của Đơn hàng.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/orders/{id}/payment-logs":{"get":{"operationId":"get_orders_payment_logs","tags":["Thương mại"],"summary":"Xem payment-logs của Đơn hàng","parameters":[{"name":"id","in":"path","required":true,"description":"ID của Đơn hàng.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/order-items":{"get":{"operationId":"list_order_items","tags":["Thương mại"],"summary":"Danh sách Dòng đơn hàng","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'order_items'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Resource này không có cột text để tìm kiếm.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","order_id","item_type","course_id","lesson_id","unlock_scope","price"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"order_id","in":"query","description":"Lọc chính xác theo cột 'order_id'.","schema":{"type":"string"}},{"name":"item_type","in":"query","description":"Lọc chính xác theo cột 'item_type'.","schema":{"type":"string","enum":["COURSE","LESSON","PRO_UPGRADE","ORG_LICENSE"]}},{"name":"course_id","in":"query","description":"Lọc chính xác theo cột 'course_id'.","schema":{"type":"string"}},{"name":"lesson_id","in":"query","description":"Lọc chính xác theo cột 'lesson_id'.","schema":{"type":"string"}},{"name":"unlock_scope","in":"query","description":"Lọc chính xác theo cột 'unlock_scope'.","schema":{"type":"string","enum":["LESSON","CHAPTER","FULL"]}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"post":{"operationId":"create_order_items","tags":["Thương mại"],"summary":"Tạo Dòng đơn hàng","description":"Body chỉ nhận các trường được phép trong schema bên dưới; id và trường hệ thống được server tạo.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrderItemInput"}}}},"responses":{"200":{"description":"Thành công"},"201":{"description":"Đã tạo dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/order-items/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Dòng đơn hàng.","schema":{"type":"string"}}],"get":{"operationId":"get_order_items","tags":["Thương mại"],"summary":"Chi tiết Dòng đơn hàng","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"patch":{"operationId":"update_order_items","tags":["Thương mại"],"summary":"Cập nhật Dòng đơn hàng","description":"PATCH chỉ cần gửi những trường muốn thay đổi. Khóa ngoại bất biến và trường nghiệp vụ không xuất hiện trong body.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOrderItemInput"}}}},"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"delete":{"operationId":"delete_order_items","tags":["Thương mại"],"summary":"Xóa Dòng đơn hàng","responses":{"200":{"description":"Thành công"},"204":{"description":"Đã xóa dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/payment-logs":{"get":{"operationId":"list_payment_logs","tags":["Thương mại"],"summary":"Danh sách Nhật ký thanh toán","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'payment_logs'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Tìm gần đúng trong: content.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","sepay_id","amount_in","content","raw_payload","related_order_id","related_user_id"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"sepay_id","in":"query","description":"Lọc chính xác theo cột 'sepay_id'.","schema":{"type":"string"}},{"name":"related_order_id","in":"query","description":"Lọc chính xác theo cột 'related_order_id'.","schema":{"type":"string"}},{"name":"related_user_id","in":"query","description":"Lọc chính xác theo cột 'related_user_id'.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/payment-logs/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Nhật ký thanh toán.","schema":{"type":"string"}}],"get":{"operationId":"get_payment_logs","tags":["Thương mại"],"summary":"Chi tiết Nhật ký thanh toán","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/wallet-transactions":{"get":{"operationId":"list_wallet_transactions","tags":["Thương mại"],"summary":"Danh sách Giao dịch ví","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'wallet_transactions'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Tìm gần đúng trong: description.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","user_id","type","amount","balance_before","balance_after","description","related_order_id","related_payment_log_id"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"user_id","in":"query","description":"Lọc chính xác theo cột 'user_id'.","schema":{"type":"string"}},{"name":"type","in":"query","description":"Lọc chính xác theo cột 'type'.","schema":{"type":"string","enum":["DEPOSIT","PURCHASE","REFUND","AI_GRADING","EDU_WELCOME_BONUS","ADMIN_ADJUSTMENT"]}},{"name":"related_order_id","in":"query","description":"Lọc chính xác theo cột 'related_order_id'.","schema":{"type":"string"}},{"name":"related_payment_log_id","in":"query","description":"Lọc chính xác theo cột 'related_payment_log_id'.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/wallet-transactions/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Giao dịch ví.","schema":{"type":"string"}}],"get":{"operationId":"get_wallet_transactions","tags":["Thương mại"],"summary":"Chi tiết Giao dịch ví","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/spend-xp-logs":{"get":{"operationId":"list_spend_xp_logs","tags":["Thương mại"],"summary":"Danh sách Nhật ký Spend XP","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'spend_xp_logs'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Resource này không có cột text để tìm kiếm.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","user_id","amount","xp_earned","related_order_id","related_wallet_transaction_id"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"user_id","in":"query","description":"Lọc chính xác theo cột 'user_id'.","schema":{"type":"string"}},{"name":"related_order_id","in":"query","description":"Lọc chính xác theo cột 'related_order_id'.","schema":{"type":"string"}},{"name":"related_wallet_transaction_id","in":"query","description":"Lọc chính xác theo cột 'related_wallet_transaction_id'.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/spend-xp-logs/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Nhật ký Spend XP.","schema":{"type":"string"}}],"get":{"operationId":"get_spend_xp_logs","tags":["Thương mại"],"summary":"Chi tiết Nhật ký Spend XP","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/spend-xp-rewards":{"get":{"operationId":"list_spend_xp_rewards","tags":["Thương mại"],"summary":"Danh sách Phần thưởng Spend XP","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'spend_xp_rewards'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Tìm gần đúng trong: milestone_key, reward_type.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","user_id","milestone_key","reward_type","reward_qty"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"user_id","in":"query","description":"Lọc chính xác theo cột 'user_id'.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/spend-xp-rewards/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Phần thưởng Spend XP.","schema":{"type":"string"}}],"get":{"operationId":"get_spend_xp_rewards","tags":["Thương mại"],"summary":"Chi tiết Phần thưởng Spend XP","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/blogs":{"get":{"operationId":"list_blogs","tags":["Nội dung"],"summary":"Danh sách Bài blog","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'blogs'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Tìm gần đúng trong: title, slug, excerpt, content.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","title","slug","excerpt","content","view_count","published"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"slug","in":"query","description":"Lọc chính xác theo cột 'slug'.","schema":{"type":"string"}},{"name":"published","in":"query","description":"Lọc chính xác theo cột 'published'.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"post":{"operationId":"create_blogs","tags":["Nội dung"],"summary":"Tạo Bài blog","description":"Body chỉ nhận các trường được phép trong schema bên dưới; id và trường hệ thống được server tạo.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBlogInput"}}}},"responses":{"200":{"description":"Thành công"},"201":{"description":"Đã tạo dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/blogs/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Bài blog.","schema":{"type":"string"}}],"get":{"operationId":"get_blogs","tags":["Nội dung"],"summary":"Chi tiết Bài blog","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"patch":{"operationId":"update_blogs","tags":["Nội dung"],"summary":"Cập nhật Bài blog","description":"PATCH chỉ cần gửi những trường muốn thay đổi. Khóa ngoại bất biến và trường nghiệp vụ không xuất hiện trong body.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBlogInput"}}}},"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"delete":{"operationId":"delete_blogs","tags":["Nội dung"],"summary":"Xóa Bài blog","responses":{"200":{"description":"Thành công"},"204":{"description":"Đã xóa dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/blogs/{id}/tags":{"get":{"operationId":"get_blogs_tags","tags":["Nội dung"],"summary":"Xem tags của Bài blog","parameters":[{"name":"id","in":"path","required":true,"description":"ID của Bài blog.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/blogs/{id}/comments":{"get":{"operationId":"get_blogs_comments","tags":["Nội dung"],"summary":"Xem comments của Bài blog","parameters":[{"name":"id","in":"path","required":true,"description":"ID của Bài blog.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/blogs/{id}/views":{"get":{"operationId":"get_blogs_views","tags":["Nội dung"],"summary":"Xem views của Bài blog","parameters":[{"name":"id","in":"path","required":true,"description":"ID của Bài blog.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/tags":{"get":{"operationId":"list_tags","tags":["Nội dung"],"summary":"Danh sách Nhãn blog","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'tags'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Tìm gần đúng trong: name, slug, desc.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","name","slug","desc"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"slug","in":"query","description":"Lọc chính xác theo cột 'slug'.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"post":{"operationId":"create_tags","tags":["Nội dung"],"summary":"Tạo Nhãn blog","description":"Body chỉ nhận các trường được phép trong schema bên dưới; id và trường hệ thống được server tạo.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTagInput"}}}},"responses":{"200":{"description":"Thành công"},"201":{"description":"Đã tạo dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/tags/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Nhãn blog.","schema":{"type":"string"}}],"get":{"operationId":"get_tags","tags":["Nội dung"],"summary":"Chi tiết Nhãn blog","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"patch":{"operationId":"update_tags","tags":["Nội dung"],"summary":"Cập nhật Nhãn blog","description":"PATCH chỉ cần gửi những trường muốn thay đổi. Khóa ngoại bất biến và trường nghiệp vụ không xuất hiện trong body.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTagInput"}}}},"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"delete":{"operationId":"delete_tags","tags":["Nội dung"],"summary":"Xóa Nhãn blog","responses":{"200":{"description":"Thành công"},"204":{"description":"Đã xóa dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/tags/{id}/blogs":{"get":{"operationId":"get_tags_blogs","tags":["Nội dung"],"summary":"Xem blogs của Nhãn blog","parameters":[{"name":"id","in":"path","required":true,"description":"ID của Nhãn blog.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/blog-tags":{"get":{"operationId":"list_blog_tags","tags":["Nội dung"],"summary":"Danh sách Quan hệ blog và nhãn","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'blog_tags'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Resource này không có cột text để tìm kiếm.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","blog_id","tag_id"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"blog_id","in":"query","description":"Lọc chính xác theo cột 'blog_id'.","schema":{"type":"string"}},{"name":"tag_id","in":"query","description":"Lọc chính xác theo cột 'tag_id'.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"post":{"operationId":"create_blog_tags","tags":["Nội dung"],"summary":"Tạo Quan hệ blog và nhãn","description":"Body chỉ nhận các trường được phép trong schema bên dưới; id và trường hệ thống được server tạo.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBlogTagInput"}}}},"responses":{"200":{"description":"Thành công"},"201":{"description":"Đã tạo dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/blog-tags/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Quan hệ blog và nhãn.","schema":{"type":"string"}}],"get":{"operationId":"get_blog_tags","tags":["Nội dung"],"summary":"Chi tiết Quan hệ blog và nhãn","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"delete":{"operationId":"delete_blog_tags","tags":["Nội dung"],"summary":"Xóa Quan hệ blog và nhãn","responses":{"200":{"description":"Thành công"},"204":{"description":"Đã xóa dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/comments":{"get":{"operationId":"list_comments","tags":["Nội dung"],"summary":"Danh sách Bình luận","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'comments'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Tìm gần đúng trong: content.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","blog_id","user_id","content","parent_id"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"blog_id","in":"query","description":"Lọc chính xác theo cột 'blog_id'.","schema":{"type":"string"}},{"name":"user_id","in":"query","description":"Lọc chính xác theo cột 'user_id'.","schema":{"type":"string"}},{"name":"parent_id","in":"query","description":"Lọc chính xác theo cột 'parent_id'.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"post":{"operationId":"create_comments","tags":["Nội dung"],"summary":"Tạo Bình luận","description":"Body chỉ nhận các trường được phép trong schema bên dưới; id và trường hệ thống được server tạo.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommentInput"}}}},"responses":{"200":{"description":"Thành công"},"201":{"description":"Đã tạo dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/comments/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Bình luận.","schema":{"type":"string"}}],"get":{"operationId":"get_comments","tags":["Nội dung"],"summary":"Chi tiết Bình luận","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"patch":{"operationId":"update_comments","tags":["Nội dung"],"summary":"Cập nhật Bình luận","description":"PATCH chỉ cần gửi những trường muốn thay đổi. Khóa ngoại bất biến và trường nghiệp vụ không xuất hiện trong body.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCommentInput"}}}},"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}},"delete":{"operationId":"delete_comments","tags":["Nội dung"],"summary":"Xóa Bình luận","responses":{"200":{"description":"Thành công"},"204":{"description":"Đã xóa dữ liệu"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/comments/{id}/replies":{"get":{"operationId":"get_comments_replies","tags":["Nội dung"],"summary":"Xem replies của Bình luận","parameters":[{"name":"id","in":"path","required":true,"description":"ID của Bình luận.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/user-views":{"get":{"operationId":"list_user_views","tags":["Nội dung"],"summary":"Danh sách Lượt xem của người dùng","description":"Phân trang, tìm kiếm, lọc và sắp xếp dữ liệu trong bảng 'user_views'.","parameters":[{"name":"page","in":"query","description":"Trang kết quả, bắt đầu từ 1.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Số bản ghi trên một trang.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"search","in":"query","description":"Resource này không có cột text để tìm kiếm.","schema":{"type":"string"}},{"name":"sort","in":"query","description":"Tên cột dùng để sắp xếp.","schema":{"type":"string","enum":["id","blog_id","user_id"],"default":"id"}},{"name":"order","in":"query","description":"Chiều sắp xếp.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}},{"name":"blog_id","in":"query","description":"Lọc chính xác theo cột 'blog_id'.","schema":{"type":"string"}},{"name":"user_id","in":"query","description":"Lọc chính xác theo cột 'user_id'.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/user-views/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"ID của Lượt xem của người dùng.","schema":{"type":"string"}}],"get":{"operationId":"get_user_views","tags":["Nội dung"],"summary":"Chi tiết Lượt xem của người dùng","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"404":{"description":"Không tìm thấy dữ liệu"},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/courses/{id}/actions/publish":{"post":{"operationId":"courses_publish","tags":["Hệ thống"],"summary":"Xuất bản khóa học","description":"Action nghiệp vụ thay đổi trạng thái theo quy tắc của hệ thống.","parameters":[{"name":"id","in":"path","required":true,"description":"ID của courses.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/courses/{id}/actions/unpublish":{"post":{"operationId":"courses_unpublish","tags":["Hệ thống"],"summary":"Chuyển khóa học về bản nháp","description":"Action nghiệp vụ thay đổi trạng thái theo quy tắc của hệ thống.","parameters":[{"name":"id","in":"path","required":true,"description":"ID của courses.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/lessons/{id}/actions/publish":{"post":{"operationId":"lessons_publish","tags":["Hệ thống"],"summary":"Xuất bản bài học","description":"Action nghiệp vụ thay đổi trạng thái theo quy tắc của hệ thống.","parameters":[{"name":"id","in":"path","required":true,"description":"ID của lessons.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/lessons/{id}/actions/unpublish":{"post":{"operationId":"lessons_unpublish","tags":["Hệ thống"],"summary":"Chuyển bài học về bản nháp","description":"Action nghiệp vụ thay đổi trạng thái theo quy tắc của hệ thống.","parameters":[{"name":"id","in":"path","required":true,"description":"ID của lessons.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/blogs/{id}/actions/publish":{"post":{"operationId":"blogs_publish","tags":["Hệ thống"],"summary":"Xuất bản bài blog","description":"Action nghiệp vụ thay đổi trạng thái theo quy tắc của hệ thống.","parameters":[{"name":"id","in":"path","required":true,"description":"ID của blogs.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/blogs/{id}/actions/unpublish":{"post":{"operationId":"blogs_unpublish","tags":["Hệ thống"],"summary":"Chuyển bài blog về bản nháp","description":"Action nghiệp vụ thay đổi trạng thái theo quy tắc của hệ thống.","parameters":[{"name":"id","in":"path","required":true,"description":"ID của blogs.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/submissions/{id}/actions/review":{"post":{"operationId":"submissions_review","tags":["Hệ thống"],"summary":"Duyệt kết quả bài nộp","description":"Action nghiệp vụ thay đổi trạng thái theo quy tắc của hệ thống.","parameters":[{"name":"id","in":"path","required":true,"description":"ID của submissions.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewSubmissionInput"}}}},"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/orders/{id}/actions/pay":{"post":{"operationId":"orders_pay","tags":["Hệ thống"],"summary":"Xác nhận đơn hàng đã thanh toán","description":"Action nghiệp vụ thay đổi trạng thái theo quy tắc của hệ thống.","parameters":[{"name":"id","in":"path","required":true,"description":"ID của orders.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/orders/{id}/actions/fail":{"post":{"operationId":"orders_fail","tags":["Hệ thống"],"summary":"Đánh dấu đơn hàng thất bại","description":"Action nghiệp vụ thay đổi trạng thái theo quy tắc của hệ thống.","parameters":[{"name":"id","in":"path","required":true,"description":"ID của orders.","schema":{"type":"string"}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/users/{id}/actions/adjust-wallet":{"post":{"operationId":"users_adjust_wallet","tags":["Hệ thống"],"summary":"Điều chỉnh số dư ví của người dùng","description":"Action dành cho vai trò quản trị demo. Server khóa bản ghi user, giữ wallet_balance = real_balance + bonus_balance và ghi ledger ADMIN_ADJUSTMENT.","parameters":[{"name":"id","in":"path","required":true,"description":"ID của users.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdjustWalletInput"}}}},"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/enrollments/actions/upsert":{"post":{"operationId":"enrollments_upsert","tags":["Hệ thống"],"summary":"Tạo hoặc cập nhật đăng ký khóa học","description":"Action nghiệp vụ nhận body có kiểu dữ liệu, required fields và example cụ thể.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertEnrollmentInput"}}}},"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/lesson-progress/actions/complete":{"post":{"operationId":"lesson_progress_complete","tags":["Hệ thống"],"summary":"Đánh dấu bài học đã hoàn thành","description":"Action nghiệp vụ nhận body có kiểu dữ liệu, required fields và example cụ thể.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteLessonInput"}}}},"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/course-certificates/actions/issue":{"post":{"operationId":"course_certificates_issue","tags":["Hệ thống"],"summary":"Cấp chứng chỉ khóa học","description":"Action nghiệp vụ nhận body có kiểu dữ liệu, required fields và example cụ thể.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueCertificateInput"}}}},"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/payment-logs/actions/record":{"post":{"operationId":"payment_logs_record","tags":["Hệ thống"],"summary":"Ghi nhận giao dịch thanh toán","description":"Action nghiệp vụ nhận body có kiểu dữ liệu, required fields và example cụ thể.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordPaymentInput"}}}},"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/user-views/actions/record":{"post":{"operationId":"user_views_record","tags":["Hệ thống"],"summary":"Ghi nhận lượt xem bài blog","description":"Action nghiệp vụ nhận body có kiểu dữ liệu, required fields và example cụ thể.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordUserViewInput"}}}},"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/spend-xp-logs/actions/award":{"post":{"operationId":"spend_xp_logs_award","tags":["Hệ thống"],"summary":"Cộng Spend XP từ giao dịch ví","description":"Action nghiệp vụ nhận body có kiểu dữ liệu, required fields và example cụ thể.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwardSpendXpInput"}}}},"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/spend-xp-rewards/actions/redeem":{"post":{"operationId":"spend_xp_rewards_redeem","tags":["Hệ thống"],"summary":"Ghi nhận phần thưởng Spend XP","description":"Action nghiệp vụ nhận body có kiểu dữ liệu, required fields và example cụ thể.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedeemSpendXpInput"}}}},"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/meta/health":{"get":{"operationId":"meta_health","tags":["Hệ thống"],"summary":"Kiểm tra kết nối SQL Lab","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/meta/schema":{"get":{"operationId":"meta_schema","tags":["Hệ thống"],"summary":"Đọc schema và baseline đang phục vụ","responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}},"/playground/api/v1/reports/{domain}":{"get":{"operationId":"get_report","tags":["Báo cáo"],"summary":"Đọc báo cáo tổng hợp theo miền","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","enum":["learning-overview","commerce-overview","content-overview"]}}],"responses":{"200":{"description":"Thành công"},"401":{"description":"API key không hợp lệ","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"409":{"description":"Xung đột với trạng thái dữ liệu hiện tại","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"422":{"description":"Request không đúng contract","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}},"429":{"description":"Đã vượt giới hạn request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/PlaygroundProblem"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"T5Edu API key"}},"schemas":{"PlaygroundProblem":{"type":"object","required":["type","title","status","detail","instance","requestId"],"properties":{"type":{"type":"string","format":"uri"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"instance":{"type":"string"},"requestId":{"type":"string"},"errors":{"nullable":true}}},"CreateUserInput":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","description":"Cột 'name' được sinh từ name trong schema SQL Lab.","example":"Nguyễn Minh Anh","nullable":true},"email":{"type":"string","description":"Cột 'email' được sinh từ email trong schema SQL Lab.","example":"tester@example.com","nullable":true},"role":{"type":"string","enum":["STUDENT","ADMIN"],"description":"Cột 'role' được sinh từ role trong schema SQL Lab.","example":"STUDENT"}},"required":["email"]},"UpdateUserInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"name":{"type":"string","description":"Cột 'name' được sinh từ name trong schema SQL Lab.","example":"Nguyễn Minh Anh","nullable":true},"email":{"type":"string","description":"Cột 'email' được sinh từ email trong schema SQL Lab.","example":"tester@example.com","nullable":true},"role":{"type":"string","enum":["STUDENT","ADMIN"],"description":"Cột 'role' được sinh từ role trong schema SQL Lab.","example":"STUDENT"}}},"CreateProfileInput":{"type":"object","additionalProperties":false,"properties":{"user_id":{"type":"string","description":"Cột 'user_id' được sinh từ userId trong schema SQL Lab.","example":"user_001"},"slug":{"type":"string","description":"Cột 'slug' được sinh từ slug trong schema SQL Lab.","example":"du-lieu-demo"},"tier":{"type":"string","enum":["FREE","PRO"],"description":"Cột 'tier' được sinh từ tier trong schema SQL Lab.","example":"FREE"},"headline":{"type":"string","description":"Cột 'headline' được sinh từ headline trong schema SQL Lab.","example":"headline_demo","nullable":true},"bio":{"type":"string","description":"Cột 'bio' được sinh từ bio trong schema SQL Lab.","example":"Mô tả dùng trong môi trường thực hành.","nullable":true},"is_public":{"type":"boolean","description":"Cột 'is_public' được sinh từ isPublic trong schema SQL Lab.","example":true}},"required":["user_id","slug"]},"UpdateProfileInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"slug":{"type":"string","description":"Cột 'slug' được sinh từ slug trong schema SQL Lab.","example":"du-lieu-demo"},"tier":{"type":"string","enum":["FREE","PRO"],"description":"Cột 'tier' được sinh từ tier trong schema SQL Lab.","example":"FREE"},"headline":{"type":"string","description":"Cột 'headline' được sinh từ headline trong schema SQL Lab.","example":"headline_demo","nullable":true},"bio":{"type":"string","description":"Cột 'bio' được sinh từ bio trong schema SQL Lab.","example":"Mô tả dùng trong môi trường thực hành.","nullable":true},"is_public":{"type":"boolean","description":"Cột 'is_public' được sinh từ isPublic trong schema SQL Lab.","example":true}}},"CreateUserSkillInput":{"type":"object","additionalProperties":false,"properties":{"profile_id":{"type":"string","description":"Cột 'profile_id' được sinh từ profileId trong schema SQL Lab.","example":"profile_001"},"name":{"type":"string","description":"Cột 'name' được sinh từ name trong schema SQL Lab.","example":"Nguyễn Minh Anh"},"level":{"type":"string","enum":["BEGINNER","INTERMEDIATE","ADVANCED","EXPERT"],"description":"Cột 'level' được sinh từ level trong schema SQL Lab.","example":"BEGINNER"},"verified":{"type":"boolean","description":"Cột 'verified' được sinh từ verified trong schema SQL Lab.","example":true},"order":{"type":"integer","minimum":0,"description":"Cột 'order' được sinh từ order trong schema SQL Lab.","example":1}},"required":["profile_id","name"]},"UpdateUserSkillInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"name":{"type":"string","description":"Cột 'name' được sinh từ name trong schema SQL Lab.","example":"Nguyễn Minh Anh"},"level":{"type":"string","enum":["BEGINNER","INTERMEDIATE","ADVANCED","EXPERT"],"description":"Cột 'level' được sinh từ level trong schema SQL Lab.","example":"BEGINNER"},"verified":{"type":"boolean","description":"Cột 'verified' được sinh từ verified trong schema SQL Lab.","example":true},"order":{"type":"integer","minimum":0,"description":"Cột 'order' được sinh từ order trong schema SQL Lab.","example":1}}},"CreatePortfolioProjectInput":{"type":"object","additionalProperties":false,"properties":{"profile_id":{"type":"string","description":"Cột 'profile_id' được sinh từ profileId trong schema SQL Lab.","example":"profile_001"},"title":{"type":"string","description":"Cột 'title' được sinh từ title trong schema SQL Lab.","example":"Nội dung thực hành"},"description":{"type":"string","description":"Cột 'description' được sinh từ description trong schema SQL Lab.","example":"Mô tả dùng trong môi trường thực hành.","nullable":true},"technologies":{"type":"array","items":{"type":"string"},"description":"Cột 'technologies' được sinh từ technologies trong schema SQL Lab.","example":["PostgreSQL","Postman"]},"order":{"type":"integer","minimum":0,"description":"Cột 'order' được sinh từ order trong schema SQL Lab.","example":1}},"required":["profile_id","title"]},"UpdatePortfolioProjectInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"title":{"type":"string","description":"Cột 'title' được sinh từ title trong schema SQL Lab.","example":"Nội dung thực hành"},"description":{"type":"string","description":"Cột 'description' được sinh từ description trong schema SQL Lab.","example":"Mô tả dùng trong môi trường thực hành.","nullable":true},"technologies":{"type":"array","items":{"type":"string"},"description":"Cột 'technologies' được sinh từ technologies trong schema SQL Lab.","example":["PostgreSQL","Postman"]},"order":{"type":"integer","minimum":0,"description":"Cột 'order' được sinh từ order trong schema SQL Lab.","example":1}}},"CreateUserExperienceInput":{"type":"object","additionalProperties":false,"properties":{"profile_id":{"type":"string","description":"Cột 'profile_id' được sinh từ profileId trong schema SQL Lab.","example":"profile_001"},"company":{"type":"string","description":"Cột 'company' được sinh từ company trong schema SQL Lab.","example":"company_demo","nullable":true},"role":{"type":"string","description":"Cột 'role' được sinh từ role trong schema SQL Lab.","example":"role_demo"},"period":{"type":"string","description":"Cột 'period' được sinh từ period trong schema SQL Lab.","example":"period_demo"},"technologies":{"type":"array","items":{"type":"string"},"description":"Cột 'technologies' được sinh từ technologies trong schema SQL Lab.","example":["PostgreSQL","Postman"]},"order":{"type":"integer","minimum":0,"description":"Cột 'order' được sinh từ order trong schema SQL Lab.","example":1}},"required":["profile_id","role","period"]},"UpdateUserExperienceInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"company":{"type":"string","description":"Cột 'company' được sinh từ company trong schema SQL Lab.","example":"company_demo","nullable":true},"role":{"type":"string","description":"Cột 'role' được sinh từ role trong schema SQL Lab.","example":"role_demo"},"period":{"type":"string","description":"Cột 'period' được sinh từ period trong schema SQL Lab.","example":"period_demo"},"technologies":{"type":"array","items":{"type":"string"},"description":"Cột 'technologies' được sinh từ technologies trong schema SQL Lab.","example":["PostgreSQL","Postman"]},"order":{"type":"integer","minimum":0,"description":"Cột 'order' được sinh từ order trong schema SQL Lab.","example":1}}},"CreateCourseInput":{"type":"object","additionalProperties":false,"properties":{"title":{"type":"string","description":"Cột 'title' được sinh từ title trong schema SQL Lab.","example":"Nội dung thực hành"},"slug":{"type":"string","description":"Cột 'slug' được sinh từ slug trong schema SQL Lab.","example":"du-lieu-demo"},"description":{"type":"string","description":"Cột 'description' được sinh từ description trong schema SQL Lab.","example":"Mô tả dùng trong môi trường thực hành.","nullable":true},"price":{"type":"number","format":"double","minimum":0,"description":"Cột 'price' được sinh từ price trong schema SQL Lab.","example":100000},"free_lesson_count":{"type":"integer","minimum":0,"description":"Cột 'free_lesson_count' được sinh từ freeLessonCount trong schema SQL Lab.","example":1}},"required":["title","slug"]},"UpdateCourseInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"title":{"type":"string","description":"Cột 'title' được sinh từ title trong schema SQL Lab.","example":"Nội dung thực hành"},"slug":{"type":"string","description":"Cột 'slug' được sinh từ slug trong schema SQL Lab.","example":"du-lieu-demo"},"description":{"type":"string","description":"Cột 'description' được sinh từ description trong schema SQL Lab.","example":"Mô tả dùng trong môi trường thực hành.","nullable":true},"price":{"type":"number","format":"double","minimum":0,"description":"Cột 'price' được sinh từ price trong schema SQL Lab.","example":100000},"free_lesson_count":{"type":"integer","minimum":0,"description":"Cột 'free_lesson_count' được sinh từ freeLessonCount trong schema SQL Lab.","example":1}}},"CreateChapterInput":{"type":"object","additionalProperties":false,"properties":{"course_id":{"type":"string","description":"Cột 'course_id' được sinh từ courseId trong schema SQL Lab.","example":"course_001"},"title":{"type":"string","description":"Cột 'title' được sinh từ title trong schema SQL Lab.","example":"Nội dung thực hành"},"order":{"type":"integer","minimum":0,"description":"Cột 'order' được sinh từ order trong schema SQL Lab.","example":1}},"required":["course_id","title","order"]},"UpdateChapterInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"course_id":{"type":"string","description":"Cột 'course_id' được sinh từ courseId trong schema SQL Lab.","example":"course_001"},"title":{"type":"string","description":"Cột 'title' được sinh từ title trong schema SQL Lab.","example":"Nội dung thực hành"},"order":{"type":"integer","minimum":0,"description":"Cột 'order' được sinh từ order trong schema SQL Lab.","example":1}}},"CreateLessonInput":{"type":"object","additionalProperties":false,"properties":{"chapter_id":{"type":"string","description":"Cột 'chapter_id' được sinh từ chapterId trong schema SQL Lab.","example":"chapter_001"},"title":{"type":"string","description":"Cột 'title' được sinh từ title trong schema SQL Lab.","example":"Nội dung thực hành"},"content":{"type":"string","description":"Cột 'content' được sinh từ content trong schema SQL Lab.","example":"Nội dung kiểm thử API","nullable":true},"type":{"type":"string","enum":["THEORY","EXERCISE","QUIZ","TESTCASE"],"description":"Cột 'type' được sinh từ type trong schema SQL Lab.","example":"THEORY"},"order":{"type":"integer","minimum":0,"description":"Cột 'order' được sinh từ order trong schema SQL Lab.","example":1}},"required":["chapter_id","title","order"]},"UpdateLessonInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"chapter_id":{"type":"string","description":"Cột 'chapter_id' được sinh từ chapterId trong schema SQL Lab.","example":"chapter_001"},"title":{"type":"string","description":"Cột 'title' được sinh từ title trong schema SQL Lab.","example":"Nội dung thực hành"},"content":{"type":"string","description":"Cột 'content' được sinh từ content trong schema SQL Lab.","example":"Nội dung kiểm thử API","nullable":true},"type":{"type":"string","enum":["THEORY","EXERCISE","QUIZ","TESTCASE"],"description":"Cột 'type' được sinh từ type trong schema SQL Lab.","example":"THEORY"},"order":{"type":"integer","minimum":0,"description":"Cột 'order' được sinh từ order trong schema SQL Lab.","example":1}}},"CreateEnrollmentInput":{"type":"object","additionalProperties":false,"properties":{"user_id":{"type":"string","description":"Cột 'user_id' được sinh từ userId trong schema SQL Lab.","example":"user_001"},"course_id":{"type":"string","description":"Cột 'course_id' được sinh từ courseId trong schema SQL Lab.","example":"course_001"},"unlock_scope":{"type":"string","enum":["LESSON","CHAPTER","FULL"],"description":"Cột 'unlock_scope' được sinh từ unlockScope trong schema SQL Lab.","example":"LESSON"},"unlocked_chapters":{"type":"array","items":{"type":"string"},"description":"Cột 'unlocked_chapters' được sinh từ unlockedChapters trong schema SQL Lab.","example":["PostgreSQL","Postman"]},"unlocked_lessons":{"type":"array","items":{"type":"string"},"description":"Cột 'unlocked_lessons' được sinh từ unlockedLessons trong schema SQL Lab.","example":["PostgreSQL","Postman"]},"progress":{"type":"number","format":"double","minimum":0,"maximum":1,"description":"Cột 'progress' được sinh từ progress trong schema SQL Lab.","example":0.5}},"required":["user_id","course_id"]},"UpdateEnrollmentInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"user_id":{"type":"string","description":"Cột 'user_id' được sinh từ userId trong schema SQL Lab.","example":"user_001"},"course_id":{"type":"string","description":"Cột 'course_id' được sinh từ courseId trong schema SQL Lab.","example":"course_001"},"unlock_scope":{"type":"string","enum":["LESSON","CHAPTER","FULL"],"description":"Cột 'unlock_scope' được sinh từ unlockScope trong schema SQL Lab.","example":"LESSON"},"unlocked_chapters":{"type":"array","items":{"type":"string"},"description":"Cột 'unlocked_chapters' được sinh từ unlockedChapters trong schema SQL Lab.","example":["PostgreSQL","Postman"]},"unlocked_lessons":{"type":"array","items":{"type":"string"},"description":"Cột 'unlocked_lessons' được sinh từ unlockedLessons trong schema SQL Lab.","example":["PostgreSQL","Postman"]},"progress":{"type":"number","format":"double","minimum":0,"maximum":1,"description":"Cột 'progress' được sinh từ progress trong schema SQL Lab.","example":0.5}}},"CreateSubmissionInput":{"type":"object","additionalProperties":false,"properties":{"user_id":{"type":"string","description":"Cột 'user_id' được sinh từ userId trong schema SQL Lab.","example":"user_001"},"lesson_id":{"type":"string","description":"Cột 'lesson_id' được sinh từ lessonId trong schema SQL Lab.","example":"lesson_001"},"content":{"type":"string","description":"Cột 'content' được sinh từ content trong schema SQL Lab.","example":"Nội dung kiểm thử API"}},"required":["user_id","lesson_id","content"]},"UpdateSubmissionInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"user_id":{"type":"string","description":"Cột 'user_id' được sinh từ userId trong schema SQL Lab.","example":"user_001"},"lesson_id":{"type":"string","description":"Cột 'lesson_id' được sinh từ lessonId trong schema SQL Lab.","example":"lesson_001"},"content":{"type":"string","description":"Cột 'content' được sinh từ content trong schema SQL Lab.","example":"Nội dung kiểm thử API"}}},"CreateLessonProgressInput":{"type":"object","additionalProperties":false,"properties":{"user_id":{"type":"string","description":"Cột 'user_id' được sinh từ userId trong schema SQL Lab.","example":"user_001"},"lesson_id":{"type":"string","description":"Cột 'lesson_id' được sinh từ lessonId trong schema SQL Lab.","example":"lesson_001"},"course_id":{"type":"string","description":"Cột 'course_id' được sinh từ courseId trong schema SQL Lab.","example":"course_001"}},"required":["user_id","lesson_id","course_id"]},"UpdateLessonProgressInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"user_id":{"type":"string","description":"Cột 'user_id' được sinh từ userId trong schema SQL Lab.","example":"user_001"},"lesson_id":{"type":"string","description":"Cột 'lesson_id' được sinh từ lessonId trong schema SQL Lab.","example":"lesson_001"},"course_id":{"type":"string","description":"Cột 'course_id' được sinh từ courseId trong schema SQL Lab.","example":"course_001"}}},"CreateCourseCertificateInput":{"type":"object","additionalProperties":false,"properties":{"certificate_number":{"type":"string","description":"Cột 'certificate_number' được sinh từ certificateNumber trong schema SQL Lab.","example":"certificate_number_demo"},"user_id":{"type":"string","description":"Cột 'user_id' được sinh từ userId trong schema SQL Lab.","example":"user_001"},"course_id":{"type":"string","description":"Cột 'course_id' được sinh từ courseId trong schema SQL Lab.","example":"course_001"},"recipient_name_at_issue":{"type":"string","description":"Cột 'recipient_name_at_issue' được sinh từ recipientNameAtIssue trong schema SQL Lab.","example":"recipient_name_at_issue_demo"},"course_title_at_issue":{"type":"string","description":"Cột 'course_title_at_issue' được sinh từ courseTitleAtIssue trong schema SQL Lab.","example":"course_title_at_issue_demo"}},"required":["certificate_number","user_id","course_id","recipient_name_at_issue","course_title_at_issue"]},"UpdateCourseCertificateInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"certificate_number":{"type":"string","description":"Cột 'certificate_number' được sinh từ certificateNumber trong schema SQL Lab.","example":"certificate_number_demo"},"user_id":{"type":"string","description":"Cột 'user_id' được sinh từ userId trong schema SQL Lab.","example":"user_001"},"course_id":{"type":"string","description":"Cột 'course_id' được sinh từ courseId trong schema SQL Lab.","example":"course_001"},"recipient_name_at_issue":{"type":"string","description":"Cột 'recipient_name_at_issue' được sinh từ recipientNameAtIssue trong schema SQL Lab.","example":"recipient_name_at_issue_demo"},"course_title_at_issue":{"type":"string","description":"Cột 'course_title_at_issue' được sinh từ courseTitleAtIssue trong schema SQL Lab.","example":"course_title_at_issue_demo"}}},"CreateOrderInput":{"type":"object","additionalProperties":false,"properties":{"user_id":{"type":"string","description":"Cột 'user_id' được sinh từ userId trong schema SQL Lab.","example":"user_001"},"amount":{"type":"number","format":"double","minimum":0,"description":"Cột 'amount' được sinh từ amount trong schema SQL Lab.","example":100000},"sepay_ref":{"type":"string","description":"Cột 'sepay_ref' được sinh từ sepayRef trong schema SQL Lab.","example":"sepay_ref_demo","nullable":true}},"required":["user_id","amount"]},"UpdateOrderInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"user_id":{"type":"string","description":"Cột 'user_id' được sinh từ userId trong schema SQL Lab.","example":"user_001"},"amount":{"type":"number","format":"double","minimum":0,"description":"Cột 'amount' được sinh từ amount trong schema SQL Lab.","example":100000},"sepay_ref":{"type":"string","description":"Cột 'sepay_ref' được sinh từ sepayRef trong schema SQL Lab.","example":"sepay_ref_demo","nullable":true}}},"CreateOrderItemInput":{"type":"object","additionalProperties":false,"properties":{"order_id":{"type":"string","description":"Cột 'order_id' được sinh từ orderId trong schema SQL Lab.","example":"order_001"},"item_type":{"type":"string","enum":["COURSE","LESSON","PRO_UPGRADE","ORG_LICENSE"],"description":"Cột 'item_type' được sinh từ itemType trong schema SQL Lab.","example":"COURSE"},"course_id":{"type":"string","description":"Cột 'course_id' được sinh từ courseId trong schema SQL Lab.","example":"course_001","nullable":true},"lesson_id":{"type":"string","description":"Cột 'lesson_id' được sinh từ lessonId trong schema SQL Lab.","example":"lesson_001","nullable":true},"unlock_scope":{"type":"string","enum":["LESSON","CHAPTER","FULL"],"description":"Cột 'unlock_scope' được sinh từ unlockScope trong schema SQL Lab.","example":"LESSON"},"price":{"type":"number","format":"double","minimum":0,"description":"Cột 'price' được sinh từ price trong schema SQL Lab.","example":100000}},"required":["order_id","unlock_scope","price"]},"UpdateOrderItemInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"item_type":{"type":"string","enum":["COURSE","LESSON","PRO_UPGRADE","ORG_LICENSE"],"description":"Cột 'item_type' được sinh từ itemType trong schema SQL Lab.","example":"COURSE"},"course_id":{"type":"string","description":"Cột 'course_id' được sinh từ courseId trong schema SQL Lab.","example":"course_001","nullable":true},"lesson_id":{"type":"string","description":"Cột 'lesson_id' được sinh từ lessonId trong schema SQL Lab.","example":"lesson_001","nullable":true},"unlock_scope":{"type":"string","enum":["LESSON","CHAPTER","FULL"],"description":"Cột 'unlock_scope' được sinh từ unlockScope trong schema SQL Lab.","example":"LESSON"},"price":{"type":"number","format":"double","minimum":0,"description":"Cột 'price' được sinh từ price trong schema SQL Lab.","example":100000}}},"CreatePaymentLogInput":{"type":"object","additionalProperties":false,"properties":{"sepay_id":{"type":"string","description":"Cột 'sepay_id' được sinh từ sepayId trong schema SQL Lab.","example":"sepay_001"},"amount_in":{"type":"number","format":"double","minimum":0,"description":"Cột 'amount_in' được sinh từ amountIn trong schema SQL Lab.","example":100000},"content":{"type":"string","description":"Cột 'content' được sinh từ content trong schema SQL Lab.","example":"Nội dung kiểm thử API"},"raw_payload":{"type":"object","additionalProperties":true,"description":"Cột 'raw_payload' được sinh từ rawPayload trong schema SQL Lab.","example":{}},"related_order_id":{"type":"string","description":"Cột 'related_order_id' được sinh từ relatedOrderId trong schema SQL Lab.","example":"related_order_001","nullable":true},"related_user_id":{"type":"string","description":"Cột 'related_user_id' được sinh từ relatedUserId trong schema SQL Lab.","example":"related_user_001","nullable":true}},"required":["sepay_id","amount_in","content","raw_payload"]},"UpdatePaymentLogInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"sepay_id":{"type":"string","description":"Cột 'sepay_id' được sinh từ sepayId trong schema SQL Lab.","example":"sepay_001"},"amount_in":{"type":"number","format":"double","minimum":0,"description":"Cột 'amount_in' được sinh từ amountIn trong schema SQL Lab.","example":100000},"content":{"type":"string","description":"Cột 'content' được sinh từ content trong schema SQL Lab.","example":"Nội dung kiểm thử API"},"raw_payload":{"type":"object","additionalProperties":true,"description":"Cột 'raw_payload' được sinh từ rawPayload trong schema SQL Lab.","example":{}},"related_order_id":{"type":"string","description":"Cột 'related_order_id' được sinh từ relatedOrderId trong schema SQL Lab.","example":"related_order_001","nullable":true},"related_user_id":{"type":"string","description":"Cột 'related_user_id' được sinh từ relatedUserId trong schema SQL Lab.","example":"related_user_001","nullable":true}}},"CreateWalletTransactionInput":{"type":"object","additionalProperties":false,"properties":{"user_id":{"type":"string","description":"Cột 'user_id' được sinh từ userId trong schema SQL Lab.","example":"user_001"},"type":{"type":"string","enum":["DEPOSIT","PURCHASE","REFUND","AI_GRADING","EDU_WELCOME_BONUS","ADMIN_ADJUSTMENT"],"description":"Cột 'type' được sinh từ type trong schema SQL Lab.","example":"DEPOSIT"},"amount":{"type":"number","format":"double","minimum":0,"description":"Cột 'amount' được sinh từ amount trong schema SQL Lab.","example":100000},"balance_before":{"type":"number","format":"double","description":"Cột 'balance_before' được sinh từ balanceBefore trong schema SQL Lab.","example":1},"balance_after":{"type":"number","format":"double","description":"Cột 'balance_after' được sinh từ balanceAfter trong schema SQL Lab.","example":1},"description":{"type":"string","description":"Cột 'description' được sinh từ description trong schema SQL Lab.","example":"Mô tả dùng trong môi trường thực hành.","nullable":true},"related_order_id":{"type":"string","description":"Cột 'related_order_id' được sinh từ relatedOrderId trong schema SQL Lab.","example":"related_order_001","nullable":true},"related_payment_log_id":{"type":"string","description":"Cột 'related_payment_log_id' được sinh từ relatedPaymentLogId trong schema SQL Lab.","example":"related_payment_log_001","nullable":true}},"required":["user_id","type","amount","balance_before","balance_after"]},"UpdateWalletTransactionInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"user_id":{"type":"string","description":"Cột 'user_id' được sinh từ userId trong schema SQL Lab.","example":"user_001"},"type":{"type":"string","enum":["DEPOSIT","PURCHASE","REFUND","AI_GRADING","EDU_WELCOME_BONUS","ADMIN_ADJUSTMENT"],"description":"Cột 'type' được sinh từ type trong schema SQL Lab.","example":"DEPOSIT"},"amount":{"type":"number","format":"double","minimum":0,"description":"Cột 'amount' được sinh từ amount trong schema SQL Lab.","example":100000},"balance_before":{"type":"number","format":"double","description":"Cột 'balance_before' được sinh từ balanceBefore trong schema SQL Lab.","example":1},"balance_after":{"type":"number","format":"double","description":"Cột 'balance_after' được sinh từ balanceAfter trong schema SQL Lab.","example":1},"description":{"type":"string","description":"Cột 'description' được sinh từ description trong schema SQL Lab.","example":"Mô tả dùng trong môi trường thực hành.","nullable":true},"related_order_id":{"type":"string","description":"Cột 'related_order_id' được sinh từ relatedOrderId trong schema SQL Lab.","example":"related_order_001","nullable":true},"related_payment_log_id":{"type":"string","description":"Cột 'related_payment_log_id' được sinh từ relatedPaymentLogId trong schema SQL Lab.","example":"related_payment_log_001","nullable":true}}},"CreateSpendXPLogInput":{"type":"object","additionalProperties":false,"properties":{"user_id":{"type":"string","description":"Cột 'user_id' được sinh từ userId trong schema SQL Lab.","example":"user_001"},"amount":{"type":"number","format":"double","minimum":0,"description":"Cột 'amount' được sinh từ amount trong schema SQL Lab.","example":100000},"xp_earned":{"type":"number","format":"double","description":"Cột 'xp_earned' được sinh từ xpEarned trong schema SQL Lab.","example":1},"related_order_id":{"type":"string","description":"Cột 'related_order_id' được sinh từ relatedOrderId trong schema SQL Lab.","example":"related_order_001","nullable":true},"related_wallet_transaction_id":{"type":"string","description":"Cột 'related_wallet_transaction_id' được sinh từ relatedWalletTransactionId trong schema SQL Lab.","example":"related_wallet_transaction_001","nullable":true}},"required":["user_id","amount","xp_earned"]},"UpdateSpendXPLogInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"user_id":{"type":"string","description":"Cột 'user_id' được sinh từ userId trong schema SQL Lab.","example":"user_001"},"amount":{"type":"number","format":"double","minimum":0,"description":"Cột 'amount' được sinh từ amount trong schema SQL Lab.","example":100000},"xp_earned":{"type":"number","format":"double","description":"Cột 'xp_earned' được sinh từ xpEarned trong schema SQL Lab.","example":1},"related_order_id":{"type":"string","description":"Cột 'related_order_id' được sinh từ relatedOrderId trong schema SQL Lab.","example":"related_order_001","nullable":true},"related_wallet_transaction_id":{"type":"string","description":"Cột 'related_wallet_transaction_id' được sinh từ relatedWalletTransactionId trong schema SQL Lab.","example":"related_wallet_transaction_001","nullable":true}}},"CreateSpendXPRewardInput":{"type":"object","additionalProperties":false,"properties":{"user_id":{"type":"string","description":"Cột 'user_id' được sinh từ userId trong schema SQL Lab.","example":"user_001"},"milestone_key":{"type":"string","description":"Cột 'milestone_key' được sinh từ milestoneKey trong schema SQL Lab.","example":"milestone_key_demo"},"reward_type":{"type":"string","description":"Cột 'reward_type' được sinh từ rewardType trong schema SQL Lab.","example":"reward_type_demo"},"reward_qty":{"type":"integer","description":"Cột 'reward_qty' được sinh từ rewardQty trong schema SQL Lab.","example":1}},"required":["user_id","milestone_key","reward_type"]},"UpdateSpendXPRewardInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"user_id":{"type":"string","description":"Cột 'user_id' được sinh từ userId trong schema SQL Lab.","example":"user_001"},"milestone_key":{"type":"string","description":"Cột 'milestone_key' được sinh từ milestoneKey trong schema SQL Lab.","example":"milestone_key_demo"},"reward_type":{"type":"string","description":"Cột 'reward_type' được sinh từ rewardType trong schema SQL Lab.","example":"reward_type_demo"},"reward_qty":{"type":"integer","description":"Cột 'reward_qty' được sinh từ rewardQty trong schema SQL Lab.","example":1}}},"CreateBlogInput":{"type":"object","additionalProperties":false,"properties":{"title":{"type":"string","description":"Cột 'title' được sinh từ title trong schema SQL Lab.","example":"Nội dung thực hành"},"slug":{"type":"string","description":"Cột 'slug' được sinh từ slug trong schema SQL Lab.","example":"du-lieu-demo"},"excerpt":{"type":"string","description":"Cột 'excerpt' được sinh từ excerpt trong schema SQL Lab.","example":"excerpt_demo","nullable":true},"content":{"type":"string","description":"Cột 'content' được sinh từ content trong schema SQL Lab.","example":"Nội dung kiểm thử API"}},"required":["title","slug","content"]},"UpdateBlogInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"title":{"type":"string","description":"Cột 'title' được sinh từ title trong schema SQL Lab.","example":"Nội dung thực hành"},"slug":{"type":"string","description":"Cột 'slug' được sinh từ slug trong schema SQL Lab.","example":"du-lieu-demo"},"excerpt":{"type":"string","description":"Cột 'excerpt' được sinh từ excerpt trong schema SQL Lab.","example":"excerpt_demo","nullable":true},"content":{"type":"string","description":"Cột 'content' được sinh từ content trong schema SQL Lab.","example":"Nội dung kiểm thử API"}}},"CreateTagInput":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","description":"Cột 'name' được sinh từ name trong schema SQL Lab.","example":"Nguyễn Minh Anh"},"slug":{"type":"string","description":"Cột 'slug' được sinh từ slug trong schema SQL Lab.","example":"du-lieu-demo"},"desc":{"type":"string","description":"Cột 'desc' được sinh từ desc trong schema SQL Lab.","example":"desc_demo","nullable":true}},"required":["name","slug"]},"UpdateTagInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"name":{"type":"string","description":"Cột 'name' được sinh từ name trong schema SQL Lab.","example":"Nguyễn Minh Anh"},"slug":{"type":"string","description":"Cột 'slug' được sinh từ slug trong schema SQL Lab.","example":"du-lieu-demo"},"desc":{"type":"string","description":"Cột 'desc' được sinh từ desc trong schema SQL Lab.","example":"desc_demo","nullable":true}}},"CreateBlogTagInput":{"type":"object","additionalProperties":false,"properties":{"blog_id":{"type":"string","description":"Cột 'blog_id' được sinh từ blogId trong schema SQL Lab.","example":"blog_001"},"tag_id":{"type":"string","description":"Cột 'tag_id' được sinh từ tagId trong schema SQL Lab.","example":"tag_001"}},"required":["blog_id","tag_id"]},"UpdateBlogTagInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"blog_id":{"type":"string","description":"Cột 'blog_id' được sinh từ blogId trong schema SQL Lab.","example":"blog_001"},"tag_id":{"type":"string","description":"Cột 'tag_id' được sinh từ tagId trong schema SQL Lab.","example":"tag_001"}}},"CreateCommentInput":{"type":"object","additionalProperties":false,"properties":{"blog_id":{"type":"string","description":"Cột 'blog_id' được sinh từ blogId trong schema SQL Lab.","example":"blog_001"},"user_id":{"type":"string","description":"Cột 'user_id' được sinh từ userId trong schema SQL Lab.","example":"user_001"},"content":{"type":"string","description":"Cột 'content' được sinh từ content trong schema SQL Lab.","example":"Nội dung kiểm thử API"},"parent_id":{"type":"string","description":"Cột 'parent_id' được sinh từ parentId trong schema SQL Lab.","example":"parent_001","nullable":true}},"required":["blog_id","user_id","content"]},"UpdateCommentInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"blog_id":{"type":"string","description":"Cột 'blog_id' được sinh từ blogId trong schema SQL Lab.","example":"blog_001"},"user_id":{"type":"string","description":"Cột 'user_id' được sinh từ userId trong schema SQL Lab.","example":"user_001"},"content":{"type":"string","description":"Cột 'content' được sinh từ content trong schema SQL Lab.","example":"Nội dung kiểm thử API"},"parent_id":{"type":"string","description":"Cột 'parent_id' được sinh từ parentId trong schema SQL Lab.","example":"parent_001","nullable":true}}},"CreateUserViewInput":{"type":"object","additionalProperties":false,"properties":{"blog_id":{"type":"string","description":"Cột 'blog_id' được sinh từ blogId trong schema SQL Lab.","example":"blog_001"},"user_id":{"type":"string","description":"Cột 'user_id' được sinh từ userId trong schema SQL Lab.","example":"user_001"}},"required":["blog_id","user_id"]},"UpdateUserViewInput":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"blog_id":{"type":"string","description":"Cột 'blog_id' được sinh từ blogId trong schema SQL Lab.","example":"blog_001"},"user_id":{"type":"string","description":"Cột 'user_id' được sinh từ userId trong schema SQL Lab.","example":"user_001"}}},"ReviewSubmissionInput":{"type":"object","additionalProperties":false,"required":["status"],"properties":{"status":{"type":"string","enum":["PENDING","APPROVED","WRONG","MISSING"],"example":"APPROVED","description":"Trạng thái đánh giá mới của bài nộp."}}},"AdjustWalletInput":{"type":"object","additionalProperties":false,"required":["direction","bucket","amount","reason"],"properties":{"direction":{"type":"string","enum":["CREDIT","DEBIT"],"example":"CREDIT","description":"CREDIT để cộng tiền, DEBIT để trừ tiền."},"bucket":{"type":"string","enum":["REAL","BONUS"],"example":"REAL","description":"Nguồn số dư quản trị muốn điều chỉnh."},"amount":{"type":"number","format":"double","minimum":0.01,"example":50000,"description":"Giá trị dương; chiều thay đổi nằm ở direction."},"reason":{"type":"string","minLength":3,"maxLength":300,"example":"Hỗ trợ người dùng theo ticket DEMO-001","description":"Lý do bắt buộc để ghi vào wallet ledger."}}},"UpsertEnrollmentInput":{"type":"object","additionalProperties":false,"required":["user_id","course_id"],"properties":{"user_id":{"type":"string","example":"usr_001"},"course_id":{"type":"string","example":"course_001"},"unlock_scope":{"type":"string","enum":["LESSON","CHAPTER","FULL"],"default":"CHAPTER"},"unlocked_chapters":{"type":"array","items":{"type":"string"},"example":["chapter_001"]},"unlocked_lessons":{"type":"array","items":{"type":"string"},"example":["lesson_001"]},"progress":{"type":"number","minimum":0,"maximum":1,"default":0,"example":0.5}}},"CompleteLessonInput":{"type":"object","additionalProperties":false,"required":["user_id","lesson_id","course_id"],"properties":{"user_id":{"type":"string","example":"usr_001"},"lesson_id":{"type":"string","example":"lesson_001"},"course_id":{"type":"string","example":"course_001"}}},"IssueCertificateInput":{"type":"object","additionalProperties":false,"required":["user_id","course_id"],"properties":{"user_id":{"type":"string","example":"usr_001"},"course_id":{"type":"string","example":"course_001"},"certificate_number":{"type":"string","example":"T5LAB-DEMO-001"},"recipient_name":{"type":"string","example":"Nguyễn Minh Anh"}}},"RecordPaymentInput":{"type":"object","additionalProperties":false,"required":["sepay_id","amount_in","content"],"properties":{"sepay_id":{"type":"string","example":"SEPAY-DEMO-001"},"amount_in":{"type":"number","minimum":0.01,"example":490000},"content":{"type":"string","example":"Thanh toan order_001"},"raw_payload":{"type":"object","additionalProperties":true,"example":{"gateway":"demo"}},"related_order_id":{"type":"string","example":"order_001"},"related_user_id":{"type":"string","example":"usr_001"}}},"RecordUserViewInput":{"type":"object","additionalProperties":false,"required":["user_id","blog_id"],"properties":{"user_id":{"type":"string","example":"usr_001"},"blog_id":{"type":"string","example":"blog_001"}}},"AwardSpendXpInput":{"type":"object","additionalProperties":false,"required":["user_id","amount","xp_earned"],"properties":{"user_id":{"type":"string","example":"usr_001"},"amount":{"type":"number","minimum":0.01,"example":100000},"xp_earned":{"type":"number","minimum":0.01,"example":100},"related_order_id":{"type":"string","example":"order_001"},"related_wallet_transaction_id":{"type":"string","example":"wallet_001"}}},"RedeemSpendXpInput":{"type":"object","additionalProperties":false,"required":["user_id","milestone_key","reward_type","reward_qty"],"properties":{"user_id":{"type":"string","example":"usr_001"},"milestone_key":{"type":"string","example":"LIFETIME_100K"},"reward_type":{"type":"string","example":"AI_GRADE_FREE"},"reward_qty":{"type":"integer","minimum":1,"example":1}}}}}}