diff --git a/general-market-intelligence/utils/reportParser.ts b/general-market-intelligence/utils/reportParser.ts new file mode 100644 index 00000000..3af51310 --- /dev/null +++ b/general-market-intelligence/utils/reportParser.ts @@ -0,0 +1,83 @@ + +import { AnalysisResult, LeadStatus, SearchStrategy, Tier, SearchSignal } from "../types"; + +export const parseMarkdownReport = (md: string): { strategy: SearchStrategy; results: AnalysisResult[] } | null => { + try { + const lines = md.split('\n'); + + // 1. Extract Product Context from H1 + const h1Line = lines.find(l => l.startsWith('# Market Intelligence Report:')); + const productContext = h1Line ? h1Line.replace('# Market Intelligence Report:', '').trim() : "Imported Analysis"; + + // 2. Extract ICP from Context line + const icpLine = lines.find(l => l.includes('**Context:**')); + const idealCustomerProfile = icpLine ? icpLine.replace('**Context:**', '').replace(/\*/g, '').trim() : ""; + + // 3. Find Table and Headers + const tableStartIndex = lines.findIndex(l => l.trim().startsWith('|') && l.includes('Company')); + if (tableStartIndex === -1) return null; + + const headerLine = lines[tableStartIndex]; + const headers = headerLine.split('|').map(h => h.trim()).filter(h => h !== ''); + + // Identify dynamic signal columns (everything between 'Status' and 'Recommendation') + const statusIdx = headers.indexOf('Status'); + const recIdx = headers.indexOf('Recommendation'); + + const signalNames = headers.slice(statusIdx + 1, recIdx); + const signals: SearchSignal[] = signalNames.map((name, i) => ({ + id: `sig_${i + 1}`, + name, + description: `Imported signal: ${name}`, + targetPageKeywords: [] + })); + + const strategy: SearchStrategy = { + productContext, + idealCustomerProfile, + signals + }; + + // 4. Parse Rows + const results: AnalysisResult[] = []; + // Start after header and separator line + for (let i = tableStartIndex + 2; i < lines.length; i++) { + const line = lines[i].trim(); + if (!line.startsWith('|')) continue; + + const cells = line.split('|').map(c => c.trim()).filter(c => c !== ''); + if (cells.length < headers.length) continue; + + const [name, prio, revEmp, statusCell] = cells; + const [rev, emp] = revEmp.split('/').map(s => s.trim()); + + // Reconstruct dynamic Analysis + const dynamicAnalysis: Record = {}; + signalNames.forEach((sigName, idx) => { + const sigId = signals[idx].id; + dynamicAnalysis[sigId] = { + value: cells[statusIdx + 1 + idx], + proof: "Imported from file", + sentiment: "Neutral" + }; + }); + + results.push({ + companyName: name, + tier: (prio as Tier) || Tier.TIER_3, + revenue: rev || "?", + employees: emp || "?", + status: (statusCell as LeadStatus) || LeadStatus.UNKNOWN, + dataSource: "Imported File", + recommendation: cells[recIdx] || "", + dynamicAnalysis, + processingChecks: { wiki: true, revenue: true, signalsChecked: true } + }); + } + + return { strategy, results }; + } catch (e) { + console.error("Failed to parse markdown", e); + return null; + } +};