feat(ai): v2 新增 GenerateReport RPC + ReportService

第 9 个 RPC GenerateReport(学情报告生成):data-ana 学情数据 → LLM 生成 → 结构化提取

新增 ReportService 业务编排层 + GenerateReportRequest/GeneratedReport 模型

gRPC servicer + HTTP POST /v1/ai/generate/report(权限 ai:report:generate)

proto_gen 重新生成 + 测试覆盖(servicer/service/HTTP/模型/权限 共 26 用例)

402 测试通过,覆盖率 88.5%
This commit is contained in:
SpecialX
2026-07-14 22:57:57 +08:00
parent 843b370b3d
commit aac26c7c6f
21 changed files with 1954 additions and 278 deletions

View File

@@ -9,6 +9,7 @@ from src.ai.middleware.permission import (
PERMISSION_AI_LESSON_CONFIRM,
PERMISSION_AI_LESSON_GENERATE,
PERMISSION_AI_QUESTION_GENERATE,
PERMISSION_AI_REPORT_GENERATE,
PermissionGuard,
)
@@ -39,6 +40,7 @@ class TestPermissionGuard:
guard.check(ctx, PERMISSION_AI_QUESTION_GENERATE)
guard.check(ctx, PERMISSION_AI_LESSON_GENERATE)
guard.check(ctx, PERMISSION_AI_LESSON_CONFIRM)
guard.check(ctx, PERMISSION_AI_REPORT_GENERATE)
def test_student_only_chat(self) -> None:
"""student 角色仅有 chat 权限."""
@@ -49,6 +51,14 @@ class TestPermissionGuard:
guard.check(ctx, PERMISSION_AI_QUESTION_GENERATE)
assert exc_info.value.code == ErrorCode.AI_FORBIDDEN
def test_student_denied_report(self) -> None:
"""student 角色无权生成学情报告."""
guard = PermissionGuard(dev_mode=False)
ctx = UserContext(user_id="u-1", role="student")
with pytest.raises(AIError) as exc_info:
guard.check(ctx, PERMISSION_AI_REPORT_GENERATE)
assert exc_info.value.code == ErrorCode.AI_FORBIDDEN
def test_unknown_role_defaults_student(self) -> None:
"""未知角色降级为 student 权限."""
guard = PermissionGuard(dev_mode=False)