Initial commit

This commit is contained in:
2026-05-13 19:42:49 -07:00
commit cfa01bd4ef
54 changed files with 11718 additions and 0 deletions

View File

@@ -0,0 +1,84 @@
package scheduler
import (
"strings"
"veola/internal/apify"
)
// ShouldAlert returns true if the result should trigger an alert.
//
// - Result must not already be in DB (caller checks that first).
// - If targetPrice is nil, alert on every new result.
// - If targetPrice is non-nil, alert only when price <= targetPrice.
//
// price=0 is treated as "unknown" and never alerts under a target.
func ShouldAlert(targetPrice *float64, price float64) bool {
if targetPrice == nil {
return true
}
if price <= 0 {
return false
}
return price <= *targetPrice
}
// FilterResults applies match-confidence and out-of-stock filtering. Returns
// a fresh slice; the input is not mutated.
func FilterResults(in []apify.UnifiedResult, minConfidence float64, includeOOS bool) []apify.UnifiedResult {
out := make([]apify.UnifiedResult, 0, len(in))
for _, r := range in {
if !includeOOS && r.OutOfStock {
continue
}
if r.MatchConfidence != 0 && r.MatchConfidence < minConfidence {
continue
}
if r.URL == "" || r.Price <= 0 {
continue
}
out = append(out, r)
}
return out
}
// ApplyItemFilters drops results below minPrice (when set) and any whose title
// contains one of excludeKeywords (case-insensitive substring match). Pass nil
// or empty for either to skip that filter. Returns a fresh slice.
func ApplyItemFilters(in []apify.UnifiedResult, minPrice *float64, excludeKeywords []string) []apify.UnifiedResult {
lowered := make([]string, 0, len(excludeKeywords))
for _, k := range excludeKeywords {
k = strings.ToLower(strings.TrimSpace(k))
if k != "" {
lowered = append(lowered, k)
}
}
out := make([]apify.UnifiedResult, 0, len(in))
outer:
for _, r := range in {
if minPrice != nil && r.Price < *minPrice {
continue
}
if len(lowered) > 0 {
title := strings.ToLower(r.Title)
for _, k := range lowered {
if strings.Contains(title, k) {
continue outer
}
}
}
out = append(out, r)
}
return out
}
// PickBest returns the index of the lowest-priced result, or -1 if none.
func PickBest(rs []apify.UnifiedResult) int {
best := -1
for i, r := range rs {
if best == -1 || r.Price < rs[best].Price {
best = i
}
}
return best
}