コメント・アクティビティ 仕様書
スレッドコメント・@メンション・変更履歴の自動記録
ステータス: Draft / 作成日: 2026-05-27 PR #4 — 依存: コア
1. データモデル
1.1 task_comments
pub struct Model {
pub id: Uuid,
pub task_id: Uuid,
pub user_id: Uuid,
pub body: String, // Markdown(@メンション含む)
pub parent_comment_id: Option<Uuid>, // スレッド返信(1 段のみ)
pub created_at: DateTimeUtc,
pub updated_at: DateTimeUtc,
pub deleted_at: Option<DateTimeUtc>, // ソフトデリート
}
1.2 task_activities
タスクへのあらゆる変更を自動記録する監査ログ。アプリ層から明示的に書き込む。
event_type 一覧:
2. マイグレーション
CREATE TABLE task_comments (
id UUID PRIMARY KEY,
task_id UUID NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
body TEXT NOT NULL,
parent_comment_id UUID REFERENCES task_comments(id) ON DELETE SET NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
deleted_at TIMESTAMPTZ
);
CREATE TABLE task_activities (
id UUID PRIMARY KEY,
task_id UUID NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
user_id UUID REFERENCES users(id) ON DELETE SET NULL,
event_type VARCHAR NOT NULL,
payload JSONB NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX idx_comments_task ON task_comments(task_id, created_at)
WHERE deleted_at IS NULL;
CREATE INDEX idx_activities_task ON task_activities(task_id, created_at DESC);
3. @メンション処理
コメント本文中の @ユーザー名 をサーバー側でパースし、通知を生成する。
パース対象: @username 形式(アルファベット・数字・_・- を含む)
1. body から正規表現で @mention を抽出
2. username でユーザーを検索
3. 見つかった場合 → notifications テーブルに type=mentioned で挿入
(通知システムは PR #5 で実装。本 PR では mention 抽出のみ行い、
通知テーブルが存在しない場合は INSERT をスキップする)
4. API
コメント
POST リクエスト:
{
"body": "この件は @tanaka さんに確認してください。",
"parent_comment_id": null
}
GET レスポンス(スレッド構造):
{
"comments": [
{
"id": "uuid",
"user": { "id": "uuid", "name": "田中" },
"body": "設計は完了しました。",
"replies": [
{
"id": "uuid",
"user": { "id": "uuid", "name": "鈴木" },
"body": "レビュー依頼します。",
"created_at": "2026-05-27T12:00:00Z"
}
],
"created_at": "2026-05-27T11:00:00Z",
"updated_at": "2026-05-27T11:00:00Z",
"is_deleted": false
}
]
}
削除済みコメントは "body": null, "is_deleted": true で返す(返信があれば親は残す)。
アクティビティ
レスポンス:
{
"activities": [
{
"id": "uuid",
"event_type": "status_changed",
"user": { "id": "uuid", "name": "田中" },
"payload": { "from": "Backlog", "to": "In Review" },
"created_at": "2026-05-27T11:00:00Z"
}
]
}
5. フロントエンド(Phase B)
タスク詳細のタイムライン
コメントとアクティビティを時系列に混在表示する。
──── アクティビティ ──────────────────────────────
田中 が優先度を変更: medium → high 11:00
──── コメント ────────────────────────────────────
🧑 田中 11:10
設計は完了しました。
└ 🧑 鈴木 11:15
レビュー依頼します。
──── アクティビティ ──────────────────────────────
システム が PR #87 をリンク 11:20