[MVP][READY] #175-B: Shared key-map + locale-kontrakt mellem backend/frontend #231

Merged
integrator-bot merged 2 commits from feat/issue-226-shared-keymap-locale-contract into main 2026-03-01 23:55:56 +01:00
3 changed files with 13 additions and 5 deletions

View File

@@ -2,6 +2,7 @@ import lobbyCatalog from '../../../shared/i18n/lobby.json';
const frontendErrors = lobbyCatalog.frontend.errors;
const localeConfig = lobbyCatalog.locales;
const backendToFrontendErrorKeys = lobbyCatalog.contract.backend_to_frontend_error_keys as Record<string, keyof typeof frontendErrors>;
type FrontendErrorKey = keyof typeof frontendErrors;
type SupportedLocale = (typeof localeConfig.supported)[number];
@@ -40,9 +41,15 @@ export function lobbyMessageFromApiPayload(payload: unknown, fallbackKey: Fronte
const record = payload as Record<string, unknown>;
const code = typeof record.error_code === 'string' ? record.error_code : '';
const payloadLocale = typeof record.locale === 'string' ? record.locale : locale;
if (!isFrontendErrorKey(code)) {
return lobbyMessage(fallbackKey, payloadLocale);
const mappedKey = code ? backendToFrontendErrorKeys[code] : undefined;
if (mappedKey && isFrontendErrorKey(mappedKey)) {
return lobbyMessage(mappedKey, payloadLocale);
}
return lobbyMessage(code, payloadLocale);
if (isFrontendErrorKey(code)) {
return lobbyMessage(code, payloadLocale);
}
return lobbyMessage(fallbackKey, payloadLocale);
}

View File

@@ -48,11 +48,11 @@ describe('lobbyMessage locale handling', () => {
).toBe('Sessionskoden er ugyldig, eller sessionen findes ikke længere.');
});
it('uses shared backend→frontend key-map when backend key differs from frontend copy key', () => {
it('uses shared backend→frontend key-map at runtime even when fallback key differs', () => {
expect(
lobbyMessageFromApiPayload(
{ error_code: 'session_not_joinable', locale: 'da' },
'join_failed',
'start_round_failed',
),
).toBe('Kunne ikke joine. Tjek kode eller kaldenavn og prøv igen.');
});

View File

@@ -404,6 +404,7 @@
"host_only_start_round": "start_round_failed",
"host_only_show_question": "start_round_failed",
"host_only_mix_answers": "start_round_failed",
"host_only_action": "start_round_failed",
"category_has_no_questions": "start_round_failed",
"show_question_invalid_phase": "start_round_failed",
"round_config_missing": "start_round_failed",