Compare commits
6 Commits
cc02d04097
...
3f1024d342
| Author | SHA1 | Date |
|---|---|---|
|
|
3f1024d342 | 2 months ago |
|
|
c1974d8379 | 2 months ago |
|
|
e0fbca8e1a | 2 months ago |
|
|
772c8d8055 | 2 months ago |
|
|
28d7daccb2 | 2 months ago |
|
|
53ff0d6049 | 2 months ago |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,31 @@
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker, declarative_base
|
||||
|
||||
from app.core.settings import settings
|
||||
|
||||
|
||||
if settings.mock_db_cloud_sql_connection_name:
|
||||
# Cloud SQL MySQL via Unix socket
|
||||
MOCK_DATABASE_URL = (
|
||||
f"mysql+pymysql://{settings.mock_db_user}:{settings.mock_db_password}@/{settings.mock_db_name}"
|
||||
f"?unix_socket=/cloudsql/{settings.mock_db_cloud_sql_connection_name}"
|
||||
)
|
||||
else:
|
||||
MOCK_DATABASE_URL = (
|
||||
f"mysql+pymysql://{settings.mock_db_user}:{settings.mock_db_password}@"
|
||||
f"{settings.mock_db_host}:{settings.mock_db_port}/{settings.mock_db_name}"
|
||||
)
|
||||
|
||||
mock_engine = create_engine(
|
||||
MOCK_DATABASE_URL,
|
||||
pool_pre_ping=True,
|
||||
connect_args={"connect_timeout": 5},
|
||||
)
|
||||
|
||||
SessionMockLocal = sessionmaker(
|
||||
autocommit=False,
|
||||
autoflush=False,
|
||||
bind=mock_engine,
|
||||
)
|
||||
|
||||
MockBase = declarative_base()
|
||||
@ -0,0 +1,54 @@
|
||||
from sqlalchemy import Boolean, Column, DateTime, Float, ForeignKey, Integer, String, Text
|
||||
from sqlalchemy.sql import func
|
||||
|
||||
from app.db.mock_database import MockBase
|
||||
|
||||
|
||||
class Vehicle(MockBase):
|
||||
__tablename__ = "vehicles"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
modelo = Column(String(120), nullable=False)
|
||||
categoria = Column(String(50), nullable=False, index=True)
|
||||
preco = Column(Float, nullable=False, index=True)
|
||||
created_at = Column(DateTime, server_default=func.current_timestamp())
|
||||
|
||||
|
||||
class Customer(MockBase):
|
||||
__tablename__ = "customers"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
cpf = Column(String(11), unique=True, nullable=False, index=True)
|
||||
nome = Column(String(120), nullable=False)
|
||||
score = Column(Integer, nullable=False)
|
||||
limite_credito = Column(Float, nullable=False)
|
||||
possui_restricao = Column(Boolean, nullable=False, default=False)
|
||||
created_at = Column(DateTime, server_default=func.current_timestamp())
|
||||
|
||||
|
||||
class Order(MockBase):
|
||||
__tablename__ = "orders"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
numero_pedido = Column(String(40), unique=True, nullable=False, index=True)
|
||||
cpf = Column(String(11), ForeignKey("customers.cpf"), nullable=False, index=True)
|
||||
status = Column(String(20), nullable=False, default="Ativo")
|
||||
motivo_cancelamento = Column(Text, nullable=True)
|
||||
data_cancelamento = Column(DateTime, nullable=True)
|
||||
created_at = Column(DateTime, server_default=func.current_timestamp())
|
||||
updated_at = Column(
|
||||
DateTime,
|
||||
server_default=func.current_timestamp(),
|
||||
onupdate=func.current_timestamp(),
|
||||
)
|
||||
|
||||
|
||||
class ReviewSchedule(MockBase):
|
||||
__tablename__ = "review_schedules"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
protocolo = Column(String(50), unique=True, nullable=False, index=True)
|
||||
placa = Column(String(10), nullable=False, index=True)
|
||||
data_hora = Column(DateTime, nullable=False)
|
||||
status = Column(String(20), nullable=False, default="agendado")
|
||||
created_at = Column(DateTime, server_default=func.current_timestamp())
|
||||
@ -0,0 +1,96 @@
|
||||
import random
|
||||
from datetime import datetime
|
||||
|
||||
from app.core.settings import settings
|
||||
from app.db.mock_database import SessionMockLocal
|
||||
from app.db.mock_models import Customer, Order, Vehicle
|
||||
|
||||
|
||||
VEHICLE_MODELS = [
|
||||
"Toyota Corolla",
|
||||
"Honda Civic",
|
||||
"Chevrolet Onix",
|
||||
"Hyundai HB20",
|
||||
"Volkswagen T-Cross",
|
||||
"Jeep Compass",
|
||||
"Fiat Argo",
|
||||
"Nissan Kicks",
|
||||
"Renault Duster",
|
||||
"Ford Ranger",
|
||||
]
|
||||
|
||||
CATEGORIES = ["hatch", "sedan", "suv", "pickup"]
|
||||
NAMES = [
|
||||
"Ana Souza",
|
||||
"Bruno Lima",
|
||||
"Carla Mendes",
|
||||
"Diego Santos",
|
||||
"Eduarda Alves",
|
||||
"Felipe Rocha",
|
||||
"Gabriela Costa",
|
||||
"Henrique Martins",
|
||||
"Isabela Ferreira",
|
||||
"Joao Ribeiro",
|
||||
]
|
||||
|
||||
|
||||
def _cpf_from_index(index: int) -> str:
|
||||
return str(10_000_000_000 + index).zfill(11)
|
||||
|
||||
|
||||
def seed_mock_data() -> None:
|
||||
if not settings.mock_seed_enabled:
|
||||
return
|
||||
|
||||
rng = random.Random(42)
|
||||
db = SessionMockLocal()
|
||||
try:
|
||||
if db.query(Vehicle).count() == 0:
|
||||
vehicles = []
|
||||
for idx in range(60):
|
||||
model = VEHICLE_MODELS[idx % len(VEHICLE_MODELS)]
|
||||
category = CATEGORIES[idx % len(CATEGORIES)]
|
||||
base_price = 55_000 + (idx * 1_700)
|
||||
noise = rng.randint(-7_000, 9_000)
|
||||
vehicles.append(
|
||||
Vehicle(
|
||||
modelo=f"{model} {2020 + (idx % 6)}",
|
||||
categoria=category,
|
||||
preco=float(max(35_000, base_price + noise)),
|
||||
)
|
||||
)
|
||||
db.add_all(vehicles)
|
||||
db.commit()
|
||||
|
||||
if db.query(Customer).count() == 0:
|
||||
customers = []
|
||||
for idx in range(120):
|
||||
entropy = (idx * 9973) % 10_000
|
||||
customers.append(
|
||||
Customer(
|
||||
cpf=_cpf_from_index(idx),
|
||||
nome=f"{NAMES[idx % len(NAMES)]} {idx + 1}",
|
||||
score=300 + (entropy % 550),
|
||||
limite_credito=float(30_000 + (entropy * 12)),
|
||||
possui_restricao=(idx % 11 == 0),
|
||||
)
|
||||
)
|
||||
db.add_all(customers)
|
||||
db.commit()
|
||||
|
||||
if db.query(Order).count() == 0:
|
||||
orders = []
|
||||
for idx in range(40):
|
||||
created = datetime(2026, 1, 1, 8, 0, 0)
|
||||
orders.append(
|
||||
Order(
|
||||
numero_pedido=f"PED-{2026}{idx + 1:05d}",
|
||||
cpf=_cpf_from_index(idx),
|
||||
status="Ativo",
|
||||
created_at=created,
|
||||
)
|
||||
)
|
||||
db.add_all(orders)
|
||||
db.commit()
|
||||
finally:
|
||||
db.close()
|
||||
@ -1,57 +0,0 @@
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
import httpx
|
||||
|
||||
from app.core.settings import settings
|
||||
|
||||
|
||||
class FakerApiClient:
|
||||
def __init__(
|
||||
self,
|
||||
base_url: Optional[str] = None,
|
||||
locale: Optional[str] = None,
|
||||
seed: Optional[int] = None,
|
||||
):
|
||||
self.base_url = (base_url or settings.fakerapi_base_url).rstrip("/")
|
||||
self.locale = locale or settings.fakerapi_locale
|
||||
self.seed = settings.fakerapi_seed if seed is None else seed
|
||||
|
||||
async def fetch_resource(
|
||||
self,
|
||||
resource: str,
|
||||
quantity: int,
|
||||
extra_params: Optional[Dict[str, Any]] = None,
|
||||
) -> List[Dict[str, Any]]:
|
||||
url = f"{self.base_url}/{resource.lstrip('/')}"
|
||||
params: Dict[str, Any] = {
|
||||
"_quantity": quantity,
|
||||
"_locale": self.locale,
|
||||
"_seed": self.seed,
|
||||
}
|
||||
if extra_params:
|
||||
params.update(extra_params)
|
||||
|
||||
timeout = httpx.Timeout(connect=5.0, read=15.0, write=10.0, pool=5.0)
|
||||
headers = {
|
||||
"Accept": "application/json",
|
||||
"User-Agent": "orquestrador-fakerapi-client/1.0",
|
||||
}
|
||||
async with httpx.AsyncClient(timeout=timeout, headers=headers) as client:
|
||||
try:
|
||||
response = await client.get(url, params=params)
|
||||
response.raise_for_status()
|
||||
payload = response.json()
|
||||
except httpx.ReadTimeout:
|
||||
# Retry once with smaller payload to reduce timeout risk in free/public APIs.
|
||||
reduced_quantity = min(quantity, 20)
|
||||
retry_params = dict(params)
|
||||
retry_params["_quantity"] = reduced_quantity
|
||||
response = await client.get(url, params=retry_params)
|
||||
response.raise_for_status()
|
||||
payload = response.json()
|
||||
|
||||
if isinstance(payload, dict) and isinstance(payload.get("data"), list):
|
||||
return payload["data"]
|
||||
if isinstance(payload, list):
|
||||
return payload
|
||||
return []
|
||||
Binary file not shown.
Loading…
Reference in New Issue