refactor: Update pricing calculator item titles, consolidate visual staging and complex interaction, and revise descriptions for clarity.
Some checks failed
Build & Deploy Mintel Blog / build-and-deploy (push) Failing after 32s

This commit is contained in:
2026-02-04 18:45:21 +01:00
parent 39006c16b1
commit 3e10bca3ac
6 changed files with 211 additions and 327 deletions

View File

@@ -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 }], messages: [{ role: 'system', content: pass1SystemPrompt }, { role: 'user', content: pass1UserPrompt }],
response_format: { type: 'json_object' } response_format: { type: 'json_object' }
}, { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } }); }, { 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)); const facts = JSON.parse(cleanJson(p1Resp.data.choices[0].message.content));
// 2. PASS 2: Feature Deep-Dive // 2. PASS 2: Feature Deep-Dive
@@ -363,6 +366,10 @@ ${JSON.stringify(facts, null, 2)}
response_format: { type: 'json_object' } response_format: { type: 'json_object' }
}, { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } }); }, { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } });
addUsage(p2Resp.data); 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)); const details = JSON.parse(cleanJson(p2Resp.data.choices[0].message.content));
// 3. PASS 3: Strategic Content (Bespoke Strategy) // 3. PASS 3: Strategic Content (Bespoke Strategy)
@@ -382,7 +389,7 @@ ${tone}
- **ABSOLUTE REGEL**: Keine Halluzinationen über fehlende Präsenzen bei Relaunches. - **ABSOLUTE REGEL**: Keine Halluzinationen über fehlende Präsenzen bei Relaunches.
- **DATENSCHUTZ**: KEINERLEI namentliche Nennungen von Personen (z. B. "Danny Joseph") in diesen Texten. - **DATENSCHUTZ**: KEINERLEI namentliche Nennungen von Personen (z. B. "Danny Joseph") in diesen Texten.
4. **designVision**: Ein abstraktes, strategisches Konzept. 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. - **FORM**: EXAKT ZWEI ABSÄTZE. Insgesamt ca. 4 Sätze.
- **DATENSCHUTZ**: KEINERLEI namentliche Nennungen von Personen in diesen Texten. - **DATENSCHUTZ**: KEINERLEI namentliche Nennungen von Personen in diesen Texten.
- **FOKUS**: Welche strategische Wirkung soll erzielt werden? (Z. B. "Industrielle Souveränität"). - **FOKUS**: Welche strategische Wirkung soll erzielt werden? (Z. B. "Industrielle Souveränität").
@@ -402,6 +409,10 @@ ${tone}
response_format: { type: 'json_object' } response_format: { type: 'json_object' }
}, { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } }); }, { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } });
addUsage(p3Resp.data); 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)); const strategy = JSON.parse(cleanJson(p3Resp.data.choices[0].message.content));
// 4. PASS 4: Information Architecture (Sitemap) // 4. PASS 4: Information Architecture (Sitemap)
@@ -431,62 +442,58 @@ ${JSON.stringify({ facts, strategy }, null, 2)}
response_format: { type: 'json_object' } response_format: { type: 'json_object' }
}, { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } }); }, { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } });
addUsage(p4Resp.data); 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)); const ia = JSON.parse(cleanJson(p4Resp.data.choices[0].message.content));
// 5. PASS 5: Position Synthesis & Pricing Transparency // 5. PASS 5: Position Synthesis & Pricing Transparency
console.log(' ↳ Pass 5: Position Synthesis...'); console.log(' ↳ Pass 5: Position Synthesis...');
const pass5SystemPrompt = ` const pass5SystemPrompt = `
You are a Senior Solution Architect. Your goal is ABSOLUTE TRANSPARENCY for the customer. You are a Senior Solution Architect. Your goal is ABSOLUTE TRANSPARENCY and professionalism.
Each position in the quote must be perfectly justified and detailed. Each position in the quote must be perfectly justified and detailed using an objective, technical tone.
### POSITION TITLES: ### POSITION TITLES (STRICT - MUST MATCH EXACTLY):
"Basis Website Setup", "Individuelle Seiten", "System-Module", "Logik-Funktionen", "Visuelle Inszenierung", "Komplexe Interaktion", "Schnittstellen (API)", "Inhaltsverwaltung (CMS)", "Sorglos-Betrieb (Hosting)". "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): ### MAPPING RULES (STRICT):
- **Basis Website Setup**: Infrastructure, Hosting, SEO-Basics, Cookie-Consent, Staging/Production. - **1. Das technische Fundament**: Infrastructure, Hosting setup, SEO-Basics, Analytics, Environments.
- **Individuelle Seiten**: Layout and structure for specific pages (e.g. Home, Services). - **2. Individuelle Seiten**: Layout/structure for specific pages (Home, About, etc.).
- **System-Module (Features)**: Closed systems with data structures (Blog, News, Products, Jobs, References). - **3. System-Module (Features)**: Functional systems like Blog, News, Products, Jobs, References.
- **Logik-Funktionen**: Pure logic (Search, Filter, Forms, PDF-Export, Multi-lang). - **4. Logik-Funktionen**: Logic modules like Search, Filter, Forms, PDF-Export.
- **Visuelle Inszenierung**: Hero-Story, visual flows, Scroll-effects. - **5. Schnittstellen (API)**: Data Syncs with CRM, ERP, Payment systems.
- **Komplexe Interaktion**: UI-experiences like Configurators or multi-step processes. - **6. Inhaltsverwaltung (CMS)**: Setup and mapping for CMS.
- **Schnittstellen (API)**: REAL Data Syncs (CRM, ERP, Stripe). - **7. Inszenierung & Interaktion**: Hero-stories, visual effects, configurators.
- **Inhaltsverwaltung (CMS)**: Setup and mapping for Headless CMS. - **8. Mehrsprachigkeit**: Architecture scaling for multiple languages.
- **Sorglos-Betrieb (Hosting)**: Hosting, Updates, Backups. - **9. Inhaltliche Initial-Pflege**: Manual data entry/cleanup.
- **10. Laufender Betrieb & Hosting**: Ongoing maintenance, updates, 24/7 monitoring.
### RULES FOR positionDescriptions (STRICT): ### RULES FOR positionDescriptions (STRICT):
1. **NO "ICH-FORM"**: Do NOT use "Ich" or "Mein". Lead with the action or component. 1. **ABSOLUTE RULE: NO FIRST PERSON**: NEVER use "Ich", "Mein", "Wir" or "Unser". Lead with nouns or passive verbs.
2. **CONCISE & ITEM-BASED**: Use short, technical sentences. Focus on WHAT is delivered. 2. **PROFESSIONAL TONE**: Use "Erstellung von...", "Anbindung der...", "Implementierung technischer...", "Bereitstellung von...".
3. **ZERO GENERALIZATION**: Do NOT say "Verschiedene Funktionen" or "Optimierte Darstellung". Name the things. 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. 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. 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, not a cheap website. 6. **INDUSTRIAL AMBITION**: Describe it as a high-end technical solution. Avoid "schöne Website" or marketing fluff.
7. **SPECIFIC - PAGES**: For "Individuelle Seiten", list the pages as a comma-separated list. 7. **PAGES**: For "2. Individuelle Seiten", list the pages (e.g., "Startseite (Hero-Video), Leistungen, Kontakt").
8. **SPECIFIC - HOSTING**: Always append: "Inkl. 20GB Speicher." 8. **LOGIC**: Describe the ACTUAL logic (e.g., "Volltextsuche mit Auto-Complete", not "eine Suche").
9. **SPECIFIC - LOGIC**: Describe the ACTUAL logic. NEVER use generic terms. 9. **KEYS**: Return EXACTLY the keys defined in "POSITION TITLES".
10. **STRICT KEYS**: Keys MUST be EXACTLY the ones defined in POSITION TITLES. 10. **NO AGB**: NEVER mention "AGB" or "Geschäftsbedingungen".
11. **AGB BAN (CRITICAL)**: NEVER mention "Allgemeine Geschäftsbedingungen" or "AGGs" in any text. They are NOT part of this offer.
### EXAMPLES (FEW-SHOT): ### EXAMPLES (PASSIVE & TECHNICAL):
- **BAD**: "Ich entwickle die Seiten: Startseite, Leistungen, Kontakt." - **GOOD**: "Konfiguration der CMS-Infrastruktur zur unabhängigen Verwaltung von Produkt-Katalogen und News-Beiträgen."
- **GOOD**: "Erstellung der Seiten: Startseite (Video-Hero), Über uns (Timeline), Leistungen, Kontakt." - **GOOD**: "Implementierung einer Volltextsuche inkl. Kategorisierungs-Logik für effizientes Auffinden von Projektreferenzen."
- **BAD**: "Ich binde Google Maps an." - **GOOD**: "Native API-Anbindung an das ERP-System zur Echtzeit-Synchronisation von Bestandsdaten."
- **GOOD**: "Native API-Integration von Google Maps mit individueller Standort-Visualisierung." - **BAD**: "Ich richte dir das CMS ein."
- **BAD**: "Ich programmiere Scroll-Effekte." - **BAD**: "Ich programmiere eine tolle Suche für deine Seite."
- **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).
### DATA CONTEXT: ### DATA CONTEXT:
${JSON.stringify({ facts, details, strategy, ia }, null, 2)} ${JSON.stringify({ facts, details, strategy, ia }, null, 2)}
### OUTPUT FORMAT (Strict JSON): ### 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', { 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' } response_format: { type: 'json_object' }
}, { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } }); }, { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } });
addUsage(p5Resp.data); 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)); const positionsData = JSON.parse(cleanJson(p5Resp.data.choices[0].message.content));
// 6. PASS 6: The Industrial Critic // 6. PASS 6: The Industrial Critic
@@ -526,6 +537,10 @@ ${JSON.stringify({ facts, strategy, ia, positionsData }, null, 2)}
response_format: { type: 'json_object' } response_format: { type: 'json_object' }
}, { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } }); }, { headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' } });
addUsage(p6Resp.data); 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)); const reflection = JSON.parse(cleanJson(p6Resp.data.choices[0].message.content));
// 6. Reflection Merge Utility // 6. Reflection Merge Utility

View File

@@ -22,41 +22,41 @@ const styles = StyleSheet.create({
export const AboutModule = () => ( export const AboutModule = () => (
<> <>
<PDFText style={styles.industrialTitle}>Über mich</PDFText> <PDFText style={styles.industrialTitle}>Expertise & Profil</PDFText>
<PDFText style={styles.industrialSubtitle}>Senior Software Developer & Technischer Partner</PDFText> <PDFText style={styles.industrialSubtitle}>Entwicklung & Technischer Partner für den Mittelstand</PDFText>
<Divider style={{ marginVertical: 16, backgroundColor: COLORS.GRID }} /> <Divider style={{ marginVertical: 16, backgroundColor: COLORS.GRID }} />
<PDFView style={{ marginTop: 24 }}> <PDFView style={{ marginTop: 24 }}>
<PDFText style={styles.industrialTextLead}> <PDFText style={styles.industrialTextLead}>
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.
</PDFText> </PDFText>
<PDFView style={[styles.industrialGrid2, { marginTop: 20 }]}> <PDFView style={[styles.industrialGrid2, { marginTop: 20 }]}>
<PDFView style={[styles.industrialCol, { marginRight: '8%' }]}> <PDFView style={[styles.industrialCol, { marginRight: '8%' }]}>
<PDFText style={[styles.industrialText, { fontWeight: 'bold', color: COLORS.CHARCOAL, marginBottom: 8 }]}>Erfahrung & Substanz</PDFText> <PDFText style={[styles.industrialText, { fontWeight: 'bold', color: COLORS.CHARCOAL, marginBottom: 8 }]}>Erfahrung & Substanz</PDFText>
<PDFText style={styles.industrialText}> <PDFText style={styles.industrialText}>
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.
</PDFText> </PDFText>
<PDFText style={styles.industrialText}> <PDFText style={styles.industrialText}>
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.
</PDFText> </PDFText>
</PDFView> </PDFView>
<PDFView style={styles.industrialCol}> <PDFView style={styles.industrialCol}>
<PDFText style={[styles.industrialText, { fontWeight: 'bold', color: COLORS.CHARCOAL, marginBottom: 8 }]}>Fokus Einzelentwicklung</PDFText> <PDFText style={[styles.industrialText, { fontWeight: 'bold', color: COLORS.CHARCOAL, marginBottom: 8 }]}>Fokus Einzelentwicklung</PDFText>
<PDFText style={styles.industrialText}> <PDFText style={styles.industrialText}>
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.
</PDFText> </PDFText>
<PDFText style={styles.industrialText}> <PDFText style={styles.industrialText}>
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.
</PDFText> </PDFText>
</PDFView> </PDFView>
</PDFView> </PDFView>
<PDFView style={{ marginTop: 32, paddingVertical: 16, borderTopWidth: 1, borderTopColor: COLORS.GRID }}> <PDFView style={{ marginTop: 32, paddingVertical: 16, borderTopWidth: 1, borderTopColor: COLORS.GRID }}>
<PDFText style={[styles.industrialText, { fontWeight: 'bold', color: COLORS.CHARCOAL, marginBottom: 4 }]}>Meine Zusage</PDFText> <PDFText style={[styles.industrialText, { fontWeight: 'bold', color: COLORS.CHARCOAL, marginBottom: 4 }]}>Qualitäts-Zusage</PDFText>
<PDFText style={styles.industrialText}> <PDFText style={styles.industrialText}>
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.
</PDFText> </PDFText>
</PDFView> </PDFView>
</PDFView> </PDFView>
@@ -77,11 +77,11 @@ export const CrossSellModule = ({ state }: any) => {
{isWebsite ? ( {isWebsite ? (
<> <>
<PDFView style={[styles.industrialCol, { marginRight: '8%' }]}> <PDFView style={[styles.industrialCol, { marginRight: '8%' }]}>
<PDFText style={styles.industrialTextLead}>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.</PDFText> <PDFText style={styles.industrialTextLead}>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.</PDFText>
<PDFText style={[styles.industrialText, { fontWeight: 'bold' }]}>Keine Abos. Keine komplexen neuen Systeme. Nur gezielte Zeitersparnis.</PDFText> <PDFText style={[styles.industrialText, { fontWeight: 'bold' }]}>Keine Abos. Keine komplexen neuen Systeme. Gezielte Zeitersparnis.</PDFText>
<PDFView style={{ marginTop: 24, padding: 16, backgroundColor: '#f8fafc', borderLeftWidth: 2, borderLeftColor: COLORS.GRID }}> <PDFView style={{ marginTop: 24, padding: 16, backgroundColor: '#f8fafc', borderLeftWidth: 2, borderLeftColor: COLORS.GRID }}>
<PDFText style={[styles.industrialText, { fontWeight: 'bold', color: COLORS.CHARCOAL, marginBottom: 4 }]}>Individuelle Prüfung</PDFText> <PDFText style={[styles.industrialText, { fontWeight: 'bold', color: COLORS.CHARCOAL, marginBottom: 4 }]}>Individuelle Analyse</PDFText>
<PDFText style={styles.industrialText}>Ich analysiere Ihren spezifischen Prozess auf technisches Automatisierungspotenzial. Das Ergebnis liefert Klarheit darüber, ob eine Umsetzung wirtschaftlich sinnvoll ist.</PDFText> <PDFText style={styles.industrialText}>Spezifische Prozesse werden auf technisches Automatisierungspotenzial untersucht. Das Ergebnis liefert Klarheit über die wirtschaftliche Sinnhaftigkeit einer Umsetzung.</PDFText>
</PDFView> </PDFView>
</PDFView> </PDFView>
<PDFView style={styles.industrialCol}> <PDFView style={styles.industrialCol}>
@@ -89,17 +89,17 @@ export const CrossSellModule = ({ state }: any) => {
<PDFText style={styles.industrialText}>Erstellung von PDF-Angeboten, Berichten oder Protokollen in Sekunden statt Stunden.</PDFText> <PDFText style={styles.industrialText}>Erstellung von PDF-Angeboten, Berichten oder Protokollen in Sekunden statt Stunden.</PDFText>
</IndustrialCard> </IndustrialCard>
<IndustrialCard title="EXCEL-LOGIK"> <IndustrialCard title="EXCEL-LOGIK">
<PDFText style={styles.industrialText}>Intelligente Tabellen und automatisierte Auswertungen Ihrer Bestandsdaten.</PDFText> <PDFText style={styles.industrialText}>Intelligente Tabellen und automatisierte Auswertungen bestehender Datensätze.</PDFText>
</IndustrialCard> </IndustrialCard>
<IndustrialCard title="KI-ASSISTENZ"> <IndustrialCard title="KI-ASSISTENZ">
<PDFText style={styles.industrialText}>Effizientes Einlesen und Verarbeiten von analogen Dokumenten oder handschriftlichen Notizen.</PDFText> <PDFText style={styles.industrialText}>Effiziente Verarbeitung von analogen Dokumenten oder handschriftlichen Notizen mittels KI.</PDFText>
</IndustrialCard> </IndustrialCard>
</PDFView> </PDFView>
</> </>
) : ( ) : (
<PDFView style={{ width: '100%' }}> <PDFView style={{ width: '100%' }}>
<PDFText style={styles.industrialTextLead}>Ich baue die technische Basis für Ihr Unternehmen. Ich meide Baukästen und Agentur-Abhängigkeiten.</PDFText> <PDFText style={styles.industrialTextLead}>Bereitstellung einer stabilen technischen Basis ohne Abhängigkeiten von Baukasten-Systemen oder Agenturen.</PDFText>
<PDFText style={styles.industrialText}>Ich entwickle performante Frontends und stabile Backends. Ich liefere Code, den Sie besitzen und selbst kontrollieren.</PDFText> <PDFText style={styles.industrialText}>Entwicklung performanter Frontends und skalierbarer Backends. Die Auslieferung erfolgt als kontrollierbarer und nachhaltiger Quellcode.</PDFText>
</PDFView> </PDFView>
)} )}
</PDFView> </PDFView>

View File

@@ -14,14 +14,11 @@ const styles = StyleSheet.create({
configLabel: { fontSize: FONT_SIZES.BLUEPRINT, color: COLORS.TEXT_LIGHT, textTransform: 'uppercase', marginBottom: 8 }, 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) => ( export const techPageModule = ({ techDetails, headerIcon }: any) => (
<> <>
<DocumentTitle title="Technische Umsetzung" /> <DocumentTitle title="Technische Umsetzung" />
<PDFView style={styles.section}> <PDFView style={styles.section}>
<PDFText style={{ fontSize: FONT_SIZES.SUB, color: COLORS.TEXT_DIM, lineHeight: 1.6, marginBottom: 16 }}>Ich entwickle Websites als moderne, performante Websysteme.</PDFText> <PDFText style={{ fontSize: FONT_SIZES.SUB, color: COLORS.TEXT_DIM, lineHeight: 1.6, marginBottom: 16 }}>Entwicklung von Websites als moderne, performante Websysteme nach industriellen Standards.</PDFText>
<PDFView style={styles.pricingGrid}> <PDFView style={styles.pricingGrid}>
{techDetails?.map((item: any, i: number) => ( {techDetails?.map((item: any, i: number) => (
<PDFView key={i} style={styles.pricingRow}> <PDFView key={i} style={styles.pricingRow}>
@@ -39,45 +36,60 @@ export const TransparenzModule = ({ pricing }: any) => (
<DocumentTitle title="Preis-Transparenz & Modell" /> <DocumentTitle title="Preis-Transparenz & Modell" />
<PDFView style={styles.section}> <PDFView style={styles.section}>
<PDFText style={{ fontSize: FONT_SIZES.BODY + 1, fontWeight: 'bold', color: COLORS.CHARCOAL, marginBottom: 8 }}>Festpreise statt Stundenabrechnung</PDFText> <PDFText style={{ fontSize: FONT_SIZES.BODY + 1, fontWeight: 'bold', color: COLORS.CHARCOAL, marginBottom: 8 }}>Festpreise statt Stundenabrechnung</PDFText>
<PDFText style={{ fontSize: FONT_SIZES.SUB, color: COLORS.TEXT_DIM, lineHeight: 1.6, marginBottom: 12 }}>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.</PDFText> <PDFText style={{ fontSize: FONT_SIZES.SUB, color: COLORS.TEXT_DIM, lineHeight: 1.6, marginBottom: 12 }}>Maximale Planungssicherheit durch ein modulares Festpreis-System. Die Abrechnung erfolgt nach Ergebnissen statt nach reinem Zeitaufwand. Versteckte Kosten sind durch die modulare Struktur ausgeschlossen.</PDFText>
<Divider style={{ marginTop: 12 }} /> <Divider style={{ marginTop: 12 }} />
</PDFView> </PDFView>
<PDFView style={styles.section}> <PDFView style={styles.section}>
<PDFView style={styles.pricingGrid}> <PDFView style={styles.pricingGrid}>
<PDFView style={styles.pricingRow}> <PDFView style={styles.pricingRow}>
<PDFText style={styles.pricingTitle}>1. Das Fundament</PDFText> <PDFText style={styles.pricingTitle}>1. Das technische Fundament</PDFText>
<PDFText style={styles.pricingDesc}>Ich richte die technische Infrastruktur ein. Ich installiere das Hosting, schaffe SEO-Basics und erstelle die Test-, Staging- und Live-Umgebungen.</PDFText> <PDFText style={styles.pricingDesc}>Einrichtung der technischen Infrastruktur, Hosting-Bereitstellung, SEO-Basics sowie Bereitstellung von Test-, Staging- und produktiven Live-Umgebungen.</PDFText>
<PDFText style={styles.pricingTag}>{pricing.BASE_WEBSITE?.toLocaleString('de-DE')} </PDFText> <PDFText style={styles.pricingTag}>{pricing.BASE_WEBSITE?.toLocaleString('de-DE')} </PDFText>
</PDFView> </PDFView>
<PDFView style={styles.pricingRow}> <PDFView style={styles.pricingRow}>
<PDFText style={styles.pricingTitle}>2. Seiten</PDFText> <PDFText style={styles.pricingTitle}>2. Individuelle Seiten</PDFText>
<PDFText style={styles.pricingDesc}>Ich entwickle das individuelle Layout und die Struktur jeder Seite. Ich garantiere die korrekte Darstellung auf allen Endgeräten.</PDFText> <PDFText style={styles.pricingDesc}>Entwicklung individueller Layouts und Strukturen pro Seite. Optimierung für alle Endgeräte (Responsive Design) und Browser-Kompatibilität.</PDFText>
<PDFText style={styles.pricingTag}>{pricing.PAGE?.toLocaleString('de-DE')} / Stk</PDFText> <PDFText style={styles.pricingTag}>{pricing.PAGE?.toLocaleString('de-DE')} / Stk</PDFText>
</PDFView> </PDFView>
<PDFView style={styles.pricingRow}> <PDFView style={styles.pricingRow}>
<PDFText style={styles.pricingTitle}>3. Features</PDFText> <PDFText style={styles.pricingTitle}>3. System-Module (Features)</PDFText>
<PDFText style={styles.pricingDesc}>Ich erstelle abgeschlossene technische Systeme (z. B. Blog oder News). Ich definiere die Datenfelder und die Pflege-Oberflächen.</PDFText> <PDFText style={styles.pricingDesc}>Implementierung abgeschlossener technischer Systeme (z. B. Blog, News, Produkte). Definition notwendiger Datenfelder und Pflege-Oberflächen.</PDFText>
<PDFText style={styles.pricingTag}>{pricing.FEATURE?.toLocaleString('de-DE')} / Stk</PDFText> <PDFText style={styles.pricingTag}>{pricing.FEATURE?.toLocaleString('de-DE')} / Stk</PDFText>
</PDFView> </PDFView>
<PDFView style={styles.pricingRow}> <PDFView style={styles.pricingRow}>
<PDFText style={styles.pricingTitle}>4. Funktionen</PDFText> <PDFText style={styles.pricingTitle}>4. Logik-Funktionen</PDFText>
<PDFText style={styles.pricingDesc}>Ich programmiere Logik-Module wie Filter, Suchen oder Kontakt-Schnittstellen. Ich sorge für die fehlerfreie Verarbeitung Ihrer Daten.</PDFText> <PDFText style={styles.pricingDesc}>Programmierung technischer Logik-Einheiten wie Filter, Suchen oder Kontakt-Schnittstellen zur fehlerfreien Datenverarbeitung.</PDFText>
<PDFText style={styles.pricingTag}>{pricing.FUNCTION?.toLocaleString('de-DE')} / Stk</PDFText> <PDFText style={styles.pricingTag}>{pricing.FUNCTION?.toLocaleString('de-DE')} / Stk</PDFText>
</PDFView> </PDFView>
<PDFView style={styles.pricingRow}> <PDFView style={styles.pricingRow}>
<PDFText style={styles.pricingTitle}>5. Interaktion</PDFText> <PDFText style={styles.pricingTitle}>5. Schnittstellen (API)</PDFText>
<PDFText style={styles.pricingDesc}>Ich entwerfe komplexe UI-Abläufe und Konfiguratoren. Ich optimiere die Nutzerführung für maximale Abschlüsse.</PDFText> <PDFText style={styles.pricingDesc}>Anbindung externer Drittsysteme (CRM, ERP, Payment-Provider) zur automatisierten Datensynchronisation und Prozessoptimierung.</PDFText>
<PDFText style={styles.pricingTag}>{pricing.COMPLEX_INTERACTION?.toLocaleString('de-DE')} / Stk</PDFText>
</PDFView>
<PDFView style={styles.pricingRow}>
<PDFText style={styles.pricingTitle}>6. Integrationen</PDFText>
<PDFText style={styles.pricingDesc}>Ich binde Drittsysteme wie CRM, ERP oder Stripe an. Ich richte CMS-Schnittstellen zur unabhängigen Inhaltsverwaltung ein.</PDFText>
<PDFText style={styles.pricingTag}>ab {pricing.API_INTEGRATION?.toLocaleString('de-DE')} / Stk</PDFText> <PDFText style={styles.pricingTag}>ab {pricing.API_INTEGRATION?.toLocaleString('de-DE')} / Stk</PDFText>
</PDFView> </PDFView>
<PDFView style={styles.pricingRow}> <PDFView style={styles.pricingRow}>
<PDFText style={styles.pricingTitle}>7. Betrieb (12 Monate)</PDFText> <PDFText style={styles.pricingTitle}>6. Inhaltsverwaltung (CMS)</PDFText>
<PDFText style={styles.pricingDesc}>Ich betreibe das Hosting, pflege Sicherheitsupdates ein und erstelle monatliche Berichte. Ich garantiere die Verfügbarkeit r ein Jahr.</PDFText> <PDFText style={styles.pricingDesc}>Bereitstellung und Konfiguration eines Content Management Systems (CMS) inkl. technischer Anbindung aller Module zur unabhängigen Datenpflege.</PDFText>
<PDFText style={styles.pricingTag}>1.440 </PDFText> <PDFText style={styles.pricingTag}>{pricing.CMS_SETUP?.toLocaleString('de-DE')} </PDFText>
</PDFView>
<PDFView style={styles.pricingRow}>
<PDFText style={styles.pricingTitle}>7. Inszenierung & Interaktion</PDFText>
<PDFText style={styles.pricingDesc}>Umsetzung komplexer Interaktions-Mechanismen, Konfiguratoren oder aufwendiger visueller Storytelling-Elemente zur Steigerung der Conversion.</PDFText>
<PDFText style={styles.pricingTag}>ab {pricing.VISUAL_STAGING?.toLocaleString('de-DE')} </PDFText>
</PDFView>
<PDFView style={styles.pricingRow}>
<PDFText style={styles.pricingTitle}>8. Mehrsprachigkeit</PDFText>
<PDFText style={styles.pricingDesc}>Skalierung der System-Architektur auf zusätzliche Sprachen. Inklusive struktureller Anpassungen und Logik für Sprachumschaltung.</PDFText>
<PDFText style={styles.pricingTag}>+20% / Sprache</PDFText>
</PDFView>
<PDFView style={styles.pricingRow}>
<PDFText style={styles.pricingTitle}>9. Inhaltliche Initial-Pflege</PDFText>
<PDFText style={styles.pricingDesc}>Manuelle Übernahme und Aufbereitung von Datensätzen in das Zielsystem zur Sicherstellung einer initialen Inhaltsabdeckung.</PDFText>
<PDFText style={styles.pricingTag}>{pricing.NEW_DATASET?.toLocaleString('de-DE')} / Stk</PDFText>
</PDFView>
<PDFView style={styles.pricingRow}>
<PDFText style={styles.pricingTitle}>10. Laufender Betrieb & Hosting</PDFText>
<PDFText style={styles.pricingDesc}>Laufender Betrieb, Hosting, Sicherheits-Updates sowie monatliche Backups und Monitoring zur Sicherstellung der Systemverfügbarkeit.</PDFText>
<PDFText style={styles.pricingTag}>{pricing.HOSTING_MONTHLY?.toLocaleString('de-DE')} / Monat</PDFText>
</PDFView> </PDFView>
</PDFView> </PDFView>
</PDFView> </PDFView>
@@ -86,7 +98,7 @@ export const TransparenzModule = ({ pricing }: any) => (
export const PrinciplesModule = ({ principles }: any) => ( export const PrinciplesModule = ({ principles }: any) => (
<> <>
<DocumentTitle title="Meine Prinzipien" /> <DocumentTitle title="Prinzipien & Standards" />
<PDFView style={styles.pricingGrid}> <PDFView style={styles.pricingGrid}>
{principles?.map((item: any, i: number) => ( {principles?.map((item: any, i: number) => (
<PDFView key={i} style={styles.pricingRow}> <PDFView key={i} style={styles.pricingRow}>

View File

@@ -69,7 +69,7 @@ export function calculatePositions(state: FormState, pricing: any): Position[] {
if (state.projectType === 'website') { if (state.projectType === 'website') {
positions.push({ positions.push({
pos: pos++, pos: pos++,
title: 'Basis Website Setup', title: '1. Das technische Fundament',
desc: 'Projekt-Setup, Infrastruktur, Hosting-Bereitstellung, Grundstruktur & Design-Vorlage, technisches SEO-Basics, Analytics.', desc: 'Projekt-Setup, Infrastruktur, Hosting-Bereitstellung, Grundstruktur & Design-Vorlage, technisches SEO-Basics, Analytics.',
qty: 1, qty: 1,
price: pricing.BASE_WEBSITE price: pricing.BASE_WEBSITE
@@ -92,7 +92,7 @@ export function calculatePositions(state: FormState, pricing: any): Position[] {
positions.push({ positions.push({
pos: pos++, pos: pos++,
title: 'Individuelle Seiten', title: '2. Individuelle Seiten',
desc: `Gestaltung und Umsetzung von ${totalPagesCount} individuellen Seiten-Layouts (${uniquePages.join(', ')}).`, desc: `Gestaltung und Umsetzung von ${totalPagesCount} individuellen Seiten-Layouts (${uniquePages.join(', ')}).`,
qty: totalPagesCount, qty: totalPagesCount,
price: totalPagesCount * pricing.PAGE 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 || [])]; const allFeatures = [...state.features.map((f: string) => FEATURE_LABELS[f] || f), ...(state.otherFeatures || [])];
positions.push({ positions.push({
pos: pos++, pos: pos++,
title: 'System-Module', title: '3. System-Module (Features)',
desc: `Implementierung funktionaler Bereiche: ${allFeatures.join(', ')}. Inklusive Datenstruktur und Darstellung.`, desc: `Implementierung funktionaler Bereiche: ${allFeatures.join(', ')}. Inklusive Datenstruktur und Darstellung.`,
qty: allFeatures.length, qty: allFeatures.length,
price: allFeatures.length * pricing.FEATURE 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 || [])]; const allFunctions = [...state.functions.map((f: string) => FUNCTION_LABELS[f] || f), ...(state.otherFunctions || [])];
positions.push({ positions.push({
pos: pos++, pos: pos++,
title: 'Logik-Funktionen', title: '4. Logik-Funktionen',
desc: `Implementierung technischer Logik: ${allFunctions.join(', ')}.`, desc: `Implementierung technischer Logik: ${allFunctions.join(', ')}.`,
qty: allFunctions.length, qty: allFunctions.length,
price: allFunctions.length * pricing.FUNCTION 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 || [])]; const allApis = [...state.apiSystems.map((a: string) => API_LABELS[a] || a), ...(state.otherTech || [])];
positions.push({ positions.push({
pos: pos++, pos: pos++,
title: 'Schnittstellen (API)', title: '5. Schnittstellen (API)',
desc: `Anbindung externer Systeme zur Datensynchronisation: ${allApis.join(', ')}.`, desc: `Anbindung externer Systeme zur Datensynchronisation: ${allApis.join(', ')}.`,
qty: allApis.length, qty: allApis.length,
price: allApis.length * pricing.API_INTEGRATION 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); const totalFeatures = state.features.length + (state.otherFeatures?.length || 0) + (state.otherFeaturesCount || 0);
positions.push({ positions.push({
pos: pos++, pos: pos++,
title: 'Inhaltsverwaltung (CMS)', title: '6. Inhaltsverwaltung (CMS)',
desc: 'Einrichtung eines Systems zur eigenständigen Pflege von Inhalten und Datensätzen.', desc: 'Einrichtung eines Systems zur eigenständigen Pflege von Inhalten und Datensätzen.',
qty: 1, qty: 1,
price: pricing.CMS_SETUP + totalFeatures * pricing.CMS_CONNECTION_PER_FEATURE 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) { if (state.newDatasets > 0) {
positions.push({ positions.push({
pos: pos++, pos: pos++,
title: 'Inhaltspflege (Initial)', title: '9. Inhaltliche Initial-Pflege',
desc: `Manuelle Einpflege von ${state.newDatasets} Datensätzen (z.B. Produkte, Blogartikel).`, desc: `Manuelle Übernahme und Aufbereitung von ${state.newDatasets} Datensätzen (Produkte, Artikel) in das Zielsystem.`,
qty: state.newDatasets, qty: state.newDatasets,
price: state.newDatasets * pricing.NEW_DATASET price: state.newDatasets * pricing.NEW_DATASET
}); });
} }
if (state.visualStaging && Number(state.visualStaging) > 0) { if ((state.visualStaging && Number(state.visualStaging) > 0) || (state.complexInteractions && Number(state.complexInteractions) > 0)) {
const count = Number(state.visualStaging); const vsCount = Number(state.visualStaging || 0);
positions.push({ const ciCount = Number(state.complexInteractions || 0);
pos: pos++, const totalCount = vsCount + ciCount;
title: 'Visuelle Inszenierung',
desc: `Umsetzung von ${count} Hero-Stories, Scroll-Effekten oder speziell inszenierten Sektionen.`,
qty: count,
price: count * pricing.VISUAL_STAGING
});
}
if (state.complexInteractions && Number(state.complexInteractions) > 0) {
const count = Number(state.complexInteractions);
positions.push({ positions.push({
pos: pos++, pos: pos++,
title: 'Komplexe Interaktion', title: '7. Inszenierung & Interaktion',
desc: `Umsetzung von ${count} Konfiguratoren, Live-Previews oder mehrstufigen Auswahlprozessen.`, desc: `Umsetzung von ${totalCount} speziellen Sektionen, Hero-Stories oder Konfiguratoren zur Steigerung der Conversion.`,
qty: count, qty: totalCount,
price: count * pricing.COMPLEX_INTERACTION price: (vsCount * pricing.VISUAL_STAGING) + (ciCount * pricing.COMPLEX_INTERACTION)
}); });
} }
@@ -181,7 +173,7 @@ export function calculatePositions(state: FormState, pricing: any): Position[] {
positions.push({ positions.push({
pos: pos++, pos: pos++,
title: 'Mehrsprachigkeit', title: '8. Mehrsprachigkeit',
desc: `Erweiterung des Systems auf ${languagesCount} Sprachen (Struktur & Logik).`, desc: `Erweiterung des Systems auf ${languagesCount} Sprachen (Struktur & Logik).`,
qty: languagesCount, qty: languagesCount,
price: Math.round(factorPrice) 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); const monthlyRate = pricing.HOSTING_MONTHLY + (state.storageExpansion * pricing.STORAGE_EXPANSION_MONTHLY);
positions.push({ positions.push({
pos: pos++, pos: pos++,
title: 'Betriebs- und Pflegeleistung (12 Monate)', title: '10. Laufender Betrieb & Hosting',
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'}.`, desc: `Bereitstellung der Infrastruktur, technische Instandhaltung, Sicherheits-Updates und Backup-Management gemäß AGB Punkt 7a. Inklusive 12 Monate Service.`,
qty: 1, qty: 1,
price: monthlyRate * 12 price: monthlyRate * 12
}); });

View File

@@ -1,27 +1,68 @@
{ {
"requestsFinished": 8, "requestsFinished": 0,
"requestsFailed": 0, "requestsFailed": 1,
"requestsRetries": 0, "requestsRetries": 1,
"requestsFailedPerMinute": 0, "requestsFailedPerMinute": 279,
"requestsFinishedPerMinute": 158, "requestsFinishedPerMinute": 0,
"requestMinDurationMillis": 610, "requestMinDurationMillis": null,
"requestMaxDurationMillis": 2310, "requestMaxDurationMillis": 0,
"requestTotalFailedDurationMillis": 0, "requestTotalFailedDurationMillis": 2,
"requestTotalFinishedDurationMillis": 12652, "requestTotalFinishedDurationMillis": 0,
"crawlerStartedAt": "2026-02-03T18:57:19.097Z", "crawlerStartedAt": "2026-02-04T17:39:09.193Z",
"crawlerFinishedAt": "2026-02-03T18:57:22.128Z", "crawlerFinishedAt": "2026-02-04T17:39:09.396Z",
"statsPersistedAt": "2026-02-03T18:57:22.128Z", "statsPersistedAt": "2026-02-04T17:39:09.396Z",
"crawlerRuntimeMillis": 3044, "crawlerRuntimeMillis": 215,
"crawlerLastStartTimestamp": 1770145039084, "crawlerLastStartTimestamp": 1770226749181,
"requestRetryHistogram": [ "requestRetryHistogram": [
8 null,
null,
null,
1
], ],
"statsId": 0, "statsId": 0,
"requestAvgFailedDurationMillis": null, "requestAvgFailedDurationMillis": 2,
"requestAvgFinishedDurationMillis": 1582, "requestAvgFinishedDurationMillis": null,
"requestTotalDurationMillis": 12652, "requestTotalDurationMillis": 2,
"requestsTotal": 8, "requestsTotal": 1,
"requestsWithStatusCode": {}, "requestsWithStatusCode": {},
"errors": {}, "errors": {
"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": 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
}
}
}
}
}
} }

View File

@@ -1,9 +1,9 @@
{ {
"usableSessionsCount": 8, "usableSessionsCount": 4,
"retiredSessionsCount": 0, "retiredSessionsCount": 0,
"sessions": [ "sessions": [
{ {
"id": "session_4ERnLfhRfe", "id": "session_qS9LzMPYLU",
"cookieJar": { "cookieJar": {
"version": "tough-cookie@6.0.0", "version": "tough-cookie@6.0.0",
"storeType": "MemoryCookieStore", "storeType": "MemoryCookieStore",
@@ -11,31 +11,19 @@
"enableLooseMode": false, "enableLooseMode": false,
"allowSpecialUseDomain": true, "allowSpecialUseDomain": true,
"prefixSecurity": "silent", "prefixSecurity": "silent",
"cookies": [ "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"
}
]
}, },
"userData": {}, "userData": {},
"maxErrorScore": 3, "maxErrorScore": 3,
"errorScoreDecrement": 0.5, "errorScoreDecrement": 0.5,
"expiresAt": "2026-02-03T19:47:19.140Z", "expiresAt": "2026-02-04T18:29:09.266Z",
"createdAt": "2026-02-03T18:57:19.140Z", "createdAt": "2026-02-04T17:39:09.266Z",
"usageCount": 1, "usageCount": 1,
"maxUsageCount": 50, "maxUsageCount": 50,
"errorScore": 0 "errorScore": 1
}, },
{ {
"id": "session_b0TzOu99YB", "id": "session_rQXoQ3YoSI",
"cookieJar": { "cookieJar": {
"version": "tough-cookie@6.0.0", "version": "tough-cookie@6.0.0",
"storeType": "MemoryCookieStore", "storeType": "MemoryCookieStore",
@@ -43,31 +31,19 @@
"enableLooseMode": false, "enableLooseMode": false,
"allowSpecialUseDomain": true, "allowSpecialUseDomain": true,
"prefixSecurity": "silent", "prefixSecurity": "silent",
"cookies": [ "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"
}
]
}, },
"userData": {}, "userData": {},
"maxErrorScore": 3, "maxErrorScore": 3,
"errorScoreDecrement": 0.5, "errorScoreDecrement": 0.5,
"expiresAt": "2026-02-03T19:47:19.796Z", "expiresAt": "2026-02-04T18:29:09.369Z",
"createdAt": "2026-02-03T18:57:19.796Z", "createdAt": "2026-02-04T17:39:09.369Z",
"usageCount": 1, "usageCount": 1,
"maxUsageCount": 50, "maxUsageCount": 50,
"errorScore": 0 "errorScore": 1
}, },
{ {
"id": "session_FQDoGeShzw", "id": "session_VQKYMg9QOd",
"cookieJar": { "cookieJar": {
"version": "tough-cookie@6.0.0", "version": "tough-cookie@6.0.0",
"storeType": "MemoryCookieStore", "storeType": "MemoryCookieStore",
@@ -75,31 +51,19 @@
"enableLooseMode": false, "enableLooseMode": false,
"allowSpecialUseDomain": true, "allowSpecialUseDomain": true,
"prefixSecurity": "silent", "prefixSecurity": "silent",
"cookies": [ "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"
}
]
}, },
"userData": {}, "userData": {},
"maxErrorScore": 3, "maxErrorScore": 3,
"errorScoreDecrement": 0.5, "errorScoreDecrement": 0.5,
"expiresAt": "2026-02-03T19:47:19.798Z", "expiresAt": "2026-02-04T18:29:09.376Z",
"createdAt": "2026-02-03T18:57:19.798Z", "createdAt": "2026-02-04T17:39:09.376Z",
"usageCount": 1, "usageCount": 1,
"maxUsageCount": 50, "maxUsageCount": 50,
"errorScore": 0 "errorScore": 1
}, },
{ {
"id": "session_7qPl1RuIhU", "id": "session_Jf7MUM5INz",
"cookieJar": { "cookieJar": {
"version": "tough-cookie@6.0.0", "version": "tough-cookie@6.0.0",
"storeType": "MemoryCookieStore", "storeType": "MemoryCookieStore",
@@ -107,156 +71,16 @@
"enableLooseMode": false, "enableLooseMode": false,
"allowSpecialUseDomain": true, "allowSpecialUseDomain": true,
"prefixSecurity": "silent", "prefixSecurity": "silent",
"cookies": [ "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"
}
]
}, },
"userData": {}, "userData": {},
"maxErrorScore": 3, "maxErrorScore": 3,
"errorScoreDecrement": 0.5, "errorScoreDecrement": 0.5,
"expiresAt": "2026-02-03T19:47:19.799Z", "expiresAt": "2026-02-04T18:29:09.380Z",
"createdAt": "2026-02-03T18:57:19.799Z", "createdAt": "2026-02-04T17:39:09.380Z",
"usageCount": 1, "usageCount": 1,
"maxUsageCount": 50, "maxUsageCount": 50,
"errorScore": 0 "errorScore": 1
},
{
"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
} }
] ]
} }