Add Polaris FastAPI backend: models/schemas, pricing+scoring+order router, importer, Celery tasks, API routers, seed script
This commit is contained in:
140
backend/app/schemas.py
Normal file
140
backend/app/schemas.py
Normal file
@@ -0,0 +1,140 @@
|
||||
"""Pydantic v2 request/response schemas."""
|
||||
from datetime import datetime
|
||||
from typing import Any, List, Optional
|
||||
from uuid import UUID
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
|
||||
class ORMModel(BaseModel):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
# ── auth ────────────────────────────────────────────────────────────────
|
||||
class LoginRequest(BaseModel):
|
||||
email: str
|
||||
password: str
|
||||
|
||||
|
||||
class TokenResponse(BaseModel):
|
||||
access_token: str
|
||||
token_type: str = "bearer"
|
||||
|
||||
|
||||
class CustomerRegister(BaseModel):
|
||||
email: str
|
||||
name: Optional[str] = None
|
||||
shipping_addr: Optional[dict] = None
|
||||
# NOTE: customers table has no password column — password (if sent) is not
|
||||
# stored. Customer identity for MVP is email-only; TODO: add password column + hash.
|
||||
password: Optional[str] = None
|
||||
|
||||
|
||||
# ── products ────────────────────────────────────────────────────────────
|
||||
class ProductOut(ORMModel):
|
||||
id: UUID
|
||||
sku: str
|
||||
title: str
|
||||
description: Optional[str] = None
|
||||
category: Optional[str] = None
|
||||
brand: Optional[str] = None
|
||||
manufacturer: Optional[str] = None
|
||||
images: Any = None
|
||||
weight_grams: Optional[float] = None
|
||||
cost: float
|
||||
retail_price: Optional[float] = None
|
||||
min_price: Optional[float] = None
|
||||
max_price: Optional[float] = None
|
||||
status: str
|
||||
created_at: Optional[datetime] = None
|
||||
updated_at: Optional[datetime] = None
|
||||
|
||||
|
||||
class ImportRequest(BaseModel):
|
||||
supplier_id: UUID
|
||||
feed_type: str = "csv"
|
||||
data_or_url: str = ""
|
||||
|
||||
|
||||
class PriceHistoryOut(ORMModel):
|
||||
price: float
|
||||
reason: Optional[str] = None
|
||||
created_at: Optional[datetime] = None
|
||||
|
||||
|
||||
# ── suppliers ───────────────────────────────────────────────────────────
|
||||
class SupplierCreate(BaseModel):
|
||||
name: str
|
||||
adapter_type: str = "csv"
|
||||
api_endpoint: Optional[str] = None
|
||||
account_id: Optional[str] = None
|
||||
fulfillment_caps: dict = {}
|
||||
shipping_regions: List[str] = []
|
||||
reliability_score: float = 50.0
|
||||
status: str = "active"
|
||||
|
||||
|
||||
class SupplierOut(ORMModel):
|
||||
id: UUID
|
||||
name: str
|
||||
adapter_type: str
|
||||
api_endpoint: Optional[str] = None
|
||||
fulfillment_caps: Any = None
|
||||
shipping_regions: Any = None
|
||||
reliability_score: float
|
||||
status: str
|
||||
created_at: Optional[datetime] = None
|
||||
|
||||
|
||||
class SupplierPerformanceOut(BaseModel):
|
||||
supplier_id: UUID
|
||||
supplier_name: str
|
||||
fulfillment_rate: float
|
||||
avg_shipping_days: Optional[float] = None
|
||||
cancellation_rate: float
|
||||
stock_accuracy: float
|
||||
return_rate: float
|
||||
updated_at: Optional[datetime] = None
|
||||
|
||||
|
||||
# ── customers ───────────────────────────────────────────────────────────
|
||||
class CustomerOut(ORMModel):
|
||||
id: UUID
|
||||
email: str
|
||||
name: Optional[str] = None
|
||||
shipping_addr: Any = None
|
||||
created_at: Optional[datetime] = None
|
||||
|
||||
|
||||
# ── orders ──────────────────────────────────────────────────────────────
|
||||
class OrderItemIn(BaseModel):
|
||||
product_id: UUID
|
||||
qty: int = Field(ge=1)
|
||||
|
||||
|
||||
class OrderCreate(BaseModel):
|
||||
customer_email: str
|
||||
items: List[OrderItemIn] = Field(min_length=1)
|
||||
|
||||
|
||||
class OrderOut(ORMModel):
|
||||
id: UUID
|
||||
order_number: str
|
||||
customer_id: Optional[UUID] = None
|
||||
items: Any
|
||||
retail_total: float
|
||||
supplier_id: Optional[UUID] = None
|
||||
supplier_cost: float
|
||||
shipping_cost: float
|
||||
fees: float
|
||||
profit: float
|
||||
status: str
|
||||
tracking: Optional[str] = None
|
||||
carrier: Optional[str] = None
|
||||
created_at: Optional[datetime] = None
|
||||
updated_at: Optional[datetime] = None
|
||||
|
||||
|
||||
class TrackingIn(BaseModel):
|
||||
tracking: str
|
||||
carrier: Optional[str] = None
|
||||
Reference in New Issue
Block a user