投薬管理仕様 (FR-009)
| 項目 | 内容 |
|---|---|
| 対象FR | FR-009(投薬管理) |
| 優先度 | 中 |
| ステータス | 詳細化済み |
概要
ユーザーはペットの投薬情報(薬名、用量、頻度、期間)を登録し、投薬スケジュールを管理できる。さらに、実際に投与した記録(投薬ログ)をつけることで、飲み忘れの防止やFR-010(通知・リマインド)との連携を可能にする。
データモデル
本機能は2つのエンティティで構成される:
| エンティティ | 役割 |
|---|---|
| medications | 処方情報・投薬スケジュール(「何を、どれだけ、どの頻度で」) |
| medication_logs | 投薬記録(「いつ、実際に投与したか」) |
medications — 入力フィールド
| フィールド | 型 | 必須 | バリデーション |
|---|---|---|---|
| name | varchar | ○ | 1〜100文字 |
| dosageAmount | decimal | ○ | 0より大きい値 |
| dosageUnit | varchar | ○ | 後述のenum値 |
| timesPerDay | integer | ○ | 1〜24 |
| frequencyNote | varchar | - | 最大100文字(例: 「朝夕食後」「8時間おき」) |
| route | varchar | - | 後述のenum値(default: oral) |
| startDate | date | ○ | - |
| endDate | date | - | startDate 以降であること。null の場合は継続中 |
| memo | text | - | 最大500文字 |
dosageUnit(用量単位)
猫に処方される薬の剤形を網羅する:
| 値 | 表示名 | 用途 |
|---|---|---|
tablet | 錠 | 錠剤(最も一般的) |
capsule | カプセル | カプセル剤 |
ml | mL | 液剤・シロップ・注射液 |
mg | mg | 粉薬・顆粒(重量指定) |
g | g | 軟膏・クリーム(重量指定) |
drop | 滴 | 点眼薬・点耳薬 |
packet | 包 | 分包された粉薬・顆粒 |
piece | 個 | チュアブル・おやつタイプ |
tube | 本 | スポットオン(ノミ・ダニ予防薬など) |
cm | cm | チューブから出す軟膏の長さ指定 |
puff | パフ | 吸入薬(猫喘息用スペーサー等) |
route(投与経路)
| 値 | 表示名 | 具体例 |
|---|---|---|
oral | 経口 | 錠剤、カプセル、液剤、粉薬 |
topical | 外用(皮膚) | 軟膏、スポットオン |
eye | 点眼 | 点眼薬 |
ear | 点耳 | 点耳薬 |
injection | 注射 | 皮下補液、インスリン |
inhalation | 吸入 | 喘息用吸入薬 |
other | その他 | 上記に該当しない投与方法 |
投薬状態の判定
isActive のような状態カラムは持たず、endDate と deletedAt から導出する:
| 状態 | 条件 |
|---|---|
| 投薬中 | endDate IS NULL OR endDate >= TODAY かつ deletedAt IS NULL |
| 終了済み | endDate < TODAY かつ deletedAt IS NULL |
| 削除済み | deletedAt IS NOT NULL |
medication_logs — 入力フィールド
| フィールド | 型 | 必須 | バリデーション |
|---|---|---|---|
| medicationId | integer | ○ | 存在する medications.id であること |
| status | varchar | ○ | administered / skipped / partial |
| administeredAt | timestamptz | ○ | 未来日時不可 |
| dosageAmount | decimal | - | 0より大きい値。省略時は medications の値を引き継ぐ |
| dosageUnit | varchar | - | enum値。省略時は medications の値を引き継ぐ |
| memo | text | - | 最大500文字(スキップ理由や体調メモなど) |
status(投与ステータス)
| 値 | 表示名 | 説明 |
|---|---|---|
administered | 投与済み | 予定通り投与した |
skipped | スキップ | 投与しなかった(体調不良で吐き出した等) |
partial | 一部投与 | 規定量の一部のみ投与した(吐き出し等) |
APIエンドポイント
全エンドポイントで認証必須(__Host-session Cookie)。
medications(投薬スケジュール)
| メソッド | パス | 概要 |
|---|---|---|
| POST | /api/pets/:petId/medications | 投薬スケジュール登録 |
| GET | /api/pets/:petId/medications | 投薬スケジュール一覧 |
| GET | /api/pets/:petId/medications/:medicationId | 投薬スケジュール詳細 |
| PATCH | /api/pets/:petId/medications/:medicationId | 投薬スケジュール更新 |
| DELETE | /api/pets/:petId/medications/:medicationId | 投薬スケジュール削除(論理削除) |
medication_logs(投薬記録)
| メソッド | パス | 概要 |
|---|---|---|
| POST | /api/pets/:petId/medications/:medicationId/logs | 投薬記録登録 |
| GET | /api/pets/:petId/medications/:medicationId/logs | 投薬記録一覧 |
| GET | /api/pets/:petId/medications/:medicationId/logs/:logId | 投薬記録詳細 |
| PATCH | /api/pets/:petId/medications/:medicationId/logs/:logId | 投薬記録更新 |
| DELETE | /api/pets/:petId/medications/:medicationId/logs/:logId | 投薬記録削除(物理削除) |
POST /api/pets/:petId/medications — 投薬スケジュール登録
リクエストボディに入力フィールドを指定して投薬スケジュールを登録する。
- 成功時:
201 Created、作成されたスケジュール情報を返す - ペットが存在しない / 他ユーザーのペット / 論理削除済み:
404 Not Found
{ "data": { "id": 1, "petId": 1, "name": "アモキシシリン", "dosageAmount": 1, "dosageUnit": "tablet", "timesPerDay": 2, "frequencyNote": "朝夕食後", "route": "oral", "startDate": "2026-02-18", "endDate": "2026-03-04", "memo": "動物病院で処方。14日間投与。", "createdAt": "2026-02-18T10:00:00Z", "updatedAt": "2026-02-18T10:00:00Z" }}GET /api/pets/:petId/medications — 投薬スケジュール一覧
指定ペットの投薬スケジュール一覧を返す。論理削除済みは含まない。
- 成功時:
200 OK - 未登録時: 空配列を返す(エラーではない)
- クエリパラメータ
status:active(投薬中のみ)/completed(終了済みのみ)/ 未指定(全件)
{ "data": [ { "id": 1, "name": "アモキシシリン", "..." : "..." }, { "id": 2, "name": "プレドニゾロン", "..." : "..." } ]}GET /api/pets/:petId/medications/:medicationId — 投薬スケジュール詳細
指定IDの投薬スケジュール情報を返す。
- 成功時:
200 OK - 存在しない / 他ユーザーのペット / 論理削除済み:
404 Not Found
PATCH /api/pets/:petId/medications/:medicationId — 投薬スケジュール更新
指定したフィールドのみ部分更新する。リクエストボディに含まれないフィールドは変更しない。
- 成功時:
200 OK、更新後のスケジュール情報を返す - 存在しない / 他ユーザーのペット / 論理削除済み:
404 Not Found
DELETE /api/pets/:petId/medications/:medicationId — 投薬スケジュール削除
論理削除(deleted_at に現在日時を設定)する。関連する投薬記録は保持される。
- 成功時:
204 No Content - 存在しない / 他ユーザーのペット / 既に削除済み:
404 Not Found
POST /api/pets/:petId/medications/:medicationId/logs — 投薬記録登録
投薬記録を登録する。
- 成功時:
201 Created、作成された記録を返す - 投薬スケジュールが存在しない / 論理削除済み:
404 Not Found
{ "data": { "id": 1, "medicationId": 1, "status": "administered", "administeredAt": "2026-02-18T08:30:00Z", "dosageAmount": null, "dosageUnit": null, "memo": null, "createdAt": "2026-02-18T08:31:00Z" }}GET /api/pets/:petId/medications/:medicationId/logs — 投薬記録一覧
指定投薬スケジュールの投薬記録一覧を administeredAt の降順で返す。
- 成功時:
200 OK - 未登録時: 空配列を返す(エラーではない)
GET /api/pets/:petId/medications/:medicationId/logs/:logId — 投薬記録詳細
- 成功時:
200 OK - 存在しない:
404 Not Found
PATCH /api/pets/:petId/medications/:medicationId/logs/:logId — 投薬記録更新
指定したフィールドのみ部分更新する。
- 成功時:
200 OK、更新後の記録を返す - 存在しない:
404 Not Found
DELETE /api/pets/:petId/medications/:medicationId/logs/:logId — 投薬記録削除
物理削除する。
- 成功時:
204 No Content - 存在しない:
404 Not Found
認可ルール
- 全エンドポイントで認証必須
- 自分が登録したペットの投薬情報のみ操作可能(他ユーザーのペットIDを指定した場合は
404を返し、存在の有無を漏らさない) - 論理削除済みペットの投薬情報へのアクセスは
404を返す - 論理削除済み投薬スケジュールの投薬記録へのアクセスは
404を返す
エッジケース
endDateがstartDateより前の場合 →422 Unprocessable EntitydosageAmountとdosageUnitの片方のみ指定された投薬記録 → 両方指定するか両方省略のみ許可、片方のみの場合は422 Unprocessable Entity- 論理削除済みペットへの投薬登録 →
404 Not Found - 論理削除済み投薬スケジュールへの記録登録 →
404 Not Found administeredAtが未来日時 →422 Unprocessable Entity- 同一
medicationIdに対して同一administeredAtの重複記録 → 許可する(1日複数回の投薬を想定)
FR-010(通知・リマインド)との連携
投薬スケジュールの timesPerDay と startDate / endDate は、FR-010 の投薬リマインド通知の基礎データとなる。通知のタイミング設定(何時に通知するか等)はFR-010側で定義する。本仕様では通知機能自体は対象外とする。
拡張予定(現時点ではスコープ外)
- 通知連携(FR-010で対応)
- 家族共有時の投薬記録アクセス(FR-011で対応)
- 通院履歴(FR-006)との関連付け(処方元の記録)
- 投薬カレンダー表示
- 薬の残量管理
検証方法
- 投薬スケジュール登録 → 一覧取得 → 詳細取得の一連フローが完了すること
- 必須フィールド(name, dosageAmount, dosageUnit, timesPerDay, startDate)未指定時にバリデーションエラーが返ること
endDateがstartDateより前の場合に422が返ることstatusクエリパラメータで投薬中/終了済みのフィルタが正しく動作すること- 他ユーザーのペットの投薬情報に対して
404が返ること - PATCH で指定したフィールドのみが更新され、他フィールドが変更されないこと
- DELETE 後に一覧・詳細から表示されなくなること
- DELETE 後に関連する投薬記録が保持されていること
- 投薬記録登録時にステータス(administered/skipped/partial)が正しく保存されること
- 投薬記録の
dosageAmount/dosageUnit片方のみ指定で422が返ること - 論理削除済み投薬スケジュールへの記録登録が
404で拒否されること