package education import ( "time" "github.com/google/uuid" "github.com/lib/pq" "gorm.io/gorm" ) // CourseStatus represents the publication status of a course type CourseStatus string const ( CourseStatusDraft CourseStatus = "draft" CourseStatusPublished CourseStatus = "published" CourseStatusArchived CourseStatus = "archived" ) // CourseLevel represents the difficulty level type CourseLevel string const ( CourseLevelBeginner CourseLevel = "beginner" CourseLevelIntermediate CourseLevel = "intermediate" CourseLevelAdvanced CourseLevel = "advanced" ) // PricingModel represents the pricing strategy type PricingModel string const ( PricingFixed PricingModel = "fixed" PricingPayWhatYou PricingModel = "pay_what_you_want" PricingFree PricingModel = "free" ) // EnrollmentStatus represents the enrollment state type EnrollmentStatus string const ( EnrollmentActive EnrollmentStatus = "active" EnrollmentExpired EnrollmentStatus = "expired" EnrollmentRefunded EnrollmentStatus = "refunded" ) // TranscodingStatus represents video processing state type TranscodingStatus string const ( TranscodingPending TranscodingStatus = "pending" TranscodingProcessing TranscodingStatus = "processing" TranscodingComplete TranscodingStatus = "complete" TranscodingFailed TranscodingStatus = "failed" ) // CertificateStatus represents certificate validity type CertificateStatus string const ( CertificateActive CertificateStatus = "active" CertificateRevoked CertificateStatus = "revoked" ) // ReviewStatus represents review moderation status type ReviewStatus string const ( ReviewApproved ReviewStatus = "approved" ReviewPending ReviewStatus = "pending" ReviewRejected ReviewStatus = "rejected" ) // Course represents an educational course created by a user type Course struct { ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"` CreatorID uuid.UUID `gorm:"type:uuid;not null" json:"creator_id"` Title string `gorm:"size:255;not null" json:"title"` Slug string `gorm:"size:255;not null;uniqueIndex" json:"slug"` Description string `gorm:"type:text;not null;default:''" json:"description"` Category string `gorm:"size:100" json:"category,omitempty"` Tags pq.StringArray `gorm:"type:varchar(50)[];default:'{}'" json:"tags"` CoverImageURL string `gorm:"type:text" json:"cover_image_url,omitempty"` PriceCents int `gorm:"not null;default:0" json:"price_cents"` Currency string `gorm:"size:3;not null;default:'USD'" json:"currency"` PricingModel PricingModel `gorm:"size:50;not null;default:'fixed'" json:"pricing_model"` MinimumPriceCents int `gorm:"default:0" json:"minimum_price_cents"` Status CourseStatus `gorm:"size:50;not null;default:'draft'" json:"status"` Level CourseLevel `gorm:"size:50;default:'beginner'" json:"level"` Language string `gorm:"size:5;default:'en'" json:"language"` TotalDurationSeconds int `gorm:"not null;default:0" json:"total_duration_seconds"` LessonCount int `gorm:"not null;default:0" json:"lesson_count"` EnrollmentCount int `gorm:"not null;default:0" json:"enrollment_count"` ReviewCount int `gorm:"not null;default:0" json:"review_count"` AverageRating float64 `gorm:"type:numeric(3,2);default:0" json:"average_rating"` PublishedAt *time.Time `json:"published_at,omitempty"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` DeletedAt gorm.DeletedAt `gorm:"index" json:"deleted_at,omitempty"` } func (Course) TableName() string { return "courses" } func (c *Course) BeforeCreate(tx *gorm.DB) error { if c.ID == uuid.Nil { c.ID = uuid.New() } return nil } // Lesson represents a single lesson within a course type Lesson struct { ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"` CourseID uuid.UUID `gorm:"type:uuid;not null" json:"course_id"` OrderIndex int `gorm:"not null" json:"order_index"` Title string `gorm:"size:255;not null" json:"title"` Description string `gorm:"type:text" json:"description,omitempty"` VideoFilePath string `gorm:"size:512" json:"video_file_path,omitempty"` DurationSeconds int `gorm:"not null;default:0" json:"duration_seconds"` IsPreviewFree bool `gorm:"not null;default:false" json:"is_preview_free"` TranscodingStatus TranscodingStatus `gorm:"size:50;not null;default:'pending'" json:"transcoding_status"` HLSMasterPlaylistURL string `gorm:"type:text" json:"hls_master_playlist_url,omitempty"` ThumbnailURL string `gorm:"type:text" json:"thumbnail_url,omitempty"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` } func (Lesson) TableName() string { return "lessons" } func (l *Lesson) BeforeCreate(tx *gorm.DB) error { if l.ID == uuid.Nil { l.ID = uuid.New() } return nil } // CourseEnrollment represents a user's enrollment (purchase) in a course type CourseEnrollment struct { ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"` UserID uuid.UUID `gorm:"type:uuid;not null" json:"user_id"` CourseID uuid.UUID `gorm:"type:uuid;not null" json:"course_id"` PurchasedPriceCents int `gorm:"not null;default:0" json:"purchased_price_cents"` Currency string `gorm:"size:3;not null;default:'USD'" json:"currency"` Status EnrollmentStatus `gorm:"size:50;not null;default:'active'" json:"status"` AccessExpiresAt *time.Time `json:"access_expires_at,omitempty"` PurchasedAt time.Time `gorm:"not null" json:"purchased_at"` RefundedAt *time.Time `json:"refunded_at,omitempty"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` } func (CourseEnrollment) TableName() string { return "course_enrollments" } func (e *CourseEnrollment) BeforeCreate(tx *gorm.DB) error { if e.ID == uuid.Nil { e.ID = uuid.New() } return nil } // LessonProgress tracks a user's progress on a specific lesson type LessonProgress struct { ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"` UserID uuid.UUID `gorm:"type:uuid;not null" json:"user_id"` LessonID uuid.UUID `gorm:"type:uuid;not null" json:"lesson_id"` EnrollmentID uuid.UUID `gorm:"type:uuid;not null" json:"enrollment_id"` WatchedPercentage int `gorm:"default:0" json:"watched_percentage"` WatchedDurationSeconds int `gorm:"default:0" json:"watched_duration_seconds"` PlaybackPositionSeconds int `gorm:"default:0" json:"playback_position_seconds"` IsCompleted bool `gorm:"not null;default:false" json:"is_completed"` CompletedAt *time.Time `json:"completed_at,omitempty"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` } func (LessonProgress) TableName() string { return "lesson_progress" } func (p *LessonProgress) BeforeCreate(tx *gorm.DB) error { if p.ID == uuid.Nil { p.ID = uuid.New() } return nil } // Certificate represents a course completion certificate type Certificate struct { ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"` UserID uuid.UUID `gorm:"type:uuid;not null" json:"user_id"` CourseID uuid.UUID `gorm:"type:uuid;not null" json:"course_id"` EnrollmentID uuid.UUID `gorm:"type:uuid;not null" json:"enrollment_id"` CertificateCode string `gorm:"size:255;not null;uniqueIndex" json:"certificate_code"` IssueDate time.Time `gorm:"not null" json:"issue_date"` Status CertificateStatus `gorm:"size:50;not null;default:'active'" json:"status"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` } func (Certificate) TableName() string { return "certificates" } func (cert *Certificate) BeforeCreate(tx *gorm.DB) error { if cert.ID == uuid.Nil { cert.ID = uuid.New() } return nil } // CourseReview represents a user's review of a course type CourseReview struct { ID uuid.UUID `gorm:"type:uuid;primaryKey" json:"id"` CourseID uuid.UUID `gorm:"type:uuid;not null" json:"course_id"` UserID uuid.UUID `gorm:"type:uuid;not null" json:"user_id"` EnrollmentID uuid.UUID `gorm:"type:uuid;not null" json:"enrollment_id"` Rating int `gorm:"not null" json:"rating"` Title string `gorm:"size:255" json:"title,omitempty"` Content string `gorm:"type:text;not null" json:"content"` Status ReviewStatus `gorm:"size:50;not null;default:'approved'" json:"status"` HelpfulCount int `gorm:"not null;default:0" json:"helpful_count"` CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` DeletedAt gorm.DeletedAt `gorm:"index" json:"deleted_at,omitempty"` } func (CourseReview) TableName() string { return "course_reviews" } func (r *CourseReview) BeforeCreate(tx *gorm.DB) error { if r.ID == uuid.Nil { r.ID = uuid.New() } return nil }