ここは あなたOS のワークフローをそのままデータ構造に落とし込むのが最も美しい。
以下は「ニュース → 分類 → 特許請求項 → 下書き → OR選択 → 投稿」という流れを 最小状態遷移モデルとして整理したデータベース設計です。

構造は 5つの主要テーブル + 2つの補助テーブルで完結します。


🧱 データベース設計(テーブル定義)

1. news_items(ニュース記事の原文ストア)

外界から入ってくる「生データ」。
OS の Input Buffer に相当。

CREATE TABLE news_items (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    external_id VARCHAR(255) NOT NULL,   -- RSSのGUIDやURLハッシュ
    title TEXT NOT NULL,
    url TEXT NOT NULL,
    source VARCHAR(255),
    published_at DATETIME,
    content MEDIUMTEXT,                  -- 本文(全文 or 抽出)
    fetched_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY (external_id)
);

2. classifications(事故/警鐘/失敗の分類結果)

Gemini の一次解釈。
あなたOS の「意味レイヤー」

CREATE TABLE classifications (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    news_id BIGINT NOT NULL,
    category ENUM('事故','警鐘','失敗','その他') NOT NULL,
    reason TEXT,                          -- なぜその分類になったか
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (news_id) REFERENCES news_items(id)
);

3. patent_drafts(技術特許/政策特許の請求項生成)

Gemini の二次解釈。
あなたOS の「変換レイヤー(IR生成)」

CREATE TABLE patent_drafts (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    news_id BIGINT NOT NULL,
    classification_id BIGINT NOT NULL,
    kind ENUM('技術特許','政策特許') NOT NULL,
    summary TEXT,                         -- 特許の要約
    claims JSON NOT NULL,                 -- ["請求項1...", "請求項2..."]
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (news_id) REFERENCES news_items(id),
    FOREIGN KEY (classification_id) REFERENCES classifications(id)
);

4. blog_drafts(はてなブログ投稿用の下書き)

あなたが OR 選択するための 中間バッファ
あなたOS の「意思決定レイヤー」。

CREATE TABLE blog_drafts (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    patent_draft_id BIGINT NOT NULL,
    title TEXT NOT NULL,
    body MEDIUMTEXT NOT NULL,
    status ENUM('pending','approved','posted','discarded') 
           NOT NULL DEFAULT 'pending',
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (patent_draft_id) REFERENCES patent_drafts(id)
);

5. posted_logs(実際に投稿された記事のログ)

Output Layer(I/Oデバイス)
はてなブログ AtomPub の結果を記録。

CREATE TABLE posted_logs (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    blog_draft_id BIGINT NOT NULL,
    hatena_entry_id VARCHAR(255) NOT NULL,
    posted_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (blog_draft_id) REFERENCES blog_drafts(id)
);

🔧 補助テーブル

6. processed_news(重複処理防止)

ニュース巡回時の Dedup 用。

CREATE TABLE processed_news (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    external_id VARCHAR(255) NOT NULL,
    processed_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY (external_id)
);

7. system_settings(巡回設定・APIキーなど)

アプリ設定の保存。

CREATE TABLE system_settings (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(255) NOT NULL UNIQUE,
    value TEXT NOT NULL
);

🧩 全体の状態遷移(あなたOSのミニマルモデル)

news_items
    ↓ (分類)
classifications
    ↓ (特許生成)
patent_drafts
    ↓ (ブログ下書き)
blog_drafts (pending)
    ↓ あなたの OR 選択
blog_drafts (approved)
    ↓ AtomPub 投稿
posted_logs

この 直線的な状態遷移 があなたの OS と完全に一致している。


🌱 あなたの OS に合わせた特徴

1. 意味レイヤーと構造レイヤーを分離

  • news_items = 生データ
  • classifications = 意味
  • patent_drafts = 構造化(請求項IR)
  • blog_drafts = 出力フォーマット

あなたの「意味と構造の分離」思想をそのまま反映。


2. OR 選択を中心に据えた設計

あなたの OS の核は「AI はスカウト、あなたが OR 選択」。

そのため:

  • blog_drafts.status = pending → approved → posted
    という 人間中心の状態遷移を採用。

3. 請求項は JSON 配列で保持

あなたの「IR(中間表現)としての請求項」をそのまま保持できる。


✨ 次に進むなら

  • API 設計(REST / GraphQL)
  • バックエンド構成(FastAPI / Flask / Rails)
  • Review UI のワイヤーフレーム
  • はてなブログ投稿モジュールの実装

どこを深掘りしたい?