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

@@ -12,7 +12,7 @@ class Settings(BaseSettings):
openai_base_url: str = "https://api.openai.com/v1"
anthropic_api_key: str = ""
# 开发模式true 时跳过 OTel exporter 初始化,避免本地无 collector 时报错
dev_mode: str = "false"
dev_mode: bool = False
# 可观测性
otel_endpoint: str = "http://localhost:4318"
log_level: str = "info"
@@ -22,7 +22,7 @@ class Settings(BaseSettings):
@property
def is_dev(self) -> bool:
"""是否处于开发模式."""
return self.dev_mode.lower() == "true"
return self.dev_mode
@property
def llm_available(self) -> bool:

View File

@@ -41,7 +41,7 @@ def init_tracer() -> None:
@asynccontextmanager
async def lifespan(app: FastAPI):
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
"""应用生命周期."""
init_tracer()
logger.info(
@@ -89,6 +89,12 @@ class ChatResponse(BaseModel):
degraded: bool = False
class QuestionRequest(BaseModel):
"""题目生成请求."""
prompt: str
def _extract_content(result: dict[str, Any] | None) -> tuple[str, str, dict[str, Any]]:
"""从 OpenAI 响应中抽取 (content, model, usage)。"""
if result is None:
@@ -171,7 +177,7 @@ async def chat_stream(req: ChatRequest) -> StreamingResponse:
@router.post("/generate/question")
async def generate_question(prompt: str) -> dict[str, Any]:
async def generate_question(req: QuestionRequest) -> dict[str, Any]:
"""生成题目(无 API key 时降级返回骨架)."""
with tracer.start_as_current_span("generate_question"):
messages = [
@@ -180,7 +186,7 @@ async def generate_question(prompt: str) -> dict[str, Any]:
"content": "You are an educational question generator. "
"Generate a clear, concise question based on the user's prompt.",
},
{"role": "user", "content": prompt},
{"role": "user", "content": req.prompt},
]
result = await chat_completion(
messages=messages,
@@ -190,7 +196,7 @@ async def generate_question(prompt: str) -> dict[str, Any]:
base_url=settings.openai_base_url,
)
if result is None:
logger.warning("generate_question_degraded", prompt=prompt[:100])
logger.warning("generate_question_degraded", prompt=req.prompt[:100])
return {
"success": True,
"data": {"question": "[degraded] question generation skeleton"},