feat(api): Knowledge Base Phase 1 後端四層架構
- models/knowledge.py: Pydantic Schema (EntryType/Source/Status/CRUD)
- db/models.py: KnowledgeEntryRecord ORM (PostgreSQL)
- repositories/interfaces.py: IKnowledgeRepository Protocol
- repositories/knowledge_repository.py: PostgreSQL CRUD 實作
- services/knowledge_service.py: 業務邏輯 (get_db_context 內部管理 session)
- api/v1/knowledge.py: REST Router (get_knowledge_service,無直接 DB 存取)
- main.py: 掛載 Knowledge Base Router
- k8s/jobs/migrate-knowledge-entries.yaml: DB Migration Job
API 端點: GET/POST / | GET/PATCH/DELETE /{id} | POST /{id}/approve
GET /search | GET /categories
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -30,6 +30,7 @@ from sqlalchemy.orm import Mapped, mapped_column
|
||||
from src.db.base import Base
|
||||
from src.models.approval import ApprovalStatus, RiskLevel
|
||||
from src.models.incident import IncidentStatus, Severity
|
||||
from src.models.knowledge import EntrySource, EntryStatus, EntryType
|
||||
|
||||
# =============================================================================
|
||||
# Helper Functions
|
||||
@@ -454,3 +455,100 @@ class IncidentRecord(Base):
|
||||
Index("ix_incident_created_at", "created_at"),
|
||||
Index("ix_incident_resolved_at", "resolved_at"),
|
||||
)
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# KnowledgeEntry - Knowledge Base Phase 1
|
||||
# =============================================================================
|
||||
|
||||
class KnowledgeEntryRecord(Base):
|
||||
"""
|
||||
知識庫條目 - Knowledge Base Phase 1
|
||||
|
||||
兩層架構:
|
||||
- KnowledgeEntry: 知識條目 (此表)
|
||||
- Playbook: 獨立 Redis,透過 related_playbook_id 關聯
|
||||
|
||||
建立時間: 2026-04-02 (台北時區)
|
||||
建立者: Claude Code (Knowledge Base Phase 1)
|
||||
"""
|
||||
__tablename__ = "knowledge_entries"
|
||||
|
||||
# Primary Key
|
||||
id: Mapped[str] = mapped_column(
|
||||
String(36),
|
||||
primary_key=True,
|
||||
default=generate_uuid,
|
||||
)
|
||||
|
||||
# Core Fields
|
||||
title: Mapped[str] = mapped_column(String(255), nullable=False)
|
||||
content: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
entry_type: Mapped[str] = mapped_column(
|
||||
SQLEnum(EntryType),
|
||||
nullable=False,
|
||||
comment="incident_case / runbook / best_practice / postmortem",
|
||||
)
|
||||
category: Mapped[str] = mapped_column(
|
||||
String(100),
|
||||
nullable=False,
|
||||
comment="分類樹節點 (基礎設施/應用層/AI系統/安全合規)",
|
||||
)
|
||||
tags: Mapped[list[dict[str, Any]]] = mapped_column(
|
||||
JSON,
|
||||
default=list,
|
||||
nullable=False,
|
||||
comment="標籤列表 (JSONB)",
|
||||
)
|
||||
|
||||
# Source & Status
|
||||
source: Mapped[str] = mapped_column(
|
||||
SQLEnum(EntrySource),
|
||||
nullable=False,
|
||||
comment="ai_extracted / human",
|
||||
)
|
||||
status: Mapped[str] = mapped_column(
|
||||
SQLEnum(EntryStatus),
|
||||
default=EntryStatus.DRAFT,
|
||||
nullable=False,
|
||||
comment="draft / review / approved / archived",
|
||||
)
|
||||
|
||||
# Relations (soft references, not FK)
|
||||
related_incident_id: Mapped[str | None] = mapped_column(
|
||||
String(30),
|
||||
nullable=True,
|
||||
comment="關聯 Incident ID",
|
||||
)
|
||||
related_playbook_id: Mapped[str | None] = mapped_column(
|
||||
String(255),
|
||||
nullable=True,
|
||||
comment="關聯 Playbook Redis Key",
|
||||
)
|
||||
|
||||
# Metrics
|
||||
view_count: Mapped[int] = mapped_column(
|
||||
Integer,
|
||||
default=0,
|
||||
nullable=False,
|
||||
)
|
||||
|
||||
# Metadata
|
||||
created_by: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True),
|
||||
default=utc_now,
|
||||
)
|
||||
updated_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True),
|
||||
default=utc_now,
|
||||
onupdate=utc_now,
|
||||
)
|
||||
|
||||
# Indexes
|
||||
__table_args__ = (
|
||||
Index("ix_knowledge_entry_type", "entry_type"),
|
||||
Index("ix_knowledge_category", "category"),
|
||||
Index("ix_knowledge_status", "status"),
|
||||
Index("ix_knowledge_created_at", "created_at"),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user