97 lines
3.0 KiB
Go
97 lines
3.0 KiB
Go
package tables
|
|
|
|
import (
|
|
"encoding/json"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// TableTeam represents a team entity with budget, rate limit and customer association
|
|
type TableTeam struct {
|
|
ID string `gorm:"primaryKey;type:varchar(255)" json:"id"`
|
|
Name string `gorm:"type:varchar(255);not null" json:"name"`
|
|
CustomerID *string `gorm:"type:varchar(255);index" json:"customer_id,omitempty"` // A team can belong to a customer
|
|
RateLimitID *string `gorm:"type:varchar(255);index" json:"rate_limit_id,omitempty"`
|
|
|
|
// Relationships
|
|
Customer *TableCustomer `gorm:"foreignKey:CustomerID" json:"customer,omitempty"`
|
|
Budgets []TableBudget `gorm:"foreignKey:TeamID;constraint:OnDelete:CASCADE" json:"budgets,omitempty"` // Multiple budgets with different reset intervals
|
|
RateLimit *TableRateLimit `gorm:"foreignKey:RateLimitID" json:"rate_limit,omitempty"`
|
|
VirtualKeys []TableVirtualKey `gorm:"foreignKey:TeamID" json:"virtual_keys,omitempty"`
|
|
|
|
// Computed (not a DB column) — populated via correlated subquery in query layer, hence no migration
|
|
VirtualKeyCount int64 `gorm:"->;-:migration" json:"virtual_key_count"`
|
|
|
|
Profile *string `gorm:"type:text" json:"-"`
|
|
ParsedProfile map[string]any `gorm:"-" json:"profile"`
|
|
|
|
Config *string `gorm:"type:text" json:"-"`
|
|
ParsedConfig map[string]any `gorm:"-" json:"config"`
|
|
|
|
Claims *string `gorm:"type:text" json:"-"`
|
|
ParsedClaims map[string]any `gorm:"-" json:"claims"`
|
|
|
|
// Config hash is used to detect the changes synced from config.json file
|
|
// Every time we sync the config.json file, we will update the config hash
|
|
ConfigHash string `gorm:"type:varchar(255);null" json:"config_hash"`
|
|
|
|
CreatedAt time.Time `gorm:"index;not null" json:"created_at"`
|
|
UpdatedAt time.Time `gorm:"index;not null" json:"updated_at"`
|
|
}
|
|
|
|
// TableName sets the table name for each model
|
|
func (TableTeam) TableName() string { return "governance_teams" }
|
|
|
|
// BeforeSave hook for TableTeam to serialize JSON fields
|
|
func (t *TableTeam) BeforeSave(tx *gorm.DB) error {
|
|
if t.ParsedProfile != nil {
|
|
data, err := json.Marshal(t.ParsedProfile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
t.Profile = new(string(data))
|
|
} else {
|
|
t.Profile = nil
|
|
}
|
|
if t.ParsedConfig != nil {
|
|
data, err := json.Marshal(t.ParsedConfig)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
t.Config = new(string(data))
|
|
} else {
|
|
t.Config = nil
|
|
}
|
|
if t.ParsedClaims != nil {
|
|
data, err := json.Marshal(t.ParsedClaims)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
t.Claims = new(string(data))
|
|
} else {
|
|
t.Claims = nil
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// AfterFind hook for TableTeam to deserialize JSON fields
|
|
func (t *TableTeam) AfterFind(tx *gorm.DB) error {
|
|
if t.Profile != nil {
|
|
if err := json.Unmarshal([]byte(*t.Profile), &t.ParsedProfile); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
if t.Config != nil {
|
|
if err := json.Unmarshal([]byte(*t.Config), &t.ParsedConfig); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
if t.Claims != nil {
|
|
if err := json.Unmarshal([]byte(*t.Claims), &t.ParsedClaims); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|