feat: add demand page modules and admin endpoints
Add full backend support for a demand request page, including: - New database models for demand hero, feature cards, form configuration, and product recommendations - Alembic migration for the new tables - Default seed data for demand page components - Public site config endpoint exposing demand data - Admin CRUD operations and configuration for demand modules - Extended lead query filters for source page, keyword, and date range - Updated Pydantic schemas for lead query parameters - Comprehensive test coverage for all new endpoints
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Literal
|
||||
from pydantic import BaseModel, EmailStr, Field, field_validator
|
||||
from pydantic import BaseModel, EmailStr, Field, ValidationInfo, field_validator
|
||||
|
||||
|
||||
ProductStatus = Literal["draft", "published", "archived"]
|
||||
@@ -115,8 +115,23 @@ class AdminProductQuery(BaseModel):
|
||||
|
||||
class LeadQuery(BaseModel):
|
||||
status: LeadStatus | None = None
|
||||
sourcePage: str | None = None
|
||||
keyword: str | None = None
|
||||
createdFrom: datetime | None = None
|
||||
createdTo: datetime | None = None
|
||||
take: int = Field(default=100, ge=1, le=200)
|
||||
|
||||
@field_validator("createdFrom", "createdTo", mode="before")
|
||||
@classmethod
|
||||
def parse_date_only_range(cls, value, info: ValidationInfo):
|
||||
if isinstance(value, str) and len(value) == 10:
|
||||
try:
|
||||
parsed = datetime.strptime(value, "%Y-%m-%d")
|
||||
return parsed + timedelta(days=1) if info.field_name == "createdTo" else parsed
|
||||
except ValueError:
|
||||
return value
|
||||
return value
|
||||
|
||||
|
||||
class SiteConfigPatchIn(BaseModel):
|
||||
title: str | None = None
|
||||
@@ -135,6 +150,15 @@ class SiteConfigPatchIn(BaseModel):
|
||||
priceAmount: int | None = Field(default=None, ge=0)
|
||||
priceUnit: str | None = None
|
||||
tags: list[str] | None = None
|
||||
steps: list[str] | None = None
|
||||
destinationLabel: str | None = None
|
||||
destinationPlaceholder: str | None = None
|
||||
phoneLabel: str | None = None
|
||||
phonePlaceholder: str | None = None
|
||||
noteLabel: str | None = None
|
||||
notePlaceholder: str | None = None
|
||||
submitLabel: str | None = None
|
||||
chips: list[str] | None = None
|
||||
productIds: list[str] | None = None
|
||||
status: str | None = None
|
||||
startsAt: datetime | None = None
|
||||
|
||||
Reference in New Issue
Block a user