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>
This commit is contained in:
93
internal/models/alert.go
Normal file
93
internal/models/alert.go
Normal file
@@ -0,0 +1,93 @@
|
||||
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"
|
||||
}
|
||||
Reference in New Issue
Block a user