feat: 添加飞书集成和审计API密钥认证

- 在数据库配置中添加飞书模型导入
- 添加审计API密钥配置项和认证中间件
- 实现飞书事件重复处理防止机制
- 为审批路由添加API密钥认证
- 优化AI适配器错误处理并添加JSON解析异常捕获
- 更新测试用例以包含新的认证和事件处理逻辑
```
This commit is contained in:
2026-07-06 11:34:15 +08:00
parent 0dbe5c1c2d
commit 514b14d390
16 changed files with 353 additions and 16 deletions

View File

@@ -28,6 +28,15 @@ class DummyResponse:
return self._data
class NonJsonResponse(DummyResponse):
def __init__(self, text: str, status_code: int = 200):
super().__init__({}, status_code=status_code)
self.text = text
def json(self) -> dict[str, Any]:
raise ValueError("invalid json")
def chat_response(content: str) -> DummyResponse:
return DummyResponse(
{
@@ -265,3 +274,53 @@ def test_direct_llm_adapter_wraps_unexpected_chat_response(monkeypatch) -> None:
assert exc_info.value.status_code == 502
assert exc_info.value.detail[AIErrorKey.DIRECT_LLM] == "Unexpected chat completion response"
assert exc_info.value.detail[AIResponseKey.RAW] == {AIHttpPayloadKey.CHOICES: []}
def test_hermes_adapter_wraps_non_json_chat_response(monkeypatch) -> None:
class BadJsonClient(DummyClient):
def post(
self,
url: str,
json: dict[str, Any],
headers: dict[str, str],
) -> NonJsonResponse:
self.calls.append({"method": "POST", "url": url, "json": json, "headers": headers})
return NonJsonResponse("upstream html")
DummyClient.calls = []
monkeypatch.setattr(adapters.httpx, "Client", BadJsonClient)
settings = Settings(hermes_base_url="http://hermes.local/v1", hermes_api_key="hermes-key")
with pytest.raises(HTTPException) as exc_info:
adapters.HermesAdapter(settings).ask("summarize")
assert exc_info.value.status_code == 502
assert exc_info.value.detail[AIErrorKey.HERMES] == "Unexpected chat completion response"
assert exc_info.value.detail[AIResponseKey.RAW][AIResponseKey.TEXT] == "upstream html"
def test_direct_llm_adapter_wraps_non_json_chat_response(monkeypatch) -> None:
class BadJsonClient(DummyClient):
def post(
self,
url: str,
json: dict[str, Any],
headers: dict[str, str],
) -> NonJsonResponse:
self.calls.append({"method": "POST", "url": url, "json": json, "headers": headers})
return NonJsonResponse("upstream html")
DummyClient.calls = []
monkeypatch.setattr(adapters.httpx, "Client", BadJsonClient)
settings = Settings(
direct_llm_base_url="http://llm.local/v1",
direct_llm_api_key="direct-key",
direct_llm_model="company-model",
)
with pytest.raises(HTTPException) as exc_info:
adapters.DirectLLMAdapter(settings).ask("summarize")
assert exc_info.value.status_code == 502
assert exc_info.value.detail[AIErrorKey.DIRECT_LLM] == "Unexpected chat completion response"
assert exc_info.value.detail[AIResponseKey.RAW][AIResponseKey.TEXT] == "upstream html"