fix: Resolve ID Vision conflicts and validation errors in Event Exhibit Tracking
- Modified 'sanitize_payload' to ignore 'external_person_id', preventing incorrect lookup attempts for email/passcode fields. - Refined 'Event_Exhibit_Tracking_Base' to allow 'Union[int, str]' for relational IDs, bypassing string-length validation for internal integers. - Adjusted root validator to preserve relational integers during POST/PUT operations while still stripping primary/account IDs for Vision-compliant READ views. - Aligned model configuration with other V3 objects for consistency.
This commit is contained in:
@@ -212,6 +212,8 @@ def sanitize_payload(data: dict, model: Any, ignore_extra: bool = False) -> None
|
||||
# Scenario B: Vision naming (e.g., account_id: "abc")
|
||||
# We only resolve if it's a string of the correct length (random ID format)
|
||||
elif k.endswith('_id') and 11 <= len(v) <= 22:
|
||||
if k == 'external_person_id':
|
||||
continue
|
||||
target_id_field = k
|
||||
obj_type_lookup = k.replace('_id', '')
|
||||
|
||||
|
||||
@@ -17,14 +17,15 @@ class Event_Exhibit_Tracking_Base(BaseModel):
|
||||
log.setLevel(logging.WARNING) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
|
||||
log.debug(locals())
|
||||
|
||||
# --- Standardized Vision IDs (Strings for API, Integers for DB) ---
|
||||
id: Optional[Union[int, str]] = Field(**base_fields['event_exhibit_tracking_id_random'])
|
||||
event_exhibit_tracking_id: Optional[Union[int, str]] = Field(**base_fields['event_exhibit_tracking_id_random'])
|
||||
account_id: Optional[Union[int, str]] = Field(**base_fields['account_id_random'])
|
||||
event_id: Optional[Union[int, str]] = Field(**base_fields['event_id_random'])
|
||||
event_exhibit_id: Optional[Union[int, str]] = Field(**base_fields['event_exhibit_id_random'])
|
||||
event_person_id: Optional[Union[int, str]] = Field(**base_fields['event_person_id_random'])
|
||||
event_badge_id: Optional[Union[int, str]] = Field(**base_fields['event_badge_id_random'])
|
||||
# --- Standardized Vision IDs (Strings for API, Integers/Strings for DB) ---
|
||||
id: Optional[str] = Field(None, **base_fields['event_exhibit_tracking_id_random'])
|
||||
event_exhibit_tracking_id: Optional[str] = Field(None, **base_fields['event_exhibit_tracking_id_random'])
|
||||
account_id: Optional[str] = Field(None, **base_fields['account_id_random'])
|
||||
|
||||
event_id: Optional[Union[int, str]] = Field(None, **base_fields['event_id_random'])
|
||||
event_exhibit_id: Optional[Union[int, str]] = Field(None, **base_fields['event_exhibit_id_random'])
|
||||
event_person_id: Optional[Union[int, str]] = Field(None, **base_fields['event_person_id_random'])
|
||||
event_badge_id: Optional[Union[int, str]] = Field(None, **base_fields['event_badge_id_random'])
|
||||
|
||||
# --- Standardized Legacy / Internal IDs (Excluded) ---
|
||||
id_random: Optional[str] = Field(None, alias='event_exhibit_tracking_id_random', exclude=True)
|
||||
@@ -38,49 +39,26 @@ class Event_Exhibit_Tracking_Base(BaseModel):
|
||||
def map_v3_ids(cls, values):
|
||||
"""
|
||||
Vision Transformer:
|
||||
Map DB keys to clean API keys and strip internal integers during READ operations.
|
||||
Falls back to Redis/DB lookups if random string IDs are missing from the view.
|
||||
Map DB keys to clean API keys and strip internal integers.
|
||||
"""
|
||||
from app.db_sql import get_id_random
|
||||
|
||||
# 1. Map Primary Object ID
|
||||
rid = values.get('id_random') or values.get('event_exhibit_tracking_id_random')
|
||||
if rid and isinstance(rid, str):
|
||||
# 1. Map Random Strings to Clean Names
|
||||
if rid := values.get('id_random') or values.get('event_exhibit_tracking_id_random'):
|
||||
values['id'] = rid
|
||||
values['event_exhibit_tracking_id'] = rid
|
||||
elif values.get('id') and isinstance(values.get('id'), int):
|
||||
# Fallback for primary ID
|
||||
resolved_rid = get_id_random(values['id'], 'event_exhibit_tracking')
|
||||
if resolved_rid:
|
||||
values['id'] = resolved_rid
|
||||
values['event_exhibit_tracking_id'] = resolved_rid
|
||||
values['id_random'] = resolved_rid
|
||||
|
||||
# 2. Map & Resolve Relational IDs
|
||||
id_map = [
|
||||
('account_id', 'account'),
|
||||
('event_id', 'event'),
|
||||
('event_exhibit_id', 'event_exhibit'),
|
||||
('event_person_id', 'event_person'),
|
||||
('event_badge_id', 'event_badge'),
|
||||
]
|
||||
|
||||
for field, table in id_map:
|
||||
r_val = values.get(f'{field}_random')
|
||||
if r_val and isinstance(r_val, str):
|
||||
values[field] = r_val
|
||||
elif values.get(field) and isinstance(values[field], int):
|
||||
# Fallback: Resolve from Redis/DB if missing from view result
|
||||
resolved_rid = get_id_random(values[field], table)
|
||||
if resolved_rid:
|
||||
values[field] = resolved_rid
|
||||
values[f'{field}_random'] = resolved_rid
|
||||
|
||||
# 3. Final Vision Enforcement: Strip internal integers
|
||||
for k in ['id', 'event_exhibit_tracking_id', 'account_id', 'event_id', 'event_exhibit_id', 'event_person_id', 'event_badge_id']:
|
||||
val = values.get(k)
|
||||
if val is not None and not isinstance(val, str):
|
||||
values[k] = None
|
||||
|
||||
if a_rid := values.get('account_id_random'): values['account_id'] = a_rid
|
||||
if e_rid := values.get('event_id_random'): values['event_id'] = e_rid
|
||||
if ee_rid := values.get('event_exhibit_id_random'): values['event_exhibit_id'] = ee_rid
|
||||
if ep_rid := values.get('event_person_id_random'): values['event_person_id'] = ep_rid
|
||||
if eb_rid := values.get('event_badge_id_random'): values['event_badge_id'] = eb_rid
|
||||
|
||||
# 2. Prevent "Collision Population"
|
||||
# We only strip integers for the primary IDs and account_id to prevent leak in READ views.
|
||||
# Relational IDs (event_id, exhibit_id, etc.) are allowed to remain as integers during
|
||||
# POST/PUT operations so they reach the database correctly.
|
||||
for k in ['id', 'event_exhibit_tracking_id', 'account_id']:
|
||||
if k in values and not isinstance(values[k], str) and values[k] is not None:
|
||||
del values[k]
|
||||
|
||||
return values
|
||||
|
||||
|
||||
Reference in New Issue
Block a user