"""Integration — registration of a connector bound to a tenant. The connector itself lives in ``asf-connectors``; this record stores: * which connector type is in use * tenant-scoped configuration references (secrets live elsewhere) * last health state """ from __future__ import annotations from typing import Any, Optional, Dict from enum import Enum from pydantic import Field from asf_domain.base import ( ASFBaseModel, TenantScopedModel, ASFFieldID, UTCDatetime, generate_id, ) class ConnectorType(str, Enum): GITHUB = "github" GITLAB = "gitlab" BITBUCKET = "bitbucket" JIRA = "jira" CONFLUENCE = "confluence" NOTION = "notion" JENKINS = "jenkins" SONARQUBE = "sonarqube" GRAFANA = "grafana" GENERIC_WEBHOOK = "generic_webhook" CUSTOM = "custom" class IntegrationBase(ASFBaseModel): name: str = Field(..., min_length=2, max_length=80) connector: ConnectorType = ConnectorType.CUSTOM is_enabled: bool = True class IntegrationCreate(IntegrationBase): config_ref: Optional[str] = Field( None, max_length=512, description="Reference to a secure store (e.g. vault path) holding connector secrets. " "NEVER inline credentials here.", ) metadata: Dict[str, Any] = Field(default_factory=dict) class Integration(TenantScopedModel, IntegrationBase): id: ASFFieldID = Field(default_factory=generate_id) config_ref: Optional[str] = None metadata: Dict[str, Any] = Field(default_factory=dict) last_health_at: Optional[UTCDatetime] = None last_health_status: Optional[str] = Field(None, max_length=40) created_at: UTCDatetime = ... updated_at: UTCDatetime = ...