All checks were successful
Build and Release / Create Release (push) Successful in 0s
Build and Release / Unit Tests (push) Successful in 3m17s
Build and Release / Integration Tests (PostgreSQL) (push) Successful in 4m49s
Build and Release / Lint (push) Successful in 4m57s
Build and Release / Build Binaries (amd64, linux, linux-latest) (push) Successful in 3m0s
Build and Release / Build Binaries (amd64, windows, windows-latest) (push) Successful in 9h4m54s
Build and Release / Build Binaries (amd64, darwin, macos) (push) Successful in 7m7s
Build and Release / Build Binaries (arm64, darwin, macos) (push) Successful in 7m59s
Build and Release / Build Binary (linux/arm64) (push) Successful in 8m35s
Adds revive:disable-line comments for exported types without doc comments. Fixes column alignment in migration struct. Adds explanatory nolint comments for intentional nil returns. Sorts imports alphabetically.
170 lines
4.3 KiB
Go
170 lines
4.3 KiB
Go
// Copyright 2026 MarketAlly. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package wishlist
|
|
|
|
import (
|
|
"context"
|
|
|
|
"code.gitcaddy.com/server/v3/models/db"
|
|
"code.gitcaddy.com/server/v3/modules/timeutil"
|
|
)
|
|
|
|
// Importance rating levels.
|
|
const (
|
|
ImportanceNotInterested = 0
|
|
ImportanceImportant = 1
|
|
ImportanceRequired = 2
|
|
)
|
|
|
|
// WishlistImportance represents a user's importance rating on a wishlist item.
|
|
type WishlistImportance struct { //revive:disable-line:exported
|
|
ID int64 `xorm:"pk autoincr"`
|
|
ItemID int64 `xorm:"UNIQUE(user_item) INDEX NOT NULL"`
|
|
UserID int64 `xorm:"UNIQUE(user_item) INDEX NOT NULL"`
|
|
Rating int `xorm:"SMALLINT NOT NULL DEFAULT 0"`
|
|
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
|
}
|
|
|
|
func init() {
|
|
db.RegisterModel(new(WishlistImportance))
|
|
}
|
|
|
|
// ImportanceSummary holds aggregated importance counts for an item.
|
|
type ImportanceSummary struct {
|
|
NotInterested int64
|
|
Important int64
|
|
Required int64
|
|
}
|
|
|
|
// SetImportance upserts a user's importance rating on an item.
|
|
func SetImportance(ctx context.Context, userID, itemID int64, rating int) error {
|
|
existing := &WishlistImportance{}
|
|
has, err := db.GetEngine(ctx).Where("user_id = ? AND item_id = ?", userID, itemID).Get(existing)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if has {
|
|
if existing.Rating == rating {
|
|
return nil // no change
|
|
}
|
|
existing.Rating = rating
|
|
_, err = db.GetEngine(ctx).ID(existing.ID).Cols("rating").Update(existing)
|
|
return err
|
|
}
|
|
|
|
_, err = db.GetEngine(ctx).Insert(&WishlistImportance{
|
|
ItemID: itemID,
|
|
UserID: userID,
|
|
Rating: rating,
|
|
})
|
|
return err
|
|
}
|
|
|
|
// GetUserImportance returns the user's importance rating for an item, or -1 if not set.
|
|
func GetUserImportance(ctx context.Context, userID, itemID int64) (int, error) {
|
|
imp := &WishlistImportance{}
|
|
has, err := db.GetEngine(ctx).Where("user_id = ? AND item_id = ?", userID, itemID).Get(imp)
|
|
if err != nil {
|
|
return -1, err
|
|
}
|
|
if !has {
|
|
return -1, nil
|
|
}
|
|
return imp.Rating, nil
|
|
}
|
|
|
|
// GetImportanceSummary returns aggregated importance counts for an item.
|
|
func GetImportanceSummary(ctx context.Context, itemID int64) (*ImportanceSummary, error) {
|
|
summary := &ImportanceSummary{}
|
|
|
|
type countRow struct {
|
|
Rating int `xorm:"rating"`
|
|
Cnt int64 `xorm:"cnt"`
|
|
}
|
|
var rows []countRow
|
|
err := db.GetEngine(ctx).Table("wishlist_importance").
|
|
Select("rating, COUNT(*) AS cnt").
|
|
Where("item_id = ?", itemID).
|
|
GroupBy("rating").
|
|
Find(&rows)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, r := range rows {
|
|
switch r.Rating {
|
|
case ImportanceNotInterested:
|
|
summary.NotInterested = r.Cnt
|
|
case ImportanceImportant:
|
|
summary.Important = r.Cnt
|
|
case ImportanceRequired:
|
|
summary.Required = r.Cnt
|
|
}
|
|
}
|
|
return summary, nil
|
|
}
|
|
|
|
// GetImportanceSummaryBatch returns importance summaries for multiple items.
|
|
func GetImportanceSummaryBatch(ctx context.Context, itemIDs []int64) (map[int64]*ImportanceSummary, error) {
|
|
result := make(map[int64]*ImportanceSummary, len(itemIDs))
|
|
for _, id := range itemIDs {
|
|
result[id] = &ImportanceSummary{}
|
|
}
|
|
if len(itemIDs) == 0 {
|
|
return result, nil
|
|
}
|
|
|
|
type countRow struct {
|
|
ItemID int64 `xorm:"item_id"`
|
|
Rating int `xorm:"rating"`
|
|
Cnt int64 `xorm:"cnt"`
|
|
}
|
|
var rows []countRow
|
|
err := db.GetEngine(ctx).Table("wishlist_importance").
|
|
Select("item_id, rating, COUNT(*) AS cnt").
|
|
In("item_id", itemIDs).
|
|
GroupBy("item_id, rating").
|
|
Find(&rows)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, r := range rows {
|
|
s, ok := result[r.ItemID]
|
|
if !ok {
|
|
s = &ImportanceSummary{}
|
|
result[r.ItemID] = s
|
|
}
|
|
switch r.Rating {
|
|
case ImportanceNotInterested:
|
|
s.NotInterested = r.Cnt
|
|
case ImportanceImportant:
|
|
s.Important = r.Cnt
|
|
case ImportanceRequired:
|
|
s.Required = r.Cnt
|
|
}
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
// GetUserImportanceBatch returns the user's importance ratings for multiple items.
|
|
func GetUserImportanceBatch(ctx context.Context, userID int64, itemIDs []int64) (map[int64]int, error) {
|
|
result := make(map[int64]int, len(itemIDs))
|
|
if len(itemIDs) == 0 || userID == 0 {
|
|
return result, nil
|
|
}
|
|
|
|
var imps []*WishlistImportance
|
|
err := db.GetEngine(ctx).
|
|
Where("user_id = ?", userID).
|
|
In("item_id", itemIDs).
|
|
Find(&imps)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, imp := range imps {
|
|
result[imp.ItemID] = imp.Rating
|
|
}
|
|
return result, nil
|
|
}
|