You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
orquestrador/app/services/user/mock_customer_service.py

98 lines
2.8 KiB
Python

import hashlib
from app.db.mock_database import SessionMockLocal
from app.db.mock_models import Customer, User
from app.services.orchestration.technical_normalizer import is_valid_cpf, normalize_cpf
# Helpers para criar clientes ficticios deterministas a partir do CPF.
MOCK_CUSTOMER_NAMES = [
"Ana Souza",
"Bruno Lima",
"Carla Mendes",
"Diego Santos",
"Eduarda Alves",
"Felipe Rocha",
"Gabriela Costa",
"Henrique Martins",
"Isabela Ferreira",
"Joao Ribeiro",
]
def _stable_int(seed_text: str) -> int:
digest = hashlib.sha256(seed_text.encode("utf-8")).hexdigest()
return int(digest[:16], 16)
def _build_mock_customer_profile(cpf: str) -> dict:
entropy = _stable_int(cpf)
name = MOCK_CUSTOMER_NAMES[entropy % len(MOCK_CUSTOMER_NAMES)]
return {
"cpf": cpf,
"nome": f"{name} {_stable_int(cpf + '-suffix') % 900 + 100}",
"score": int(350 + (entropy % 500)),
"limite_credito": float(35_000 + (entropy % 140_000)),
"possui_restricao": (entropy % 9 == 0),
}
async def hydrate_mock_customer_from_cpf(
cpf: str,
user_id: int | None = None,
) -> dict:
"""
Simula uma consulta externa por CPF e garante dados ficticios no banco mock.
Esta funcao existe apenas para a fase local/mock. Quando a API real entrar,
ela deve ser substituida/removida.
"""
cpf_norm = normalize_cpf(cpf)
if not cpf_norm or not is_valid_cpf(cpf_norm):
raise ValueError("CPF invalido para hidratacao mock.")
db = SessionMockLocal()
try:
customer = db.query(Customer).filter(Customer.cpf == cpf_norm).first()
created_customer = False
if not customer:
customer = Customer(**_build_mock_customer_profile(cpf_norm))
db.add(customer)
created_customer = True
linked_user = False
user = None
if user_id is not None:
conflicting_user = (
db.query(User)
.filter(User.cpf == cpf_norm, User.id != user_id)
.first()
)
if conflicting_user:
raise ValueError("cpf_already_linked")
user = db.query(User).filter(User.id == user_id).first()
if user and user.cpf != cpf_norm:
user.cpf = cpf_norm
linked_user = True
db.commit()
db.refresh(customer)
if user is not None:
db.refresh(user)
return {
"cpf": customer.cpf,
"nome": customer.nome,
"score": int(customer.score),
"limite_credito": float(customer.limite_credito),
"possui_restricao": bool(customer.possui_restricao),
"customer_created": created_customer,
"user_linked": linked_user,
}
finally:
db.close()