# Data Layer Architecture

> Bronze Layer（LLM抽出ログ層）とGold Layer（確定データ層）の2層アーキテクチャ設計。LLM抽出結果の履歴管理と人間修正の保護を実現。抽出処理の実装、ExtractionLogの使用、is_manually_verifiedフラグの扱いに関するガイダンスを提供。

- Skill: `majiayu000/data-layer-architecture` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds add majiayu000/data-layer-architecture`
- Raw SKILL.md: https://api.skillmd.com/api/skills/majiayu000/data-layer-architecture/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: majiayu000 (https://skillmd.com/u/majiayu000)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/majiayu000/data-layer-architecture

---


# Data Layer Architecture（Bronze Layer / Gold Layer）

## Purpose
LLM抽出結果と確定データを分離する2層アーキテクチャの設計ガイド。AIの抽出履歴を保持しながら、人間の修正を保護する。

## When to Activate
このスキルは以下の場合にアクティベートされます：
- LLM抽出処理を新規実装する時
- ExtractionLogエンティティを使用する時
- `is_manually_verified`フラグを扱う時
- 抽出結果からGoldエンティティを更新する時
- Bronze/Gold Layerの設計について質問された時

## Architecture Overview

```
┌─────────────────────────────────────────────────────────────┐
│                    Bronze Layer（抽出ログ層）                 │
│                                                              │
│  - LLM抽出結果を追記専用（Immutable）で保存                   │
│  - 精度分析・トレーサビリティのための履歴                      │
│  - テーブル: extraction_logs                                 │
└─────────────────────────────────────────────────────────────┘
                              │
                              │ is_manually_verified = false の場合のみ反映
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                    Gold Layer（確定データ層）                  │
│                                                              │
│  - アプリケーションが参照する唯一の正解データ                   │
│  - 人間の修正が優先される                                     │
│  - テーブル: statements, politicians, speakers, etc.         │
└─────────────────────────────────────────────────────────────┘
```

## Design Principles

### 1. Bronze Layer（抽出ログ層）
- **目的**: LLM抽出結果の履歴保持、精度分析
- **特性**: 追記専用（Immutable）、削除・更新なし
- **用途**:
  - AIモデル改善の検証データ
  - 抽出精度の時系列分析
  - デバッグ・トラブルシューティング

### 2. Gold Layer（確定データ層）
- **目的**: ユーザーに提供する正解データ
- **特性**: 人間の修正が最優先
- **用途**:
  - Streamlit UIでの表示
  - API経由でのデータ提供
  - レポート・分析の基礎データ

## Data Flow

```
LLM抽出実行
    │
    ▼
┌────────────────────────────┐
│ ExtractionLog に必ず保存    │  ← Bronze Layer（常に履歴として残る）
│ （Immutable）               │
└────────────────────────────┘
    │
    ▼
┌────────────────────────────┐
│ is_manually_verified?      │
└────────────────────────────┘
    │                │
    │ false          │ true
    │（未検証）       │（検証済み）
    ▼                ▼
┌──────────┐    ┌──────────────────┐
│ Gold更新  │    │ Gold更新しない    │
│          │    │（人間の修正を保護）│
└──────────┘    └──────────────────┘
```

## Target Entities

| 抽出オブジェクト（Bronze） | → | 確定オブジェクト（Gold） |
|---------------------------|---|-------------------------|
| StatementExtraction | → | Statement（発言） |
| PoliticianExtraction | → | Politician（政治家） |
| SpeakerExtraction | → | Speaker（話者） |
| ConferenceMemberExtraction | → | ConferenceMember（会議体メンバー） |
| ParliamentaryGroupMemberExtraction | → | ParliamentaryGroupMember（議員団メンバー） |

## Key Components

### ExtractionLog Entity

```python
class EntityType(Enum):
    STATEMENT = "statement"
    POLITICIAN = "politician"
    SPEAKER = "speaker"
    CONFERENCE_MEMBER = "conference_member"
    PARLIAMENTARY_GROUP_MEMBER = "parliamentary_group_member"

@dataclass
class ExtractionLog:
    id: UUID
    entity_type: EntityType          # どのエンティティの抽出か
    entity_id: UUID                  # 対象GoldエンティティのID
    pipeline_version: str            # "gemini-2.0-flash-v1" など
    extracted_data: dict             # AIが出した生データ（JSON）
    confidence_score: Optional[float]
    extraction_metadata: dict        # モデル名、トークン数等
    created_at: datetime             # Immutable
```

### Gold Entity Common Fields

```python
# 全Goldエンティティ（Statement, Politician等）に追加
is_manually_verified: bool = False      # 人間が検証済みか
latest_extraction_log_id: Optional[UUID] # 最新の抽出ログへの参照
```

## Behavior Rules

| 状態 | AI再抽出時の動作 | 理由 |
|------|-----------------|------|
| `is_manually_verified = false` | Gold Layerを更新 | 最新AIの精度向上を反映 |
| `is_manually_verified = true` | Gold Layerは更新しない | 人間の判断を最優先 |
| （両方） | Bronze Layerには常に保存 | 履歴・分析用 |

## Implementation Guide

### Adding New Extraction Process

1. `UpdateEntityFromExtractionUseCase` を継承して実装
2. 抽出結果は必ず `ExtractionLog` に保存
3. `is_manually_verified` フラグをチェックしてから Gold を更新

```python
class UpdateStatementFromExtractionUseCase(UpdateEntityFromExtractionUseCase):
    async def execute(
        self,
        entity_id: UUID,
        extraction_result: StatementExtractionResult,
        pipeline_version: str
    ) -> UpdateEntityResult:
        # 1. Bronze Layer: 抽出ログを必ず保存
        log = ExtractionLog(
            entity_type=EntityType.STATEMENT,
            entity_id=entity_id,
            pipeline_version=pipeline_version,
            extracted_data=extraction_result.to_dict(),
            ...
        )
        log_id = await self._extraction_log_repo.save(log)

        # 2. Gold Layer: 人間修正済みならスキップ
        entity = await self._statement_repo.find_by_id(entity_id)
        if entity.is_manually_verified:
            return UpdateEntityResult(updated=False, reason="manually_verified")

        # 3. Gold Layer: 未検証なら更新
        entity.update_from_extraction(extraction_result)
        entity.latest_extraction_log_id = log_id
        await self._statement_repo.save(entity)

        return UpdateEntityResult(updated=True)
```

### Handling Human Modifications

1. Gold エンティティを直接更新
2. `is_manually_verified = true` をセット
3. 以降のAI再抽出では上書きされない

```python
async def mark_as_verified(entity_id: UUID) -> None:
    entity = await repo.find_by_id(entity_id)
    entity.is_manually_verified = True
    await repo.save(entity)
```

## Quick Checklist

新しい抽出処理を実装する際のチェックリスト：

- [ ] `ExtractionLog` にログを保存しているか
- [ ] `is_manually_verified` をチェックしているか
- [ ] `latest_extraction_log_id` を更新しているか
- [ ] `pipeline_version` を適切に設定しているか
- [ ] エラー時もログが保存されるか
- [ ] 単体テストを書いたか

## Related Issues
- Product Goal: [#813](https://github.com/trust-chain-organization/sagebase/issues/813)
- Implementation PBIs: #861〜#872

## References
- [ARCHITECTURE.md](docs/ARCHITECTURE.md): System architecture overview
- [DOMAIN_MODEL.md](docs/DOMAIN_MODEL.md): Domain entities
- [DATABASE_SCHEMA.md](docs/DATABASE_SCHEMA.md): Database structure

