6 課題整理
みてるぞ edited this page 23 hours ago

タグ広場 今後の Gitea Issue 草案

  • レビュー日: 2026-04-27
  • 対象: btrc-hub-feature_317.zip 静的レビュー、仕様書、既存 Gitea issue dump
  • 注意: この環境では bundlenode_modules が無く、RSpec / frontend build は実行できていない。よって「コード上の疑い」と「実装提案」を含む。

優先度の目安

  • P0: 公開前に塞がないと危険
  • P1: 中核機能・データ整合性・運用上かなり重要
  • P2: 早めに直すべき改善・機能
  • P3: 余力で育てるゼロイチ・快適化

既存 issue 棚卸しメモ

  • #164 タグ検索機能作成#171 OR/NOT 検索 は、現ソースでは概ね実装済みに見える。close するか、残作業に title/body を更新する。
  • #165 管理者用別名タグ作成画面#169/#170 ユーザ一覧/詳細#137 設定画面反映#150 Wiki画像アップロード#151 Wiki検索自動補完#180 タグサイドバー見切れ#237 同定文字 はまだ有効な核として扱う。
  • bot操作 削減系は似た issue が多いので、バッチ仕様 issue に統合してから残タスクへ分解した方がよい。

Issue 草案一覧(90 件)

2. [P0] preview API の SSRF 対策を入れる

種別: security

対象

  • backend/app/controllers/preview_controller.rb
  • backend/lib/screenshot.js

背景 / 問題
/preview/title と /preview/thumbnail が任意 URL を外部取得している。private IP、localhost、メタデータ IP、file:// 相当、巨大レスポンス、リダイレクト経由を遮断しないと SSRF の入口になる。

完了条件

5. [P0] GET /users/me を query code 依存から current_user 依存に直す

種別: security / design

対象

  • backend/app/controllers/users_controller.rb
  • frontend/src/App.tsx
  • frontend/src/lib/api.ts

背景 / 問題
UsersController#me が params[:code] でユーザを探し、inheritance_code まで返している。認証ヘッダを使う設計と不一致で、コードが URL やログに載る導線を残している。

完了条件

6. [P0] 一覧・履歴・コメント系 API に limit 上限を設ける

種別: performance / security

対象

  • backend/app/controllers/posts_controller.rb
  • backend/app/controllers/tags_controller.rb
  • backend/app/controllers/nico_tags_controller.rb
  • backend/app/controllers/materials_controller.rb
  • backend/app/controllers/theatre_comments_controller.rb

背景 / 問題
複数 API が limit をほぼ無制限に受け付ける。小さいサイトでも、公開直後に巨大 limit 一発で DB と JSON 生成が詰まる。

完了条件

7. [P0] 外部 iframe / Markdown リンクに CSP と sandbox 方針を入れる

種別: security

対象

  • frontend/src/components/PostEmbed.tsx
  • frontend/src/components/WikiBody.tsx
  • backend/config/initializers/*

背景 / 問題
投稿埋め込みや Wiki Markdown は外部 URL と強く結びつく。公開するなら CSP、iframe sandbox、許可ドメイン、クリックジャック対策を明示しないと XSS 周辺の事故面積が広い。

完了条件

14. [P1] WikiHistoryPage の null user クラッシュを防ぐ

種別: bug

対象

  • frontend/src/pages/wiki/WikiHistoryPage.tsx
  • backend/app/controllers/wiki_pages_controller.rb

背景 / 問題
バックエンドは user が nil の履歴を返しうるが、フロントは change.user.id を直参照している。bot 操作や古い移行データで落ちる。

完了条件

15. [P1] React Hooks の条件付き呼び出しを修正する

種別: bug / frontend

対象

  • frontend/src/pages/posts/PostHistoryPage.tsx
  • frontend/src/pages/wiki/WikiNewPage.tsx
  • frontend/src/pages/wiki/WikiEditPage.tsx

背景 / 問題
tagId ? useQuery(...) : ... のような条件付き hook と、権限分岐 return の前後で hook 数が変わる箇所がある。React の基本契約違反で、状態破壊の地雷。

完了条件

17. [P1] タグ補完の stale state バグを直す

種別: bug / UX

対象

  • frontend/src/components/TagSearch.tsx
  • frontend/src/components/common/TagInput.tsx
  • frontend/src/components/PostFormTagsArea.tsx

背景 / 問題
setSuggestions(data) の直後に古い suggestions.length を見て visible を決める箇所がある。初回補完が表示されない等の微妙な挙動になる。

完了条件

18. [P1] タグ名を URL に入れる箇所で encodeURIComponent を徹底する

種別: bug

対象

  • frontend/src/lib/tags.ts
  • frontend/src/components/TagLink.tsx
  • frontend/src/lib/prefetchers.ts
  • frontend/src/components/TopNav.tsx

背景 / 問題
fetchTagByName などでタグ名をそのまま URL に入れている。スラッシュ、空白、?、#、日本語正規化絡みで route が壊れる。

完了条件

19. [P1] TanStack Query key の id/name 衝突を分離する

種別: bug / frontend

対象

  • frontend/src/lib/queryKeys.ts
  • frontend/src/lib/tags.ts
  • frontend/src/lib/wiki.ts

背景 / 問題
tagsKeys.show が ID と名前の両方に使われている。名前が数字のタグや、Wiki の id/title でもキャッシュ衝突が起こりうる。

完了条件

20. [P1] TagsController#index の count で Relation 全体をロードしない

種別: performance

対象

  • backend/app/controllers/tags_controller.rb

背景 / 問題
count に q.size を使うと、includes 済み relation のロード状況次第で全件メモリ展開になる。タグ数が増えるほど鈍い毒になる。

完了条件

26. [P2] 投稿編集で URL とサムネイルを扱えるようにするか、非対応を UI に明記する

種別: feature / UX

対象

  • backend/app/controllers/posts_controller.rb
  • frontend/src/components/PostEditForm.tsx

背景 / 問題
投稿作成では URL/thumbnail を扱うが、更新では URL/thumbnail 更新がない。実運用ではリンク修正とサムネ更新が必ず出る。

完了条件

32. [P1] Material 更新時に file 未指定で既存ファイルを purge しない

種別: bug

対象

  • backend/app/controllers/materials_controller.rb

背景 / 問題
MaterialsController#update は file が無いと既存 file を purge する。タグ名や URL だけ編集したつもりでファイルが消える。

完了条件

33. [P2] Material 作成時の nil attach を避ける

種別: bug

対象

  • backend/app/controllers/materials_controller.rb

背景 / 問題
URL のみ素材でも material.file.attach(file) が呼ばれる。nil attach が環境差で例外化する可能性がある。

完了条件

36. [P1] Theatre コメントに件数上限・長さ上限・削除を入れる

種別: moderation / performance

対象

  • backend/app/controllers/theatre_comments_controller.rb
  • backend/app/models/theatre_comment.rb
  • frontend/src/pages/theatres/TheatreDetailPage.tsx

背景 / 問題
コメント index は no_gt 以降を上限なしで返し、投稿内容の長さ制限も弱い。荒らしと巨大レスポンスに弱い。

完了条件

44. [P2] タグ統合 UI/API を作る

種別: feature

対象

  • backend/app/models/tag.rb
  • backend/app/controllers/tags_controller.rb
  • frontend/src/pages/tags/*

背景 / 問題
Tag.merge_tags! は存在するが、運用 UI/API がない。タグ整理基盤を名乗るなら、統合は中核作業になる。

完了条件

52. [P1] 御意見番フォームを実装する

種別: feature / ops

対象

  • frontend/src/pages/*
  • backend/app/controllers/*
  • backend/db/migrate

背景 / 問題
公開後の不具合報告導線として、操作ログ・画面 URL・環境情報・スクリーンショット添付を持つフォームが必要。単なる問い合わせより再現性を重視する。

完了条件

57. [P1] アップロードファイルの content-type / サイズ制限を入れる

種別: security / ops

対象

  • backend/app/controllers/posts_controller.rb
  • backend/app/controllers/materials_controller.rb
  • backend/app/models/material.rb

背景 / 問題
thumbnail / material file は ActiveStorage に入るが、サイズや種類の上限が明確でない。R2/ストレージ費用と危険ファイル対策の両面で必要。

完了条件

59. [P2] フロントの role guard を共通化する

種別: frontend / refactor

対象

  • frontend/src/pages/wiki/WikiNewPage.tsx
  • frontend/src/pages/wiki/WikiEditPage.tsx
  • frontend/src/pages/tags/TagDetailPage.tsx
  • frontend/src/components/*

背景 / 問題
各ページで user?.role を直接見て分岐している。権限表示、hook 順序、guest 体験がばらつく。

完了条件

60. [P2] TypeScript の型を API 実態に合わせて null 許容を増やす

種別: bug / frontend

対象

  • frontend/src/types.ts
  • frontend/src/pages/*
  • frontend/src/components/*

背景 / 問題
uploadedUser / createdByUser / Wiki history user など、bot 操作や移行データで null になりうる値がある。型が嘘をつくと UI が落ちる。

完了条件

65. [P3] preview API を OpenGraph / oEmbed 対応に寄せる

種別: feature

対象

  • backend/app/controllers/preview_controller.rb

背景 / 問題
現在は title と screenshot 中心の暫定実装。外部サイトごとのタイトル/サムネ取得は OG/oEmbed をまず見る方が安定する。

完了条件

71. [P1] RSpec にセキュリティ回帰テスト群を追加する

種別: test

対象

  • backend/spec/requests/*

背景 / 問題
BAN、SSRF、権限、limit、system tag 保護は一度壊れると公開事故になる。仕様より spec で縛るべき。

完了条件

73. [P3] Gemfile の未使用 gem を棚卸しする

種別: maintenance

対象

  • backend/Gemfile
  • backend/Gemfile.lock

背景 / 問題
jwt や gollum 等、現行コードで使っているか怪しい gem がある。依存は攻撃面積と更新負荷になる。

完了条件

76. [P2] Post / Tag / Wiki の操作ログを共通 AuditLog に寄せる

種別: architecture / audit

対象

  • backend/app/models/*_version.rb
  • backend/app/controllers/*

背景 / 問題
各 version table は便利だが、管理画面で「このユーザが何をしたか」を横断表示するには共通ログが欲しい。

完了条件

86. [P3] Wiki 下書き保存を実装する

種別: feature / UX

対象

  • frontend/src/pages/wiki/WikiEditPage.tsx
  • backend/app/controllers/wiki_pages_controller.rb

背景 / 問題
Wiki 編集が長文化すると、ブラウザ落ちや競合で書きかけが消える。公開後の編集体験に効く。

完了条件

88. [P2] WikiDiffPage の query 変更時再取得と key 不足を直す

種別: bug / frontend

対象

  • frontend/src/pages/wiki/WikiDiffPage.tsx

背景 / 問題
diff 取得 useEffect の依存配列が空で、id/from/to が変わっても再取得されない。map の key も不足している。

完了条件