{"openapi":"3.0.0","info":{"title":"InCar API","description":"InCar (GoGo Driving) marketplace and in-car training API for Alberta/Ontario. Machine-readable OpenAPI for AI agents and crawlers: GET /openapi.json or GET /swagger.json. Human docs: /api-docs. Discovery: /llms.txt and /.well-known/api-catalog.","version":"1.1.0","contact":{"name":"InCar API","url":"https://incar.roshsur.com"}},"paths":{"/auth/register":{"post":{"tags":["Auth"],"summary":"Register user","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","firstname","lastname","is_instructor"],"properties":{"email":{"type":"string","format":"email"},"firstname":{"type":"string"},"lastname":{"type":"string"},"is_instructor":{"type":"integer","minimum":0,"maximum":1}},"example":{"email":"john.doe@example.com","firstname":"John","lastname":"Doe","is_instructor":0}}}}},"responses":{"200":{"description":"Registration successful"},"400":{"description":"Validation failed"}}}},"/auth/enableUser":{"post":{"tags":["Auth"],"summary":"Enable user account","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["password"],"properties":{"password":{"type":"string"}},"example":{"password":"StrongPassword123!"}}}}},"responses":{"200":{"description":"User enabled successfully"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized request"}}}},"/auth/login":{"post":{"tags":["Auth"],"summary":"Login user","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string"},"g-recaptcha-response":{"type":"string","description":"Required only after multiple failed attempts from same IP"}},"example":{"email":"waqas.iqbal@phenologix.com","password":"Muhammad@123"}}}}},"responses":{"200":{"description":"Login successful"},"400":{"description":"Validation failed or invalid credentials"},"401":{"description":"Unauthorized"}}}},"/auth/forget-password":{"post":{"tags":["Auth"],"summary":"Send forgot password email","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"}},"example":{"email":"john.doe@example.com"}}}}},"responses":{"200":{"description":"Request processed successfully"},"400":{"description":"Validation failed"}}}},"/auth/resendEmail":{"post":{"tags":["Auth"],"summary":"Resend verification email","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"}},"example":{"email":"john.doe@example.com"}}}}},"responses":{"200":{"description":"Verification email sent"},"400":{"description":"Validation failed"}}}},"/users/get/{id}":{"get":{"tags":["Users"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/userSuccessSchema"}}}}}}},"/users/logout":{"get":{"tags":["Users"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"boolean"},"msg":{"type":"string"},"data":{"type":null}},"example":{"error":false,"msg":"success","data":null}}}}}}}},"/users/getAll":{"get":{"tags":["Users"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"keyword","in":"query","schema":{"type":"string"}},{"name":"roles","in":"query","schema":{"type":"array","items":{"type":"integer","format":"int32"}},"style":"form","explode":true},{"name":"status","in":"query","schema":{"type":"integer","format":"int32","enum":[0,1,2]}},{"name":"orderByCol","in":"query","schema":{"type":"string","enum":["id","created_at","updated_at","firstname","lastname","middlename","email","cnic","phone","role_id","status","is_instructor"]}},{"name":"orderDirection","in":"query","schema":{"type":"string","enum":["DESC","ASC"]}},{"name":"page","in":"query","required":true,"schema":{"minimum":1,"type":"integer","format":"int32"}},{"name":"pageSize","in":"query","required":true,"schema":{"maximum":100,"minimum":1,"type":"integer","format":"int32"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/usersSuccessSchema"}}}}}}},"/users/update":{"put":{"tags":["Users"],"security":[{"bearerAuth":[]}],"summary":"User profile update","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/updateUserSchema"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/userSuccessSchema"}}}},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"}}}},"/users/updateStatus":{"put":{"tags":["Users"],"security":[{"bearerAuth":[]}],"summary":"User status update","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"integer"},"status":{"type":"integer","description":"0: Inactive, 1: Active, 2: Disabled","minimum":0,"maximum":2}},"required":["id","status"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"boolean","example":false},"msg":{"type":"string","example":"Status updated successfully"},"result":{"type":"object","nullable":true}}}}}},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"}}}},"/users/create":{"post":{"tags":["Users"],"security":[{"bearerAuth":[]}],"summary":"Invite a new user (sends registration email)","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/inviteUserSchema"}}}},"responses":{"200":{"description":"User invited and registration email sent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/userSuccessSchema"}}}},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"}}}},"/users/changePassword":{"put":{"tags":["Users"],"security":[{"bearerAuth":[]}],"summary":"Change user password","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["old_password","new_password"],"properties":{"old_password":{"type":"string"},"new_password":{"type":"string"}}}}}},"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"}}}},"/file/create":{"post":{"tags":["Files"],"security":[{"bearerAuth":[]}],"summary":"Create new file","requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"array","items":{"type":"string","format":"binary"}}}},"encoding":{"file":{"style":"form"}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/fileSuccessSchema"}}}},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"}}}},"/role/create":{"post":{"tags":["Roles"],"security":[{"bearerAuth":[]}],"summary":"Create new role","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"status":{"type":"integer","enum":[0,1]},"permissions":{"type":"array","items":{"type":"integer"}}},"required":["name","status","permissions","role_type"]}}}},"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"}}}},"/role/getAll":{"get":{"tags":["Roles"],"security":[{"bearerAuth":[]}],"summary":"Get all roles","parameters":[{"name":"keyword","in":"query","schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"integer"}},{"name":"page","in":"query","required":true,"schema":{"type":"integer"}},{"name":"pageSize","in":"query","required":true,"schema":{"type":"integer"}},{"name":"orderByCol","in":"query","schema":{"type":"string","enum":["id","name","description","status"]}},{"name":"orderDirection","in":"query","schema":{"type":"string","enum":["ASC","DESC","asc","desc"]}}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"}}}},"/role/getAllPermissions":{"get":{"tags":["Roles"],"security":[{"bearerAuth":[]}],"summary":"Get all permissions","responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"}}}},"/role/get/{id}":{"get":{"tags":["Roles"],"security":[{"bearerAuth":[]}],"summary":"Get role by ID","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"}}}},"/role/delete/{id}":{"delete":{"tags":["Roles"],"security":[{"bearerAuth":[]}],"summary":"Delete role by ID","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"}}}},"/role/update":{"put":{"tags":["Roles"],"security":[{"bearerAuth":[]}],"summary":"Update role","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"description":{"type":"string"},"status":{"type":"integer","enum":[0,1]},"permissions":{"type":"array","items":{"type":"integer"}}},"required":["id","name","status","permissions","role_type"]}}}},"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"}}}},"/world/getCountries":{"get":{"tags":["World"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/worldSuccessSchema"}}}}}}},"/world/getStatesByCountryId/{id}":{"get":{"tags":["World"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/worldSuccessSchema"}}}}}}},"/world/getCitiesByStateId/{id}":{"get":{"tags":["World"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/worldSuccessSchema"}}}}}}},"/world/getCitiesByStateIds":{"get":{"tags":["World"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"state_ids","in":"query","required":true,"schema":{"type":"array","items":{"type":"integer","format":"int32"},"example":[1,2]}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/worldSuccessSchema"}}}}}}},"/setting/getAll":{"get":{"tags":["Settings"],"security":[{"bearerAuth":[]}],"summary":"Get paginated settings","parameters":[{"name":"keyword","in":"query","schema":{"type":"string"}},{"name":"type","in":"query","schema":{"type":"string"}},{"name":"name","in":"query","schema":{"type":"string"}},{"name":"val","in":"query","schema":{"type":"string"}},{"name":"orderByCol","in":"query","schema":{"type":"string","enum":["type","name","val"]}},{"name":"orderDirection","in":"query","schema":{"type":"string","enum":["ASC","asc","DESC","desc"]}},{"name":"page","in":"query","required":true,"schema":{"type":"integer","minimum":1}},{"name":"pageSize","in":"query","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/settingsListSuccessSchema"}}}},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"}}}},"/setting/get/{id}":{"get":{"tags":["Settings"],"security":[{"bearerAuth":[]}],"summary":"Get setting by ID","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/settingSuccessSchema"}}}},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"}}}},"/setting/getSetting/{type}":{"get":{"tags":["Settings"],"security":[{"bearerAuth":[]}],"summary":"Get settings by type","parameters":[{"name":"type","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/settingsByTypeSuccessSchema"}}}},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"}}}},"/setting/update":{"put":{"tags":["Settings"],"security":[{"bearerAuth":[]}],"summary":"Bulk update settings","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/settingPayloadSchema"}}}}},"responses":{"200":{"description":"Settings updated successfully"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"}}}},"/setting/create":{"post":{"tags":["Settings"],"security":[{"bearerAuth":[]}],"summary":"Bulk create settings","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/newSettingPayloadSchema"}}}}},"responses":{"200":{"description":"Settings created successfully"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"}}}},"/language/create":{"post":{"tags":["Languages"],"security":[{"bearerAuth":[]}],"summary":"Create language","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/languageCreateBodySchema"}}}},"responses":{"200":{"description":"Language created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/languageSingleSuccessSchema"}}}},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"},"500":{"description":"Internal server error"}}}},"/language/getAll":{"get":{"tags":["Languages"],"security":[{"bearerAuth":[]}],"summary":"List languages (paginated)","parameters":[{"name":"keyword","in":"query","schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"integer"}},{"name":"page","in":"query","required":true,"schema":{"type":"integer","minimum":1}},{"name":"pageSize","in":"query","required":true,"schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"orderByCol","in":"query","schema":{"type":"string","enum":["id","name","shortname","status","created_at","updated_at"]}},{"name":"orderDirection","in":"query","schema":{"type":"string","enum":["ASC","DESC","asc","desc"]}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/languageListSuccessSchema"}}}},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"},"500":{"description":"Internal server error"}}}},"/language/update":{"put":{"tags":["Languages"],"security":[{"bearerAuth":[]}],"summary":"Update language","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/languageUpdateBodySchema"}}}},"responses":{"200":{"description":"Language updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/languageSingleSuccessSchema"}}}},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"},"404":{"description":"Language not found"},"500":{"description":"Internal server error"}}}},"/language/updateStatus":{"put":{"tags":["Languages"],"security":[{"bearerAuth":[]}],"summary":"Update language status","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/languageUpdateStatusBodySchema"}}}},"responses":{"200":{"description":"Status updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/languageSingleSuccessSchema"}}}},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"},"404":{"description":"Language not found"},"500":{"description":"Internal server error"}}}},"/langRecord/create":{"post":{"tags":["LangRecords"],"security":[{"bearerAuth":[]}],"summary":"Create lang record with items","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/langRecordCreateBodySchema"}}}},"responses":{"200":{"description":"Lang record created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/langRecordSingleSuccessSchema"}}}},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"},"404":{"description":"Related school/language not found"},"500":{"description":"Internal server error"}}}},"/langRecord/getAll":{"get":{"tags":["LangRecords"],"security":[{"bearerAuth":[]}],"summary":"List lang records (paginated)","parameters":[{"name":"keyword","in":"query","schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"integer"}},{"name":"school_id","in":"query","schema":{"type":"integer","minimum":1}},{"name":"type","in":"query","schema":{"type":"string"}},{"name":"page","in":"query","required":true,"schema":{"type":"integer","minimum":1}},{"name":"pageSize","in":"query","required":true,"schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"orderByCol","in":"query","schema":{"type":"string","enum":["id","name","type","status","school_id","created_at","updated_at"]}},{"name":"orderDirection","in":"query","schema":{"type":"string","enum":["ASC","DESC","asc","desc"]}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/langRecordListSuccessSchema"}}}},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"},"500":{"description":"Internal server error"}}}},"/langRecord/get/{id}":{"get":{"tags":["LangRecords"],"security":[{"bearerAuth":[]}],"summary":"Get lang record by ID","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/langRecordSingleSuccessSchema"}}}},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"},"404":{"description":"Lang record not found"},"500":{"description":"Internal server error"}}}},"/langRecord/update":{"put":{"tags":["LangRecords"],"security":[{"bearerAuth":[]}],"summary":"Update lang record and replace items","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/langRecordUpdateBodySchema"}}}},"responses":{"200":{"description":"Lang record updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/langRecordSingleSuccessSchema"}}}},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"},"404":{"description":"Lang record/school/language not found"},"500":{"description":"Internal server error"}}}},"/locations/setStatus":{"put":{"tags":["Locations"],"summary":"Set location active status","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoSetStatusBodySchema"}}}},"responses":{"200":{"description":"Status updated"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/products/getAll":{"get":{"deprecated":true,"tags":["Products"],"summary":"List products (deprecated â€” use GET /courses/getAll)","description":"Deprecated legacy alias. Operates on the courses table. Prefer GET /courses/getAll.","security":[{"bearerAuth":[]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"keyword","in":"query","schema":{"type":"string","maxLength":255}},{"name":"orderBy","in":"query","schema":{"type":"string","enum":["id","name","description","type","price","isActive","createdAt","updatedAt","locationId"]}},{"name":"orderDirection","in":"query","schema":{"type":"string","enum":["asc","desc","ASC","DESC"],"default":"desc"}},{"name":"location_id","in":"query","schema":{"type":"integer","minimum":1},"description":"Filter by location"}],"responses":{"200":{"description":"Paginated list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoPaginatedListSchema"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/products/create":{"post":{"deprecated":true,"tags":["Products"],"summary":"Create product (deprecated â€” use POST /courses/create)","description":"Deprecated legacy alias. Creates a course record. Prefer POST /courses/create.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/productCreateBodySchema"}}}},"responses":{"201":{"description":"Product created"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/products/get/{id}":{"get":{"deprecated":true,"tags":["Products"],"summary":"Get product by ID (deprecated â€” use GET /courses/get/{id})","description":"Deprecated legacy alias. Returns a course record. Prefer GET /courses/get/{id}.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Record ID","schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}],"responses":{"200":{"description":"Product"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/products/update":{"put":{"deprecated":true,"tags":["Products"],"summary":"Update product (deprecated â€” use PUT /courses/update)","description":"Deprecated legacy alias. Updates a course record. Prefer PUT /courses/update.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/productUpdateBodySchema"}}}},"responses":{"200":{"description":"Product updated"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/products/setStatus":{"put":{"deprecated":true,"tags":["Products"],"summary":"Set product active status (deprecated â€” use PUT /courses/setStatus)","description":"Deprecated legacy alias. Maps is_active to course status. Prefer PUT /courses/setStatus with status 0 or 1.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoSetStatusBodySchema"}}}},"responses":{"200":{"description":"Status updated"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/products/delete/{id}":{"delete":{"deprecated":true,"tags":["Products"],"summary":"Delete product (deprecated â€” use DELETE /courses/delete/{id})","description":"Deprecated legacy alias. Soft-deletes a course record. Prefer DELETE /courses/delete/{id}.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Record ID","schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}],"responses":{"200":{"description":"Product deleted"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/packages/getAll":{"get":{"tags":["Packages"],"summary":"List packages","security":[{"bearerAuth":[]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"keyword","in":"query","schema":{"type":"string","maxLength":255}},{"name":"orderBy","in":"query","schema":{"type":"string","enum":["id","name","description","actualPrice","effectedPrice","createdAt","updatedAt","locationId"]}},{"name":"orderDirection","in":"query","schema":{"type":"string","enum":["asc","desc","ASC","DESC"],"default":"desc"}}],"responses":{"200":{"description":"Paginated list","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/legacyApiResponseSchema"},{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/packageItemSchema"}},"total":{"type":"integer"},"page":{"type":"integer"},"pageSize":{"type":"integer"}}}}}]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/packages/create":{"post":{"tags":["Packages"],"summary":"Create package","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/packageCreateBodySchema"}}}},"responses":{"201":{"description":"Package created"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/packages/get/{id}":{"get":{"tags":["Packages"],"summary":"Get package by ID","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Record ID","schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}],"responses":{"200":{"description":"Package"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/packages/update":{"put":{"tags":["Packages"],"summary":"Update package","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/packageUpdateBodySchema"}}}},"responses":{"200":{"description":"Package updated"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/packages/delete/{id}":{"delete":{"tags":["Packages"],"summary":"Delete package","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Record ID","schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}],"responses":{"200":{"description":"Package deleted"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/features/getAll":{"get":{"tags":["Features"],"summary":"List features","security":[{"bearerAuth":[]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"keyword","in":"query","schema":{"type":"string","maxLength":255}},{"name":"orderBy","in":"query","schema":{"type":"string","enum":["id","packageId","service","isEnabled","status","createdAt","updatedAt"]}},{"name":"orderDirection","in":"query","schema":{"type":"string","enum":["asc","desc","ASC","DESC"],"default":"desc"}}],"responses":{"200":{"description":"Paginated list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoPaginatedListSchema"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/features/create":{"post":{"tags":["Features"],"summary":"Create feature","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/featureCreateBodySchema"}}}},"responses":{"201":{"description":"Feature created"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/features/get/{id}":{"get":{"tags":["Features"],"summary":"Get feature by ID","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Record ID","schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}],"responses":{"200":{"description":"Feature"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/features/update":{"put":{"tags":["Features"],"summary":"Update feature","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/featureUpdateBodySchema"}}}},"responses":{"200":{"description":"Feature updated"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/features/delete/{id}":{"delete":{"tags":["Features"],"summary":"Delete feature","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Record ID","schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}],"responses":{"200":{"description":"Feature deleted"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/transactions/getAll":{"get":{"tags":["Transactions"],"summary":"List transactions","security":[{"bearerAuth":[]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"keyword","in":"query","schema":{"type":"string","maxLength":255}},{"name":"orderBy","in":"query","schema":{"type":"string","enum":["id","fullName","email","packageName","courseName","amount","status","paidAt","createdAt"]}},{"name":"orderDirection","in":"query","schema":{"type":"string","enum":["asc","desc","ASC","DESC"],"default":"desc"}},{"name":"status","in":"query","schema":{"type":"string","enum":["pending","paid","failed","expired","cancelled"]}}],"responses":{"200":{"description":"Paginated transactions","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/legacyApiResponseSchema"},{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/transactionItemSchema"}},"total":{"type":"integer"},"page":{"type":"integer"},"pageSize":{"type":"integer"}}}}}]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/enrollments/getMine":{"get":{"tags":["Enrollments"],"summary":"List my enrolled courses","description":"Returns paginated enrollments for the authenticated user. Defaults to active enrollments only.","security":[{"bearerAuth":[]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"keyword","in":"query","schema":{"type":"string","maxLength":255}},{"name":"activeOnly","in":"query","schema":{"type":"boolean","default":true},"description":"When true, only enrollments active today (status active and within start/end dates)."},{"name":"orderBy","in":"query","schema":{"type":"string","enum":["id","courseName","packageName","startDate","endDate","source","status","createdAt"],"default":"startDate"}},{"name":"orderDirection","in":"query","schema":{"type":"string","enum":["asc","desc","ASC","DESC"],"default":"DESC"}}],"responses":{"200":{"description":"Paginated enrollments for current user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/enrollmentListResponseSchema"}}}},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"500":{"description":"Internal server error"}}}},"/enrollments/getAll":{"get":{"tags":["Enrollments"],"summary":"List all enrollments (admin)","description":"Requires permission enrollments.getAll.","security":[{"bearerAuth":[]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"keyword","in":"query","schema":{"type":"string","maxLength":255}},{"name":"user_id","in":"query","schema":{"type":"integer","minimum":1},"description":"Filter by user id"},{"name":"course_id","in":"query","schema":{"type":"integer","minimum":1},"description":"Filter by course id"},{"name":"status","in":"query","schema":{"type":"string","enum":["active","suspended","inactive"]}},{"name":"activeOnly","in":"query","schema":{"type":"boolean","default":false}},{"name":"orderBy","in":"query","schema":{"type":"string","enum":["id","userFullName","userEmail","courseName","packageName","startDate","endDate","source","status","createdAt"],"default":"id"}},{"name":"orderDirection","in":"query","schema":{"type":"string","enum":["asc","desc","ASC","DESC"],"default":"DESC"}}],"responses":{"200":{"description":"Paginated enrollments","content":{"application/json":{"schema":{"$ref":"#/components/schemas/enrollmentListResponseSchema"}}}},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"},"500":{"description":"Internal server error"}}}},"/enrollments/create":{"post":{"tags":["Enrollments"],"summary":"Create enrollment (admin)","description":"Enroll a user in a course or all courses in a package without payment. Requires permission enrollments.create. Provide either course_id or package_id.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/enrollmentCreateBodySchema"}}}},"responses":{"201":{"description":"Enrollment created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/enrollmentCreateResponseSchema"}}}},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"},"404":{"description":"User, course, or package not found"},"409":{"description":"User already has an active enrollment for this course"},"500":{"description":"Internal server error"}}}},"/enrollments/update":{"put":{"tags":["Enrollments"],"summary":"Update enrollment (admin)","description":"Suspend, inactivate, reactivate, or adjust enrollment dates. Requires permission enrollments.update.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/enrollmentUpdateBodySchema"}}}},"responses":{"200":{"description":"Enrollment updated","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"boolean","example":false},"msg":{"type":"string","example":"success"},"result":{"$ref":"#/components/schemas/enrollmentItemSchema"}}}}}},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"},"404":{"description":"Enrollment not found"},"500":{"description":"Internal server error"}}}},"/contactMessages/create":{"post":{"tags":["Public"],"summary":"Submit contact form message","description":"No authentication. Mounted via publicRouter (Contact Us form).","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/contactMessageCreateBodySchema"}}}},"responses":{"200":{"description":"Message received","content":{"application/json":{"schema":{"$ref":"#/components/schemas/legacyApiResponseSchema"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"500":{"description":"Internal server error"}}}},"/contactMessages/getAll":{"get":{"tags":["ContactMessages"],"summary":"List contact messages","security":[{"bearerAuth":[]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"keyword","in":"query","schema":{"type":"string","maxLength":255}},{"name":"orderByCol","in":"query","schema":{"type":"string","enum":["id","full_name","email","subject","status","created_at"]}},{"name":"orderDirection","in":"query","schema":{"type":"string","enum":["asc","desc","ASC","DESC"],"default":"desc"}},{"name":"status","in":"query","schema":{"type":"string","enum":["new","read"]}}],"responses":{"200":{"description":"Paginated messages","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoPaginatedListSchema"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/contactMessages/get/{id}":{"get":{"tags":["ContactMessages"],"summary":"Get contact message","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Record ID","schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}],"responses":{"200":{"description":"Message"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/faqs/setStatus":{"put":{"tags":["FAQs"],"summary":"Set FAQ item active status","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoSetStatusBodySchema"}}}},"responses":{"200":{"description":"Status updated"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/stripeWebhook":{"post":{"tags":["StripeWebhook"],"summary":"Stripe webhook handler","description":"No Bearer auth (stripeWebhookRouter.skipGlobalAuth). Raw JSON body on /stripeWebhook mount. Requires Stripe-Signature header.","security":[],"parameters":[{"name":"Stripe-Signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Stripe event payload"}}}},"responses":{"200":{"description":"Event received","content":{"application/json":{"schema":{"$ref":"#/components/schemas/legacyApiResponseSchema"}}}},"400":{"description":"Webhook verification failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/legacyApiResponseSchema"}}}},"500":{"description":"Internal server error"}}}},"/locations/getAll":{"get":{"tags":["Locations"],"summary":"List locations","security":[{"bearerAuth":[]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"keyword","in":"query","schema":{"type":"string","maxLength":255}},{"name":"orderByCol","in":"query","schema":{"type":"string","enum":["id","name","isActive","createdAt","updatedAt"]}},{"name":"orderDirection","in":"query","schema":{"type":"string","enum":["asc","desc","ASC","DESC"],"default":"desc"}}],"responses":{"200":{"description":"Paginated list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoPaginatedListSchema"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/locations/create":{"post":{"tags":["Locations"],"summary":"Create location","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/locationCreateBodySchema"}}}},"responses":{"201":{"description":"Location created"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/locations/getBySlug/{slug}":{"get":{"tags":["Locations"],"summary":"Get location by slug (marketing)","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255}}],"responses":{"200":{"description":"Location"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/locations/get/{id}":{"get":{"tags":["Locations"],"summary":"Get location by ID","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Record ID","schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}],"responses":{"200":{"description":"Location"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/locations/update":{"put":{"tags":["Locations"],"summary":"Update location","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/locationUpdateBodySchema"}}}},"responses":{"200":{"description":"Location updated"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/locations/delete/{id}":{"delete":{"tags":["Locations"],"summary":"Delete location","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Record ID","schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}],"responses":{"200":{"description":"Location deleted"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/products/getBySlug/{slug}":{"get":{"deprecated":true,"tags":["Products"],"summary":"Get product by slug (deprecated â€” use GET /courses/getPublicBySlug/{slug} for public)","description":"Deprecated legacy alias for authenticated slug lookup. Public marketing should use GET /courses/getPublicBySlug/{slug}.","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255}}],"responses":{"200":{"description":"Product"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/contact/getPublic":{"get":{"tags":["Public"],"summary":"Public contact page content","description":"No authentication. Mounted via publicRouter. Returns active contact settings for the marketing site.","security":[],"responses":{"200":{"description":"Contact public payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/legacyApiResponseSchema"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"500":{"description":"Internal server error"}}}},"/contact/getSettings":{"get":{"tags":["Contact"],"summary":"Get contact settings (admin)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Contact settings"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/contact/updateSettings":{"put":{"tags":["Contact"],"summary":"Update contact settings","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/contactSettingsUpdateBodySchema"}}}},"responses":{"200":{"description":"Settings updated"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/contactMessages/markRead/{id}":{"put":{"tags":["ContactMessages"],"summary":"Mark contact message as read","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Record ID","schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}],"responses":{"200":{"description":"Message marked read"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/faqs/getPublic":{"get":{"tags":["Public"],"summary":"Public FAQs page content","description":"No authentication. Mounted via publicRouter.","security":[],"responses":{"200":{"description":"Public FAQs payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/legacyApiResponseSchema"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"500":{"description":"Internal server error"}}}},"/faqs/getSettings":{"get":{"tags":["FAQs"],"summary":"Get FAQ page settings","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"FAQ settings"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/faqs/updateSettings":{"put":{"tags":["FAQs"],"summary":"Update FAQ page settings","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/faqSettingsUpdateBodySchema"}}}},"responses":{"200":{"description":"Settings updated"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/faqs/getAll":{"get":{"tags":["FAQs"],"summary":"List FAQ items (admin)","security":[{"bearerAuth":[]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"keyword","in":"query","schema":{"type":"string","maxLength":255}},{"name":"orderByCol","in":"query","schema":{"type":"string","enum":["id","question","sortOrder","isActive","isDefault","createdAt","updatedAt"]}},{"name":"orderDirection","in":"query","schema":{"type":"string","enum":["asc","desc","ASC","DESC"],"default":"desc"}}],"responses":{"200":{"description":"Paginated list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoPaginatedListSchema"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/faqs/create":{"post":{"tags":["FAQs"],"summary":"Create FAQ item","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/faqItemCreateBodySchema"}}}},"responses":{"201":{"description":"FAQ created"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/faqs/get/{id}":{"get":{"tags":["FAQs"],"summary":"Get FAQ item","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Record ID","schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}],"responses":{"200":{"description":"FAQ item"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/faqs/update":{"put":{"tags":["FAQs"],"summary":"Update FAQ item","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/faqItemUpdateBodySchema"}}}},"responses":{"200":{"description":"FAQ updated"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/faqs/delete/{id}":{"delete":{"tags":["FAQs"],"summary":"Delete FAQ item","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Record ID","schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}],"responses":{"200":{"description":"FAQ deleted"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/checkout/checkEnrollment":{"get":{"tags":["Checkout"],"summary":"Check if email is already enrolled for a course","description":"No authentication (checkoutRouter.skipGlobalAuth). Accepts course_slug; product_slug is deprecated but still supported.","security":[],"parameters":[{"name":"course_slug","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":255}},{"name":"product_slug","in":"query","required":false,"description":"Deprecated alias for course_slug","schema":{"type":"string","minLength":1,"maxLength":255}},{"name":"email","in":"query","required":true,"schema":{"type":"string","format":"email","maxLength":255}}],"responses":{"200":{"description":"Enrollment check result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/legacyApiResponseSchema"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"500":{"description":"Internal server error"}}}},"/checkout/getContext":{"get":{"tags":["Checkout"],"summary":"Course checkout context","description":"No authentication (checkoutRouter.skipGlobalAuth). Accepts course_slug; product_slug is deprecated but still supported.","security":[],"parameters":[{"name":"course_slug","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":255}},{"name":"product_slug","in":"query","required":false,"description":"Deprecated alias for course_slug","schema":{"type":"string","minLength":1,"maxLength":255}}],"responses":{"200":{"description":"Checkout context","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/legacyApiResponseSchema"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/checkoutCourseContextSchema"}}}]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"500":{"description":"Internal server error"}}}},"/checkout/getSession":{"get":{"tags":["Checkout"],"summary":"Verify Stripe checkout session after redirect","description":"No authentication (checkoutRouter.skipGlobalAuth).","security":[],"parameters":[{"name":"session_id","in":"query","required":true,"schema":{"type":"string","minLength":1},"description":"Stripe checkout session ID"}],"responses":{"200":{"description":"Session verified","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/legacyApiResponseSchema"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/checkoutVerifySessionDataSchema"}}}]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"500":{"description":"Internal server error"}}}},"/checkout/createSession":{"post":{"tags":["Checkout"],"summary":"Create Stripe checkout session for a course","description":"No authentication (checkoutRouter.skipGlobalAuth). Accepts course_slug in body; product_slug is deprecated but still supported.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/checkoutCreateSessionBodySchema"}}}},"responses":{"200":{"description":"Checkout session created (includes Stripe URL)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/legacyApiResponseSchema"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"500":{"description":"Internal server error"}}}},"/checkout/getPackageContext":{"get":{"tags":["Checkout"],"summary":"Package checkout context","description":"No authentication (checkoutRouter.skipGlobalAuth).","security":[],"parameters":[{"name":"package_slug","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":255}}],"responses":{"200":{"description":"Package checkout context","content":{"application/json":{"schema":{"$ref":"#/components/schemas/legacyApiResponseSchema"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"500":{"description":"Internal server error"}}}},"/checkout/createPackageSession":{"post":{"tags":["Checkout"],"summary":"Create Stripe checkout session for a package","description":"No authentication (checkoutRouter.skipGlobalAuth).","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/packageCheckoutCreateSessionBodySchema"}}}},"responses":{"200":{"description":"Checkout session created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/legacyApiResponseSchema"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"500":{"description":"Internal server error"}}}},"/locations/getPublic":{"get":{"tags":["Public"],"summary":"Public active locations (marketing)","description":"No authentication. Mounted via publicRouter. Returns id, name, and slug for active locations.","security":[],"responses":{"200":{"description":"Active locations list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/legacyApiResponseSchema"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"500":{"description":"Internal server error"}}}},"/courses/getPublic":{"get":{"tags":["Public"],"summary":"Public active courses (marketing)","description":"No authentication. Mounted via publicRouter. Returns active courses with location and slug for the marketing site.","security":[],"responses":{"200":{"description":"Active courses list","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/legacyApiResponseSchema"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/coursePublicItemSchema"}}}}]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"500":{"description":"Internal server error"}}}},"/courses/getPublicBySlug/{slug}":{"get":{"tags":["Public"],"summary":"Public course by slug (marketing)","description":"No authentication. Mounted via publicRouter. Active courses only.","security":[],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255}}],"responses":{"200":{"description":"Course details","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/legacyApiResponseSchema"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/coursePublicItemSchema"}}}]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/locations/getPublicBySlug/{slug}":{"get":{"tags":["Public"],"summary":"Public location by slug (marketing)","description":"No authentication. Mounted via publicRouter. Active locations only.","security":[],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255}}],"responses":{"200":{"description":"Location","content":{"application/json":{"schema":{"$ref":"#/components/schemas/legacyApiResponseSchema"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/packages/getPublic":{"get":{"tags":["Public"],"summary":"Public marketing packages","description":"No authentication. Mounted via publicRouter. Packages with at least one active course.","security":[],"responses":{"200":{"description":"Marketing packages list","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/legacyApiResponseSchema"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/packageItemSchema"}}}}]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"500":{"description":"Internal server error"}}}},"/packages/getPublicBySlug/{slug}":{"get":{"tags":["Public"],"summary":"Public package by slug (marketing)","description":"No authentication. Mounted via publicRouter.","security":[],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255}}],"responses":{"200":{"description":"Package with courses","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/legacyApiResponseSchema"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/packageItemSchema"}}}]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/emailTemplate/getAll":{"get":{"tags":["EmailTemplates"],"summary":"List email templates","security":[{"bearerAuth":[]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"keyword","in":"query","schema":{"type":"string","maxLength":255}},{"name":"orderByCol","in":"query","schema":{"type":"string","enum":["id","name","subject","createdAt","updatedAt"]}},{"name":"orderDirection","in":"query","schema":{"type":"string","enum":["asc","desc","ASC","DESC"],"default":"desc"}}],"responses":{"200":{"description":"Paginated list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoPaginatedListSchema"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/emailTemplate/get/{id}":{"get":{"tags":["EmailTemplates"],"summary":"Get email template by ID","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Record ID","schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}],"responses":{"200":{"description":"Email template","content":{"application/json":{"schema":{"$ref":"#/components/schemas/legacyApiResponseSchema"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/emailTemplate/update":{"put":{"tags":["EmailTemplates"],"summary":"Update email template","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id"],"properties":{"id":{"type":"integer","minimum":1},"name":{"type":"string"},"subject":{"type":"string"},"body":{"type":"string"}}}}}},"responses":{"200":{"description":"Email template updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/legacyApiResponseSchema"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoValidationErrorSchema"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/gogoMessageSchema"}}}},"500":{"description":"Internal server error"}}}},"/courses/getAll":{"get":{"tags":["Courses"],"summary":"Get all courses","security":[{"bearerAuth":[]}],"parameters":[{"name":"keyword","in":"query","schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"integer","enum":[0,1]}},{"name":"location_id","in":"query","description":"Filter by one or more location ids (single value, comma-separated, or repeated query param).","schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"array","items":{"type":"integer","minimum":1}},{"type":"string","example":"1,2,3"}]}},{"name":"page","in":"query","required":true,"schema":{"type":"integer","minimum":1}},{"name":"pageSize","in":"query","required":true,"schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"orderBy","in":"query","schema":{"type":"string","enum":["id","name","shortName","locationId","orderBy","status","createdAt","updatedAt"],"default":"orderBy"}},{"name":"orderDirection","in":"query","schema":{"type":"string","enum":["ASC","DESC","asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"}}}},"/courses/create":{"post":{"tags":["Courses"],"summary":"Create course","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/courseCreateBodySchema"},"example":{"name":"Database Management System","short_name":"DBMS","description":"Database Course","price":149.99,"location_id":1,"order_by":0,"status":1}}}},"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"}}}},"/courses/get/{id}":{"get":{"tags":["Courses"],"summary":"Get course by ID","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"},"404":{"description":"Not found"}}}},"/courses/update":{"put":{"tags":["Courses"],"summary":"Update course","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/courseUpdateBodySchema"}}}},"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"}}}},"/courses/setStatus":{"put":{"tags":["Courses"],"summary":"Set course status","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","status"],"properties":{"id":{"type":"integer","minimum":1},"status":{"type":"integer","enum":[0,1],"description":"0 = Inactive, 1 = Active"}}}}}},"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"}}}},"/courses/delete/{id}":{"delete":{"tags":["Courses"],"summary":"Delete course (soft delete)","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"},"404":{"description":"Not found"}}}},"/blogs/getAll":{"get":{"tags":["Blogs"],"summary":"List blog posts (admin)","security":[{"bearerAuth":[]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"keyword","in":"query","schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"integer","enum":[0,1]},"description":"0=draft, 1=published"},{"name":"orderBy","in":"query","schema":{"type":"string","enum":["id","title","slug","status","publishedAt","createdAt","updatedAt"]}},{"name":"orderDirection","in":"query","schema":{"type":"string","enum":["ASC","DESC","asc","desc"]}}],"responses":{"200":{"description":"Success"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"}}}},"/blogs/create":{"post":{"tags":["Blogs"],"summary":"Create blog post","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/blogCreateBodySchema"}}}},"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed (including duplicate slug)"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"}}}},"/blogs/checkSlug":{"get":{"tags":["Blogs"],"summary":"Check blog slug availability","security":[{"bearerAuth":[]}],"parameters":[{"name":"slug","in":"query","required":true,"schema":{"type":"string"}},{"name":"exclude_id","in":"query","schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Success"},"400":{"description":"Invalid slug"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"}}}},"/blogs/get/{id}":{"get":{"tags":["Blogs"],"summary":"Get blog post by id","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Success"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"},"404":{"description":"Not found"}}}},"/blogs/update":{"put":{"tags":["Blogs"],"summary":"Update blog post","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/blogUpdateBodySchema"}}}},"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed (including duplicate slug)"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"},"404":{"description":"Not found"}}}},"/blogs/setStatus":{"put":{"tags":["Blogs"],"summary":"Publish or unpublish blog post","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","status"],"properties":{"id":{"type":"integer","minimum":1},"status":{"type":"integer","enum":[0,1],"description":"0=draft, 1=published"}}}}}},"responses":{"200":{"description":"Success"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"},"404":{"description":"Not found"}}}},"/blogs/delete/{id}":{"delete":{"tags":["Blogs"],"summary":"Soft-delete blog post","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Success"},"401":{"description":"Unauthorized"},"403":{"description":"Permission denied"},"404":{"description":"Not found"}}}},"/blogs/getPublic":{"get":{"tags":["Blogs","Public"],"summary":"List published blog posts","description":"No authentication. Use limit for homepage teasers (e.g. limit=3).","parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":50}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50},"description":"Shortcut for pageSize (homepage latest posts)"},{"name":"keyword","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Success"}}}},"/blogs/getPublicBySlug/{slug}":{"get":{"tags":["Blogs","Public"],"summary":"Get published blog post by slug","description":"No authentication. SEO-friendly public detail.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"404":{"description":"Not found"}}}},"/health":{"get":{"tags":["System"],"summary":"Health check","description":"Returns OK when the API and database are reachable. No auth required.","responses":{"200":{"description":"OK"},"500":{"description":"Database unavailable"}}}},"/openapi.json":{"get":{"tags":["System"],"summary":"OpenAPI 3 specification (JSON)","description":"Machine-readable OpenAPI document for AI agents, crawlers, and API clients. Same payload as /swagger.json.","responses":{"200":{"description":"OpenAPI 3.0 document","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/swagger.json":{"get":{"tags":["System"],"summary":"OpenAPI 3 specification alias","description":"Alias of /openapi.json for crawlers that look for swagger.json.","responses":{"200":{"description":"OpenAPI 3.0 document","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/schools/getPublic":{"get":{"tags":["Schools"],"summary":"List public partner schools","responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"parameters":[{"name":"province","in":"query","schema":{"type":"string"}},{"name":"city","in":"query","schema":{"type":"string"}}]}},"/schools/getPublicBySlug/{slug}":{"get":{"tags":["Schools"],"summary":"Get public school by slug","responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}]}},"/schools/register":{"post":{"tags":["Schools"],"summary":"Request school partner signup (pending approval)","responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","email","password","firstname","lastname"],"properties":{"name":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"type":"string"},"city":{"type":"string"},"province":{"type":"string"},"address":{"type":"string"},"password":{"type":"string"},"firstname":{"type":"string"},"lastname":{"type":"string"}}}}}}}},"/schools/getAll":{"get":{"tags":["Schools"],"summary":"List schools (scoped)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"keyword","in":"query","schema":{"type":"string"}}]}},"/schools/get/{id}":{"get":{"tags":["Schools"],"summary":"Get school by id","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}]}},"/schools/create":{"post":{"tags":["Schools"],"summary":"Create school (super admin)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"city":{"type":"string"},"province":{"type":"string"},"address":{"type":"string"}}}}}}}},"/schools/update":{"put":{"tags":["Schools"],"summary":"Update school profile / page content","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"city":{"type":"string"},"province":{"type":"string"},"address":{"type":"string"},"description":{"type":"string"},"publicBio":{"type":"string"},"website":{"type":"string"},"metaTitle":{"type":"string"},"metaDescription":{"type":"string"},"isPublic":{"type":"boolean"},"pageContent":{"type":"object"}}}}}}}},"/schools/setStatus":{"put":{"tags":["Schools"],"summary":"Set school active status","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id"],"properties":{"id":{"type":"integer"},"isActive":{"type":"boolean"}}}}}}}},"/schools/setApproval":{"put":{"tags":["Schools"],"summary":"Approve or reject partner school (super admin)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","approvalStatus"],"properties":{"id":{"type":"integer"},"approvalStatus":{"type":"string","enum":["pending","approved","rejected"]}}}}}}}},"/branches/getAll":{"get":{"tags":["Branches"],"summary":"List school branches","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"keyword","in":"query","schema":{"type":"string"}}]}},"/branches/create":{"post":{"tags":["Branches"],"summary":"Create branch","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"city":{"type":"string"},"schoolId":{"type":"integer"}}}}}}}},"/branches/update":{"put":{"tags":["Branches"],"summary":"Update branch","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"city":{"type":"string"}}}}}}}},"/branches/delete/{id}":{"delete":{"tags":["Branches"],"summary":"Delete branch","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}]}},"/instructors/getAll":{"get":{"tags":["Instructors"],"summary":"List instructors","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"keyword","in":"query","schema":{"type":"string"}}]}},"/instructors/create":{"post":{"tags":["Instructors"],"summary":"Create instructor link","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"firstname":{"type":"string"},"lastname":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"drivingLicense":{"type":"string"},"schoolId":{"type":"integer"},"branchId":{"type":"integer"}}}}}}}},"/instructors/update":{"put":{"tags":["Instructors"],"summary":"Update instructor","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"integer"},"firstname":{"type":"string"},"lastname":{"type":"string"}}}}}}}},"/instructors/delete/{id}":{"delete":{"tags":["Instructors"],"summary":"Delete instructor","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}]}},"/schoolStudents/getAll":{"get":{"tags":["SchoolStudents"],"summary":"List school students","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"keyword","in":"query","schema":{"type":"string"}}]}},"/schoolStudents/create":{"post":{"tags":["SchoolStudents"],"summary":"Create school student","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"firstname":{"type":"string"},"lastname":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"schoolId":{"type":"integer"}}}}}}}},"/schoolStudents/update":{"put":{"tags":["SchoolStudents"],"summary":"Update school student","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"integer"},"firstname":{"type":"string"},"lastname":{"type":"string"}}}}}}}},"/schoolStudents/delete/{id}":{"delete":{"tags":["SchoolStudents"],"summary":"Delete school student","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}]}},"/schoolUsers/roles":{"get":{"tags":["SchoolUsers"],"summary":"List assignable school staff roles","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}}}},"/schoolUsers/getAll":{"get":{"tags":["SchoolUsers"],"summary":"List school staff users","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"keyword","in":"query","schema":{"type":"string"}}]}},"/schoolUsers/create":{"post":{"tags":["SchoolUsers"],"summary":"Create school staff user","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"firstname":{"type":"string"},"lastname":{"type":"string"},"email":{"type":"string"},"roleId":{"type":"integer"},"schoolId":{"type":"integer"},"branchId":{"type":"integer"}}}}}}}},"/schoolUsers/update":{"put":{"tags":["SchoolUsers"],"summary":"Update school staff user","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"integer"},"roleId":{"type":"integer"}}}}}}}},"/schoolUsers/delete/{id}":{"delete":{"tags":["SchoolUsers"],"summary":"Delete school staff user","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}]}},"/incar/getAll":{"get":{"tags":["InCar"],"summary":"List in-car training sheets","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"keyword","in":"query","schema":{"type":"string"}},{"name":"schoolId","in":"query","schema":{"type":"integer"}},{"name":"studentId","in":"query","schema":{"type":"integer"}},{"name":"instructorId","in":"query","schema":{"type":"integer"}},{"name":"jurisdiction","in":"query","schema":{"type":"string","enum":["alberta","ontario"]}}]}},"/incar/get/{id}":{"get":{"tags":["InCar"],"summary":"Get in-car sheet by id","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}]}},"/incar/create":{"post":{"tags":["InCar"],"summary":"Create in-car sheet","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"schoolId":{"type":"integer"},"studentId":{"type":"integer"},"instructorId":{"type":"integer"},"jurisdiction":{"type":"string","enum":["alberta","ontario"]}}}}}}}},"/incar/update":{"put":{"tags":["InCar"],"summary":"Update in-car sheet fields / hours / ratings","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id"],"properties":{"id":{"type":"integer"}}}}}}}},"/incar/delete/{id}":{"delete":{"tags":["InCar"],"summary":"Delete in-car sheet","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}]}},"/incar/sessions/create":{"post":{"tags":["InCar"],"summary":"Add lesson session to sheet","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"sheetId":{"type":"integer"},"date":{"type":"string","format":"date"}}}}}}}},"/incar/sessions/update":{"put":{"tags":["InCar"],"summary":"Update lesson session","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id"],"properties":{"id":{"type":"integer"}}}}}}}},"/incar/sessions/delete/{id}":{"delete":{"tags":["InCar"],"summary":"Delete lesson session","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}]}},"/incar/sign":{"post":{"tags":["InCar"],"summary":"Sign sheet (instructor / student / dual)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"sheetId":{"type":"integer"},"role":{"type":"string"},"signature":{"type":"string"}}}}}}}},"/incar/remind/{id}":{"post":{"tags":["InCar"],"summary":"Send reminder for unsigned sheet","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}]}},"/incar/request-sign":{"post":{"tags":["InCar"],"summary":"Request student signature","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["sheetId"],"properties":{"sheetId":{"type":"integer"}}}}}}}},"/incar/qr/pending":{"get":{"tags":["InCar"],"summary":"Get pending QR sign challenge for student","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}}}},"/incar/qr/image":{"get":{"tags":["InCar"],"summary":"Get QR image for student sign flow","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}}}},"/incar/validate-qr":{"post":{"tags":["InCar"],"summary":"Validate scanned QR and apply student signature","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string"},"payload":{"type":"string"}}}}}}}},"/incar/pdf/{id}":{"get":{"tags":["InCar"],"summary":"Download in-car PDF (Alberta or Ontario form)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Success"},"400":{"description":"Validation failed"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}]}}},"components":{"schemas":{"userSuccessSchema":{"type":"object","properties":{"error":{"type":"boolean"},"msg":{"type":"string"},"result":{"type":"object","properties":{"id":{"type":"integer"},"firstname":{"type":"string"},"middlename":{"type":"string","nullable":true},"lastname":{"type":"string"},"email":{"type":"string","format":"email"},"cnic":{"type":"string","nullable":true},"designation":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"status":{"type":"integer"},"role_id":{"type":"integer","nullable":true}}}}},"usersSuccessSchema":{"type":"object","properties":{"error":{"type":"boolean"},"msg":{"type":"string"},"result":{"type":"object","properties":{"rows":{"type":"array","items":{"type":"object"}},"count":{"type":"integer"},"inactive":{"type":"integer"},"active":{"type":"integer"},"disabled":{"type":"integer"}}}}},"newUserSchema":{"type":"object","required":["firstname","lastname","email","password","status"],"properties":{"id":{"type":"integer"},"firstname":{"type":"string"},"middlename":{"type":"string","nullable":true},"lastname":{"type":"string"},"email":{"type":"string","format":"email"},"password":{"type":"string"},"cnic":{"type":"string","nullable":true},"designation":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"summary":{"type":"string","nullable":true},"image":{"type":"integer","nullable":true},"role_id":{"type":"integer","nullable":true},"is_instructor":{"type":"integer","enum":[0,1]},"status":{"type":"integer"}}},"inviteUserSchema":{"type":"object","required":["firstname","lastname","email","is_instructor"],"properties":{"firstname":{"type":"string"},"lastname":{"type":"string"},"email":{"type":"string","format":"email"},"is_instructor":{"type":"integer","enum":[0,1]},"middlename":{"type":"string","nullable":true},"designation":{"type":"string","nullable":true},"country_id":{"type":"integer","nullable":true},"state_id":{"type":"integer","nullable":true},"city_id":{"type":"integer","nullable":true},"summary":{"type":"string","nullable":true},"image":{"type":"integer","nullable":true},"phone":{"type":"string","nullable":true},"role_id":{"type":"integer","nullable":true}}},"updateUserSchema":{"type":"object","required":["id","firstname","lastname","status"],"properties":{"id":{"type":"integer"},"firstname":{"type":"string"},"middlename":{"type":"string","nullable":true},"lastname":{"type":"string"},"cnic":{"type":"string","nullable":true},"designation":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"summary":{"type":"string","nullable":true},"image":{"type":"integer","nullable":true},"role_id":{"type":"integer","nullable":true},"is_instructor":{"type":"integer","enum":[0,1]},"status":{"type":"integer"}}},"fileSuccessSchema":{"type":"object","properties":{"error":{"type":"boolean"},"msg":{"type":"string"},"result":{"type":"object","nullable":true}}},"settingPayloadSchema":{"type":"object","required":["id","name","type","val"],"properties":{"id":{"type":"integer","minimum":1},"name":{"type":"string"},"type":{"type":"string"},"val":{"type":"string"}}},"worldSuccessSchema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":"string","minLength":1}}},"example":[{"id":0,"name":"string"}]},"newSettingPayloadSchema":{"type":"object","required":["name","type","val"],"properties":{"name":{"type":"string"},"type":{"type":"string"},"val":{"type":"string"}}},"settingEntitySchema":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"type":{"type":"string"},"val":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"settingSuccessSchema":{"type":"object","properties":{"error":{"type":"boolean"},"msg":{"type":"string"},"result":{"$ref":"#/components/schemas/settingEntitySchema"}}},"settingsListSuccessSchema":{"type":"object","properties":{"error":{"type":"boolean"},"msg":{"type":"string"},"result":{"type":"object","properties":{"count":{"type":"integer"},"rows":{"type":"array","items":{"$ref":"#/components/schemas/settingEntitySchema"}}}}}},"settingsByTypeSuccessSchema":{"type":"object","properties":{"error":{"type":"boolean"},"msg":{"type":"string"},"result":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/settingEntitySchema"},{"type":"object","properties":{"captua":{"type":"integer"}}}]}}}},"languageEntitySchema":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"shortname":{"type":"string"},"status":{"type":"integer","enum":[0,1]},"created_at":{"type":"string","format":"date-time","nullable":true},"updated_at":{"type":"string","format":"date-time","nullable":true}}},"languageCreateBodySchema":{"type":"object","required":["name","shortname"],"properties":{"name":{"type":"string"},"shortname":{"type":"string"},"status":{"type":"integer","minimum":0,"maximum":1}}},"languageUpdateBodySchema":{"type":"object","required":["id","name","shortname","status"],"properties":{"id":{"type":"integer","minimum":1},"name":{"type":"string"},"shortname":{"type":"string"},"status":{"type":"integer","minimum":0,"maximum":1}}},"languageUpdateStatusBodySchema":{"type":"object","required":["id","status"],"properties":{"id":{"type":"integer","minimum":1},"status":{"type":"integer","minimum":0,"maximum":1}}},"languageSingleSuccessSchema":{"type":"object","properties":{"error":{"type":"boolean"},"msg":{"type":"string"},"result":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/languageEntitySchema"}]}}},"languageListSuccessSchema":{"type":"object","properties":{"error":{"type":"boolean"},"msg":{"type":"string"},"result":{"type":"object","properties":{"count":{"type":"integer"},"rows":{"type":"array","items":{"$ref":"#/components/schemas/languageEntitySchema"}}}}}},"langItemPayloadSchema":{"type":"object","required":["language_id","text"],"properties":{"language_id":{"type":"integer","minimum":1},"text":{"type":"string"}}},"langRecordCreateBodySchema":{"type":"object","required":["school_id","name","type","default","lang_items"],"properties":{"school_id":{"type":"integer","minimum":1},"name":{"type":"string"},"type":{"type":"string"},"default":{"type":"string","minLength":1},"status":{"type":"integer","minimum":0,"maximum":1},"lang_items":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/langItemPayloadSchema"}}}},"langRecordUpdateBodySchema":{"type":"object","required":["id","school_id","name","type","default","status","lang_items"],"properties":{"id":{"type":"integer","minimum":1},"school_id":{"type":"integer","minimum":1},"name":{"type":"string"},"type":{"type":"string"},"default":{"type":"string","minLength":1},"status":{"type":"integer","minimum":0,"maximum":1},"lang_items":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/langItemPayloadSchema"}}}},"langItemEntitySchema":{"type":"object","properties":{"id":{"type":"integer"},"language_id":{"type":"integer"},"text":{"type":"string"},"language":{"type":"object","nullable":true,"properties":{"id":{"type":"integer"},"name":{"type":"string"},"shortname":{"type":"string"}}}}},"langRecordEntitySchema":{"type":"object","properties":{"id":{"type":"integer"},"school_id":{"type":"integer"},"name":{"type":"string"},"type":{"type":"string"},"default":{"type":"string"},"status":{"type":"integer","enum":[0,1]},"created_at":{"type":"string","format":"date-time","nullable":true},"updated_at":{"type":"string","format":"date-time","nullable":true},"lang_items":{"type":"array","items":{"$ref":"#/components/schemas/langItemEntitySchema"}},"school":{"type":"object","nullable":true,"properties":{"id":{"type":"integer"},"name":{"type":"string"},"email":{"type":"string","nullable":true}}}}},"langRecordSingleSuccessSchema":{"type":"object","properties":{"error":{"type":"boolean"},"msg":{"type":"string"},"result":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/langRecordEntitySchema"}]}}},"langRecordListSuccessSchema":{"type":"object","properties":{"error":{"type":"boolean"},"msg":{"type":"string"},"result":{"type":"object","properties":{"count":{"type":"integer"},"rows":{"type":"array","items":{"$ref":"#/components/schemas/langRecordEntitySchema"}}}}}},"gogoMessageSchema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]},"gogoValidationErrorSchema":{"type":"object","properties":{"message":{"type":"string","example":"Validation failed"},"errors":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}}}}}},"gogoPaginatedListSchema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object"}},"total":{"type":"integer"},"page":{"type":"integer"},"pageSize":{"type":"integer"}}},"gogoSetStatusBodySchema":{"type":"object","required":["id","is_active"],"properties":{"id":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]},"is_active":{"type":"boolean"}}},"locationCreateBodySchema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":255}}},"courseCreateBodySchema":{"type":"object","required":["name","short_name","price","location_id"],"properties":{"name":{"type":"string","minLength":1,"maxLength":255},"short_name":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","maxLength":5000,"nullable":true},"price":{"type":"number","exclusiveMinimum":0,"maximum":99999999.99},"location_id":{"type":"integer","minimum":1},"order_by":{"type":"integer","minimum":0,"maximum":9,"default":0,"description":"Controls course listing order (0-9). Lower values are listed first."},"enrollment_duration_days":{"type":"integer","minimum":1,"maximum":3650,"default":90,"description":"Access length in days after purchase. Default 90 (~3 months)."},"status":{"type":"integer","enum":[0,1],"default":1,"description":"0 = Inactive, 1 = Active"},"original_price":{"type":"number","exclusiveMinimum":0,"maximum":99999999.99,"nullable":true,"description":"List/compare-at price shown with strikethrough. Must be >= price (effected/sale price)."},"exam_builder_price":{"type":"number","minimum":0,"maximum":99999999.99,"default":0,"description":"Standalone Exam Builder full-access price for this course (sold without enrollment). Use 0 for free unlock."}}},"courseUpdateBodySchema":{"allOf":[{"$ref":"#/components/schemas/courseCreateBodySchema"},{"type":"object","required":["id"],"properties":{"id":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}}]},"coursePublicItemSchema":{"type":"object","properties":{"id":{"type":"string","example":"1"},"name":{"type":"string","example":"Nursing Prep"},"slug":{"type":"string","example":"nursing-prep"},"shortName":{"type":"string","example":"Nursing"},"description":{"type":"string"},"price":{"type":"string","example":"149.99"},"locationId":{"type":"string","example":"1"},"locationName":{"type":"string","example":"California"},"status":{"type":"integer","enum":[0,1]},"features":{"type":"array","items":{"$ref":"#/components/schemas/featurePublicItemSchema"}},"originalPrice":{"type":"string","nullable":true,"example":"199.99"}}},"featurePublicItemSchema":{"type":"object","properties":{"id":{"type":"string"},"service":{"type":"string"},"isEnabled":{"type":"boolean"},"status":{"type":"string","enum":["active","inactive","pending"]}}},"packageItemSchema":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"locationId":{"type":"string"},"locationName":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"actualPrice":{"type":"string","description":"Sum of linked course prices"},"effectedPrice":{"type":"string"},"courseIds":{"type":"array","items":{"type":"string"}},"courseNames":{"type":"array","items":{"type":"string"}},"coursePrices":{"type":"array","items":{"type":"string"}},"courseNamesLabel":{"type":"string"},"courses":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"price":{"type":"string"}}}}}},"transactionItemSchema":{"type":"object","properties":{"id":{"type":"string"},"courseId":{"type":"string","description":"Set when purchaseType is course"},"packageId":{"type":"string","description":"Set when purchaseType is package"},"purchaseType":{"type":"string","enum":["course","package",""]},"packageName":{"type":"string"},"courseName":{"type":"string"},"fullName":{"type":"string"},"email":{"type":"string"},"amount":{"type":"string"},"currency":{"type":"string"},"status":{"type":"string"},"paidAt":{"type":"string","format":"date-time","nullable":true}}},"enrollmentItemSchema":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"userEmail":{"type":"string"},"userFullName":{"type":"string"},"courseId":{"type":"string"},"courseName":{"type":"string"},"courseSlug":{"type":"string"},"packageId":{"type":"string","description":"Empty when enrolled via single course"},"packageName":{"type":"string"},"transactionId":{"type":"string","description":"Set when source is payment"},"startDate":{"type":"string","format":"date"},"endDate":{"type":"string","format":"date"},"source":{"type":"string","enum":["payment","admin"]},"status":{"type":"string","enum":["active","suspended","inactive"],"description":"active = access granted; suspended = temporarily blocked by admin; inactive = permanently deactivated"},"isActive":{"type":"boolean","description":"True when status is active and today is within start/end dates"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"enrollmentListResponseSchema":{"type":"object","properties":{"error":{"type":"boolean","example":false},"msg":{"type":"string","example":"success"},"result":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/enrollmentItemSchema"}},"total":{"type":"integer"},"page":{"type":"integer"},"pageSize":{"type":"integer"}}}}},"enrollmentCreateBodySchema":{"type":"object","required":["user_id","start_date","end_date"],"properties":{"user_id":{"type":"integer","minimum":1,"example":5},"course_id":{"type":"integer","minimum":1,"example":12,"description":"Enroll in a single course (xor with package_id)"},"package_id":{"type":"integer","minimum":1,"example":3,"description":"Enroll in all courses in package (xor with course_id)"},"start_date":{"type":"string","format":"date","example":"2026-06-28"},"end_date":{"type":"string","format":"date","example":"2027-06-28"}}},"enrollmentUpdateBodySchema":{"type":"object","required":["id"],"properties":{"id":{"type":"integer","minimum":1,"example":1},"status":{"type":"string","enum":["active","suspended","inactive"],"description":"active = restore access; suspended = temporary block; inactive = permanent deactivation"},"start_date":{"type":"string","format":"date","example":"2026-06-28"},"end_date":{"type":"string","format":"date","example":"2027-06-28"}},"description":"At least one of status, start_date, or end_date is required."},"enrollmentCreateResponseSchema":{"type":"object","properties":{"error":{"type":"boolean","example":false},"msg":{"type":"string","example":"success"},"result":{"oneOf":[{"$ref":"#/components/schemas/enrollmentItemSchema"},{"type":"object","description":"Package enrollment response","properties":{"packageId":{"type":"string"},"created":{"type":"array","items":{"$ref":"#/components/schemas/enrollmentItemSchema"}},"skipped":{"type":"array","items":{"type":"object","properties":{"courseId":{"type":"string"},"enrollmentId":{"type":"string"}}}}}}]}}},"courseActivityMarkCompleteBodySchema":{"type":"object","required":["course_activity_id"],"properties":{"course_activity_id":{"type":"integer","minimum":1,"example":12,"description":"ID of the course activity mapping to mark complete"}}},"courseActivityCompletionSchema":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"string"},"courseId":{"type":"string"},"courseActivityId":{"type":"string"},"source":{"type":"string","enum":["manual","scorm","h5p"]},"completedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"checkoutCourseContextSchema":{"type":"object","properties":{"courseId":{"type":"string"},"courseTitle":{"type":"string"},"courseSlug":{"type":"string"},"amount":{"type":"string"},"currency":{"type":"string","example":"USD"}}},"checkoutVerifySessionDataSchema":{"type":"object","properties":{"transactionId":{"type":"string"},"status":{"type":"string"},"email":{"type":"string"},"courseTitle":{"type":"string"},"courseSlug":{"type":"string"},"paidAt":{"type":"string","format":"date-time","nullable":true}}},"productCreateBodySchema":{"deprecated":true,"description":"Deprecated. Use courseCreateBodySchema with POST /courses/create. Legacy /products/* routes operate on the courses table.","type":"object","required":["name","location_id","price"],"properties":{"name":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","maxLength":65535,"nullable":true},"location_id":{"type":"integer","minimum":1},"price":{"type":"number","exclusiveMinimum":0,"maximum":99999999.99},"short_name":{"type":"string","minLength":1,"maxLength":120,"description":"Optional; defaults to truncated name when omitted on legacy /products/create"},"type":{"type":"string","enum":["course","service","training"],"deprecated":true,"description":"Ignored; kept for backward compatibility"}}},"productUpdateBodySchema":{"allOf":[{"$ref":"#/components/schemas/productCreateBodySchema"},{"type":"object","required":["id"],"properties":{"id":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}}]},"packageCreateBodySchema":{"type":"object","required":["location_id","name","effected_price","course_ids"],"properties":{"location_id":{"type":"integer","minimum":1},"name":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","maxLength":65535,"nullable":true},"actual_price":{"type":"number","minimum":0,"maximum":99999999.99,"description":"Optional. If omitted, computed as the sum of linked course prices."},"actualPrice":{"type":"number","minimum":0,"maximum":99999999.99,"description":"CamelCase alias for actual_price"},"effected_price":{"type":"number","exclusiveMinimum":0,"maximum":99999999.99},"course_ids":{"type":"array","minItems":1,"items":{"type":"integer","minimum":1}}}},"packageUpdateBodySchema":{"allOf":[{"$ref":"#/components/schemas/packageCreateBodySchema"},{"type":"object","required":["id"],"properties":{"id":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}}]},"featureCreateBodySchema":{"type":"object","required":["service"],"properties":{"package_id":{"type":"integer","minimum":1,"description":"Attach feature to a package (xor with course_id)"},"course_id":{"type":"integer","minimum":1,"description":"Attach feature to a course (xor with package_id)"},"service":{"type":"string","minLength":1,"maxLength":255},"is_enabled":{"type":"boolean","default":true},"status":{"type":"string","enum":["active","inactive","pending"],"default":"active"}},"description":"Provide exactly one of package_id or course_id."},"featureUpdateBodySchema":{"allOf":[{"$ref":"#/components/schemas/featureCreateBodySchema"},{"type":"object","required":["id"],"properties":{"id":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]}}}]},"contactSettingsUpdateBodySchema":{"type":"object","required":["intro","details_heading","details_lead","detail_items","form_title","form_subtitle","map_embed_url","map_open_url","map_caption","office_hours_title","office_hours_content","is_active"],"properties":{"intro":{"type":"string","minLength":1,"maxLength":10000},"details_heading":{"type":"string","minLength":1,"maxLength":255},"details_lead":{"type":"string","minLength":1,"maxLength":10000},"detail_items":{"type":"array","minItems":1,"maxItems":12,"items":{"type":"object","required":["id","title","lines"],"properties":{"id":{"type":"string","maxLength":64},"title":{"type":"string","minLength":1,"maxLength":255},"lines":{"type":"array","minItems":1,"items":{"type":"string","maxLength":500}}}}},"form_title":{"type":"string","minLength":1,"maxLength":255},"form_subtitle":{"type":"string","maxLength":10000},"map_embed_url":{"type":"string","minLength":1,"maxLength":8000},"map_open_url":{"type":"string","minLength":1,"maxLength":2000},"map_caption":{"type":"string","maxLength":2000},"office_hours_title":{"type":"string","minLength":1,"maxLength":255},"office_hours_content":{"type":"string","minLength":1,"maxLength":10000},"notification_email":{"type":"string","format":"email","maxLength":255,"nullable":true,"description":"Recipient address for contact form submission notifications. Falls back to the account owner when empty."},"notification_cc":{"type":"string","maxLength":1000,"nullable":true,"description":"Optional comma-separated list of CC addresses for contact form notifications."},"is_active":{"type":"boolean"}}},"contactMessageCreateBodySchema":{"type":"object","required":["full_name","email","subject","message"],"properties":{"full_name":{"type":"string","minLength":2,"maxLength":255},"email":{"type":"string","format":"email","maxLength":255},"subject":{"type":"string","minLength":3,"maxLength":512},"message":{"type":"string","minLength":10,"maxLength":20000}}},"faqSettingsUpdateBodySchema":{"type":"object","required":["intro","heading","description","is_active"],"properties":{"intro":{"type":"string","minLength":1,"maxLength":10000},"heading":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","minLength":1,"maxLength":10000},"is_active":{"type":"boolean"}}},"faqItemCreateBodySchema":{"type":"object","required":["question","answer"],"properties":{"question":{"type":"string","minLength":1,"maxLength":512},"answer":{"type":"string","minLength":1,"maxLength":50000},"is_active":{"type":"boolean","default":true}}},"faqItemUpdateBodySchema":{"type":"object","required":["id","question","answer"],"properties":{"id":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]},"question":{"type":"string","minLength":1,"maxLength":512},"answer":{"type":"string","minLength":1,"maxLength":50000},"is_active":{"type":"boolean"}}},"checkoutCreateSessionBodySchema":{"type":"object","required":["first_name","last_name","email","state","city"],"properties":{"course_slug":{"type":"string","minLength":1,"maxLength":255},"product_slug":{"type":"string","minLength":1,"maxLength":255,"description":"Deprecated alias for course_slug"},"first_name":{"type":"string","minLength":1,"maxLength":120},"middle_name":{"type":"string","maxLength":120,"nullable":true},"last_name":{"type":"string","minLength":1,"maxLength":120},"email":{"type":"string","format":"email","maxLength":255},"country":{"type":"string","minLength":2,"maxLength":2,"default":"US"},"state":{"type":"string","minLength":1,"maxLength":120},"city":{"type":"string","minLength":1,"maxLength":120}},"anyOf":[{"required":["course_slug"]},{"required":["product_slug"]}]},"packageCheckoutCreateSessionBodySchema":{"type":"object","required":["package_slug","first_name","last_name","email","state","city"],"properties":{"package_slug":{"type":"string","minLength":1,"maxLength":255},"first_name":{"type":"string","minLength":1,"maxLength":120},"middle_name":{"type":"string","maxLength":120,"nullable":true},"last_name":{"type":"string","minLength":1,"maxLength":120},"email":{"type":"string","format":"email","maxLength":255},"country":{"type":"string","minLength":2,"maxLength":2,"default":"US"},"state":{"type":"string","minLength":1,"maxLength":120},"city":{"type":"string","minLength":1,"maxLength":120}}},"locationUpdateBodySchema":{"type":"object","required":["id","name"],"properties":{"id":{"oneOf":[{"type":"integer","minimum":1},{"type":"string","pattern":"^\\d+$"}]},"name":{"type":"string","minLength":1,"maxLength":255}}},"legacyApiResponseSchema":{"type":"object","description":"Standard API envelope from common/response.js","properties":{"error":{"type":"boolean","example":false},"result":{"description":"Payload on success; validation errors array or null on failure"},"msg":{"type":"string","example":"success"}},"required":["error","result","msg"]},"scormPackageSchema":{"type":"object","description":"Uploaded SCORM package metadata","properties":{"id":{"type":"integer","example":1},"title":{"type":"string","example":"Infotainment-1"},"identifier":{"type":"string","nullable":true,"example":"_66ilV4Qs1Wm_course_id"},"version":{"type":"string","enum":["1.2","2004"],"example":"1.2"},"launch_url":{"type":"string","example":"index_lms.html","description":"Relative launch file inside the extracted package"},"storage_path":{"type":"string","example":"a1b2c3d4e5f6g7h8","description":"Folder name under /public/scorm/"},"mastery_score":{"type":"integer","nullable":true,"example":80},"file_id":{"type":"integer","nullable":true},"content_url":{"type":"string","example":"/public/scorm/a1b2c3d4/index_lms.html"},"launch_content_url":{"type":"string","example":"http://localhost:3011/public/scorm/a1b2c3d4/index_lms.html","description":"Full URL for iframe src"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"scormProgressSchema":{"type":"object","nullable":true,"properties":{"lesson_status":{"type":"string","example":"incomplete","description":"SCORM 1.2 cmi.core.lesson_status"},"lesson_location":{"type":"string","nullable":true,"description":"Bookmark / slide location"},"score_raw":{"type":"number","nullable":true,"example":85},"total_time":{"type":"string","example":"0000:15:30.00"},"suspend_data":{"type":"string","nullable":true,"description":"Opaque suspend/resume payload from the SCO"},"completed_at":{"type":"string","format":"date-time","nullable":true},"initialized":{"type":"boolean"},"last_commit_at":{"type":"string","format":"date-time","nullable":true}}},"scormLaunchSchema":{"type":"object","properties":{"course_activity_id":{"type":"integer","example":15},"scorm_package":{"$ref":"#/components/schemas/scormPackageSchema"},"attempt_id":{"type":"integer","example":3},"progress":{"$ref":"#/components/schemas/scormProgressSchema"},"cmi_data":{"type":"object","additionalProperties":{"type":"string"},"description":"Full SCORM 1.2 CMI key/value map for the player","example":{"cmi.core.student_id":"42","cmi.core.student_name":"John Doe","cmi.core.lesson_status":"incomplete","cmi.core.entry":"ab-initio","cmi.core.score.raw":"","cmi.suspend_data":""}}}},"scormCourseActivityRequestSchema":{"type":"object","required":["course_activity_id"],"properties":{"course_activity_id":{"type":"integer","minimum":1}}},"scormGetValueRequestSchema":{"type":"object","required":["course_activity_id","element"],"properties":{"course_activity_id":{"type":"integer","minimum":1},"element":{"type":"string","example":"cmi.core.lesson_status","description":"SCORM 1.2 CMI element name"}}},"scormSetValueRequestSchema":{"type":"object","required":["course_activity_id","element","value"],"properties":{"course_activity_id":{"type":"integer","minimum":1},"element":{"type":"string","example":"cmi.core.lesson_status"},"value":{"type":"string","example":"completed"}}},"scormRuntimeResponseSchema":{"type":"object","properties":{"error_code":{"type":"string","example":"0","description":"SCORM error code (0 = no error)"},"error_string":{"type":"string","example":"No Error"},"element":{"type":"string"},"value":{"type":"string"},"cmi_data":{"type":"object","additionalProperties":{"type":"string"}},"progress":{"$ref":"#/components/schemas/scormProgressSchema"}}},"blogCreateBodySchema":{"type":"object","required":["title","body"],"properties":{"title":{"type":"string","minLength":1,"maxLength":255},"slug":{"type":"string","maxLength":255,"description":"Optional unique SEO slug. Auto-generated from title when omitted. Validated for uniqueness before insert.","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"excerpt":{"type":"string","maxLength":1000,"nullable":true},"body":{"type":"string","description":"Rich HTML body"},"cover_image_url":{"type":"string","maxLength":1000,"nullable":true},"meta_title":{"type":"string","maxLength":255,"nullable":true},"meta_description":{"type":"string","maxLength":500,"nullable":true},"status":{"type":"integer","enum":[0,1],"description":"0=draft, 1=published"}}},"blogUpdateBodySchema":{"allOf":[{"$ref":"#/components/schemas/blogCreateBodySchema"},{"type":"object","required":["id"],"properties":{"id":{"type":"integer","minimum":1}}}]}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}}},"tags":[{"name":"Auth","description":"Authentication and account enablement"},{"name":"Blogs","description":"Marketing blogs"},{"name":"Branches","description":"School branches"},{"name":"Checkout","description":"Stripe checkout"},{"name":"Contact","description":"Contact settings"},{"name":"ContactMessages","description":"ContactMessages"},{"name":"Courses","description":"Marketplace course catalog"},{"name":"EmailTemplates","description":"EmailTemplates"},{"name":"Enrollments","description":"Student enrollments"},{"name":"FAQs","description":"FAQs"},{"name":"Features","description":"Course features"},{"name":"Files","description":"Files"},{"name":"InCar","description":"Digital in-car training sheets, QR sign, PDF"},{"name":"Instructors","description":"In-car instructors"},{"name":"LangRecords","description":"LangRecords"},{"name":"Languages","description":"Languages"},{"name":"Locations","description":"Cities / locations"},{"name":"Packages","description":"Course packages"},{"name":"Products","description":"Products"},{"name":"Public","description":"Public marketing endpoints"},{"name":"Roles","description":"Roles"},{"name":"SchoolStudents","description":"School-scoped students"},{"name":"SchoolUsers","description":"School staff accounts"},{"name":"Schools","description":"Driving school partners and public directory"},{"name":"Settings","description":"App settings"},{"name":"StripeWebhook","description":"StripeWebhook"},{"name":"System","description":"Health and OpenAPI discovery"},{"name":"Transactions","description":"Payment transactions"},{"name":"Users","description":"User management"},{"name":"World","description":"World"}],"servers":[{"url":"https://incar.api.roshsur.com","description":"Current API server"}]}