1
移行方針草案
みてるぞ edited this page 2026-03-10 23:45:37 +09:00

BTRC Hub バックエンド v2 移行仕様書草案

  • 作成日: 2026-03-10
  • 対象: BTRC Hub backend v1 → v2
  • 位置づけ: 設計見直しのための草案
  • 前提: 2026-03-08 時点の現行仕様書、ソースコード、Wiki、Issue スナップショットを踏まへた再設計案

1. 本書の目的

本書は、現行の BTRC Hub backend v1 を全面否定するための文書ではない。 むしろ、v1 で既に形になってゐる強い核を残しつつ、今後の拡張で説明コストと実装コストが膨らみやすい箇所を切り分け、v2 でどの境界を引き直すべきか を明文化するための移行仕様書である。

本書が扱ふのは主に次の 3 点である。

  1. v1 のどこが構造的な弱点になってゐるか
  2. v2 ではどのやぅなドメイン境界・テーブル境界を採るか
  3. v1 から v2 へどう段階移行するか

本書は「今すぐ全部作り直す」ことを強制するものではない。 ただし、今後も BTRC Hub を育てるのであれば、一度きちんと切り分けておかないと将来の足回りが重くなる といふ認識に立ってゐる。


2. v1 の評価

先に結論を書く。

v1 は失敗作ではない。むしろ、個人開発としてはかなり芯がある。 特に以下は v1 の明確な長所であり、v2 でも残すべきである。

  • 投稿・タグ・Wiki の三本柱が明確
  • 単なるリンク集ではなく、知識蓄積基盤として設計されてゐる
  • タグ別名、上位タグ、Wiki 履歴、外部同期、類似度といった中核機能が既に存在する
  • 外部ソースから内部知識へ変換する ETL 的発想がある
  • 監査性や履歴を重視する思想がある

一方で、v1 には「壊れてゐる」といふより、賢く作らうとして責務が寄りすぎた部分 がある。 それが今後の弱点になる。

本草案では、その弱点を次の 6 類型に整理する。

  1. 名前と概念の責務混在
  2. 現在状態と履歴の責務混在
  3. 内部概念と外部ソース表現の混在
  4. 書込みモデルに対して保存構造が凝りすぎてゐる箇所
  5. 認証・セッション・BAN の責務分離不足
  6. 将来機能のための足場が現在のモデルに混ざってゐること

3. v2 の基本方針

v2 は「機能を増やす」より先に、境界を引き直す ことを第一目的とする。

3.1 残すもの

以下は v2 でも残す。

  • Rails API + React フロントの基本構成
  • 投稿、タグ、Wiki を軸とした知識モデル
  • 外部ソース同期
  • タグ階層
  • 監査ログ・履歴の重視
  • 類似度の事前計算

3.2 捨てるのではなく再分解するもの

以下は廃止といふより、責務を再分解する。

  • tag_namestags の絡み方
  • post_tags に現在状態と履歴を同居させる構造
  • nico: プレフィクスを内部タグ空間に持ち込む方式
  • 行単位重複排除ベースの Wiki 保存構造
  • 引継ぎコードが認証・引継ぎ・セッションの責務を兼ねる方式
  • 汎用設定や将来機能の先置きテーブル

3.3 v2 設計原則

原則 1. 概念と名前を分ける

内部的に一意な概念としてのタグと、人間が入力・検索・表示する名前は分ける。

原則 2. 現在状態と履歴を分ける

今ついてゐる関係と、かつて何が起きたかを同じテーブルに詰め込まない。

原則 3. 内部知識と外部語彙を分ける

ニコニコなどの外部タグは、内部タグの一種としてではなく、外部ソースの語彙 として扱ふ。

原則 4. 書込みモデルは素直にする

編集や更新時に最も多い要求に対して、保存構造が複雑すぎる設計は避ける。

原則 5. 監査は append-only を優先する

監査のために現在値テーブルを複雑にするより、イベントログを素直に追加する。

原則 6. 検索を第一級機能として扱ふ

検索は controller の if 文の寄せ集めではなく、専用クエリレイヤとして設計する。


4. v1 の主要課題

4.1 タグ周りに責務が集まりすぎてゐる

v1 では tag_names が単なる名称辞書ではなく、以下を同時に背負ってゐる。

  • 実体名 / 別名
  • タグとの一対一対応
  • Wiki タイトルとの対応
  • canonical 化
  • 別名制約
  • プレフィクス制約

このため、タグ名に関する仕様変更がそのまま Wiki や別名ルールやカテゴリ整合性に波及する。

問題点

  • 名前レイヤと概念レイヤが癒着してゐる
  • Wiki のページタイトル制約がタグ名制約に混ざる
  • 外部タグや表記ゆれや redirect といった将来要件を吸ひ込みやすい
  • 名前に関する例外処理が tag_names 周りに集中しやすい

v2 方針

  • 概念としてのタグは tags
  • 検索・入力・旧名・同義語は tag_aliases
  • Wiki はタグと結びつけられるが、タグ名そのものの制約とは分離

4.2 post_tags が現在値テーブルと履歴テーブルを兼ねてゐる

v1 の post_tags は論理削除で履歴を保持し、作成者・削除者も持つ。 これは初期設計としては合理的だが、長期では責務が重い。

問題点

  • 今ついてゐるタグ関係と、過去に何が起きたかが同じ器に入ってゐる
  • 再付与、バッチ操作、手動操作、監査、集計で見たい粒度が異なる
  • post_count 更新や一意制約の考へ方が複雑化する

v2 方針

  • 現在有効な関係は post_taggings
  • 追加・削除イベントは post_tag_events
  • post_countpost_taggings 基準で算出または同期する

4.3 外部タグを内部タグ化してゐる

v1 ではニコニコタグを nico: 付きの内部タグとして保持し、nico_tag_relations で内部タグと結びつけてゐる。 これは ETL としては筋が良いが、表現としては内部タグ空間を汚しやすい。

問題点

  • 外部語彙と内部概念が同一モデルに見える
  • 将来 YouTube, bilibili, Pixiv などを追加した際にモデルが拡張しづらい
  • 外部タグ原文、取得元、取得時点、マッピング根拠の管理が曖昧になる

v2 方針

  • 外部語彙は source_terms
  • 外部投稿と語彙の関係は source_entry_terms
  • 外部語彙と内部タグの対応は source_term_mappings
  • 内部タグ側には nico: のやうなプレフィクスを持ち込まない

4.4 Wiki の保存構造が凝りすぎてゐる

v1 Wiki は wiki_pages, wiki_revisions, wiki_lines, wiki_revision_lines に分かれ、行単位で重複排除を行ってゐる。 思想としては美しいが、現在の開発体制と機能要求に対してはやや重い。

問題点

  • 保存構造の理解コストが高い
  • バグ時の切り分けが難しい
  • 「本文を保存し履歴を見る」といふ要求に対して内部構造が複雑すぎる
  • 競合制御はまだ十分に API へ露出してをらず、複雑さに見合ふ価値が出切ってゐない

v2 方針

  • wiki_pages
  • wiki_revisions に本文をそのまま持たせる
  • 差分は表示時または保存時に計算
  • redirect は revision kind として維持可能
  • 競合制御は base revision 明示送信で実装する

4.5 認証が軽量すぎて責務分離が弱い

v1 は引継ぎコードを中心にユーザ継続利用を実現してゐる。軽量さ自体は良いが、引継ぎコードが次を兼ねてゐる。

  • 認証要素
  • 継続ログインの鍵
  • セッション相当
  • ブラウザ間移行の鍵

問題点

  • セッション失効や監査や revoke が考へづらい
  • BAN と組み合わせた制御の拡張余地が弱い
  • 権限や認証強度の段階づけがしにくい

v2 方針

  • auth_identities に認証手段を保存
  • sessions で継続利用を管理
  • 引継ぎコードは認証方式の一種に降格
  • user / session / ban / ip linkage を分離

4.6 将来機能の足場が現在モデルに混ざってゐる

settingsparent_id など、将来構想のための足場が現行スキーマに混ざってゐる。

問題点

  • 使ってゐる概念と使ってゐない概念の境目が曖昧になる
  • API と UI と DB の整合性説明が難しくなる
  • 「存在するが使ってゐない」が増えると仕様理解コストが上がる

v2 方針

  • 今使ふ概念だけを中核スキーマに残す
  • 未来機能は issue / ADR / 設計メモに退避
  • 関係性は一般化できるものだけ一般化して先に作る

5. v2 ドメインモデル

5.1 中核モデル

posts

リンク対象の中核オブジェクト。

想定属性:

  • id
  • url
  • title
  • thumbnail_asset_id または Active Storage 参照
  • thumbnail_source_url
  • original_created_from
  • original_created_before
  • created_by_user_id
  • updated_by_user_id
  • created_at
  • updated_at

備考:

  • parent_id は廃止
  • 投稿同士の関係は post_relations へ移す

post_relations

投稿間関係を一般化する。

想定属性:

  • source_post_id
  • target_post_id
  • relation_type
  • created_by_user_id
  • created_at

想定 relation_type:

  • parent
  • duplicate
  • derived
  • alternate
  • source

5.2 タグモデル

tags

内部概念としてのタグ。

想定属性:

  • id
  • category
  • canonical_label
  • slug
  • description nullable
  • post_count
  • created_at
  • updated_at

補足:

  • canonical_label は表示上の正名
  • 一意性は slug または別管理キーで担保
  • 名前の表記ゆれは tag_aliases 側で受ける

tag_aliases

タグに紐づく入力名・別名・旧名・検索名。

想定属性:

  • id
  • tag_id
  • name
  • alias_type
  • is_primary
  • created_at
  • updated_at

想定 alias_type:

  • primary
  • synonym
  • old_name
  • search_only
  • redirect

tag_implications

v1 をほぼ踏襲するが、タグ概念を基準に維持する。

5.3 投稿とタグの関係

post_taggings

現在有効なタグ付与だけを持つ。

想定属性:

  • id
  • post_id
  • tag_id
  • created_by_user_id nullable
  • created_source_type
  • created_source_id nullable
  • created_at

制約:

  • (post_id, tag_id) 一意

post_tag_events

タグ付与イベントの監査ログ。

想定属性:

  • id
  • post_id
  • tag_id
  • event_type
  • actor_user_id nullable
  • actor_type
  • source_type
  • source_id nullable
  • occurred_at
  • metadata json

想定 event_type:

  • add
  • remove
  • import_add
  • import_remove
  • merge_rewrite

5.4 Wiki

wiki_pages

想定属性:

  • id
  • slug
  • title
  • subject_type nullable
  • subject_id nullable
  • current_revision_id
  • created_by_user_id
  • updated_by_user_id
  • created_at
  • updated_at

補足:

  • タグ対応ページは subject_type = 'Tag'
  • 独立ページも許容可能

wiki_revisions

想定属性:

  • id
  • wiki_page_id
  • kind
  • body_markdown nullable
  • redirect_target_page_id nullable
  • base_revision_id nullable
  • message nullable
  • created_by_user_id
  • created_at

想定 kind:

  • content
  • redirect

5.5 外部ソース同期

sources

外部ソース定義。

想定属性:

  • id
  • code (niconico, youtube, pixiv など)
  • name
  • created_at
  • updated_at

source_entries

外部ソース上の個別エントリ。

想定属性:

  • id
  • source_id
  • external_key
  • canonical_url
  • fetched_at
  • raw_payload json
  • created_at
  • updated_at

source_terms

外部ソース語彙。

想定属性:

  • id
  • source_id
  • raw_name
  • normalized_name
  • created_at
  • updated_at

source_entry_terms

外部エントリと外部語彙の関係。

想定属性:

  • source_entry_id
  • source_term_id
  • fetched_at

source_term_mappings

外部語彙と内部タグの対応。

想定属性:

  • id
  • source_term_id
  • tag_id
  • mapping_type
  • confidence
  • created_by_user_id nullable
  • created_at

想定 mapping_type:

  • manual
  • rule
  • suggested

5.6 主体モデル

subjects

人物・団体・キャラクタ・投稿者等を統一的に扱ふ場合に導入する。

想定属性:

  • id
  • subject_type
  • display_name
  • created_at
  • updated_at

subject_identities

外部サービス上の主体識別子。

想定属性:

  • id
  • subject_id
  • source_id
  • external_code
  • created_at
  • updated_at

備考:

  • v1 deerjikists を一般化した形
  • v2 初期段階では必須ではないが、将来の拡張性は高い

5.7 認証・権限

users

想定属性:

  • id
  • display_name
  • role
  • status
  • created_at
  • updated_at

auth_identities

想定属性:

  • id
  • user_id
  • provider_type
  • secret_hash
  • last_used_at
  • created_at
  • updated_at

想定 provider_type:

  • transfer_code
  • passwordless_token
  • oauth など将来拡張

sessions

想定属性:

  • id
  • user_id
  • session_token_hash
  • expires_at
  • last_seen_at
  • created_ip_id nullable
  • user_agent nullable
  • created_at
  • updated_at

ip_addresses

v1 を踏襲。ただし user_ipssessions との役割分担を明確にする。

user_bans

想定属性:

  • id
  • user_id nullable
  • ip_address_id nullable
  • reason
  • starts_at
  • ends_at nullable
  • created_by_user_id
  • created_at

6. v1 → v2 対応表

v1 v2 方針
posts posts 基本踏襲。ただし parent_id 廃止
post_tags post_taggings + post_tag_events 現在状態と履歴を分離
tags tags 概念として維持
tag_names tag_aliases へ再編 名前責務を分離
tag_implications tag_implications 維持
nico_tag_relations source_term_mappings 外部語彙対応へ再編
deerjikists subject_identities または専用互換層 一般化
wiki_pages wiki_pages subject 参照型へ見直し
wiki_revisions + wiki_lines + wiki_revision_lines wiki_revisions 本文保存へ単純化
users users role は維持
inheritance_code auth_identities 認証手段へ分離
user_ips user_ips + sessions + user_bans 責務整理
settings 一旦保留 or feature-specific table 汎用設定を急がない
user_post_views user_post_views 維持可
post_similarities post_similarities 維持
tag_similarities tag_similarities 維持

7. v1 データ移行方針

7.1 投稿

posts は基本的にそのまま移す。

変換ルール

  • url, title, thumbnail, thumbnail_base, original_created_from, original_created_before は踏襲
  • uploaded_user_idcreated_by_user_id へ写す
  • parent_id は廃止し、存在するデータがあれば post_relationsrelation_type = 'parent' に変換する

7.2 タグ / タグ名

v1 構造

  • tags が概念
  • tag_names が名称辞書
  • tag_names.canonical_id で別名

v2 変換ルール

  1. tags を v2 tags に移す
  2. 各 tag の正名は v1 tag_name.name から canonical_label へ移す
  3. 正名は同時に tag_aliasesalias_type = 'primary' として追加する
  4. canonical_id を持つ tag_names は、対応する v2 tag_aliasesalias_type = 'synonym' として追加する
  5. Wiki タイトルとしてのみ存在し、タグを持たない tag_names はタグへは変換せず、Wiki 側のページタイトルとして扱ふ

備考

この変換で、v1 の tag_names が担ってゐた「名前の辞書」「タグ実体」「Wiki タイトル」といふ三重責務を解体する。

7.3 投稿タグ付け

v1 構造

  • post_tags.discarded_at IS NULL が現在有効
  • 論理削除が履歴も兼ねる

v2 変換ルール

  1. discarded_at IS NULL の行は post_taggings へ移す
  2. post_tags 行から post_tag_events を生成する
    • 追加イベント: created_at
    • 削除イベント: discarded_at がある場合のみ生成
  3. created_user_id, deleted_user_id は actor として転記する
  4. deleted_user_id IS NULL かつ削除済みなら actor_type = 'system' とする

注意点

v1 の論理削除行は履歴として保存されてゐるので、監査情報は概ね保持可能である。 ただし、v1 にはイベント ID が存在しないため、完全な逐次イベント列としての厳密性は移行時に再構成する

7.4 ニコニコタグ連携

v1 構造

  • nico カテゴリタグとして内部タグ化
  • nico_tag_relations で内部タグと結びつける

v2 変換ルール

  1. category = 'nico' のタグは v2 内部タグとしては移さない
  2. これらは source_terms へ変換する
    • source = 'niconico'
    • raw_namenico: プレフィクスを外した形を基本とする
  3. nico_tag_relationssource_term_mappings に変換する
  4. 各投稿に付いてゐる nico タグは source_entry_terms に変換する
  5. 同期バッチは v2 以降、source_entry_termssource_term_mappingspost_taggings といふ流れで内部タグへ反映する

効果

  • 内部タグ空間から nico: プレフィクスを除去できる
  • 将来の他ソース追加時に同じ枠組みで扱へる

7.5 ニジラー / deerjikists

v1 構造

  • (platform, code) を主キーとし tag_id に紐づけ

v2 変換案 A: 当面互換維持

  • v2 初期では deerjikists を暫定残置
  • 周辺だけ API 層でラップする

v2 変換案 B: 一般化

  1. subjects を作成
  2. deerjikist カテゴリのタグごとに subject を作る
  3. subject_identities(platform, code) を移す
  4. タグとは subject_tags または subject.primary_tag_id で結ぶ

推奨

v2 初期の移行負荷を下げるなら 案 A、中期で多用途化するなら 案 B。 本草案では、移行第一段階では案 A、v2.1 以降で B へ進めることを推奨する。

7.6 Wiki

v1 構造

  • wiki_pages
  • wiki_revisions
  • wiki_lines
  • wiki_revision_lines

v2 変換ルール

  1. wiki_pages を v2 wiki_pages に移す
  2. 各 revision について本文を復元し、wiki_revisions.body_markdown に保存する
  3. redirect revision は kind = 'redirect' のまま移す
  4. tag_name_id 依存は titleslug および subject_type, subject_id へ再編する
  5. タグと 1 対 1 に対応する Wiki は subject_type = 'Tag', subject_id = tag.id に変換する

注意点

v2 では wiki_lines / wiki_revision_lines は廃止するため、行単位 dedupe は移行時点で終了する。 これはデータ損失ではなく、保存形式の単純化である。

7.7 ユーザ認証

v1 構造

  • users.inheritance_code
  • X-Transfer-Code による継続認証

v2 変換ルール

  1. users を v2 users に移す
  2. inheritance_codeauth_identities へ移し、provider_type = 'transfer_code' とする
  3. 現行クライアントの互換のため、一定期間 X-Transfer-Code を受け付ける互換 API を残す
  4. サーバ側では受け付け時に session を発行し、徐々にセッション方式へ移行する

備考

この互換層を置くことで、フロントを一気に書き換へずに済む。


8. API 設計方針

8.1 互換方針

v2 は可能な限り読み取り API を先に互換維持し、書込み API から徐々に切り替へる。

優先順位

  1. 既存フロントが壊れないこと
  2. 内部データの境界整理
  3. 最終的な API の純化

8.2 読み取り API

以下は v1 互換をある程度維持可能である。

  • GET /posts
  • GET /posts/:id
  • GET /tags
  • GET /tags/autocomplete
  • GET /wiki
  • GET /wiki/:id
  • GET /wiki/title/:title

ただし内部では、v2 テーブルや query object を参照する実装へ切り替へる。

8.3 書込み API

以下は v2 化の影響を受けやすい。

  • POST /posts
  • PUT /posts/:id
  • PUT /tags/nico/:id 相当
  • POST /wiki
  • PUT /wiki/:id
  • POST /users/verify

これらは互換 API を一旦残しつつ、内部実装を command / service object へ切り出してから v2 モデルへ接続する。

8.4 検索 API

v2 では検索を query layer に集約する。

想定クラス:

  • PostSearchQuery
  • TagAutocompleteQuery
  • WikiSearchQuery
  • SourceTermMappingQuery

検索文法の目標例:

喜多郁代 合作 -R-18 source:niconico order:updated_at:desc

または将来的には次のやぅな DSL へ寄せる。

tag:喜多郁代 tag:合作 -tag:R-18 source:niconico sort:updated

9. 実装移行ステップ

フェーズ 0. 準備

目的:

  • v2 テーブル群を追加するが、既存 API はまだ v1 を使ふ

作業:

  • 新テーブル作成
  • 変換用 service / rake task 作成
  • 整合性確認用スクリプト作成

完了条件:

  • v1 本番データから v2 へバックフィルできる

フェーズ 1. 読み取り専用バックフィル

目的:

  • v1 から v2 への初回コピーを行ふ

作業:

  • tags / tag_aliases 生成
  • post_taggings / post_tag_events 生成
  • wiki_revisions.body_markdown 復元
  • auth_identities 生成

完了条件:

  • v1 と v2 で主要件数が整合する

確認項目:

  • 投稿件数
  • タグ件数
  • 有効タグ付与件数
  • Wiki ページ数
  • revision 数
  • user 数

フェーズ 2. 二重書込み

目的:

  • v1 API を維持したまま v2 にも同時書込みする

作業:

  • 投稿追加・更新時、v1 と v2 の両方へ反映
  • Wiki 更新時、v1 と v2 の両方へ反映
  • 認証時、互換層経由で session も発行

注意:

  • 二重書込みは最も事故りやすい層なので、対象を絞る
  • 最初から全部ではなく、投稿 → Wiki → 認証の順で段階導入する

フェーズ 3. 読み取りの v2 切替

目的:

  • 一部 read API を v2 読みへ切り替へる

推奨順:

  1. タグ補完
  2. Wiki 詳細
  3. 投稿履歴
  4. 投稿一覧 / 詳細

完了条件:

  • フロントの主要画面が v2 読みで正常動作する

フェーズ 4. 外部同期バッチ切替

目的:

  • nico:sync を v2 モデル前提で再実装する

新フロー:

  1. 外部データ取得
  2. source_entries 更新
  3. source_terms / source_entry_terms 更新
  4. source_term_mappings に基づき内部タグ集合を導出
  5. post_taggings 同期
  6. post_tag_events 記録

フェーズ 5. 旧モデル参照停止

目的:

  • API / batch / admin tool から v1 専用テーブルへの直接依存を止める

対象:

  • tag_names
  • post_tags
  • wiki_lines
  • wiki_revision_lines
  • users.inheritance_code 直参照
  • nico カテゴリタグ依存ロジック

フェーズ 6. 旧モデル整理

目的:

  • v1 専用構造を正式に廃止する

条件:

  • 監査・履歴・検索・同期の全主要系が v2 で動くこと
  • 差分検証が一定期間安定してゐること

10. フロントエンド影響

10.1 影響が小さい箇所

  • 投稿一覧表示
  • 投稿詳細表示
  • Wiki 表示
  • タグ補完 UI

これらは API 互換が維持できれば大きく変へずに済む。

10.2 影響が大きい箇所

  • ニコニコ連携画面
  • タグ名 / 別名管理 UI
  • ユーザ引継ぎ UI
  • 投稿更新処理の排他制御

10.3 フロントで先に直すべきこと

  1. 書込み API を command 指向に合わせて整理する
  2. updated_at 依存または revision id 依存の排他制御パラメータを明示送信できるやうにする
  3. 引継ぎコード前提の利用状態をセッション前提へ徐々に移す

11. 非互換変更

以下は v2 で非互換になる可能性が高い。

11.1 nico: タグの直接露出

内部タグとしての nico: は廃止する。 よって、既存 API で nico: をタグとしてそのまま返してゐる箇所は、将来的に外部語彙情報として返す形へ変はる。

11.2 tag_names 直接依存

フロントや管理ツールが tag_name_idcanonical_id に依存してゐる場合、そのままでは使へなくなる。

11.3 post_tags の解釈

discarded_at ベースの関係履歴は post_tag_events へ移るため、旧仕様を前提にした直接 SQL は壊れる。

11.4 Wiki revision 構造

wiki_lines / wiki_revision_lines 前提の内部構造は消える。


12. リスク

12.1 二重書込み不整合

最も危険。 対策:

  • 対象操作を絞る
  • 冪等設計を徹底する
  • 差分検証バッチを持つ

12.2 タグ移行時の alias 崩れ

tag_names.canonical_id 由来の alias 変換で不整合が起きる可能性がある。 対策:

  • 変換前後で検索結果差分を確認
  • 代表タグごとに snapshot 比較を行ふ

12.3 ニコニコ同期の意味変化

v1 の nico: は内部タグでもあったため、完全分離すると挙動差が出る可能性がある。 対策:

  • まずは read API 上で v1 互換表現を残す
  • 内部的にのみ分離する

12.4 Wiki 本文復元の取りこぼし

行ベース保存から本文復元する処理は要注意。 対策:

  • 全 revision の復元テスト
  • tree hash と body hash の照合

12.5 認証移行時のログイン継続性

引継ぎコード方式から session 方式へ寄せる過程で、既存ユーザが弾かれると痛い。 対策:

  • 当面は X-Transfer-Code 互換を残す
  • セッション導入は透過的に始める

13. 実装優先順位

v2 を全部一気にやる必要はない。 優先順位は以下を推奨する。

優先度 A

  1. タグ体系の再分解
  2. post_tags の現在値 / 履歴分離
  3. 外部タグ表現の分離

優先度 B

  1. Wiki 保存構造の単純化
  2. 認証 / session / ban 整理
  3. 検索 query layer の独立

優先度 C

  1. deerjikists の一般化
  2. 設定や周辺機能の再整理
  3. 互換 API の整理・削除

14. この草案でまだ決め切ってゐないこと

以下は本草案の時点では保留とする。

  1. タグ slug を必須にするか
  2. subjects を v2 初期で入れるか、v2.1 以降に送るか
  3. settings を完全廃止するか、feature-specific table に分解するか
  4. post_count を同期値として持つか、集計結果として算出するか
  5. Wiki をタグ直結主体に寄せるか、独立ページを本格サポートするか

15. 推奨する最初の一手

今すぐ着手するなら、最初の一手はこれがよい。

案 1. 最小リスク路線

  • post_taggings
  • post_tag_events
  • tag_aliases

だけ先に追加し、既存 API を壊さず移行を始める。

案 2. 将来最適路線

  • 上記に加へて source_terms 系も一気に入れる
  • nico: モデル依存を早めに絶つ

推奨

現実的には 案 1 → 案 2 の順がよい。 理由は単純で、post_tagstag_names が今の詰まりの中心だからである。 ここを割るだけでも設計はかなり呼吸しやすくなる。


16. まとめ

v1 の問題は、思想が弱いことではない。 むしろ逆で、思想が強いがゆゑに責務が一箇所へ寄ってゐることが問題である。

v2 の目的は機能追加ではなく、以下の 3 つを回復することにある。

  1. 概念と名前の分離
  2. 現在状態と履歴の分離
  3. 内部知識と外部ソースの分離

この 3 つを守れば、BTRC Hub は単なるリンク集の延長ではなく、長く育てられる知識基盤になる。 逆にここを曖昧にしたまま機能を足し続けると、今後は毎回「どこに責務を置くのか」の議論からやり直すことになる。

本草案はまだ確定仕様ではない。 ただし、v1 を踏まへた v2 の叩き台としては十分に使へる水準 を狙ってゐる。