Добавляет endpoint для приёма заявок на пилот (lead-gen).
INSERT в pilot_requests, response {id, created_at, status}.
Telegram-уведомление — TODO (creds не настроены, #307 SF-B3).
Migration: data/sql/118_pilot_requests.sql
74 lines
2.3 KiB
Python
74 lines
2.3 KiB
Python
"""Pilot request lead-gen endpoint.
|
||
|
||
POST /api/v1/pilot/request — принимает заявку на пилот (лид с лендинга или страницы анализа),
|
||
сохраняет в таблицу pilot_requests.
|
||
Telegram-уведомление — TODO (creds не настроены, см. #307 SF-B3).
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import logging
|
||
from typing import Annotated, Any, Literal
|
||
|
||
from fastapi import APIRouter, Depends, Request
|
||
from pydantic import BaseModel, EmailStr, Field
|
||
from sqlalchemy import text
|
||
from sqlalchemy.orm import Session
|
||
|
||
from app.core.db import get_db
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
router = APIRouter()
|
||
|
||
|
||
class PilotRequestInput(BaseModel):
|
||
name: str = Field(min_length=2, max_length=200)
|
||
phone: str | None = Field(default=None, max_length=50)
|
||
email: EmailStr | None = None
|
||
company: str | None = Field(default=None, max_length=200)
|
||
message: str | None = Field(default=None, max_length=2000)
|
||
source: Literal["landing", "analyze_page", "other"] = "landing"
|
||
|
||
|
||
@router.post("/request")
|
||
async def create_pilot_request(
|
||
payload: PilotRequestInput,
|
||
request: Request,
|
||
db: Annotated[Session, Depends(get_db)],
|
||
) -> dict[str, Any]:
|
||
"""Сохраняет заявку на пилот в pilot_requests."""
|
||
user_agent = request.headers.get("user-agent")
|
||
|
||
row = (
|
||
db.execute(
|
||
text(
|
||
"""
|
||
INSERT INTO pilot_requests (name, phone, email, company, message, source, user_agent)
|
||
VALUES (:name, :phone, :email, :company, :message, :source, :user_agent)
|
||
RETURNING CAST(id AS text), created_at
|
||
"""
|
||
),
|
||
{
|
||
"name": payload.name,
|
||
"phone": payload.phone,
|
||
"email": str(payload.email) if payload.email else None,
|
||
"company": payload.company,
|
||
"message": payload.message,
|
||
"source": payload.source,
|
||
"user_agent": user_agent,
|
||
},
|
||
)
|
||
.mappings()
|
||
.one()
|
||
)
|
||
|
||
db.commit()
|
||
|
||
logger.info("pilot_request saved id=%s source=%s", row["id"], payload.source)
|
||
|
||
return {
|
||
"id": row["id"],
|
||
"created_at": row["created_at"].isoformat(),
|
||
"status": "received",
|
||
}
|