fix(legacy): resolve 422 error on site domain lookup and enhance V3 filtering

This commit is contained in:
Scott Idem
2026-01-06 16:29:09 -05:00
parent 459bd89198
commit d584457997
3 changed files with 60 additions and 11 deletions

View File

@@ -35,11 +35,10 @@ def safe_json_loads(json_str: Optional[str]) -> Any:
log.warning(f"Failed to parse JSON string: {json_str}. Error: {e}")
return None
def filter_order_by(order_by_li: Any, model: Any) -> Optional[Dict[str, str]]:
def filter_order_by(order_by_li: Any, model: Any, table_name: str = None) -> Optional[Dict[str, str]]:
"""
Filters the order_by_li dictionary to only include fields present in the Pydantic model.
This prevents SQL errors when the frontend requests ordering by fields that don't exist
on specific objects (e.g., 'priority' or 'sort' on 'account').
Filters the order_by_li dictionary to only include fields present in the Pydantic model
AND actually present in the database table/view.
"""
if not order_by_li or not isinstance(order_by_li, dict) or not model:
return order_by_li
@@ -47,12 +46,28 @@ def filter_order_by(order_by_li: Any, model: Any) -> Optional[Dict[str, str]]:
if not hasattr(model, '__fields__'):
return order_by_li
# Get all field names and aliases from the model
# 1. Filter by Pydantic Model Fields/Aliases
model_fields = set(model.__fields__.keys())
model_fields.update({f.alias for f in model.__fields__.values() if f.alias})
filtered = {k: v for k, v in order_by_li.items() if k in model_fields}
# 2. Filter by actual DB Column existence (Dry run)
if table_name and filtered:
from app.db_sql import db
from sqlalchemy import text
final_filtered = {}
for column in filtered:
try:
# Use a lightweight query to check if column exists
db.execute(text(f"SELECT `{column}` FROM `{table_name}` LIMIT 0"))
final_filtered[column] = filtered[column]
except Exception:
log.warning(f"Column '{column}' does not exist in '{table_name}'. Removing from order_by_li.")
continue
filtered = final_filtered
if len(filtered) != len(order_by_li):
log.info(f"Filtered order_by_li. Removed fields: {set(order_by_li.keys()) - set(filtered.keys())}")
@@ -279,7 +294,7 @@ async def get_obj_li(
if not table_name or not base_name:
return mk_resp(data=False, status_code=500, response=response, status_message=f"Configuration for object type '{obj_name}' (view: {view}) is incomplete.")
order_by_li = filter_order_by(order_by_li, base_name)
order_by_li = filter_order_by(order_by_li, base_name, table_name)
status_filter = get_supported_filters(base_name, status_filter)
if for_obj_type and for_obj_id:
@@ -376,7 +391,7 @@ async def search_obj_li(
if not table_name or not base_name:
return mk_resp(data=False, status_code=500, response=response, status_message=f"Configuration for object type '{obj_name}' (view: {view}) is incomplete.")
order_by_li = filter_order_by(order_by_li, base_name)
order_by_li = filter_order_by(order_by_li, base_name, table_name)
status_filter = get_supported_filters(base_name, status_filter)
searchable_fields = obj_cfg.get('searchable_fields')
@@ -640,7 +655,7 @@ async def get_child_obj_li(
if not table_name or not base_name:
return mk_resp(data=False, status_code=500, response=response, status_message=f"Configuration for object type '{obj_name}' is incomplete.")
order_by_li = filter_order_by(order_by_li, base_name)
order_by_li = filter_order_by(order_by_li, base_name, table_name)
status_filter = get_supported_filters(base_name, status_filter)
resolved_parent_id = redis_lookup_id_random(record_id_random=parent_obj_id, table_name=parent_obj_type)