Some checks failed
CI/CD / go-lint (push) Has been skipped
CI/CD / python-lint (push) Has been skipped
CI/CD / nodejs-lint (push) Has been skipped
CI/CD / test-go-ai-compliance (push) Failing after 32s
CI/CD / test-python-backend-compliance (push) Successful in 30s
CI/CD / test-python-document-crawler (push) Successful in 19s
CI/CD / test-python-dsms-gateway (push) Successful in 16s
CI/CD / validate-canonical-controls (push) Successful in 11s
CI/CD / Deploy (push) Has been skipped
- flow-data.ts: vendor-compliance moved from betrieb/seq:4200 to dokumentation/seq:2500, prerequisite changed to vvt, added 5 DB tables - architecture-data.ts: added vendor tables and API endpoints to backend-compliance service definition - StepHeader.tsx: added vendor-compliance explanation with 4 tips (Art. 28, cross-module integration, third-country transfers, controls library). Updated obligations (12 checks, vendor-link, document), loeschfristen (vendor picker), tom (vendor-controls cross-ref), vvt (processor tab from vendor API) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
426 lines
18 KiB
TypeScript
426 lines
18 KiB
TypeScript
/**
|
|
* Architecture Data — Service Topology for BreakPilot Compliance
|
|
*
|
|
* Statische Definition aller 13 Services, ihrer Verbindungen,
|
|
* DB-Tabellen, RAG-Collections und API-Endpunkte.
|
|
*/
|
|
|
|
// =============================================================================
|
|
// TYPES
|
|
// =============================================================================
|
|
|
|
export type ServiceLayer = 'frontend' | 'backend' | 'infrastructure' | 'data-sovereignty'
|
|
|
|
export interface ArchService {
|
|
id: string
|
|
name: string
|
|
nameShort: string
|
|
layer: ServiceLayer
|
|
tech: string
|
|
port: number | null
|
|
url: string | null
|
|
container: string
|
|
description: string
|
|
descriptionLong: string
|
|
dbTables: string[]
|
|
ragCollections: string[]
|
|
apiEndpoints: string[]
|
|
dependsOn: string[]
|
|
}
|
|
|
|
export interface ArchEdge {
|
|
source: string
|
|
target: string
|
|
label?: string
|
|
}
|
|
|
|
// =============================================================================
|
|
// LAYER CONFIG
|
|
// =============================================================================
|
|
|
|
export const LAYERS: Record<ServiceLayer, {
|
|
name: string
|
|
color: string
|
|
colorBg: string
|
|
colorBorder: string
|
|
colorText: string
|
|
y: number
|
|
}> = {
|
|
frontend: {
|
|
name: 'Frontend',
|
|
color: '#3b82f6',
|
|
colorBg: '#eff6ff',
|
|
colorBorder: '#3b82f6',
|
|
colorText: '#1e40af',
|
|
y: 0,
|
|
},
|
|
backend: {
|
|
name: 'Backend APIs',
|
|
color: '#8b5cf6',
|
|
colorBg: '#f5f3ff',
|
|
colorBorder: '#8b5cf6',
|
|
colorText: '#5b21b6',
|
|
y: 220,
|
|
},
|
|
infrastructure: {
|
|
name: 'Infrastructure',
|
|
color: '#64748b',
|
|
colorBg: '#f8fafc',
|
|
colorBorder: '#64748b',
|
|
colorText: '#334155',
|
|
y: 440,
|
|
},
|
|
'data-sovereignty': {
|
|
name: 'Data Sovereignty',
|
|
color: '#22c55e',
|
|
colorBg: '#f0fdf4',
|
|
colorBorder: '#22c55e',
|
|
colorText: '#166534',
|
|
y: 600,
|
|
},
|
|
}
|
|
|
|
// =============================================================================
|
|
// SERVICES
|
|
// =============================================================================
|
|
|
|
export const ARCH_SERVICES: ArchService[] = [
|
|
// ── Frontend ──────────────────────────────────────────────────────────────
|
|
{
|
|
id: 'admin-compliance',
|
|
name: 'Admin Compliance Dashboard',
|
|
nameShort: 'Admin',
|
|
layer: 'frontend',
|
|
tech: 'Next.js 15',
|
|
port: 3007,
|
|
url: 'https://macmini:3007',
|
|
container: 'bp-compliance-admin',
|
|
description: 'Haupt-Dashboard fuer alle 17+ DSGVO/AI-Act Compliance-Module. SDK-Sidebar, CommandBar, ComplianceAdvisor.',
|
|
descriptionLong: 'Das Admin Compliance Dashboard ist die zentrale Benutzeroberflaeche fuer alle Compliance-Aktivitaeten. Es beinhaltet ueber 48 SDK-Module — von VVT und DSFA ueber Loeschfristen bis hin zu Schulungen und Audit-Reports. Saemtliche Backend-Aufrufe laufen ueber Next.js API-Routes als Reverse Proxy, sodass keine direkten Backend-URLs im Browser exponiert werden.',
|
|
dbTables: [],
|
|
ragCollections: [],
|
|
apiEndpoints: [
|
|
'/api/sdk/v1/compliance/[[...path]]',
|
|
'/api/sdk/v1/training/[[...path]]',
|
|
'/api/sdk/v1/rag/[[...path]]',
|
|
'/api/admin/consent/[[...path]]',
|
|
],
|
|
dependsOn: ['backend-compliance', 'ai-compliance-sdk', 'document-crawler'],
|
|
},
|
|
{
|
|
id: 'developer-portal',
|
|
name: 'Developer Portal',
|
|
nameShort: 'Dev Portal',
|
|
layer: 'frontend',
|
|
tech: 'Next.js 15',
|
|
port: 3006,
|
|
url: 'https://macmini:3006',
|
|
container: 'bp-compliance-developer-portal',
|
|
description: 'API-Dokumentation und SDK-Referenz fuer Kunden-Integration.',
|
|
descriptionLong: 'Das Developer Portal richtet sich an externe Entwickler, die das Compliance SDK in ihre eigenen Anwendungen integrieren moechten. Es dokumentiert alle REST-Endpunkte mit Request/Response-Beispielen, Authentifizierungs-Flows und SDK-Initialisierung. Das Portal laeuft als eigenstaendige Next.js-Instanz ohne Backend-Abhaengigkeiten.',
|
|
dbTables: [],
|
|
ragCollections: [],
|
|
apiEndpoints: [],
|
|
dependsOn: [],
|
|
},
|
|
{
|
|
id: 'docs',
|
|
name: 'SDK Dokumentation',
|
|
nameShort: 'Docs',
|
|
layer: 'frontend',
|
|
tech: 'MkDocs / Nginx',
|
|
port: 8011,
|
|
url: 'https://macmini:8011',
|
|
container: 'bp-compliance-docs',
|
|
description: 'MkDocs-basierte technische Dokumentation. Statische Site via Nginx.',
|
|
descriptionLong: 'Die SDK-Dokumentation wird aus Markdown-Quelldateien (docs-src/) mit MkDocs generiert und als statische HTML-Site ueber Nginx ausgeliefert. Sie enthaelt Architektur-Beschreibungen, API-Referenzen, Deployment-Anleitungen und Compliance-Leitfaeden. Updates werden durch einen Docker-Rebuild automatisch veroeffentlicht.',
|
|
dbTables: [],
|
|
ragCollections: [],
|
|
apiEndpoints: [],
|
|
dependsOn: [],
|
|
},
|
|
|
|
// ── Backend APIs ──────────────────────────────────────────────────────────
|
|
{
|
|
id: 'backend-compliance',
|
|
name: 'Backend Compliance',
|
|
nameShort: 'Backend',
|
|
layer: 'backend',
|
|
tech: 'Python / FastAPI',
|
|
port: 8002,
|
|
url: 'https://macmini:8002',
|
|
container: 'bp-compliance-backend',
|
|
description: 'Zentrale Compliance-API: DSGVO, DSR, GDPR, VVT, Loeschfristen, Obligations, Legal Documents, Consent.',
|
|
descriptionLong: 'Das Backend Compliance ist das Herzsttueck der Datenverarbeitung. Es verwaltet 16+ DB-Tabellen fuer Risiken, Kontrollen, Nachweise, VVT-Eintraege, Loeschfristen, rechtliche Dokumente und Einwilligungen. Alle CRUD-Operationen laufen ueber SQLAlchemy mit Pydantic-Validierung. Sessions und Caching werden ueber Valkey (Redis-kompatibel) abgewickelt, um schnelle Antwortzeiten zu gewaehrleisten.',
|
|
dbTables: [
|
|
'compliance_risks', 'compliance_controls', 'compliance_requirements',
|
|
'compliance_evidence', 'compliance_vvt', 'compliance_loeschfristen',
|
|
'compliance_obligations', 'legal_documents', 'legal_templates',
|
|
'einwilligungen_consents', 'consent_history',
|
|
'security_backlog', 'quality_entries',
|
|
'notfallplan_incidents', 'notfallplan_templates',
|
|
'data_processing_agreement',
|
|
'vendor_vendors', 'vendor_contracts', 'vendor_findings',
|
|
'vendor_control_instances', 'compliance_templates',
|
|
'compliance_isms_scope', 'compliance_isms_context', 'compliance_isms_policy',
|
|
'compliance_security_objectives', 'compliance_soa',
|
|
'compliance_audit_findings', 'compliance_corrective_actions',
|
|
'compliance_management_reviews', 'compliance_internal_audits',
|
|
'compliance_audit_trail', 'compliance_isms_readiness_checks',
|
|
],
|
|
ragCollections: [],
|
|
apiEndpoints: [
|
|
'POST/GET /api/v1/compliance/risks',
|
|
'POST/GET /api/v1/compliance/controls',
|
|
'POST/GET /api/v1/compliance/requirements',
|
|
'POST/GET /api/v1/compliance/evidence',
|
|
'POST/GET /api/v1/dsr/requests',
|
|
'POST/GET /api/v1/gdpr/exports',
|
|
'POST/GET /api/v1/consent/admin',
|
|
'CRUD /api/compliance/vvt',
|
|
'CRUD /api/compliance/loeschfristen',
|
|
'CRUD /api/compliance/obligations',
|
|
'CRUD /api/sdk/v1/vendor-compliance/vendors',
|
|
'CRUD /api/sdk/v1/vendor-compliance/contracts',
|
|
'CRUD /api/sdk/v1/vendor-compliance/findings',
|
|
'CRUD /api/sdk/v1/vendor-compliance/control-instances',
|
|
'CRUD /api/isms/scope',
|
|
'CRUD /api/isms/policies',
|
|
'CRUD /api/isms/objectives',
|
|
'CRUD /api/isms/soa',
|
|
'CRUD /api/isms/findings',
|
|
'CRUD /api/isms/capa',
|
|
'CRUD /api/isms/management-reviews',
|
|
'CRUD /api/isms/internal-audits',
|
|
'GET /api/isms/overview',
|
|
'POST /api/isms/readiness-check',
|
|
'CRUD /api/compliance/legal-documents',
|
|
'CRUD /api/compliance/legal-templates',
|
|
],
|
|
dependsOn: ['postgresql', 'valkey'],
|
|
},
|
|
{
|
|
id: 'ai-compliance-sdk',
|
|
name: 'AI Compliance SDK',
|
|
nameShort: 'AI SDK',
|
|
layer: 'backend',
|
|
tech: 'Go / Gin',
|
|
port: 8093,
|
|
url: 'https://macmini:8093',
|
|
container: 'bp-compliance-ai-sdk',
|
|
description: 'KI-konforme Compliance-Analyse: UCCA, Training, RAG-Suche, IACE, Portfolio, Roadmap, Workshop.',
|
|
descriptionLong: 'Der AI Compliance SDK Service ist in Go geschrieben und bietet KI-gestuetzte Compliance-Analysen. Er fuehrt UCCA-Bewertungen (Use Case Compliance Assessments) durch, verwaltet Schulungsmodule mit Fortschrittstracking und durchsucht Rechtstexte per RAG (Retrieval Augmented Generation) ueber Qdrant. Als LLM wird primaer Ollama (qwen3.5:35b-a3b) lokal genutzt, mit Fallback auf Claude Sonnet ueber die Anthropic API.',
|
|
dbTables: [
|
|
'ai_assessments', 'ai_training_modules', 'ai_training_progress',
|
|
],
|
|
ragCollections: [
|
|
'bp_dsgvo', 'bp_ai_act', 'bp_bdsg', 'bp_ttdsg',
|
|
'bp_compliance_templates',
|
|
],
|
|
apiEndpoints: [
|
|
'GET /regulations',
|
|
'POST /search',
|
|
'CRUD /assessments',
|
|
'CRUD /training/modules',
|
|
'GET /training/progress',
|
|
'POST /analyze',
|
|
],
|
|
dependsOn: ['qdrant', 'ollama', 'postgresql'],
|
|
},
|
|
{
|
|
id: 'document-crawler',
|
|
name: 'Document Crawler',
|
|
nameShort: 'Crawler',
|
|
layer: 'backend',
|
|
tech: 'Python / FastAPI',
|
|
port: 8098,
|
|
url: 'https://macmini:8098',
|
|
container: 'bp-compliance-document-crawler',
|
|
description: 'Dokument-Analyse (PDF, DOCX, XLSX, PPTX), Gap-Analyse, IPFS-Archivierung.',
|
|
descriptionLong: 'Der Document Crawler nimmt hochgeladene Dokumente (PDF, DOCX, XLSX, PPTX) entgegen, extrahiert deren Inhalt und fuehrt eine Gap-Analyse gegen bestehende Compliance-Anforderungen durch. Dafuer leitet er die Textinhalte an den AI Compliance SDK weiter, der die semantische Analyse uebernimmt. Abgeschlossene Dokumente koennen ueber den DSMS-Service dezentral auf IPFS archiviert werden.',
|
|
dbTables: [],
|
|
ragCollections: [],
|
|
apiEndpoints: [
|
|
'POST /analyze',
|
|
'POST /gap-analysis',
|
|
'POST /archive',
|
|
],
|
|
dependsOn: ['ai-compliance-sdk', 'dsms'],
|
|
},
|
|
{
|
|
id: 'compliance-tts',
|
|
name: 'Compliance TTS',
|
|
nameShort: 'TTS',
|
|
layer: 'backend',
|
|
tech: 'Piper TTS + FFmpeg',
|
|
port: 8095,
|
|
url: null,
|
|
container: 'bp-compliance-tts',
|
|
description: 'Text-to-Speech fuer Schulungsvideos. Piper TTS (de_DE-thorsten-high), Video-Generierung, MinIO-Storage.',
|
|
descriptionLong: 'Der TTS-Service wandelt Schulungstexte in natuerlich klingende Sprache um und generiert daraus komplette Schulungsvideos. Er nutzt das deutsche Piper-TTS-Modell (thorsten-high) fuer die Sprachsynthese und FFmpeg fuer die Video-Komposition. Die fertigen Audio- und Videodateien werden in MinIO (S3-kompatibel) gespeichert und koennen ueber das Training-Modul abgerufen werden.',
|
|
dbTables: [],
|
|
ragCollections: [],
|
|
apiEndpoints: [
|
|
'POST /synthesize',
|
|
'POST /generate-video',
|
|
],
|
|
dependsOn: ['minio'],
|
|
},
|
|
|
|
// ── Infrastructure ────────────────────────────────────────────────────────
|
|
{
|
|
id: 'postgresql',
|
|
name: 'PostgreSQL',
|
|
nameShort: 'PostgreSQL',
|
|
layer: 'infrastructure',
|
|
tech: 'PostgreSQL 17',
|
|
port: 54321,
|
|
url: null,
|
|
container: '46.225.100.82:54321 (extern)',
|
|
description: 'Externe PostgreSQL-Instanz (Hetzner/meghshakka). Schemas: compliance (51 Tabellen) + public (33 compliance_*-Tabellen). Migriert 2026-03-06.',
|
|
descriptionLong: 'Die Compliance-Daten liegen seit 2026-03-06 auf einer dedizierten externen PostgreSQL 17-Instanz bei Hetzner (meghshakka, 46.225.100.82:54321). Das compliance-Schema umfasst 51 Tabellen fuer Risiken, Kontrollen, VVT, DSFA, Einwilligungen, Loeschfristen u.v.m. Weitere 33 compliance_*-Tabellen befinden sich im public-Schema (Tenants, Namespaces, LLM-Policies, Legal Documents etc.). Die Verbindung ist TLS-verschluesselt (sslmode=require). Die lokale bp-core-postgres auf dem Mac Mini wird exklusiv von breakpilot-lehrer (NIBIS-Daten) genutzt.',
|
|
dbTables: [],
|
|
ragCollections: [],
|
|
apiEndpoints: [],
|
|
dependsOn: [],
|
|
},
|
|
{
|
|
id: 'valkey',
|
|
name: 'Valkey (Redis)',
|
|
nameShort: 'Valkey',
|
|
layer: 'infrastructure',
|
|
tech: 'Valkey 7',
|
|
port: 6379,
|
|
url: null,
|
|
container: 'bp-core-valkey',
|
|
description: 'Session-Cache und Pub/Sub. Redis-kompatibel, von breakpilot-core bereitgestellt.',
|
|
descriptionLong: 'Valkey ist ein Redis-kompatibler In-Memory-Store, der von breakpilot-core bereitgestellt wird. Er speichert Session-Daten, kurzlebige Caches und dient als Pub/Sub-Broker fuer Event-basierte Kommunikation zwischen Services. Durch die Redis-Kompatibilitaet koennen bestehende Redis-Clients und -Bibliotheken ohne Aenderungen verwendet werden.',
|
|
dbTables: [],
|
|
ragCollections: [],
|
|
apiEndpoints: [],
|
|
dependsOn: [],
|
|
},
|
|
{
|
|
id: 'qdrant',
|
|
name: 'Qdrant',
|
|
nameShort: 'Qdrant',
|
|
layer: 'infrastructure',
|
|
tech: 'Qdrant Cloud',
|
|
port: 443,
|
|
url: 'https://qdrant-dev.breakpilot.ai',
|
|
container: 'qdrant-dev.breakpilot.ai (extern)',
|
|
description: 'Externe Vektor-Datenbank (Hetzner/meghshakka). RAG-Compliance-Suche. Collections: DSGVO, AI Act, BDSG, TTDSG. Migriert 2026-03-06.',
|
|
descriptionLong: 'Qdrant laeuft seit 2026-03-06 als externe Instanz auf qdrant-dev.breakpilot.ai (Hetzner/meghshakka). Es speichert Vektorembeddings von Rechtstexten und Compliance-Dokumenten in thematischen Collections. Der AI Compliance SDK verbindet sich per HTTPS mit API-Key-Authentifizierung. Durch die externe Instanz skaliert der Vektorspeicher unabhaengig vom Mac Mini.',
|
|
dbTables: [],
|
|
ragCollections: [
|
|
'bp_dsgvo', 'bp_ai_act', 'bp_bdsg', 'bp_ttdsg',
|
|
'bp_compliance_templates',
|
|
],
|
|
apiEndpoints: [],
|
|
dependsOn: [],
|
|
},
|
|
{
|
|
id: 'minio',
|
|
name: 'Hetzner Object Storage',
|
|
nameShort: 'Object Storage',
|
|
layer: 'infrastructure',
|
|
tech: 'S3-kompatibel',
|
|
port: 443,
|
|
url: 'https://nbg1.your-objectstorage.com',
|
|
container: 'nbg1.your-objectstorage.com (extern)',
|
|
description: 'Externer S3-kompatibler Object Storage (Hetzner Nuernberg). TTS-Audio, generierte Videos. Migriert 2026-03-06.',
|
|
descriptionLong: 'Der Object Storage laeuft seit 2026-03-06 auf dem Hetzner-Standort Nuernberg (nbg1.your-objectstorage.com) und ist vollstaendig S3-kompatibel. Der Compliance TTS-Service speichert dort generierte Schulungsvideos und Audio-Dateien. Die Verbindung ist TLS-verschluesselt (MINIO_SECURE=true). Die lokale bp-core-minio-Instanz auf dem Mac Mini wird nicht mehr vom Compliance-Stack genutzt.',
|
|
dbTables: [],
|
|
ragCollections: [],
|
|
apiEndpoints: [],
|
|
dependsOn: [],
|
|
},
|
|
{
|
|
id: 'ollama',
|
|
name: 'Ollama',
|
|
nameShort: 'Ollama',
|
|
layer: 'infrastructure',
|
|
tech: 'Ollama',
|
|
port: 11434,
|
|
url: null,
|
|
container: 'bp-core-ollama',
|
|
description: 'Lokaler LLM-Server. Modell: qwen3.5:35b-a3b. Fallback: Claude Sonnet via Anthropic API.',
|
|
descriptionLong: 'Ollama hostet ein lokales Large Language Model (qwen3.5:35b-a3b) fuer Compliance-Analysen, Textgenerierung und UCCA-Bewertungen. Durch die lokale Ausfuehrung bleiben alle Daten im eigenen Netzwerk — ein zentraler Vorteil fuer DSGVO-Konformitaet. Ist das lokale Modell nicht verfuegbar oder die Aufgabe zu komplex, wird automatisch auf Claude Sonnet ueber die Anthropic API zurueckgegriffen.',
|
|
dbTables: [],
|
|
ragCollections: [],
|
|
apiEndpoints: [],
|
|
dependsOn: [],
|
|
},
|
|
|
|
// ── Data Sovereignty ──────────────────────────────────────────────────────
|
|
{
|
|
id: 'dsms',
|
|
name: 'DSMS (IPFS + Gateway)',
|
|
nameShort: 'DSMS',
|
|
layer: 'data-sovereignty',
|
|
tech: 'Kubo + Node.js',
|
|
port: 8082,
|
|
url: null,
|
|
container: 'bp-compliance-dsms-node / dsms-gateway',
|
|
description: 'Data Sovereignty Management System. IPFS-Node (Kubo) + Gateway fuer dezentrale Dokument-Archivierung.',
|
|
descriptionLong: 'Das DSMS (Data Sovereignty Management System) besteht aus einem IPFS-Node (Kubo) und einem Node.js-Gateway. Es ermoeglicht die dezentrale, manipulationssichere Archivierung von Compliance-Dokumenten ueber das InterPlanetary File System. Jedes archivierte Dokument erhaelt einen Content Identifier (CID), der als kryptografischer Nachweis der Dokumentenintegritaet dient.',
|
|
dbTables: [],
|
|
ragCollections: [],
|
|
apiEndpoints: [
|
|
'POST /pin',
|
|
'GET /retrieve/:cid',
|
|
'GET /status',
|
|
],
|
|
dependsOn: [],
|
|
},
|
|
]
|
|
|
|
// =============================================================================
|
|
// EDGES (Datenfluss-Verbindungen)
|
|
// =============================================================================
|
|
|
|
export const ARCH_EDGES: ArchEdge[] = [
|
|
// Frontend → Backend
|
|
{ source: 'admin-compliance', target: 'backend-compliance', label: 'REST API' },
|
|
{ source: 'admin-compliance', target: 'ai-compliance-sdk', label: 'REST API' },
|
|
{ source: 'admin-compliance', target: 'document-crawler', label: 'REST API' },
|
|
|
|
// Backend → Infrastructure
|
|
{ source: 'backend-compliance', target: 'postgresql', label: 'SQLAlchemy' },
|
|
{ source: 'backend-compliance', target: 'valkey', label: 'Sessions' },
|
|
{ source: 'ai-compliance-sdk', target: 'qdrant', label: 'Vektor-Suche' },
|
|
{ source: 'ai-compliance-sdk', target: 'ollama', label: 'LLM Inference' },
|
|
{ source: 'ai-compliance-sdk', target: 'postgresql', label: 'GORM' },
|
|
{ source: 'compliance-tts', target: 'minio', label: 'Audio/Video' },
|
|
|
|
// Backend → Backend
|
|
{ source: 'document-crawler', target: 'ai-compliance-sdk', label: 'LLM Gateway' },
|
|
|
|
// Backend → Data Sovereignty
|
|
{ source: 'document-crawler', target: 'dsms', label: 'IPFS Archive' },
|
|
]
|
|
|
|
// =============================================================================
|
|
// HELPERS
|
|
// =============================================================================
|
|
|
|
export function getServiceById(id: string): ArchService | undefined {
|
|
return ARCH_SERVICES.find(s => s.id === id)
|
|
}
|
|
|
|
export function getServicesByLayer(layer: ServiceLayer): ArchService[] {
|
|
return ARCH_SERVICES.filter(s => s.layer === layer)
|
|
}
|
|
|
|
export function getAllDbTables(): string[] {
|
|
const tables = new Set<string>()
|
|
ARCH_SERVICES.forEach(s => s.dbTables.forEach(t => tables.add(t)))
|
|
return Array.from(tables)
|
|
}
|
|
|
|
export function getAllRagCollections(): string[] {
|
|
const collections = new Set<string>()
|
|
ARCH_SERVICES.forEach(s => s.ragCollections.forEach(c => collections.add(c)))
|
|
return Array.from(collections)
|
|
}
|