87 строки
3.2 KiB
Go
87 строки
3.2 KiB
Go
package models
|
|
|
|
import (
|
|
"gorm.io/datatypes"
|
|
|
|
"rsgit.ru/rsmon/rsmon/app/models/concerns"
|
|
)
|
|
|
|
// Contact represents a notification contact.
|
|
//
|
|
// Ownership / tenancy:
|
|
//
|
|
// - A Contact belongs to exactly one Account (tenant). AccountID may be
|
|
// nil for system-level admin contacts (see SystemContacts).
|
|
// - A Contact may belong to at most one User. UserID is set when the
|
|
// contact was created on behalf of a specific user (the typical
|
|
// case for self-service "My email" / "My Telegram" contacts) and is
|
|
// nil for account-wide contacts.
|
|
//
|
|
// `User` is omitempty because most list payloads don't preload it; the
|
|
// `/settings/users` page loads it server-side via the AccountUserRow
|
|
// payload.
|
|
type Contact struct {
|
|
concerns.Model
|
|
|
|
AccountID *int64 `json:"account_id" gorm:"type:bigint REFERENCES accounts(id)"`
|
|
Account *Account `json:"-"`
|
|
UserID *int64 `gorm:"type:bigint REFERENCES users(id)" json:"user_id"`
|
|
User *User `json:"user,omitempty"`
|
|
Name string `json:"name" gorm:"not null"`
|
|
Kind string `json:"kind" gorm:"not null;index:contact_value"`
|
|
Value string `json:"value" gorm:"index:contact_value"`
|
|
Enabled bool `json:"enabled" gorm:"not null;default:true"`
|
|
Data datatypes.JSON `json:"data"`
|
|
IsSystem *bool `json:"is_system" gorm:"default:false"`
|
|
Notifications []Notification `json:"-" gorm:"many2many:notification_contacts;"`
|
|
NotificationsCount int `gorm:"-:all" json:"notifications_count"`
|
|
MonitorsCount int `gorm:"-:all" json:"monitors_count"`
|
|
Messages []Message `json:"-"`
|
|
|
|
concerns.Timestamped
|
|
concerns.HasToken
|
|
Audited
|
|
}
|
|
|
|
// SystemContacts returns all contacts marked as system/admin (is_system=true).
|
|
// These are the contacts distributed workers notify directly when the main
|
|
// API is unreachable (see docs/worker-protocol.md "System Selfcheck").
|
|
func SystemContacts() ([]Contact, error) {
|
|
var contacts []Contact
|
|
err := DB().Where("is_system = ? AND enabled = ?", true, true).Find(&contacts).Error
|
|
return contacts, err
|
|
}
|
|
|
|
// ContactsCounts fills NotificationsCount and MonitorsCount for each contact.
|
|
func ContactsCounts(contacts *[]Contact) {
|
|
groupIDs := make(map[int64]bool, 0)
|
|
groupCount := make(map[int64]int, 0)
|
|
|
|
for i, c := range *contacts { //nolint:gocritic // range copy is acceptable here
|
|
(*contacts)[i].NotificationsCount = len(c.Notifications)
|
|
for _, n := range c.Notifications { //nolint:gocritic // range copy is acceptable here
|
|
for _, g := range n.Groups { //nolint:gocritic // range copy is acceptable here
|
|
groupIDs[g.ID] = true
|
|
groupCount[g.ID] = 0
|
|
}
|
|
}
|
|
}
|
|
|
|
gids := make([]int64, 0, len(groupIDs))
|
|
for g := range groupIDs {
|
|
gids = append(gids, g)
|
|
}
|
|
|
|
CountGroups(gids, &groupCount)
|
|
|
|
for i, c := range *contacts { //nolint:gocritic // range copy is acceptable here
|
|
cnt := 0
|
|
for _, n := range c.Notifications { //nolint:gocritic // range copy is acceptable here
|
|
for _, g := range n.Groups { //nolint:gocritic // range copy is acceptable here
|
|
cnt += groupCount[g.ID]
|
|
}
|
|
}
|
|
(*contacts)[i].MonitorsCount = cnt
|
|
}
|
|
}
|