エンティティ構成
idPKint AUTO
studio_idFKint
namevarchar(100)
descriptiontext NULL
image_urlvarchar(500) NULL
duration_minutesint = 60
is_activebool = true
display_orderint = 0
deleted_attimestamp NULL
idPKint AUTO
sub_plan_idFKint
day_of_weektinyint (0-6)
start_timetime
end_timetime
capacityint
is_activebool = true
idPKint AUTO
sub_plan_idFKint
datedate
start_timetime
end_timetime
capacityint
idPKint AUTO
reservation_idFKint
sub_plan_idFKint
user_idFKvarchar(36)
studio_idFKint
reserved_datedate
start_time / end_timetime
statusRESERVED | CANCELLED | COMPLETED
リレーション
Studio
→
SubPlan
1 : N — 店舗が複数のサブプランを持つ
SubPlan
→
SubPlanSlot
1 : N — 曜日ごとの通常枠設定
SubPlan
→
SubPlanSlotOverride
1 : N — 特定日の枠上書き(臨時変更用)
Reservation
→
SubPlanReservation
1 : N — メイン予約に紐づくサブプラン予約
SubPlan
→
SubPlanReservation
1 : N — どのサブプランの予約か
インデックス(Migration)
IDX sub_plans(studio_id)
IDX sub_plan_slots(sub_plan_id, day_of_week)
IDX sub_plan_slot_overrides(sub_plan_id, date)
IDX sub_plan_reservations(reservation_id)
IDX sub_plan_reservations(sub_plan_id, reserved_date, status)
IDX sub_plan_reservations(user_id)
IDX sub_plan_reservations(studio_id, reserved_date)
UNQ sub_plan_reservations(reservation_id, sub_plan_id)
予約作成フロー(createReservation 拡張部分)
1. 仮予約作成(Transaction 1)
プログラム取得 → 既存仮予約削除 → PREACTIVE ステータスで Reservation 作成
2. バリデーション & ACTIVE化(Transaction 2)
時間帯チェック、重複チェック、定員チェックなど既存バリデーション実行後、仮予約を ACTIVE に更新
3. サブプラン予約作成(同一 Transaction 2 内)
sub_plan_reservations[] が渡された場合に実行。重複サブプランチェック → メイン予約時間範囲内かチェック →
サブプランの存在確認 & 店舗一致確認 → Override / Slot から枠容量を取得 → 空きチェック →
SubPlanReservation 作成(status: RESERVED)
4. RemoteLock API 呼び出し
トランザクション外で RemoteLock の Booking を作成。失敗時は予約を CANCELLED に戻し、チケットを復元
5. RemoteLock 情報更新 & 後処理
booking_id / pin / qr_code を reservation に保存(Transaction 3) → 通知購読 → QRコード生成 & アップロード → メール送信
キャンセルフロー(cancelReservation 拡張部分)
1. RemoteLock 解除 & キャンセル(単一 Transaction)
RemoteLock booking deactivate(失敗してもログのみで続行) →
Reservation を CANCELLED に更新 →
cancelSubPlanReservationsForReservation でサブプラン予約も一括 CANCELLED →
チケット復元 → メール送信
空き枠取得フロー(getAvailableSlots)
1. 枠情報取得
対象日の曜日から SubPlanSlot(is_active)を取得。同日の SubPlanSlotOverride があればそちらを優先
2. 空き計算
各枠の時間帯に対して既存の RESERVED/COMPLETED 件数をカウント。capacity - reserved_count = available_count として返却。reservation_start_time / reservation_end_time が指定されていれば、メイン予約時間内の枠のみにフィルタ
新規ファイル
NEWcontrollers/dto/sub-plans.dto.ts+147
NEWcontrollers/sub-plans.controller.ts+611
NEWmodels/sub-plan.ts+66
NEWmodels/sub-plan-slot.ts+59
NEWmodels/sub-plan-slot-override.ts+44
NEWmodels/sub-plan-reservation.ts+85
NEWpersistence/sub-plans.persistence.ts+376
NEWservices/sub-plans.service.ts+557
NEWdatabase/migrations/create_sub_plans_tables.ts+372
NEWdatabase/seeder/seeds/sub_plans.ts+307
変更ファイル
MODcontrollers/dto/users.dto.ts+8
MODcontrollers/users.controller.ts+15
MODcontrollers/user-payment-methods.controller.ts-1 ログ絵文字削除
MODmodels/reservation.ts+5 OneToMany 追加
MODmodels/change-log.ts+8 テーブル名定義追加
MODmodels/index.ts+8 エンティティ登録
MODmodules/api.module.ts+2 Controller登録
MODpersistence/reservations.persistence.ts+2 JOIN追加
MODservices/reservations.service.ts+350 -356 大幅リファクタ + サブプラン連携
MODconfig/constants.ts+4
MODdatabase/seeder/index.ts+4 -1
MODdatabase/migrations/add_indexes_for_search_performance.ts+1 -1