TorbatYar/backend/core-service/app/main.py
Mortezakoohjani 800b0ba2c5 Deploy TorbatYar for torbatyar.ir with nginx multi-tenant routing.
Wire production domain, CORS for tenant subdomains, celery volume mounts, and nginx reverse proxy configs for apex, API, identity, auth, and wildcard tenants.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 21:43:33 +03:30

85 lines
2.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""نقطه ورود برنامه FastAPI برای Core Platform Service."""
from __future__ import annotations
from contextlib import asynccontextmanager
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from app import __version__
from app.api.v1 import api_router, health
from app.core.cache import cache
from app.core.config import settings
from app.core.logging import configure_logging, get_logger
from app.middlewares.tenant import TenantResolutionMiddleware
from shared.exceptions import AppError
from shared.responses import ErrorDetail, ErrorResponse
configure_logging()
logger = get_logger(__name__)
@asynccontextmanager
async def lifespan(app: FastAPI):
logger.info("service_starting", extra={"service": settings.service_name})
yield
await cache.close()
logger.info("service_stopped")
def create_app() -> FastAPI:
app = FastAPI(
title=f"{settings.platform_name} - Core Platform Service",
version=__version__,
description="سرویس هسته پلتفرم SaaS چندمستأجری (فاز ۱).",
lifespan=lifespan,
)
# CORS - در production باید origins محدود شود.
# allow_origin_regex برای ساب‌دامین tenantها (<slug>.torbatyar.ir)
app.add_middleware(
CORSMiddleware,
allow_origins=settings.cors_origin_list,
allow_origin_regex=r"https?://([a-z0-9-]+\.)*torbatyar\.ir",
allow_credentials=False,
allow_methods=["*"],
allow_headers=["*"],
)
# Middleware تشخیص tenant.
app.add_middleware(
TenantResolutionMiddleware, base_domain=settings.platform_base_domain or None
)
# ثبت exception handlerها برای تبدیل خطاهای دامنه به پاسخ استاندارد.
_register_exception_handlers(app)
# routerها
app.include_router(health.router)
app.include_router(api_router, prefix=settings.api_v1_prefix)
return app
def _register_exception_handlers(app: FastAPI) -> None:
@app.exception_handler(AppError)
async def app_error_handler(request: Request, exc: AppError) -> JSONResponse:
response = ErrorResponse(
error=ErrorDetail(
code=exc.error_code, message=exc.message, details=exc.details
)
)
return JSONResponse(status_code=exc.status_code, content=response.model_dump())
@app.exception_handler(Exception)
async def unhandled_handler(request: Request, exc: Exception) -> JSONResponse:
logger.error("unhandled_exception", extra={"error": str(exc)}, exc_info=exc)
response = ErrorResponse(
error=ErrorDetail(code="internal_error", message="خطای داخلی سرور")
)
return JSONResponse(status_code=500, content=response.model_dump())
app = create_app()