feat: 添加飞书用户模块和订阅功能支持

- 新增feishu_users模块用于处理飞书用户身份验证和权限管理
- 新增subscriptions模块用于处理订阅相关功能
- 新增personalization模块用于个性化服务
- 在alembic迁移配置中注册新的模型模块
- 在API路由器中添加feishu_users和subscriptions路由
- 实现事件调度服务的改进,包括错误处理和状态更新优化
- 添加飞书命令处理的权限检查机制
- 实现飞书应用票据事件处理
- 改进审计日志记录功能
```
This commit is contained in:
2026-07-27 08:02:17 +08:00
parent db751f03b4
commit d7db84571d
148 changed files with 17110 additions and 765 deletions

View File

@@ -4,7 +4,6 @@ from enum import StrEnum
class AuditAction(StrEnum):
AI_ASK = "ai.ask"
AI_PROVIDER_HEALTH = "ai.provider_health"
OPENCLAW_TOOLS_INVOKE = "openclaw.tools.invoke"
GENERATE_EVENTS = "generate_events"
FEISHU_WEBHOOK_EVENT = "webhook_event"
FEISHU_LONG_CONNECTION_EVENT = "long_connection_event"
@@ -34,7 +33,6 @@ class AuditRiskLevel(StrEnum):
class AuditSource(StrEnum):
API = "api"
OPENCLAW = "openclaw"
RISK = "risk"
FEISHU = "feishu"
LEGACY_MYSQL = "legacy_mysql"
@@ -47,7 +45,6 @@ class AuditSource(StrEnum):
class AuditTargetType(StrEnum):
AI = "ai"
OPENCLAW_TOOL = "openclaw_tool"
RISK_EVENTS = "risk-events"
WORK_REPORTS = "work-reports"
ENTERPRISE_ANALYTICS = "enterprise-analytics"
@@ -62,21 +59,3 @@ class AuditStatus(StrEnum):
AUDIT_REDACTED_VALUE = "[REDACTED]"
AUDIT_SENSITIVE_KEYS = frozenset(
{
"authorization",
"api_key",
"apikey",
"access_token",
"tenant_access_token",
"token",
"secret",
"password",
"openclaw_gateway_token",
"hermes_api_key",
"direct_llm_api_key",
"market_data_token",
"feishu_app_secret",
"feishu_verification_token",
}
)

View File

@@ -4,9 +4,10 @@ from typing import Any
from sqlalchemy import select
from sqlalchemy.orm import Session
from app.core.http.masking import is_sensitive_key
from app.core.http.pagination import bounded_limit
from app.core.http.request_context import get_request_id
from app.modules.audit.constants import AUDIT_REDACTED_VALUE, AUDIT_SENSITIVE_KEYS
from app.modules.audit.constants import AUDIT_REDACTED_VALUE
from app.modules.audit.models import AuditLog
from app.modules.audit.schemas import AuditLogCreate
@@ -16,7 +17,7 @@ def _redact(value: Any) -> Any:
safe: dict[str, Any] = {}
for key, item in value.items():
key_text = str(key)
if key_text.lower() in AUDIT_SENSITIVE_KEYS:
if is_sensitive_key(key_text):
safe[key_text] = AUDIT_REDACTED_VALUE
else:
safe[key_text] = _redact(item)
@@ -34,6 +35,12 @@ def _dump(value: Any | None) -> str | None:
if value is None:
return None
if isinstance(value, str):
try:
parsed = json.loads(value)
except (json.JSONDecodeError, TypeError):
return value
if isinstance(parsed, (dict, list)):
return json.dumps(_redact(parsed), ensure_ascii=False, default=str)
return value
return json.dumps(_redact(value), ensure_ascii=False, default=str)