feat(backend): complete modular monolith with ledger, fastapi and websocket

This commit is contained in:
Bot
2026-08-31 01:02:16 +08:00
parent 9f6ecf33f9
commit 30dc22a989
16 changed files with 706 additions and 17 deletions
+30 -16
View File
@@ -1,22 +1,25 @@
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
import logging
from contextlib import asynccontextmanager
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.middleware.cors import CORSMiddleware
from app.config import settings
from app.api.routes.api import api_router
from app.ws.manager import ws_manager
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s")
logger = logging.getLogger("WTFX-Backend")
@asynccontextmanager
async def lifespan(app: FastAPI):
# 启动时:初始化 DB 连接池、Redis 事件总线与外部适配器
print(f"Starting {settings.PROJECT_NAME} in [{settings.ENVIRONMENT}] mode...")
logger.info(f"Starting {settings.PROJECT_NAME} v{settings.VERSION} [{settings.ENVIRONMENT}]")
yield
# 关闭时:优雅断开连接
print(f"Shutting down {settings.PROJECT_NAME}...")
logger.info("Shutting down WTFX Backend service...")
app = FastAPI(
title=settings.PROJECT_NAME,
version=settings.VERSION,
lifespan=lifespan,
docs_url="/docs" if settings.ENVIRONMENT != "production" else None,
redoc_url="/redoc" if settings.ENVIRONMENT != "production" else None
docs_url="/docs" if settings.DEBUG or settings.ENVIRONMENT != "production" else None,
)
# CORS 配置
@@ -28,12 +31,23 @@ app.add_middleware(
allow_headers=["*"],
)
@app.get("/health", tags=["System"])
# 注册 API 路由
app.include_router(api_router, prefix="/api")
# WebSocket 实时订阅端点
@app.websocket("/ws/market/{market_address}")
async def websocket_market_endpoint(websocket: WebSocket, market_address: str):
channel = f"market:{market_address.lower()}"
await ws_manager.connect(websocket, channel)
try:
while True:
data = await websocket.receive_text()
# 客户端心跳 ping/pong
if data == "ping":
await websocket.send_text("pong")
except WebSocketDisconnect:
ws_manager.disconnect(websocket, channel)
@app.get("/health")
async def health_check():
"""生产探活与健康检查端点 (Blue-Green Probe)"""
return {
"status": "ok",
"service": "wtfx-backend",
"version": settings.VERSION,
"environment": settings.ENVIRONMENT
}
return {"status": "ok", "version": settings.VERSION, "env": settings.ENVIRONMENT}