カスタムフィールド 仕様書
プロジェクト固有の属性(ストーリーポイント・バージョン等)
ステータス: Draft / 作成日: 2026-05-27 PR #6 — 依存: コア
1. データモデル
1.1 project_custom_fields
pub struct Model {
pub id: Uuid,
pub project_id: Uuid,
pub name: String,
pub field_type: CustomFieldType, // text | number | select | date | url | checkbox
pub options: Option<Value>, // select 型の選択肢 JSON
pub is_required: bool,
pub position: i16,
pub created_at: DateTimeUtc,
}
1.2 task_custom_field_values
型ごとの値フォーマット:
2. マイグレーション
CREATE TABLE project_custom_fields (
id UUID PRIMARY KEY,
project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
name VARCHAR(100) NOT NULL,
field_type VARCHAR NOT NULL,
options JSONB,
is_required BOOLEAN NOT NULL DEFAULT false,
position SMALLINT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
UNIQUE (project_id, name)
);
CREATE TABLE task_custom_field_values (
task_id UUID NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
field_id UUID NOT NULL REFERENCES project_custom_fields(id) ON DELETE CASCADE,
value TEXT,
PRIMARY KEY (task_id, field_id)
);
3. API
フィールド定義(プロジェクトスコープ)
POST /custom-fields リクエスト:
{
"name": "Story Points",
"field_type": "select",
"options": [
{ "label": "XS (1)", "value": "1" },
{ "label": "S (2)", "value": "2" },
{ "label": "M (3)", "value": "3" },
{ "label": "L (5)", "value": "5" },
{ "label": "XL (8)", "value": "8" }
],
"is_required": false
}
フィールド値(タスクスコープ)
PUT リクエスト:
{
"values": [
{ "field_id": "uuid", "value": "5" },
{ "field_id": "uuid2", "value": "2026-07-01" }
]
}
is_required=true のフィールドが未入力のままタスクのステータスを is_done_state=true に変更しようとすると 400 Bad Request。
GET /tasks/{id}/custom-fields レスポンス:
{
"values": [
{
"field": { "id": "uuid", "name": "Story Points", "field_type": "select" },
"value": "5",
"display_value": "L (5)"
}
]
}
4. フロントエンド(Phase B)
タスク詳細(右ペイン)
── カスタムフィールド ───────────────────
Story Points [L (5) ▼]
バージョン [v2.0 ]
対応環境 [本番 ]
管理画面
/tenants/{tid}/projects/{pid}/custom-fields
フィールド一覧 + ドラッグで並び替え。select 型は選択肢をインラインで追加・削除。