fix(12-04): align setup config client to camelCase API contract + readable errors
BUG 1: Rename SetupConfigPayload fields from snake_case to camelCase to match the API configSchema (appExternalUrl, oidcIssuer, oidcClientId, vapidPublicKey). Update SetupPage.tsx handleSaveAndValidate to send the correct camelCase keys. BUG 2: Extract human-readable message from ZodError object in postSetupConfig error handler. When body.error is an object with issues[], use issues[0].message instead of stringifying the object (which produces "[object Object]"). All 245 PWA tests pass; TypeScript clean.
This commit is contained in:
@@ -543,12 +543,15 @@ export interface SetupStatusResponse {
|
||||
* Payload for POST /api/setup/config.
|
||||
* Collects non-secret runtime config written to the app_config table (D-02).
|
||||
* No secrets — VAPID private key and encryption key stay in Docker env.
|
||||
*
|
||||
* Field names match the API's configSchema exactly (camelCase).
|
||||
* API contract: { oidcIssuer, oidcClientId, vapidPublicKey, appExternalUrl }
|
||||
*/
|
||||
export interface SetupConfigPayload {
|
||||
app_url: string;
|
||||
oidc_issuer: string;
|
||||
oidc_client_id: string;
|
||||
vapid_public_key: string;
|
||||
appExternalUrl: string;
|
||||
oidcIssuer: string;
|
||||
oidcClientId: string;
|
||||
vapidPublicKey: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -594,8 +597,26 @@ export async function postSetupConfig(payload: SetupConfigPayload): Promise<void
|
||||
}
|
||||
|
||||
if (!res.ok) {
|
||||
const body = (await res.json().catch(() => ({}))) as { error?: string };
|
||||
throw new Error(body.error ?? `POST /api/setup/config failed: ${res.status}`);
|
||||
const body = (await res.json().catch(() => ({}))) as {
|
||||
error?: string | { name?: string; issues?: Array<{ message: string }> };
|
||||
};
|
||||
// body.error may be a ZodError object ({ name: "ZodError", issues: [...] })
|
||||
// rather than a plain string — extract the first issue message to avoid
|
||||
// "[object Object]" appearing in the UI (BUG 2 fix).
|
||||
let message: string;
|
||||
if (typeof body.error === 'string') {
|
||||
message = body.error;
|
||||
} else if (
|
||||
body.error &&
|
||||
typeof body.error === 'object' &&
|
||||
Array.isArray((body.error as { issues?: unknown[] }).issues) &&
|
||||
(body.error as { issues: Array<{ message: string }> }).issues.length > 0
|
||||
) {
|
||||
message = (body.error as { issues: Array<{ message: string }> }).issues[0].message;
|
||||
} else {
|
||||
message = `POST /api/setup/config failed: ${res.status}`;
|
||||
}
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user