feat: add appointments, campaigns, admin, storage, tests and various updates

- Add new routers: admin, appointments, campaigns
- Add storage service and logging config
- Add migrations directory and test suite with pytest config
- Add supabase_migration_features.sql
- Update models, dependencies, config, and existing routers
- Remove whatsapp_service (deleted)
- Update pyproject.toml and uv.lock dependencies

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
belviskhoremk
2026-04-03 09:11:58 +00:00
parent 9dccc83293
commit 92d4c2fc5e
51 changed files with 7076 additions and 515 deletions

View File

@@ -4,17 +4,18 @@ from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse, Response
import logging
from app.logging_config import configure_logging
configure_logging() # Must be called before any logger is created
from app.config import settings
from app.routers import auth, chatbots, documents, chat, marketplace, billing, models, analytics, inbox, leads, upload
from app.routers.documents import router_url_sources
from app.routers.leads import leads_public_router
from app.routers.channels import router as channels_router, webhook_router as channels_webhook_router
from app.routers import admin as admin_router
from app.routers.appointments import router as appointments_router, public_router as appointments_public_router
from app.routers.campaigns import router as campaigns_router
# Configure logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
)
logger = logging.getLogger(__name__)
@@ -62,13 +63,28 @@ app.include_router(router_url_sources, prefix="/api/v1")
app.include_router(leads_public_router, prefix="/api/v1")
app.include_router(channels_router, prefix="/api/v1")
app.include_router(channels_webhook_router, prefix="/api/v1")
app.include_router(appointments_router, prefix="/api/v1")
app.include_router(appointments_public_router, prefix="/api/v1")
app.include_router(campaigns_router, prefix="/api/v1")
app.include_router(admin_router.router, prefix="/api/v1")
# ── Widget ─────────────────────────────────────────────────────────────────────
@app.get("/widget.js")
@app.get("/widget.js", include_in_schema=False)
async def serve_widget():
from app.services.widget import generate_widget_js
return Response(generate_widget_js(settings.app_url), media_type="application/javascript")
return Response(
content=generate_widget_js(settings.app_url),
media_type="application/javascript",
headers={
# Allow any site to load this script tag cross-origin
"Access-Control-Allow-Origin": "*",
# Cache for 1 hour in browsers / CDN; revalidate when stale
"Cache-Control": "public, max-age=3600, stale-while-revalidate=86400",
# Prevent MIME sniffing
"X-Content-Type-Options": "nosniff",
},
)
# ── Health & Info ──────────────────────────────────────────────────────────────
@@ -87,6 +103,15 @@ async def health():
return {"status": "healthy", "environment": settings.app_env}
# ── Prometheus Metrics ──────────────────────────────────────────────────────────
try:
from prometheus_fastapi_instrumentator import Instrumentator
Instrumentator().instrument(app).expose(app, endpoint="/metrics", include_in_schema=False)
logger.info("Prometheus metrics enabled at /metrics")
except ImportError:
logger.info("prometheus-fastapi-instrumentator not installed, metrics endpoint disabled")
# ── Sentry ─────────────────────────────────────────────────────────────────────
if settings.sentry_dsn:
import sentry_sdk