コンテンツにスキップ

ペット管理仕様 (FR-003)

項目内容
対象FRFR-003(ペット登録)
優先度
ステータス詳細化済み

概要

認証済みユーザーは1匹以上の猫をペットとして登録できる。登録されたペットは体重・食事・通院などの健康記録の親エンティティとなる。ペットプロフィールには名前・品種・生年月日・性別・避妊/去勢状態・写真を含む。初期フェーズでは猫のみを対象とする。

入力フィールド

フィールド必須バリデーション
namevarchar1〜50文字、前後の空白はトリム
breedIdinteger-存在する cat_breeds.id であること
breedOthervarchar-breedId 未指定時のみ有効、1〜50文字
dateOfBirthdate-ISO 8601 日付形式(YYYY-MM-DD)、未来日不可
isBirthdayEstimatedboolean-dateOfBirth 指定時のみ有効、default false
sexvarcharmale / female / unknown
isNeuteredboolean-
coatColorvarchar-1〜50文字
memotext-最大500文字
  • 品種は cat_breeds マスタテーブルから選択するか、「その他」として breedOther に自由入力する
  • breedIdbreedOther の両方が指定された場合は breedId を優先し、breedOther は無視する
  • 生年月日が不明な場合(保護猫など)は推定日付を入力し、isBirthdayEstimatedtrue にする
  • 写真(photoUrl)はスキーマに定義するが、アップロード機能は後続フェーズで実装する

制約

項目
1ユーザーあたりの登録上限50匹
対象ペット種別猫のみ(初期フェーズ)

APIエンドポイント

全エンドポイントで認証必須(__Host-session Cookie)。

メソッドパス概要
POST/api/petsペット登録
GET/api/pets自分のペット一覧
GET/api/pets/:petIdペット詳細
PATCH/api/pets/:petIdペット更新
DELETE/api/pets/:petIdペット削除(論理削除)

POST /api/pets — ペット登録

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

  • 成功時: 201 Created、作成されたペット情報を返す
  • breedId が存在しない場合: 422 Unprocessable Entity
  • 登録上限超過: 409 Conflict

リクエスト:

{
"name": "そうにゃ",
"breedId": 3,
"dateOfBirth": "2024-05-01",
"isBirthdayEstimated": false,
"sex": "female",
"isNeutered": true,
"coatColor": "キジトラ"
}

成功レスポンス:

{
"data": {
"id": 1,
"name": "そうにゃ",
"breedId": 3,
"breedOther": null,
"dateOfBirth": "2024-05-01",
"isBirthdayEstimated": false,
"sex": "female",
"isNeutered": true,
"coatColor": "キジトラ",
"photoUrl": null,
"memo": null,
"createdAt": "2026-02-18T10:00:00Z",
"updatedAt": "2026-02-18T10:00:00Z"
}
}

GET /api/pets — ペット一覧

ログインユーザーが登録したペットの一覧を返す。論理削除済みペットは含まない。

  • 成功時: 200 OK
  • ペット未登録時: 空配列を返す(エラーではない)
{
"data": [
{ "id": 1, "name": "そうにゃ", "..." : "..." },
{ "id": 2, "name": "みけ", "..." : "..." }
]
}

GET /api/pets/:petId — ペット詳細

指定IDのペット情報を返す。

  • 成功時: 200 OK(レスポンス形式はPOSTと同一)
  • 存在しない / 他ユーザーのペット / 論理削除済み: 404 Not Found

PATCH /api/pets/:petId — ペット更新

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

リクエスト(例: 名前と避妊状態を更新):

{
"name": "そうにゃん",
"isNeutered": true
}
  • 成功時: 200 OK、更新後のペット情報を返す
  • 存在しない / 他ユーザーのペット / 論理削除済み: 404 Not Found
  • breedId が存在しない場合: 422 Unprocessable Entity

DELETE /api/pets/:petId — ペット削除

論理削除(deleted_at に現在日時を設定)する。関連する健康記録は保持される。

  • 成功時: 204 No Content
  • 存在しない / 他ユーザーのペット / 既に削除済み: 404 Not Found

認可ルール

  • 全エンドポイントで認証必須(未認証は 401 Unauthorized
  • 自分が登録したペットのみ操作可能(他ユーザーのペットIDを指定した場合は 404 を返し、存在の有無を漏らさない)
  • 論理削除済みペットへのアクセスは 404 を返す
  • 家族メンバーによる共有アクセスは FR-011 で定義

エッジケース

  • breedIdbreedOther の両方が指定された場合 → breedId を優先し、breedOthernull として保存する
  • dateOfBirth なしで isBirthdayEstimated: true が送信された場合 → isBirthdayEstimatedfalse として保存する
  • 登録上限(50匹)超過 → 409 Conflict(エラー詳細に上限超過を明示)
  • 同名のペット登録 → 許可する(別個体として扱う)
  • 生年月日が未来日 → 422 Unprocessable Entity
  • 削除済みペットのIDへのアクセス → 404 Not Found
  • 削除済みペットへの更新・再削除リクエスト → 404 Not Found
  • ペット削除時に関連する健康記録が存在 → 健康記録は保持される(論理削除のため)

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

  • 猫以外のペット種別への対応(犬、小動物等)
  • プロフィール写真のアップロードAPI
  • ペットの並び順カスタマイズ
  • ペットのアーカイブ機能(削除ではなく非表示化)
  • 家族共有時の共有ペットへのアクセス(FR-011で対応)

検証方法

  • ペットを登録し、一覧・詳細で取得できること
  • 必須フィールド(name, sex, isNeutered)が欠けた場合にバリデーションエラーになること
  • 存在しない breedId 指定時に 422 が返ること
  • 未来日の生年月日が拒否されること
  • 登録上限(50匹)を超えた場合にエラーになること
  • 他ユーザーのペットにアクセスした場合に 404 が返ること
  • ペット情報の部分更新が正しく反映されること
  • ペット削除後に関連する健康記録データがDBに保持されていること
  • 未認証状態で全エンドポイントが 401 を返すこと