use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PageResponse<T> {
pub items: Vec<T>,
#[serde(skip_serializing_if = "Option::is_none")]
pub page_token: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub has_more: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CourseRegistration {
pub registration_id: String,
pub course_id: String,
pub user_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub registration_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub progress: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub start_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub completion_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub total_duration: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub studied_duration: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub score: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub passed: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub course_info: Option<CourseInfo>,
#[serde(skip_serializing_if = "Option::is_none")]
pub user_info: Option<UserInfo>,
#[serde(skip_serializing_if = "Option::is_none")]
pub learning_records: Option<Vec<LearningRecord>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub created_at: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub updated_at: Option<i64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CourseInfo {
pub course_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub course_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub course_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub category: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tags: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub duration: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub difficulty: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cover_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub creator: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub status: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserInfo {
pub user_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub email: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub avatar_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub department: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub position: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LearningRecord {
pub record_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub chapter_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub chapter_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub progress: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub duration: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub completed: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub start_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub end_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub attempt_count: Option<i32>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LearningStatistics {
#[serde(skip_serializing_if = "Option::is_none")]
pub total_courses: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub completed_courses: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub in_progress_courses: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub total_study_time: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub average_progress: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub average_score: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pass_rate: Option<f64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CourseRegistrationEvent {
pub event_type: String,
pub registration: CourseRegistration,
#[serde(skip_serializing_if = "Option::is_none")]
pub old_registration: Option<CourseRegistration>,
pub timestamp: i64,
#[serde(skip_serializing_if = "Option::is_none")]
pub source: Option<String>,
}