feat: expand AI workflow support and refresh docs

This commit is contained in:
2026-03-12 13:47:42 +08:00
parent 8688422578
commit 4ecab597f4
28 changed files with 4806 additions and 1907 deletions

View File

@@ -2,18 +2,39 @@ from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
import os
import logging
from app.core.config import settings
from app.api.v1 import auth, client, admin, analytics, admin_config, feature, checkin, user_profile, stats, algorithm, logs, ai_chat
from app.api.v1 import (
auth,
client,
admin,
analytics,
admin_config,
feature,
checkin,
user_profile,
stats,
algorithm,
logs,
ai_chat,
ai_pattern,
ai_identify,
)
from app.db import init_db
from datetime import datetime
from pathlib import Path
app = FastAPI(title=settings.PROJECT_NAME)
log = logging.getLogger("designercep.startup")
SERVER_DIR = Path(__file__).resolve().parents[2]
ARCHIVES_DIR = SERVER_DIR / "archives"
# Ensure archives directory exists
os.makedirs("archives", exist_ok=True)
os.makedirs(ARCHIVES_DIR, exist_ok=True)
# ========== CORS 配置 ==========
IS_DEV = os.getenv("ENV", "development") == "development"
IS_DEV = settings.ENV == "development"
if IS_DEV:
# 开发环境:保持宽松
@@ -27,9 +48,9 @@ if IS_DEV:
)
else:
# 生产环境:严格配置
allowed_origins = os.getenv("ALLOWED_ORIGINS", "").split(",")
allowed_origins = settings.ALLOWED_ORIGINS.split(",")
print(f"🔒 Running in Production Mode: CORS allowed origins: {allowed_origins}")
app.add_middleware(
CORSMiddleware,
allow_origins=allowed_origins,
@@ -37,63 +58,93 @@ else:
allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
allow_headers=["*"],
)
# ✅ CEP 环境特殊处理 (Origin: null or cep://)
@app.middleware("http")
async def cep_cors_middleware(request: Request, call_next):
origin = request.headers.get("origin")
# CEP 的 Origin 是 null 或 cep://
if origin in ["null", None] or (origin and origin.startswith("cep://")):
response = await call_next(request)
response.headers["Access-Control-Allow-Origin"] = "*"
response.headers["Access-Control-Allow-Credentials"] = "true"
response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS"
response.headers["Access-Control-Allow-Methods"] = (
"GET, POST, PUT, DELETE, OPTIONS"
)
response.headers["Access-Control-Allow-Headers"] = "*"
return response
return await call_next(request)
app.include_router(auth.router, prefix=f"{settings.API_V1_STR}/auth", tags=["authentication"])
app.include_router(client.router, prefix=f"{settings.API_V1_STR}/client", tags=["client"])
app.include_router(
auth.router, prefix=f"{settings.API_V1_STR}/auth", tags=["authentication"]
)
app.include_router(
client.router, prefix=f"{settings.API_V1_STR}/client", tags=["client"]
)
app.include_router(admin.router, prefix=f"{settings.API_V1_STR}/admin", tags=["admin"])
app.include_router(analytics.router, prefix=f"{settings.API_V1_STR}/analytics", tags=["analytics"])
app.include_router(
analytics.router, prefix=f"{settings.API_V1_STR}/analytics", tags=["analytics"]
)
# 新增路由
app.include_router(admin_config.router, prefix=settings.API_V1_STR, tags=["admin-config"])
app.include_router(
admin_config.router, prefix=settings.API_V1_STR, tags=["admin-config"]
)
app.include_router(feature.router, prefix=settings.API_V1_STR, tags=["feature"])
app.include_router(checkin.router, prefix=settings.API_V1_STR, tags=["checkin"])
app.include_router(user_profile.router, prefix=settings.API_V1_STR, tags=["user-profile"])
app.include_router(
user_profile.router, prefix=settings.API_V1_STR, tags=["user-profile"]
)
app.include_router(stats.router, prefix=settings.API_V1_STR, tags=["stats"])
app.include_router(algorithm.router, prefix=settings.API_V1_STR, tags=["algorithm"])
app.include_router(logs.router, prefix=settings.API_V1_STR, tags=["logs"])
app.include_router(ai_chat.router, prefix=settings.API_V1_STR, tags=["ai-chat"])
app.include_router(ai_pattern.router, prefix=settings.API_V1_STR, tags=["ai-pattern"])
app.include_router(ai_identify.router, prefix=settings.API_V1_STR, tags=["ai-identify"])
# Health Check
@app.get("/health")
def health_check():
return {"status": "healthy", "timestamp": datetime.now().isoformat(), "env": "development" if IS_DEV else "production"}
return {
"status": "healthy",
"timestamp": datetime.now().isoformat(),
"env": "development" if IS_DEV else "production",
}
# ========== Static Files (Development Only) ==========
if IS_DEV:
# Mount archives directory for download
app.mount("/download", StaticFiles(directory="archives"), name="download")
app.mount("/download", StaticFiles(directory=ARCHIVES_DIR), name="download")
else:
print(" Production Mode: Static files are NOT mounted by FastAPI (handled by Caddy/Nginx).")
print(
" Production Mode: Static files are NOT mounted by FastAPI (handled by Caddy/Nginx)."
)
@app.get("/")
def read_root():
from fastapi.responses import RedirectResponse
if IS_DEV:
# 重定向到 Shell 登录页
return RedirectResponse(url="/shell/index.html")
return {"message": "DesignerCEP API is running"}
@app.on_event("startup")
def on_startup():
# 应用启动时初始化数据库(创建表)
init_db()
for warning in settings.runtime_warnings():
log.warning("[Config] %s", warning)
if __name__ == "__main__":
import uvicorn
uvicorn.run("app.main:app", host="0.0.0.0", port=8000, reload=True)