028 - Resto: Spaces Reservation, VIP Room Bundling & Table Mapping POS
- Tanggal: 2026-08-13
- Chat/topik: Fitur Resto end-to-end — reservasi space (Room/TableArea) by pax, bundling Court VIP dengan Room, mapping meja oleh kasir di POS. QR ordering per meja = app terpisah (fase lain).
Ringkasan perubahan
Fitur Resto lintas 7 aplikasi:
- Schema (migration 020):
spaces(Room = unit eksklusif; TableArea = pool pax, meja fleksibel),space_reservations,space_tables+space_reservation_tables(mapping meja kasir),courts.bundled_space_id, setting durasi/jam resto distore_settings. - Member (Android v1.17 → parity iOS v1.6 + Web v0.7): menu Resto → landing space → reservasi by pax (tanggal, jam mulai, guests; durasi fixed dari settings) atau Room VIP eksplisit dengan minimum spend terlihat; History dengan cancel; callout "Includes Private VIP Room" di court detail.
- Backend (mpc-be v1.7): endpoint spaces/availability/reservations; availability Room eksklusif vs TableArea pool (
online_capacity_pax= buffer walk-in,max_party_pax= batas rombongan online); hard block court VIP saat Room bundling terisi;POST /ordersauto-create reservasi CourtBundle + cascade cancel/reschedule. - Admin (v0.8): halaman Resto (Spaces CRUD + Reservations harian + walk-in manual), picker Bundled VIP Room di form Court.
- POS (mpc-be-pos v1.7 + mpc-pos v1.4): rutinitas kasir — daftar reservasi harian, assign meja per reservasi (multi-meja), ubah status (Seated/Completed/NoShow), kelola meja per area.
Keputusan desain kunci:
- Reservasi TIDAK berhubungan dengan meja — availability online murni pax pool / room eksklusif; mapping meja lapisan operasional kasir.
- Minimum spend display-only — reservasi Rp 0 (tanpa pajak); pemenuhan lewat pembelian FnB yang kena PB1 10% + service 5% di jalur existing; harga court tetap non-PB1.
- Bundling best-effort (keputusan owner 2026-08-13, menggantikan hard block awal): court VIP tetap bisa dibook saat Room bundling penuh; reservasi CourtBundle hanya dibuat bila Room kosong; response
POST /ordersmenyertakanbundled_room_included(true/false); copy court detail member apps: "Included when the room is available for your slot". - QR ordering per meja = app terpisah, fase berikutnya;
space_tablessudah kompatibel (nol rework). - Order F&B tidak dari landing Resto (feedback owner 2026-08-13): link "Order food & drinks" dihapus dari landing Resto di ketiga member app; aksi order F&B hanya muncul di success state setelah reservasi space berhasil.
- Flow reservasi berurutan (feedback owner 2026-08-13, revisi lanjutan): tanggal dipilih di landing Resto (bukan di reserve screen) → pilih ruangan/space + pax → pilih jam tersedia → confirm (bottom sheet, bukan dialog usang) → opsional pre-order F&B terikat ke reservasi itu (bukan alur cart court booking yang membingungkan).
- Order F&B terikat reservasi butuh schema baru:
transactions.space_reservation_id(migration 021) — pre-order F&B pasca-reservasi disimpan dengan reference ke reservasi, lalu ditampilkan sebagaiorders[]diGET /spaces/reservations/mesehingga History menampilkan reservasi + pesanan menunya sebagai satu kesatuan (bukan dua entri terpisah/hilang).
Impact bisnis
Resto venue jadi bisa direservasi online (positioning premium, cross-sell F&B), Room VIP termonetisasi via minimum spend tanpa komplikasi pajak, Court VIP naik value karena bundling private room, dan operasional kasir tetap sederhana (mapping meja pagi hari, tanpa denah rumit).
Epic / User stories
- Epic: Reservasi Resto end-to-end (member → admin → kasir POS).
- US: Sebagai member, saya ingin reservasi meja resto berdasarkan jumlah tamu, agar tempat siap saat saya datang.
- US: Sebagai member, saya ingin memilih Room VIP dengan minimum spend yang jelas di awal, agar tidak ada kejutan biaya.
- US: Sebagai member yang booking court VIP, saya ingin private room otomatis termasuk, agar pengalaman VIP utuh.
- US: Sebagai kasir, saya ingin melihat reservasi hari ini dan menentukan meja yang dipakai, agar penataan siap sebelum tamu datang.
- US: Sebagai admin, saya ingin mengelola spaces & reservasi (termasuk walk-in), agar operasional terkontrol.
User terdampak
Member (Android/iOS/Web), admin, kasir POS.
Aplikasi terdampak
- mpc-be: PERLU (selesai, v1.7) — endpoint spaces/reservations, bundling + hard block, api_contract §14.
- mpc-be-pos: PERLU (selesai, v1.7) — endpoint
/resto(spaces, tables CRUD, reservasi harian, status, assign meja), api_contract POS. - mpc-admin: PERLU (selesai, v0.8) — Prisma models, halaman Resto, picker bundled room.
- mpc-android: PERLU (selesai, v1.17) — menu Resto, flow reservasi, History, callout VIP room. APK di Downloads.
- mpc-ios: PERLU (selesai, v1.6) — parity 1:1.
- mpc-web: PERLU (selesai, v0.7) — parity 1:1 (
/resto,/resto/reserve). - mpc-pos: PERLU (selesai, v1.4) — tab Resto (reservasi harian + meja). APK di Downloads.
- mpc-owner: TIDAK — domain dashboard owner; data resto belum masuk datamart.
- ksr-sync: TIDAK — belum ada kebutuhan sync tabel resto ke ksrdb (evaluasi menyusul bila owner butuh laporan resto).
Perubahan schema
spaces, space_reservations, space_tables, space_reservation_tables (baru); courts.bundled_space_id; store_settings.space_reservation_duration_minutes + resto_open_time + resto_close_time. Detail + seed + rollback: mpc-dev/docs/schema/migration/020-resto-spaces-reservations.md (sudah diapply ke mpcdb lokal; jalankan di server saat deploy).
Lanjutan (flow reorder + pre-order terikat): transactions.space_reservation_id (nullable FK ke space_reservations, + index) — mpc-dev/docs/schema/migration/021-link-orders-to-space-reservations.md.
Perubahan kode
mpc-be:internal/spaces/baru;internal/courts(bundled_space + hard block),internal/bookings/internal/orders(auto-reserve CourtBundle + cascade),internal/settings;mpc-dev/docs/api/be.md§14.- Lanjutan:
internal/transactions(SpaceReservationID+GetTransactionsBySpaceReservationIDs),internal/spaces(GetMyReservationsenrichorders[],GetReservationForCustomer),internal/orders(CheckoutRequest.space_reservation_id+ validasi kepemilikan).
- Lanjutan:
mpc-be-pos:internal/resto/baru + wiring;mpc-dev/docs/api/be.mdsection Resto.mpc-admin:prisma/schema.prisma,src/actions/resto.ts,src/app/(dashboard)/services/resto/*, form Court + sidebar.mpc-android:feature/resto/*baru; Dtos/Models/Mappers/Api/Repository; Home, History, CourtDetail, nav.- Lanjutan:
RestoScreen.kt(date picker + "Your reservations"),SpaceReserveScreen.kt(hapus date picker internal, pre-order CTA),FoodDrinksScreen.kt/ProductCatalogScreen.kt(mode pre-order viareservationId),HistoryScreen.kt(ReservationOrdersSummary),CheckoutState.spaceReservationId,MainTabState+goHistory(), Dtos/Models/Mappers untukorders[].
- Lanjutan:
mpc-ios:Features/Resto/*baru; Dtos/Models/Mappers/Api/Repository; Home, History, CourtDetail, Route.- Lanjutan: parity 1:1 dari perubahan Android di atas (
RestoScreen.swift,SpaceReserveScreen.swift,FoodDrinksScreen.swift/ProductCatalogScreen.swift,HistoryScreen.swift,AppState.swift(CheckoutState.spaceReservationId,MainTabState),Router.goHistory(), Dtos/Models/Mappers).
- Lanjutan: parity 1:1 dari perubahan Android di atas (
mpc-web:src/app/resto/*,src/lib/resto/space.ts, repo/types, History, courts, header/home.- Lanjutan:
/resto(date strip + "Your reservations"),/resto/reserve(hapus date picker internal, pre-order CTA + "Maybe later"),/resto/orderbaru (katalog F&B standalone tertaut reservasi),/history(ReservationOrdersSummary+?tab=resto),useCheckout(spaceReservationId),/payment(kirimspace_reservation_id, guard court-less checkout).
- Lanjutan:
Deploy production (lanjutan, 2026-08-13 malam)
- Migration 021 diapply ke
mpcdbproduction (docker exec mpc-postgres psql) — kolom + indextransactions.space_reservation_idterverifikasi via\d transactions. SKIP_WEB=1 SKIP_POS_WEB=1 ./deploy-mpc.sh— build+kirimmpc-be,mpc-be-pos(tanpa perubahan, ikut restart), member web (mpc-web-cs.glenrh.com); admin & POS Flutter web di-skip (tidak ada perubahan kode yang perlu redeploy sesi ini).- Smoke test prod:
GET /spaces200,mpc-web-cs.glenrh.com/resto200,/resto/order200,/history307 (redirect login, expected tanpa sesi) — semua service (mpc-be,mpc-be-pos,mpc-web-cs) active. - APK
mpc-android-demo-v1.17.apkdi-rebuild ulang (overwrite) untuk menyertakan perubahan flow reorder + pre-order; instalasi ke Mi 9 di-skip karena device belum terhubung ke adb saat sesi ini — APK sudah siap di Downloads. - iOS:
xcodebuild ... build→ BUILD SUCCEEDED (simulator).
Deploy production (2026-08-13)
- Migration 020 diapply ke
mpcdbproduction (mpc-postgresdi VPS) — 4 spaces + 10 meja + bundling CRT-03 terverifikasi. deploy-mpc.shfull: mpc-be, mpc-be-pos, mpc-admin (mpc-web.glenrh.com), member web (mpc-web-cs.glenrh.com/resto), POS web (mpc-pos.glenrh.com) — semua smoke test 200;GET /spaces+ availability +bundled_spaceCourt 3 terverifikasi di prod.- APK demo:
mpc-android-demo-v1.17.apk+mpc-pos-demo-v1.4.apkdi Downloads (Android di-rebuild setelah copy best-effort).
Catatan terbuka
- Fase berikutnya (disepakati, belum dikerjakan): QR ordering per meja sebagai app terpisah (web menu tamu + intake order + seat layout POS + tracking otomatis minimum spend).