feat(founding-wizard): Gründungs-Wizard für 2-Mann GmbH + 14 Notar-Templates
[migration-approved]
Templates (Migrations 123-136):
- 123 GO-GF (Geschäftsordnung Geschäftsführung)
- 124 SHA (Shareholders' Agreement, 56 Platzhalter)
- 125 Satzung (Articles of Association mit UG-Variante)
- 126 GF-Dienstvertrag (Trennungsprinzip Organ/Anstellung)
- 127 Arbeitsvertrag (AGG-neutral, NachwG, eAU)
- 128 Gesellschafterliste (§ 40 GmbHG)
- 129 GF-Bestellungsbeschluss (mit § 6 Abs. 2 Versicherung)
- 130 HRB-Anmeldung (§§ 7, 8, 39 GmbHG, § 12 HGB)
- 131 IP-Assignment Agreement (Gründer→GmbH)
- 132 Term Sheet (Pre-Seed/Seed VC-Standard)
- 133 Wandeldarlehensvertrag (Convertible Loan)
- 134 Beteiligungsvertrag (Subscription Agreement)
- 135 ESOP/VSOP-Plan (3 Varianten)
- 136 Cap Table
Kategorisierung (Migrations 137-138):
- ALTER TABLE compliance_legal_templates ADD lifecycle_stage TEXT[],
functional_category TEXT (mit CHECK Constraints + GIN-Index)
- Backfill aller 105 Templates: lifecycle_stage (pre_founding|founding|
startup|kmu|konzern) + functional_category (founding_legal|employment|
investor_funding|...)
Backend Founding-Wizard Service:
- template_renderer.py: Handlebars-light ({{VAR}}, {{#IF FLAG}}...{{/IF}})
- wizard_to_context.py: Mapping Wizard-State → SCREAMING_SNAKE_CASE Vars
- markdown_to_docx.py: Markdown → DOCX via python-docx
- founding_wizard_routes.py: POST /v1/founding-wizard/generate
→ liefert base64-DOCX-Files für ausgewählte Templates
Frontend Founding-Wizard (/sdk/founding-wizard):
- 8-Step Wizard (Basics, Gesellschafter, GF, Kapital, Notar, SHA, GF-Verträge, Generate)
- useFoundingWizardForm Hook mit localStorage-Persistenz
- TypeScript Code-Registry (template-categories.ts) als Backup zur DB
- Word-Download via data:URLs (base64)
Tests:
- 20 Unit-Tests grün (Renderer, Context-Mapping, DOCX-Conversion)
- Playwright E2E-Test mit 2-Mann GmbH (Benjamin + Sharang) Test-Daten
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Next.js Proxy: leitet POST /api/v1/founding-wizard/generate an Backend.
|
||||
*
|
||||
* Konvertiert das Backend-Response (base64 DOCX) in data: URLs,
|
||||
* die das Frontend direkt als Download anbieten kann.
|
||||
*/
|
||||
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
|
||||
const BACKEND_URL = process.env.BACKEND_COMPLIANCE_URL || 'http://bp-compliance-backend:8002'
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
try {
|
||||
const body = await req.json()
|
||||
|
||||
const backendRes = await fetch(`${BACKEND_URL}/v1/founding-wizard/generate`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body),
|
||||
})
|
||||
|
||||
if (!backendRes.ok) {
|
||||
const errorText = await backendRes.text()
|
||||
return NextResponse.json(
|
||||
{ error: 'Backend-Generierung fehlgeschlagen', detail: errorText },
|
||||
{ status: backendRes.status }
|
||||
)
|
||||
}
|
||||
|
||||
const data = await backendRes.json()
|
||||
const documents = (data.documents || []).map((doc: {
|
||||
document_type: string
|
||||
title: string
|
||||
filename: string
|
||||
content_base64: string
|
||||
size_bytes: number
|
||||
generated_at: string
|
||||
}) => ({
|
||||
document_type: doc.document_type,
|
||||
title: doc.title,
|
||||
filename: doc.filename,
|
||||
download_url: `data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,${doc.content_base64}`,
|
||||
size_bytes: doc.size_bytes,
|
||||
generated_at: doc.generated_at,
|
||||
}))
|
||||
|
||||
return NextResponse.json({
|
||||
documents,
|
||||
warnings: data.warnings || [],
|
||||
})
|
||||
} catch (e: unknown) {
|
||||
const message = e instanceof Error ? e.message : 'Unbekannter Fehler'
|
||||
return NextResponse.json(
|
||||
{ error: 'Proxy-Fehler', detail: message },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user