package repository import ( "database/sql" ) // RecordBrandView inserts a brand view record. func RecordBrandView(d *sql.DB, userID, brand string) error { _, err := d.Exec(` INSERT INTO user_brand_views (user_id, brand) VALUES ($1, $2) `, userID, brand) return err } // FrequentBrand represents a brand the user interacts with frequently. type FrequentBrand struct { Brand string `json:"brand"` ViewCount int `json:"view_count"` FavCount int `json:"fav_count"` LogoURL string `json:"logo_url,omitempty"` StyleCount int `json:"style_count,omitempty"` } // GetFrequentBrands returns brands where user has views≄3 or favorites≄2. func GetFrequentBrands(d *sql.DB, userID string) ([]FrequentBrand, error) { rows, err := d.Query(` SELECT brand, COALESCE(v.cnt, 0) AS view_count, COALESCE(f.cnt, 0) AS fav_count FROM ( SELECT brand, COUNT(*) AS cnt FROM user_brand_views WHERE user_id = $1 GROUP BY brand HAVING COUNT(*) >= 3 ) v FULL OUTER JOIN ( SELECT brand, COUNT(*) AS cnt FROM favorites WHERE user_id = $1 GROUP BY brand HAVING COUNT(*) >= 2 ) f USING (brand) ORDER BY COALESCE(v.cnt, 0) + COALESCE(f.cnt, 0) * 2 DESC `, userID) if err != nil { return nil, err } defer rows.Close() var out []FrequentBrand for rows.Next() { var fb FrequentBrand if err := rows.Scan(&fb.Brand, &fb.ViewCount, &fb.FavCount); err != nil { continue } // Load brand logo and stats logoMap := loadBrandLogos() if u, ok := logoMap[fb.Brand]; ok { fb.LogoURL = u } // Get style count from products var sc int d.QueryRow(`SELECT COUNT(DISTINCT style_name) FROM products WHERE brand = $1`, fb.Brand).Scan(&sc) fb.StyleCount = sc out = append(out, fb) } return out, rows.Err() }