""" HR Portal Backend API FastAPI 主應用程式 """ import traceback from fastapi import FastAPI, Request from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse from app.core.config import settings from app.core.logging_config import setup_logging from app.db.session import get_engine from app.db.base import Base # 設置日誌 setup_logging() # 創建 FastAPI 應用 app = FastAPI( title=settings.PROJECT_NAME, version=settings.VERSION, description="HR Portal - 人力資源管理系統 API", docs_url="/docs", redoc_url="/redoc", openapi_url="/openapi.json", ) # CORS 設定 app.add_middleware( CORSMiddleware, allow_origins=settings.get_allowed_origins(), allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # 全局異常處理器 @app.exception_handler(Exception) async def global_exception_handler(request: Request, exc: Exception): """全局異常處理器 - 記錄所有未捕獲的異常""" print(f"\n{'=' * 80}") print(f"[ERROR] Unhandled Exception in {request.method} {request.url.path}") print(f"Exception Type: {type(exc).__name__}") print(f"Exception Message: {str(exc)}") print(f"Traceback:") print(traceback.format_exc()) print(f"{'=' * 80}\n") return JSONResponse( status_code=500, content={ "detail": str(exc), "type": type(exc).__name__, "path": request.url.path } ) # 啟動事件 @app.on_event("startup") async def startup_event(): """應用啟動時執行""" # 資料庫表格由 Alembic 管理,不需要在啟動時創建 print(f"[OK] {settings.PROJECT_NAME} v{settings.VERSION} started!") print(f"[*] Environment: {settings.ENVIRONMENT}") print(f"[*] API Documentation: http://{settings.HOST}:{settings.PORT}/docs") # 關閉事件 @app.on_event("shutdown") async def shutdown_event(): """應用關閉時執行""" print(f"[*] {settings.PROJECT_NAME} stopped") # 健康檢查端點 @app.get("/health", tags=["Health"]) async def health_check(): """健康檢查""" return JSONResponse( content={ "status": "healthy", "service": settings.PROJECT_NAME, "version": settings.VERSION, "environment": settings.ENVIRONMENT, } ) # 根路徑 @app.get("/", tags=["Root"]) async def root(): """根路徑""" return { "message": f"Welcome to {settings.PROJECT_NAME}", "version": settings.VERSION, "docs": "/docs", "redoc": "/redoc", } # 導入並註冊 API 路由 from app.api.v1.router import api_router app.include_router(api_router, prefix="/api/v1")