package models import "time" // --- Enums (matches DB types) --- type QuestionType string const ( Single QuestionType = "single" Multiple QuestionType = "multiple" ) type DeliveryType string const ( Physical DeliveryType = "physical" Digital DeliveryType = "digital" ) type PurchaseStatus string const ( Pending PurchaseStatus = "pending" Delivered PurchaseStatus = "delivered" Cancelled PurchaseStatus = "cancelled" ) type QRScanType string const ( QRReward QRScanType = "reward" QRQuiz QRScanType = "quiz" QRShop QRScanType = "shop" ) type QRScanSource string const ( InApp QRScanSource = "in_app" External QRScanSource = "external" ) type AdminRole string const ( RoleAdmin AdminRole = "admin" RoleOperator AdminRole = "operator" ) // --- Model Structs --- type User struct { TelegramID int64 `json:"telegram_id"` Username *string `json:"username,omitempty"` FirstName *string `json:"first_name,omitempty"` LastName *string `json:"last_name,omitempty"` PhotoURL *string `json:"photo_url,omitempty"` StarsBalance int `json:"stars_balance"` CreatedAt time.Time `json:"created_at"` } type Quiz struct { ID int `json:"id"` Title string `json:"title"` Description *string `json:"description,omitempty"` ImageURL *string `json:"image_url,omitempty"` RewardStars int `json:"reward_stars"` HasTimer bool `json:"has_timer"` TimerPerQuestion *int `json:"timer_per_question,omitempty"` CanRepeat bool `json:"can_repeat"` RepeatCooldownHours *int `json:"repeat_cooldown_hours,omitempty"` IsActive bool `json:"is_active"` CreatedBy *int64 `json:"created_by,omitempty"` CreatedAt time.Time `json:"created_at"` Questions []Question `json:"questions,omitempty"` // This field is for API responses, not DB storage } type Question struct { ID int `json:"id"` QuizID int `json:"quiz_id"` Text string `json:"text"` Type QuestionType `json:"type"` Options []Option `json:"options"` // Stored as JSONB OrderIndex int `json:"order_index"` } type Option struct { ID int `json:"id"` Text string `json:"text"` IsCorrect bool `json:"is_correct"` } type QuizAttempt struct { ID int `json:"id"` UserID int64 `json:"user_id"` QuizID int `json:"quiz_id"` Score int `json:"score"` StarsEarned int `json:"stars_earned"` CompletedAt time.Time `json:"completed_at"` Answers []UserAnswer `json:"answers"` // Stored as JSONB // Additional fields for response CorrectAnswers int `json:"correct_answers"` TotalQuestions int `json:"total_questions"` } type Reward struct { ID int `json:"id"` Title string `json:"title"` Description *string `json:"description,omitempty"` ImageURL *string `json:"image_url,omitempty"` PriceStars int `json:"price_stars"` DeliveryType DeliveryType `json:"delivery_type"` Instructions *string `json:"instructions,omitempty"` Stock int `json:"stock"` IsActive bool `json:"is_active"` CreatedBy *int64 `json:"created_by,omitempty"` CreatedAt time.Time `json:"created_at"` } type Purchase struct { ID int `json:"id"` UserID int64 `json:"user_id"` RewardID int `json:"reward_id"` StarsSpent int `json:"stars_spent"` PurchasedAt time.Time `json:"purchased_at"` Status PurchaseStatus `json:"status"` } type QRScan struct { ID int `json:"id"` UserID int64 `json:"user_id"` Type QRScanType `json:"type"` Value *string `json:"value,omitempty"` ScannedAt time.Time `json:"scanned_at"` Source QRScanSource `json:"source"` } type Admin struct { TelegramID int64 `json:"telegram_id"` Role AdminRole `json:"role"` Name *string `json:"name,omitempty"` AddedBy *int64 `json:"added_by,omitempty"` AddedAt time.Time `json:"added_at"` } // --- API Request/Response Structs --- // TransactionType defines whether stars were earned or spent. type TransactionType string const ( TransactionEarned TransactionType = "earned" TransactionSpent TransactionType = "spent" ) // Transaction represents a single entry in the user's balance history. type Transaction struct { Type TransactionType `json:"type"` Amount int `json:"amount"` Description string `json:"description"` CreatedAt time.Time `json:"created_at"` } // SubmissionRequest defines the structure for a user submitting quiz answers. type SubmissionRequest struct { Answers []UserAnswer `json:"answers"` } // UserAnswer defines a single answer provided by the user. type UserAnswer struct { QuestionID int `json:"question_id"` OptionIDs []int `json:"option_ids"` } // GrantStarsRequest defines the structure for an admin to grant stars to a user. type GrantStarsRequest struct { UserID int64 `json:"user_id"` Amount int `json:"amount"` } // CanRepeatResponse defines the response for the can-repeat check. type CanRepeatResponse struct { CanRepeat bool `json:"can_repeat"` NextAvailableAt *time.Time `json:"next_available_at,omitempty"` } // QRValidateRequest defines the structure for a QR validation request. type QRValidateRequest struct { Payload string `json:"payload"` } // QRValidateResponse defines the structure for a QR validation response. type QRValidateResponse struct { Type string `json:"type"` // e.g., "REWARD", "OPEN_QUIZ" Data interface{} `json:"data"` } // GenerateQRCodesRequest defines the structure for generating unique QR codes. type GenerateQRCodesRequest struct { Type string `json:"type"` // e.g., "reward", "quiz" Value string `json:"value"` // e.g., "50" for reward, "1" for quiz Count int `json:"count"` // Number of codes to generate } // QRTokenData represents the data stored for a unique QR token type QRTokenData struct { Type string `json:"type"` // "reward", "quiz", "shop" Value string `json:"value"` // e.g., "50", "123" Used bool `json:"used"` // Whether the token has been used } // GenerateQRCodesResponse defines the response for generating QR codes type GenerateQRCodesResponse struct { Tokens []string `json:"tokens"` // List of generated unique tokens } // CreateOperatorRequest defines the structure for creating a new operator type CreateOperatorRequest struct { TelegramID int64 `json:"telegram_id"` Name string `json:"name"` } // Analytics represents various statistics and metrics for the admin dashboard type Analytics struct { TotalUsers int `json:"total_users"` TotalQuizzes int `json:"total_quizzes"` ActiveQuizzes int `json:"active_quizzes"` TotalRewards int `json:"total_rewards"` ActiveRewards int `json:"active_rewards"` TotalAttempts int `json:"total_attempts"` TotalPurchases int `json:"total_purchases"` TotalQRScans int `json:"total_qr_scans"` StarsDistributed int `json:"stars_distributed"` StarsSpent int `json:"stars_spent"` }