content: replace scaffolding with bilingual pages and case studies

Ship the final German and English copy, compose every route from shared page primitives, and cover claims, parity and contact briefing in tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-25 17:34:04 +02:00
parent 9ea2885c7b
commit d954361724
95 changed files with 4161 additions and 419 deletions

View File

@@ -0,0 +1,86 @@
import { APP_LOCALES } from '../i18n/locale';
import { ROUTE_IDS } from '../routing/route-ids';
import { CASE_STUDY_IDS } from './content.contracts';
import { SITE_CONTENT_DATA } from './site-content';
const STRUCTURAL_KEYS = new Set([
'id',
'status',
'control',
'required',
'routeId',
'caseId',
'referenceCaseId',
'external',
]);
function assertParity(left: unknown, right: unknown, path: string): void {
if (Array.isArray(left) || Array.isArray(right)) {
expect(Array.isArray(left), path).toBe(true);
expect(Array.isArray(right), path).toBe(true);
expect((left as unknown[]).length, path).toBe((right as unknown[]).length);
(left as unknown[]).forEach((item, index) =>
assertParity(item, (right as unknown[])[index], `${path}[${index}]`),
);
return;
}
if (left && right && typeof left === 'object' && typeof right === 'object') {
const leftKeys = Object.keys(left).sort();
const rightKeys = Object.keys(right).sort();
expect(leftKeys, path).toEqual(rightKeys);
for (const key of leftKeys) {
const nextPath = `${path}.${key}`;
const leftValue = (left as Record<string, unknown>)[key];
const rightValue = (right as Record<string, unknown>)[key];
if (STRUCTURAL_KEYS.has(key)) {
expect(leftValue, nextPath).toEqual(rightValue);
} else {
assertParity(leftValue, rightValue, nextPath);
}
}
return;
}
if (
typeof left === 'string' &&
typeof right === 'string' &&
(/featuredCaseIds\[\d+\]$/.test(path) || /options\[\d+\]\.value$/.test(path))
) {
expect(left, path).toBe(right);
}
}
describe('content parity', () => {
it('keeps the German and English trees structurally aligned', () => {
assertParity(SITE_CONTENT_DATA.de, SITE_CONTENT_DATA.en, 'site');
});
it('uses different long-form copy in German and English', () => {
for (const routeId of ROUTE_IDS) {
const german = SITE_CONTENT_DATA.de.pages[routeId];
const english = SITE_CONTENT_DATA.en.pages[routeId];
expect(german.title, routeId).not.toBe(english.title);
expect(german.description, routeId).not.toBe(english.description);
expect(german.hero.headline, routeId).not.toBe(english.hero.headline);
german.sections.forEach((section, index) => {
const other = english.sections[index];
expect(section.body?.join('\n'), `${routeId}.${section.id}`).not.toBe(
other?.body?.join('\n'),
);
});
}
for (const caseId of CASE_STUDY_IDS) {
const german = SITE_CONTENT_DATA.de.cases[caseId];
const english = SITE_CONTENT_DATA.en.cases[caseId];
expect(german.summary, caseId).not.toBe(english.summary);
expect(german.situation, caseId).not.toBe(english.situation);
}
expect(APP_LOCALES).toEqual(['de', 'en']);
});
});