From 4cad0a29adca215892ae5155df3e8289e2ca220e Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Sun, 7 Jun 2026 08:26:14 +0200 Subject: [PATCH] fix(company-profile): deserialize JSONB columns in row_to_response MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Raw text() queries return JSONB columns as JSON-encoded Python strings, not as Python list/dict objects. The existing isinstance check then fails and silently falls back to defaults — so list-valued fields like target_markets, offerings, processing_systems, ai_systems were always returned as their defaults regardless of stored content. Add a JSON-decode pass over _JSONB_FIELDS before the type check. Verified: PATCH of target_markets=["DE","EU"] now round-trips through GET correctly. Previously the DB had the right data but GET returned ["DE"] (the default). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../compliance/services/company_profile_service.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/backend-compliance/compliance/services/company_profile_service.py b/backend-compliance/compliance/services/company_profile_service.py index 80059991..384f32aa 100644 --- a/backend-compliance/compliance/services/company_profile_service.py +++ b/backend-compliance/compliance/services/company_profile_service.py @@ -109,7 +109,12 @@ def _where_clause() -> str: def row_to_response(row: Any) -> CompanyProfileResponse: - """Convert a DB row to response model using zip-based column mapping.""" + """Convert a DB row to response model using zip-based column mapping. + + JSONB columns may arrive as JSON strings from raw text() queries — we + json.loads them first so the isinstance check below succeeds against the + expected Python type. + """ raw = dict(zip(_BASE_COLUMNS_LIST, row)) coerced: dict[str, Any] = {} @@ -117,6 +122,13 @@ def row_to_response(row: Any) -> CompanyProfileResponse: default, expected_type = _FIELD_DEFAULTS[col] value = raw[col] + # JSONB columns can come back as JSON-encoded strings from raw queries + if col in _JSONB_FIELDS and isinstance(value, str): + try: + value = json.loads(value) + except (json.JSONDecodeError, TypeError): + pass # fall through to default below + if expected_type == "STR": coerced[col] = str(value) elif expected_type == "STR_OR_NONE":