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

@@ -5,6 +5,7 @@
保证服务在 ClickHouse 不可用时仍可启动并响应骨架数据。
"""
import asyncio
from datetime import datetime
from typing import Any
@@ -68,7 +69,7 @@ async def close_client() -> None:
global _client, _client_initialized
if _client is not None:
try:
_client.close()
await asyncio.to_thread(_client.close)
except Exception as exc: # noqa: BLE001
logger.warning("clickhouse_client_close_failed", error=str(exc))
finally:
@@ -86,7 +87,8 @@ async def query_dashboard(student_id: str) -> dict | None:
return None
try:
rows = client.query(
result = await asyncio.to_thread(
client.query,
"SELECT student_id, class_id, exam_id, subject_id, score, "
"rank_in_class, knowledge_point_id, mastery_level, error_count, "
"last_updated "
@@ -95,7 +97,8 @@ async def query_dashboard(student_id: str) -> dict | None:
"ORDER BY last_updated DESC "
"LIMIT 50",
parameters={"sid": student_id},
).result_rows
)
rows = result.result_rows
except Exception as exc: # noqa: BLE001
logger.warning("query_dashboard_failed_degraded", error=str(exc), student_id=student_id)
return None
@@ -131,7 +134,8 @@ async def query_class_performance(class_id: str) -> dict | None:
try:
# 平均分、参考人数、及格率(>=60
agg_rows = client.query(
result = await asyncio.to_thread(
client.query,
"SELECT "
" count() AS total_students, "
" avg(score) AS average_score, "
@@ -139,7 +143,8 @@ async def query_class_performance(class_id: str) -> dict | None:
"FROM student_dashboard_view "
"WHERE class_id = {cid:String}",
parameters={"cid": class_id},
).result_rows
)
agg_rows = result.result_rows
except Exception as exc: # noqa: BLE001
logger.warning(
"query_class_performance_failed_degraded",
@@ -175,7 +180,8 @@ async def query_student_errors(student_id: str) -> list[dict] | None:
return None
try:
rows = client.query(
result = await asyncio.to_thread(
client.query,
"SELECT student_id, question_id, knowledge_point_id, error_count, "
"last_error_time, content "
"FROM student_errors "
@@ -183,7 +189,8 @@ async def query_student_errors(student_id: str) -> list[dict] | None:
"ORDER BY last_error_time DESC "
"LIMIT 100",
parameters={"sid": student_id},
).result_rows
)
rows = result.result_rows
except Exception as exc: # noqa: BLE001
logger.warning(
"query_student_errors_failed_degraded",
@@ -212,7 +219,7 @@ async def ping() -> bool:
if client is None:
return False
try:
client.query("SELECT 1")
await asyncio.to_thread(client.query, "SELECT 1")
return True
except Exception as exc: # noqa: BLE001
logger.warning("clickhouse_ping_failed", error=str(exc))
@@ -241,7 +248,8 @@ async def upsert_student_dashboard(
return False
try:
client.insert(
await asyncio.to_thread(
client.insert,
"student_dashboard_view",
[
[
@@ -305,7 +313,8 @@ async def upsert_student_error(
return False
try:
client.insert(
await asyncio.to_thread(
client.insert,
"student_errors",
[
[