Live video on the AT Protocol
at issue-784 76 lines 2.0 kB view raw
1package model 2 3import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "time" 8 9 "gorm.io/gorm" 10) 11 12type Recommendation struct { 13 UserDID string `gorm:"column:user_did;primaryKey"` 14 Streamers json.RawMessage `gorm:"column:streamers;type:json;not null"` 15 CreatedAt time.Time `gorm:"column:created_at"` 16 UpdatedAt time.Time `gorm:"column:updated_at"` 17} 18 19func (r *Recommendation) TableName() string { 20 return "recommendations" 21} 22 23func (r *Recommendation) GetStreamersArray() ([]string, error) { 24 var streamers []string 25 if err := json.Unmarshal(r.Streamers, &streamers); err != nil { 26 return nil, fmt.Errorf("failed to unmarshal streamers: %w", err) 27 } 28 return streamers, nil 29} 30 31// UpsertRecommendation creates or updates recommendations for a user 32func (m *DBModel) UpsertRecommendation(rec *Recommendation) error { 33 if rec.UserDID == "" { 34 return fmt.Errorf("user DID cannot be empty") 35 } 36 37 // Validate JSON contains array of max 8 DIDs 38 var streamers []string 39 if err := json.Unmarshal(rec.Streamers, &streamers); err != nil { 40 return fmt.Errorf("invalid streamers JSON: %w", err) 41 } 42 if len(streamers) > 8 { 43 return fmt.Errorf("maximum 8 recommendations allowed, got %d", len(streamers)) 44 } 45 46 now := time.Now() 47 if rec.CreatedAt.IsZero() { 48 rec.CreatedAt = now 49 } 50 rec.UpdatedAt = now 51 52 // Use GORM's upsert (On Conflict Do Update) 53 result := m.DB.Save(rec) 54 if result.Error != nil { 55 return fmt.Errorf("database upsert failed: %w", result.Error) 56 } 57 58 return nil 59} 60 61// GetRecommendation retrieves a valid recommendation from a user 62func (m *DBModel) GetRecommendation(userDID string) (*Recommendation, error) { 63 if userDID == "" { 64 return nil, fmt.Errorf("user DID cannot be empty") 65 } 66 67 var rec Recommendation 68 err := m.DB.Where("user_did = ?", userDID).First(&rec).Error 69 if err != nil { 70 if errors.Is(err, gorm.ErrRecordNotFound) { 71 return nil, err 72 } 73 return nil, fmt.Errorf("database query failed: %w", err) 74 } 75 return &rec, nil 76}