fix: code compliance audit and fix across all services
NestJS (6 services): implement @RequirePermission decorator with SetMetadata+Reflector, register APP_GUARD globally, fix as assertions to type guards, add explicit return types, fix import type for express, fix /metrics implicit any, replace native Error with ApplicationError, remove typeorm remnants, register LifecycleService. teacher-bff: add logger, ApplicationError, GlobalErrorFilter, forward real userId to downstream, log downstream failures, migrate health controller to shared/health. Go (2 services): interface to any, doc comments, CORS dev whitelist, JWT secret fail-fast, push-gateway internal API auth, metrics and readyz endpoints, remove dead code. Python (2 services): lifespan return type, dev_mode to bool, data-ana APIRouter, ai POST body model, ClickHouse async wrapping.
This commit is contained in:
@@ -9,11 +9,12 @@
|
||||
|
||||
import asyncio
|
||||
import contextlib
|
||||
from collections.abc import AsyncGenerator
|
||||
from contextlib import asynccontextmanager
|
||||
from datetime import UTC, datetime
|
||||
|
||||
import structlog
|
||||
from fastapi import FastAPI
|
||||
from fastapi import APIRouter, FastAPI
|
||||
from opentelemetry import trace
|
||||
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
|
||||
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
|
||||
@@ -89,7 +90,7 @@ def init_tracer() -> None:
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
|
||||
"""应用生命周期.
|
||||
|
||||
1. 初始化 logger(structlog)
|
||||
@@ -133,6 +134,9 @@ FastAPIInstrumentor.instrument_app(app)
|
||||
# Prometheus 指标
|
||||
app.mount("/metrics", make_asgi_app())
|
||||
|
||||
# 业务路由
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@app.get("/healthz")
|
||||
async def healthz() -> dict:
|
||||
@@ -189,7 +193,7 @@ async def readyz() -> dict:
|
||||
}
|
||||
|
||||
|
||||
@app.get("/analytics/class/{class_id}/performance")
|
||||
@router.get("/analytics/class/{class_id}/performance")
|
||||
async def class_performance(class_id: str) -> dict:
|
||||
"""班级成绩分析.
|
||||
|
||||
@@ -215,7 +219,7 @@ async def class_performance(class_id: str) -> dict:
|
||||
return {"success": True, "data": {**result, "degraded": False}}
|
||||
|
||||
|
||||
@app.get("/analytics/student/{student_id}/weakness")
|
||||
@router.get("/analytics/student/{student_id}/weakness")
|
||||
async def student_weakness(student_id: str) -> dict:
|
||||
"""学生薄弱知识点分析.
|
||||
|
||||
@@ -259,7 +263,7 @@ async def student_weakness(student_id: str) -> dict:
|
||||
}
|
||||
|
||||
|
||||
@app.get("/analytics/student/{student_id}/errorbook")
|
||||
@router.get("/analytics/student/{student_id}/errorbook")
|
||||
async def student_errorbook(student_id: str) -> dict:
|
||||
"""学生错题本.
|
||||
|
||||
@@ -290,3 +294,6 @@ async def student_errorbook(student_id: str) -> dict:
|
||||
"degraded": False,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
app.include_router(router)
|
||||
|
||||
Reference in New Issue
Block a user