from contextlib import asynccontextmanager from fastapi import Depends, FastAPI from fastapi.middleware.cors import CORSMiddleware from sqlalchemy import select, text from sqlalchemy.orm import Session from .config import settings from .database import Base, engine, get_db from .auth import current_user from .models import ActivityEvent, UserAccount from .routes_admin import router as admin_router from .routes_api_keys import router as api_keys_router from .routes_auth import router as auth_router from .routes_compliance import router as compliance_router from .routes_dlt import router as dlt_router from .routes_kyc import router as kyc_router from .routes_analytics import router as analytics_router from .routes_logs import router as logs_router from .routes_otp import router as otp_router from .routes_messages import router as messages_router from .routes_messaging import router as messaging_router from .routes_campaigns import router as campaigns_router from .routes_integrations import router as integrations_router from .routes_numbers import router as numbers_router from .routes_urmiotp import router as urmiotp_router from .routes_voice import router as voice_router from .routes_whatsapp import router as whatsapp_router @asynccontextmanager async def lifespan(_: FastAPI): Base.metadata.create_all(bind=engine) with engine.begin() as conn: conn.execute( text( "ALTER TABLE urmiotp_projects " "ADD COLUMN IF NOT EXISTS message_label VARCHAR(20) NOT NULL DEFAULT 'URMI'" ) ) conn.execute( text( "ALTER TABLE phone_numbers " "ADD COLUMN IF NOT EXISTS monthly_number_price NUMERIC(10,2) NOT NULL DEFAULT 0" ) ) conn.execute( text( "ALTER TABLE phone_numbers " "ADD COLUMN IF NOT EXISTS monthly_inbound_price NUMERIC(10,2) NOT NULL DEFAULT 0" ) ) conn.execute( text( "ALTER TABLE phone_numbers " "ADD COLUMN IF NOT EXISTS monthly_outbound_price NUMERIC(10,2) NOT NULL DEFAULT 0" ) ) yield app = FastAPI( title=settings.app_name, version="0.1.0", lifespan=lifespan, docs_url="/docs", ) app.add_middleware( CORSMiddleware, allow_origins=settings.cors_allowed_origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.include_router(auth_router) app.include_router(kyc_router) app.include_router(dlt_router) app.include_router(compliance_router) app.include_router(messaging_router) app.include_router(api_keys_router) app.include_router(messages_router) app.include_router(otp_router) app.include_router(logs_router) app.include_router(analytics_router) app.include_router(urmiotp_router) app.include_router(campaigns_router) app.include_router(numbers_router) app.include_router(integrations_router) app.include_router(voice_router) app.include_router(whatsapp_router) app.include_router(admin_router) @app.get("/health") def health(db: Session = Depends(get_db)) -> dict[str, str]: db.execute(text("SELECT 1")) return {"status": "healthy", "service": settings.app_name} @app.get("/api/v1/dashboard") def dashboard( db: Session = Depends(get_db), _: UserAccount = Depends(current_user), ) -> dict: events = db.scalars( select(ActivityEvent).order_by(ActivityEvent.occurred_at.desc()).limit(8) ).all() return { "metrics": { "voice_calls": 1243, "messages_sent": 45231, "delivery_rate": 98.7, "api_requests": 1_200_000, "balance": 24820, }, "activity": [ { "id": str(event.id), "type": event.event_type, "title": event.title, "detail": event.detail, "status": event.status, "occurred_at": event.occurred_at, } for event in events ], }