組織一覧に検索機能を追加(組織名・契約プラン)

done

セッション開始:2026/06/05 05:54

planning developing done

目的 / なぜ必要か

システム管理画面の組織一覧 /organizations は全組織を名前順に無条件で並べるだけで、 組織数が増えると目的の組織を探しづらい。システム管理者が 組織名契約プランで素早く絞り込めるよう、一覧上部に検索 UI を追加する。

スコープ

やること

  • 組織一覧上部に検索フォーム(組織名入力+契約プラン選択+検索ボタン)を追加
  • 組織名:部分一致・大文字小文字を区別しない
  • 契約プラン:プルダウン単一選択(すべて/各プラン)
  • 両条件は AND で絞り込み
  • 条件を URL クエリ?name=&contractPlan=)に保持し、検索ボタンで適用
  • 結果が 0 件のときのメッセージを表示

やらないこと

  • 契約プラン「未設定」での絞り込み(組織の登録・変更 UI 上、プラン未設定は不可のため該当組織が存在しない)
  • クリア(リセット)ボタン(条件は手動で空に戻す)
  • 該当件数の表示
  • 利用状況(有効化/無効化)・ユーザー数などでの絞り込み
  • 並び順の変更(既存どおり名前昇順)
  • 一覧以外の画面の変更

決定事項(仕様)

対象画面 system-manager /organizations(組織一覧)
組織名検索 部分一致・大文字小文字を区別しない(Prisma containsmode: "insensitive"
契約プラン絞り込み プルダウン単一選択。選択肢は すべて/各プラン名(月額昇順)。「未設定」は設けない(組織作成時にプラン必須のため)
条件の結合 両方指定時は AND(両条件を満たす組織のみ)
実行方式 URL クエリ?name=&contractPlan=)+検索ボタンで適用。Prisma where でサーバー側絞り込み
プランの値エンコード すべて → クエリ無し、各プラン → contractPlan={'{id}'}(フォーム内部値「all」はクエリに出さない)
状態保持 URL に残り、リロード・共有でも条件が維持される
補助 UI 0 件時のメッセージのみ(クリアボタン・件数表示は付けない)
並び順 既存どおり名前昇順(変更なし)

UI イメージ(修正後)

見出し「組織」の下・一覧の上に検索フォーム(組織名入力+プラン選択+検索ボタン)を配置する。

組織
新しい組織を登録
組織名で検索
すべて
検索
○○不動産株式会社
👥 12 📄 スタンダードプラン 🕒 利用開始:2025-04-01
△△不動産
👥 3 📄 未設定 🕒 利用開始:未設定

条件に合致する組織が無い場合:

該当する組織がありません

実装内容(影響範囲)

変更 apps/system-manager/actions/organization/list-organization.ts

{ name?, contractPlanId? } を受け取り where を組み立て。 namecontainsmode: "insensitive"contractPlanIdundefined=絞り込まない / null=未設定 / 文字列=そのプラン。

新規 apps/system-manager/app/organizations/_components/organization-search-form/index.tsx

クライアントコンポーネント。組織名 Input・契約プラン Select・検索 Button を持ち、 送信時に createSearchParams でクエリを組んで router.push。 入力欄は _fields/ に分割、バリデーションは schema.ts に集約。

新規 apps/system-manager/lib/url/create-search-params.ts

Record<string, string | undefined> から undefined・空文字を除いた URLSearchParams を生成するユーティリティ。

変更 apps/system-manager/app/organizations/page.tsx

searchParams を解釈して listOrganizationCached に渡す。 検索フォーム(プラン選択肢は listContractPlanCached から取得)を一覧上部に配置し、 結果 0 件時のメッセージを表示。

流用 apps/system-manager/actions/contract-plan/list-contract-plan.ts

既存。プルダウンの選択肢(月額昇順)として利用(変更なし)。

留意点 / 確認事項

動作チェックでの修正

実機での動作確認を経て、以下を修正・確定した。

契約プラン「未設定」絞り込みを廃止

組織の登録・変更 UI 上、契約プランの未設定(null)が不可で該当組織が発生しないため、 プルダウンの「未設定」選択肢・URL の contractPlan=none エンコードを廃止。 選択肢は「すべて/各プラン」のみ。

URL クエリ名を contractPlan に統一

当初の計画 contractPlanId から contractPlan に変更。 値は各プランの cuid2(フォーム内部値「all」はクエリへ出力しない)。

フォームの構成を分割・共通化

入力欄を _fields/name-field.tsx / _fields/contract-plan-id-field.tsx に分割し、 バリデーションは _components/organization-search-form/schema.ts(react-hook-form + zod)へ集約。 クエリ組み立ては apps/system-manager/lib/url/create-search-params.ts に切り出し (undefined・空文字を除外)。