テーマ
Requirements: 管理画面
概要
運営者が候補者情報および候補者画像を管理するための管理画面。Miss World Japan ファイナリストの登録・編集・削除と、画像のアップロード・差し替えを行う。
ファイル配置・技術設計(認証連携、Server Actions、配信エンドポイント)は
design.md、ビジュアル仕様はui-design.mdを参照。
機能仕様
Feature 1: 認証
Purpose: 管理画面へのアクセスを管理者ロール保有ユーザーに限定し、一般ユーザー向け認証経路と分離して安全性を確保する。 Scope: 管理画面配下のアクセス制御とセッション管理。
Acceptance Criteria (EARS)
- THE SYSTEM SHALL 管理画面へのアクセスは管理者ロールを持つユーザーに限定する
- WHEN 未認証ユーザーが管理画面にアクセスした THEN システムはログイン画面に誘導する
- WHEN 一般ユーザー(管理者ロールなし)が管理画面にアクセスした THEN システムはアクセスを拒否し、適切なエラーメッセージを表示する
- THE SYSTEM SHALL 管理者の認証は一般ユーザー(投票者)向けの認証(Facebook / Instagram)とは別系統で管理する
- WHEN 管理者がログアウトを要求した THEN システムはセッションを終了する
Feature 2: 候補者一覧画面
Purpose: 登録済み候補者を俯瞰し、各候補者の主要属性と編集/削除アクションへの導線を一画面で提供する。 Scope: 管理画面の候補者一覧領域。
Acceptance Criteria (EARS)
- WHEN 認証済み管理者が候補者一覧画面を表示した THEN システムは登録されているすべての候補者を一覧表示する
- THE SYSTEM SHALL 各候補者について以下を表示する:
- 候補者名
- 出身地
- メイン画像のサムネイル
- 現在の得票数
- 関連画像の枚数
- 編集・削除へのアクション
- THE SYSTEM SHALL 「新規候補者登録」のアクションを提供する
Feature 3: 候補者新規登録
Purpose: 投票期間の準備や追加エントリーに対応するため、候補者の各属性と画像を一括で登録できる入力フォームを提供する。 Scope: 候補者新規登録フォームと保存処理。
Acceptance Criteria (EARS)
- WHEN 管理者が新規登録を要求した THEN システムは候補者の各属性を入力するフォームを提供する
- THE SYSTEM SHALL 入力項目として以下を提供する:
- 表示名(必須)
- 出身地
- 年齢
- 身長
- 職業
- 趣味・特技(複数入力可)
- 資格・大会実績(複数入力可)
- 座右の銘
- 夢
- PRメッセージ(複数行のテキスト)
- 表示順
- 候補者画像(複数枚のアップロード可)
- WHEN 入力内容が必須項目を満たさない THEN システムはエラーを提示し登録しない
- WHEN 入力内容が有効である THEN システムは候補者と画像を保存し、一覧画面に戻る
Feature 4: 候補者情報の編集
Purpose: 既存候補者のテキスト系属性を更新し、関連キャッシュを無効化して公開情報の最新化を保証する。 Scope: 候補者編集フォームと更新処理。
Acceptance Criteria (EARS)
- WHEN 管理者が候補者の編集を要求した THEN システムは現在の値を表示する編集フォームを提供する
- THE SYSTEM SHALL すべての属性(画像以外のテキスト系項目)を編集可能とする
- WHEN 管理者が変更を保存した THEN システムは更新内容をDBに反映し、関連するキャッシュを無効化する
- WHEN キャッシュ無効化が完了した THEN システムは次のユーザーアクセスから新しい情報を表示する
Feature 5: 候補者画像の管理
Purpose: 候補者画像のアップロード・差し替え・削除・並び替え・メイン画像指定を一連の操作として提供し、ブラウザキャッシュも整合させる。 Scope: 候補者画像のCRUDと並び替え。
Acceptance Criteria (EARS)
- THE SYSTEM SHALL 候補者ごとに画像を複数アップロードできる手段を提供する
- THE SYSTEM SHALL 受け付ける画像形式を JPEG / PNG / WebP に限定する
- THE SYSTEM SHALL 画像ファイルのサイズに上限を設ける(具体値は design.md で定義)
- WHEN 管理者が画像をアップロードした THEN システムは画像本体をDBに保存し、対応する候補者に関連付ける
- WHEN 管理者が画像を差し替えた THEN システムは元の画像レコードを更新し、
updatedAtを新しくする - WHEN 画像が更新された THEN ユーザー側ではキャッシュ無効化により、ブラウザキャッシュから古い画像が返らないことを保証する(具体的なURL設計は
design.mdを参照) - WHEN 管理者が画像を削除した THEN システムはDBから該当画像レコードを削除する
- THE SYSTEM SHALL 画像の表示順を変更する手段を提供する
- THE SYSTEM SHALL 表示順
0の画像をメイン画像として一覧画面・詳細画面で使用することを明示する
Feature 6: 候補者の削除
Purpose: 投票が記録されていない候補者を確認付きで削除できるようにし、投票済み候補者は削除を拒否してデータ整合性を守る。 Scope: 候補者削除アクションのバリデーションと実行。
Acceptance Criteria (EARS)
- WHEN 管理者が候補者の削除を要求した THEN システムは確認を求める
- WHEN 確認後に削除が実行された AND 投票が記録されていない THEN システムは候補者と関連画像をすべて削除する
- WHEN 確認後に削除が実行された AND 投票が記録されている THEN システムは削除を拒否し、運用ルールに反する旨をエラーメッセージで通知する
Feature 7: 公開後の確認
Purpose: 管理者が運営者としてログインしたまま一般ユーザー向け画面を閲覧でき、表示確認に管理者専用UIが混入しないよう分離する。 Scope: 一般画面と管理画面の表示モード分離。
Acceptance Criteria (EARS)
- THE SYSTEM SHALL 管理者が一般ユーザー向け画面(Home/候補者詳細/ランキング)を閲覧できることを許可する
- THE SYSTEM SHALL 管理者として閲覧している場合でも、一般ユーザーと同じ表示・挙動とする(管理者専用の編集ボタン等は管理画面側に集約する)
Feature 8: 初期データの一括投入
Purpose: 投票開始前に候補者と画像をまとめて登録できるよう、CSV と画像ファイルを読み込むコマンドラインスクリプトを提供する。 Scope: バッチ投入スクリプト。
Acceptance Criteria (EARS)
- THE SYSTEM SHALL CSVファイルと画像ファイル群を読み込み、候補者と画像を一括投入するスクリプトを提供する
- THE SYSTEM SHALL スクリプトは以下を満たす:
- CSVから候補者の全属性を読み込む
- CSVに記載された画像ファイル名に対応する画像をDBに格納する
- 画像のMIME型はファイル拡張子から推定する
- 投入時に既存の候補者を上書きしない(運用ルールで担保 or
--forceフラグで明示)
- THE SYSTEM SHALL スクリプト実行はコマンドラインから行えるものとする(管理画面UIからの実行は不要)
Feature 9: キャッシュ無効化
Purpose: 候補者情報や画像の更新が一般ユーザー向け画面に確実に反映されるようキャッシュ戦略を仕様として定義する。 Scope: 候補者/画像更新に伴うキャッシュ無効化ポリシー。
Acceptance Criteria (EARS)
- WHEN 候補者情報が更新された THEN システムは候補者一覧・詳細・ランキング画面のキャッシュタグを無効化する
- WHEN 画像が更新された THEN システムは画像URLにバージョン情報が付与されることでブラウザキャッシュが自然に切り替わるため、画像自体のキャッシュ無効化は不要(具体形式は
design.mdを参照)
非機能要件
- 管理者数の想定: 1〜数名(同時編集の競合は想定外)
- 編集頻度: 投票期間中はほぼなし。準備期間中は集中的
- 画像処理性能: 1枚あたり数MB以下の画像を扱う前提
セキュリティ(認証・認可・CSRF対策・監査ログ等)は
steering/tech.mdの「セキュリティポリシー(全画面共通)」を参照。
依存仕様
data-model/requirements.md(Candidate / CandidateImage の整合性ルール)home/requirements.mdcandidate-detail/requirements.md(更新対象の表示要件)
エッジケース
- アップロード途中の通信切断: 部分的なファイルが保存されないようトランザクションで原子性を保つ
- 大きすぎる画像: アップロード前にクライアント側でサイズチェック、サーバー側でも制限
- 不正なMIME型: 受付時にバリデーションし、JPEG/PNG/WebP以外は拒否
- 同時編集: 1〜数名の運用なので想定しない。発生した場合は最終書き込み優先(last-write-wins)
- 削除しようとした候補者に投票がある: 削除を拒否し、運用ルールに従って対応(投票無効化等は別途対応)