Yimaru-Admin/src/types/course.types.ts
2026-03-06 06:02:02 -08:00

559 lines
11 KiB
TypeScript

export interface CourseCategory {
id: number
name: string
is_active: boolean
parent_id?: number | null
created_at: string
}
export interface CreateCourseCategoryRequest {
name: string
parent_id?: number | null
}
export interface GetCourseCategoriesResponse {
message: string
data: {
categories: CourseCategory[]
total_count: number
}
success: boolean
status_code: number
metadata: unknown
}
export interface Course {
id: number
category_id: number
title: string
description: string
thumbnail: string
is_active: boolean
}
export interface GetCoursesResponse {
message: string
data: {
courses: Course[]
total_count: number
}
success: boolean
status_code: number
metadata: unknown
}
export interface CreateCourseRequest {
category_id: number
title: string
description: string
}
export interface UpdateCourseRequest {
title?: string
description?: string
thumbnail?: string
is_active?: boolean
}
// ============================================
// Legacy Types (deprecated - using SubCourse hierarchy now)
// Keeping for backward compatibility with existing API endpoints
// ============================================
/** @deprecated Use SubCourse instead */
export interface Program {
id: number
course_id: number
title: string
description: string
thumbnail: string
display_order: number
is_active: boolean
}
/** @deprecated Use GetSubCoursesResponse instead */
export interface GetProgramsResponse {
message: string
data: {
programs: Program[]
total_count: number
}
success: boolean
status_code: number
metadata: unknown
}
/** @deprecated Use UpdateSubCourseStatusRequest instead */
export interface UpdateProgramStatusRequest {
is_active: boolean
}
/** @deprecated Use CreateSubCourseRequest instead */
export interface CreateProgramRequest {
course_id: number
title: string
description: string
}
/** @deprecated Use UpdateSubCourseRequest instead */
export interface UpdateProgramRequest {
title: string
description: string
is_active: boolean
}
/** @deprecated Use SubCourse instead */
export interface Level {
id: number
program_id: number
title: string
description: string
level_index: number
number_of_modules: number
number_of_practices: number
number_of_videos: number
is_active: boolean
}
/** @deprecated Use GetSubCoursesResponse instead */
export interface GetLevelsResponse {
message: string
data: {
levels: Level[]
total_count: number
}
success: boolean
status_code: number
metadata: unknown
}
/** @deprecated Use CreateSubCourseRequest instead */
export interface CreateLevelRequest {
program_id: number
title: string
description: string
}
/** @deprecated Use UpdateSubCourseRequest instead */
export interface UpdateLevelRequest {
title: string
description: string
}
/** @deprecated Use UpdateSubCourseStatusRequest instead */
export interface UpdateLevelStatusRequest {
is_active: boolean
}
/** @deprecated Use SubCourse hierarchy instead */
export interface Module {
id: number
level_id: number
title: string
content: string
display_order: number
is_active: boolean
}
/** @deprecated Use GetSubCoursesResponse instead */
export interface GetModulesResponse {
message: string
data: {
modules: Module[]
total_count: number
}
success: boolean
status_code: number
metadata: unknown
}
/** @deprecated Use CreateSubCourseRequest instead */
export interface CreateModuleRequest {
level_id: number
title: string
content: string
}
/** @deprecated Use UpdateSubCourseRequest instead */
export interface UpdateModuleRequest {
title: string
content: string
}
/** @deprecated Use UpdateSubCourseStatusRequest instead */
export interface UpdateModuleStatusRequest {
is_active: boolean
}
// ============================================
// New Hierarchy: SubCourse (replaces Program/Level/Module)
// ============================================
export interface SubCourse {
id: number
course_id: number
title: string
description: string
level: string
thumbnail: string
display_order: number
is_active: boolean
}
export interface GetSubCoursesResponse {
message: string
data: {
sub_courses: SubCourse[]
total_count: number
}
success: boolean
status_code: number
metadata: unknown
}
export interface CreateSubCourseRequest {
course_id: number
title: string
description: string
level: string
}
export interface UpdateSubCourseRequest {
title: string
description: string
level: string
}
export interface UpdateSubCourseStatusRequest {
is_active: boolean
level: string
title: string
}
// SubCourse Video
export interface SubCourseVideo {
id: number
sub_course_id: number
title: string
description: string
video_url: string
duration: number
thumbnail: string
is_published: boolean
is_active: boolean
}
export interface GetSubCourseVideosResponse {
message: string
data: {
videos: SubCourseVideo[]
total_count: number
}
success: boolean
status_code: number
metadata: unknown
}
export interface CreateSubCourseVideoRequest {
sub_course_id: number
title: string
description: string
video_url: string
}
export interface CreateVimeoVideoRequest {
sub_course_id: number
title: string
description: string
source_url: string
file_size: number
duration: number
}
export interface UpdateSubCourseVideoRequest {
title: string
description: string
video_url: string
}
// Practice now belongs to SubCourse
export interface Practice {
id: number
sub_course_id: number
title: string
description: string
banner_image: string
persona: string
is_active: boolean
}
export interface GetPracticesResponse {
message: string
data: {
practices: Practice[]
total_count: number
}
success: boolean
status_code: number
metadata: unknown
}
export interface CreatePracticeRequest {
sub_course_id: number
title: string
description: string
persona?: string
}
export interface UpdatePracticeRequest {
title: string
description: string
persona?: string
}
export interface UpdatePracticeStatusRequest {
is_active: boolean
}
export interface PracticeQuestion {
id: number
practice_id: number
question: string
question_voice_prompt: string
sample_answer_voice_prompt: string
sample_answer: string
tips: string
type: "MCQ" | "TRUE_FALSE" | "SHORT"
}
export interface GetPracticeQuestionsResponse {
message: string
data: {
questions: PracticeQuestion[]
total_count: number
}
success: boolean
status_code: number
metadata: unknown
}
export interface CreatePracticeQuestionRequest {
practice_id: number
question: string
question_voice_prompt?: string
sample_answer_voice_prompt?: string
sample_answer: string
tips?: string
type: "MCQ" | "TRUE_FALSE" | "SHORT"
}
export interface UpdatePracticeQuestionRequest {
question: string
question_voice_prompt?: string
sample_answer_voice_prompt?: string
sample_answer: string
tips?: string
type: "MCQ" | "TRUE_FALSE" | "SHORT"
}
// Question Sets (Practice sets fetched via /question-sets)
export type QuestionSetType = "PRACTICE" | "EXAM"
export type QuestionSetStatus = "PUBLISHED" | "DRAFT" | "ARCHIVED"
export type QuestionSetOwnerType = "SUB_COURSE" | "COURSE"
export interface QuestionSet {
id: number
title: string
description: string
set_type: QuestionSetType
owner_type: QuestionSetOwnerType
owner_id: number
persona: string
shuffle_questions: boolean
status: QuestionSetStatus
created_at: string
}
export interface GetQuestionSetsResponse {
message: string
data: QuestionSet[]
success: boolean
status_code: number
metadata: unknown
}
export interface CreateQuestionSetRequest {
title: string
description: string
set_type: string
owner_type: string
owner_id: number
persona?: string
shuffle_questions?: boolean
status?: string
banner_image?: string
passing_score?: number
time_limit_minutes?: number
}
export interface AddQuestionToSetRequest {
display_order: number
question_id: number
}
export interface QuestionOption {
option_order: number
option_text: string
is_correct: boolean
}
export interface CreateQuestionRequest {
question_text: string
question_type: string
difficulty_level: string
points: number
tips?: string
explanation?: string
status?: string
options?: QuestionOption[]
voice_prompt?: string
sample_answer_voice_prompt?: string
short_answers?: string[]
}
export interface CreateQuestionResponse {
message: string
data: {
id: number
}
success: boolean
status_code: number
metadata: unknown
}
export interface CreateQuestionSetResponse {
message: string
data: {
id: number
}
success: boolean
status_code: number
metadata: unknown
}
// Sub-course Prerequisites
export interface SubCoursePrerequisite {
id: number
sub_course_id: number
prerequisite_sub_course_id: number
prerequisite_title: string
prerequisite_level: string
prerequisite_display_order: number
}
export interface GetSubCoursePrerequisitesResponse {
message: string
data: SubCoursePrerequisite[]
success: boolean
status_code: number
metadata: unknown
}
export interface AddSubCoursePrerequisiteRequest {
prerequisite_sub_course_id: number
}
// Learning Path (full tree from GET /courses/:courseId/learning-path)
export interface LearningPathSubCourse {
id: number
title: string
description: string
thumbnail: string
display_order: number
level: string
prerequisite_count: number
video_count: number
practice_count: number
prerequisites: { sub_course_id: number; title: string; level: string }[]
videos: unknown[]
practices: unknown[]
}
export interface LearningPath {
course_id: number
course_title: string
description: string
thumbnail: string
intro_video_url: string
category_id: number
category_name: string
sub_courses: LearningPathSubCourse[]
}
export interface GetLearningPathResponse {
message: string
data: LearningPath
success: boolean
status_code: number
metadata: unknown
}
export interface ReorderItem {
sub_course_id: number
display_order: number
}
// Ratings
export interface Rating {
id: number
user_id: number
target_type: string
target_id: number
stars: number
review: string
created_at: string
updated_at: string
}
export interface GetRatingsParams {
target_type: string
target_id: number
limit?: number
offset?: number
}
export interface GetRatingsResponse {
message: string
data: Rating[]
success: boolean
status_code: number
metadata: unknown
}
// Vimeo Sample Video
export interface VimeoSampleVideo {
vimeo_id: string
uri: string
name: string
description: string
duration: number
width: number
height: number
link: string
embed_url: string
embed_html: string
thumbnail_url: string
status: string
transcode_status: string
}
export interface GetVimeoSampleResponse {
message: string
data: {
video: VimeoSampleVideo
iframe: string
}
success: boolean
status_code: number
metadata: unknown
}