fix: code compliance audit and fix across all services
Some checks failed
CI / quality-ts (push) Failing after 48s
CI / quality-go (push) Failing after 4s
CI / quality-proto (push) Failing after 2s
CI / deploy (push) Has been skipped

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:
SpecialX
2026-07-09 17:28:27 +08:00
parent b53a486c6e
commit 0a71b02e04
93 changed files with 5775 additions and 608 deletions

View File

@@ -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. 初始化 loggerstructlog
@@ -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)