feat(api): add alert system with CRUD endpoints and statistics

Introduce a comprehensive alert management system for monitoring
system events and notifications.

Changes include:
- Add Alert model with type, severity, status, and metadata fields
- Implement AlertHandler with full CRUD operations (create, list,
  get, acknowledge, resolve, dismiss)
- Add alert statistics endpoint for counts by status and severity
- Register Alert model in database auto-migration
- Add minute-level aggregation to log stats (limited to 6-hour range)
This commit is contained in:
zenfun
2025-12-31 13:43:48 +08:00
parent 53c18c3867
commit 2b5e657b3d
4 changed files with 538 additions and 4 deletions

View File

@@ -143,7 +143,7 @@ func main() {
// Auto Migrate
if logDB != db {
if err := db.AutoMigrate(&model.Master{}, &model.Key{}, &model.ProviderGroup{}, &model.APIKey{}, &model.Model{}, &model.Binding{}, &model.Namespace{}, &model.OperationLog{}, &model.SyncOutbox{}); err != nil {
if err := db.AutoMigrate(&model.Master{}, &model.Key{}, &model.ProviderGroup{}, &model.APIKey{}, &model.Model{}, &model.Binding{}, &model.Namespace{}, &model.OperationLog{}, &model.SyncOutbox{}, &model.Alert{}); err != nil {
fatal(logger, "failed to auto migrate", "err", err)
}
if err := logDB.AutoMigrate(&model.LogRecord{}); err != nil {
@@ -153,7 +153,7 @@ func main() {
fatal(logger, "failed to ensure log indexes", "err", err)
}
} else {
if err := db.AutoMigrate(&model.Master{}, &model.Key{}, &model.ProviderGroup{}, &model.APIKey{}, &model.Model{}, &model.Binding{}, &model.Namespace{}, &model.OperationLog{}, &model.LogRecord{}, &model.SyncOutbox{}); err != nil {
if err := db.AutoMigrate(&model.Master{}, &model.Key{}, &model.ProviderGroup{}, &model.APIKey{}, &model.Model{}, &model.Binding{}, &model.Namespace{}, &model.OperationLog{}, &model.LogRecord{}, &model.SyncOutbox{}, &model.Alert{}); err != nil {
fatal(logger, "failed to auto migrate", "err", err)
}
if err := service.EnsureLogIndexes(db); err != nil {
@@ -220,6 +220,7 @@ func main() {
adminHandler := api.NewAdminHandler(db, logDB, masterService, syncService, statsService, logPartitioner)
masterHandler := api.NewMasterHandler(db, logDB, masterService, syncService, statsService, logPartitioner)
dashboardHandler := api.NewDashboardHandler(db, logDB, statsService, logPartitioner)
alertHandler := api.NewAlertHandler(db)
internalHandler := api.NewInternalHandler(db)
featureHandler := api.NewFeatureHandler(rdb)
authHandler := api.NewAuthHandler(db, rdb, adminService, masterService)
@@ -358,6 +359,13 @@ func main() {
adminGroup.GET("/realtime", adminHandler.GetAdminRealtime)
adminGroup.GET("/dashboard/summary", dashboardHandler.GetSummary)
adminGroup.GET("/apikey-stats/summary", adminHandler.GetAPIKeyStatsSummary)
adminGroup.GET("/alerts", alertHandler.ListAlerts)
adminGroup.POST("/alerts", alertHandler.CreateAlert)
adminGroup.GET("/alerts/stats", alertHandler.GetAlertStats)
adminGroup.GET("/alerts/:id", alertHandler.GetAlert)
adminGroup.POST("/alerts/:id/ack", alertHandler.AcknowledgeAlert)
adminGroup.POST("/alerts/:id/resolve", alertHandler.ResolveAlert)
adminGroup.DELETE("/alerts/:id", alertHandler.DismissAlert)
adminGroup.POST("/bindings", handler.CreateBinding)
adminGroup.GET("/bindings", handler.ListBindings)
adminGroup.GET("/bindings/:id", handler.GetBinding)