"""FastAPI application entry point.""" import logging from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from .auth import get_password_hash from .config import settings from .database import SessionLocal, create_tables from .models.db_models import SystemSetting logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) def _init_admin_and_defaults() -> None: """Initialize admin password hash and default settings.""" db = SessionLocal() try: # Store admin password hash existing = ( db.query(SystemSetting) .filter(SystemSetting.key == "admin_password_hash") .first() ) if not existing: hashed = get_password_hash(settings.ADMIN_PASSWORD) db.add(SystemSetting(key="admin_password_hash", value=hashed, encrypted=True)) logger.info("Admin user initialized.") # Store Airwallex credentials from env if provided for key, env_val in [ ("airwallex_client_id", settings.AIRWALLEX_CLIENT_ID), ("airwallex_api_key", settings.AIRWALLEX_API_KEY), ("airwallex_base_url", settings.AIRWALLEX_BASE_URL), ]: if env_val: s = db.query(SystemSetting).filter(SystemSetting.key == key).first() if not s: db.add(SystemSetting(key=key, value=env_val, encrypted=(key == "airwallex_api_key"))) # Default daily card limit if not db.query(SystemSetting).filter(SystemSetting.key == "daily_card_limit").first(): db.add(SystemSetting(key="daily_card_limit", value="100")) db.commit() finally: db.close() @asynccontextmanager async def lifespan(app: FastAPI): """Startup and shutdown logic.""" create_tables() _init_admin_and_defaults() logger.info("Application started.") yield logger.info("Application shutting down.") app = FastAPI( title="Airwallex Card Management", version="1.0.0", lifespan=lifespan, ) # CORS - allow all origins for development app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # --- Mount routers (each router defines its own prefix) --- from .routers import auth as auth_router from .routers import cards as cards_router from .routers import cardholders as cardholders_router from .routers import dashboard as dashboard_router from .routers import settings as settings_router from .routers import logs as logs_router from .routers import tokens as tokens_router from .routers import transactions as transactions_router from .routers import external_api as external_api_router app.include_router(auth_router.router) app.include_router(dashboard_router.router) app.include_router(cards_router.router) app.include_router(cardholders_router.router) app.include_router(transactions_router.router) app.include_router(settings_router.router) app.include_router(tokens_router.router) app.include_router(logs_router.router) app.include_router(external_api_router.router) # --- Health check --- @app.get("/api/health") async def health_check(): """Simple health check endpoint.""" return {"status": "ok"}