71 lines
1.8 KiB
Go
71 lines
1.8 KiB
Go
|
|
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()
|
||
|
|
}
|