Files
omega-server/local/model/integration.go
2025-07-06 19:19:36 +02:00

145 lines
4.0 KiB
Go

package model
import (
"encoding/json"
"errors"
"strings"
"gorm.io/gorm"
)
// Integration represents a third-party integration configuration
type Integration struct {
BaseModel
ProjectID string `json:"project_id" gorm:"not null;type:uuid;index;references:projects(id);onDelete:CASCADE"`
Type string `json:"type" gorm:"not null;type:varchar(50)"`
Config json.RawMessage `json:"config" gorm:"type:jsonb;not null"`
Project Project `json:"project,omitempty" gorm:"foreignKey:ProjectID"`
}
// IntegrationCreateRequest represents the request to create a new integration
type IntegrationCreateRequest struct {
ProjectID string `json:"project_id" validate:"required,uuid"`
Type string `json:"type" validate:"required,min=1,max=50"`
Config map[string]interface{} `json:"config" validate:"required"`
}
// IntegrationUpdateRequest represents the request to update an integration
type IntegrationUpdateRequest struct {
Config map[string]interface{} `json:"config" validate:"required"`
}
// IntegrationInfo represents public integration information
type IntegrationInfo struct {
ID string `json:"id"`
ProjectID string `json:"project_id"`
Type string `json:"type"`
Config map[string]interface{} `json:"config"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
}
// BeforeCreate is called before creating an integration
func (i *Integration) BeforeCreate(tx *gorm.DB) error {
i.BaseModel.BeforeCreate()
// Normalize type
i.Type = strings.ToLower(strings.TrimSpace(i.Type))
return i.Validate()
}
// BeforeUpdate is called before updating an integration
func (i *Integration) BeforeUpdate(tx *gorm.DB) error {
i.BaseModel.BeforeUpdate()
// Normalize type if it's being updated
if i.Type != "" {
i.Type = strings.ToLower(strings.TrimSpace(i.Type))
}
return i.Validate()
}
// Validate validates integration data
func (i *Integration) Validate() error {
if i.ProjectID == "" {
return errors.New("project_id is required")
}
if i.Type == "" {
return errors.New("type is required")
}
if len(i.Type) > 50 {
return errors.New("type must not exceed 50 characters")
}
if len(i.Config) == 0 {
return errors.New("config is required")
}
// Validate that config is valid JSON
var configMap map[string]interface{}
if err := json.Unmarshal(i.Config, &configMap); err != nil {
return errors.New("config must be valid JSON")
}
return nil
}
// ToIntegrationInfo converts Integration to IntegrationInfo (public information)
func (i *Integration) ToIntegrationInfo() IntegrationInfo {
integrationInfo := IntegrationInfo{
ID: i.ID,
ProjectID: i.ProjectID,
Type: i.Type,
CreatedAt: i.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
UpdatedAt: i.UpdatedAt.Format("2006-01-02T15:04:05Z07:00"),
}
// Parse config JSON to map
var configMap map[string]interface{}
if err := json.Unmarshal(i.Config, &configMap); err == nil {
integrationInfo.Config = configMap
}
return integrationInfo
}
// SetConfig sets the configuration from a map
func (i *Integration) SetConfig(config map[string]interface{}) error {
configJSON, err := json.Marshal(config)
if err != nil {
return err
}
i.Config = configJSON
return nil
}
// GetConfig gets the configuration as a map
func (i *Integration) GetConfig() (map[string]interface{}, error) {
var configMap map[string]interface{}
err := json.Unmarshal(i.Config, &configMap)
return configMap, err
}
// GetConfigValue gets a specific configuration value
func (i *Integration) GetConfigValue(key string) (interface{}, error) {
configMap, err := i.GetConfig()
if err != nil {
return nil, err
}
return configMap[key], nil
}
// SetConfigValue sets a specific configuration value
func (i *Integration) SetConfigValue(key string, value interface{}) error {
configMap, err := i.GetConfig()
if err != nil {
return err
}
configMap[key] = value
return i.SetConfig(configMap)
}