feat: F022 source acquisition, crawling & connector abstraction

This commit is contained in:
Benjamin Sutter
2026-05-15 15:32:53 +02:00
parent 8efd6e1974
commit fce0f684af
20 changed files with 1647 additions and 0 deletions
+147
View File
@@ -0,0 +1,147 @@
import type { FreshnessStatus } from './enums'
// ── Connector / Source Type ───────────────────────────────────────────────────
export const DataSourceType = {
API_CONNECTOR: 'API_CONNECTOR',
CSV_IMPORT: 'CSV_IMPORT',
MANUAL_UPLOAD: 'MANUAL_UPLOAD',
PUBLIC_WEB_SOURCE: 'PUBLIC_WEB_SOURCE',
PARTNER_FEED: 'PARTNER_FEED',
INTERNAL_PORTFOLIO_EXPORT: 'INTERNAL_PORTFOLIO_EXPORT',
CONTRACT_METADATA_IMPORT: 'CONTRACT_METADATA_IMPORT',
ANALYST_ENTRY: 'ANALYST_ENTRY',
FUTURE_CRAWLER_STUB: 'FUTURE_CRAWLER_STUB',
} as const
export type DataSourceType = typeof DataSourceType[keyof typeof DataSourceType]
export const DATA_SOURCE_TYPE_LABELS: Record<DataSourceType, string> = {
API_CONNECTOR: 'API-Connector',
CSV_IMPORT: 'CSV-Import',
MANUAL_UPLOAD: 'Manueller Upload',
PUBLIC_WEB_SOURCE: 'Öffentliche Web-Quelle',
PARTNER_FEED: 'Partner-Feed',
INTERNAL_PORTFOLIO_EXPORT: 'Portfolio-Export',
CONTRACT_METADATA_IMPORT: 'Vertrags-Import',
ANALYST_ENTRY: 'Analysten-Eingabe',
FUTURE_CRAWLER_STUB: 'Crawler (geplant)',
}
// ── Source Status ─────────────────────────────────────────────────────────────
export const SourceStatus = {
ACTIVE: 'ACTIVE',
PAUSED: 'PAUSED',
ERROR: 'ERROR',
PENDING_REVIEW: 'PENDING_REVIEW',
DISABLED: 'DISABLED',
} as const
export type SourceStatus = typeof SourceStatus[keyof typeof SourceStatus]
export const SOURCE_STATUS_LABELS: Record<SourceStatus, string> = {
ACTIVE: 'Aktiv',
PAUSED: 'Pausiert',
ERROR: 'Fehler',
PENDING_REVIEW: 'Prüfung ausstehend',
DISABLED: 'Deaktiviert',
}
export const SOURCE_STATUS_COLORS: Record<SourceStatus, { bg: string; fg: string }> = {
ACTIVE: { bg: 'rgba(22,163,74,0.1)', fg: '#15803d' },
PAUSED: { bg: 'rgba(234,179,8,0.1)', fg: '#a16207' },
ERROR: { bg: 'rgba(239,68,68,0.1)', fg: '#dc2626' },
PENDING_REVIEW: { bg: 'rgba(59,130,246,0.1)', fg: '#1d4ed8' },
DISABLED: { bg: 'rgba(148,163,184,0.1)', fg: '#64748b' },
}
// ── Terms / Legal Status ──────────────────────────────────────────────────────
export const TermsStatus = {
APPROVED: 'APPROVED',
NEEDS_LEGAL_REVIEW: 'NEEDS_LEGAL_REVIEW',
RESTRICTED: 'RESTRICTED',
BLOCKED: 'BLOCKED',
UNKNOWN: 'UNKNOWN',
} as const
export type TermsStatus = typeof TermsStatus[keyof typeof TermsStatus]
export const TERMS_STATUS_LABELS: Record<TermsStatus, string> = {
APPROVED: 'Genehmigt',
NEEDS_LEGAL_REVIEW: 'Rechtliche Prüfung',
RESTRICTED: 'Eingeschränkt',
BLOCKED: 'Gesperrt',
UNKNOWN: 'Unbekannt',
}
export const TERMS_STATUS_COLORS: Record<TermsStatus, { bg: string; fg: string; border: string }> = {
APPROVED: { bg: 'rgba(22,163,74,0.08)', fg: '#15803d', border: 'rgba(22,163,74,0.3)' },
NEEDS_LEGAL_REVIEW: { bg: 'rgba(234,179,8,0.08)', fg: '#a16207', border: 'rgba(234,179,8,0.3)' },
RESTRICTED: { bg: 'rgba(249,115,22,0.08)', fg: '#c2410c', border: 'rgba(249,115,22,0.3)' },
BLOCKED: { bg: 'rgba(239,68,68,0.08)', fg: '#dc2626', border: 'rgba(239,68,68,0.3)' },
UNKNOWN: { bg: 'rgba(148,163,184,0.08)', fg: '#64748b', border: 'rgba(148,163,184,0.3)' },
}
// ── Connector Run Status ──────────────────────────────────────────────────────
export const ConnectorRunStatus = {
RUNNING: 'RUNNING',
COMPLETED: 'COMPLETED',
FAILED: 'FAILED',
PARTIAL: 'PARTIAL',
CANCELLED: 'CANCELLED',
} as const
export type ConnectorRunStatus = typeof ConnectorRunStatus[keyof typeof ConnectorRunStatus]
export const CONNECTOR_RUN_STATUS_LABELS: Record<ConnectorRunStatus, string> = {
RUNNING: 'Läuft',
COMPLETED: 'Abgeschlossen',
FAILED: 'Fehlgeschlagen',
PARTIAL: 'Teilweise',
CANCELLED: 'Abgebrochen',
}
export const CONNECTOR_RUN_STATUS_COLORS: Record<ConnectorRunStatus, { bg: string; fg: string }> = {
RUNNING: { bg: 'rgba(99,102,241,0.1)', fg: '#4f46e5' },
COMPLETED: { bg: 'rgba(22,163,74,0.1)', fg: '#15803d' },
FAILED: { bg: 'rgba(239,68,68,0.1)', fg: '#dc2626' },
PARTIAL: { bg: 'rgba(234,179,8,0.1)', fg: '#a16207' },
CANCELLED: { bg: 'rgba(148,163,184,0.1)', fg: '#64748b' },
}
// ── Interfaces ────────────────────────────────────────────────────────────────
export interface DataSource {
id: string
name: string
sourceType: DataSourceType
ownerOrganizationId?: string
legalBasis: string
termsStatus: TermsStatus
dataCategories: string[]
supportedAssetTypes: string[]
regionCoverage: string[]
reliabilityScore: number
freshnessStatus: FreshnessStatus
lastRunAt?: string
nextRunAt?: string
status: SourceStatus
errorState?: string
notes?: string
}
export interface ConnectorRun {
id: string
sourceId: string
startedAt: string
finishedAt?: string
status: ConnectorRunStatus
itemsDetected: number
itemsNormalized: number
itemsRejected: number
signalsCreated: number
errors: string[]
warnings: string[]
runSummary: string
}
export interface SourceFilters {
search?: string
sourceType?: DataSourceType
status?: SourceStatus
termsStatus?: TermsStatus
}