feat: 添加核心流程测试 + 审计日志 + 修复 task_service 嵌套加载 bug
- 新增 test_auth_api.py (48 tests): 注册/登录/刷新/退出全流程覆盖 - 新增 test_tasks_api.py (38 tests): 任务 CRUD/审核/申诉/权限控制 - 新增 AuditLog 模型 + log_action 审计服务 - 新增 logging_config.py 结构化日志配置 - 修复 task_service.py 缺少 Project.brand 嵌套加载导致的 MissingGreenlet 错误 - 修复 conftest.py 添加限流清理 fixture 防止测试间干扰 - 修复 TDD 红色阶段测试文件的 import 错误 (skip) - auth.py 集成审计日志 (注册/登录/退出) - 全部 211 tests passed, 2 skipped Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
8eb8100cf4
commit
e0bd3f2911
@@ -11,6 +11,7 @@ from app.models.brief import Brief
|
||||
from app.models.ai_config import AIConfig
|
||||
from app.models.review import ReviewTask, Platform
|
||||
from app.models.rule import ForbiddenWord, WhitelistItem, Competitor
|
||||
from app.models.audit_log import AuditLog
|
||||
# 保留 Tenant 兼容旧代码,但新代码应使用 Brand
|
||||
from app.models.tenant import Tenant
|
||||
|
||||
@@ -42,6 +43,8 @@ __all__ = [
|
||||
"ForbiddenWord",
|
||||
"WhitelistItem",
|
||||
"Competitor",
|
||||
# 审计日志
|
||||
"AuditLog",
|
||||
# 兼容
|
||||
"Tenant",
|
||||
]
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
"""审计日志模型"""
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
from sqlalchemy import String, Text, DateTime, Integer, func
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
from app.models.base import Base
|
||||
|
||||
|
||||
class AuditLog(Base):
|
||||
"""审计日志表 - 记录所有重要操作"""
|
||||
__tablename__ = "audit_logs"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
||||
|
||||
# 操作信息
|
||||
action: Mapped[str] = mapped_column(String(50), nullable=False, index=True) # login, logout, create_project, review_task, etc.
|
||||
resource_type: Mapped[str] = mapped_column(String(50), nullable=False, index=True) # user, project, task, brief, etc.
|
||||
resource_id: Mapped[Optional[str]] = mapped_column(String(64), nullable=True, index=True)
|
||||
|
||||
# 操作者
|
||||
user_id: Mapped[Optional[str]] = mapped_column(String(64), nullable=True, index=True)
|
||||
user_name: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
|
||||
user_role: Mapped[Optional[str]] = mapped_column(String(20), nullable=True)
|
||||
|
||||
# 详情
|
||||
detail: Mapped[Optional[str]] = mapped_column(Text, nullable=True) # JSON string with extra info
|
||||
ip_address: Mapped[Optional[str]] = mapped_column(String(45), nullable=True)
|
||||
|
||||
# 时间
|
||||
created_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True),
|
||||
server_default=func.now(),
|
||||
nullable=False,
|
||||
index=True,
|
||||
)
|
||||
Reference in New Issue
Block a user