feat(phase6-9): Complete modular architecture and Agent Teams
Phase 6.4 - Modular Architecture: - Add lewooogo-brain adapters for LLM providers - Add lewooogo-data dual memory (Redis + PostgreSQL) - Implement consensus engine for multi-agent decisions - Add incident memory service for historical context Phase 9 - Agent Teams (Claude Agent SDK): - Add base agent class with Claude Sonnet 4 integration - Implement action planner, blast radius, and security agents - Add agent API endpoints and proposal workflow - Integrate ADR-009 OpenClaw Agent Teams architecture DevOps & CI/CD: - Add GitHub Actions CI/CD workflows (ci.yaml, cd.yaml) - Add pre-commit hooks and secrets baseline - Add docker-compose for local development - Update Kubernetes network policies Frontend Improvements: - Add auto-healing error boundary component - Update i18n messages for agent features - Enhance dual-state incident card with execution feedback Documentation: - Add 7 ADRs covering MCP, design system, architecture decisions - Update ARCHITECTURE_MEMORY.md with modular design - Add GLOBAL_RULES.md and SOUL.md for project identity Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -19,7 +19,6 @@ from uuid import UUID
|
||||
|
||||
import structlog
|
||||
from sqlalchemy import select, update, and_, or_
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from src.db.base import get_db_context
|
||||
from src.db.models import ApprovalRecord, TimelineEvent
|
||||
@@ -572,6 +571,78 @@ class ApprovalDBService:
|
||||
success=success,
|
||||
)
|
||||
|
||||
# =========================================================================
|
||||
# Phase 6.4h: Proposals API 支援方法
|
||||
# =========================================================================
|
||||
|
||||
async def get_approval_by_id(self, approval_id: UUID) -> ApprovalRequest | None:
|
||||
"""
|
||||
根據 ID 取得單一授權請求 (Phase 6.4h)
|
||||
|
||||
Args:
|
||||
approval_id: 授權請求 UUID
|
||||
|
||||
Returns:
|
||||
ApprovalRequest if found, None otherwise
|
||||
"""
|
||||
async with get_db_context() as db:
|
||||
result = await db.execute(
|
||||
select(ApprovalRecord).where(ApprovalRecord.id == str(approval_id))
|
||||
)
|
||||
record = result.scalar_one_or_none()
|
||||
|
||||
if record is None:
|
||||
return None
|
||||
|
||||
return approval_record_to_request(record)
|
||||
|
||||
async def get_all_approvals(
|
||||
self,
|
||||
status: ApprovalStatus | None = None,
|
||||
incident_id: str | None = None,
|
||||
limit: int = 50,
|
||||
offset: int = 0,
|
||||
) -> list[ApprovalRequest]:
|
||||
"""
|
||||
取得所有授權請求 (Phase 6.4h)
|
||||
|
||||
Args:
|
||||
status: 狀態篩選 (可選)
|
||||
incident_id: Incident ID 篩選 (可選)
|
||||
limit: 每頁數量
|
||||
offset: 偏移量
|
||||
|
||||
Returns:
|
||||
ApprovalRequest 清單
|
||||
"""
|
||||
async with get_db_context() as db:
|
||||
query = select(ApprovalRecord)
|
||||
|
||||
# 狀態篩選
|
||||
if status is not None:
|
||||
query = query.where(ApprovalRecord.status == status)
|
||||
|
||||
# Incident ID 篩選 (從 extra_metadata JSON 欄位)
|
||||
# NOTE: 這是基於 JSON 欄位查詢,效能可能受影響
|
||||
# 若有效能問題,考慮新增 incident_id 欄位到 ApprovalRecord
|
||||
|
||||
query = query.order_by(ApprovalRecord.created_at.desc())
|
||||
query = query.offset(offset).limit(limit)
|
||||
|
||||
result = await db.execute(query)
|
||||
records = result.scalars().all()
|
||||
|
||||
approvals = [approval_record_to_request(r) for r in records]
|
||||
|
||||
# 若有 incident_id 篩選,在應用層過濾
|
||||
if incident_id:
|
||||
approvals = [
|
||||
a for a in approvals
|
||||
if a.metadata and a.metadata.get("incident_id") == incident_id
|
||||
]
|
||||
|
||||
return approvals
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Timeline Event Service
|
||||
|
||||
Reference in New Issue
Block a user