urmi-ai/backend/app/main.py
2026-10-15 01:58:00 +05:30

157 lines
5.8 KiB
Python

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
from .routes_whatsapp_templates import router as whatsapp_templates_router
from .routes_meta import router as meta_router
from .routes_agent_templates import router as agent_templates_router
from .routes_agent_messages import router as agent_messages_router
from .routes_urmiport import router as urmiport_router
from .routes_urmiport_api import router as urmiport_api_router
from .agent_templates_seed import seed_agent_message_templates
from .whatsapp_broadcast_jobs import resume_broadcast_jobs
@asynccontextmanager
async def lifespan(_: FastAPI):
Base.metadata.create_all(bind=engine)
resume_broadcast_jobs()
with Session(engine) as db:
seed_agent_message_templates(db)
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"
)
)
conn.execute(
text(
"ALTER TABLE whatsapp_phone_assets "
"ADD COLUMN IF NOT EXISTS two_step_pin VARCHAR(6)"
)
)
conn.execute(text("ALTER TABLE whatsapp_messages ADD COLUMN IF NOT EXISTS user_id UUID"))
conn.execute(text("ALTER TABLE whatsapp_messages ADD COLUMN IF NOT EXISTS phone_number_id VARCHAR(64)"))
conn.execute(text("ALTER TABLE whatsapp_messages ADD COLUMN IF NOT EXISTS contact_name VARCHAR(200)"))
conn.execute(text("ALTER TABLE whatsapp_meta_connections ADD COLUMN IF NOT EXISTS meta_app_id VARCHAR(64)"))
conn.execute(text("ALTER TABLE whatsapp_meta_connections ADD COLUMN IF NOT EXISTS meta_app_secret TEXT"))
conn.execute(text("CREATE INDEX IF NOT EXISTS ix_whatsapp_messages_user_id ON whatsapp_messages (user_id)"))
conn.execute(text("CREATE INDEX IF NOT EXISTS ix_whatsapp_messages_phone_number_id ON whatsapp_messages (phone_number_id)"))
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(whatsapp_templates_router)
app.include_router(meta_router)
app.include_router(agent_templates_router)
app.include_router(agent_messages_router)
app.include_router(urmiport_router)
app.include_router(urmiport_api_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
],
}