From 69305a0b0bf8d6389ca7638c364a6b094f938673 Mon Sep 17 00:00:00 2001 From: Thomas Reitz Date: Sun, 15 Mar 2026 09:28:06 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20Firmendaten=20um=20Gesch=C3=A4ftsf?= =?UTF-8?q?=C3=BChrer,=20Amtsgericht,=20Handelsregister=20erweitert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Backend: CompanySettings Interface + GET/POST um managingDirector, localCourt, commercialRegister ergänzt (Redis-Storage) - Frontend AdminCompanyPage: neue Sektion „Rechtliche Angaben" mit 3 Feldern, Footer-Vorschau zeigt alle Angaben inkl. HR-Nummer - Export-Service: PDF- und DOCX-Fußzeile enthält jetzt Geschäftsführer und Handelsregistereintrag (HRB + Amtsgericht kombiniert) Co-Authored-By: Claude Sonnet 4.6 --- .../expert-profile/profile-export.service.ts | 11 +++++ .../src/core/settings/settings.controller.ts | 38 +++++++++------ .../frontend/src/admin/AdminCompanyPage.tsx | 48 ++++++++++++++++++- 3 files changed, 81 insertions(+), 16 deletions(-) diff --git a/packages/core-service/src/core/expert-profile/profile-export.service.ts b/packages/core-service/src/core/expert-profile/profile-export.service.ts index 04925b8..e2ca4fd 100644 --- a/packages/core-service/src/core/expert-profile/profile-export.service.ts +++ b/packages/core-service/src/core/expert-profile/profile-export.service.ts @@ -245,12 +245,17 @@ export class ProfileExportService { if (companyRaw) { const c = JSON.parse(companyRaw) as Record; const address = [c['street'], [c['postalCode'], c['city']].filter(Boolean).join(' ')].filter(Boolean).join(', '); + const hrEntry = c['commercialRegister'] && c['localCourt'] + ? `${c['commercialRegister']} ${c['localCourt']}` + : (c['commercialRegister'] || c['localCourt'] || null); companyFooterText = [ c['name'], address || null, c['phone'] ? `Tel: ${c['phone']}` : null, c['email'], c['website'], + c['managingDirector'] ? `Geschäftsführer: ${c['managingDirector']}` : null, + hrEntry, ].filter(Boolean).join(' | '); } if (brandingRaw) { @@ -713,6 +718,7 @@ export class ProfileExportService { const c = JSON.parse(companyRaw) as { name?: string | null; street?: string | null; postalCode?: string | null; city?: string | null; phone?: string | null; email?: string | null; website?: string | null; + managingDirector?: string | null; localCourt?: string | null; commercialRegister?: string | null; }; const parts: string[] = []; if (c.name) parts.push(c.name); @@ -721,6 +727,11 @@ export class ProfileExportService { if (c.phone) parts.push(`Tel: ${c.phone}`); if (c.email) parts.push(c.email); if (c.website) parts.push(c.website); + if (c.managingDirector) parts.push(`Geschäftsführer: ${c.managingDirector}`); + const hrEntry = c.commercialRegister && c.localCourt + ? `${c.commercialRegister} ${c.localCourt}` + : (c.commercialRegister || c.localCourt || null); + if (hrEntry) parts.push(hrEntry); if (parts.length) companyFooterText = parts.join(' | '); } catch { /* ignore */ } } diff --git a/packages/core-service/src/core/settings/settings.controller.ts b/packages/core-service/src/core/settings/settings.controller.ts index b0890a4..6c94e17 100644 --- a/packages/core-service/src/core/settings/settings.controller.ts +++ b/packages/core-service/src/core/settings/settings.controller.ts @@ -44,6 +44,9 @@ interface CompanySettings { phone: string | null; email: string | null; website: string | null; + managingDirector: string | null; + localCourt: string | null; + commercialRegister: string | null; } /** @@ -428,19 +431,23 @@ export class SettingsController { const empty: CompanySettings = { name: null, street: null, postalCode: null, city: null, phone: null, email: null, website: null, + managingDirector: null, localCourt: null, commercialRegister: null, }; const raw = await this.redis.get(COMPANY_SETTINGS_KEY); if (!raw) return empty; try { const data = JSON.parse(raw) as Record; return { - name: typeof data.name === 'string' ? data.name : null, - street: typeof data.street === 'string' ? data.street : null, - postalCode: typeof data.postalCode === 'string' ? data.postalCode : null, - city: typeof data.city === 'string' ? data.city : null, - phone: typeof data.phone === 'string' ? data.phone : null, - email: typeof data.email === 'string' ? data.email : null, - website: typeof data.website === 'string' ? data.website : null, + name: typeof data.name === 'string' ? data.name : null, + street: typeof data.street === 'string' ? data.street : null, + postalCode: typeof data.postalCode === 'string' ? data.postalCode : null, + city: typeof data.city === 'string' ? data.city : null, + phone: typeof data.phone === 'string' ? data.phone : null, + email: typeof data.email === 'string' ? data.email : null, + website: typeof data.website === 'string' ? data.website : null, + managingDirector: typeof data.managingDirector === 'string' ? data.managingDirector : null, + localCourt: typeof data.localCourt === 'string' ? data.localCourt : null, + commercialRegister: typeof data.commercialRegister === 'string' ? data.commercialRegister : null, }; } catch { return empty; @@ -459,13 +466,16 @@ export class SettingsController { @Body() body: CompanySettings, ): Promise<{ success: boolean }> { const data: CompanySettings = { - name: body.name?.trim() || null, - street: body.street?.trim() || null, - postalCode: body.postalCode?.trim() || null, - city: body.city?.trim() || null, - phone: body.phone?.trim() || null, - email: body.email?.trim() || null, - website: body.website?.trim() || null, + name: body.name?.trim() || null, + street: body.street?.trim() || null, + postalCode: body.postalCode?.trim() || null, + city: body.city?.trim() || null, + phone: body.phone?.trim() || null, + email: body.email?.trim() || null, + website: body.website?.trim() || null, + managingDirector: body.managingDirector?.trim() || null, + localCourt: body.localCourt?.trim() || null, + commercialRegister: body.commercialRegister?.trim() || null, }; await this.redis.set(COMPANY_SETTINGS_KEY, JSON.stringify(data)); this.logger.log('Firmendaten aktualisiert'); diff --git a/packages/frontend/src/admin/AdminCompanyPage.tsx b/packages/frontend/src/admin/AdminCompanyPage.tsx index 72453d4..e0b141e 100644 --- a/packages/frontend/src/admin/AdminCompanyPage.tsx +++ b/packages/frontend/src/admin/AdminCompanyPage.tsx @@ -10,11 +10,15 @@ interface CompanySettings { phone: string | null; email: string | null; website: string | null; + managingDirector: string | null; + localCourt: string | null; + commercialRegister: string | null; } const empty: CompanySettings = { name: null, street: null, postalCode: null, city: null, phone: null, email: null, website: null, + managingDirector: null, localCourt: null, commercialRegister: null, }; const cardStyle: React.CSSProperties = { @@ -163,7 +167,7 @@ export function AdminCompanyPage() { -
+
+
+

+ Rechtliche Angaben +

+ +
+ + set('managingDirector', e.target.value)} + placeholder="Max Mustermann" + /> +
+ +
+
+ + set('localCourt', e.target.value)} + placeholder="Amtsgericht Köln" + /> +
+
+ + set('commercialRegister', e.target.value)} + placeholder="HRB 12345" + /> +
+
+