Files
QuoteForge/internal/models/alert.go
Mikhail Chusavitin 190a9aa0a3 Add initial backend implementation
- Go module with Gin, GORM, JWT, excelize dependencies
- Configuration loading from YAML with all settings
- GORM models for users, categories, components, configurations, alerts
- Repository layer for all entities
- Services: auth (JWT), pricing (median/average/weighted), components,
  quotes, configurations, export (CSV/XLSX), alerts
- Middleware: JWT auth, role-based access, CORS
- HTTP handlers for all API endpoints
- Main server with dependency injection and graceful shutdown

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 10:49:56 +03:00

94 lines
3.0 KiB
Go

package models
import (
"database/sql/driver"
"encoding/json"
"errors"
"time"
)
type AlertType string
const (
AlertHighDemandStalePrice AlertType = "high_demand_stale_price"
AlertPriceSpike AlertType = "price_spike"
AlertPriceDrop AlertType = "price_drop"
AlertNoRecentQuotes AlertType = "no_recent_quotes"
AlertTrendingNoPrice AlertType = "trending_no_price"
)
type AlertSeverity string
const (
SeverityLow AlertSeverity = "low"
SeverityMedium AlertSeverity = "medium"
SeverityHigh AlertSeverity = "high"
SeverityCritical AlertSeverity = "critical"
)
type AlertStatus string
const (
AlertStatusNew AlertStatus = "new"
AlertStatusAcknowledged AlertStatus = "acknowledged"
AlertStatusResolved AlertStatus = "resolved"
AlertStatusIgnored AlertStatus = "ignored"
)
type AlertDetails map[string]interface{}
func (d AlertDetails) Value() (driver.Value, error) {
return json.Marshal(d)
}
func (d *AlertDetails) Scan(value interface{}) error {
if value == nil {
*d = make(AlertDetails)
return nil
}
bytes, ok := value.([]byte)
if !ok {
return errors.New("type assertion to []byte failed")
}
return json.Unmarshal(bytes, d)
}
type PricingAlert struct {
ID uint `gorm:"primaryKey;autoIncrement" json:"id"`
LotName string `gorm:"size:255;not null" json:"lot_name"`
AlertType AlertType `gorm:"type:enum('high_demand_stale_price','price_spike','price_drop','no_recent_quotes','trending_no_price');not null" json:"alert_type"`
Severity AlertSeverity `gorm:"type:enum('low','medium','high','critical');default:'medium'" json:"severity"`
Message string `gorm:"type:text;not null" json:"message"`
Details AlertDetails `gorm:"type:json" json:"details"`
Status AlertStatus `gorm:"type:enum('new','acknowledged','resolved','ignored');default:'new'" json:"status"`
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
}
func (PricingAlert) TableName() string {
return "qt_pricing_alerts"
}
type TrendDirection string
const (
TrendUp TrendDirection = "up"
TrendStable TrendDirection = "stable"
TrendDown TrendDirection = "down"
)
type ComponentUsageStats struct {
LotName string `gorm:"column:lot_name;primaryKey;size:255" json:"lot_name"`
QuotesTotal int `gorm:"default:0" json:"quotes_total"`
QuotesLast30d int `gorm:"default:0" json:"quotes_last_30d"`
QuotesLast7d int `gorm:"default:0" json:"quotes_last_7d"`
TotalQuantity int `gorm:"default:0" json:"total_quantity"`
TotalRevenue float64 `gorm:"type:decimal(14,2);default:0" json:"total_revenue"`
TrendDirection TrendDirection `gorm:"type:enum('up','stable','down');default:'stable'" json:"trend_direction"`
TrendPercent float64 `gorm:"type:decimal(5,2);default:0" json:"trend_percent"`
LastUsedAt *time.Time `json:"last_used_at"`
}
func (ComponentUsageStats) TableName() string {
return "qt_component_usage_stats"
}