diff --git a/src/app/core/content/content-claims.spec.ts b/src/app/core/content/content-claims.spec.ts index 8260a83..5e1c356 100644 --- a/src/app/core/content/content-claims.spec.ts +++ b/src/app/core/content/content-claims.spec.ts @@ -108,4 +108,30 @@ describe('content claims and attribution', () => { ); } }); + + it('keeps pitch timeline roles free of the period date', () => { + for (const locale of APP_LOCALES) { + for (const entry of SITE_CONTENT_DATA[locale].pitch.timeline) { + expect(entry.role, `${locale}.${entry.id}`).not.toMatch(/\d{2}\/\d{4}/); + } + } + }); + + it('keeps Pitch and Home free of editorial omission commentary', () => { + const editorial = + /not listed on this site|auf dieser Seite zu listen|This page shows the public selection|Diese Seite zeigt die öffentliche Auswahl|What this page covers|Was diese Seite abdeckt/i; + + for (const locale of APP_LOCALES) { + const site = SITE_CONTENT_DATA[locale]; + const text = [ + ...site.pitch.profile, + ...site.pitch.timeline.map((entry) => entry.body), + ...site.pitch.sections.flatMap((section) => [section.headline, ...(section.body ?? [])]), + ...site.home.sections.flatMap((section) => [section.headline, ...(section.body ?? [])]), + ...site.home.serviceAreas.map((area) => area.body), + ].join('\n'); + + expect(editorial.test(text), locale).toBe(false); + } + }); }); diff --git a/src/app/core/content/de/home.ts b/src/app/core/content/de/home.ts index 175b431..386d332 100644 --- a/src/app/core/content/de/home.ts +++ b/src/app/core/content/de/home.ts @@ -20,13 +20,13 @@ export const HOME_DE: HomePageCopy = { { id: 'workplaces', title: 'Arbeitsplätze und Netz', - body: 'Geräte, Netz und die Dienste, mit denen Dein Team täglich arbeitet — so geschnitten, dass sich der Alltag tragen lässt.', + body: 'Geräte, Netz und die Dienste, mit denen Dein Team täglich arbeitet, bleiben zuverlässig.', routeId: 'servicesHardwareNetwork', }, { id: 'servers', title: 'Server und Cluster', - body: 'Einzelne Hosts, Virtualisierung oder ein Cluster. Der Weg dorthin bleibt nachvollziehbar, on-premise oder auf Azure AKS.', + body: 'Einzelne Hosts, Virtualisierung oder ein Cluster. Der Weg dorthin bleibt nachvollziehbar, vor Ort oder auf Azure AKS.', routeId: 'servicesClusters', }, { @@ -38,7 +38,7 @@ export const HOME_DE: HomePageCopy = { { id: 'ai', title: 'KI-Abläufe', - body: 'Zwei umgesetzte Werkzeuge bei der Rösterei Tangermünde. Weitere Bausteine — lokale Modelle, RAG, Mensch in der Schleife — werden auftragsbezogen geprüft.', + body: 'Zwei umgesetzte Werkzeuge bei der Rösterei Tangermünde. Weitere Bausteine — lokale Modelle, Suche in eigenen Unterlagen, Prüfung durch einen Menschen — werden je Auftrag geprüft.', routeId: 'servicesAi', }, ], @@ -57,7 +57,7 @@ export const HOME_DE: HomePageCopy = { { id: 'implement', title: 'Umsetzung', - body: 'Ein Ansprechpartner setzt um: Software, Infrastruktur, Cluster oder ein schmales KI-Werkzeug, je nach Briefing.', + body: 'Ein Ansprechpartner setzt um: Software, Infrastruktur, Cluster oder ein klar umrissenes KI-Werkzeug, je nach Briefing.', }, { id: 'operate', @@ -72,7 +72,7 @@ export const HOME_DE: HomePageCopy = { sections: [ { id: 'scope', - headline: 'Was diese Seite abdeckt', + headline: 'Vier Arbeitsbereiche', body: [ 'Vier Bereiche: Arbeitsplätze und Netz, Server und Cluster, Software und Daten sowie KI-Abläufe. Was nicht dazu gehört, wird im Briefing benannt — nicht stillschweigend mitverkauft.', ], diff --git a/src/app/core/content/de/pitch.ts b/src/app/core/content/de/pitch.ts index 69c8f6a..c752639 100644 --- a/src/app/core/content/de/pitch.ts +++ b/src/app/core/content/de/pitch.ts @@ -5,17 +5,17 @@ export const PITCH_DE: PitchPageCopy = { routeId: 'pitch', title: 'Profil | Antonio Ledebuhr', description: - 'Fullstack- und DevOps-Ingenieur in Tangermünde: rund sieben Jahre Webanwendungen, direkter Kundenkontakt und Teamverantwortung. Freelance seit 04/2023.', + 'Fullstack- und DevOps-Ingenieur in Tangermünde: rund sieben Jahre Webanwendungen, direkter Kundenkontakt und Teamverantwortung. Freiberuflich seit 04/2023.', hero: { headline: 'Fullstack- und DevOps-Ingenieur in Tangermünde', proof: - 'Rund sieben Jahre berufliche Erfahrung mit dem Bau und Betrieb von Webanwendungen. Freelance seit 04/2023.', + 'Rund sieben Jahre berufliche Erfahrung mit dem Bau und Betrieb von Webanwendungen. Freiberuflich seit 04/2023.', playfulLine: 'IT mit Drehmoment', }, profile: [ 'Rund sieben Jahre berufliche Erfahrung mit dem Bau und Betrieb von Webanwendungen.', 'Fullstack-Entwicklung, DevOps, direkter Kundenkontakt vom ersten Anforderungsworkshop bis in den Produktivbetrieb sowie Personal- und Teamverantwortung.', - 'Freelance seit 04/2023, mit Sitz in Tangermünde.', + 'Freiberuflich seit 04/2023, mit Sitz in Tangermünde.', 'Heimspiel Java mit Spring; dazu C# und .NET, Angular, SQL, Docker und Kubernetes, Azure einschließlich AKS sowie GitLab CI/CD und Azure DevOps.', ], metrics: [ @@ -43,38 +43,38 @@ export const PITCH_DE: PitchPageCopy = { { id: 'self-employed', period: 'seit 12/2021', - role: 'unternehmerisch selbständig seit 12/2021', - body: 'Eigene Verantwortung für Auftrag, Technik und Betrieb — ohne die früheren Angestelltenverhältnisse auf dieser Seite zu listen.', + role: 'unternehmerisch selbständig', + body: 'Eigene Verantwortung für Auftrag, Technik und Betrieb; eigene Rechnungsstellung und Kundenbeziehungen.', }, { id: 'freelance', period: 'seit 04/2023', - role: 'freiberuflich seit 04/2023', + role: 'freiberuflich', body: 'Freiberufliche Fullstack- und DevOps-Arbeit mit direktem Kundenkontakt, vom Anforderungsworkshop bis in den Produktivbetrieb.', }, { id: 'hdi', period: '05/2023 – 01/2024', role: 'Senior Fullstack / DevOps bei HDI Specialty', - body: 'Exposure-Management-Software und die Migration der Umgebungen von Azure App Services auf Azure AKS.', + body: 'Fullstack- und DevOps-Verantwortung in einem regulierten Versicherungsumfeld.', }, { id: 'roesterei', period: 'seit 10/2023', role: 'Gesamtverantwortung für die Technik der Rösterei Tangermünde', - body: 'Netz, Arbeitsplätze, Shop und zwei interne KI-Werkzeuge aus einer Hand. Antonio Ledebuhr hält eine wirtschaftliche Beteiligung an der Rösterei.', + body: 'Ein Ansprechpartner für die gesamte Betriebstechnik; die wirtschaftliche Beteiligung bleibt offengelegt.', }, { id: 'myspa', period: '03/2024 – 09/2024', role: 'Lead Backend / DevOps bei Aracom IT Services / MySpa', - body: 'Leitung des Backend-Teams (4) und des DevOps-Teams (2) bis zum Start der Software, mit direktem Kundenkontakt.', + body: 'Führung von Backend und DevOps bis zum Softwarestart, Anforderungen direkt vom Kunden.', }, { id: 'innofocus', period: 'seit 09/2025', role: 'Senior Backend- und Datenbankingenieur bei Innofocus / reifen.com', - body: 'Alleinverantwortung für die ERP-Datenmigration. Laufzeit von rund acht Stunden auf etwa 90 Minuten.', + body: 'Alleinverantwortung für die Migration, als einziger Freiberufler im direkten Kontakt mit dem Endkunden.', }, ], stackHeading: 'Kernstack', @@ -88,13 +88,13 @@ export const PITCH_DE: PitchPageCopy = { { id: 'angular', title: 'Angular und TypeScript', - body: 'Einzelanwendungen, RxJS-zeitige SPA-Arbeit und SCSS.', + body: 'Angular-SPAs, RxJS und SCSS.', }, { id: 'sql', title: 'SQL', body: 'Microsoft SQL Server, T-SQL, MySQL und MariaDB.' }, { id: 'containers', title: 'Docker und Kubernetes', - body: 'Container und Cluster on-premise und in der Cloud.', + body: 'Container und Cluster vor Ort und in der Cloud.', }, { id: 'azure', @@ -113,14 +113,14 @@ export const PITCH_DE: PitchPageCopy = { id: 'profile', headline: 'In dreißig Sekunden', body: [ - 'Antonio Ledebuhr arbeitet als Fullstack- und DevOps-Ingenieur aus Tangermünde. Diese Seite zeigt die öffentliche Auswahl von Stationen; der vollständige Lebenslauf steht als PDF bereit.', + 'Antonio Ledebuhr arbeitet als Fullstack- und DevOps-Ingenieur aus Tangermünde. Der Lebenslauf als PDF führt die Stationen vollständig.', ], }, { id: 'featured-cases', headline: 'Ausgewählte Fälle', body: [ - 'Die vier öffentlichen Fälle decken eCommerce und ERP, Laden-IT, IoT und Versicherung ab. Jeder Fall ist auf der Projektseite vollständig beschrieben.', + 'Vier Fälle decken eCommerce und ERP, Laden-IT, IoT und Versicherung ab. Jeder Fall ist auf der Projektseite vollständig beschrieben.', ], }, ], diff --git a/src/app/core/content/en/home.ts b/src/app/core/content/en/home.ts index edce892..5125740 100644 --- a/src/app/core/content/en/home.ts +++ b/src/app/core/content/en/home.ts @@ -4,7 +4,7 @@ export const HOME_EN: HomePageCopy = { routeId: 'home', title: 'Home | Antonio Ledebuhr', description: - 'You describe what the business needs to achieve. One technical counterpart owns the path from diagnosis through delivery to operations or handover.', + 'You describe what the business needs to achieve. One technical contact takes the path from diagnosis through delivery to operations or handover.', hero: { headline: 'You describe what the business needs to achieve. I take the technical path from there.', @@ -12,21 +12,21 @@ export const HOME_EN: HomePageCopy = { 'At Rösterei Tangermünde the public work runs from the network and workplaces through to the shop and two in-house AI tools.', playfulLine: 'Full-stack, full throttle', body: [ - 'You put the outcome, the bottleneck or the recurring process in your own words. One counterpart then owns diagnosis, implementation and operations or handover.', + 'You put the outcome, the bottleneck or the recurring process in your own words. One person then handles diagnosis, implementation and operations or handover.', ], }, - serviceAreasHeading: 'Where this work fits', + serviceAreasHeading: 'What I can help with', serviceAreas: [ { id: 'workplaces', title: 'Workplaces and network', - body: 'Devices, the network and the services your team uses every day — cut so that Tuesday still works.', + body: 'Devices, the network and the everyday services your team uses stay reliable.', routeId: 'servicesHardwareNetwork', }, { id: 'servers', title: 'Servers and clusters', - body: 'A single host, virtualisation or a cluster. The path there stays readable, on-premise or on Azure AKS.', + body: 'A single host, virtualisation or a cluster. The path there stays clear, on-premise or on Azure AKS.', routeId: 'servicesClusters', }, { @@ -38,7 +38,7 @@ export const HOME_EN: HomePageCopy = { { id: 'ai', title: 'AI workflows', - body: 'Two delivered tools at Rösterei Tangermünde. Further building blocks — local models, retrieval, a person in the loop — are scoped per engagement.', + body: 'Two delivered tools at Rösterei Tangermünde. Further building blocks — local models, search over your own documents, review by a person — are agreed for each assignment.', routeId: 'servicesAi', }, ], @@ -57,12 +57,12 @@ export const HOME_EN: HomePageCopy = { { id: 'implement', title: 'Implementation', - body: 'One counterpart delivers: software, infrastructure, a cluster or a narrow AI tool, according to the brief.', + body: 'One person delivers: software, infrastructure, a cluster or a clearly defined AI tool, according to the brief.', }, { id: 'operate', title: 'Operations or handover', - body: 'The result stays operable. Handover means readable structures, not an undocumented snapshot.', + body: 'The result stays operable. Handover means structures you can follow, not an undocumented snapshot.', }, ], proofCaseId: 'roesterei', @@ -72,7 +72,7 @@ export const HOME_EN: HomePageCopy = { sections: [ { id: 'scope', - headline: 'What this page covers', + headline: 'Four areas of work', body: [ 'Four areas: workplaces and network, servers and clusters, software and data, and AI workflows. What sits outside that set is named in the briefing — it is not sold by implication.', ], diff --git a/src/app/core/content/en/pitch.ts b/src/app/core/content/en/pitch.ts index 4f77431..70b7f00 100644 --- a/src/app/core/content/en/pitch.ts +++ b/src/app/core/content/en/pitch.ts @@ -14,9 +14,9 @@ export const PITCH_EN: PitchPageCopy = { }, profile: [ 'About seven years of professional experience building and operating web applications.', - 'Fullstack development, DevOps, direct customer contact from the first requirements workshop through to production, and personnel and team responsibility.', + 'Fullstack development, DevOps, direct customer contact from the first requirements workshop through to production, and line management and team leadership.', 'Freelance since 04/2023, based in Tangermünde.', - 'Home ground is Java with Spring; also C# and .NET, Angular, SQL, Docker and Kubernetes, Azure including AKS, plus GitLab CI/CD and Azure DevOps.', + 'Java with Spring is the home stack; also C# and .NET, Angular, SQL, Docker and Kubernetes, Azure including AKS, plus GitLab CI/CD and Azure DevOps.', ], metrics: [ { @@ -43,38 +43,38 @@ export const PITCH_EN: PitchPageCopy = { { id: 'self-employed', period: 'since 12/2021', - role: 'entrepreneurially self-employed since 12/2021', - body: 'Own responsibility for the brief, the technology and operations — earlier employment stations are not listed on this site.', + role: 'entrepreneurially self-employed', + body: 'Own responsibility for the brief, the technology and operations; own invoicing and client relationships.', }, { id: 'freelance', period: 'since 04/2023', - role: 'freelance since 04/2023', + role: 'freelance', body: 'Freelance fullstack and DevOps work with direct customer contact, from the requirements workshop through to production.', }, { id: 'hdi', period: '05/2023 – 01/2024', role: 'Senior fullstack / DevOps at HDI Specialty', - body: 'Exposure-management software and the move of the environments from Azure App Services onto Azure AKS.', + body: 'Fullstack and DevOps ownership in a regulated insurance setting.', }, { id: 'roesterei', period: 'since 10/2023', role: 'Full technical responsibility at Rösterei Tangermünde', - body: 'Network, workplaces, shop and two in-house AI tools from one counterpart. Antonio Ledebuhr holds an economic stake in the roastery.', + body: 'One contact for the company’s technology as a whole; the economic stake stays disclosed.', }, { id: 'myspa', period: '03/2024 – 09/2024', role: 'Lead backend / DevOps at Aracom IT Services / MySpa', - body: 'Led the backend team (4) and the DevOps team (2) through the software launch, with direct customer contact.', + body: 'Led backend and DevOps through go-live, taking requirements directly from the customer.', }, { id: 'innofocus', period: 'since 09/2025', role: 'Senior backend and database engineer at Innofocus / reifen.com', - body: 'Sole responsibility for the ERP data migration. Run time from about eight hours down to about 90 minutes.', + body: 'Sole ownership of the migration, as the only freelancer in direct contact with the end customer.', }, ], stackHeading: 'Core stack', @@ -82,13 +82,13 @@ export const PITCH_EN: PitchPageCopy = { { id: 'java', title: 'Java and Spring', - body: 'Home ground: Java with Spring Boot, Spring Data and tests.', + body: 'Home stack: Java with Spring Boot, Spring Data and tests.', }, { id: 'dotnet', title: 'C# and .NET', body: 'ASP.NET Core, Entity Framework and xUnit.' }, { id: 'angular', title: 'Angular and TypeScript', - body: 'Single-page apps, RxJS-era SPA work and SCSS.', + body: 'Angular SPAs with RxJS and SCSS.', }, { id: 'sql', title: 'SQL', body: 'Microsoft SQL Server, T-SQL, MySQL and MariaDB.' }, { @@ -113,14 +113,14 @@ export const PITCH_EN: PitchPageCopy = { id: 'profile', headline: 'Thirty seconds', body: [ - 'Antonio Ledebuhr works as a fullstack and DevOps engineer from Tangermünde. This page shows the public selection of stations; the full curriculum vitae is available as a PDF.', + 'Antonio Ledebuhr works as a fullstack and DevOps engineer from Tangermünde. The CV PDF carries the full record.', ], }, { id: 'featured-cases', headline: 'Selected cases', body: [ - 'The four public cases cover eCommerce and ERP, shop-floor IT, IoT and insurance. Each case is written in full on the projects page.', + 'Four cases cover eCommerce and ERP, shop IT, IoT and insurance. Each case is written in full on the projects page.', ], }, ],