- FastAPI backend: PostGIS estimator + 3 scrapers (Avito/Cian/Yandex)
- Next.js 15 frontend: tradein.html mockup design, basePath=/trade-in
- WeasyPrint PDF (Брусника-style 4-page report)
- Address autocomplete с typo-tolerance + 6 EKB presets
- Изолированный docker stack gendesign-tradein (отдельная postgres БД)
- Caddy inline routes: gendsgn.ru/trade-in/* и /trade-in/api/v1/*
- Forgejo Actions: .forgejo/workflows/deploy-tradein.yml (shell-based GHCR login)
- Триггер только по paths: tradein-mvp/** (не пересекается с deploy.yml)
- Образы: ghcr.io/lekss361/gendesign-tradein-{backend,frontend}:latest
Первый запуск на сервере (вручную, один раз):
- создать /opt/gendesign/tradein-mvp/.env.runtime (postgres pwd, contact email)
- docker network create gendesign_shared (если нет)
- docker compose -p gendesign-tradein up -d
- docker compose -p gendesign exec caddy caddy reload
45 lines
1.4 KiB
Python
45 lines
1.4 KiB
Python
"""Trade-In MVP — FastAPI entry point.
|
|
|
|
Standalone версия, выделена из основного gendesign repo для локальной разработки.
|
|
Только trade-in фича; никаких других роутеров (concepts/parcels/analytics/etc) нет.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
from fastapi import FastAPI
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
|
|
from app.api.v1 import admin, brand, geocode, trade_in
|
|
from app.core.config import settings
|
|
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format="%(asctime)s %(levelname)s %(name)s: %(message)s",
|
|
)
|
|
|
|
app = FastAPI(
|
|
title="Trade-In MVP API",
|
|
description="Оценка вторичного жилья (выкупная стоимость) — копия trade-in feature из gendesign",
|
|
version="0.1.0",
|
|
)
|
|
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=settings.cors_origins,
|
|
allow_credentials=True,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
|
|
@app.get("/health")
|
|
def health() -> dict[str, str]:
|
|
return {"status": "ok", "environment": settings.environment}
|
|
|
|
|
|
app.include_router(geocode.router, prefix="/api/v1/geocode", tags=["geocode"])
|
|
app.include_router(admin.router, prefix="/api/v1/admin", tags=["admin"])
|
|
app.include_router(brand.router, prefix="/api/v1/brand", tags=["brand"])
|
|
app.include_router(trade_in.router, prefix="/api/v1/trade-in", tags=["trade-in"])
|