```
feat: 添加数据库迁移脚本并更新Dockerfile配置 - 在Dockerfile中添加alembic配置文件和目录的复制指令 - 更新alembic/env.py注册新的模块模型:events、workflows、writebacks - 生成完整的初始数据库schema迁移脚本,包含以下表: - approval_requests, attendance_records, audit_logs, domain_events - expenses, feishu_event_receipts, fund_accounts, legacy_sync_runs - official_writeback_runs, performance_metrics, policies, procurements - projects, report_push_runs, risk_event_actions, risk_events - standards, suppliers, work_reports, work_tasks, workflow_actions - workflow_instances等21个数据表结构定义 - 在API路由器中添加新模块的路由:events、workflows、writebacks、observability ```
This commit is contained in:
74
app/modules/writebacks/adapters.py
Normal file
74
app/modules/writebacks/adapters.py
Normal file
@@ -0,0 +1,74 @@
|
||||
from typing import Any, Protocol
|
||||
|
||||
import httpx
|
||||
from fastapi import HTTPException, status
|
||||
|
||||
from app.core.config import Settings
|
||||
from app.core.constants import BEARER_TOKEN_TEMPLATE, HttpHeader
|
||||
from app.modules.writebacks.constants import (
|
||||
WRITEBACK_DISABLED_MESSAGE,
|
||||
WritebackErrorDetail,
|
||||
WritebackPayloadKey,
|
||||
WritebackStatus,
|
||||
)
|
||||
from app.modules.writebacks.models import OfficialWritebackRun
|
||||
|
||||
|
||||
class WritebackAdapter(Protocol):
|
||||
def submit(self, run: OfficialWritebackRun) -> dict[str, Any]:
|
||||
"""Submit one writeback run to the configured official integration."""
|
||||
|
||||
|
||||
class DisabledWritebackAdapter:
|
||||
def submit(self, run: OfficialWritebackRun) -> dict[str, Any]:
|
||||
return {
|
||||
WritebackPayloadKey.STATUS: WritebackStatus.DISABLED,
|
||||
WritebackPayloadKey.ERROR_MESSAGE: WRITEBACK_DISABLED_MESSAGE,
|
||||
WritebackPayloadKey.CODE: run.code,
|
||||
}
|
||||
|
||||
|
||||
class HttpWritebackAdapter:
|
||||
def __init__(self, settings: Settings):
|
||||
self.settings = settings
|
||||
|
||||
def submit(self, run: OfficialWritebackRun) -> dict[str, Any]:
|
||||
if not self.settings.official_api_base_url or not self.settings.official_api_token:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail=WritebackErrorDetail.OFFICIAL_API_NOT_CONFIGURED,
|
||||
)
|
||||
url = f"{self.settings.official_api_base_url.rstrip('/')}/writebacks/{run.domain}"
|
||||
headers = {
|
||||
HttpHeader.AUTHORIZATION: BEARER_TOKEN_TEMPLATE.format(
|
||||
token=self.settings.official_api_token
|
||||
)
|
||||
}
|
||||
payload = {
|
||||
WritebackPayloadKey.CODE: run.code,
|
||||
WritebackPayloadKey.DOMAIN: run.domain,
|
||||
WritebackPayloadKey.RECORD_ID: run.record_id,
|
||||
WritebackPayloadKey.ACTION: run.action,
|
||||
WritebackPayloadKey.PAYLOAD: run.request_payload or {},
|
||||
}
|
||||
with httpx.Client(timeout=self.settings.official_api_timeout_seconds) as client:
|
||||
response = client.post(url, json=payload, headers=headers)
|
||||
if response.status_code >= status.HTTP_400_BAD_REQUEST:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_502_BAD_GATEWAY,
|
||||
detail=response.text,
|
||||
)
|
||||
try:
|
||||
data = response.json()
|
||||
except ValueError:
|
||||
data = {"text": response.text}
|
||||
return {
|
||||
WritebackPayloadKey.STATUS: WritebackStatus.SENT,
|
||||
WritebackPayloadKey.PROVIDER_RESPONSE: data,
|
||||
}
|
||||
|
||||
|
||||
def get_writeback_adapter(settings: Settings) -> WritebackAdapter:
|
||||
if settings.official_writeback_enabled:
|
||||
return HttpWritebackAdapter(settings)
|
||||
return DisabledWritebackAdapter()
|
||||
Reference in New Issue
Block a user