tech / note タブの posts 統合(type 概念の廃止 スコープ1)
起票日: 2026-07-11
ステータス: スコープ1 完了(スコープ2 = DB クリーンアップは未着手)
起票理由
タブ(tech / note)と記事の type カラムによる分類は、タグ階層のルート(tech/ / misc/)と完全に重複していた。タグ絞り込みがサーバーサイド化されたことで「misc や tech のルートタグで絞る」ことが可能になり、type は冗長な分類軸になったため、タブを posts に統合して type 概念を廃止する。
2段階で進める。
スコープ1(本タスク): API から
typeパラメータ / レスポンスフィールドを廃止し、web を posts タブ化する。DB は無変更(articles.typeカラムとtag_article_counts.typeは残るが読み取りに使わない)スコープ2(別タスク): DB クリーンアップ。
articles.typeカラム削除、インデックス(user_id, status, type, published_at, article_id)→(user_id, status, published_at, article_id)への張り替え、tag_article_countsの PK から type を除去、frontmatter パーサのtype必須解除、webhook 書き込みパスからの type 除去
設計方針
論点 |
決定 |
|---|---|
タブ構成 |
|
|
設定しない(404 で許容) |
タグパネルのツリー |
root 剥がしをやめ、第1階層にルートタグ( |
タグの表記 |
UI・URL ともフルパス(例: |
ファセット集計 |
|
RSS フィード |
従来 tech のみ配信 → 全記事配信に変更(仕様変更として認識済み) |
記事詳細の OGP 出し分け |
旧 |
変更内容
blog-api
GET /users/{name}/articlesとGET /users/{name}/articles/tag-facetsのtype必須クエリパラメータを廃止(全公開記事が対象になる)一覧・詳細レスポンスから
typeフィールドを削除kernel:UsersArticlesRepository::find_published_by_user_name_and_type→find_published_by_user_nameにリネームしArticleType引数を除去adapter: 一覧 / COUNT / ファセット SQL からAND a.type = ?を除去。フィルタなしファセットはtag_article_countsを type 横断で SUM 集計に変更webhook 書き込みパス(frontmatter の
type必須、tag_article_countsの type 単位再計算)はスコープ1では無変更
apps/web
BaseLayout: タブをposts/aboutの2つに変更/type/note・/type/note/page/[page]ルートを削除(リダイレクトなし)lib/api.ts:getArticlesByType→getArticles(type 引数廃止)、getTagFacetsの type 引数廃止、Article/ArticleSummaryからtypeフィールド削除TagFilterProvider/FilteredArticleList/lib/tagFilter.ts:tagRoot概念とtoRelativeTagsを廃止し、選択タグ・表示タグをフルパスに統一。buildTagTreeFromFacetsはルートタグを第1階層に持つツリーを返すfeed/route.ts: 全記事配信に変更、sitemap.ts: 2回フェッチ → 1回に簡素化記事詳細
generateMetadata: OGP 出し分けをmiscルートタグの有無で判定DESIGN.md/apps/web/CLAUDE.mdのタブラベル記述をposts/aboutに更新
検証
# blog-api
cd apps/blog-api
cargo check --workspace
cargo test --workspace # 全 pass
cargo clippy --workspace --all-targets
# web
cd apps/web
bun test # tagFilter 14 tests pass
bun run type-check
bun run build # ルート一覧から /type/note が消えることを確認
# リポジトリ全体
bun run lint
注意点 / 残課題
タグなし記事はタグ絞り込みで拾えない。旧 note 記事に
misc/タグが付いていない場合、posts 一覧には出るが「misc で絞る」ことができず、記事詳細の OGP も大カード扱いになる。全記事に最低1つルート配下のタグが付いていることを確認すること一覧クエリはインデックス
(user_id, status, type, published_at, article_id)のプレフィックス(user_id, status)までしか効かず、published_at 順は Top-N ソートになる。現状の記事数では問題ないが、スコープ2でインデックスを張り替える/type/noteへの旧リンクは 404 になる(意図的にリダイレクトを設定していない)デプロイ順は API → web。旧 API は
type必須のため新 web を先に出すと一覧が 400 になる。逆(新 API + 旧 web)はtypeパラメータが無視されるだけで動くフォローアップ: 旧タブの代替であるルートタグの発見性が低かったため、タグ UI を画面下部固定の
FloatingTagFilter(IDE 風ツリーTagFilterTree)に刷新し、ヘッダー・タブ行・一覧をBaseLayout narrowで同一の中央カラムに揃えた。ヘッダーの tags トグルとインラインのTagFilterPanelは廃止