コンテンツにスキップ

食事記録仕様 (FR-005)

項目内容
対象FRFR-005(食事記録)
優先度
ステータス詳細化済み

概要

ユーザーは登録済みペットの食事内容を記録できる。フード名・種類・量・日時を構造化して保存し、日々の食事管理に活用する。食事記録はペットの健康記録の一部であり、ペット削除時にカスケード削除される。

入力フィールド

フィールド必須バリデーション
foodNamevarchar1〜100文字、前後の空白はトリム
foodTypevarchardry / wet / treat / supplement / other
amountnumeric正の数値(0より大きい)
amountUnitvarcharg / ml / piece
mealDatedate未来日不可
mealTimetime-HH:MM 形式
memotext-最大500文字

フード種類 (foodType)

説明
dryドライフード(カリカリ)
wetウェットフード(缶詰・パウチ等)
treatおやつ
supplementサプリメント
otherその他

量の単位 (amountUnit)

説明
gグラム
mlミリリットル
piece個・粒

APIエンドポイント

全エンドポイントで認証必須(__Host-session Cookie)。 :petId は自分が所有するペットのIDであること。

メソッドパス概要
POST/api/pets/:petId/meals食事記録の登録
GET/api/pets/:petId/meals食事記録の一覧取得
GET/api/pets/:petId/meals/:mealId食事記録の詳細取得
PATCH/api/pets/:petId/meals/:mealId食事記録の更新
DELETE/api/pets/:petId/meals/:mealId食事記録の削除(物理削除)

POST /api/pets/:petId/meals — 食事記録の登録

リクエストボディに入力フィールドを指定して食事記録を登録する。

  • 成功時: 201 Created、作成された食事記録を返す
  • ペットが存在しない / 他ユーザーのペット: 404 Not Found
{
"data": {
"id": 1,
"petId": 1,
"foodName": "ロイヤルカナン インドア",
"foodType": "dry",
"amount": 30,
"amountUnit": "g",
"mealDate": "2026-02-18",
"mealTime": "08:30",
"memo": null,
"createdAt": "2026-02-18T10:00:00Z",
"updatedAt": "2026-02-18T10:00:00Z"
}
}

GET /api/pets/:petId/meals — 食事記録の一覧取得

指定ペットの食事記録を日付の降順で返す。

  • 成功時: 200 OK
  • 記録なし: 空配列を返す(エラーではない)
  • ペットが存在しない / 他ユーザーのペット: 404 Not Found

クエリパラメータ:

パラメータデフォルト説明
limitinteger20取得件数(1〜100)
offsetinteger0スキップ件数
dateFromdate-開始日(この日以降)
dateTodate-終了日(この日以前)
{
"data": [
{
"id": 2,
"petId": 1,
"foodName": "チュール まぐろ味",
"foodType": "treat",
"amount": 1,
"amountUnit": "piece",
"mealDate": "2026-02-18",
"mealTime": "15:00",
"memo": null,
"createdAt": "2026-02-18T16:00:00Z",
"updatedAt": "2026-02-18T16:00:00Z"
},
{
"id": 1,
"petId": 1,
"foodName": "ロイヤルカナン インドア",
"foodType": "dry",
"amount": 30,
"amountUnit": "g",
"mealDate": "2026-02-18",
"mealTime": "08:30",
"memo": null,
"createdAt": "2026-02-18T10:00:00Z",
"updatedAt": "2026-02-18T10:00:00Z"
}
]
}

GET /api/pets/:petId/meals/:mealId — 食事記録の詳細取得

指定IDの食事記録を返す。

  • 成功時: 200 OK
  • 存在しない / 他ユーザーのペットの記録: 404 Not Found

PATCH /api/pets/:petId/meals/:mealId — 食事記録の更新

指定したフィールドのみ部分更新する。リクエストボディに含まれないフィールドは変更しない。

  • 成功時: 200 OK、更新後の食事記録を返す
  • 存在しない / 他ユーザーのペットの記録: 404 Not Found

DELETE /api/pets/:petId/meals/:mealId — 食事記録の削除

物理削除する。

  • 成功時: 204 No Content
  • 存在しない / 他ユーザーのペットの記録: 404 Not Found

認可ルール

  • 全エンドポイントで認証必須
  • 自分が所有するペットの食事記録のみ操作可能
  • 他ユーザーのペットIDを指定した場合は 404 を返し、存在の有無を漏らさない
  • 論理削除済みペットの食事記録へのアクセスは 404 を返す

エッジケース

  • mealTime 未指定の記録 → 日付のみで記録される(一覧のソートは mealTime が null のものを後ろに表示)
  • 同一ペット・同一日時に複数の食事記録 → 許可する(朝食でドライフードとウェットフードを別々に記録するケースに対応)
  • ペットの論理削除後 → 食事記録には直接アクセスできない(ペットが 404 を返すため)
  • ペットの物理削除(カスケード削除)→ 関連する食事記録もすべて削除される
  • amount に極端に大きい値 → アプリケーション側で上限を設定(TBD、例: 99999.9 以下)
  • dateFromdateTo より後 → 空配列を返す(エラーではない)

拡張予定(現時点ではスコープ外)

  • フードマスタテーブル(よく使うフードの登録・選択)
  • カロリー計算・1日の摂取量集計
  • 食事記録のCSVエクスポート
  • 家族共有時の共有ペットの食事記録へのアクセス(FR-011で対応)

検証方法

  • 食事記録の登録 → 一覧取得 → 詳細取得の一連フローが完了すること
  • 必須フィールド(foodName, foodType, amount, amountUnit, mealDate)未指定時にバリデーションエラーが返ること
  • 無効な foodType / amountUnit 指定時にバリデーションエラーが返ること
  • amount に0以下の値を指定した場合にバリデーションエラーが返ること
  • 未来日の mealDate が拒否されること
  • 他ユーザーのペットの食事記録へのアクセスが 404 を返すこと
  • PATCH で指定したフィールドのみが更新され、他フィールドが変更されないこと
  • DELETE 後に一覧・詳細から表示されなくなること
  • 日付範囲フィルタ(dateFrom, dateTo)が正しく機能すること
  • ページネーション(limit, offset)が正しく機能すること
  • 論理削除済みペットの食事記録にアクセスした場合に 404 が返ること
  • 未認証状態で全エンドポイントが 401 を返すこと