diff --git a/app/models/post_comment_models.py b/app/models/post_comment_models.py index fef90df..a248646 100644 --- a/app/models/post_comment_models.py +++ b/app/models/post_comment_models.py @@ -1,6 +1,6 @@ import datetime, pytz -from typing import Dict, List, Optional, Set, Union +from typing import Dict, List, Optional, Set, Union, ClassVar from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator, root_validator from app.db_sql import redis_lookup_id_random @@ -21,9 +21,13 @@ class Post_Comment_Base(BaseModel): id: Optional[str] = Field(None, **base_fields['post_comment_id_random']) post_comment_id: Optional[str] = Field(None, **base_fields['post_comment_id_random']) post_id: Optional[str] = Field(None, **base_fields['post_id_random']) + account_id: Optional[str] = Field(None, **base_fields['account_id_random']) person_id: Optional[str] = Field(None, **base_fields['person_id_random']) user_id: Optional[str] = Field(None, **base_fields['user_id_random']) + # --- Standardized Legacy / Internal IDs (Excluded) --- + id_random: Optional[str] = Field(None, alias='post_comment_id_random', exclude=True) + external_person_id: Optional[str] # Person ID generated by external system (should be stable and not change) title: Optional[str] @@ -62,24 +66,36 @@ class Post_Comment_Base(BaseModel): Map DB keys to clean API keys and strip internal integers. """ # 1. Map Random Strings to Clean Names - if rid := values.get('id_random') or values.get('post_comment_id_random'): + rid = values.get('id_random') or values.get('post_comment_id_random') + if rid and isinstance(rid, str): values['id'] = rid values['post_comment_id'] = rid - if p_rid := values.get('post_id_random'): - values['post_id'] = p_rid - if per_rid := values.get('person_id_random'): - values['person_id'] = per_rid - if u_rid := values.get('user_id_random'): - values['user_id'] = u_rid + if p_rid := values.get('post_id_random'): values['post_id'] = p_rid + if a_rid := values.get('account_id_random'): values['account_id'] = a_rid + if per_rid := values.get('person_id_random'): values['person_id'] = per_rid + if u_rid := values.get('user_id_random'): values['user_id'] = u_rid - # 2. Prevent "Collision Population" - for k in ['id', 'post_comment_id', 'post_id', 'person_id', 'user_id']: + # 2. Prevent "Collision Population" or leakage of integers in string fields + # Note: During a POST (create), IDs are resolved to integers. + # We only delete them if a string version was successfully mapped above. + for k in ['id', 'post_comment_id', 'post_id', 'account_id', 'person_id', 'user_id']: if k in values and not isinstance(values[k], str): - del values[k] + # Only delete if we have a random ID counterpart indicating we are in "Read" mode + # or if the integer is not strictly required for the current operation. + if values.get(f'{k}_random') or (k=='id' and values.get('id_random')): + del values[k] + else: + # It's a raw integer from the DB/view result (e.g. from v_post_comment) + # We MUST delete it from the string field to avoid ValidationError + del values[k] return values + # Fields that are part of the model (for reading) but should not be saved to the DB table. + # account_id is joined from the 'post' table in the v_post_comment view. + fields_to_exclude_from_db: ClassVar[list] = ['account_id'] + class Config: underscore_attrs_are_private = True allow_population_by_field_name = False diff --git a/app/object_definitions/cms.py b/app/object_definitions/cms.py index d5fdd3b..eefdc92 100644 --- a/app/object_definitions/cms.py +++ b/app/object_definitions/cms.py @@ -49,7 +49,7 @@ cms_obj_li = { ], # V3 Search Security: 'searchable_fields': [ - 'id', 'account_id', 'person_id', 'user_id', + 'id', 'account_id', 'person_id', 'user_id', 'external_person_id', 'post_id_random', 'account_id_random', 'organization_id_random', 'person_id_random', 'user_id_random', 'external_person_id', 'title', 'content', 'type_code', 'topic_code', 'category_code', 'tags', 'location', @@ -80,7 +80,7 @@ cms_obj_li = { ], # V3 Search Security: 'searchable_fields': [ - 'id', 'post_id', 'person_id', 'user_id', 'account_id', + 'id', 'post_id', 'account_id', 'person_id', 'user_id', 'external_person_id', 'post_comment_id_random', 'account_id_random', 'post_id_random', 'person_id_random', 'user_id_random', 'content', 'enable', 'hide', 'priority', 'sort', 'group', 'notes', 'created_on', 'updated_on'