fix: parse JSON string values from MariaDB in org_config loader

MariaDB returns JSON columns as strings via mysql2 driver. Added
parseJsonValue() to handle both string and object values. Fixes
config not loading on production (always showing defaults).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-26 17:02:16 -05:00
co-authored by Claude Opus 4.6
parent 6307d1b515
commit f645a19da1
2 changed files with 24 additions and 2 deletions
+11 -2
View File
@@ -87,6 +87,13 @@ const KEY_MAP: Record<string, keyof OrgConfig> = {
setup_complete: 'setupComplete' setup_complete: 'setupComplete'
}; };
function parseJsonValue(value: unknown): unknown {
if (typeof value === 'string') {
try { return JSON.parse(value); } catch { return value; }
}
return value;
}
export function parseOrgConfig(rows: { key: string; value: unknown }[]): OrgConfig { export function parseOrgConfig(rows: { key: string; value: unknown }[]): OrgConfig {
const config = structuredClone(DEFAULTS); const config = structuredClone(DEFAULTS);
@@ -94,12 +101,14 @@ export function parseOrgConfig(rows: { key: string; value: unknown }[]): OrgConf
const configKey = KEY_MAP[row.key]; const configKey = KEY_MAP[row.key];
if (!configKey) continue; if (!configKey) continue;
const parsed = parseJsonValue(row.value);
if (configKey === 'setupComplete') { if (configKey === 'setupComplete') {
config.setupComplete = Boolean(row.value); config.setupComplete = Boolean(parsed);
} else { } else {
config[configKey] = { config[configKey] = {
...config[configKey], ...config[configKey],
...(row.value as Record<string, unknown>) ...(parsed as Record<string, unknown>)
} as any; } as any;
} }
} }
+13
View File
@@ -15,6 +15,19 @@ describe('config', () => {
expect(config.locale.language).toBe('en'); expect(config.locale.language).toBe('en');
}); });
it('handles JSON string values from MariaDB', () => {
const rows = [
{ key: 'branding', value: '{"primaryColor":"#ea580c","accentColor":"#0d9488","logoUrl":""}' },
{ key: 'org_info', value: '{"name":"Sunny Paws Rescue","city":"Austin","state":"TX"}' },
{ key: 'setup_complete', value: 'true' }
];
const config = parseOrgConfig(rows);
expect(config.branding.primaryColor).toBe('#ea580c');
expect(config.orgInfo.name).toBe('Sunny Paws Rescue');
expect(config.setupComplete).toBe(true);
});
it('provides defaults for missing keys', () => { it('provides defaults for missing keys', () => {
const config = parseOrgConfig([]); const config = parseOrgConfig([]);
expect(config.branding.primaryColor).toBe('#0d9488'); expect(config.branding.primaryColor).toBe('#0d9488');