Yimaru-BackEnd/docs/docs.go
Yared Yemane 2f73b60122 Allow ADMIN users to bulk deactivate and reactivate by role.
Platform ADMIN callers no longer hit 403 on these endpoints; bulk changes to platform users.role ADMIN remain restricted to SUPER_ADMIN, while team_members.team_role ADMIN is still eligible under path ADMIN.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 01:09:42 -07:00

13054 lines
441 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Package docs Code generated by swaggo/swag. DO NOT EDIT
package docs
import "github.com/swaggo/swag"
const docTemplate = `{
"schemes": {{ marshal .Schemes }},
"swagger": "2.0",
"info": {
"description": "{{escape .Description}}",
"title": "{{.Title}}",
"termsOfService": "http://swagger.io/terms/",
"contact": {
"name": "API Support",
"url": "http://www.swagger.io/support",
"email": "support@swagger.io"
},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
},
"version": "{{.Version}}"
},
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/api/v1/activity-logs": {
"get": {
"description": "Returns a filtered, paginated list of activity logs",
"produces": [
"application/json"
],
"tags": [
"activity-logs"
],
"summary": "Get activity logs",
"parameters": [
{
"type": "integer",
"description": "Filter by actor ID",
"name": "actor_id",
"in": "query"
},
{
"type": "string",
"description": "Filter by action",
"name": "action",
"in": "query"
},
{
"type": "string",
"description": "Filter by resource type",
"name": "resource_type",
"in": "query"
},
{
"type": "integer",
"description": "Filter by resource ID",
"name": "resource_id",
"in": "query"
},
{
"type": "string",
"description": "Filter logs after this RFC3339 timestamp",
"name": "after",
"in": "query"
},
{
"type": "string",
"description": "Filter logs before this RFC3339 timestamp",
"name": "before",
"in": "query"
},
{
"type": "integer",
"default": 20,
"description": "Limit",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/activity-logs/{id}": {
"get": {
"description": "Returns a single activity log entry by its ID",
"produces": [
"application/json"
],
"tags": [
"activity-logs"
],
"summary": "Get activity log by ID",
"parameters": [
{
"type": "integer",
"description": "Activity Log ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/admin": {
"get": {
"description": "Get all Admins",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Get all Admins",
"parameters": [
{
"type": "integer",
"description": "Page number",
"name": "page",
"in": "query"
},
{
"type": "integer",
"description": "Page size",
"name": "page_size",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.AdminRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"post": {
"description": "Create Admin",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Create Admin",
"parameters": [
{
"description": "Create admin",
"name": "manger",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.CreateAdminReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/admin/faqs": {
"get": {
"description": "Returns FAQs for admin management with status/category filtering",
"produces": [
"application/json"
],
"tags": [
"faqs"
],
"summary": "List FAQs (admin)",
"parameters": [
{
"type": "string",
"description": "ACTIVE or INACTIVE",
"name": "status",
"in": "query"
},
{
"type": "string",
"description": "Filter by category",
"name": "category",
"in": "query"
},
{
"type": "integer",
"description": "Limit (default 20)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Offset (default 0)",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"post": {
"description": "Creates a new FAQ item",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"faqs"
],
"summary": "Create FAQ",
"parameters": [
{
"description": "Create FAQ payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.createFAQReq"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/admin/faqs/{id}": {
"get": {
"description": "Returns one FAQ regardless of status",
"produces": [
"application/json"
],
"tags": [
"faqs"
],
"summary": "Get FAQ by ID (admin)",
"parameters": [
{
"type": "integer",
"description": "FAQ ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"put": {
"description": "Updates an existing FAQ item",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"faqs"
],
"summary": "Update FAQ",
"parameters": [
{
"type": "integer",
"description": "FAQ ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Update FAQ payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.updateFAQReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"delete": {
"description": "Deletes an FAQ item",
"produces": [
"application/json"
],
"tags": [
"faqs"
],
"summary": "Delete FAQ",
"parameters": [
{
"type": "integer",
"description": "FAQ ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/admin/roles/{role}/bulk-deactivate": {
"post": {
"security": [
{
"Bearer": []
}
],
"description": "Sets all platform users with the given users.role to DEACTIVATED (except the caller) and all team_members with the given team_role to inactive. The path role must match a valid learner role or team role string (e.g. STUDENT, INSTRUCTOR, ADMIN, CONTENT_MANAGER). SUPER_ADMIN cannot be bulk-deactivated. ADMIN platform users must use SUPER_ADMIN to bulk change other platform ADMIN users (team_members with team_role ADMIN under path ADMIN remain allowed). Empty body allowed; optionally pass exclude_team_member_id to skip one team_members row (e.g. yourself).",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Bulk deactivate accounts by role (SUPER_ADMIN or ADMIN platform users only)",
"parameters": [
{
"type": "string",
"description": "Role key (matches users.role and/or team_members.team_role)",
"name": "role",
"in": "path",
"required": true
},
{
"description": "Optional exclusions",
"name": "body",
"in": "body",
"schema": {
"$ref": "#/definitions/domain.BulkAccountsByRoleRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/admin/roles/{role}/bulk-reactivate": {
"post": {
"security": [
{
"Bearer": []
}
],
"description": "Sets all platform users with the given role from DEACTIVATED to ACTIVE (except the caller) and all team_members with the given team_role from inactive to active. Path role must be a valid platform or team role. SUPER_ADMIN cannot be bulk changed. ADMIN callers cannot bulk change other platform ADMIN users (team_members ADMIN under path ADMIN is allowed). Matches only users currently DEACTIVATED and team rows currently inactive.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Bulk reactivate accounts by role (SUPER_ADMIN or ADMIN platform users only)",
"parameters": [
{
"type": "string",
"description": "Role key (matches users.role and/or team_members.team_role)",
"name": "role",
"in": "path",
"required": true
},
{
"description": "Optional exclusions",
"name": "body",
"in": "body",
"schema": {
"$ref": "#/definitions/domain.BulkAccountsByRoleRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/admin/users/deletion-requests": {
"get": {
"description": "Returns account deletion requests for admin panel tracking with filtering and pagination",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "List account deletion requests",
"parameters": [
{
"type": "string",
"description": "Search in first_name, last_name, email, phone_number",
"name": "query",
"in": "query"
},
{
"type": "string",
"description": "Role filter",
"name": "role",
"in": "query"
},
{
"type": "string",
"description": "User status filter (ACTIVE, PENDING, SUSPENDED, DEACTIVATED)",
"name": "status",
"in": "query"
},
{
"type": "string",
"description": "Deletion state filter (PENDING, DUE, CANCELLED)",
"name": "state",
"in": "query"
},
{
"type": "string",
"description": "Requested before (RFC3339)",
"name": "requested_before",
"in": "query"
},
{
"type": "string",
"description": "Requested after (RFC3339)",
"name": "requested_after",
"in": "query"
},
{
"type": "string",
"description": "Scheduled before (RFC3339)",
"name": "scheduled_before",
"in": "query"
},
{
"type": "string",
"description": "Scheduled after (RFC3339)",
"name": "scheduled_after",
"in": "query"
},
{
"type": "integer",
"description": "Page number (default 1)",
"name": "page",
"in": "query"
},
{
"type": "integer",
"description": "Page size (default 10, max 100)",
"name": "page_size",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/admin/users/{user_id}/lms-learning-activity": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "Returns programs, courses, modules, and lessons with completion details and completed practices. Only persisted completion signals are included (completed lessons, completed published practices, and rollup completion timestamps—not partial or in-progress attempts).",
"produces": [
"application/json"
],
"tags": [
"lms"
],
"summary": "Get a user's nested LMS learning activity (admin)",
"parameters": [
{
"type": "integer",
"description": "Target user ID",
"name": "user_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/admin/users/{user_id}/recent-activity": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "Reverse-chronological feed for profile UI: account joined plus LMS completion milestones (lessons/modules/courses/programs). Optional practice completions via include_practices. Does not include \"started learning path\" unless you add persisted engagement events—the schema stores completions only.",
"produces": [
"application/json"
],
"tags": [
"lms"
],
"summary": "Recent activity timeline for a user (admin)",
"parameters": [
{
"type": "integer",
"description": "Target user ID",
"name": "user_id",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "Max items after merge (default 40, max 120)",
"name": "limit",
"in": "query"
},
{
"type": "boolean",
"description": "Include completed LMS practices (more verbose)",
"name": "include_practices",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/admin/{id}": {
"get": {
"description": "Get a single admin by id",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Get admin by id",
"parameters": [
{
"type": "integer",
"description": "User ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.AdminRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"put": {
"description": "Update Admin",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Update Admin",
"parameters": [
{
"description": "Update Admin",
"name": "admin",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.updateAdminReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/analytics/dashboard": {
"get": {
"description": "Platform analytics with optional date filters: all-time (default), year, year+month, or custom from/to range. When year is set, payments.revenue_monthly returns JanDec SUCCESS revenue totals (UTC) per currency for that calendar year — use for yearly revenue charts. Daily series remains in revenue_last_30_days (see date_filter.series_*). Courses section counts LMS + exam_prep inventory.",
"produces": [
"application/json"
],
"tags": [
"analytics"
],
"summary": "Analytics dashboard",
"parameters": [
{
"type": "integer",
"description": "Calendar year (e.g. 2025)",
"name": "year",
"in": "query"
},
{
"type": "integer",
"description": "Calendar month 1-12 (requires year)",
"name": "month",
"in": "query"
},
{
"type": "string",
"description": "Custom range start (YYYY-MM-DD or RFC3339)",
"name": "from",
"in": "query"
},
{
"type": "string",
"description": "Custom range end (YYYY-MM-DD or RFC3339, inclusive)",
"name": "to",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.AnalyticsDashboard"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/assessment/questions": {
"get": {
"description": "Returns all active assessment questions from the initial assessment set",
"produces": [
"application/json"
],
"tags": [
"assessment-question"
],
"summary": "List assessment questions",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.QuestionWithDetails"
}
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"post": {
"description": "Creates a new assessment question using the unified questions system",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"assessment-question"
],
"summary": "Create assessment question",
"parameters": [
{
"description": "Create question payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.createQuestionReq"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/assessment/questions/{id}": {
"get": {
"description": "Returns a single assessment question with its options or answer",
"produces": [
"application/json"
],
"tags": [
"assessment-question"
],
"summary": "Get assessment question by ID",
"parameters": [
{
"type": "integer",
"description": "Question ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.QuestionWithDetails"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/auth/google/android": {
"post": {
"tags": [
"auth"
],
"summary": "Login via Google Android ID Token",
"parameters": [
{
"description": "Google ID Token from Android",
"name": "idToken",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {}
}
},
"/api/v1/auth/google/callback": {
"get": {
"tags": [
"auth"
],
"summary": "Google login callback",
"responses": {}
}
},
"/api/v1/auth/google/login": {
"get": {
"tags": [
"auth"
],
"summary": "Google login redirect",
"responses": {}
}
},
"/api/v1/auth/logout": {
"post": {
"description": "Logout user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"auth"
],
"summary": "Logout user",
"parameters": [
{
"description": "Logout user",
"name": "logout",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.logoutReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/auth/refresh": {
"post": {
"description": "Refresh token",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"auth"
],
"summary": "Refresh token",
"parameters": [
{
"description": "tokens",
"name": "refresh",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.refreshToken"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.loginUserRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/courses/{courseId}/modules": {
"get": {
"produces": [
"application/json"
],
"tags": [
"modules"
],
"summary": "List modules for a course",
"parameters": [
{
"type": "integer",
"description": "Course ID",
"name": "courseId",
"in": "path",
"required": true
},
{
"type": "integer",
"default": 20,
"description": "Page size",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
}
}
},
"post": {
"description": "Create a module under a course; parent program is taken from the course.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"modules"
],
"summary": "Create module",
"parameters": [
{
"type": "integer",
"description": "Course ID",
"name": "courseId",
"in": "path",
"required": true
},
{
"description": "Module",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.CreateModuleInput"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/courses/{courseId}/modules/reorder": {
"put": {
"tags": [
"modules"
],
"summary": "Reorder modules within a course",
"parameters": [
{
"type": "integer",
"description": "Course ID",
"name": "courseId",
"in": "path",
"required": true
},
{
"description": "ordered_ids: every module id in this course, in the new order",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.ReorderIDsRequest"
}
}
],
"responses": {}
}
},
"/api/v1/courses/{id}": {
"get": {
"produces": [
"application/json"
],
"tags": [
"courses"
],
"summary": "Get course by ID",
"parameters": [
{
"type": "integer",
"description": "Course ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"put": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"courses"
],
"summary": "Update course",
"parameters": [
{
"type": "integer",
"description": "Course ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Fields to update",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.UpdateCourseInput"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"delete": {
"tags": [
"courses"
],
"summary": "Delete course",
"parameters": [
{
"type": "integer",
"description": "Course ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/courses/{id}/practices": {
"get": {
"tags": [
"practices"
],
"parameters": [
{
"type": "integer",
"description": "Course ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {}
}
},
"/api/v1/exam-prep/catalog-courses": {
"get": {
"produces": [
"application/json"
],
"tags": [
"exam-prep"
],
"summary": "List exam-prep catalog courses",
"parameters": [
{
"type": "integer",
"default": 20,
"description": "Page size",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
}
}
},
"post": {
"description": "Top-level exam track (DET, IELTS, …) in schema exam_prep — separate from LMS programs/courses",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"exam-prep"
],
"summary": "Create exam-prep catalog course",
"parameters": [
{
"description": "Catalog course",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.CreateExamPrepCatalogCourseInput"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/exam-prep/catalog-courses/reorder": {
"put": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"exam-prep"
],
"summary": "Reorder all exam-prep catalog courses",
"parameters": [
{
"description": "ordered_ids: every catalog course id exactly once",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.ReorderIDsRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
}
}
}
},
"/api/v1/exam-prep/catalog-courses/{catalogCourseId}/units": {
"get": {
"tags": [
"exam-prep"
],
"summary": "List exam-prep units for a catalog course",
"parameters": [
{
"type": "integer",
"description": "Catalog course ID",
"name": "catalogCourseId",
"in": "path",
"required": true
},
{
"type": "integer",
"default": 20,
"description": "Page size",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
}
}
},
"post": {
"description": "Unit under a catalog course (e.g. chapter title)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"exam-prep"
],
"summary": "Create exam-prep unit",
"parameters": [
{
"type": "integer",
"description": "Catalog course ID",
"name": "catalogCourseId",
"in": "path",
"required": true
},
{
"description": "Unit",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.CreateExamPrepUnitInput"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/domain.Response"
}
}
}
}
},
"/api/v1/exam-prep/catalog-courses/{catalogCourseId}/units/reorder": {
"put": {
"tags": [
"exam-prep"
],
"summary": "Reorder units within a catalog course",
"parameters": [
{
"type": "integer",
"description": "Catalog course ID",
"name": "catalogCourseId",
"in": "path",
"required": true
},
{
"description": "ordered_ids: every unit id in this catalog course, new order",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.ReorderIDsRequest"
}
}
],
"responses": {}
}
},
"/api/v1/exam-prep/catalog-courses/{id}": {
"get": {
"produces": [
"application/json"
],
"tags": [
"exam-prep"
],
"summary": "Get exam-prep catalog course by ID",
"parameters": [
{
"type": "integer",
"description": "Catalog course ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
}
}
},
"put": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"exam-prep"
],
"summary": "Update exam-prep catalog course",
"parameters": [
{
"type": "integer",
"description": "Catalog course ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Fields to update",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.UpdateExamPrepCatalogCourseInput"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
}
}
},
"delete": {
"tags": [
"exam-prep"
],
"summary": "Delete exam-prep catalog course",
"parameters": [
{
"type": "integer",
"description": "Catalog course ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
}
}
}
},
"/api/v1/exam-prep/lessons/{id}": {
"get": {
"tags": [
"exam-prep"
],
"summary": "Get exam-prep lesson by ID",
"responses": {}
},
"put": {
"tags": [
"exam-prep"
],
"summary": "Update exam-prep lesson",
"responses": {}
},
"delete": {
"tags": [
"exam-prep"
],
"summary": "Delete exam-prep lesson",
"responses": {}
}
},
"/api/v1/exam-prep/lessons/{lessonId}/practices": {
"get": {
"tags": [
"exam-prep"
],
"summary": "List exam-prep practices for a lesson",
"parameters": [
{
"type": "integer",
"description": "Exam prep lesson ID",
"name": "lessonId",
"in": "path",
"required": true
},
{
"type": "integer",
"default": 20,
"description": "Page size",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {}
},
"post": {
"tags": [
"exam-prep"
],
"summary": "Create exam-prep practice (under a lesson; uses shared question_sets)",
"parameters": [
{
"type": "integer",
"description": "Exam prep lesson ID (unit_module_lessons.id)",
"name": "lessonId",
"in": "path",
"required": true
},
{
"description": "Practice",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.CreateExamPrepPracticeInput"
}
}
],
"responses": {}
}
},
"/api/v1/exam-prep/modules/{id}": {
"get": {
"tags": [
"exam-prep"
],
"summary": "Get exam-prep module by ID",
"responses": {}
},
"put": {
"tags": [
"exam-prep"
],
"summary": "Update exam-prep module",
"responses": {}
},
"delete": {
"tags": [
"exam-prep"
],
"summary": "Delete exam-prep module",
"responses": {}
}
},
"/api/v1/exam-prep/modules/{moduleId}/lessons": {
"get": {
"tags": [
"exam-prep"
],
"summary": "List exam-prep lessons for a unit module",
"parameters": [
{
"type": "integer",
"description": "Exam prep unit module ID",
"name": "moduleId",
"in": "path",
"required": true
},
{
"type": "integer",
"default": 20,
"description": "Page size",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {}
},
"post": {
"tags": [
"exam-prep"
],
"summary": "Create exam-prep lesson (under a unit module)",
"parameters": [
{
"type": "integer",
"description": "Exam prep unit module ID",
"name": "moduleId",
"in": "path",
"required": true
},
{
"description": "Lesson",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.CreateExamPrepLessonInput"
}
}
],
"responses": {}
}
},
"/api/v1/exam-prep/modules/{moduleId}/lessons/reorder": {
"put": {
"tags": [
"exam-prep"
],
"summary": "Reorder lessons within an exam-prep unit module",
"responses": {}
}
},
"/api/v1/exam-prep/practices/{id}": {
"get": {
"tags": [
"exam-prep"
],
"summary": "Get exam-prep practice by ID",
"parameters": [
{
"type": "integer",
"description": "Exam prep practice ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {}
},
"put": {
"tags": [
"exam-prep"
],
"summary": "Update exam-prep practice",
"parameters": [
{
"type": "integer",
"description": "Exam prep practice ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Fields to update",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.UpdateExamPrepPracticeInput"
}
}
],
"responses": {}
},
"delete": {
"tags": [
"exam-prep"
],
"summary": "Delete exam-prep practice",
"parameters": [
{
"type": "integer",
"description": "Exam prep practice ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {}
}
},
"/api/v1/exam-prep/units/{id}": {
"get": {
"tags": [
"exam-prep"
],
"summary": "Get exam-prep unit by ID",
"parameters": [
{
"type": "integer",
"description": "Unit ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {}
},
"put": {
"tags": [
"exam-prep"
],
"summary": "Update exam-prep unit",
"parameters": [
{
"type": "integer",
"description": "Unit ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Fields to update",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.UpdateExamPrepUnitInput"
}
}
],
"responses": {}
},
"delete": {
"tags": [
"exam-prep"
],
"summary": "Delete exam-prep unit",
"parameters": [
{
"type": "integer",
"description": "Unit ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {}
}
},
"/api/v1/exam-prep/units/{unitId}/modules": {
"get": {
"tags": [
"exam-prep"
],
"summary": "List exam-prep modules for a unit",
"parameters": [
{
"type": "integer",
"description": "Unit ID",
"name": "unitId",
"in": "path",
"required": true
}
],
"responses": {}
},
"post": {
"tags": [
"exam-prep"
],
"summary": "Create exam-prep module",
"parameters": [
{
"type": "integer",
"description": "Unit ID",
"name": "unitId",
"in": "path",
"required": true
},
{
"description": "Module",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.CreateExamPrepModuleInput"
}
}
],
"responses": {}
}
},
"/api/v1/exam-prep/units/{unitId}/modules/reorder": {
"put": {
"tags": [
"exam-prep"
],
"summary": "Reorder modules within a unit",
"parameters": [
{
"type": "integer",
"description": "Unit ID",
"name": "unitId",
"in": "path",
"required": true
},
{
"description": "ordered_ids",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.ReorderIDsRequest"
}
}
],
"responses": {}
}
},
"/api/v1/faqs": {
"get": {
"description": "Returns active FAQs for public/help center usage",
"produces": [
"application/json"
],
"tags": [
"faqs"
],
"summary": "List published FAQs",
"parameters": [
{
"type": "string",
"description": "Filter by category",
"name": "category",
"in": "query"
},
{
"type": "integer",
"description": "Limit (default 50)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Offset (default 0)",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/faqs/{id}": {
"get": {
"description": "Returns one active FAQ item",
"produces": [
"application/json"
],
"tags": [
"faqs"
],
"summary": "Get published FAQ by ID",
"parameters": [
{
"type": "integer",
"description": "FAQ ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/files/audio": {
"post": {
"consumes": [
"multipart/form-data"
],
"tags": [
"files"
],
"summary": "Upload an audio file",
"parameters": [
{
"type": "file",
"description": "Audio file (mp3, wav, ogg, m4a, aac, webm)",
"name": "file",
"in": "formData",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
}
}
}
},
"/api/v1/files/refresh-url": {
"post": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"files"
],
"summary": "Refresh presigned URL for a file",
"parameters": [
{
"description": "reference (object key, minio://..., or existing presigned URL)",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.refreshFileURLReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
}
}
}
},
"/api/v1/files/upload": {
"post": {
"consumes": [
"multipart/form-data"
],
"tags": [
"files"
],
"summary": "Upload media file",
"parameters": [
{
"type": "string",
"description": "Media type: image|audio|video",
"name": "media_type",
"in": "formData",
"required": true
},
{
"type": "file",
"description": "Media file",
"name": "file",
"in": "formData",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
}
}
}
},
"/api/v1/files/url": {
"get": {
"tags": [
"files"
],
"summary": "Get presigned URL for a file",
"parameters": [
{
"type": "string",
"description": "MinIO object key (e.g. profile_pictures/uuid.jpg)",
"name": "key",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
}
}
}
},
"/api/v1/internal/users/purge-due-deletions": {
"post": {
"security": [
{
"Bearer": []
}
],
"description": "Worker-safe purge for due self-deletion requests",
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Purge due account deletions",
"parameters": [
{
"type": "integer",
"description": "Max users to purge in one run (default 100, max 1000)",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/issues": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "Returns all reported issues with pagination (admin only)",
"produces": [
"application/json"
],
"tags": [
"issues"
],
"summary": "Get all issues",
"parameters": [
{
"type": "integer",
"default": 20,
"description": "Limit",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/domain.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/handlers.issueListRes"
}
}
}
]
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"post": {
"security": [
{
"Bearer": []
}
],
"description": "Allows any authenticated user to report an issue they encountered",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"issues"
],
"summary": "Report an issue",
"parameters": [
{
"description": "Issue report payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.createIssueReq"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"allOf": [
{
"$ref": "#/definitions/domain.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/handlers.issueRes"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/issues/me": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "Returns paginated issues reported by the authenticated user",
"produces": [
"application/json"
],
"tags": [
"issues"
],
"summary": "Get my reported issues",
"parameters": [
{
"type": "integer",
"default": 20,
"description": "Limit",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/domain.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/handlers.issueListRes"
}
}
}
]
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/issues/user/{user_id}": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "Returns paginated issues reported by a specific user (admin only)",
"produces": [
"application/json"
],
"tags": [
"issues"
],
"summary": "Get issues for a specific user",
"parameters": [
{
"type": "integer",
"description": "User ID",
"name": "user_id",
"in": "path",
"required": true
},
{
"type": "integer",
"default": 20,
"description": "Limit",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/domain.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/handlers.issueListRes"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/issues/{id}": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "Returns a single issue report by its ID (admin only)",
"produces": [
"application/json"
],
"tags": [
"issues"
],
"summary": "Get issue by ID",
"parameters": [
{
"type": "integer",
"description": "Issue ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/domain.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/handlers.issueRes"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"delete": {
"security": [
{
"Bearer": []
}
],
"description": "Deletes an issue report (admin only)",
"produces": [
"application/json"
],
"tags": [
"issues"
],
"summary": "Delete an issue",
"parameters": [
{
"type": "integer",
"description": "Issue ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/issues/{id}/status": {
"patch": {
"security": [
{
"Bearer": []
}
],
"description": "Updates the status of an issue (admin only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"issues"
],
"summary": "Update issue status",
"parameters": [
{
"type": "integer",
"description": "Issue ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Status update payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.updateIssueStatusReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/lessons/{id}": {
"get": {
"tags": [
"lessons"
],
"parameters": [
{
"type": "integer",
"description": "Lesson ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {}
},
"put": {
"tags": [
"lessons"
],
"parameters": [
{
"type": "integer",
"description": "Lesson ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Fields to update",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.UpdateLessonInput"
}
}
],
"responses": {}
},
"delete": {
"tags": [
"lessons"
],
"parameters": [
{
"type": "integer",
"description": "Lesson ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {}
}
},
"/api/v1/lessons/{id}/complete": {
"post": {
"description": "Records lesson completion; may cascade to module, course, and program progress for the authenticated user. Learners must meet sequential prerequisites; staff bypass checks.",
"tags": [
"lessons"
],
"summary": "Mark a lesson as completed",
"parameters": [
{
"type": "integer",
"description": "Lesson ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/lessons/{id}/practices": {
"get": {
"tags": [
"practices"
],
"parameters": [
{
"type": "integer",
"description": "Lesson ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {}
}
},
"/api/v1/lms/progress": {
"get": {
"description": "Returns completed lesson, module, course, and program IDs for the authenticated user (ordered by completion time, then id).",
"produces": [
"application/json"
],
"tags": [
"lms"
],
"summary": "Get my LMS completion history",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/logs": {
"get": {
"description": "Fetches application logs from MongoDB with pagination, level filtering, and search",
"produces": [
"application/json"
],
"tags": [
"Logs"
],
"summary": "Retrieve application logs with filtering and pagination",
"parameters": [
{
"type": "string",
"description": "Filter logs by level (debug, info, warn, error, dpanic, panic, fatal)",
"name": "level",
"in": "query"
},
{
"type": "string",
"description": "Search term to match against message or fields",
"name": "search",
"in": "query"
},
{
"type": "integer",
"default": 1,
"description": "Page number for pagination (default: 1)",
"name": "page",
"in": "query"
},
{
"type": "integer",
"default": 50,
"description": "Number of items per page (default: 50, max: 100)",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "Paginated list of application logs",
"schema": {
"$ref": "#/definitions/domain.LogResponse"
}
},
"400": {
"description": "Invalid request parameters",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/modules/{id}": {
"get": {
"tags": [
"modules"
],
"parameters": [
{
"type": "integer",
"description": "Module ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
}
}
},
"put": {
"tags": [
"modules"
],
"parameters": [
{
"type": "integer",
"description": "Module ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Fields to update",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.UpdateModuleInput"
}
}
],
"responses": {}
},
"delete": {
"tags": [
"modules"
],
"parameters": [
{
"type": "integer",
"description": "Module ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {}
}
},
"/api/v1/modules/{id}/practices": {
"get": {
"tags": [
"practices"
],
"parameters": [
{
"type": "integer",
"description": "Module ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {}
}
},
"/api/v1/modules/{moduleId}/lessons": {
"get": {
"tags": [
"lessons"
],
"parameters": [
{
"type": "integer",
"description": "Module ID",
"name": "moduleId",
"in": "path",
"required": true
},
{
"type": "integer",
"default": 20,
"description": "Page size",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {}
},
"post": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"lessons"
],
"summary": "Create lesson",
"parameters": [
{
"type": "integer",
"description": "Module ID",
"name": "moduleId",
"in": "path",
"required": true
},
{
"description": "Lesson",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.CreateLessonInput"
}
}
],
"responses": {}
}
},
"/api/v1/notifications/bulk-email": {
"post": {
"description": "Sends an email to specified user IDs, all users of a role, or direct email addresses with optional image attachment. Optionally schedule for later with scheduled_at (RFC3339).",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"notifications"
],
"summary": "Send bulk email",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/notifications/bulk-push": {
"post": {
"description": "Sends a push notification to specified user IDs or all users matching a role. Optionally schedule for later with scheduled_at (RFC3339).",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"notifications"
],
"summary": "Send bulk push notification",
"parameters": [
{
"description": "Bulk push content",
"name": "body",
"in": "body",
"required": true,
"schema": {
"type": "object",
"properties": {
"image": {
"type": "string"
},
"message": {
"type": "string"
},
"role": {
"type": "string"
},
"scheduled_at": {
"type": "string"
},
"title": {
"type": "string"
},
"user_ids": {
"type": "array",
"items": {
"type": "integer",
"format": "int64"
}
}
}
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/notifications/bulk-sms": {
"post": {
"description": "Sends an SMS to specified user IDs, all users of a role, or direct phone numbers. Optionally schedule for later with scheduled_at (RFC3339).",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"notifications"
],
"summary": "Send bulk SMS",
"parameters": [
{
"description": "Bulk SMS content",
"name": "body",
"in": "body",
"required": true,
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string"
},
"phone_numbers": {
"type": "array",
"items": {
"type": "string"
}
},
"role": {
"type": "string"
},
"scheduled_at": {
"type": "string"
},
"user_ids": {
"type": "array",
"items": {
"type": "integer",
"format": "int64"
}
}
}
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/notifications/scheduled": {
"get": {
"description": "Returns paginated scheduled notifications with optional status, channel, and date filters",
"produces": [
"application/json"
],
"tags": [
"notifications"
],
"summary": "List scheduled notifications",
"parameters": [
{
"type": "string",
"description": "Filter by status",
"name": "status",
"in": "query"
},
{
"type": "string",
"description": "Filter by channel",
"name": "channel",
"in": "query"
},
{
"type": "string",
"description": "Filter after date (RFC3339)",
"name": "after",
"in": "query"
},
{
"type": "string",
"description": "Filter before date (RFC3339)",
"name": "before",
"in": "query"
},
{
"type": "integer",
"default": 20,
"description": "Page size",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 1,
"description": "Page number",
"name": "page",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/notifications/scheduled/{id}": {
"get": {
"description": "Returns a single scheduled notification by its ID",
"produces": [
"application/json"
],
"tags": [
"notifications"
],
"summary": "Get scheduled notification",
"parameters": [
{
"type": "integer",
"description": "Scheduled Notification ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/notifications/scheduled/{id}/cancel": {
"post": {
"description": "Cancels a scheduled notification if it is still pending or processing",
"produces": [
"application/json"
],
"tags": [
"notifications"
],
"summary": "Cancel scheduled notification",
"parameters": [
{
"type": "integer",
"description": "Scheduled Notification ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/notifications/send-email": {
"post": {
"description": "Sends an email to a single email address with optional image attachment",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"notifications"
],
"summary": "Send single email",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/notifications/test-push": {
"post": {
"description": "Sends a test push notification to all registered devices of the current user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"notifications"
],
"summary": "Send test push notification",
"parameters": [
{
"description": "Test notification content",
"name": "body",
"in": "body",
"required": true,
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string"
},
"title": {
"type": "string"
}
}
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/payments": {
"get": {
"description": "Returns the authenticated user's payment history",
"produces": [
"application/json"
],
"tags": [
"payments"
],
"summary": "Get payment history",
"parameters": [
{
"type": "integer",
"default": 20,
"description": "Limit",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
}
}
}
},
"/api/v1/payments/direct": {
"post": {
"description": "Creates a payment session and initiates direct payment (OTP-based)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"payments"
],
"summary": "Initiate direct payment",
"parameters": [
{
"description": "Direct payment request",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.initiateDirectPaymentReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/payments/direct/methods": {
"get": {
"description": "Returns list of payment methods that support direct payment (OTP-based)",
"produces": [
"application/json"
],
"tags": [
"payments"
],
"summary": "Get direct payment methods",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
}
}
}
},
"/api/v1/payments/direct/verify-otp": {
"post": {
"description": "Verifies the OTP sent for direct payment methods (Amole, HelloCash, etc.)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"payments"
],
"summary": "Verify OTP for direct payment",
"parameters": [
{
"description": "OTP verification request",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.verifyOTPReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/payments/methods": {
"get": {
"description": "Returns list of supported ArifPay payment methods",
"produces": [
"application/json"
],
"tags": [
"payments"
],
"summary": "Get available payment methods",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
}
}
}
},
"/api/v1/payments/subscribe": {
"post": {
"description": "Creates a payment session for a subscription plan",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"payments"
],
"summary": "Initiate subscription payment",
"parameters": [
{
"description": "Payment request",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.initiatePaymentReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/payments/verify/{session_id}": {
"get": {
"description": "Checks the payment status with the payment provider",
"produces": [
"application/json"
],
"tags": [
"payments"
],
"summary": "Verify payment status",
"parameters": [
{
"type": "string",
"description": "Session ID",
"name": "session_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/payments/webhook": {
"post": {
"description": "Processes payment notifications from ArifPay",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"payments"
],
"summary": "Handle ArifPay webhook",
"parameters": [
{
"description": "Webhook payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.WebhookRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/payments/{id}": {
"get": {
"description": "Returns details of a specific payment",
"produces": [
"application/json"
],
"tags": [
"payments"
],
"summary": "Get payment details",
"parameters": [
{
"type": "integer",
"description": "Payment ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/payments/{id}/cancel": {
"post": {
"description": "Cancels a payment that is still pending",
"produces": [
"application/json"
],
"tags": [
"payments"
],
"summary": "Cancel a pending payment",
"parameters": [
{
"type": "integer",
"description": "Payment ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/practices": {
"post": {
"consumes": [
"application/json"
],
"tags": [
"practices"
],
"parameters": [
{
"description": "Practice (parent_kind: COURSE | MODULE | LESSON)",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.CreatePracticeInput"
}
}
],
"responses": {}
}
},
"/api/v1/practices/{id}": {
"get": {
"tags": [
"practices"
],
"parameters": [
{
"type": "integer",
"description": "Practice ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {}
},
"put": {
"tags": [
"practices"
],
"parameters": [
{
"type": "integer",
"description": "Practice ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Fields to update (parent is immutable)",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.UpdatePracticeInput"
}
}
],
"responses": {}
},
"delete": {
"tags": [
"practices"
],
"parameters": [
{
"type": "integer",
"description": "Practice ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {}
}
},
"/api/v1/practices/{practiceId}/questions": {
"get": {
"description": "Returns paginated questions for a practice(question-set), including AUDIO fields",
"produces": [
"application/json"
],
"tags": [
"question-set-items"
],
"summary": "Get questions by practice",
"parameters": [
{
"type": "integer",
"description": "Practice(question-set) ID",
"name": "practiceId",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Question type filter (e.g. AUDIO)",
"name": "question_type",
"in": "query"
},
{
"type": "integer",
"default": 10,
"description": "Limit",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/programs": {
"get": {
"description": "Paginated list of programs",
"produces": [
"application/json"
],
"tags": [
"programs"
],
"summary": "List programs",
"parameters": [
{
"type": "integer",
"default": 20,
"description": "Page size",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"post": {
"description": "Create a top-level LMS program",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"programs"
],
"summary": "Create program",
"parameters": [
{
"description": "Program",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.CreateProgramInput"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/programs/reorder": {
"put": {
"description": "Sets learning order of programs. Body must list every current program id exactly once, in the desired order (index 0 = first in path).",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"programs"
],
"summary": "Reorder all programs",
"parameters": [
{
"description": "New order: ordered_ids is the full set of program ids",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.ReorderIDsRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/programs/{id}": {
"get": {
"produces": [
"application/json"
],
"tags": [
"programs"
],
"summary": "Get program by ID",
"parameters": [
{
"type": "integer",
"description": "Program ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"put": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"programs"
],
"summary": "Update program",
"parameters": [
{
"type": "integer",
"description": "Program ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Fields to update",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.UpdateProgramInput"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"delete": {
"tags": [
"programs"
],
"summary": "Delete program",
"parameters": [
{
"type": "integer",
"description": "Program ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/programs/{id}/courses": {
"get": {
"produces": [
"application/json"
],
"tags": [
"courses"
],
"summary": "List courses by program",
"parameters": [
{
"type": "integer",
"description": "Program ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "integer",
"default": 20,
"description": "Page size",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"post": {
"description": "Create a course under a program",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"courses"
],
"summary": "Create course",
"parameters": [
{
"type": "integer",
"description": "Program ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Course",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.CreateCourseInput"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/programs/{id}/courses/reorder": {
"put": {
"tags": [
"courses"
],
"summary": "Reorder courses within a program",
"parameters": [
{
"type": "integer",
"description": "Program ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "ordered_ids: every course id in this program, in the new order",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.ReorderIDsRequest"
}
}
],
"responses": {}
}
},
"/api/v1/progress/practices/{id}/complete": {
"post": {
"description": "Marks a practice question set as completed for the authenticated learner",
"produces": [
"application/json"
],
"tags": [
"progression"
],
"summary": "Mark practice as completed",
"parameters": [
{
"type": "integer",
"description": "Practice Question Set ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/question-sets": {
"get": {
"description": "Returns a paginated list of question sets filtered by type",
"produces": [
"application/json"
],
"tags": [
"question-sets"
],
"summary": "Get question sets by type",
"parameters": [
{
"type": "string",
"description": "Set type (PRACTICE, INITIAL_ASSESSMENT, QUIZ, EXAM, SURVEY, CAPSTONE)",
"name": "set_type",
"in": "query",
"required": true
},
{
"type": "integer",
"default": 10,
"description": "Limit",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"post": {
"description": "Creates a new question set (practice, assessment, quiz, exam, or survey)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"question-sets"
],
"summary": "Create a new question set",
"parameters": [
{
"description": "Create question set payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.createQuestionSetReq"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/question-sets/by-owner": {
"get": {
"description": "Returns question sets for a specific owner (e.g., sub-course)",
"produces": [
"application/json"
],
"tags": [
"question-sets"
],
"summary": "Get question sets by owner",
"parameters": [
{
"type": "string",
"description": "Owner type (SUB_COURSE, COURSE, CATEGORY, STANDALONE)",
"name": "owner_type",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "Owner ID",
"name": "owner_id",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/question-sets/{id}": {
"get": {
"description": "Returns a question set with question count",
"produces": [
"application/json"
],
"tags": [
"question-sets"
],
"summary": "Get question set by ID",
"parameters": [
{
"type": "integer",
"description": "Question Set ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"put": {
"description": "Updates a question set's properties",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"question-sets"
],
"summary": "Update a question set",
"parameters": [
{
"type": "integer",
"description": "Question Set ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Update question set payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.updateQuestionSetReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"delete": {
"description": "Archives a question set (soft delete)",
"produces": [
"application/json"
],
"tags": [
"question-sets"
],
"summary": "Delete a question set",
"parameters": [
{
"type": "integer",
"description": "Question Set ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/question-sets/{setId}/personas": {
"get": {
"description": "Returns all users assigned as personas to a question set (practice)",
"produces": [
"application/json"
],
"tags": [
"question-sets"
],
"summary": "Get user personas for a question set",
"parameters": [
{
"type": "integer",
"description": "Question Set ID",
"name": "setId",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"post": {
"description": "Links a user as a persona to a question set (practice)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"question-sets"
],
"summary": "Add a user as persona to a question set",
"parameters": [
{
"type": "integer",
"description": "Question Set ID",
"name": "setId",
"in": "path",
"required": true
},
{
"description": "Add user persona payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.addUserPersonaReq"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/question-sets/{setId}/personas/{userId}": {
"delete": {
"description": "Unlinks a user as persona from a question set (practice)",
"produces": [
"application/json"
],
"tags": [
"question-sets"
],
"summary": "Remove a user persona from a question set",
"parameters": [
{
"type": "integer",
"description": "Question Set ID",
"name": "setId",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "User ID",
"name": "userId",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/question-sets/{setId}/questions": {
"get": {
"description": "Returns all questions in a question set with details",
"produces": [
"application/json"
],
"tags": [
"question-set-items"
],
"summary": "Get questions in set",
"parameters": [
{
"type": "integer",
"description": "Question Set ID",
"name": "setId",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"post": {
"description": "Links a question to a question set",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"question-set-items"
],
"summary": "Add question to set",
"parameters": [
{
"type": "integer",
"description": "Question Set ID",
"name": "setId",
"in": "path",
"required": true
},
{
"description": "Add question to set payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.addQuestionToSetReq"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/question-sets/{setId}/questions/{questionId}": {
"delete": {
"description": "Unlinks a question from a question set",
"produces": [
"application/json"
],
"tags": [
"question-set-items"
],
"summary": "Remove question from set",
"parameters": [
{
"type": "integer",
"description": "Question Set ID",
"name": "setId",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "Question ID",
"name": "questionId",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/question-sets/{setId}/questions/{questionId}/order": {
"put": {
"description": "Updates the display order of a question in a set",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"question-set-items"
],
"summary": "Update question order in set",
"parameters": [
{
"type": "integer",
"description": "Question Set ID",
"name": "setId",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "Question ID",
"name": "questionId",
"in": "path",
"required": true
},
{
"description": "Update order payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.updateQuestionOrderReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/questions": {
"get": {
"description": "Returns a paginated list of questions with optional filters",
"produces": [
"application/json"
],
"tags": [
"questions"
],
"summary": "List questions",
"parameters": [
{
"type": "string",
"description": "Question type filter (MCQ, TRUE_FALSE, SHORT_ANSWER)",
"name": "question_type",
"in": "query"
},
{
"type": "string",
"description": "Difficulty level filter (EASY, MEDIUM, HARD)",
"name": "difficulty",
"in": "query"
},
{
"type": "string",
"description": "Status filter (DRAFT, PUBLISHED, INACTIVE)",
"name": "status",
"in": "query"
},
{
"type": "integer",
"default": 10,
"description": "Limit",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"post": {
"description": "Creates a new question with options (for MCQ/TRUE_FALSE) or short answers (for SHORT_ANSWER). Supports question_type_definition_id for dynamic builder-linked questions.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"questions"
],
"summary": "Create a new question",
"parameters": [
{
"description": "Create question payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.createQuestionReq"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/questions/audio-answer": {
"post": {
"consumes": [
"multipart/form-data"
],
"tags": [
"questions"
],
"summary": "Submit audio answer for a question",
"parameters": [
{
"type": "integer",
"description": "Question ID",
"name": "question_id",
"in": "formData",
"required": true
},
{
"type": "integer",
"description": "Question Set ID",
"name": "question_set_id",
"in": "formData",
"required": true
},
{
"type": "file",
"description": "Audio recording",
"name": "file",
"in": "formData",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
}
}
}
},
"/api/v1/questions/component-catalog": {
"get": {
"description": "Valid stimulus and response component kind codes for dynamic question-type definitions",
"produces": [
"application/json"
],
"tags": [
"questions"
],
"summary": "Question-type builder component catalog",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
}
}
}
},
"/api/v1/questions/search": {
"get": {
"description": "Search questions by text",
"produces": [
"application/json"
],
"tags": [
"questions"
],
"summary": "Search questions",
"parameters": [
{
"type": "string",
"description": "Search query",
"name": "q",
"in": "query",
"required": true
},
{
"type": "integer",
"default": 10,
"description": "Limit",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/questions/type-definitions": {
"get": {
"produces": [
"application/json"
],
"tags": [
"questions"
],
"summary": "List reusable question-type definitions",
"parameters": [
{
"type": "string",
"description": "Filter by status (ACTIVE, INACTIVE)",
"name": "status",
"in": "query"
},
{
"type": "boolean",
"description": "Include system seeded definitions",
"name": "include_system",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"post": {
"description": "Stores a reusable dynamic question-type definition for future question construction. Only runtime-mappable definitions are persisted.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"questions"
],
"summary": "Create reusable question-type definition",
"parameters": [
{
"description": "Question type definition payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.createQuestionTypeDefinitionReq"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/questions/type-definitions/{id}": {
"get": {
"produces": [
"application/json"
],
"tags": [
"questions"
],
"summary": "Get reusable question-type definition by id",
"parameters": [
{
"type": "integer",
"description": "Question type definition id",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"put": {
"description": "Updates a reusable dynamic question-type definition. Updated definitions must remain runtime-mappable.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"questions"
],
"summary": "Update reusable question-type definition",
"parameters": [
{
"type": "integer",
"description": "Question type definition id",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Update question type definition payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.updateQuestionTypeDefinitionReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"delete": {
"produces": [
"application/json"
],
"tags": [
"questions"
],
"summary": "Delete reusable question-type definition",
"parameters": [
{
"type": "integer",
"description": "Question type definition id",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/questions/validate-question-type-definition": {
"post": {
"description": "Validates selected stimulus and response component kinds for temporary question-type definitions (component-level validation only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"questions"
],
"summary": "Validate dynamic question-type definition",
"parameters": [
{
"description": "Stimulus and response component kinds",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.validateQuestionTypeDefinitionReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/questions/{id}": {
"get": {
"description": "Returns a question with its options/short answers",
"produces": [
"application/json"
],
"tags": [
"questions"
],
"summary": "Get question by ID",
"parameters": [
{
"type": "integer",
"description": "Question ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"put": {
"description": "Updates a question and optionally replaces its options/short answers. Supports question_type_definition_id for dynamic builder-linked questions.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"questions"
],
"summary": "Update a question",
"parameters": [
{
"type": "integer",
"description": "Question ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Update question payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.updateQuestionReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"delete": {
"description": "Archives a question (soft delete)",
"produces": [
"application/json"
],
"tags": [
"questions"
],
"summary": "Delete a question",
"parameters": [
{
"type": "integer",
"description": "Question ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/ratings": {
"get": {
"description": "Returns paginated ratings for a specific target",
"produces": [
"application/json"
],
"tags": [
"ratings"
],
"summary": "Get ratings for a target",
"parameters": [
{
"type": "string",
"description": "Target type (app, course, sub_course)",
"name": "target_type",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "Target ID (0 for app)",
"name": "target_id",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "Limit (default 20)",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"description": "Offset (default 0)",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"post": {
"description": "Submit a rating for an app, course, or sub-course",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"ratings"
],
"summary": "Submit a rating",
"parameters": [
{
"description": "Submit rating payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.submitRatingReq"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/ratings/me": {
"get": {
"description": "Returns the current user's rating for a specific target",
"produces": [
"application/json"
],
"tags": [
"ratings"
],
"summary": "Get my rating for a target",
"parameters": [
{
"type": "string",
"description": "Target type (app, course, sub_course)",
"name": "target_type",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "Target ID (0 for app)",
"name": "target_id",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/ratings/me/all": {
"get": {
"description": "Returns all ratings submitted by the current user",
"produces": [
"application/json"
],
"tags": [
"ratings"
],
"summary": "Get all my ratings",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/ratings/summary": {
"get": {
"description": "Returns the total count and average stars for a specific target",
"produces": [
"application/json"
],
"tags": [
"ratings"
],
"summary": "Get rating summary for a target",
"parameters": [
{
"type": "string",
"description": "Target type (app, course, sub_course)",
"name": "target_type",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "Target ID (0 for app)",
"name": "target_id",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/ratings/{id}": {
"delete": {
"description": "Deletes a rating by ID for the current user",
"produces": [
"application/json"
],
"tags": [
"ratings"
],
"summary": "Delete a rating",
"parameters": [
{
"type": "integer",
"description": "Rating ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/rbac/permissions": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "Get all permissions in the system grouped by group name",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"rbac"
],
"summary": "List all permissions",
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/domain.Response"
},
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.Permission"
}
}
}
}
]
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/rbac/permissions/groups": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "Get all distinct permission group names",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"rbac"
],
"summary": "List permission groups",
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/domain.Response"
},
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
]
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/rbac/permissions/sync": {
"post": {
"security": [
{
"Bearer": []
}
],
"description": "Re-seed permissions from code and reload the RBAC cache",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"rbac"
],
"summary": "Sync permissions",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/rbac/roles": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "Get all roles with optional filters",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"rbac"
],
"summary": "List all roles",
"parameters": [
{
"type": "string",
"description": "Search by role name",
"name": "query",
"in": "query"
},
{
"type": "boolean",
"description": "Filter by system role (true/false)",
"name": "is_system",
"in": "query"
},
{
"type": "integer",
"description": "Page number (default: 1)",
"name": "page",
"in": "query"
},
{
"type": "integer",
"description": "Page size (default: 20)",
"name": "page_size",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"post": {
"security": [
{
"Bearer": []
}
],
"description": "Create a new role with a name and description",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"rbac"
],
"summary": "Create a new role",
"parameters": [
{
"description": "Role creation payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.CreateRoleReq"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"allOf": [
{
"$ref": "#/definitions/domain.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/domain.RoleRecord"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/rbac/roles/{id}": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "Get a role and its permissions by ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"rbac"
],
"summary": "Get a role by ID",
"parameters": [
{
"type": "integer",
"description": "Role ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/domain.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/domain.RoleWithPermissions"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"put": {
"security": [
{
"Bearer": []
}
],
"description": "Update an existing role's name and description",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"rbac"
],
"summary": "Update a role",
"parameters": [
{
"type": "integer",
"description": "Role ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Role update payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.UpdateRoleReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"delete": {
"security": [
{
"Bearer": []
}
],
"description": "Delete a non-system role by ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"rbac"
],
"summary": "Delete a role",
"parameters": [
{
"type": "integer",
"description": "Role ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/rbac/roles/{id}/permissions": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "Get all permissions assigned to a role",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"rbac"
],
"summary": "Get permissions for a role",
"parameters": [
{
"type": "integer",
"description": "Role ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/domain.Response"
},
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.Permission"
}
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"put": {
"security": [
{
"Bearer": []
}
],
"description": "Replace all permissions for a role with the given permission IDs",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"rbac"
],
"summary": "Set permissions for a role",
"parameters": [
{
"type": "integer",
"description": "Role ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Permission IDs payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.SetRolePermissionsReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/sendSMS": {
"post": {
"description": "Sends an SMS message to a single phone number using AfroMessage",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Send single SMS via AfroMessage",
"parameters": [
{
"description": "Send SMS request",
"name": "sendSMS",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.SendSingleAfroSMSReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/subscription-plans": {
"get": {
"description": "Returns all subscription plans",
"produces": [
"application/json"
],
"tags": [
"subscriptions"
],
"summary": "List subscription plans",
"parameters": [
{
"type": "boolean",
"description": "Return only active plans",
"name": "active_only",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"post": {
"description": "Creates a new subscription plan (admin only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"subscriptions"
],
"summary": "Create a subscription plan",
"parameters": [
{
"description": "Create plan payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.createPlanReq"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/subscription-plans/{id}": {
"get": {
"description": "Returns a single subscription plan by ID",
"produces": [
"application/json"
],
"tags": [
"subscriptions"
],
"summary": "Get a subscription plan",
"parameters": [
{
"type": "integer",
"description": "Plan ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"put": {
"description": "Updates a subscription plan (admin only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"subscriptions"
],
"summary": "Update a subscription plan",
"parameters": [
{
"type": "integer",
"description": "Plan ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Update plan payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.updatePlanReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"delete": {
"description": "Deletes a subscription plan (admin only)",
"produces": [
"application/json"
],
"tags": [
"subscriptions"
],
"summary": "Delete a subscription plan",
"parameters": [
{
"type": "integer",
"description": "Plan ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/subscriptions": {
"post": {
"description": "Creates a new subscription for the authenticated user. For regular users, use /payments/subscribe instead.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"subscriptions"
],
"summary": "Subscribe to a plan (Admin only - bypasses payment)",
"deprecated": true,
"parameters": [
{
"description": "Subscribe payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.subscribeReq"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/subscriptions/checkout": {
"post": {
"description": "Initiates payment for a subscription plan. Returns payment URL for checkout.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"subscriptions"
],
"summary": "Subscribe to a plan with payment",
"parameters": [
{
"description": "Subscribe with payment payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.subscribeWithPaymentReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"409": {
"description": "User already has active subscription",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/subscriptions/history": {
"get": {
"description": "Returns the authenticated user's subscription history",
"produces": [
"application/json"
],
"tags": [
"subscriptions"
],
"summary": "Get subscription history",
"parameters": [
{
"type": "integer",
"default": 20,
"description": "Limit",
"name": "limit",
"in": "query"
},
{
"type": "integer",
"default": 0,
"description": "Offset",
"name": "offset",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
}
}
}
},
"/api/v1/subscriptions/me": {
"get": {
"description": "Returns the authenticated user's active subscription",
"produces": [
"application/json"
],
"tags": [
"subscriptions"
],
"summary": "Get current subscription",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/subscriptions/status": {
"get": {
"description": "Returns whether the authenticated user has an active subscription",
"produces": [
"application/json"
],
"tags": [
"subscriptions"
],
"summary": "Check subscription status",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
}
}
}
},
"/api/v1/subscriptions/{id}/auto-renew": {
"put": {
"description": "Enables or disables auto-renewal for a subscription",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"subscriptions"
],
"summary": "Set auto-renew",
"parameters": [
{
"type": "integer",
"description": "Subscription ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Auto-renew payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.autoRenewReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/subscriptions/{id}/cancel": {
"post": {
"description": "Cancels the user's subscription",
"produces": [
"application/json"
],
"tags": [
"subscriptions"
],
"summary": "Cancel subscription",
"parameters": [
{
"type": "integer",
"description": "Subscription ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/super-login": {
"post": {
"description": "Login super-admin",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"auth"
],
"summary": "Login super-admin",
"parameters": [
{
"description": "Login super-admin",
"name": "login",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.LoginRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.LoginAdminRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/t-approver/{id}": {
"get": {
"description": "Get a single admin by id",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Get admin by id",
"parameters": [
{
"type": "integer",
"description": "User ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.AdminRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
},
"put": {
"description": "Update Admin",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Update Admin",
"parameters": [
{
"description": "Update Admin",
"name": "admin",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.updateAdminReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/team/login": {
"post": {
"description": "Authenticate a team member (internal staff) with email and password",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"team"
],
"summary": "Login team member",
"parameters": [
{
"description": "Team member login credentials",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.TeamMemberLoginReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/domain.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/handlers.teamMemberLoginRes"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/team/me": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "Get the authenticated team member's own profile",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"team"
],
"summary": "Get my team profile",
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/domain.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/domain.TeamMemberResponse"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/team/members": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "Get a paginated list of team members with optional filtering",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"team"
],
"summary": "List all team members",
"parameters": [
{
"type": "string",
"description": "Filter by team role (super_admin, admin, content_manager, support_agent, instructor, finance, hr, analyst)",
"name": "team_role",
"in": "query"
},
{
"type": "string",
"description": "Filter by department",
"name": "department",
"in": "query"
},
{
"type": "string",
"description": "Filter by status (active, inactive, suspended, terminated)",
"name": "status",
"in": "query"
},
{
"type": "string",
"description": "Search by name, email, or phone number",
"name": "search",
"in": "query"
},
{
"type": "integer",
"description": "Page number (default: 1)",
"name": "page",
"in": "query"
},
{
"type": "integer",
"description": "Items per page (default: 10, max: 100)",
"name": "page_size",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/domain.Response"
},
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.TeamMemberResponse"
}
},
"metadata": {
"$ref": "#/definitions/domain.Pagination"
}
}
}
]
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"post": {
"security": [
{
"Bearer": []
}
],
"description": "Create a new internal team member (admin only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"team"
],
"summary": "Create a new team member",
"parameters": [
{
"description": "Team member creation payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.CreateTeamMemberReq"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"allOf": [
{
"$ref": "#/definitions/domain.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/domain.TeamMemberResponse"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/team/members/{id}": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "Retrieve a team member's details by their ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"team"
],
"summary": "Get team member by ID",
"parameters": [
{
"type": "integer",
"description": "Team Member ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/domain.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/domain.TeamMemberResponse"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"put": {
"security": [
{
"Bearer": []
}
],
"description": "Update an existing team member's details (admin only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"team"
],
"summary": "Update team member",
"parameters": [
{
"type": "integer",
"description": "Team Member ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Team member update payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.UpdateTeamMemberReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"delete": {
"security": [
{
"Bearer": []
}
],
"description": "Delete a team member (super admin only)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"team"
],
"summary": "Delete team member",
"parameters": [
{
"type": "integer",
"description": "Team Member ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/team/members/{id}/change-password": {
"post": {
"security": [
{
"Bearer": []
}
],
"description": "Change a team member's password (requires current password)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"team"
],
"summary": "Change team member password",
"parameters": [
{
"type": "integer",
"description": "Team Member ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Password change payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.changePasswordReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/team/members/{id}/status": {
"patch": {
"security": [
{
"Bearer": []
}
],
"description": "Update a team member's status (active, inactive, suspended, terminated)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"team"
],
"summary": "Update team member status",
"parameters": [
{
"type": "integer",
"description": "Team Member ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Status update payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.UpdateTeamMemberStatusReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/team/refresh": {
"post": {
"description": "Exchanges a valid team refresh token for a new access JWT and a rotated refresh token (use only tokens from POST /team/login or this endpoint).",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"team"
],
"summary": "Refresh team member tokens",
"parameters": [
{
"description": "Current refresh token",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.teamMemberRefreshReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/domain.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/handlers.teamMemberLoginRes"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/team/stats": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "Get statistics about team members by status",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"team"
],
"summary": "Get team member statistics",
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/domain.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/domain.TeamMemberStats"
}
}
}
]
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/tenant": {
"get": {
"description": "Check if phone number or email exist",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Check if phone number or email exist",
"parameters": [
{
"description": "Check phone number or email exist",
"name": "checkPhoneEmailExist",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.CheckPhoneEmailExistReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.CheckPhoneEmailExistRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/user": {
"put": {
"description": "Updates user profile information (partial updates supported)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Update user profile",
"parameters": [
{
"type": "integer",
"description": "User ID",
"name": "user_id",
"in": "path",
"required": true
},
{
"description": "Update user payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.UpdateUserReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/user/delete/{id}": {
"delete": {
"description": "Delete a user by their ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Delete user by ID",
"parameters": [
{
"type": "integer",
"description": "User ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/user/me": {
"delete": {
"security": [
{
"Bearer": []
}
],
"description": "Starts account deletion with grace period before permanent purge",
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Request deletion of my account",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/user/me/deletion/cancel": {
"post": {
"security": [
{
"Bearer": []
}
],
"description": "Cancels a pending self-deletion request during grace period",
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Cancel my account deletion request",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/user/resetPassword": {
"post": {
"description": "Reset password",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Reset password",
"parameters": [
{
"description": "Reset password",
"name": "resetPassword",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.ResetPasswordReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/user/search": {
"post": {
"description": "Search for user using name or phone",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Search for user using name or phone",
"parameters": [
{
"description": "Search for using his name or phone",
"name": "searchUserByNameOrPhone",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.SearchUserByNameOrPhoneReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.UserProfileResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/user/sendResetCode": {
"post": {
"description": "Send reset code",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Send reset code",
"parameters": [
{
"description": "Send reset code",
"name": "resetCode",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.ResetCodeReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/user/single/{id}": {
"get": {
"description": "Get a single user by id",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Get user by id",
"parameters": [
{
"type": "integer",
"description": "User ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.UserProfileResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/user/status": {
"patch": {
"description": "Activates, deactivates, or suspends a user account",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Update user status",
"parameters": [
{
"description": "Status update payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"type": "object"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/user/verify-otp": {
"post": {
"description": "Verify OTP for registration or other actions",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Verify OTP",
"parameters": [
{
"description": "Verify OTP",
"name": "verifyOtp",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.VerifyOtpReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/user/{id}/profile-picture": {
"post": {
"security": [
{
"Bearer": []
}
],
"description": "Uploads a profile picture for the specified user",
"consumes": [
"multipart/form-data"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Upload profile picture",
"parameters": [
{
"type": "integer",
"description": "User ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "file",
"description": "Image file (jpg|png|webp)",
"name": "file",
"in": "formData",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/user/{user_id}/is-pending": {
"get": {
"description": "Returns whether the specified user has a status of \"pending\"",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Check if user status is pending",
"parameters": [
{
"type": "string",
"description": "User ID",
"name": "user_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/user/{user_id}/is-profile-completed": {
"get": {
"description": "Returns the profile completion status and percentage for the specified user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Check if user profile is completed",
"parameters": [
{
"type": "integer",
"description": "User ID",
"name": "user_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/users": {
"get": {
"description": "Get users with optional filters. Each user includes subscription_status: ACTIVE, PENDING, or Unsubscribed.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Get all users",
"parameters": [
{
"type": "string",
"description": "Role filter",
"name": "role",
"in": "query"
},
{
"type": "string",
"description": "Search query",
"name": "query",
"in": "query"
},
{
"type": "integer",
"description": "Page number",
"name": "page",
"in": "query"
},
{
"type": "integer",
"description": "Page size",
"name": "page_size",
"in": "query"
},
{
"type": "string",
"description": "Created before (RFC3339)",
"name": "created_before",
"in": "query"
},
{
"type": "string",
"description": "Created after (RFC3339)",
"name": "created_after",
"in": "query"
},
{
"type": "string",
"description": "User account status filter (ACTIVE, PENDING, SUSPENDED, DEACTIVATED)",
"name": "status",
"in": "query"
},
{
"type": "string",
"description": "Country filter (case-insensitive match on stored value)",
"name": "country",
"in": "query"
},
{
"type": "string",
"description": "Region filter (case-insensitive match on stored value)",
"name": "region",
"in": "query"
},
{
"type": "string",
"description": "Derived subscription filter: ACTIVE, PENDING, or Unsubscribed (matches response subscription_status semantics)",
"name": "subscription_status",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/users/summary": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "Returns total users, active users, and users who joined this month",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Get user summary statistics",
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/domain.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/domain.UserSummary"
}
}
}
]
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/vimeo/oembed": {
"get": {
"description": "Fetches oEmbed metadata for a Vimeo video URL",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Vimeo"
],
"summary": "Get oEmbed data for a Vimeo URL",
"parameters": [
{
"type": "string",
"description": "Vimeo video URL",
"name": "url",
"in": "query",
"required": true
},
{
"type": "integer",
"description": "Desired width",
"name": "width",
"in": "query"
},
{
"type": "integer",
"description": "Desired height",
"name": "height",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/vimeo.OEmbedResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/vimeo/sample": {
"get": {
"description": "Fetches a sample video from Vimeo and returns video details along with an embeddable iframe for client-side integration",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Vimeo"
],
"summary": "Get a sample Vimeo video with iframe embed",
"parameters": [
{
"type": "string",
"default": "76979871",
"description": "Vimeo Video ID to use as sample",
"name": "video_id",
"in": "query"
},
{
"type": "integer",
"default": 640,
"description": "Player width",
"name": "width",
"in": "query"
},
{
"type": "integer",
"default": 360,
"description": "Player height",
"name": "height",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/vimeo/uploads/pull": {
"post": {
"description": "Initiates a pull upload where Vimeo fetches the video from a URL",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Vimeo"
],
"summary": "Create a pull upload to Vimeo",
"parameters": [
{
"description": "Pull Upload Request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.CreatePullUploadRequest"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/handlers.VimeoUploadResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/vimeo/uploads/tus": {
"post": {
"description": "Initiates a TUS resumable upload and returns the upload link",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Vimeo"
],
"summary": "Create a TUS resumable upload to Vimeo",
"parameters": [
{
"description": "TUS Upload Request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.CreateTusUploadRequest"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/handlers.VimeoUploadResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/vimeo/videos": {
"get": {
"description": "Returns a paginated list of videos for the Vimeo API token (GET https://api.vimeo.com/me/videos)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Vimeo"
],
"summary": "List videos stored in the Vimeo account",
"parameters": [
{
"type": "integer",
"default": 1,
"description": "Page number (starts at 1)",
"name": "page",
"in": "query"
},
{
"type": "integer",
"default": 25,
"description": "Page size (Vimeo max 100)",
"name": "per_page",
"in": "query"
},
{
"type": "string",
"description": "Search query",
"name": "query",
"in": "query"
},
{
"type": "string",
"description": "Sort field (e.g. date, alphabetical, plays, likes, comments, duration, relevance)",
"name": "sort",
"in": "query"
},
{
"type": "string",
"description": "asc or desc",
"name": "direction",
"in": "query"
},
{
"type": "string",
"description": "Vimeo filter (e.g. embeddable, playable)",
"name": "filter",
"in": "query"
},
{
"type": "string",
"description": "Vimeo filter_type when using filter",
"name": "filter_type",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/domain.Response"
},
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/handlers.VimeoVideoResponse"
}
},
"metadata": {
"$ref": "#/definitions/handlers.VimeoVideosListMetadata"
}
}
}
]
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"503": {
"description": "Service Unavailable",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/vimeo/videos/{video_id}": {
"get": {
"description": "Retrieves video details from Vimeo by video ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Vimeo"
],
"summary": "Get video information from Vimeo",
"parameters": [
{
"type": "string",
"description": "Vimeo Video ID",
"name": "video_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.VimeoVideoResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
},
"delete": {
"description": "Deletes a video from the Vimeo account",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Vimeo"
],
"summary": "Delete a video from Vimeo",
"parameters": [
{
"type": "string",
"description": "Vimeo Video ID",
"name": "video_id",
"in": "path",
"required": true
}
],
"responses": {
"204": {
"description": "No Content"
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/vimeo/videos/{video_id}/embed": {
"get": {
"description": "Generates an embeddable player iframe for the video",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Vimeo"
],
"summary": "Get embed code for a Vimeo video",
"parameters": [
{
"type": "string",
"description": "Vimeo Video ID",
"name": "video_id",
"in": "path",
"required": true
},
{
"type": "integer",
"default": 640,
"description": "Player width",
"name": "width",
"in": "query"
},
{
"type": "integer",
"default": 360,
"description": "Player height",
"name": "height",
"in": "query"
},
{
"type": "boolean",
"description": "Autoplay video",
"name": "autoplay",
"in": "query"
},
{
"type": "boolean",
"description": "Loop video",
"name": "loop",
"in": "query"
},
{
"type": "boolean",
"description": "Mute video",
"name": "muted",
"in": "query"
},
{
"type": "boolean",
"description": "Background mode (no controls)",
"name": "background",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.VimeoEmbedResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/vimeo/videos/{video_id}/status": {
"get": {
"description": "Returns the current transcoding status of a video",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Vimeo"
],
"summary": "Get transcode status of a Vimeo video",
"parameters": [
{
"type": "string",
"description": "Vimeo Video ID",
"name": "video_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/{tenant_slug}/admin-login": {
"post": {
"description": "Login user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"auth"
],
"summary": "Login user",
"parameters": [
{
"description": "Login admin",
"name": "login",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.LoginRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.LoginAdminRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/{tenant_slug}/otp/resend": {
"post": {
"description": "Resend OTP if the previous one is expired",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"otp"
],
"summary": "Resend OTP",
"parameters": [
{
"description": "Resend OTP",
"name": "resendOtp",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.ResendOtpReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/{tenant_slug}/user-login": {
"post": {
"description": "Login user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"auth"
],
"summary": "Login user",
"parameters": [
{
"description": "Login user",
"name": "login",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.LoginRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.loginUserRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/{tenant_slug}/user/admin-profile": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "Get user profile",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Get user profile",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.AdminProfileRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/{tenant_slug}/user/checkPhoneEmailExist": {
"post": {
"description": "Check if phone number or email exist",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Check if phone number or email exist",
"parameters": [
{
"description": "Check phone number or email exist",
"name": "checkPhoneEmailExist",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.CheckPhoneEmailExistReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handlers.CheckPhoneEmailExistRes"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/{tenant_slug}/user/knowledge-level": {
"put": {
"description": "Updates the knowledge level of the specified user after initial assessment",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Update user's knowledge level",
"parameters": [
{
"type": "integer",
"description": "User ID",
"name": "user_id",
"in": "path",
"required": true
},
{
"description": "Knowledge level",
"name": "knowledge_level",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.UpdateKnowledgeLevelReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.Response"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/domain.ErrorResponse"
}
}
}
}
},
"/api/v1/{tenant_slug}/user/register": {
"post": {
"description": "Register user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Register user",
"parameters": [
{
"description": "Register user",
"name": "registerUser",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/domain.RegisterUserReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/{tenant_slug}/user/resetPassword": {
"post": {
"description": "Reset tenant password",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Reset tenant password",
"parameters": [
{
"description": "Reset password",
"name": "resetPassword",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.ResetPasswordReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/{tenant_slug}/user/sendRegisterCode": {
"post": {
"description": "Send register code",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Send register code",
"parameters": [
{
"description": "Send register code",
"name": "registerCode",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.RegisterCodeReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/{tenant_slug}/user/sendResetCode": {
"post": {
"description": "Send reset code",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Send reset code",
"parameters": [
{
"description": "Send reset code",
"name": "resetCode",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handlers.ResetCodeReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
},
"/api/v1/{tenant_slug}/user/user-profile": {
"get": {
"security": [
{
"Bearer": []
}
],
"description": "Get user profile",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"user"
],
"summary": "Get user profile",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.UserProfileResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.APIResponse"
}
}
}
}
}
},
"definitions": {
"domain.AgeGroup": {
"type": "string",
"enum": [
"UNDER_13",
"13_17",
"18_24",
"25_34",
"35_44",
"45_54",
"55_PLUS"
],
"x-enum-varnames": [
"AgeUnder13",
"Age13To17",
"Age18To24",
"Age25To34",
"Age35To44",
"Age45To54",
"Age55Plus"
]
},
"domain.AnalyticsContentSection": {
"type": "object",
"properties": {
"question_sets_by_type": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.AnalyticsLabelCount"
}
},
"questions_by_type": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.AnalyticsLabelCount"
}
},
"total_question_sets": {
"type": "integer"
},
"total_questions": {
"type": "integer"
}
}
},
"domain.AnalyticsCoursesSection": {
"type": "object",
"properties": {
"exam_prep": {
"$ref": "#/definitions/domain.AnalyticsExamPrepContentCounts"
},
"lms": {
"$ref": "#/definitions/domain.AnalyticsLMSContentCounts"
},
"total_categories": {
"description": "Top-level keys preserved for existing clients: map to LMS programs, courses, modules, and all video lessons (LMS + exam prep).",
"type": "integer"
},
"total_courses": {
"type": "integer"
},
"total_sub_courses": {
"type": "integer"
},
"total_videos": {
"type": "integer"
}
}
},
"domain.AnalyticsDashboard": {
"type": "object",
"properties": {
"content": {
"$ref": "#/definitions/domain.AnalyticsContentSection"
},
"courses": {
"$ref": "#/definitions/domain.AnalyticsCoursesSection"
},
"date_filter": {
"$ref": "#/definitions/domain.AnalyticsDateFilter"
},
"generated_at": {
"type": "string"
},
"issues": {
"$ref": "#/definitions/domain.AnalyticsIssuesSection"
},
"notifications": {
"$ref": "#/definitions/domain.AnalyticsNotificationsSection"
},
"payments": {
"$ref": "#/definitions/domain.AnalyticsPaymentsSection"
},
"subscriptions": {
"$ref": "#/definitions/domain.AnalyticsSubscriptionsSection"
},
"team": {
"$ref": "#/definitions/domain.AnalyticsTeamSection"
},
"users": {
"$ref": "#/definitions/domain.AnalyticsUsersSection"
}
}
},
"domain.AnalyticsDateFilter": {
"type": "object",
"properties": {
"from": {
"type": "string"
},
"mode": {
"type": "string"
},
"month": {
"type": "integer"
},
"range_end": {
"type": "string"
},
"range_start": {
"type": "string"
},
"ref_date": {
"type": "string"
},
"series_end": {
"type": "string"
},
"series_start": {
"type": "string"
},
"to": {
"type": "string"
},
"year": {
"type": "integer"
}
}
},
"domain.AnalyticsExamPrepContentCounts": {
"type": "object",
"properties": {
"catalog_courses": {
"type": "integer"
},
"lesson_practices": {
"type": "integer"
},
"lessons": {
"type": "integer"
},
"lessons_with_video": {
"type": "integer"
},
"unit_modules": {
"type": "integer"
},
"units": {
"type": "integer"
}
}
},
"domain.AnalyticsIssuesSection": {
"type": "object",
"properties": {
"by_status": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.AnalyticsLabelCount"
}
},
"by_type": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.AnalyticsLabelCount"
}
},
"resolution_rate": {
"type": "number"
},
"resolved_issues": {
"type": "integer"
},
"total_issues": {
"type": "integer"
}
}
},
"domain.AnalyticsLMSContentCounts": {
"type": "object",
"properties": {
"courses": {
"type": "integer"
},
"lessons": {
"type": "integer"
},
"lessons_with_video": {
"type": "integer"
},
"modules": {
"type": "integer"
},
"practices": {
"type": "integer"
},
"practices_at_course": {
"type": "integer"
},
"practices_at_lesson": {
"type": "integer"
},
"practices_at_module": {
"type": "integer"
},
"programs": {
"type": "integer"
}
}
},
"domain.AnalyticsLabelAmount": {
"type": "object",
"properties": {
"amount": {
"type": "number"
},
"count": {
"type": "integer"
},
"label": {
"type": "string"
}
}
},
"domain.AnalyticsLabelCount": {
"type": "object",
"properties": {
"count": {
"type": "integer"
},
"label": {
"type": "string"
}
}
},
"domain.AnalyticsMonthlyRevenuePoint": {
"type": "object",
"properties": {
"currency": {
"type": "string"
},
"label": {
"description": "Short English month label, e.g. Jan",
"type": "string"
},
"month": {
"description": "112",
"type": "integer"
},
"month_start": {
"description": "UTC date of month start (for sorting / tooltips)",
"type": "string"
},
"revenue": {
"description": "SUCCESS payments aggregate for that bucket",
"type": "number"
}
}
},
"domain.AnalyticsNotificationsSection": {
"type": "object",
"properties": {
"by_channel": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.AnalyticsLabelCount"
}
},
"by_type": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.AnalyticsLabelCount"
}
},
"read_count": {
"type": "integer"
},
"total_sent": {
"type": "integer"
},
"unread_count": {
"type": "integer"
}
}
},
"domain.AnalyticsPaymentsSection": {
"type": "object",
"properties": {
"avg_transaction_value": {
"type": "number"
},
"by_method": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.AnalyticsLabelAmount"
}
},
"by_status": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.AnalyticsLabelAmount"
}
},
"monthly_revenue_year": {
"description": "MonthlyRevenueYear is set when RevenueMonthly is non-empty (the calendar year of those buckets).",
"type": "integer"
},
"revenue_last_30_days": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.AnalyticsRevenueTimePoint"
}
},
"revenue_monthly": {
"description": "RevenueMonthly is populated only when the request includes year=..., with 12 months (possibly multiple currencies per month).",
"type": "array",
"items": {
"$ref": "#/definitions/domain.AnalyticsMonthlyRevenuePoint"
}
},
"successful_payments": {
"type": "integer"
},
"total_payments": {
"type": "integer"
},
"total_revenue": {
"type": "number"
}
}
},
"domain.AnalyticsRevenueByPlan": {
"type": "object",
"properties": {
"currency": {
"type": "string"
},
"plan_name": {
"type": "string"
},
"revenue": {
"type": "number"
}
}
},
"domain.AnalyticsRevenueTimePoint": {
"type": "object",
"properties": {
"date": {
"type": "string"
},
"revenue": {
"type": "number"
}
}
},
"domain.AnalyticsSubscriptionsSection": {
"type": "object",
"properties": {
"active_subscriptions": {
"type": "integer"
},
"by_status": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.AnalyticsLabelCount"
}
},
"new_month": {
"type": "integer"
},
"new_subscriptions_last_30_days": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.AnalyticsTimePoint"
}
},
"new_today": {
"type": "integer"
},
"new_week": {
"type": "integer"
},
"revenue_by_plan": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.AnalyticsRevenueByPlan"
}
},
"total_subscriptions": {
"type": "integer"
}
}
},
"domain.AnalyticsTeamSection": {
"type": "object",
"properties": {
"by_role": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.AnalyticsLabelCount"
}
},
"by_status": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.AnalyticsLabelCount"
}
},
"total_members": {
"type": "integer"
}
}
},
"domain.AnalyticsTimePoint": {
"type": "object",
"properties": {
"count": {
"type": "integer"
},
"date": {
"type": "string"
}
}
},
"domain.AnalyticsUsersSection": {
"type": "object",
"properties": {
"by_age_group": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.AnalyticsLabelCount"
}
},
"by_knowledge_level": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.AnalyticsLabelCount"
}
},
"by_region": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.AnalyticsLabelCount"
}
},
"by_role": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.AnalyticsLabelCount"
}
},
"by_status": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.AnalyticsLabelCount"
}
},
"new_month": {
"type": "integer"
},
"new_today": {
"type": "integer"
},
"new_week": {
"type": "integer"
},
"registrations_last_30_days": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.AnalyticsTimePoint"
}
},
"total_users": {
"type": "integer"
}
}
},
"domain.BulkAccountsByRoleRequest": {
"type": "object",
"properties": {
"exclude_team_member_id": {
"type": "integer"
}
}
},
"domain.CreateCourseInput": {
"type": "object",
"required": [
"name"
],
"properties": {
"description": {
"type": "string"
},
"name": {
"type": "string"
},
"thumbnail": {
"type": "string"
}
}
},
"domain.CreateExamPrepCatalogCourseInput": {
"type": "object",
"required": [
"name"
],
"properties": {
"description": {
"type": "string"
},
"name": {
"type": "string"
},
"thumbnail": {
"type": "string"
}
}
},
"domain.CreateExamPrepLessonInput": {
"type": "object",
"required": [
"title"
],
"properties": {
"description": {
"type": "string"
},
"thumbnail": {
"type": "string"
},
"title": {
"type": "string"
},
"video_url": {
"type": "string"
}
}
},
"domain.CreateExamPrepModuleInput": {
"type": "object",
"required": [
"name"
],
"properties": {
"description": {
"type": "string"
},
"icon": {
"type": "string"
},
"name": {
"type": "string"
},
"thumbnail": {
"type": "string"
}
}
},
"domain.CreateExamPrepPracticeInput": {
"type": "object",
"required": [
"question_set_id",
"title"
],
"properties": {
"persona_id": {
"type": "integer"
},
"question_set_id": {
"type": "integer"
},
"quick_tips": {
"type": "string"
},
"story_description": {
"type": "string"
},
"story_image": {
"type": "string"
},
"title": {
"type": "string"
}
}
},
"domain.CreateExamPrepUnitInput": {
"type": "object",
"required": [
"name"
],
"properties": {
"description": {
"type": "string"
},
"name": {
"type": "string"
},
"thumbnail": {
"type": "string"
}
}
},
"domain.CreateLessonInput": {
"type": "object",
"required": [
"title"
],
"properties": {
"description": {
"type": "string"
},
"thumbnail": {
"type": "string"
},
"title": {
"type": "string"
},
"video_url": {
"type": "string"
}
}
},
"domain.CreateModuleInput": {
"type": "object",
"required": [
"name"
],
"properties": {
"description": {
"type": "string"
},
"icon": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"domain.CreatePracticeInput": {
"type": "object",
"required": [
"parent_id",
"parent_kind",
"question_set_id",
"title"
],
"properties": {
"parent_id": {
"type": "integer"
},
"parent_kind": {
"enum": [
"COURSE",
"MODULE",
"LESSON"
],
"allOf": [
{
"$ref": "#/definitions/domain.ParentKind"
}
]
},
"persona_id": {
"type": "integer"
},
"question_set_id": {
"type": "integer"
},
"quick_tips": {
"type": "string"
},
"story_description": {
"type": "string"
},
"story_image": {
"type": "string"
},
"title": {
"type": "string"
}
}
},
"domain.CreateProgramInput": {
"type": "object",
"required": [
"name"
],
"properties": {
"description": {
"type": "string"
},
"name": {
"type": "string"
},
"thumbnail": {
"type": "string"
}
}
},
"domain.CreateRoleReq": {
"type": "object",
"required": [
"name"
],
"properties": {
"description": {
"type": "string"
},
"name": {
"type": "string",
"maxLength": 100,
"minLength": 2
}
}
},
"domain.CreateTeamMemberReq": {
"type": "object",
"required": [
"email",
"first_name",
"last_name",
"password",
"team_role"
],
"properties": {
"bio": {
"type": "string"
},
"department": {
"type": "string"
},
"email": {
"type": "string"
},
"emergency_contact": {
"type": "string"
},
"employment_type": {
"type": "string"
},
"first_name": {
"type": "string"
},
"hire_date": {
"description": "YYYY-MM-DD",
"type": "string"
},
"job_title": {
"type": "string"
},
"last_name": {
"type": "string"
},
"password": {
"type": "string",
"minLength": 8
},
"permissions": {
"type": "array",
"items": {
"type": "string"
}
},
"phone_number": {
"type": "string"
},
"profile_picture_url": {
"type": "string"
},
"team_role": {
"type": "string"
},
"work_phone": {
"type": "string"
}
}
},
"domain.DynamicElementDefinition": {
"type": "object",
"properties": {
"config": {
"type": "object",
"additionalProperties": true
},
"id": {
"type": "string"
},
"kind": {
"type": "string"
},
"label": {
"type": "string"
},
"required": {
"type": "boolean"
}
}
},
"domain.DynamicElementInstance": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"kind": {
"type": "string"
},
"meta": {
"type": "object",
"additionalProperties": true
},
"value": {}
}
},
"domain.DynamicQuestionPayload": {
"type": "object",
"properties": {
"response": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.DynamicElementInstance"
}
},
"stimulus": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.DynamicElementInstance"
}
}
}
},
"domain.EmploymentType": {
"type": "string",
"enum": [
"full_time",
"part_time",
"contract",
"intern"
],
"x-enum-varnames": [
"EmploymentTypeFullTime",
"EmploymentTypePartTime",
"EmploymentTypeContract",
"EmploymentTypeIntern"
]
},
"domain.ErrorResponse": {
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
},
"domain.LogEntry": {
"type": "object",
"properties": {
"caller": {
"type": "string"
},
"env": {
"type": "string"
},
"fields": {
"type": "object",
"additionalProperties": true
},
"level": {
"type": "string"
},
"message": {
"type": "string"
},
"service": {
"type": "string"
},
"stacktrace": {
"type": "string"
},
"timestamp": {
"type": "string"
}
}
},
"domain.LogResponse": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.LogEntry"
}
},
"message": {
"type": "string"
},
"pagination": {
"$ref": "#/definitions/domain.Pagination"
}
}
},
"domain.LoginRequest": {
"type": "object",
"properties": {
"email": {
"type": "string"
},
"otp_code": {
"type": "string"
},
"password": {
"type": "string"
},
"phone_number": {
"type": "string"
}
}
},
"domain.OtpMedium": {
"type": "string",
"enum": [
"email",
"sms"
],
"x-enum-varnames": [
"OtpMediumEmail",
"OtpMediumSms"
]
},
"domain.Pagination": {
"type": "object",
"properties": {
"current_page": {
"type": "integer"
},
"limit": {
"type": "integer"
},
"total": {
"type": "integer"
},
"total_pages": {
"type": "integer"
}
}
},
"domain.ParentKind": {
"type": "string",
"enum": [
"COURSE",
"MODULE",
"LESSON"
],
"x-enum-varnames": [
"ParentKindCourse",
"ParentKindModule",
"ParentKindLesson"
]
},
"domain.Permission": {
"type": "object",
"properties": {
"created_at": {
"type": "string"
},
"description": {
"type": "string"
},
"group_name": {
"type": "string"
},
"id": {
"type": "integer"
},
"key": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"domain.QuestionAudioAnswer": {
"type": "object",
"properties": {
"correctAnswerText": {
"type": "string"
},
"createdAt": {
"type": "string"
},
"id": {
"type": "integer",
"format": "int64"
},
"questionID": {
"type": "integer",
"format": "int64"
}
}
},
"domain.QuestionOption": {
"type": "object",
"properties": {
"createdAt": {
"type": "string"
},
"id": {
"type": "integer",
"format": "int64"
},
"isCorrect": {
"type": "boolean"
},
"optionOrder": {
"type": "integer",
"format": "int32"
},
"optionText": {
"type": "string"
},
"questionID": {
"type": "integer",
"format": "int64"
}
}
},
"domain.QuestionShortAnswer": {
"type": "object",
"properties": {
"acceptableAnswer": {
"type": "string"
},
"createdAt": {
"type": "string"
},
"id": {
"type": "integer",
"format": "int64"
},
"matchType": {
"type": "string"
},
"questionID": {
"type": "integer",
"format": "int64"
}
}
},
"domain.QuestionWithDetails": {
"type": "object",
"properties": {
"audioAnswer": {
"$ref": "#/definitions/domain.QuestionAudioAnswer"
},
"createdAt": {
"type": "string"
},
"difficultyLevel": {
"type": "string"
},
"dynamicPayload": {
"$ref": "#/definitions/domain.DynamicQuestionPayload"
},
"explanation": {
"type": "string"
},
"id": {
"type": "integer",
"format": "int64"
},
"imageURL": {
"type": "string"
},
"options": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.QuestionOption"
}
},
"points": {
"type": "integer",
"format": "int32"
},
"questionText": {
"type": "string"
},
"questionType": {
"type": "string"
},
"questionTypeDefinitionID": {
"type": "integer",
"format": "int64"
},
"sampleAnswerVoicePrompt": {
"type": "string"
},
"shortAnswers": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.QuestionShortAnswer"
}
},
"status": {
"type": "string"
},
"tips": {
"type": "string"
},
"updatedAt": {
"type": "string"
},
"voicePrompt": {
"type": "string"
}
}
},
"domain.RegisterUserReq": {
"type": "object",
"properties": {
"email": {
"type": "string"
},
"otp_medium": {
"$ref": "#/definitions/domain.OtpMedium"
},
"password": {
"type": "string"
},
"phone_number": {
"type": "string"
},
"role": {
"type": "string"
}
}
},
"domain.ReorderIDsRequest": {
"type": "object",
"properties": {
"ordered_ids": {
"type": "array",
"items": {
"type": "integer"
}
}
}
},
"domain.ResendOtpReq": {
"type": "object",
"properties": {
"email": {
"type": "string"
},
"phone_number": {
"type": "string"
}
}
},
"domain.Response": {
"type": "object",
"properties": {
"data": {},
"message": {
"type": "string"
},
"metadata": {},
"status_code": {
"type": "integer"
},
"success": {
"type": "boolean"
}
}
},
"domain.Role": {
"type": "string",
"enum": [
"SUPER_ADMIN",
"ADMIN",
"STUDENT",
"INSTRUCTOR",
"SUPPORT"
],
"x-enum-varnames": [
"RoleSuperAdmin",
"RoleAdmin",
"RoleStudent",
"RoleInstructor",
"RoleSupport"
]
},
"domain.RoleRecord": {
"type": "object",
"properties": {
"created_at": {
"type": "string"
},
"description": {
"type": "string"
},
"id": {
"type": "integer"
},
"is_system": {
"type": "boolean"
},
"name": {
"type": "string"
},
"updated_at": {
"type": "string"
}
}
},
"domain.RoleWithPermissions": {
"type": "object",
"properties": {
"created_at": {
"type": "string"
},
"description": {
"type": "string"
},
"id": {
"type": "integer"
},
"is_system": {
"type": "boolean"
},
"name": {
"type": "string"
},
"permissions": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.Permission"
}
},
"updated_at": {
"type": "string"
}
}
},
"domain.SetRolePermissionsReq": {
"type": "object",
"required": [
"permission_ids"
],
"properties": {
"permission_ids": {
"type": "array",
"items": {
"type": "integer"
}
}
}
},
"domain.TeamMemberLoginReq": {
"type": "object",
"required": [
"email",
"password"
],
"properties": {
"email": {
"type": "string"
},
"password": {
"type": "string"
}
}
},
"domain.TeamMemberResponse": {
"type": "object",
"properties": {
"bio": {
"type": "string"
},
"created_at": {
"type": "string"
},
"department": {
"type": "string"
},
"email": {
"type": "string"
},
"email_verified": {
"type": "boolean"
},
"employment_type": {
"$ref": "#/definitions/domain.EmploymentType"
},
"first_name": {
"type": "string"
},
"hire_date": {
"type": "string"
},
"id": {
"type": "integer"
},
"job_title": {
"type": "string"
},
"last_login": {
"type": "string"
},
"last_name": {
"type": "string"
},
"permissions": {
"type": "array",
"items": {
"type": "string"
}
},
"phone_number": {
"type": "string"
},
"profile_picture_url": {
"type": "string"
},
"status": {
"$ref": "#/definitions/domain.TeamMemberStatus"
},
"team_role": {
"$ref": "#/definitions/domain.TeamRole"
},
"updated_at": {
"type": "string"
},
"work_phone": {
"type": "string"
}
}
},
"domain.TeamMemberStats": {
"type": "object",
"properties": {
"active_count": {
"type": "integer"
},
"inactive_count": {
"type": "integer"
},
"suspended_count": {
"type": "integer"
},
"terminated_count": {
"type": "integer"
},
"total_count": {
"type": "integer"
}
}
},
"domain.TeamMemberStatus": {
"type": "string",
"enum": [
"active",
"inactive",
"suspended",
"terminated"
],
"x-enum-varnames": [
"TeamMemberStatusActive",
"TeamMemberStatusInactive",
"TeamMemberStatusSuspended",
"TeamMemberStatusTerminated"
]
},
"domain.TeamRole": {
"type": "string",
"enum": [
"SUPER_ADMIN",
"ADMIN",
"CONTENT_MANAGER",
"SUPPORT_AGENT",
"INSTRUCTOR",
"FINANCE",
"HR",
"ANALYST"
],
"x-enum-varnames": [
"TeamRoleSuperAdmin",
"TeamRoleAdmin",
"TeamRoleContentManager",
"TeamRoleSupportAgent",
"TeamRoleInstructor",
"TeamRoleFinance",
"TeamRoleHR",
"TeamRoleAnalyst"
]
},
"domain.UpdateCourseInput": {
"type": "object",
"properties": {
"description": {
"type": "string"
},
"name": {
"type": "string"
},
"sort_order": {
"type": "integer"
},
"thumbnail": {
"type": "string"
}
}
},
"domain.UpdateExamPrepCatalogCourseInput": {
"type": "object",
"properties": {
"description": {
"type": "string"
},
"name": {
"type": "string"
},
"sort_order": {
"type": "integer"
},
"thumbnail": {
"type": "string"
}
}
},
"domain.UpdateExamPrepPracticeInput": {
"type": "object",
"properties": {
"persona_id": {
"type": "integer"
},
"question_set_id": {
"type": "integer"
},
"quick_tips": {
"type": "string"
},
"story_description": {
"type": "string"
},
"story_image": {
"type": "string"
},
"title": {
"type": "string"
}
}
},
"domain.UpdateExamPrepUnitInput": {
"type": "object",
"properties": {
"description": {
"type": "string"
},
"name": {
"type": "string"
},
"sort_order": {
"type": "integer"
},
"thumbnail": {
"type": "string"
}
}
},
"domain.UpdateKnowledgeLevelReq": {
"type": "object",
"properties": {
"knowledge_level": {
"description": "BEGINNER, INTERMEDIATE, ADVANCED",
"type": "string"
},
"user_id": {
"type": "integer"
}
}
},
"domain.UpdateLessonInput": {
"type": "object",
"properties": {
"description": {
"type": "string"
},
"sort_order": {
"type": "integer"
},
"thumbnail": {
"type": "string"
},
"title": {
"type": "string"
},
"video_url": {
"type": "string"
}
}
},
"domain.UpdateModuleInput": {
"type": "object",
"properties": {
"description": {
"type": "string"
},
"icon": {
"type": "string"
},
"name": {
"type": "string"
},
"sort_order": {
"type": "integer"
}
}
},
"domain.UpdatePracticeInput": {
"type": "object",
"properties": {
"persona_id": {
"type": "integer"
},
"question_set_id": {
"type": "integer"
},
"quick_tips": {
"type": "string"
},
"story_description": {
"type": "string"
},
"story_image": {
"type": "string"
},
"title": {
"type": "string"
}
}
},
"domain.UpdateProgramInput": {
"type": "object",
"properties": {
"description": {
"type": "string"
},
"name": {
"type": "string"
},
"sort_order": {
"type": "integer"
},
"thumbnail": {
"type": "string"
}
}
},
"domain.UpdateRoleReq": {
"type": "object",
"required": [
"name"
],
"properties": {
"description": {
"type": "string"
},
"name": {
"type": "string",
"maxLength": 100,
"minLength": 2
}
}
},
"domain.UpdateTeamMemberReq": {
"type": "object",
"properties": {
"bio": {
"type": "string"
},
"department": {
"type": "string"
},
"emergency_contact": {
"type": "string"
},
"employment_type": {
"type": "string"
},
"first_name": {
"type": "string"
},
"hire_date": {
"type": "string"
},
"job_title": {
"type": "string"
},
"last_name": {
"type": "string"
},
"permissions": {
"type": "array",
"items": {
"type": "string"
}
},
"phone_number": {
"type": "string"
},
"profile_picture_url": {
"type": "string"
},
"team_role": {
"type": "string"
},
"work_phone": {
"type": "string"
}
}
},
"domain.UpdateTeamMemberStatusReq": {
"type": "object",
"required": [
"status"
],
"properties": {
"status": {
"type": "string"
}
}
},
"domain.UpdateUserReq": {
"type": "object",
"properties": {
"age_group": {
"$ref": "#/definitions/domain.AgeGroup"
},
"birth_day": {
"description": "YYYY-MM-DD",
"type": "string"
},
"country": {
"type": "string"
},
"education_level": {
"type": "string"
},
"favourite_topic": {
"type": "string"
},
"first_name": {
"type": "string"
},
"gender": {
"type": "string"
},
"initial_assessment_completed": {
"type": "boolean"
},
"knowledge_level": {
"type": "string"
},
"language_challange": {
"type": "string"
},
"language_goal": {
"type": "string"
},
"last_name": {
"type": "string"
},
"learning_goal": {
"type": "string"
},
"nick_name": {
"type": "string"
},
"occupation": {
"type": "string"
},
"preferred_language": {
"type": "string"
},
"profile_picture_url": {
"type": "string"
},
"region": {
"type": "string"
}
}
},
"domain.UserProfileResponse": {
"type": "object",
"properties": {
"age_group": {
"type": "string"
},
"birth_day": {
"description": "formatted as YYYY-MM-DD",
"type": "string"
},
"country": {
"type": "string"
},
"created_at": {
"type": "string"
},
"education_level": {
"type": "string"
},
"email": {
"description": "UserName string ` + "`" + `json:\"user_name,omitempty\"` + "`" + `",
"type": "string"
},
"email_verified": {
"type": "boolean"
},
"favoutite_topic": {
"type": "string"
},
"first_name": {
"type": "string"
},
"gender": {
"type": "string"
},
"id": {
"type": "integer"
},
"initial_assessment_completed": {
"description": "Profile fields",
"type": "boolean"
},
"language_challange": {
"type": "string"
},
"language_goal": {
"type": "string"
},
"last_login": {
"type": "string"
},
"last_name": {
"type": "string"
},
"learning_goal": {
"type": "string"
},
"nick_name": {
"type": "string"
},
"occupation": {
"type": "string"
},
"phone_number": {
"type": "string"
},
"phone_verified": {
"type": "boolean"
},
"preferred_language": {
"type": "string"
},
"profile_completed": {
"type": "boolean"
},
"profile_completion_percentage": {
"type": "integer"
},
"profile_picture_url": {
"type": "string"
},
"region": {
"type": "string"
},
"role": {
"$ref": "#/definitions/domain.Role"
},
"status": {
"$ref": "#/definitions/domain.UserStatus"
},
"subscription_status": {
"type": "string"
},
"updated_at": {
"type": "string"
}
}
},
"domain.UserStatus": {
"type": "string",
"enum": [
"PENDING",
"ACTIVE",
"SUSPENDED",
"DEACTIVATED"
],
"x-enum-varnames": [
"UserStatusPending",
"UserStatusActive",
"UserStatusSuspended",
"UserStatusDeactivated"
]
},
"domain.UserSummary": {
"type": "object",
"properties": {
"active_users": {
"type": "integer"
},
"joined_this_month": {
"type": "integer"
},
"total_users": {
"type": "integer"
}
}
},
"domain.VerifyOtpReq": {
"type": "object",
"required": [
"otp"
],
"properties": {
"email": {
"type": "string"
},
"otp": {
"type": "string"
},
"phone_number": {
"type": "string"
}
}
},
"domain.WebhookRequest": {
"type": "object",
"properties": {
"nonce": {
"type": "string"
},
"notificationUrl": {
"type": "string"
},
"paymentMethod": {
"type": "string"
},
"phone": {
"type": "string"
},
"sessionId": {
"type": "string"
},
"totalAmount": {
"type": "integer"
},
"transaction": {
"type": "object",
"properties": {
"transactionId": {
"type": "string"
},
"transactionStatus": {
"type": "string"
}
}
},
"transactionStatus": {
"type": "string"
},
"uuid": {
"type": "string"
}
}
},
"handlers.AdminProfileRes": {
"type": "object",
"properties": {
"created_at": {
"type": "string"
},
"email": {
"type": "string"
},
"email_verified": {
"type": "boolean"
},
"first_name": {
"type": "string"
},
"id": {
"type": "integer"
},
"last_login": {
"type": "string"
},
"last_name": {
"type": "string"
},
"phone_number": {
"type": "string"
},
"phone_verified": {
"type": "boolean"
},
"role": {
"$ref": "#/definitions/domain.Role"
},
"suspended": {
"type": "boolean"
},
"suspended_at": {
"type": "string"
},
"updated_at": {
"type": "string"
}
}
},
"handlers.AdminRes": {
"type": "object",
"properties": {
"created_at": {
"type": "string"
},
"email": {
"type": "string"
},
"email_verified": {
"type": "boolean"
},
"first_name": {
"type": "string"
},
"id": {
"type": "integer"
},
"last_login": {
"type": "string"
},
"last_name": {
"type": "string"
},
"phone_number": {
"type": "string"
},
"phone_verified": {
"type": "boolean"
},
"role": {
"$ref": "#/definitions/domain.Role"
},
"suspended": {
"type": "boolean"
},
"suspended_at": {
"type": "string"
},
"updated_at": {
"type": "string"
}
}
},
"handlers.CheckPhoneEmailExistReq": {
"type": "object",
"properties": {
"email": {
"type": "string",
"example": "john.doe@example.com"
},
"phone_number": {
"type": "string",
"example": "1234567890"
}
}
},
"handlers.CheckPhoneEmailExistRes": {
"type": "object",
"properties": {
"email_exist": {
"type": "boolean"
},
"phone_number_exist": {
"type": "boolean"
}
}
},
"handlers.CreateAdminReq": {
"type": "object",
"properties": {
"email": {
"type": "string",
"example": "john.doe@example.com"
},
"first_name": {
"type": "string",
"example": "John"
},
"last_name": {
"type": "string",
"example": "Doe"
},
"password": {
"type": "string",
"example": "password123"
},
"phone_number": {
"type": "string",
"example": "1234567890"
}
}
},
"handlers.CreatePullUploadRequest": {
"type": "object",
"required": [
"file_size",
"name",
"source_url"
],
"properties": {
"description": {
"type": "string"
},
"file_size": {
"type": "integer"
},
"name": {
"type": "string"
},
"source_url": {
"type": "string"
}
}
},
"handlers.CreateTusUploadRequest": {
"type": "object",
"required": [
"file_size",
"name"
],
"properties": {
"description": {
"type": "string"
},
"file_size": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"handlers.LoginAdminRes": {
"type": "object",
"properties": {
"access_token": {
"type": "string"
},
"refresh_token": {
"type": "string"
},
"role": {
"type": "string"
}
}
},
"handlers.RegisterCodeReq": {
"type": "object",
"properties": {
"email": {
"type": "string",
"example": "john.doe@example.com"
},
"phone_number": {
"type": "string",
"example": "1234567890"
}
}
},
"handlers.ResetCodeReq": {
"type": "object",
"properties": {
"email": {
"type": "string",
"example": "john.doe@example.com"
},
"phone_number": {
"type": "string",
"example": "1234567890"
}
}
},
"handlers.ResetPasswordReq": {
"type": "object",
"required": [
"otp",
"password"
],
"properties": {
"email": {
"type": "string",
"example": "john.doe@example.com"
},
"otp": {
"type": "string",
"example": "123456"
},
"password": {
"type": "string",
"minLength": 8,
"example": "newpassword123"
},
"phone_number": {
"type": "string",
"example": "1234567890"
}
}
},
"handlers.SearchUserByNameOrPhoneReq": {
"type": "object",
"properties": {
"query": {
"type": "string"
},
"role": {
"$ref": "#/definitions/domain.Role"
}
}
},
"handlers.SendSingleAfroSMSReq": {
"type": "object",
"required": [
"message",
"recipient"
],
"properties": {
"message": {
"type": "string",
"example": "Hello world"
},
"recipient": {
"type": "string",
"example": "+251912345678"
}
}
},
"handlers.VimeoEmbedResponse": {
"type": "object",
"properties": {
"embed_html": {
"type": "string"
},
"embed_url": {
"type": "string"
},
"video_id": {
"type": "string"
}
}
},
"handlers.VimeoUploadResponse": {
"type": "object",
"properties": {
"link": {
"type": "string"
},
"status": {
"type": "string"
},
"upload_link": {
"type": "string"
},
"uri": {
"type": "string"
},
"vimeo_id": {
"type": "string"
}
}
},
"handlers.VimeoVideoResponse": {
"type": "object",
"properties": {
"description": {
"type": "string"
},
"duration": {
"type": "integer"
},
"embed_html": {
"type": "string"
},
"embed_url": {
"type": "string"
},
"height": {
"type": "integer"
},
"link": {
"type": "string"
},
"name": {
"type": "string"
},
"status": {
"type": "string"
},
"thumbnail_url": {
"type": "string"
},
"transcode_status": {
"type": "string"
},
"uri": {
"type": "string"
},
"vimeo_id": {
"type": "string"
},
"width": {
"type": "integer"
}
}
},
"handlers.VimeoVideosListMetadata": {
"type": "object",
"properties": {
"current_page": {
"type": "integer"
},
"first": {
"type": "string"
},
"last": {
"type": "string"
},
"limit": {
"type": "integer"
},
"next": {
"type": "string"
},
"previous": {
"type": "string"
},
"total": {
"type": "integer"
},
"total_pages": {
"type": "integer"
}
}
},
"handlers.addQuestionToSetReq": {
"type": "object",
"required": [
"question_id"
],
"properties": {
"display_order": {
"type": "integer"
},
"question_id": {
"type": "integer"
}
}
},
"handlers.addUserPersonaReq": {
"type": "object",
"required": [
"user_id"
],
"properties": {
"display_order": {
"type": "integer"
},
"user_id": {
"type": "integer"
}
}
},
"handlers.autoRenewReq": {
"type": "object",
"properties": {
"auto_renew": {
"type": "boolean"
}
}
},
"handlers.changePasswordReq": {
"type": "object",
"required": [
"current_password",
"new_password"
],
"properties": {
"current_password": {
"type": "string",
"example": "oldpassword123"
},
"new_password": {
"type": "string",
"minLength": 8,
"example": "newpassword123"
}
}
},
"handlers.createFAQReq": {
"type": "object",
"required": [
"answer",
"question"
],
"properties": {
"answer": {
"type": "string"
},
"category": {
"type": "string"
},
"display_order": {
"type": "integer"
},
"question": {
"type": "string"
},
"status": {
"type": "string"
}
}
},
"handlers.createIssueReq": {
"type": "object",
"required": [
"description",
"issue_type",
"subject"
],
"properties": {
"description": {
"type": "string"
},
"issue_type": {
"type": "string"
},
"metadata": {
"type": "object",
"additionalProperties": true
},
"subject": {
"type": "string"
}
}
},
"handlers.createPlanReq": {
"type": "object",
"required": [
"currency",
"duration_unit",
"duration_value",
"name",
"price"
],
"properties": {
"currency": {
"type": "string"
},
"description": {
"type": "string"
},
"duration_unit": {
"type": "string",
"enum": [
"DAY",
"WEEK",
"MONTH",
"YEAR"
]
},
"duration_value": {
"type": "integer",
"minimum": 1
},
"is_active": {
"type": "boolean"
},
"name": {
"type": "string"
},
"price": {
"type": "number",
"minimum": 0
}
}
},
"handlers.createQuestionReq": {
"type": "object",
"required": [
"question_text"
],
"properties": {
"audio_correct_answer_text": {
"type": "string"
},
"difficulty_level": {
"type": "string"
},
"dynamic_payload": {
"$ref": "#/definitions/domain.DynamicQuestionPayload"
},
"explanation": {
"type": "string"
},
"image_url": {
"type": "string"
},
"options": {
"type": "array",
"items": {
"$ref": "#/definitions/handlers.optionInput"
}
},
"points": {
"type": "integer"
},
"question_text": {
"type": "string"
},
"question_type": {
"type": "string"
},
"question_type_definition_id": {
"type": "integer"
},
"sample_answer_voice_prompt": {
"type": "string"
},
"short_answers": {
"type": "array",
"items": {
"$ref": "#/definitions/handlers.shortAnswerInput"
}
},
"status": {
"type": "string"
},
"tips": {
"type": "string"
},
"voice_prompt": {
"type": "string"
}
}
},
"handlers.createQuestionSetReq": {
"type": "object",
"required": [
"set_type",
"title"
],
"properties": {
"banner_image": {
"type": "string"
},
"description": {
"type": "string"
},
"intro_video_url": {
"type": "string"
},
"owner_id": {
"type": "integer"
},
"owner_type": {
"type": "string"
},
"passing_score": {
"type": "integer"
},
"persona": {
"type": "string"
},
"set_type": {
"type": "string",
"enum": [
"PRACTICE",
"INITIAL_ASSESSMENT",
"QUIZ",
"EXAM",
"SURVEY",
"CAPSTONE"
]
},
"shuffle_questions": {
"type": "boolean"
},
"status": {
"type": "string"
},
"time_limit_minutes": {
"type": "integer"
},
"title": {
"type": "string"
}
}
},
"handlers.createQuestionTypeDefinitionReq": {
"type": "object",
"required": [
"display_name",
"key"
],
"properties": {
"description": {
"type": "string"
},
"display_name": {
"type": "string"
},
"key": {
"type": "string"
},
"response_component_kinds": {
"type": "array",
"items": {
"type": "string"
}
},
"response_schema": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.DynamicElementDefinition"
}
},
"status": {
"type": "string"
},
"stimulus_component_kinds": {
"type": "array",
"items": {
"type": "string"
}
},
"stimulus_schema": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.DynamicElementDefinition"
}
}
}
},
"handlers.initiateDirectPaymentReq": {
"type": "object",
"required": [
"email",
"payment_method",
"phone",
"plan_id"
],
"properties": {
"email": {
"type": "string"
},
"payment_method": {
"type": "string"
},
"phone": {
"type": "string"
},
"plan_id": {
"type": "integer"
}
}
},
"handlers.initiatePaymentReq": {
"type": "object",
"required": [
"email",
"phone",
"plan_id"
],
"properties": {
"email": {
"type": "string"
},
"phone": {
"type": "string"
},
"plan_id": {
"type": "integer"
}
}
},
"handlers.issueListRes": {
"type": "object",
"properties": {
"issues": {
"type": "array",
"items": {
"$ref": "#/definitions/handlers.issueRes"
}
},
"total_count": {
"type": "integer"
}
}
},
"handlers.issueRes": {
"type": "object",
"properties": {
"created_at": {
"type": "string"
},
"description": {
"type": "string"
},
"id": {
"type": "integer"
},
"issue_type": {
"type": "string"
},
"metadata": {
"type": "object",
"additionalProperties": true
},
"status": {
"type": "string"
},
"subject": {
"type": "string"
},
"updated_at": {
"type": "string"
},
"user_id": {
"type": "integer"
},
"user_role": {
"type": "string"
}
}
},
"handlers.loginUserRes": {
"type": "object",
"properties": {
"access_token": {
"type": "string"
},
"refresh_token": {
"type": "string"
},
"role": {
"type": "string"
},
"user_id": {
"type": "integer"
}
}
},
"handlers.logoutReq": {
"type": "object",
"required": [
"refresh_token"
],
"properties": {
"device_token": {
"type": "string",
"example": "\u003cfcm-device-token\u003e"
},
"refresh_token": {
"type": "string",
"example": "\u003crefresh-token\u003e"
}
}
},
"handlers.optionInput": {
"type": "object",
"required": [
"option_text"
],
"properties": {
"is_correct": {
"type": "boolean"
},
"option_order": {
"type": "integer"
},
"option_text": {
"type": "string"
}
}
},
"handlers.refreshFileURLReq": {
"type": "object",
"properties": {
"reference": {
"type": "string"
}
}
},
"handlers.refreshToken": {
"type": "object",
"required": [
"access_token",
"refresh_token"
],
"properties": {
"access_token": {
"type": "string",
"example": "\u003cjwt-token\u003e"
},
"refresh_token": {
"type": "string",
"example": "\u003crefresh-token\u003e"
}
}
},
"handlers.shortAnswerInput": {
"type": "object",
"required": [
"acceptable_answer"
],
"properties": {
"acceptable_answer": {
"type": "string"
},
"match_type": {
"type": "string"
}
}
},
"handlers.submitRatingReq": {
"type": "object",
"required": [
"stars",
"target_type"
],
"properties": {
"review": {
"type": "string"
},
"stars": {
"type": "integer",
"maximum": 5,
"minimum": 1
},
"target_id": {
"type": "integer"
},
"target_type": {
"type": "string"
}
}
},
"handlers.subscribeReq": {
"type": "object",
"required": [
"plan_id"
],
"properties": {
"payment_method": {
"type": "string"
},
"payment_reference": {
"type": "string"
},
"plan_id": {
"type": "integer"
}
}
},
"handlers.subscribeWithPaymentReq": {
"type": "object",
"required": [
"email",
"phone",
"plan_id"
],
"properties": {
"email": {
"type": "string"
},
"phone": {
"type": "string"
},
"plan_id": {
"type": "integer"
}
}
},
"handlers.teamMemberLoginRes": {
"type": "object",
"properties": {
"access_token": {
"type": "string",
"example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
},
"member_id": {
"type": "integer",
"example": 1
},
"refresh_token": {
"type": "string",
"example": "\u003copaque-refresh-token\u003e"
},
"team_role": {
"type": "string",
"example": "admin"
}
}
},
"handlers.teamMemberRefreshReq": {
"type": "object",
"required": [
"refresh_token"
],
"properties": {
"refresh_token": {
"type": "string"
}
}
},
"handlers.updateAdminReq": {
"type": "object",
"properties": {
"first_name": {
"type": "string",
"example": "John"
},
"last_name": {
"type": "string",
"example": "Doe"
},
"suspended": {
"type": "boolean",
"example": false
}
}
},
"handlers.updateFAQReq": {
"type": "object",
"properties": {
"answer": {
"type": "string"
},
"category": {
"type": "string"
},
"display_order": {
"type": "integer"
},
"question": {
"type": "string"
},
"status": {
"type": "string"
}
}
},
"handlers.updateIssueStatusReq": {
"type": "object",
"required": [
"status"
],
"properties": {
"status": {
"type": "string",
"enum": [
"pending",
"in_progress",
"resolved",
"rejected"
]
}
}
},
"handlers.updatePlanReq": {
"type": "object",
"properties": {
"currency": {
"type": "string"
},
"description": {
"type": "string"
},
"duration_unit": {
"type": "string"
},
"duration_value": {
"type": "integer"
},
"is_active": {
"type": "boolean"
},
"name": {
"type": "string"
},
"price": {
"type": "number"
}
}
},
"handlers.updateQuestionOrderReq": {
"type": "object",
"required": [
"display_order"
],
"properties": {
"display_order": {
"type": "integer"
}
}
},
"handlers.updateQuestionReq": {
"type": "object",
"properties": {
"audio_correct_answer_text": {
"type": "string"
},
"difficulty_level": {
"type": "string"
},
"dynamic_payload": {
"$ref": "#/definitions/domain.DynamicQuestionPayload"
},
"explanation": {
"type": "string"
},
"image_url": {
"type": "string"
},
"options": {
"type": "array",
"items": {
"$ref": "#/definitions/handlers.optionInput"
}
},
"points": {
"type": "integer"
},
"question_text": {
"type": "string"
},
"question_type": {
"type": "string"
},
"question_type_definition_id": {
"type": "integer"
},
"sample_answer_voice_prompt": {
"type": "string"
},
"short_answers": {
"type": "array",
"items": {
"$ref": "#/definitions/handlers.shortAnswerInput"
}
},
"status": {
"type": "string"
},
"tips": {
"type": "string"
},
"voice_prompt": {
"type": "string"
}
}
},
"handlers.updateQuestionSetReq": {
"type": "object",
"properties": {
"banner_image": {
"type": "string"
},
"description": {
"type": "string"
},
"intro_video_url": {
"type": "string"
},
"passing_score": {
"type": "integer"
},
"persona": {
"type": "string"
},
"shuffle_questions": {
"type": "boolean"
},
"status": {
"type": "string"
},
"time_limit_minutes": {
"type": "integer"
},
"title": {
"type": "string"
}
}
},
"handlers.updateQuestionTypeDefinitionReq": {
"type": "object",
"properties": {
"description": {
"type": "string"
},
"display_name": {
"type": "string"
},
"response_component_kinds": {
"type": "array",
"items": {
"type": "string"
}
},
"response_schema": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.DynamicElementDefinition"
}
},
"status": {
"type": "string"
},
"stimulus_component_kinds": {
"type": "array",
"items": {
"type": "string"
}
},
"stimulus_schema": {
"type": "array",
"items": {
"$ref": "#/definitions/domain.DynamicElementDefinition"
}
}
}
},
"handlers.validateQuestionTypeDefinitionReq": {
"type": "object",
"properties": {
"response_component_kinds": {
"type": "array",
"items": {
"type": "string"
}
},
"stimulus_component_kinds": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"handlers.verifyOTPReq": {
"type": "object",
"required": [
"otp",
"session_id"
],
"properties": {
"otp": {
"type": "string"
},
"session_id": {
"type": "string"
}
}
},
"response.APIResponse": {
"type": "object",
"properties": {
"data": {},
"message": {
"type": "string"
},
"metadata": {},
"page": {
"type": "integer"
},
"status": {
"$ref": "#/definitions/response.Status"
},
"timestamp": {
"type": "string"
},
"total": {
"type": "integer"
}
}
},
"response.Status": {
"type": "string",
"enum": [
"error",
"success"
],
"x-enum-varnames": [
"Error",
"Success"
]
},
"vimeo.OEmbedResponse": {
"type": "object",
"properties": {
"author_name": {
"type": "string"
},
"author_url": {
"type": "string"
},
"description": {
"type": "string"
},
"duration": {
"type": "integer"
},
"height": {
"type": "integer"
},
"html": {
"type": "string"
},
"is_plus": {
"type": "string"
},
"provider_name": {
"type": "string"
},
"provider_url": {
"type": "string"
},
"thumbnail_height": {
"type": "integer"
},
"thumbnail_url": {
"type": "string"
},
"thumbnail_width": {
"type": "integer"
},
"title": {
"type": "string"
},
"type": {
"type": "string"
},
"version": {
"type": "string"
},
"video_id": {
"type": "integer"
},
"width": {
"type": "integer"
}
}
}
},
"securityDefinitions": {
"Bearer": {
"type": "apiKey",
"name": "Authorization",
"in": "header"
}
}
}`
// SwaggerInfo holds exported Swagger Info so clients can modify it
var SwaggerInfo = &swag.Spec{
Version: "1.0.1",
Host: "",
BasePath: "",
Schemes: []string{},
Title: "Yimaru API",
Description: "This is server for Yimaru.",
InfoInstanceName: "swagger",
SwaggerTemplate: docTemplate,
LeftDelim: "{{",
RightDelim: "}}",
}
func init() {
swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
}