画面設計書とは
画面設計書(Screen Design Document)は、各画面の構成要素(UI部品・入力項目・ボタン)とその動作仕様(バリデーション・表示制御・画面遷移)を定義した設計書です。ワイヤーフレームと入力項目定義表・バリデーション定義表をセットで作成します。
基本設計フェーズの画面設計書はワイヤーフレームレベル(低精度モックアップ)で十分です。詳細なビジュアルデザイン(色・フォント・余白)は詳細設計フェーズで定義します。
💡 基本設計で定義すること vs 詳細設計で定義すること
基本設計:画面レイアウト・入力項目一覧・バリデーション種別・エラーメッセージ・画面遷移条件
詳細設計:UIコンポーネント詳細(プルダウン選択肢・ラベル文言)・CSS/スタイル定義・アニメーション仕様
① 画面レイアウト(ワイヤーフレーム)
ワイヤーフレームは画面を構成する主要ブロックの配置を定義します。基本設計段階では以下の要素を明示します。
- ヘッダー/フッター:ロゴ・ナビゲーション・ログアウトボタンの有無
- メインコンテンツ領域:検索フォーム・一覧テーブル・入力フォームの配置
- サイドバー:メニュー・フィルタパネルの有無
- ページネーション:一覧系画面でのページング位置(上部/下部)
- ボタン配置:主要アクションボタン(登録・更新・削除・キャンセル)の位置
② 入力項目定義
各入力フォームに含まれる全入力項目を定義します。項目ごとにUI部品種別・データ型・最大長・必須/任意を明記します。
| No. | 項目名 | 論理名 | UI部品 | データ型 | 最大長 | 必須 | 初期値 | 備考 |
|---|---|---|---|---|---|---|---|---|
| 1 | 商品コード | product_code | テキスト | 文字列 | 20文字 | 必須 | — | 英数字・ハイフンのみ |
| 2 | 商品名 | product_name | テキスト | 文字列 | 100文字 | 必須 | — | — |
| 3 | カテゴリ | category_id | プルダウン | 整数 | — | 必須 | — | m_categoryテーブルから取得 |
| 4 | 単価 | unit_price | 数値入力 | 数値(小数2桁) | — | 必須 | 0 | 0円以上10,000,000円未満 |
| 5 | 税区分 | tax_type | ラジオボタン | 文字列 | — | 必須 | 10(標準税率) | 10=標準税率, 8=軽減税率, 0=非課税 |
| 6 | 発売日 | release_date | 日付ピッカー | 日付 | — | 任意 | 本日 | 過去日付も入力可 |
| 7 | 商品説明 | description | テキストエリア | 文字列 | 2000文字 | 任意 | — | 改行入力可 |
| 8 | 公開フラグ | is_public | チェックボックス | 真偽値 | — | — | チェックなし | チェックあり=公開 |
③ バリデーション定義
各入力項目に対してバリデーションルールを定義します。フロントエンド(ブラウザ側)とバックエンド(サーバー側)の両方でバリデーションを実装することが前提です。
| 項目名 | バリデーション種別 | ルール | エラーメッセージID |
|---|---|---|---|
| 商品コード | 必須チェック | 入力必須 | ERR001 |
| 商品コード | フォーマットチェック | 英数字・ハイフンのみ(正規表現: ^[A-Za-z0-9\-]+$) | ERR010 |
| 商品コード | 文字数チェック | 1文字以上20文字以内 | ERR020 |
| 商品コード | 重複チェック | DBに同一コードが存在しないこと(新規登録時のみ) | ERR030 |
| 単価 | 必須チェック | 入力必須 | ERR001 |
| 単価 | 数値チェック | 数値(整数または小数)であること | ERR011 |
| 単価 | 範囲チェック | 0以上10,000,000未満 | ERR021 |
| 商品名 | 必須チェック | 空白のみは不可(trim後に空文字チェック) | ERR001 |
| 商品名 | 文字数チェック | 1文字以上100文字以内 | ERR020 |
④ エラーメッセージ定義
エラーメッセージIDに対応するメッセージ文言を定義します。メッセージは具体的に何が問題かを伝え、ユーザーが修正できるようにします。
| メッセージID | メッセージ文言 | 表示タイミング |
|---|---|---|
| ERR001 | 「{項目名}」を入力してください。 | フォーカスアウト時 / 送信ボタン押下時 |
| ERR010 | 「{項目名}」は半角英数字とハイフン(-)のみ使用できます。 | フォーカスアウト時 |
| ERR011 | 「{項目名}」は数値を入力してください。 | フォーカスアウト時 |
| ERR020 | 「{項目名}」は{最小}文字以上{最大}文字以内で入力してください。 | フォーカスアウト時 |
| ERR021 | 「{項目名}」は{最小}以上{最大}未満の数値を入力してください。 | フォーカスアウト時 |
| ERR030 | この{項目名}は既に登録されています。別の値を入力してください。 | 送信ボタン押下時(サーバー側チェック) |
⑤ 表示制御・活性・非活性条件
特定の入力値によって他の入力項目の表示・非表示・活性/非活性が変わる場合、その条件を明示します。
| 制御対象項目 | 制御種別 | 条件 | 制御内容 |
|---|---|---|---|
| 軽減税率説明欄 | 表示/非表示 | 税区分 = 8(軽減税率) | 表示する(非表示→表示) |
| 発売日 | 活性/非活性 | 公開フラグ = チェックなし | 非活性(入力不可) |
| 削除ボタン | 表示/非表示 | ユーザーロール = 管理者以上 | 表示する(一般ユーザーには非表示) |
Python Tips — 入力定義からバリデーションコードを生成する
入力項目定義をYAMLやJSONで管理しておき、Pythonスクリプトでバリデーションコードを自動生成することで、設計書とコードの乖離を防げます。
"""
入力項目定義YAMLからDjango Formクラスを自動生成するスクリプト。
pip install pyyaml
"""
import yaml
# 入力項目定義(実際はYAMLファイルから読み込む)
FIELD_DEFINITIONS = """
fields:
- name: product_code
label: 商品コード
type: CharField
max_length: 20
required: true
validators:
- type: regex
pattern: "^[A-Za-z0-9\\\\-]+$"
message: "半角英数字とハイフン(-)のみ使用できます。"
- name: product_name
label: 商品名
type: CharField
max_length: 100
required: true
- name: unit_price
label: 単価
type: DecimalField
max_digits: 10
decimal_places: 2
required: true
min_value: 0
max_value: 9999999.99
- name: category_id
label: カテゴリ
type: ChoiceField
required: true
choices_source: "m_category"
- name: description
label: 商品説明
type: CharField
widget: Textarea
max_length: 2000
required: false
- name: is_public
label: 公開フラグ
type: BooleanField
required: false
"""
def generate_django_form(yaml_str: str, form_class_name: str = "ProductForm") -> str:
"""入力定義YAMLからDjango Formクラスコードを生成する"""
definition = yaml.safe_load(yaml_str)
fields = definition.get("fields", [])
lines = ["from django import forms", "from django.core.validators import RegexValidator", ""]
lines.append(f"class {form_class_name}(forms.Form):")
for field in fields:
name = field["name"]
ftype = field.get("type", "CharField")
label = field.get("label", name)
required = field.get("required", False)
# フィールド定義生成
kwargs = [f'label="{label}"', f'required={required}']
if ftype == "CharField":
if "max_length" in field:
kwargs.append(f'max_length={field["max_length"]}')
if field.get("widget") == "Textarea":
kwargs.append("widget=forms.Textarea")
elif ftype == "DecimalField":
kwargs.append(f'max_digits={field.get("max_digits", 10)}')
kwargs.append(f'decimal_places={field.get("decimal_places", 2)}')
if "min_value" in field:
kwargs.append(f'min_value={field["min_value"]}')
if "max_value" in field:
kwargs.append(f'max_value={field["max_value"]}')
elif ftype == "ChoiceField":
kwargs.append("choices=[] # TODO: populate from model")
# バリデーターの追加
validators = field.get("validators", [])
if validators:
validator_strs = []
for v in validators:
if v["type"] == "regex":
pattern = v["pattern"].replace("\\\\", "\\")
msg = v.get("message", "入力形式が不正です。")
validator_strs.append(
f'RegexValidator(r"{pattern}", "{msg}")'
)
if validator_strs:
kwargs.append(f'validators=[{", ".join(validator_strs)}]')
kwargs_str = ", ".join(kwargs)
lines.append(f" {name} = forms.{ftype}({kwargs_str})")
return "\n".join(lines)
if __name__ == "__main__":
code = generate_django_form(FIELD_DEFINITIONS, "ProductForm")
print(code)
# ファイルに出力
with open("product_form.py", "w", encoding="utf-8") as f:
f.write(code)
print("\nproduct_form.py を生成しました")
✅ 設計書とコードの同期管理
入力項目定義をYAMLで管理し、Djangoフォーム・TypeScript型定義・OpenAPI仕様書を自動生成するパイプラインを構築することで、設計書変更時の実装漏れを防ぐことができます。
定義チェックリスト
| チェック項目 | 確認ポイント |
|---|---|
| □ 全入力項目が定義されているか | フォーム内の全入力項目が入力項目定義表に記載されているか |
| □ バリデーションが全項目に定義されているか | 必須チェック・フォーマット・文字数・範囲チェックが漏れなく定義されているか |
| □ エラーメッセージが定義されているか | 全バリデーションエラーに対応するメッセージが定義されているか |
| □ 表示制御条件が定義されているか | 条件付き表示・活性制御の条件が全て明記されているか |
| □ 二重送信防止が考慮されているか | 登録・更新ボタンの二重送信防止方法が定義されているか |
| □ 入力補助が考慮されているか | プレースホルダー・ツールチップ・入力例の有無が検討されているか |