from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy import select from sqlalchemy.orm import Session from .shared import site_config from ..auth import create_customer_token, require_customer from ..database import get_db from ..models import Customer, Lead from ..schemas import LeadCreateIn, PhoneLoginIn from ..wechat import WechatApiError, WechatConfigError, exchange_phone_code router = APIRouter() def mask_phone(phone: str) -> str: normalized = phone.strip() if len(normalized) <= 7: return "***" return f"{normalized[:3]}****{normalized[-4:]}" def public_customer_dict(customer: Customer) -> dict: return {"id": customer.id, "phoneMasked": mask_phone(customer.phone)} @router.get("/health") def health(): return {"ok": True, "service": "miniapp-api"} @router.get("/api/public/site-config") def get_site_config(db: Session = Depends(get_db)): return site_config(db, active_only=True) @router.post("/api/public/auth/phone-login") def phone_login(body: PhoneLoginIn, db: Session = Depends(get_db)): try: phone = exchange_phone_code(body.code) except WechatConfigError as exc: raise HTTPException(status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail=str(exc)) from exc except WechatApiError as exc: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc customer = db.scalar(select(Customer).where(Customer.phone == phone)) if not customer: customer = Customer(phone=phone) db.add(customer) db.flush() db.commit() db.refresh(customer) return {"token": create_customer_token(customer), "customer": public_customer_dict(customer)} @router.get("/api/public/auth/me") def current_customer(customer: Customer = Depends(require_customer)): return public_customer_dict(customer) @router.post("/api/public/leads", status_code=status.HTTP_201_CREATED) def create_lead(body: LeadCreateIn, db: Session = Depends(get_db)): lead = Lead(**body.model_dump(exclude_none=True), status="new") db.add(lead) db.commit() db.refresh(lead) return {"id": lead.id, "status": lead.status}