import type { DatasetSheet } from '../../domain/dataset'; import type { FindingRecord } from '../../domain/finding'; import { pingCastleSectionSheetId } from '../../features/project-import/canonical-model-to-dataset'; const linkedSectionFieldLabel = 'Verwandte Daten'; // Bewusst kein Text-Matching wie beim Purple-Knight-Ergebnisverweis // (result-linker.ts): die Detailquellen wurden beim Import bereits // deterministisch aufgeloest und tragen ihre sectionIds (kommagetrennt, da // eine Regel eingebettete Tabelle UND Ankerziel haben kann) direkt im Feldwert. // Der Abgleich hier ist deshalb eine exakte ID-Gleichheit, keine Heuristik. export function pingCastleSectionIds(record: FindingRecord): string[] { return record.fields .filter(field => field.label === linkedSectionFieldLabel && field.value) .flatMap(field => field.value.split(',').map(part => part.trim()).filter(Boolean)); } export function linkPingCastleSectionSheets(record: FindingRecord, sheets: DatasetSheet[]): DatasetSheet[] { const sectionIds = pingCastleSectionIds(record); if (!sectionIds.length) return []; const sheetsById = new Map(sheets.map(sheet => [sheet.id, sheet])); return sectionIds .map(sectionId => sheetsById.get(pingCastleSectionSheetId(sectionId))) .filter((sheet): sheet is DatasetSheet => Boolean(sheet)); }