- frontend/api.js: API URL 自動判斷 (localhost=dev, 其他=相對路徑 /api/v1) - main.py: 加入 StaticFiles 掛載 admin-portal,CORS 開放 - schedule_tenant: Traefik 路由範本更新 - 管理租戶加入 /api 路由 (priority 200) - /admin 加入 StripPrefix middleware - admin 服務改指向 vmis-backend:10281 - docker/vmis: 新增 Dockerfile + docker-compose.yml Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
54 lines
1.3 KiB
Python
54 lines
1.3 KiB
Python
import os
|
||
from contextlib import asynccontextmanager
|
||
from fastapi import FastAPI
|
||
from fastapi.middleware.cors import CORSMiddleware
|
||
from fastapi.staticfiles import StaticFiles
|
||
|
||
from app.core.database import SessionLocal
|
||
from app.services.seed import seed_initial_data
|
||
from app.services.scheduler.watchdog import start_watchdog, stop_watchdog
|
||
from app.api.v1.router import api_router
|
||
|
||
|
||
@asynccontextmanager
|
||
async def lifespan(app: FastAPI):
|
||
# Startup
|
||
db = SessionLocal()
|
||
try:
|
||
seed_initial_data(db)
|
||
finally:
|
||
db.close()
|
||
start_watchdog()
|
||
yield
|
||
# Shutdown
|
||
stop_watchdog()
|
||
|
||
|
||
app = FastAPI(
|
||
title="Virtual MIS API",
|
||
version="2.0.0",
|
||
description="SaaS 虛擬 MIS 平台管理後端",
|
||
lifespan=lifespan,
|
||
)
|
||
|
||
app.add_middleware(
|
||
CORSMiddleware,
|
||
allow_origins=["*"],
|
||
allow_credentials=True,
|
||
allow_methods=["*"],
|
||
allow_headers=["*"],
|
||
)
|
||
|
||
app.include_router(api_router, prefix="/api/v1")
|
||
|
||
|
||
@app.get("/health")
|
||
def health():
|
||
return {"status": "ok", "service": "vmis-backend"}
|
||
|
||
|
||
# 靜態前端(admin portal)— 掛載在最後,讓 API 路由優先
|
||
_frontend_dir = os.path.join(os.path.dirname(__file__), "..", "frontend")
|
||
if os.path.isdir(_frontend_dir):
|
||
app.mount("/", StaticFiles(directory=_frontend_dir, html=True), name="frontend")
|