Updated Contact_Base and User_Base (including New/Out variants) to use standardized string IDs mapped from random IDs via root_validator. Removed legacy integer ID fields and lookup validators to support V3 Vision standards. This completes the refactor chain for Person and Post dependencies.
154 lines
5.5 KiB
Python
154 lines
5.5 KiB
Python
import datetime, pytz
|
|
|
|
from typing import Dict, List, Optional, Set, Union
|
|
from pydantic import BaseModel, EmailStr, Field, Json, PrivateAttr, ValidationError, validator, root_validator
|
|
|
|
from app.db_sql import get_id_random, redis_lookup_id_random
|
|
from app.lib_general import log, logging
|
|
|
|
from app.models.common_field_schema import base_fields, default_num_bytes
|
|
# from app.models.account_models import Account_Base
|
|
from app.models.address_models import Address_Base
|
|
|
|
|
|
# ### BEGIN ### API Contact Models ### Contact_Base() ###
|
|
class Contact_Base(BaseModel):
|
|
log.setLevel(logging.INFO) # DEBUG, INFO, WARNING, ERROR, EXCEPTION, CRITICAL
|
|
log.debug(locals())
|
|
|
|
# --- Standardized Vision IDs (Strings) ---
|
|
id: Optional[str] = Field(None, **base_fields['contact_id_random'])
|
|
contact_id: Optional[str] = Field(None, **base_fields['contact_id_random'])
|
|
|
|
account_id: Optional[str] = Field(None, **base_fields['account_id_random'])
|
|
address_id: Optional[str] = Field(None, **base_fields['address_id_random'])
|
|
|
|
# NOTE: Linked Address ID is actually the old contact.address_id (Legacy?)
|
|
linked_address_id: Optional[str] = Field(None, **base_fields['address_id_random'])
|
|
|
|
for_type: Optional[str]
|
|
for_id: Optional[int]
|
|
for_id_random: Optional[Union[str,None]] = None # lambda:get_id_random(values.get('for_id'), table_name=values.get('for_type')),
|
|
|
|
name: Optional[str]
|
|
title: Optional[str]
|
|
tagline: Optional[str]
|
|
|
|
description: Optional[str]
|
|
lu_time_zone_id: Optional[str]
|
|
# timezone: Optional[str]
|
|
timezone_name: Optional[str]
|
|
|
|
email: Optional[str]
|
|
email_active: Optional[bool]
|
|
email_status: Optional[str]
|
|
cc_email: Optional[str]
|
|
|
|
phone_mobile: Optional[str]
|
|
phone_home: Optional[str]
|
|
phone_office: Optional[str]
|
|
phone_land: Optional[str]
|
|
phone_fax: Optional[str]
|
|
phone_other: Optional[str]
|
|
|
|
website_url: Optional[str]
|
|
website_name: Optional[str]
|
|
|
|
facebook_url: Optional[str]
|
|
instagram_url: Optional[str]
|
|
linkedin_url: Optional[str]
|
|
twitter_url: Optional[str]
|
|
|
|
other_site_url: Optional[str]
|
|
other_site_name: Optional[str]
|
|
|
|
other_text: Optional[str]
|
|
other_json: Optional[Json]
|
|
|
|
enable: Optional[bool]
|
|
hide: Optional[bool]
|
|
priority: Optional[bool]
|
|
sort: Optional[int]
|
|
group: Optional[str]
|
|
|
|
notes: Optional[str]
|
|
created_on: Optional[datetime.datetime] = None
|
|
updated_on: Optional[datetime.datetime] = None
|
|
|
|
# Including other related objects
|
|
#account: Optional[Account_Base]
|
|
address: Optional[Address_Base]
|
|
|
|
_processed_at: datetime.datetime = PrivateAttr(default_factory=datetime.datetime.now)
|
|
|
|
@root_validator(pre=True)
|
|
def map_v3_ids(cls, values):
|
|
"""
|
|
Vision Transformer:
|
|
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('contact_id_random'):
|
|
values['id'] = rid
|
|
values['contact_id'] = rid
|
|
|
|
if a_rid := values.get('account_id_random'):
|
|
values['account_id'] = a_rid
|
|
if ad_rid := values.get('address_id_random'):
|
|
values['address_id'] = ad_rid
|
|
if lad_rid := values.get('linked_address_id_random'):
|
|
values['linked_address_id'] = lad_rid
|
|
|
|
# 2. Prevent "Collision Population"
|
|
for k in ['id', 'contact_id', 'account_id', 'address_id', 'linked_address_id']:
|
|
if k in values and not isinstance(values[k], str) and values[k] is not None:
|
|
del values[k]
|
|
|
|
return values
|
|
|
|
@validator('for_id', pre=True, always=True)
|
|
def for_id_lookup(cls, v, values, **kwargs):
|
|
log.setLevel(logging.DEBUG)
|
|
log.debug(locals())
|
|
|
|
for_type = values.get('for_type')
|
|
for_id = v # values.get('for_id')
|
|
for_id_random = values.get('for_id_random')
|
|
|
|
if for_id and for_type:
|
|
log.info(f'Got For ID: {for_id}; For Type: {for_type}')
|
|
for_id_random = get_id_random(for_id, table_name=for_type)
|
|
values['for_id_random'] = for_id_random
|
|
return for_id
|
|
elif values.get('for_id_random') and values.get('for_type'):
|
|
log.info(f'Got For ID Random: {for_id_random}; For Type: {for_type}')
|
|
return redis_lookup_id_random(record_id_random=values['for_id_random'], table_name=values['for_type'])
|
|
log.info(f'Got nothing? For ID: {for_id}; For ID Random: {for_id_random}; For Type: {for_type}')
|
|
return None
|
|
|
|
@validator('for_id_random', always=True)
|
|
def for_id_random_lookup(cls, v, values, **kwargs):
|
|
log.setLevel(logging.DEBUG)
|
|
log.debug(locals())
|
|
|
|
for_type = values.get('for_type')
|
|
for_id = values.get('for_id')
|
|
for_id_random = v
|
|
|
|
if for_id_random:
|
|
log.info(f'Got For ID Random: {for_id_random}')
|
|
return for_id_random
|
|
elif for_id and for_type:
|
|
log.info(f'Got For ID: {for_id}; For Type: {for_type}')
|
|
for_id_random = get_id_random(for_id, table_name=for_type)
|
|
log.info(f'Got ID Random: {for_id_random}')
|
|
return for_id_random
|
|
log.info(f'Got nothing? For ID: {for_id}; For ID Random: {for_id_random}; For Type: {for_type}')
|
|
return None
|
|
|
|
class Config:
|
|
underscore_attrs_are_private = True
|
|
allow_population_by_field_name = False
|
|
fields = base_fields
|
|
# ### END ### API Contact Models ### Contact_Base() ###
|