From 844a5f5412d4a50cf068e51bc1198fa51b504870 Mon Sep 17 00:00:00 2001 From: Marc Mintel Date: Fri, 27 Feb 2026 15:17:28 +0100 Subject: [PATCH] feat: ai estimation --- apps/web/scripts/ai-estimate.ts | 65 ++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 10 deletions(-) diff --git a/apps/web/scripts/ai-estimate.ts b/apps/web/scripts/ai-estimate.ts index 810235c..29d5a55 100644 --- a/apps/web/scripts/ai-estimate.ts +++ b/apps/web/scripts/ai-estimate.ts @@ -18,10 +18,13 @@ try { if (existsSync(atMintelEnv)) { dotenvConfig({ path: atMintelEnv }); } -} catch { /* @mintel/concept-engine not resolvable — skip */ } +} catch { + /* @mintel/concept-engine not resolvable — skip */ +} async function main() { - const OPENROUTER_KEY = process.env.OPENROUTER_API_KEY || process.env.OPENROUTER_KEY; + const OPENROUTER_KEY = + process.env.OPENROUTER_API_KEY || process.env.OPENROUTER_KEY; if (!OPENROUTER_KEY) { console.error("❌ Error: OPENROUTER_API_KEY not found in environment."); process.exit(1); @@ -30,7 +33,9 @@ async function main() { const args = process.argv.slice(2); const briefingArg = args[0]; if (!briefingArg) { - console.error("❌ Error: Provide a briefing file or text as the first argument."); + console.error( + "❌ Error: Provide a briefing file or text as the first argument.", + ); process.exit(1); } @@ -66,18 +71,25 @@ async function main() { } const monorepoRoot = path.resolve(process.cwd(), "../../"); - const crawlDir = path.join(path.resolve(monorepoRoot, "../at-mintel"), "data/crawls"); + const crawlDir = path.join( + path.resolve(monorepoRoot, "../at-mintel"), + "data/crawls", + ); const outputDir = path.join(monorepoRoot, "out"); const konzeptDir = path.join(outputDir, "konzept"); const schaetzungDir = path.join(outputDir, "schaetzung"); const agbDir = path.join(outputDir, "agb"); const infoDir = path.join(outputDir, "info"); + const deckblattDir = path.join(outputDir, "deckblatt"); + const abschlussDir = path.join(outputDir, "abschluss"); await fs.mkdir(outputDir, { recursive: true }); await fs.mkdir(konzeptDir, { recursive: true }); await fs.mkdir(schaetzungDir, { recursive: true }); await fs.mkdir(agbDir, { recursive: true }); await fs.mkdir(infoDir, { recursive: true }); + await fs.mkdir(deckblattDir, { recursive: true }); + await fs.mkdir(abschlussDir, { recursive: true }); const conceptPipeline = new ConceptPipeline({ openrouterKey: OPENROUTER_KEY, @@ -100,7 +112,10 @@ async function main() { const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); console.log("\n📄 Generating Concept PDF..."); - const conceptPdfPath = path.join(konzeptDir, `${companyName}_Konzept_${timestamp}.pdf`); + const conceptPdfPath = path.join( + konzeptDir, + `${companyName}_Konzept_${timestamp}.pdf`, + ); await engine.generateConceptPdf(conceptResult, conceptPdfPath); console.log(`✅ Created Concept PDF at: ${conceptPdfPath}`); @@ -121,24 +136,54 @@ async function main() { if (estimationResult.formState) { console.log("\n📄 Generating Estimation PDF..."); - const estimationPdfPath = path.join(schaetzungDir, `${companyName}_Angebot_${timestamp}.pdf`); - await engine.generateEstimatePdf(estimationResult.formState, estimationPdfPath); + const estimationPdfPath = path.join( + schaetzungDir, + `${companyName}_Angebot_${timestamp}.pdf`, + ); + await engine.generateEstimatePdf( + estimationResult.formState, + estimationPdfPath, + ); console.log(`✅ Created Angebot PDF at: ${estimationPdfPath}`); console.log("\n📄 Generating AGBs PDF..."); - const agbPdfPath = path.join(agbDir, `${companyName}_AGBs_${timestamp}.pdf`); + const agbPdfPath = path.join( + agbDir, + `${companyName}_AGBs_${timestamp}.pdf`, + ); await engine.generateAgbsPdf(agbPdfPath, {}); console.log(`✅ Created AGBs PDF at: ${agbPdfPath}`); + + console.log("\n📄 Generating Deckblatt PDF..."); + const deckblattPdfPath = path.join( + deckblattDir, + `${companyName}_Deckblatt_${timestamp}.pdf`, + ); + await engine.generateFrontPagePdf( + estimationResult.formState, + deckblattPdfPath, + ); + console.log(`✅ Created Deckblatt PDF at: ${deckblattPdfPath}`); + + console.log("\n📄 Generating Abschluss PDF..."); + const abschlussPdfPath = path.join( + abschlussDir, + `${companyName}_Abschluss_${timestamp}.pdf`, + ); + await engine.generateClosingPdf(abschlussPdfPath, {}); + console.log(`✅ Created Abschluss PDF at: ${abschlussPdfPath}`); } else { console.log("\n⚠️ No formState generated, skipping Estimation PDF."); } // Generate Info PDF console.log("\n📄 Generating Arbeitsweise PDF..."); - const infoPdfPath = path.join(infoDir, `${companyName}_Arbeitsweise_${timestamp}.pdf`); + const infoPdfPath = path.join( + infoDir, + `${companyName}_Arbeitsweise_${timestamp}.pdf`, + ); await engine.generateInfoPdf(infoPdfPath, {}); console.log(`✅ Created Arbeitsweise PDF at: ${infoPdfPath}`); - } catch (e) { console.error(`\n❌ Pipeline failed: ${(e as Error).message}`); process.exit(1);