From 3e10bca3aceba4985610b741277e3c8fed5e9ceb Mon Sep 17 00:00:00 2001 From: Marc Mintel Date: Wed, 4 Feb 2026 18:45:21 +0100 Subject: [PATCH] refactor: Update pricing calculator item titles, consolidate visual staging and complex interaction, and revise descriptions for clarity. --- scripts/ai-estimate.ts | 97 ++++---- .../pdf/modules/BrandingModules.tsx | 34 +-- src/components/pdf/modules/CommonModules.tsx | 60 +++-- src/logic/pricing/calculator.ts | 46 ++-- .../default/SDK_CRAWLER_STATISTICS_0.json | 83 +++++-- .../default/SDK_SESSION_POOL_STATE.json | 218 ++---------------- 6 files changed, 211 insertions(+), 327 deletions(-) diff --git a/scripts/ai-estimate.ts b/scripts/ai-estimate.ts index 922efc0..e874648 100644 --- a/scripts/ai-estimate.ts +++ b/scripts/ai-estimate.ts @@ -330,7 +330,10 @@ Focus 100% on the BRIEFING text provided by the user. Use the DISTILLED_CRAWL on messages: [{ role: 'system', content: pass1SystemPrompt }, { role: 'user', content: pass1UserPrompt }], response_format: { type: 'json_object' } }, { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } }); - addUsage(p1Resp.data); + if (!p1Resp.data.choices?.[0]?.message?.content) { + console.error('❌ Pass 1 failed. Response:', JSON.stringify(p1Resp.data, null, 2)); + throw new Error('Pass 1: No content in response'); + } const facts = JSON.parse(cleanJson(p1Resp.data.choices[0].message.content)); // 2. PASS 2: Feature Deep-Dive @@ -363,6 +366,10 @@ ${JSON.stringify(facts, null, 2)} response_format: { type: 'json_object' } }, { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } }); addUsage(p2Resp.data); + if (!p2Resp.data.choices?.[0]?.message?.content) { + console.error('❌ Pass 2 failed. Response:', JSON.stringify(p2Resp.data, null, 2)); + throw new Error('Pass 2: No content in response'); + } const details = JSON.parse(cleanJson(p2Resp.data.choices[0].message.content)); // 3. PASS 3: Strategic Content (Bespoke Strategy) @@ -382,7 +389,7 @@ ${tone} - **ABSOLUTE REGEL**: Keine Halluzinationen über fehlende Präsenzen bei Relaunches. - **DATENSCHUTZ**: KEINERLEI namentliche Nennungen von Personen (z. B. "Danny Joseph") in diesen Texten. 4. **designVision**: Ein abstraktes, strategisches Konzept. - - **STIL**: Rein konzeptionell. Keine Umsetzungsschritte. Keinerlei "To-dos". Sei prägnant. + - **STIL**: Rein konzeptionell. Keine Umsetzungsschritte. Keinerlei "To-dos". Keine Ich-Form. Sei prägnant. - **FORM**: EXAKT ZWEI ABSÄTZE. Insgesamt ca. 4 Sätze. - **DATENSCHUTZ**: KEINERLEI namentliche Nennungen von Personen in diesen Texten. - **FOKUS**: Welche strategische Wirkung soll erzielt werden? (Z. B. "Industrielle Souveränität"). @@ -402,6 +409,10 @@ ${tone} response_format: { type: 'json_object' } }, { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } }); addUsage(p3Resp.data); + if (!p3Resp.data.choices?.[0]?.message?.content) { + console.error('❌ Pass 3 failed. Response:', JSON.stringify(p3Resp.data, null, 2)); + throw new Error('Pass 3: No content in response'); + } const strategy = JSON.parse(cleanJson(p3Resp.data.choices[0].message.content)); // 4. PASS 4: Information Architecture (Sitemap) @@ -431,62 +442,58 @@ ${JSON.stringify({ facts, strategy }, null, 2)} response_format: { type: 'json_object' } }, { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } }); addUsage(p4Resp.data); + if (!p4Resp.data.choices?.[0]?.message?.content) { + console.error('❌ Pass 4 failed. Response:', JSON.stringify(p4Resp.data, null, 2)); + throw new Error('Pass 4: No content in response'); + } const ia = JSON.parse(cleanJson(p4Resp.data.choices[0].message.content)); // 5. PASS 5: Position Synthesis & Pricing Transparency console.log(' ↳ Pass 5: Position Synthesis...'); const pass5SystemPrompt = ` -You are a Senior Solution Architect. Your goal is ABSOLUTE TRANSPARENCY for the customer. -Each position in the quote must be perfectly justified and detailed. +You are a Senior Solution Architect. Your goal is ABSOLUTE TRANSPARENCY and professionalism. +Each position in the quote must be perfectly justified and detailed using an objective, technical tone. -### POSITION TITLES: -"Basis Website Setup", "Individuelle Seiten", "System-Module", "Logik-Funktionen", "Visuelle Inszenierung", "Komplexe Interaktion", "Schnittstellen (API)", "Inhaltsverwaltung (CMS)", "Sorglos-Betrieb (Hosting)". +### POSITION TITLES (STRICT - MUST MATCH EXACTLY): +"1. Das technische Fundament", "2. Individuelle Seiten", "3. System-Module (Features)", "4. Logik-Funktionen", "5. Schnittstellen (API)", "6. Inhaltsverwaltung (CMS)", "7. Inszenierung & Interaktion", "8. Mehrsprachigkeit", "9. Inhaltliche Initial-Pflege", "10. Laufender Betrieb & Hosting". -### MAPPING RULES (STRICTLY BASED ON PRICING.MD): -- **Basis Website Setup**: Infrastructure, Hosting, SEO-Basics, Cookie-Consent, Staging/Production. -- **Individuelle Seiten**: Layout and structure for specific pages (e.g. Home, Services). -- **System-Module (Features)**: Closed systems with data structures (Blog, News, Products, Jobs, References). -- **Logik-Funktionen**: Pure logic (Search, Filter, Forms, PDF-Export, Multi-lang). -- **Visuelle Inszenierung**: Hero-Story, visual flows, Scroll-effects. -- **Komplexe Interaktion**: UI-experiences like Configurators or multi-step processes. -- **Schnittstellen (API)**: REAL Data Syncs (CRM, ERP, Stripe). -- **Inhaltsverwaltung (CMS)**: Setup and mapping for Headless CMS. -- **Sorglos-Betrieb (Hosting)**: Hosting, Updates, Backups. +### MAPPING RULES (STRICT): +- **1. Das technische Fundament**: Infrastructure, Hosting setup, SEO-Basics, Analytics, Environments. +- **2. Individuelle Seiten**: Layout/structure for specific pages (Home, About, etc.). +- **3. System-Module (Features)**: Functional systems like Blog, News, Products, Jobs, References. +- **4. Logik-Funktionen**: Logic modules like Search, Filter, Forms, PDF-Export. +- **5. Schnittstellen (API)**: Data Syncs with CRM, ERP, Payment systems. +- **6. Inhaltsverwaltung (CMS)**: Setup and mapping for CMS. +- **7. Inszenierung & Interaktion**: Hero-stories, visual effects, configurators. +- **8. Mehrsprachigkeit**: Architecture scaling for multiple languages. +- **9. Inhaltliche Initial-Pflege**: Manual data entry/cleanup. +- **10. Laufender Betrieb & Hosting**: Ongoing maintenance, updates, 24/7 monitoring. ### RULES FOR positionDescriptions (STRICT): -1. **NO "ICH-FORM"**: Do NOT use "Ich" or "Mein". Lead with the action or component. -2. **CONCISE & ITEM-BASED**: Use short, technical sentences. Focus on WHAT is delivered. -3. **ZERO GENERALIZATION**: Do NOT say "Verschiedene Funktionen" or "Optimierte Darstellung". Name the things. +1. **ABSOLUTE RULE: NO FIRST PERSON**: NEVER use "Ich", "Mein", "Wir" or "Unser". Lead with nouns or passive verbs. +2. **PROFESSIONAL TONE**: Use "Erstellung von...", "Anbindung der...", "Implementierung technischer...", "Bereitstellung von...". +3. **CONCISE & ITEM-BASED**: Use technical, high-density sentences. Name specific industry terms from context. 4. **ITEMIZED SYNTHESIS**: Mention EVERY component selected in Pass 1. -5. **HARD SPECIFICS**: Preserve technical details from the briefing and CURRENT WEBSITE (distilledCrawl). If they mention "HDD-Bohrtechnik" or "110kV Kabelanlagen", IT MUST BE IN THE DESCRIPTION. -6. **INDUSTRIAL AMBITION**: Describe it as a high-end technical solution, not a cheap website. -7. **SPECIFIC - PAGES**: For "Individuelle Seiten", list the pages as a comma-separated list. -8. **SPECIFIC - HOSTING**: Always append: "Inkl. 20GB Speicher." -9. **SPECIFIC - LOGIC**: Describe the ACTUAL logic. NEVER use generic terms. -10. **STRICT KEYS**: Keys MUST be EXACTLY the ones defined in POSITION TITLES. -11. **AGB BAN (CRITICAL)**: NEVER mention "Allgemeine Geschäftsbedingungen" or "AGGs" in any text. They are NOT part of this offer. +5. **HARD SPECIFICS**: If the briefing mentions "Glasfaser-Trassen" or "Schwerlast-Logistik", IT MUST BE IN THE DESCRIPTION. +6. **INDUSTRIAL AMBITION**: Describe it as a high-end technical solution. Avoid "schöne Website" or marketing fluff. +7. **PAGES**: For "2. Individuelle Seiten", list the pages (e.g., "Startseite (Hero-Video), Leistungen, Kontakt"). +8. **LOGIC**: Describe the ACTUAL logic (e.g., "Volltextsuche mit Auto-Complete", not "eine Suche"). +9. **KEYS**: Return EXACTLY the keys defined in "POSITION TITLES". +10. **NO AGB**: NEVER mention "AGB" or "Geschäftsbedingungen". -### EXAMPLES (FEW-SHOT): -- **BAD**: "Ich entwickle die Seiten: Startseite, Leistungen, Kontakt." -- **GOOD**: "Erstellung der Seiten: Startseite (Video-Hero), Über uns (Timeline), Leistungen, Kontakt." -- **BAD**: "Ich binde Google Maps an." -- **GOOD**: "Native API-Integration von Google Maps mit individueller Standort-Visualisierung." -- **BAD**: "Ich programmiere Scroll-Effekte." -- **GOOD**: "Visuelle Inszenierung der Meilensteine durch Scroll-aktivierte Timeline-Elemente." - -### POSITION RULES (STRICT): -1. **Basis Website Setup**: This position MUST ALWAYS contain exactly these 7 points: "Projekt-Setup & Infrastruktur, Hosting-Bereitstellung, Grundstruktur & Design-Vorlage, technisches SEO-Basics, Analytics (mit automatischem Mail-Report), Testing-, Staging- & Production-Umgebung, Livegang." -2. **Sorglos-Betrieb (Hosting)**: Describe the service (Hosting, SSL, Security-Updates, 24/7 Monitoring, Portfolio-Update-Service). NEVER mention "Inklusive Basis-Infrastruktur". -3. **LOGIC CONSISTENCY**: If Pass 1 extracted 1 function, you MUST describe exactly 1 function scope. If you describe two things (e.g., "Formular AND Search") but the count is 1, it is a FAIL. -4. **SIMPLICITY**: Write in "Simple German". High density of information, but easy for a CEO. No jargon. -5. **NO IMPLEMENTATION DETAILS**: Focus on WHAT is done, not HOW (no libraries, no technical "under-the-hood" talk). +### EXAMPLES (PASSIVE & TECHNICAL): +- **GOOD**: "Konfiguration der CMS-Infrastruktur zur unabhängigen Verwaltung von Produkt-Katalogen und News-Beiträgen." +- **GOOD**: "Implementierung einer Volltextsuche inkl. Kategorisierungs-Logik für effizientes Auffinden von Projektreferenzen." +- **GOOD**: "Native API-Anbindung an das ERP-System zur Echtzeit-Synchronisation von Bestandsdaten." +- **BAD**: "Ich richte dir das CMS ein." +- **BAD**: "Ich programmiere eine tolle Suche für deine Seite." ### DATA CONTEXT: ${JSON.stringify({ facts, details, strategy, ia }, null, 2)} ### OUTPUT FORMAT (Strict JSON): { - "positionDescriptions": { "Basis Website Setup": string, ... } + "positionDescriptions": { "1. Das technische Fundament": string, ... } } `; const p5Resp = await axios.post('https://openrouter.ai/api/v1/chat/completions', { @@ -495,6 +502,10 @@ ${JSON.stringify({ facts, details, strategy, ia }, null, 2)} response_format: { type: 'json_object' } }, { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } }); addUsage(p5Resp.data); + if (!p5Resp.data.choices?.[0]?.message?.content) { + console.error('❌ Pass 5 failed. Response:', JSON.stringify(p5Resp.data, null, 2)); + throw new Error('Pass 5: No content in response'); + } const positionsData = JSON.parse(cleanJson(p5Resp.data.choices[0].message.content)); // 6. PASS 6: The Industrial Critic @@ -526,6 +537,10 @@ ${JSON.stringify({ facts, strategy, ia, positionsData }, null, 2)} response_format: { type: 'json_object' } }, { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } }); addUsage(p6Resp.data); + if (!p6Resp.data.choices?.[0]?.message?.content) { + console.error('❌ Pass 6 failed. Response:', JSON.stringify(p6Resp.data, null, 2)); + throw new Error('Pass 6: No content in response'); + } const reflection = JSON.parse(cleanJson(p6Resp.data.choices[0].message.content)); // 6. Reflection Merge Utility diff --git a/src/components/pdf/modules/BrandingModules.tsx b/src/components/pdf/modules/BrandingModules.tsx index 50a4b4d..6402c23 100644 --- a/src/components/pdf/modules/BrandingModules.tsx +++ b/src/components/pdf/modules/BrandingModules.tsx @@ -22,41 +22,41 @@ const styles = StyleSheet.create({ export const AboutModule = () => ( <> - Über mich - Senior Software Developer & Technischer Partner + Expertise & Profil + Entwicklung & Technischer Partner für den Mittelstand - Ich begleite mittelständische Unternehmen und Agenturen bei der Realisierung anspruchsvoller Web-Projekte. Als Senior Software Developer mit über 15 Jahren Erfahrung biete ich das gesamte technische Spektrum – von der Architektur bis zum fertigen Produkt. + Begleitung mittelständischer Unternehmen und Agenturen bei der Realisierung anspruchsvoller Web-Projekte. Als Senior Software Developer mit über 15 Jahren Erfahrung wird das gesamte technische Spektrum abgedeckt – von der Architektur bis zum fertigen Produkt. Erfahrung & Substanz - Mein Weg führte mich durch alle Ebenen der Webentwicklung: vom Junior zum Teamleiter, von der kleinen Kreativagentur bis zur Softwareentwicklung für internationale Konzerne. + Der Werdegang umfasst alle Ebenen der Webentwicklung: von der Teamleitung in Kreativagenturen bis zur Softwareentwicklung für internationale Konzerne. - Ich kenne die Prozesse hinter großen Systemen ebenso gut wie die Agilität, die im Mittelstand gefordert wird. Dieses Wissen nutze ich heute, um Lösungen zu bauen, die technologisch auf Augenhöhe mit den Großen sind, aber ohne deren bürokratischen Overhead auskommen. + Die Kenntnis komplexer Enterprise-Systeme wird mit der Agilität kombiniert, die im Mittelstand gefordert ist. Dieses Wissen ermöglicht den Bau von Lösungen, die technologisch auf Augenhöhe mit Konzern-Standards sind, jedoch ohne unnötigen bürokratischen Overhead auskommen. Fokus Einzelentwicklung - Ich arbeite bewusst als Einzelentwickler. Für Sie bedeutet das: maximale Geschwindigkeit und volle Verantwortung. Es gibt keine Informationsverluste zwischen Projektmanagern, Vertrieblern und Entwicklern. + Die Umsetzung erfolgt bewusst als spezialisierter Einzelentwickler. Dies garantiert maximale Geschwindigkeit, direkte Kommunikationswege und volle technologische Verantwortung. - Sie haben einen direkten technischen Sparringspartner, der Ihren Code von der ersten bis zur letzten Zeile kennt und dafür einsteht. Diese Unmittelbarkeit garantiert Ergebnisse, die technisch sauber und wirtschaftlich sinnvoll sind. + Als direkter technischer Sparringspartner bleibt die Codebasis von der ersten bis zur letzten Zeile transparent und wartbar. Diese Unmittelbarkeit stellt sicher, dass Ergebnisse sowohl technisch sauber als auch wirtschaftlich sinnvoll realisiert werden. - Meine Zusage + Qualitäts-Zusage - Ich baue keine Prototypen, die beim ersten Nutzeransturm zusammenbrechen. Ich liefere produktionsreife Software, die wartbar bleibt und mit Ihrem Unternehmen mitwächst. Direkt. Sauber. Ohne Ballast. + Es werden keine instabilen Prototypen geliefert, sondern produktionsreife Software, die skalierbar bleibt und mit dem Unternehmen wächst. Direkt. Sauber. Ohne Ballast. @@ -77,11 +77,11 @@ export const CrossSellModule = ({ state }: any) => { {isWebsite ? ( <> - Manuelle Alltags-Aufgaben sind teuer und fehleranfällig. In einer separaten Beauftragung entwickle ich maßgeschneiderte „Helfer“, die Ihre Routine-Prozesse lautlos im Hintergrund automatisieren. - Keine Abos. Keine komplexen neuen Systeme. Nur gezielte Zeitersparnis. + Manuelle Alltags-Aufgaben sind teuer und fehleranfällig. In einer separaten Beauftragung können maßgeschneiderte Systeme entwickelt werden, die Routine-Prozesse automatisiert im Hintergrund verarbeiten. + Keine Abos. Keine komplexen neuen Systeme. Gezielte Zeitersparnis. - Individuelle Prüfung - Ich analysiere Ihren spezifischen Prozess auf technisches Automatisierungspotenzial. Das Ergebnis liefert Klarheit darüber, ob eine Umsetzung wirtschaftlich sinnvoll ist. + Individuelle Analyse + Spezifische Prozesse werden auf technisches Automatisierungspotenzial untersucht. Das Ergebnis liefert Klarheit über die wirtschaftliche Sinnhaftigkeit einer Umsetzung. @@ -89,17 +89,17 @@ export const CrossSellModule = ({ state }: any) => { Erstellung von PDF-Angeboten, Berichten oder Protokollen in Sekunden statt Stunden. - Intelligente Tabellen und automatisierte Auswertungen Ihrer Bestandsdaten. + Intelligente Tabellen und automatisierte Auswertungen bestehender Datensätze. - Effizientes Einlesen und Verarbeiten von analogen Dokumenten oder handschriftlichen Notizen. + Effiziente Verarbeitung von analogen Dokumenten oder handschriftlichen Notizen mittels KI. ) : ( - Ich baue die technische Basis für Ihr Unternehmen. Ich meide Baukästen und Agentur-Abhängigkeiten. - Ich entwickle performante Frontends und stabile Backends. Ich liefere Code, den Sie besitzen und selbst kontrollieren. + Bereitstellung einer stabilen technischen Basis ohne Abhängigkeiten von Baukasten-Systemen oder Agenturen. + Entwicklung performanter Frontends und skalierbarer Backends. Die Auslieferung erfolgt als kontrollierbarer und nachhaltiger Quellcode. )} diff --git a/src/components/pdf/modules/CommonModules.tsx b/src/components/pdf/modules/CommonModules.tsx index f7399ad..e97d7ab 100644 --- a/src/components/pdf/modules/CommonModules.tsx +++ b/src/components/pdf/modules/CommonModules.tsx @@ -14,14 +14,11 @@ const styles = StyleSheet.create({ configLabel: { fontSize: FONT_SIZES.BLUEPRINT, color: COLORS.TEXT_LIGHT, textTransform: 'uppercase', marginBottom: 8 }, }); -const CHROME_ICON = '/Users/marcmintel/Projects/mintel.me/src/assets/browser/chrome.png'; // Fallback to a placeholder if not found -const SAFARI_ICON = '/Users/marcmintel/Projects/mintel.me/src/assets/browser/safari.png'; - export const techPageModule = ({ techDetails, headerIcon }: any) => ( <> - Ich entwickle Websites als moderne, performante Websysteme. + Entwicklung von Websites als moderne, performante Websysteme nach industriellen Standards. {techDetails?.map((item: any, i: number) => ( @@ -39,45 +36,60 @@ export const TransparenzModule = ({ pricing }: any) => ( Festpreise statt Stundenabrechnung - Ich biete Planungssicherheit. Ich kalkuliere nach einem modularen Festpreis-System. Sie zahlen für Ergebnisse, nicht für die Zeit. Ich schließe versteckte Kosten aus. + Maximale Planungssicherheit durch ein modulares Festpreis-System. Die Abrechnung erfolgt nach Ergebnissen statt nach reinem Zeitaufwand. Versteckte Kosten sind durch die modulare Struktur ausgeschlossen. - 1. Das Fundament - Ich richte die technische Infrastruktur ein. Ich installiere das Hosting, schaffe SEO-Basics und erstelle die Test-, Staging- und Live-Umgebungen. + 1. Das technische Fundament + Einrichtung der technischen Infrastruktur, Hosting-Bereitstellung, SEO-Basics sowie Bereitstellung von Test-, Staging- und produktiven Live-Umgebungen. {pricing.BASE_WEBSITE?.toLocaleString('de-DE')} € - 2. Seiten - Ich entwickle das individuelle Layout und die Struktur jeder Seite. Ich garantiere die korrekte Darstellung auf allen Endgeräten. + 2. Individuelle Seiten + Entwicklung individueller Layouts und Strukturen pro Seite. Optimierung für alle Endgeräte (Responsive Design) und Browser-Kompatibilität. {pricing.PAGE?.toLocaleString('de-DE')} € / Stk - 3. Features - Ich erstelle abgeschlossene technische Systeme (z. B. Blog oder News). Ich definiere die Datenfelder und die Pflege-Oberflächen. + 3. System-Module (Features) + Implementierung abgeschlossener technischer Systeme (z. B. Blog, News, Produkte). Definition notwendiger Datenfelder und Pflege-Oberflächen. {pricing.FEATURE?.toLocaleString('de-DE')} € / Stk - 4. Funktionen - Ich programmiere Logik-Module wie Filter, Suchen oder Kontakt-Schnittstellen. Ich sorge für die fehlerfreie Verarbeitung Ihrer Daten. + 4. Logik-Funktionen + Programmierung technischer Logik-Einheiten wie Filter, Suchen oder Kontakt-Schnittstellen zur fehlerfreien Datenverarbeitung. {pricing.FUNCTION?.toLocaleString('de-DE')} € / Stk - 5. Interaktion - Ich entwerfe komplexe UI-Abläufe und Konfiguratoren. Ich optimiere die Nutzerführung für maximale Abschlüsse. - {pricing.COMPLEX_INTERACTION?.toLocaleString('de-DE')} € / Stk - - - 6. Integrationen - Ich binde Drittsysteme wie CRM, ERP oder Stripe an. Ich richte CMS-Schnittstellen zur unabhängigen Inhaltsverwaltung ein. + 5. Schnittstellen (API) + Anbindung externer Drittsysteme (CRM, ERP, Payment-Provider) zur automatisierten Datensynchronisation und Prozessoptimierung. ab {pricing.API_INTEGRATION?.toLocaleString('de-DE')} € / Stk - 7. Betrieb (12 Monate) - Ich betreibe das Hosting, pflege Sicherheitsupdates ein und erstelle monatliche Berichte. Ich garantiere die Verfügbarkeit für ein Jahr. - 1.440 € + 6. Inhaltsverwaltung (CMS) + Bereitstellung und Konfiguration eines Content Management Systems (CMS) inkl. technischer Anbindung aller Module zur unabhängigen Datenpflege. + {pricing.CMS_SETUP?.toLocaleString('de-DE')} € + + + 7. Inszenierung & Interaktion + Umsetzung komplexer Interaktions-Mechanismen, Konfiguratoren oder aufwendiger visueller Storytelling-Elemente zur Steigerung der Conversion. + ab {pricing.VISUAL_STAGING?.toLocaleString('de-DE')} € + + + 8. Mehrsprachigkeit + Skalierung der System-Architektur auf zusätzliche Sprachen. Inklusive struktureller Anpassungen und Logik für Sprachumschaltung. + +20% / Sprache + + + 9. Inhaltliche Initial-Pflege + Manuelle Übernahme und Aufbereitung von Datensätzen in das Zielsystem zur Sicherstellung einer initialen Inhaltsabdeckung. + {pricing.NEW_DATASET?.toLocaleString('de-DE')} € / Stk + + + 10. Laufender Betrieb & Hosting + Laufender Betrieb, Hosting, Sicherheits-Updates sowie monatliche Backups und Monitoring zur Sicherstellung der Systemverfügbarkeit. + {pricing.HOSTING_MONTHLY?.toLocaleString('de-DE')} € / Monat @@ -86,7 +98,7 @@ export const TransparenzModule = ({ pricing }: any) => ( export const PrinciplesModule = ({ principles }: any) => ( <> - + {principles?.map((item: any, i: number) => ( diff --git a/src/logic/pricing/calculator.ts b/src/logic/pricing/calculator.ts index 046aec1..7e69c46 100644 --- a/src/logic/pricing/calculator.ts +++ b/src/logic/pricing/calculator.ts @@ -69,7 +69,7 @@ export function calculatePositions(state: FormState, pricing: any): Position[] { if (state.projectType === 'website') { positions.push({ pos: pos++, - title: 'Basis Website Setup', + title: '1. Das technische Fundament', desc: 'Projekt-Setup, Infrastruktur, Hosting-Bereitstellung, Grundstruktur & Design-Vorlage, technisches SEO-Basics, Analytics.', qty: 1, price: pricing.BASE_WEBSITE @@ -92,7 +92,7 @@ export function calculatePositions(state: FormState, pricing: any): Position[] { positions.push({ pos: pos++, - title: 'Individuelle Seiten', + title: '2. Individuelle Seiten', desc: `Gestaltung und Umsetzung von ${totalPagesCount} individuellen Seiten-Layouts (${uniquePages.join(', ')}).`, qty: totalPagesCount, price: totalPagesCount * pricing.PAGE @@ -102,7 +102,7 @@ export function calculatePositions(state: FormState, pricing: any): Position[] { const allFeatures = [...state.features.map((f: string) => FEATURE_LABELS[f] || f), ...(state.otherFeatures || [])]; positions.push({ pos: pos++, - title: 'System-Module', + title: '3. System-Module (Features)', desc: `Implementierung funktionaler Bereiche: ${allFeatures.join(', ')}. Inklusive Datenstruktur und Darstellung.`, qty: allFeatures.length, price: allFeatures.length * pricing.FEATURE @@ -113,7 +113,7 @@ export function calculatePositions(state: FormState, pricing: any): Position[] { const allFunctions = [...state.functions.map((f: string) => FUNCTION_LABELS[f] || f), ...(state.otherFunctions || [])]; positions.push({ pos: pos++, - title: 'Logik-Funktionen', + title: '4. Logik-Funktionen', desc: `Implementierung technischer Logik: ${allFunctions.join(', ')}.`, qty: allFunctions.length, price: allFunctions.length * pricing.FUNCTION @@ -124,7 +124,7 @@ export function calculatePositions(state: FormState, pricing: any): Position[] { const allApis = [...state.apiSystems.map((a: string) => API_LABELS[a] || a), ...(state.otherTech || [])]; positions.push({ pos: pos++, - title: 'Schnittstellen (API)', + title: '5. Schnittstellen (API)', desc: `Anbindung externer Systeme zur Datensynchronisation: ${allApis.join(', ')}.`, qty: allApis.length, price: allApis.length * pricing.API_INTEGRATION @@ -135,7 +135,7 @@ export function calculatePositions(state: FormState, pricing: any): Position[] { const totalFeatures = state.features.length + (state.otherFeatures?.length || 0) + (state.otherFeaturesCount || 0); positions.push({ pos: pos++, - title: 'Inhaltsverwaltung (CMS)', + title: '6. Inhaltsverwaltung (CMS)', desc: 'Einrichtung eines Systems zur eigenständigen Pflege von Inhalten und Datensätzen.', qty: 1, price: pricing.CMS_SETUP + totalFeatures * pricing.CMS_CONNECTION_PER_FEATURE @@ -145,32 +145,24 @@ export function calculatePositions(state: FormState, pricing: any): Position[] { if (state.newDatasets > 0) { positions.push({ pos: pos++, - title: 'Inhaltspflege (Initial)', - desc: `Manuelle Einpflege von ${state.newDatasets} Datensätzen (z.B. Produkte, Blogartikel).`, + title: '9. Inhaltliche Initial-Pflege', + desc: `Manuelle Übernahme und Aufbereitung von ${state.newDatasets} Datensätzen (Produkte, Artikel) in das Zielsystem.`, qty: state.newDatasets, price: state.newDatasets * pricing.NEW_DATASET }); } - if (state.visualStaging && Number(state.visualStaging) > 0) { - const count = Number(state.visualStaging); - positions.push({ - pos: pos++, - title: 'Visuelle Inszenierung', - desc: `Umsetzung von ${count} Hero-Stories, Scroll-Effekten oder speziell inszenierten Sektionen.`, - qty: count, - price: count * pricing.VISUAL_STAGING - }); - } + if ((state.visualStaging && Number(state.visualStaging) > 0) || (state.complexInteractions && Number(state.complexInteractions) > 0)) { + const vsCount = Number(state.visualStaging || 0); + const ciCount = Number(state.complexInteractions || 0); + const totalCount = vsCount + ciCount; - if (state.complexInteractions && Number(state.complexInteractions) > 0) { - const count = Number(state.complexInteractions); positions.push({ pos: pos++, - title: 'Komplexe Interaktion', - desc: `Umsetzung von ${count} Konfiguratoren, Live-Previews oder mehrstufigen Auswahlprozessen.`, - qty: count, - price: count * pricing.COMPLEX_INTERACTION + title: '7. Inszenierung & Interaktion', + desc: `Umsetzung von ${totalCount} speziellen Sektionen, Hero-Stories oder Konfiguratoren zur Steigerung der Conversion.`, + qty: totalCount, + price: (vsCount * pricing.VISUAL_STAGING) + (ciCount * pricing.COMPLEX_INTERACTION) }); } @@ -181,7 +173,7 @@ export function calculatePositions(state: FormState, pricing: any): Position[] { positions.push({ pos: pos++, - title: 'Mehrsprachigkeit', + title: '8. Mehrsprachigkeit', desc: `Erweiterung des Systems auf ${languagesCount} Sprachen (Struktur & Logik).`, qty: languagesCount, price: Math.round(factorPrice) @@ -191,8 +183,8 @@ export function calculatePositions(state: FormState, pricing: any): Position[] { const monthlyRate = pricing.HOSTING_MONTHLY + (state.storageExpansion * pricing.STORAGE_EXPANSION_MONTHLY); positions.push({ pos: pos++, - title: 'Betriebs- und Pflegeleistung (12 Monate)', - desc: `Bereitstellung der Infrastruktur, technische Instandhaltung, Sicherheits-Updates und Backup-Management gemäß AGB Punkt 7a. Inklusive ${state.storageExpansion > 0 ? state.storageExpansion + ' GB Speicher-Erweiterung' : 'Basis-Infrastruktur'}.`, + title: '10. Laufender Betrieb & Hosting', + desc: `Bereitstellung der Infrastruktur, technische Instandhaltung, Sicherheits-Updates und Backup-Management gemäß AGB Punkt 7a. Inklusive 12 Monate Service.`, qty: 1, price: monthlyRate * 12 }); diff --git a/storage/key_value_stores/default/SDK_CRAWLER_STATISTICS_0.json b/storage/key_value_stores/default/SDK_CRAWLER_STATISTICS_0.json index a40d2ab..74f9e30 100644 --- a/storage/key_value_stores/default/SDK_CRAWLER_STATISTICS_0.json +++ b/storage/key_value_stores/default/SDK_CRAWLER_STATISTICS_0.json @@ -1,27 +1,68 @@ { - "requestsFinished": 8, - "requestsFailed": 0, - "requestsRetries": 0, - "requestsFailedPerMinute": 0, - "requestsFinishedPerMinute": 158, - "requestMinDurationMillis": 610, - "requestMaxDurationMillis": 2310, - "requestTotalFailedDurationMillis": 0, - "requestTotalFinishedDurationMillis": 12652, - "crawlerStartedAt": "2026-02-03T18:57:19.097Z", - "crawlerFinishedAt": "2026-02-03T18:57:22.128Z", - "statsPersistedAt": "2026-02-03T18:57:22.128Z", - "crawlerRuntimeMillis": 3044, - "crawlerLastStartTimestamp": 1770145039084, + "requestsFinished": 0, + "requestsFailed": 1, + "requestsRetries": 1, + "requestsFailedPerMinute": 279, + "requestsFinishedPerMinute": 0, + "requestMinDurationMillis": null, + "requestMaxDurationMillis": 0, + "requestTotalFailedDurationMillis": 2, + "requestTotalFinishedDurationMillis": 0, + "crawlerStartedAt": "2026-02-04T17:39:09.193Z", + "crawlerFinishedAt": "2026-02-04T17:39:09.396Z", + "statsPersistedAt": "2026-02-04T17:39:09.396Z", + "crawlerRuntimeMillis": 215, + "crawlerLastStartTimestamp": 1770226749181, "requestRetryHistogram": [ - 8 + null, + null, + null, + 1 ], "statsId": 0, - "requestAvgFailedDurationMillis": null, - "requestAvgFinishedDurationMillis": 1582, - "requestTotalDurationMillis": 12652, - "requestsTotal": 8, + "requestAvgFailedDurationMillis": 2, + "requestAvgFinishedDurationMillis": null, + "requestTotalDurationMillis": 2, + "requestsTotal": 1, "requestsWithStatusCode": {}, - "errors": {}, - "retryErrors": {} + "errors": { + "file:///Users/marcmintel/Projects/mintel.me/node_modules/got/dist/source/core/index.js:198:21": { + "ENOTFOUND": { + "RequestError": { + "getaddrinfo ENOTFOUND etib-et.com": { + "count": 1 + } + } + } + }, + "node:dns:120:26": { + "ENOTFOUND": { + "Error": { + "getaddrinfo ENOTFOUND etib-et.com": { + "count": 1 + } + } + } + } + }, + "retryErrors": { + "file:///Users/marcmintel/Projects/mintel.me/node_modules/got/dist/source/core/index.js:198:21": { + "ENOTFOUND": { + "RequestError": { + "getaddrinfo ENOTFOUND etib-et.com": { + "count": 3 + } + } + } + }, + "node:dns:120:26": { + "ENOTFOUND": { + "Error": { + "getaddrinfo ENOTFOUND etib-et.com": { + "count": 3 + } + } + } + } + } } \ No newline at end of file diff --git a/storage/key_value_stores/default/SDK_SESSION_POOL_STATE.json b/storage/key_value_stores/default/SDK_SESSION_POOL_STATE.json index fd55904..cdeff86 100644 --- a/storage/key_value_stores/default/SDK_SESSION_POOL_STATE.json +++ b/storage/key_value_stores/default/SDK_SESSION_POOL_STATE.json @@ -1,9 +1,9 @@ { - "usableSessionsCount": 8, + "usableSessionsCount": 4, "retiredSessionsCount": 0, "sessions": [ { - "id": "session_4ERnLfhRfe", + "id": "session_qS9LzMPYLU", "cookieJar": { "version": "tough-cookie@6.0.0", "storeType": "MemoryCookieStore", @@ -11,31 +11,19 @@ "enableLooseMode": false, "allowSpecialUseDomain": true, "prefixSecurity": "silent", - "cookies": [ - { - "key": "8a164f127e89bfa6ad5b54e0547581b9", - "value": "7faeptahkgpngts9h84iishemk", - "domain": "www.schleicher-gruppe.de", - "path": "/", - "secure": true, - "httpOnly": true, - "hostOnly": true, - "creation": "2026-02-03T18:57:19.776Z", - "lastAccessed": "2026-02-03T18:57:19.776Z" - } - ] + "cookies": [] }, "userData": {}, "maxErrorScore": 3, "errorScoreDecrement": 0.5, - "expiresAt": "2026-02-03T19:47:19.140Z", - "createdAt": "2026-02-03T18:57:19.140Z", + "expiresAt": "2026-02-04T18:29:09.266Z", + "createdAt": "2026-02-04T17:39:09.266Z", "usageCount": 1, "maxUsageCount": 50, - "errorScore": 0 + "errorScore": 1 }, { - "id": "session_b0TzOu99YB", + "id": "session_rQXoQ3YoSI", "cookieJar": { "version": "tough-cookie@6.0.0", "storeType": "MemoryCookieStore", @@ -43,31 +31,19 @@ "enableLooseMode": false, "allowSpecialUseDomain": true, "prefixSecurity": "silent", - "cookies": [ - { - "key": "8a164f127e89bfa6ad5b54e0547581b9", - "value": "dis65ncl0oggk09keriqi85sc3", - "domain": "www.schleicher-gruppe.de", - "path": "/", - "secure": true, - "httpOnly": true, - "hostOnly": true, - "creation": "2026-02-03T18:57:20.400Z", - "lastAccessed": "2026-02-03T18:57:20.400Z" - } - ] + "cookies": [] }, "userData": {}, "maxErrorScore": 3, "errorScoreDecrement": 0.5, - "expiresAt": "2026-02-03T19:47:19.796Z", - "createdAt": "2026-02-03T18:57:19.796Z", + "expiresAt": "2026-02-04T18:29:09.369Z", + "createdAt": "2026-02-04T17:39:09.369Z", "usageCount": 1, "maxUsageCount": 50, - "errorScore": 0 + "errorScore": 1 }, { - "id": "session_FQDoGeShzw", + "id": "session_VQKYMg9QOd", "cookieJar": { "version": "tough-cookie@6.0.0", "storeType": "MemoryCookieStore", @@ -75,31 +51,19 @@ "enableLooseMode": false, "allowSpecialUseDomain": true, "prefixSecurity": "silent", - "cookies": [ - { - "key": "8a164f127e89bfa6ad5b54e0547581b9", - "value": "aa5n3vgkgl8tg6dbn5vimrkr60", - "domain": "www.schleicher-gruppe.de", - "path": "/", - "secure": true, - "httpOnly": true, - "hostOnly": true, - "creation": "2026-02-03T18:57:21.228Z", - "lastAccessed": "2026-02-03T18:57:21.228Z" - } - ] + "cookies": [] }, "userData": {}, "maxErrorScore": 3, "errorScoreDecrement": 0.5, - "expiresAt": "2026-02-03T19:47:19.798Z", - "createdAt": "2026-02-03T18:57:19.798Z", + "expiresAt": "2026-02-04T18:29:09.376Z", + "createdAt": "2026-02-04T17:39:09.376Z", "usageCount": 1, "maxUsageCount": 50, - "errorScore": 0 + "errorScore": 1 }, { - "id": "session_7qPl1RuIhU", + "id": "session_Jf7MUM5INz", "cookieJar": { "version": "tough-cookie@6.0.0", "storeType": "MemoryCookieStore", @@ -107,156 +71,16 @@ "enableLooseMode": false, "allowSpecialUseDomain": true, "prefixSecurity": "silent", - "cookies": [ - { - "key": "8a164f127e89bfa6ad5b54e0547581b9", - "value": "h98q2ebuq62iuei16vj2gr27p9", - "domain": "www.schleicher-gruppe.de", - "path": "/", - "secure": true, - "httpOnly": true, - "hostOnly": true, - "creation": "2026-02-03T18:57:21.562Z", - "lastAccessed": "2026-02-03T18:57:21.562Z" - } - ] + "cookies": [] }, "userData": {}, "maxErrorScore": 3, "errorScoreDecrement": 0.5, - "expiresAt": "2026-02-03T19:47:19.799Z", - "createdAt": "2026-02-03T18:57:19.799Z", + "expiresAt": "2026-02-04T18:29:09.380Z", + "createdAt": "2026-02-04T17:39:09.380Z", "usageCount": 1, "maxUsageCount": 50, - "errorScore": 0 - }, - { - "id": "session_nT83yclMaD", - "cookieJar": { - "version": "tough-cookie@6.0.0", - "storeType": "MemoryCookieStore", - "rejectPublicSuffixes": true, - "enableLooseMode": false, - "allowSpecialUseDomain": true, - "prefixSecurity": "silent", - "cookies": [ - { - "key": "8a164f127e89bfa6ad5b54e0547581b9", - "value": "64s6fh151m5i2vqe61qpe4slpq", - "domain": "www.schleicher-gruppe.de", - "path": "/", - "secure": true, - "httpOnly": true, - "hostOnly": true, - "creation": "2026-02-03T18:57:21.682Z", - "lastAccessed": "2026-02-03T18:57:21.682Z" - } - ] - }, - "userData": {}, - "maxErrorScore": 3, - "errorScoreDecrement": 0.5, - "expiresAt": "2026-02-03T19:47:19.800Z", - "createdAt": "2026-02-03T18:57:19.800Z", - "usageCount": 1, - "maxUsageCount": 50, - "errorScore": 0 - }, - { - "id": "session_U8c4xgDdgZ", - "cookieJar": { - "version": "tough-cookie@6.0.0", - "storeType": "MemoryCookieStore", - "rejectPublicSuffixes": true, - "enableLooseMode": false, - "allowSpecialUseDomain": true, - "prefixSecurity": "silent", - "cookies": [ - { - "key": "8a164f127e89bfa6ad5b54e0547581b9", - "value": "fmep2i6s7s8hvdakvkv6gsfpqb", - "domain": "www.schleicher-gruppe.de", - "path": "/", - "secure": true, - "httpOnly": true, - "hostOnly": true, - "creation": "2026-02-03T18:57:21.862Z", - "lastAccessed": "2026-02-03T18:57:21.862Z" - } - ] - }, - "userData": {}, - "maxErrorScore": 3, - "errorScoreDecrement": 0.5, - "expiresAt": "2026-02-03T19:47:19.801Z", - "createdAt": "2026-02-03T18:57:19.801Z", - "usageCount": 1, - "maxUsageCount": 50, - "errorScore": 0 - }, - { - "id": "session_brbza8jFOb", - "cookieJar": { - "version": "tough-cookie@6.0.0", - "storeType": "MemoryCookieStore", - "rejectPublicSuffixes": true, - "enableLooseMode": false, - "allowSpecialUseDomain": true, - "prefixSecurity": "silent", - "cookies": [ - { - "key": "8a164f127e89bfa6ad5b54e0547581b9", - "value": "7klasgpre1eajidc52coun8cg4", - "domain": "www.schleicher-gruppe.de", - "path": "/", - "secure": true, - "httpOnly": true, - "hostOnly": true, - "creation": "2026-02-03T18:57:22.108Z", - "lastAccessed": "2026-02-03T18:57:22.108Z" - } - ] - }, - "userData": {}, - "maxErrorScore": 3, - "errorScoreDecrement": 0.5, - "expiresAt": "2026-02-03T19:47:19.802Z", - "createdAt": "2026-02-03T18:57:19.802Z", - "usageCount": 1, - "maxUsageCount": 50, - "errorScore": 0 - }, - { - "id": "session_J02AHwBimj", - "cookieJar": { - "version": "tough-cookie@6.0.0", - "storeType": "MemoryCookieStore", - "rejectPublicSuffixes": true, - "enableLooseMode": false, - "allowSpecialUseDomain": true, - "prefixSecurity": "silent", - "cookies": [ - { - "key": "8a164f127e89bfa6ad5b54e0547581b9", - "value": "24drbvceqmebqusaqpv78ge3mv", - "domain": "www.schleicher-gruppe.de", - "path": "/", - "secure": true, - "httpOnly": true, - "hostOnly": true, - "creation": "2026-02-03T18:57:21.727Z", - "lastAccessed": "2026-02-03T18:57:21.727Z" - } - ] - }, - "userData": {}, - "maxErrorScore": 3, - "errorScoreDecrement": 0.5, - "expiresAt": "2026-02-03T19:47:19.806Z", - "createdAt": "2026-02-03T18:57:19.806Z", - "usageCount": 1, - "maxUsageCount": 50, - "errorScore": 0 + "errorScore": 1 } ] } \ No newline at end of file