package integrations import ( "log" "strings" "gitea.dooplex.hu/admin/felhom-controller/internal/stacks" ) // IntegrationKey builds the settings key: "provider:target". func IntegrationKey(provider, target string) string { return provider + ":" + target } // ParseIntegrationKey splits "provider:target" into its components. func ParseIntegrationKey(key string) (provider, target string, ok bool) { parts := strings.SplitN(key, ":", 2) if len(parts) != 2 || parts[0] == "" || parts[1] == "" { return "", "", false } return parts[0], parts[1], true } // ApplyContext holds all context needed by an integration handler. type ApplyContext struct { ProviderName string // e.g., "onlyoffice" TargetName string // e.g., "filebrowser" Domain string // e.g., "demo-felhom.eu" ProviderEnv map[string]string // decrypted app.yaml env of provider ProviderMeta *stacks.Metadata StacksDir string Logger *log.Logger RestartStack func(name string) error // restart via stacks.Manager } // Handler defines the interface for a concrete integration handler. // Each provider:target pair has one Handler implementation. type Handler interface { // Apply enables the integration (writes configs, runs commands, restarts containers). Apply(ac *ApplyContext) error // Revoke disables the integration (removes configs, runs commands, restarts containers). Revoke(ac *ApplyContext) error } // StatusInfo is returned by the API for UI display. type StatusInfo struct { Key string `json:"key"` // "onlyoffice:filebrowser" Provider string `json:"provider"` Target string `json:"target"` Label string `json:"label"` Description string `json:"description"` Enabled bool `json:"enabled"` Status string `json:"status"` // "active", "error", "disabled", "provider_stopped", "target_unavailable" LastError string `json:"last_error,omitempty"` TargetDeployed bool `json:"target_deployed"` TargetRunning bool `json:"target_running"` }