"""Billing Service — FastAPI application. Owns: Stripe checkout/webhook, subscription management, tier feature matrix, quota enforcement. Downstream services query this service (or read the user's tier from the X-User-Tier header injected by Traefik) for billing decisions. The webhook endpoint is exposed WITHOUT ForwardAuth so Stripe can reach it. """ from __future__ import annotations import logging import sys from contextlib import asynccontextmanager from pathlib import Path from typing import AsyncGenerator # Ensure the repo root is on sys.path so "shared" is importable in local dev. _repo_root = str(Path(__file__).resolve().parents[3]) if _repo_root not in sys.path: sys.path.insert(0, _repo_root) from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from app.routes import router logger = logging.getLogger(__name__) @asynccontextmanager async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: logger.info("billing: service started") yield logger.info("billing: service stopped") app = FastAPI(title="Adiuva Billing Service", lifespan=lifespan) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["GET", "POST", "DELETE"], allow_headers=["*"], ) app.include_router(router) @app.get("/health") async def health() -> dict[str, str]: return {"status": "ok", "service": "billing"}