CI/CD pipeline migrated from Coolify to Orca.
Updated CLAUDE.md, pre-push-checks, docs-src, and pitch-deck scripts/slides.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Mandatory pre-push gates for all three language stacks with exact
commands, common pitfalls, and architecture rules. CLAUDE.md updated
with quick-reference section linking to the new files.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
TTS:
- CE → "C. E." for letter-by-letter pronunciation
- SAST → "S. A. S. T.", DAST → "D. A. S. T."
Finanzplan Slide 28:
- Data grid now loads Wandeldarlehen fp_scenario when active FM scenario
contains "wandeldarlehen" (scenarioId=c0000000-...-000000000200)
- Base Case version continues to load default fp_scenario
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Traction slide: "funktionsfähig und deployed" → "Prototyp-Stadium, mit Testkunden validiert"
- "bereit für zahlende Kunden" → "Ab August 2026 produktiver Betrieb"
- SDK Demo: "produktive Plattform" → "funktionierender Prototyp, mit Testkunden validiert"
- USP: "produktive Engine" → "leistungsfähige Engine"
Until founding in August 2026, all references must indicate prototype/test status.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
TTS Language Bug:
- ChatFAB: detect response language from text content instead of UI language
- German text with umlauts/ß triggers German TTS even when UI is in English
Presenter Script (German TTS pronunciation):
- Add proper umlauts (ä/ö/ü) throughout German text
- Expand abbreviations for clear pronunciation:
DSGVO → Datenschutz-Grundverordnung
SAST → Static Application Security Testing
DAST → Dynamic Application Security Testing
SBOM → Software Bill of Materials
VVT → Verarbeitungsverzeichnis
TOMs → technisch-organisatorische Maßnahmen
BSI → Bundesamt für Sicherheit in der Informationstechnik
KMU → kleine und mittlere Unternehmen, etc.
Technical FAQ (12 new entries):
- BGE-M3, RAG, Qdrant, Cross-Encoder, Hybrid Search
- SAST/DAST, SBOM, BSI, Cloud Providers (SysEleven/Hetzner)
- Controls/Prüfaspekte, Policy Engine, VVT/TOMs/DSFA
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Critical fix: All financial slides now use the version's preferred scenario
instead of always defaulting to Base Case (1M). This ensures the
Wandeldarlehen version shows its own lean financial plan.
- useFinancialModel: add preferredScenarioId parameter
- PitchDeck: extract default scenario from previewData.fm_scenarios
- Pass preferredScenarioId to all 5 financial slides
- FinancialsSlide layout: remove empty right column, full-width charts
- Remove ScenarioSwitcher + unused slider from FinancialsSlide
- Fix COMPLEI → COMPLAI in presenter script (only TTS pronunciation differs)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Shows "Lade Finanzplan..." when annualKPIs is empty (data not yet loaded)
instead of rendering nothing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Investors should not be able to modify business case assumptions.
Questions should be directed to founders via the AI chat agent.
Scenario switcher is kept for viewing different scenarios.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
DevSecOps, Onepager, SaaS, deployed, TypeScript, RegTech, OpenAI,
PostgreSQL, NVIDIA, GitLab, Full Compliance GPT, ERPNext — all marked
for English voice synthesis in German presenter script and FAQ.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When jwtVerify fails (JWT expired), decode the token without expiry check
to recover sessionId, validate it against the DB, and reissue a fresh 24h
JWT. Fixes investors with old 1h JWTs being locked out on magic link re-click.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace '25.000+' with 'über 25 Tausend' in DE text so Edge TTS speaks
it correctly instead of 'fünfundzwanzig Punkt null null null plus'.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
JWT was set to 1h while the session cookie lived 24h. After 1 hour the
cookie persisted but jwtVerify failed, making /api/auth/me return 401
and the re-click redirect fall through to the already-used token error.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
German permanently routes to compliance TTS service (Edge TTS neural
voice, Piper fallback). OVH DE path removed — no env var can flip it
back accidentally.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Without the flag, German routes to the compliance TTS service which uses
Edge TTS (de-DE-ConradNeural) with Piper as fallback — easier to A/B
between OVH and compliance/Edge TTS without code changes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
OVH honours sample_rate_hz and returns data at exactly the requested
rate, so synthesis and WAV header rates must always match. Decoupled
22050/16000 caused 22050 Hz PCM wrapped in a 16000 Hz header → slow
bloated playback. Both back to 16000 Hz.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
OVH uses sample_rate_hz in the request for internal synthesis quality
but always outputs raw PCM at 16000 Hz. Sending 22050 for synthesis
gives better pronunciation; declaring 16000 in the WAV header gives
correct playback speed. Previously both were the same value, forcing
a tradeoff between quality and speed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
OVH Riva ignores the sample_rate_hz request param and always returns at
its native 16000 Hz. Declaring a higher rate in the WAV header causes
proportionally slower/deeper playback. 16000 Hz matches the actual output.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
22050 Hz declared in WAV header while Riva returns 44100 Hz native PCM
causes playback at half speed — deep, bloated voice. Aligning the
declared rate with the actual output fixes pitch and speed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
If an investor clicks the magic link again after already being logged in,
check /api/auth/me first — valid session → redirect to / immediately
instead of showing the 'link already used' error.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Client component (investors/new page) imported DEFAULT_MESSAGE etc. from
lib/email.ts which also top-level initialises nodemailer — webpack tried
to bundle fs/net/dns into the client chunk and failed.
Extract the pure constants + getDefaultGreeting into lib/email-templates.ts
(client-safe), keep nodemailer in lib/email.ts (server-only), update the
page to import from email-templates.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add nodemailer to serverExternalPackages so webpack doesn't try to
bundle fs/net/dns built-ins (was fatal build error)
- Import jwtVerify from jose/jwt/verify instead of the full jose index
to avoid pulling in JWE deflate code incompatible with Edge Runtime
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ExecutiveSummarySlide:
- Unternehmensentwicklung: hardcoded table → useFinancialModel + computeAnnualKPIs
(MA, Kunden, ARR now computed from finanzplan DB for all versions)
- Pricing: aligned with BusinessModelSlide tiers (Starter/Professional/Enterprise)
Enterprise: 40k → 50k (matching Folie 11)
BusinessModelSlide:
- ACV: hardcoded "15–50k" → computed from summary.final_arr / final_customers
- Gross Margin: hardcoded "> 80%" → computed from lastResult.gross_margin_pct
All financial numbers on all slides now flow from the same compute engine.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All financial data now flows from the same compute engine (useFinancialModel).
No more hardcoded numbers in any slide — all values are derived from the
finanzplan database, ensuring consistency across all pitch deck versions.
- FinanzplanSlide: KPI table + charts now use computeAnnualKPIs() from FMResult[]
- BusinessModelSlide: bottom-up calc (customers × ACV = ARR) from compute engine
- AssumptionsSlide: Base case from compute, Bear/Bull scaled from Base
- New helper: lib/finanzplan/annual-kpis.ts for 60-month → 5-year aggregation
- PitchDeck: passes investorId to all financial slides for version-aware data
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Email template (email.ts):
- Bilingual: German body + DE/EN legal footer
- Customizable greeting, message body, and closing
- Magic Link explanation box (hardcoded)
- Confidentiality & Disclaimer footer (hardcoded, bilingual)
Invite page (investors/new):
- Name is now required, Company is optional
- Editable fields: greeting, message, closing (with defaults)
- Live email preview panel (right side)
- Shows full email content before sending
- German UI labels
API (invite/route.ts):
- Passes greeting, message, closing to email function
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds legal footer to the investor invite email with:
- Confidentiality obligation (3 years, purpose limitation)
- Disclaimer (not an offer, projections only, risk of total loss)
- Jurisdiction: Konstanz, German law
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Conditional sections only shown when instrument is "Wandeldarlehen"
- 200k investor ask + 200k L-Bank = 400k total funding visualization
- 3-step explanation: Investment → Conversion → Investor advantage
- Pre-Seed BW / L-Bank co-financing info box
- Cap Table before/after conversion example
- Use of Funds EUR amounts based on 400k total budget
- "1 Mio." version remains completely unaffected
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace emoji with Landmark icon
- Add JSON.parse fallback for use_of_funds
- Guard pieData labels and amounts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 15% tax-free acquisition grant (corrected from 25%)
- 25% exit grant on capital gains
- Up to 40% effective support (entry + exit combined)
- Program extended until 31.12.2026
- Disclaimer to verify current terms at bafa.de
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Theme toggle button below language toggle
- Uses existing theme-light CSS class from globals.css
- Moon/Sun icons with Nacht/Tag labels (DE) or Dark/Light (EN)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- All text-[10px] → text-xs (12px)
- All text-[9px] → text-[11px]
- All text-[8px] → text-[10px]
- Affected: BusinessModel, Product, Savings, Strategy slides
- Engineering: revert LoC to 481K (compliance SDK only, not all repos)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Ext. DSB: 6k→3k (halved, not eliminated)
- Compliance docs: 0→2k (reduced effort, not zero)
- Personnel: "~2/8/40 MA savings" → "50% more productive compliance time"
(realistic productivity gain, not full headcount elimination)
- ROIs now credible: KMU 3.7x, Mittelstand 6.4x, Konzern 15.6x
(was 11x/21x/62x — too aggressive for investors)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 17 more umlaut fixes (Konformitätsbewertung, Löschkonzept,
Portabilität, Regelmäßige, etc.) across 6 files
- ComplAI → COMPLAI in all string contexts for consistency
- BrandName component used for JSX rendering (gradient AI)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>