Files
apskel-pos-backend/docs/migrasi-printer-types.md
T
2026-10-01 22:26:44 +07:00

7.6 KiB

Migrasi printer_type ke printer_types

1 Oktober 2026

Ringkasan

printer_type (string) dihapus dan diganti printer_types (array string), sehingga satu produk bisa dicetak ke lebih dari satu printer. Contohnya "Paket Makan Minum" dengan ["kitchen", "bar"] tercetak di kitchen dan bar sekaligus.

Ini breaking change. Setelah backend baru dirilis, client yang masih membaca printer_type tidak menerima printer apa pun. Karena itu app POS dan dashboard harus diupdate lebih dulu, lihat Urutan rilis.

Yang perlu bertindak:

  • App POS: baca printer_types dan cetak tiap item ke semua printer di dalamnya.
  • Dashboard admin: ganti pilihan printer di form produk jadi multi-select yang mengirim printer_types.

Perubahan response

printer_type hilang dari semua response dan digantikan printer_types, yang nilainya selalu array dan tidak pernah null.

Endpoint Letak field
POST /api/v1/products, PUT /api/v1/products/:id, GET /api/v1/products, GET /api/v1/products/all, GET /api/v1/products/:id objek produk
POST /api/v1/orders, GET /api/v1/orders, GET /api/v1/orders/:id, PUT /api/v1/orders/:id order_items[]
POST /api/v1/orders/:id/add-items added_items[] dan updated_order.order_items[]
POST /api/v1/self-order/orders, GET /api/v1/self-order/orders/:session_id order_items[]
/api/v1/product-recipes (semua yang mengembalikan recipe) product
/api/v1/inventory product, selalu [] karena produk di sini hanya berisi id dan nama

Contoh satu item di order_items[]:

{
  "product_name": "Paket Makan Minum",
  "printer_types": ["kitchen", "bar"],
  "print_to_checker": true
}

Aturan nilainya:

  • printer_types: [] artinya produk tidak dicetak ke printer mana pun.
  • Urutan printer sesuai yang disimpan admin, tanpa duplikat.
  • Void, refund, payment, split bill, dan set customer tidak membawa data printer, sama seperti sebelumnya.

Perubahan request produk

POST /api/v1/products dan PUT /api/v1/products/:id menerima printer_types sebagai pengganti printer_type. Kalau printer_type masih dikirim, field itu diabaikan tanpa error.

{
  "name": "Paket Makan Minum",
  "category_id": "<uuid>",
  "price": 25000,
  "printer_types": ["kitchen", "bar"]
}
Request printer_types yang dikirim Hasil
Create tidak dikirim ["kitchen"]
Create ["kitchen", "bar"] ["kitchen", "bar"]
Create [] atau hanya string kosong ["kitchen"]
Update tidak dikirim tidak berubah
Update ["bar"] ["bar"], seluruh daftar diganti
Update [] [], produk tidak dicetak ke mana pun

Sebelum disimpan, spasi di awal dan akhir tiap entri dibuang, lalu entri kosong dan duplikat dihapus. Urutan dipertahankan.

Tiap entri maksimal 50 karakter. Kalau lebih, request ditolak dengan error code 310 dan pesan each printer_types entry cannot exceed 50 characters.

Migrasi app POS

App POS harus mengirim tiap item ke semua printer di printer_types, sehingga satu item bisa muncul di lebih dari satu tiket.

  1. Ganti printer_type dengan printer_types (list string) di model order item dan produk.
  2. Selama backend lama masih jalan, printer_types belum ada di response. Pakai [printer_type] kalau printer_types tidak ada, supaya app baru bisa dirilis sebelum backend.
  3. Saat mencetak, kelompokkan item per printer dengan mengulang setiap entri printer_types milik item.
  4. Item dengan printer_types: [] tidak dicetak ke printer station mana pun.
  5. print_to_checker tidak berubah dan tetap diperlakukan terpisah.
  6. Untuk tambahan pesanan dari POST /api/v1/orders/:id/add-items, cetak dari added_items[].
tiket = {}
untuk setiap item di order_items:
    printers = item.printer_types ?? [item.printer_type]   // fallback hanya untuk backend lama
    untuk setiap printer di printers:
        tiket[printer].tambah(item)
untuk setiap (printer, items) di tiket:
    cetak items ke printer

Perbaikan di added_items[]: sebelumnya field ini selalu berisi product_name dan printer kosong, serta print_to_checker: true. Sekarang isinya lengkap seperti item di updated_order.order_items[], dengan urutan sesuai request. Kalau app selama ini mengakali dengan mencari item baru di updated_order, cara itu bisa diganti dengan added_items[] langsung.

Migrasi dashboard

Form produk di dashboard harus memakai multi-select printer dan selalu mengirim daftar lengkapnya lewat printer_types.

  1. Ganti dropdown printer tunggal dengan multi-select, misalnya checkbox, berisi pilihan printer yang sama.
  2. Saat membuka form edit, isi pilihan dari printer_types. Selama backend lama masih jalan, pakai [printer_type] kalau printer_types tidak ada.
  3. Saat menyimpan, kirim printer_types berisi semua printer yang dipilih.
  4. Selama backend lama masih jalan, kirim juga printer_type berisi printer pertama. Backend lama hanya membaca printer_type, dan backend baru mengabaikannya.
  5. Di daftar produk, tampilkan semua printer dari printer_types.

Backend tidak membatasi nilai printer. Nilainya harus sama persis dengan nama printer yang dikenal app POS, termasuk huruf besar dan kecilnya.

Create dengan printer_types: [] tetap menghasilkan ["kitchen"]. Produk tanpa printer dibuat dulu, lalu di-update dengan printer_types: [].

Database dan urutan rilis

Migration 000099_add_printer_types_to_products menambah kolom products.printer_types (JSONB, NOT NULL, default ["kitchen"]), mengisinya dari printer_type, lalu menghapus kolom printer_type beserta index-nya.

  • Produk dengan printer_type berisi nilai menjadi [printer_type].
  • Produk dengan printer_type NULL atau kosong menjadi [].

Urutan rilis:

  1. Rilis app POS baru, yang membaca printer_types dengan fallback ke printer_type, ke semua outlet.
  2. Rilis dashboard baru, yang mengirim printer_types dan printer_type.
  3. Jalankan migration 000099 tepat sebelum deploy backend baru. Di antara keduanya, backend lama gagal menyimpan produk karena kolom printer_type sudah tidak ada.
  4. Setelah backend baru jalan, dashboard boleh berhenti mengirim printer_type, dan fallback di app POS boleh dihapus.
  5. Atur produk multi-printer, misalnya "Paket Makan Minum" ke ["kitchen", "bar"].

Outlet yang masih memakai app POS lama setelah langkah 3 tidak menerima printer untuk semua item. Pastikan langkah 1 sudah selesai di semua outlet.

Rollback: jalankan down migration dan deploy backend lama bersamaan. Down migration membuat ulang kolom printer_type berisi printer pertama, lalu menghapus printer_types, jadi yang hilang hanya printer tambahan.

Checklist

  • App POS baru (dengan fallback) terpasang di semua outlet
  • Dashboard baru mengirim printer_types dan printer_type
  • Migration 000099 dan backend baru dirilis di staging
  • Uji "Paket Makan Minum" dengan ["kitchen", "bar"] tercetak di dua printer, saat order baru dan saat tambah pesanan
  • Migration 000099 dan backend baru dirilis di production
  • Dashboard berhenti mengirim printer_type
  • Fallback printer_type di app POS dihapus

FAQ

Kenapa printer_type dihapus, bukan dipertahankan? Supaya hanya ada satu sumber data printer. Dua field yang menyimpan hal yang sama bisa saling berbeda.

Apakah kitchen dan bar menerima tiket yang sama? Ya. Keduanya mencetak "Paket Makan Minum" lengkap dengan varian dan modifier-nya. Memecah isi paket per station butuh fitur bundle, yang di luar rilis ini.

Apakah nilai printer dibatasi? Tidak. Nilainya string bebas sampai 50 karakter, dan harus sama dengan nama printer di app POS.