package models import ( "time" ) // Season represents the seasons table type Season struct { ID uint `gorm:"primaryKey;autoIncrement" json:"id"` SeasonNumber int `gorm:"not null;unique;index" json:"season_number"` SeasonName string `gorm:"size:100;not null" json:"season_name"` StartTime time.Time `gorm:"not null" json:"start_time"` EndTime time.Time `gorm:"not null" json:"end_time"` Status string `gorm:"size:20;default:'upcoming'" json:"status"` // upcoming, active, ended TotalRewards float64 `gorm:"type:decimal(30,2)" json:"total_rewards"` Multiplier float64 `gorm:"type:decimal(10,4);default:1.0000" json:"multiplier"` Description string `gorm:"type:text" json:"description"` IsActive bool `gorm:"default:true" json:"is_active"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } func (Season) TableName() string { return "seasons" } // VIPTier represents the vip_tiers table type VIPTier struct { ID uint `gorm:"primaryKey;autoIncrement" json:"id"` TierName string `gorm:"size:50;not null" json:"tier_name"` TierLevel int `gorm:"not null;unique;index" json:"tier_level"` MinPoints int64 `gorm:"not null;index" json:"min_points"` MaxPoints *int64 `json:"max_points"` Multiplier float64 `gorm:"type:decimal(10,4);default:1.0000" json:"multiplier"` Perks string `gorm:"type:json" json:"perks"` Icon string `gorm:"size:255" json:"icon"` Color string `gorm:"size:50" json:"color"` DisplayOrder int `gorm:"default:0" json:"display_order"` IsActive bool `gorm:"default:true" json:"is_active"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } func (VIPTier) TableName() string { return "vip_tiers" } // UserTeam represents the user_teams table type UserTeam struct { WalletAddress string `gorm:"primaryKey;size:42" json:"wallet_address"` TeamTVLUSD float64 `gorm:"type:decimal(30,2);default:0.00" json:"team_tvl_usd"` TeamTargetTVLUSD float64 `gorm:"type:decimal(30,2);default:10000000.00" json:"team_target_tvl_usd"` TeamMembersCount int `gorm:"default:0" json:"team_members_count"` WhalesCount int `gorm:"default:0" json:"whales_count"` WhalesTarget int `gorm:"default:3" json:"whales_target"` TradersCount int `gorm:"default:0" json:"traders_count"` TradersTarget int `gorm:"default:3" json:"traders_target"` UsersCount int `gorm:"default:0" json:"users_count"` UsersTarget int `gorm:"default:3" json:"users_target"` LastCalculatedAt *time.Time `json:"last_calculated_at"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } func (UserTeam) TableName() string { return "user_teams" } // UserPointsSummary represents the user_points_summary table type UserPointsSummary struct { WalletAddress string `gorm:"primaryKey;size:42" json:"wallet_address"` TotalPoints int64 `gorm:"default:0" json:"total_points"` HoldingPoints int64 `gorm:"default:0" json:"holding_points"` LpPoints int64 `gorm:"default:0" json:"lp_points"` LendingPoints int64 `gorm:"default:0" json:"lending_points"` TradingPoints int64 `gorm:"default:0" json:"trading_points"` InvitationPoints int64 `gorm:"default:0" json:"invitation_points"` BonusPoints int64 `gorm:"default:0" json:"bonus_points"` GlobalRank *int `json:"global_rank"` SeasonRank *int `json:"season_rank"` CurrentSeason int `gorm:"default:1" json:"current_season"` TotalTrades int `gorm:"default:0" json:"total_trades"` TotalHoldingDays int `gorm:"default:0" json:"total_holding_days"` TotalInvites int `gorm:"default:0" json:"total_invites"` LastCalculatedAt *time.Time `json:"last_calculated_at"` UpdatedAt time.Time `json:"updated_at"` } func (UserPointsSummary) TableName() string { return "user_points_summary" } // UserPointsRecord represents the user_points_records table type UserPointsRecord struct { ID uint `gorm:"primaryKey;autoIncrement" json:"id"` WalletAddress string `gorm:"size:42;not null;index" json:"wallet_address"` PointsChange int `gorm:"not null" json:"points_change"` PointsBefore int `gorm:"not null" json:"points_before"` PointsAfter int `gorm:"not null" json:"points_after"` SourceType string `gorm:"size:50;not null" json:"source_type"` MultiplierApplied float64 `gorm:"type:decimal(10,4);default:1.0000" json:"multiplier_applied"` SourceID *uint `json:"source_id"` RuleID *uint `json:"rule_id"` Description string `gorm:"type:text" json:"description"` Metadata string `gorm:"type:json" json:"metadata"` CreatedAt time.Time `json:"created_at"` } func (UserPointsRecord) TableName() string { return "user_points_records" } // Invitation represents the invitations table type Invitation struct { ID uint `gorm:"primaryKey;autoIncrement" json:"id"` ReferrerWallet string `gorm:"size:42;not null;index" json:"referrer_wallet"` RefereeWallet string `gorm:"size:42;not null;unique;index" json:"referee_wallet"` InviteCode string `gorm:"size:20;not null" json:"invite_code"` BindSignature string `gorm:"type:text" json:"bind_signature"` BindHash string `gorm:"size:66" json:"bind_hash"` Status string `gorm:"size:50;default:'active'" json:"status"` ReferrerRewardPoints int `gorm:"default:0" json:"referrer_reward_points"` RefereeRewardPoints int `gorm:"default:0" json:"referee_reward_points"` BoundAt time.Time `gorm:"not null" json:"bound_at"` CreatedAt time.Time `json:"created_at"` } func (Invitation) TableName() string { return "invitations" } // InviteCode represents the invite_codes table type InviteCode struct { ID uint `gorm:"primaryKey;autoIncrement" json:"id"` WalletAddress string `gorm:"size:42;not null;unique;index" json:"wallet_address"` Code string `gorm:"size:20;not null;unique;index" json:"code"` MaxUses int `gorm:"default:-1" json:"max_uses"` // -1 = unlimited UsedCount int `gorm:"default:0" json:"used_count"` ExpiresAt NullTime `json:"expires_at"` IsActive bool `gorm:"default:true" json:"is_active"` CreatedAt time.Time `json:"created_at"` } func (InviteCode) TableName() string { return "invite_codes" } // ===================== // Response DTOs // ===================== // DashboardResponse is the response for GET /api/points/dashboard type DashboardResponse struct { TotalPoints int64 `json:"totalPoints"` GlobalRank int `json:"globalRank"` TopPercentage string `json:"topPercentage"` MemberTier string `json:"memberTier"` VIPLevel int `json:"vipLevel"` PointsToNextTier int64 `json:"pointsToNextTier"` NextTier string `json:"nextTier"` Season SeasonInfo `json:"season"` } // SeasonInfo contains season information type SeasonInfo struct { SeasonNumber int `json:"seasonNumber"` SeasonName string `json:"seasonName"` IsLive bool `json:"isLive"` EndTime time.Time `json:"endTime"` DaysRemaining int `json:"daysRemaining"` HoursRemaining int `json:"hoursRemaining"` } // LeaderboardResponse is the response for GET /api/points/leaderboard type LeaderboardResponse struct { TopUsers []LeaderboardUser `json:"topUsers"` MyRank int `json:"myRank"` MyPoints int64 `json:"myPoints"` } // LeaderboardUser represents a user in the leaderboard type LeaderboardUser struct { Rank int `json:"rank"` WalletAddress string `json:"address"` Points int64 `json:"points"` } // InviteCodeResponse is the response for GET /api/points/invite-code type InviteCodeResponse struct { Code string `json:"code"` UsedCount int `json:"usedCount"` MaxUses int `json:"maxUses"` } // TeamTVLResponse is the response for GET /api/points/team type TeamTVLResponse struct { CurrentTVL string `json:"currentTVL"` TargetTVL string `json:"targetTVL"` ProgressPercent float64 `json:"progressPercent"` TotalMembers int `json:"totalMembers"` Roles []RoleCount `json:"roles"` } // RoleCount represents count for each role type RoleCount struct { Icon string `json:"icon"` Label string `json:"label"` Current int `json:"current"` Target int `json:"target"` } // ActivitiesResponse is the response for GET /api/points/activities type ActivitiesResponse struct { Activities []ActivityRecord `json:"activities"` Pagination PaginationInfo `json:"pagination"` } // ActivityRecord represents a single activity type ActivityRecord struct { Type string `json:"type"` UserAddress string `json:"userAddress"` FriendAddress string `json:"friendAddress,omitempty"` InviteCode string `json:"inviteCode,omitempty"` Points int `json:"points"` CreatedAt time.Time `json:"createdAt"` } // PaginationInfo contains pagination metadata type PaginationInfo struct { Page int `json:"page"` PageSize int `json:"pageSize"` Total int `json:"total"` TotalPage int `json:"totalPage"` } // BindInviteRequest is the request body for POST /api/points/bind-invite type BindInviteRequest struct { Code string `json:"code" binding:"required"` Signature string `json:"signature" binding:"required"` } // HoldersSnapshot represents the holders_snapshots table // 每小时快照:记录用户持有 YT/LP/Lending 代币的余额及积分计算结果 type HoldersSnapshot struct { ID uint `gorm:"primaryKey;autoIncrement" json:"id"` WalletAddress string `gorm:"size:42;not null;index" json:"wallet_address"` TokenType string `gorm:"size:20;not null" json:"token_type"` TokenAddress string `gorm:"size:42;not null" json:"token_address"` ChainID int `gorm:"not null" json:"chain_id"` Balance float64 `gorm:"type:decimal(30,18);not null" json:"balance"` BalanceUSD float64 `gorm:"type:decimal(30,2)" json:"balance_usd"` HoldingDurationHours int `json:"holding_duration_hours"` PointsMultiplier float64 `gorm:"type:decimal(10,4);default:1.0000" json:"points_multiplier"` EarnedPoints int `json:"earned_points"` SnapshotTime time.Time `gorm:"not null;index" json:"snapshot_time"` SeasonID *uint `gorm:"index" json:"season_id"` CreatedAt time.Time `json:"created_at"` } func (HoldersSnapshot) TableName() string { return "holders_snapshots" }