# HotelFix — Spesifikasi Master (Gabungan v1 + v2 + Multi-Property)

Versi: 2.1 · Tanggal: 5 Juli 2026 · Status: **spesifikasi final untuk implementasi**
Perubahan 2.1: penegasan pemilih properti hanya untuk user multi-akses (§2.3),
penguatan pengisian aset saat lapor (§F1), penambahan maintenance sipil &
finishing (§3, §10), pencatatan biaya perbaikan yang eksplisit — di mana &
kapan (§F14), meteran utilitas listrik/air + KWH bulanan (§F15), dan rekap
harian untuk morning briefing (§F16).
Menggantikan: spesifikasi v1 (defect tracking) dan `SPEK-ASET-MAINTENANCE.md` (draft v2).

---

## 0. Arsitektur produk

Sistem terdiri dari **dua aplikasi dan satu database**:

```
┌──────────────────────────┐      ┌──────────────────────────────┐
│ 1. APLIKASI MOBILE       │      │ 2. APLIKASI WEB (PHP)        │
│    Android + iOS         │      │    Dashboard / Admin /       │
│    (teknisi, housekeeping│      │    Monitoring / Laporan      │
│     IT staff, driver)    │      │    (dept head, admin, GM,    │
│                          │      │     corporate)               │
│  offline-first, kamera,  │      │                              │
│  QR scan, push notif     │      │  server-rendered + kalender  │
└───────────┬──────────────┘      └──────────────┬───────────────┘
            │  REST API (JSON, token)            │  session
            ▼                                    ▼
      ┌─────────────────────────────────────────────────┐
      │ 3. BACKEND PHP  —  REST API + web + generator PM │
      │    + push gateway (FCM/APNs)                     │
      └───────────────────────┬──────────────────────────┘
                              ▼
                     ┌────────────────┐
                     │  MySQL 8 /     │  satu skema, semua tabel
                     │  MariaDB       │  ber-`property_id`
                     └────────────────┘
```

| Komponen | Teknologi | Catatan |
|---|---|---|
| Mobile | **Native** — Android (Kotlin/Jetpack Compose) + iOS (Swift/SwiftUI) | Keputusan final. DB lokal Room (Android)/SQLite (iOS); Android dulu, iOS Fase 3 |
| Web + API | **Plain PHP 8.2+ terstruktur** (bukan Laravel) — 3 lapis, class-based, inheritance page builder, 1 CSS, 1 file per halaman | Konvensi lengkap di [ARSITEKTUR-BACKEND-PHP.md](ARSITEKTUR-BACKEND-PHP.md). Satu aplikasi melayani web (session) + REST API (token) |
| Database | **MySQL/MariaDB** (tetap) | utf8mb4; semua tabel membawa `property_id` |
| Push notification | Firebase Cloud Messaging (Android) + APNs (iOS) | Topic per properti+divisi untuk broadcast; token per user untuk personal |
| Penyimpanan file | Filesystem/objek storage, di luar DB | Foto WO, dokumen aset, berita acara vendor |
| Job terjadwal | Cron / Task Scheduler memanggil generator harian | + lazy-trigger saat login sebagai cadangan |

Pembagian fungsi antar aplikasi:

| Fungsi | Mobile | Web |
|---|---|---|
| Lapor defect + foto kamera | ● | ○ (bisa, darurat) |
| Tugas hari ini + eksekusi checklist | ● | ○ |
| Scan QR aset/kamar | ● | – |
| Input meter (km/jam/suhu) | ● | ○ |
| Lonceng notifikasi + kirim warning | ● | ● |
| Kelola aset, jadwal, checklist builder | – | ● |
| Review usulan rencana PM + kalender penuh | ○ (lihat) | ● (kelola) |
| Dashboard, KPI, laporan, ekspor | ○ (ringkas) | ● |
| Admin user/master/multi-property | – | ● |

● = fungsi utama · ○ = tersedia terbatas · – = tidak ada

---

## 1. Tujuan produk

Satu sistem untuk seluruh siklus pemeliharaan hotel (bisa multi-hotel):

1. **Reaktif** — defect dilaporkan dengan foto → work order → diperbaiki → foto bukti → verifikasi (v1).
2. **Proaktif** — registri aset, jadwal perawatan berulang otomatis, checklist digital, indikator kapan aset harus diganti (v2).
3. **Koordinasi** — notifikasi & warning antar divisi, kalender bersama, kompetensi teknisi, vendor.
4. **Kontrol** — dashboard per properti + konsolidasi korporat, kepatuhan sertifikat, biaya.

Target terukur: rasio WO korektif:preventif 40:60; PM compliance > 90%;
nol sertifikat kedaluwarsa; ≥ 90% pekerjaan tercatat lewat aplikasi.

---

## 2. Multi-property & struktur organisasi

### 2.1 Properti

- Tabel `properties`: `id, code, name, address, timezone, logo, active`.
- **Semua** data master dan transaksi membawa `property_id`. Isolasi
  ditegakkan di server pada setiap query (bukan sekadar filter UI).
- Konfigurasi per properti: SLA per prioritas, ambang kesehatan aset,
  jam quiet-hours notifikasi, hari kerja.

### 2.2 Level akses

| Level | Siapa | Lingkup |
|---|---|---|
| `super_admin` | Korporat/owner sistem | Semua properti: buat properti, admin properti, template korporat, dashboard konsolidasi |
| `property_admin` | Admin per hotel | Satu properti: user, master data, konfigurasi |
| `dept_head` | Chief engineer, IT manager, exec. chef, chief security, exec. housekeeper | Departemennya di satu properti (bisa lebih, lihat 2.3) |
| `technician` | Teknisi/IT staff/steward/driver | WO departemennya |
| `reporter` | HK, FO, F&B service | Lapor defect + laporan sendiri |
| `viewer` | GM, financial controller | Read-only satu properti; corporate viewer = read-only semua |

### 2.3 Akses lintas properti

- `user_property_access (user_id, property_id, role, department)` — satu
  user bisa punya peran di lebih dari satu properti:
  - *Cluster engineer*: technician di Hotel A dan Hotel B.
  - *Corporate chief engineer*: dept_head engineering di semua properti.
- **Pemilih properti hanya muncul untuk user multi-akses.** User dengan satu
  akses properti (mayoritas teknisi & HK) tidak pernah melihat pemilih
  properti, nama properti lain, atau indikasi apa pun bahwa ini sistem
  multi-hotel — bagi mereka aplikasi terasa seperti dibuat khusus untuk
  hotelnya. Pemilih properti (di header + saat login) hanya ditampilkan bila
  `user_property_access` user berjumlah > 1; jika = 1, properti dipilih
  otomatis dan disembunyikan. Notifikasi menyebutkan properti asal hanya
  untuk user multi-akses.
- Data tidak pernah bocor antar properti untuk user yang tidak punya akses.

### 2.4 Template korporat

- `super_admin` dapat membuat **template checklist** dan **template kategori
  aset** di level korporat, lalu mendorongnya ke properti (properti boleh
  menyesuaikan salinannya; template dan salinan ter-link agar bisa
  dibandingkan saat audit brand standard).

---

## 3. Taksonomi aset

(Aset = barang yang bisa rusak dan mengganggu operasi/tamu, perlu jadwal
rawat, atau perlu keputusan penggantian. Barang habis pakai = sparepart.)

### Engineering — MEP
| Kategori | Contoh |
|---|---|
| HVAC | Chiller, cooling tower, AHU, FCU, split AC, VRV, exhaust fan |
| Kelistrikan | Genset, trafo, panel LVMDP/SDP, UPS gedung, ATS, capacitor bank, penangkal petir |
| Plumbing | Pompa transfer/booster/sump, water heater/boiler, STP, WTP, water softener, grease trap, roof tank/GWT |
| Transportasi vertikal | Lift tamu/servis, eskalator, gondola *(izin Disnaker)* |
| Fire & life safety | Fire pump (jockey/electric/diesel), hydrant, sprinkler, MCFA, APAR, emergency lamp, exit sign, pintu darurat, PA/paging darurat |
| Kolam & spa | Pompa sirkulasi, filter, dosing pump, sauna/steam generator, jacuzzi |
| Laundry | Washer, dryer, flatwork ironer, press |
| Bangunan | Atap, waterproofing, fasad, rel gondola |

### Sipil & finishing (maintenance sipil)
Pekerjaan finishing yang berbasis **lokasi/area**, umumnya tidak melekat ke
satu unit aset — dikelola per lokasi dengan siklus perawatan sendiri.
| Kategori | Contoh pekerjaan |
|---|---|
| Cat & dinding | Cat ulang tembok interior/eksterior, touch-up noda, anti-jamur area lembap |
| Kayu & finishing | Plitur/politur kembali kusen-pintu-furnitur, cat duco, perbaikan veneer/HPL |
| Lantai & batu | Poles marmer/granit, isi ulang nat keramik, epoxy lantai BOH, vinyl/parket |
| Basah & sealant | Waterproofing kamar mandi/atap/kolam, sealant silikon, grouting |
| Dinding partisi | Gypsum/plafon, wallpaper, list profil, perbaikan retak rambut |
| Metal & lain | Cat besi/railing anti-karat, pengecatan marka parkir |

Catatan: karena berbasis lokasi, jadwal sipil memakai `scope = location`
(mis. "cat ulang koridor per 24 bulan") atau menjadi WO korektif dari
temuan PPM kamar (sealant jamuran, cat mengelupas).

### IT
| Kategori | Contoh |
|---|---|
| Server & jaringan | Server, NAS, switch, router, firewall, AP, rack UPS |
| Keamanan elektronik | CCTV + NVR, access control, alarm |
| Guest-facing | TV + STB, PABX/telepon, key card & door lock, Wi-Fi in-room, smart room |
| Operasional | PC/laptop, printer, POS, mesin absensi, signage |

### Kitchen / F&B — terkait HACCP
Cold room, freezer, chiller, ice maker · combi oven, range, fryer,
salamander · exhaust hood + duct *(risiko kebakaran)* · dishwasher/glass
washer · mesin kopi, blender, draft beer.

### Lainnya
Gym (treadmill, alat beban, sauna) · Transport (mobil, shuttle, buggy —
meter km + STNK/KIR) · Housekeeping (vacuum, scrubber, high-pressure washer)
· FO (trolley, kursi roda) · **In-room per unit (TV, minibar, safe box, hair
dryer per kamar) — didata sebagai aset mulai Fase 2** (keputusan §13.7),
dengan import massal per tipe × daftar kamar agar pendataan cepat.

---

## 4. Kompetensi & penugasan (baru)

### 4.1 Matriks kompetensi teknisi

- `skills (id, user_id, category_id, level, cert_document, valid_until)`
  - `level`: `basic` (boleh membantu) · `advanced` (boleh mandiri) ·
    `certified` (bersertifikat resmi — AK3 listrik/lift, teknisi
    refrigerasi, dsb; dokumen dilampirkan, `valid_until` memicu pengingat).
- Kategori aset punya flag `restricted`: pekerjaan pada kategori itu hanya
  boleh dieksekusi `certified` (genset, lift, panel TM, fire pump, boiler).
- Contoh: AC → Budi (advanced), Agus (advanced), Dedi (basic);
  Genset (restricted) → hanya Candra (certified AK3).

### 4.2 Eksekutor: internal vs vendor

Per jadwal PM atau per kategori, ditetapkan `executor`:
- `internal` — dikerjakan teknisi sendiri (butuh skill sesuai 4.1).
- `vendor` — dikerjakan vendor kontrak (WO tipe vendor; wajib field
  *pendamping internal* + berita acara difoto + rating).
- `either` — default internal, bisa dialihkan ke vendor per kejadian
  (mis. kerusakan masih garansi).

### 4.3 Mesin penugasan

Saat WO dibuat (manual, dari laporan, atau dari generator PM):
1. Kandidat = teknisi departemen terkait **yang punya skill kategori aset**
   (level ≥ advanced; kategori restricted → certified saja).
2. Sistem mengusulkan PIC dengan **beban paling ringan** pada hari itu
   (jumlah menit estimasi tugas yang sudah dipegang).
3. Dept head bisa menerima usulan atau mengganti; teknisi tanpa skill tidak
   muncul di pilihan dan tidak bisa "ambil tugas" (dicek di server, bukan
   hanya disembunyikan).
4. Fallback: jika tidak ada teknisi berkualifikasi (cuti/resign), sistem
   menyarankan vendor kontrak kategori tersebut dan memberi tahu dept head.

---

## 5. Model data (MySQL — kontrak logis)

Semua tabel: `property_id` + index gabungan `(property_id, …)`.
Tabel v1 (users, rooms→locations, categories, defects→work_orders, photos,
history) dimigrasikan, bukan dibuang.

### Master
```
properties        id, code, name, timezone, address, active
users             id, username, password_hash, full_name, phone, active
user_property_access  user_id, property_id, role, department
push_tokens       user_id, platform(android|ios|web), token, updated_at
skills            user_id, category_id, level, cert_document, valid_until
locations         id, property_id, code, name, building, wing, floor,
                  type(room|public_area|back_of_house|external), active
asset_categories  id, property_id (null=korporat), parent_id, name,
                  department, restricted, default_checklist_id
assets            id, property_id, asset_code, accounting_asset_no, name,
                  category_id, location_id, brand, model, serial_number,
                  photo, purchase_date, purchase_price, vendor_id,
                  warranty_until, install_date, expected_life_years,
                  criticality, status, meter_type, meter_current,
                  parent_asset_id, notes
                  -- accounting_asset_no = nomor fixed-asset register
                  --   akuntansi (acuan), unik; asset_code utk QR dipetakan
                  --   ke nomor ini (keputusan §13.6)
asset_documents   id, asset_id, type(manual|warranty|certificate|permit|
                  calibration|other), title, file, expiry_date, reminder_days
vendors           id, property_id (null=korporat), name, contact, phone,
                  email, specialty, rating_avg
contracts         id, property_id, vendor_id, title, start_date, end_date,
                  cost_per_year, sla_response_hours, visit_frequency,
                  reminder_days, file      (+ contract_assets: many-to-many)
parts             id, property_id, code, name, unit, stock_qty, min_stock,
                  unit_price, bin_location, department
```

### Checklist (dengan versioning)
```
checklists        id, property_id (null=template korporat), name, department,
                  version, status(draft|active|archived), parent_version_id,
                  created_by, approved_by, approved_at
checklist_items   id, checklist_id, seq, text, type(pass_fail|numeric|text|
                  photo), unit, min_value, max_value,
                  photo_required_on_fail, guidance
```
Aturan versioning: checklist `active` tidak bisa diedit langsung — edit
membuat versi `draft` baru; saat di-approve dept head, versi lama jadi
`archived`. WO yang sudah selesai selamanya menunjuk versi yang dipakainya
(hasil audit tidak berubah retroaktif).

### Jadwal & meter
```
pm_schedules      id, property_id, name, scope(asset|location|category),
                  asset_id / location_id / category_id, department,
                  checklist_id, frequency_type(daily|weekly|monthly|quarterly|
                  semiannual|yearly|custom_days|meter), frequency_value,
                  weekly_days, monthly_day, lead_time_days, grace_days,
                  schedule_base(fixed|floating), executor(internal|vendor|
                  either), vendor_id, auto_assign(bool), spread(bool),
                  estimated_minutes, priority, active, next_due_date,
                  next_due_meter
meter_readings    id, asset_id, value, read_at, read_by, source(manual|wo)
generator_log     id, property_id, run_at, schedules_processed, wo_created,
                  status, message
```

### Pekerjaan
```
work_orders       id, property_id, wo_number, type(corrective|preventive|
                  inspection|vendor|project), source(report|schedule|
                  checklist_fail|manual), asset_id, location_id, category_id,
                  schedule_id, checklist_version_id, reporter_id, assignee_id,
                  vendor_id, supervisor_id, description, priority,
                  status(scheduled|reported|in_progress|waiting_parts|done|
                  verified|rejected|skipped), skip_reason, repair_note,
                  created_at, due_date, started_at, done_at, verified_at,
                  downtime_start, downtime_end, meter_at_service,
                  labor_minutes, cost_parts, cost_vendor, cost_other
wo_checklist_results  wo_id, item_id, result(ok|fail|na), value_numeric,
                      note, photo
wo_parts          wo_id, part_id, qty, unit_price_snapshot
photos            id, wo_id, type(before|after|evidence), filename,
                  uploaded_by, created_at
history           id, wo_id, user_id, action, created_at   (immutable)
```

### Biaya (baru)
```
wo_costs          id, wo_id, kind(part|labor|vendor|material|other),
                  description, qty, unit_price, amount, incurred_at,
                  entered_by, invoice_file, approved_by, approved_at
```
Catatan: `work_orders.cost_parts/cost_vendor/cost_other/labor_minutes`
tetap ada sebagai ringkasan (di-roll-up dari `wo_costs`) agar query laporan
cepat. `wo_costs` adalah rincian per baris (bisa banyak), bisa ditambah
**setelah** WO selesai (mis. invoice vendor menyusul) dengan tetap tercatat
siapa & kapan. `part` otomatis terisi dari `wo_parts`.

### Utilitas & energi (baru)
```
utility_meters    id, property_id, code, name, utility_type(electricity|
                  water|gas|fuel), unit(kWh|m3|liter), location_id,
                  area_served, is_submeter, parent_meter_id, tariff_per_unit,
                  fixed_charge, provider, account_no, active
utility_readings  id, meter_id, period_month, reading_value, prev_reading,
                  consumption, tariff_snapshot, cost, read_at, read_by,
                  photo, note
```
`consumption = reading_value − prev_reading`; `cost = consumption ×
tariff_snapshot + fixed_charge`. Submeter (per lantai/departemen/tenant)
ditandai `is_submeter` dengan `parent_meter_id` untuk rekonsiliasi.

### Notifikasi & broadcast
```
notifications     id, property_id, user_id, type, severity(info|warning|
                  critical), title, body, link, read_at, created_at
broadcasts        id, property_id, sender_id, severity, title, body,
                  target_departments (json / "all"), requires_ack,
                  expires_at, created_at
broadcast_receipts broadcast_id, user_id, delivered_at, read_at, ack_at
```

---

## 6. Spesifikasi fitur

### F1 — Pelaporan defect (v1, disempurnakan)

1. Foto **wajib dari kamera** (mobile app memakai kamera internal — galeri
   tidak tersedia sama sekali; ini menyelesaikan tuntas keterbatasan web).
2. Lokasi via pilih atau **scan QR** kamar/aset; kategori; deskripsi;
   prioritas dengan SLA.
3. **Pengisian aset diutamakan supaya teknisi tidak salah unit.** Urutan
   mekanisme, dari paling akurat:
   a. **Scan QR aset** → aset (dan lokasinya) langsung terisi, tidak bisa
      keliru. Ini jalur yang didorong: tempel QR di setiap unit.
   b. Bila lapor via lokasi + kategori: sistem menampilkan **daftar aset di
      lokasi itu yang sesuai kategori**. Jika hanya ada satu (mis. satu AC di
      kamar), **auto-terpilih**; jika beberapa, teknisi memilih dari daftar
      pendek bergambar + kode (mis. AC-1207-A / AC-1207-B).
   c. Bila aset belum terdaftar / tidak ketemu: boleh lanjut tanpa aset,
      tetapi WO ditandai *"aset belum ter-link"* dan muncul di daftar kerja
      dept head untuk dilengkapi — jadi tidak hilang.
   Reporter (HK) minimal cukup scan QR atau pilih dari daftar; verifikasi
   akhir aset tetap bisa dikoreksi teknisi sebelum mulai kerja.
4. Routing otomatis ke departemen pemilik kategori (Wi-Fi → IT; AC →
   engineering). Dept head bisa melempar antar departemen, tercatat.
5. Deteksi duplikat: peringatan bila ada WO terbuka di lokasi+kategori sama.
6. **Offline-first**: laporan + foto masuk antrean lokal, terkirim otomatis.

### F2 — Work order lifecycle (terpadu)

Semua jenis pekerjaan (korektif, preventif, inspeksi, vendor, proyek) satu
tabel, satu daftar, satu kalender:

```
scheduled ──▶ (jendela buka) ──▶ in_progress ──▶ done ──▶ verified
                  │                   │  ▲
reported ─────────┘        waiting_parts ┘        (chief: rejected/duplikat,
                                                   reopen, skipped+alasan)
```

- Foto *after* + catatan wajib sebelum done (v1); checklist lengkap wajib
  sebelum done untuk WO preventif.
- Downtime start/stop wajib untuk aset `critical`.
- Biaya per WO: part (otomatis dari pemakaian), vendor, lainnya, menit kerja.

### F3 — Registri aset & kartu aset

Sama seperti spesifikasi v2 §F1: pendataan bertahap (wajib hanya nama +
kategori + lokasi), import Excel per departemen, kode otomatis per kategori,
label QR cetak massal, riwayat pindah lokasi, disposal dengan approval —
tidak pernah dihapus fisik.

### F4 — Kesehatan aset: kapan diperbaiki / diganti

Indikator hijau/kuning/merah berbasis aturan transparan (frekuensi korektif
90 hari, biaya kumulatif vs harga beli 35%/50%, umur vs umur ekonomis,
backlog PM, tren nilai checklist, garansi/sertifikat). Merah pada aset
critical → kartu keputusan di dashboard: *perbaiki / ganti / pensiunkan*
dengan data pendukung siap cetak untuk pengajuan capex. Ambang bisa diubah
per properti.

### F5 — Checklist builder & review (baru — permintaan eksplisit)

Halaman web untuk dept head (dan admin):

1. **Buat checklist** dari nol, dari duplikat checklist lain, atau dari
   template korporat.
2. **Tambah / hapus / ubah / geser urutan item** (drag & drop); tiap item:
   teks, tipe (OK-Fail / angka+ambang / teks / foto), satuan, ambang
   min-maks, wajib-foto-bila-fail, teks panduan singkat (muncul saat
   teknisi menekan ikon "?").
3. **Alur review**: `draft → active` dengan approval dept head; edit pada
   checklist aktif otomatis membuat draft versi baru; versi lama diarsip.
   Semua perubahan tercatat (siapa, kapan, apa).
4. **Uji coba**: tombol "preview di ponsel" merender checklist persis
   seperti yang dilihat teknisi sebelum diaktifkan.
5. Checklist ter-link ke jadwal; mengganti versi berlaku untuk WO yang
   terbit sesudahnya saja.
6. Laporan pemakaian: item yang paling sering fail per checklist — bahan
   dept head merevisi program perawatan.

### F6 — Jadwal berulang + auto-generate per kategori (diperluas)

Frekuensi: harian, mingguan (pilih hari), bulanan (tanggal), 3-bulanan,
6-bulanan, tahunan, interval hari kustom, berbasis meter (jam/km).

**Auto-generate untuk item sejenis** — alur "semua AC diservis sebulan
sekali":

1. Dept head membuat jadwal dengan `scope = category` (AC split/FCU),
   cakupan lokasi opsional (seluruh properti / gedung / lantai).
2. Sistem mengenumerasi semua aset aktif kategori itu (mis. 124 unit) dan
   menyusun **usulan rencana**:
   - **Sebaran tanggal**: unit dibagi merata ke hari kerja dalam siklus
     (124 unit ÷ 21 hari kerja ≈ 6 unit/hari), dikelompokkan per
     lantai/zona agar teknisi tidak bolak-balik; menghindari blackout
     period dan hari yang sudah padat.
   - **Usulan PIC**: dari matriks kompetensi (§4) + beban harian teknisi;
     estimasi jam kerja per hari ditampilkan.
3. Dept head me-review tabel usulan (tanggal, aset, lokasi, PIC), bisa
   menggeser baris/kelompok atau mengganti PIC, lalu **Aktifkan** → WO
   `scheduled` diterbitkan sekaligus.
4. **Dinamis**: aset baru pada kategori itu otomatis masuk siklus
   berikutnya; aset `disposed`/`out_of_service` keluar otomatis; perubahan
   jumlah unit memicu saran penyebaran ulang.
5. Kejadian berulang berikutnya mengikuti pola yang sudah disetujui
   (tanggal relatif + PIC), dengan re-balancing hanya bila ada perubahan
   (teknisi resign, aset bertambah) — jadwal tidak "melompat-lompat" tiap
   bulan tanpa alasan.

Fitur pendukung: jendela toleransi (grace), skip dengan alasan, lead time
penerbitan WO (default H-3), generator idempoten + `generator_log` yang bisa
diperiksa admin, mode rute untuk PM banyak-unit-sehari (APAR, kamera CCTV).

### F7 — Kalender maintenance

Bulan/minggu/hari; filter properti (bila multi), departemen, teknisi,
lokasi, jenis; drag-reschedule dengan alasan; beban per teknisi terlihat
(total menit/hari); blackout period; cetak jadwal mingguan untuk briefing.
Mobile: tampilan "Hari ini" per teknisi diurutkan per lantai/zona.

### F8 — Halaman aset & halaman lokasi

Halaman aset: identitas + foto + dokumen, indikator kesehatan, KPI mini,
riwayat gabungan semua WO, grafik meter & nilai checklist numerik dari
waktu ke waktu, jadwal PM aktif, komponen anak, sparepart terpakai, tombol
lapor/pindah/QR. Halaman lokasi: aset di lokasi, riwayat WO lokasi, status
OOO/OOS, jadwal PPM berikutnya.

### F9 — Vendor, kontrak, kepatuhan, garansi

WO vendor dengan pendamping internal + berita acara + rating; pengingat
kontrak habis; pengingat expiry dokumen (SLO genset, izin lift Disnaker,
sertifikat damkar, KIR/STNK, kalibrasi, **sertifikat kompetensi teknisi**);
banner garansi saat membuat WO korektif pada aset yang masih tergaransi.

### F10 — Sparepart (sederhana)

Kartu stok, pemakaian dari dalam WO, `min_stock` alert, WO `waiting_parts`
ter-link part, laporan pemakaian. Bukan sistem purchasing.

### F11 — Lonceng notifikasi & warning antar divisi (baru — diperluas)

Dua mekanisme di satu pusat notifikasi (ikon lonceng, mobile & web):

**A. Notifikasi otomatis dari sistem** — matriks lengkap:

| # | Kejadian | Penerima | Severity |
|---|---|---|---|
| 1 | Defect baru urgent | Teknisi dept + dept head | warning |
| 2 | WO ditugaskan ke saya | Teknisi ybs | info |
| 3 | WO PM terbit / masuk jendela | PIC | info |
| 4 | PM due hari ini belum mulai | PIC (pagi), dept head (sore) | warning |
| 5 | PM lewat grace (missed) | Dept head | warning |
| 6 | WO lewat SLA | Dept head; > 2× SLA → GM | warning→critical |
| 7 | Item checklist fail di aset critical | Dept head | critical |
| 8 | Nilai HACCP di luar ambang (suhu cold room) | Exec. chef + engineering | critical |
| 9 | Aset critical → out of service | Dept head + divisi terdampak (lift → FO+HK; cold room → kitchen) | critical |
| 10 | Aset kembali beroperasi | Penerima #9 | info |
| 11 | Kesehatan aset berubah merah | Dept head | warning |
| 12 | Kamar jadi OOO / kembali vacant-ready | FO + HK + dept head | warning / info |
| 13 | Laporan saya selesai diperbaiki | Reporter | info |
| 14 | Hasil perbaikan menunggu verifikasi | Dept head | info |
| 15 | Sertifikat/izin/kontrak/garansi H-60/30/7 | Dept head + property admin | warning |
| 16 | Sertifikat kompetensi teknisi akan habis | Teknisi + dept head | warning |
| 17 | Stok part < minimum | Dept head (digest harian) | info |
| 18 | Part ditunggu sudah tersedia | PIC WO waiting_parts | info |
| 19 | WO dilempar ke departemen saya | Dept head penerima | warning |
| 20 | Defect berulang ≥ 3× (lokasi+kategori) | Dept head | warning |
| 21 | Vendor visit besok (kontrak) | Dept head + pendamping | info |
| 22 | Log book shift baru diposting | Dept head + shift berikutnya | info |
| 23 | Generator PM gagal jalan | Property admin | critical |
| 24 | Ringkasan pagi (tugas hari ini, backlog) | Semua teknisi & dept head, 07.00 | digest |

**B. Warning manual antar divisi / sesama divisi** (broadcast):

- Composer: severity (info/warning/critical), target (satu/beberapa divisi,
  semua divisi, atau properti lain bila punya akses), pesan, opsi
  **wajib konfirmasi dibaca**, masa berlaku (auto-expire).
- Siapa boleh mengirim: dept head & admin ke divisi mana pun; teknisi ke
  divisinya sendiri + dept head divisi lain (bukan broadcast massal).
- **Critical**: push dengan suara/heads-up, tampil persisten di atas layar
  aplikasi sampai dikonfirmasi; pengirim melihat daftar siapa sudah/belum
  konfirmasi; belum konfirmasi dalam 15 menit → eskalasi ke dept head
  penerima.
- Skenario yang dilayani: lift OOS (eng → FO/HK) · air/listrik dimatikan
  terjadwal (eng → semua) · genset running/PLN padam (eng → semua) · bau
  gas (kitchen → eng + security) · sistem key card gangguan (IT → FO) ·
  Wi-Fi down (IT → semua) · kolam ditutup (eng → FO/rekreasi) · fogging/
  pest control (HK → semua) · kamar VIP prioritas (FO → eng) · CCTV area X
  mati (IT → security) · fire alarm terverifikasi palsu (eng → semua,
  meredakan) · cold room rusak, pindahkan stok (eng → kitchen).
- Quiet hours per user (default 22.00–06.00) — hanya `critical` yang tembus.
- Semua broadcast tercatat & bisa diaudit (siapa kirim apa kapan ke siapa,
  siapa membaca kapan).

### F12 — Laporan & KPI

Per departemen, per properti, dan **konsolidasi korporat** (bandingkan
antar hotel): PM compliance %, rasio korektif:preventif, MTTR, backlog &
umurnya, biaya per departemen / per kamar tersedia, top-10 aset bermasalah,
downtime aset kritis, kepatuhan HACCP & fire-safety, sertifikat akan habis
90 hari, kinerja vendor (kunjungan terpenuhi, rating). Ekspor Excel/PDF;
laporan bulanan satu klik.

### F13 — Log book shift engineering

Serah terima shift digital: kejadian, parameter utility, WO menggantung;
notifikasi ke shift berikutnya; dapat dicari.

### F14 — Pencatatan biaya perbaikan (di mana &amp; kapan input-nya)

Pertanyaan yang harus terjawab jelas: **di mana kotak input biaya dan kapan
diisi.** Biaya melekat pada work order dan bisa masuk di beberapa titik:

**Di mana (lokasi input box):**
1. **Mobile — saat "tag as done"** (paling utama untuk WO internal): di bawah
   catatan perbaikan & foto after ada bagian **"Biaya"** yang bisa dilipat,
   berisi:
   - *Sparepart*: teknisi menekan "+ Part" → pilih part + qty → biaya
     terhitung otomatis dari harga part (mengurangi stok). Baris ini menjadi
     `wo_costs.kind=part`.
   - *Material non-stok* (mis. beli cat di toko): deskripsi + nominal +
     lampiran foto nota → `kind=material`.
   - *Jasa/tenaga* (`kind=labor`): menit kerja terisi otomatis dari
     `started_at`→`done_at`, bisa dikoreksi; nilai rupiah opsional (bila
     hotel menghitung biaya tenaga).
   - *Lainnya*: transport, sewa alat.
2. **Web — panel "Biaya" di halaman detail WO** (untuk dept head): menambah
   atau mengoreksi rincian, dan yang terpenting **memasukkan biaya vendor**
   (`kind=vendor`) beserta **unggah file invoice**, karena invoice sering
   datang beberapa hari setelah pekerjaan selesai.
3. **WO tipe vendor**: biaya vendor bisa dari nilai kontrak (nol untuk visit
   included) atau invoice terpisah.

**Kapan diisi:**
- Sparepart & material: **saat pengerjaan / tag as done**.
- Jasa/tenaga: otomatis **saat selesai** (dari durasi), boleh dikoreksi.
- Vendor / invoice: boleh **setelah** WO `done`/`verified` — panel biaya
  tetap terbuka untuk penambahan; tiap baris mencatat `entered_by` &
  `incurred_at`, dan perubahan masuk audit trail (biaya tidak "diam-diam"
  berubah).
- **Approval**: total biaya WO di atas ambang properti (mis. > Rp 5 juta)
  butuh `approved_by` dept head/GM sebelum ditutup (opsional, §13).

Total biaya WO = penjumlahan `wo_costs`, tampil di kartu WO, mengalir ke
**biaya per aset** (indikator kesehatan / keputusan ganti-vs-perbaiki),
**biaya per lokasi**, **biaya per departemen/bulan**, dan laporan. Tanpa
pencatatan ini, angka "62% dari harga beli" pada kartu aset tidak akan ada
— jadi input biaya adalah sumber data kunci, bukan pelengkap.

### F15 — Meteran utilitas: listrik (KWH) &amp; air bulanan

Memantau konsumsi & biaya utilitas per meteran — komponen biaya terbesar
hotel setelah gaji.

1. **Registri meteran** (`utility_meters`): meteran induk PLN, submeter per
   lantai/area/tenant (restoran sewa, laundry), meteran air PDAM & sumur,
   gas, tangki solar. Tiap meteran punya tarif per unit + biaya tetap.
2. **Input pembacaan bulanan** (`utility_readings`):
   - Mobile: menu **"Catat meter"** — sama seperti meter aset, teknisi
     memasukkan angka stand meter + foto meteran (bukti). Bisa banyak
     meteran sekaligus.
   - Web: entri/koreksi oleh admin engineering, atau impor dari tagihan PLN.
   - Sistem menghitung **konsumsi = stand sekarang − stand lalu** dan
     **biaya = konsumsi × tarif + biaya tetap**; anomali (lonjakan di luar
     ±X% dari rata-rata 3 bulan) memicu notifikasi ke chief.
3. **Dashboard energi**: grafik KWH & biaya listrik per bulan, per submeter
   (mana area paling boros), air m³ per bulan, **kWh per available room-night
   (indeks efisiensi)**, perbandingan antar bulan/antar properti.
4. Kaitan ke maintenance: lonjakan KWH suatu area → sinyal aset boros
   (chiller/AHU tak efisien) → dept head bisa buka WO inspeksi. Data ini
   memperkuat keputusan penggantian aset lama boros energi.

### F16 — Rekap harian untuk morning briefing

Agar GM & chief engineer tidak kehilangan hal penting saat briefing pagi,
sistem menyusun **"Rekap harian"** otomatis (tersedia di web, bisa dicetak/
PDF, dan dikirim sebagai push digest pukul 07.00).

Isi rekap (data 24 jam terakhir + status pagi ini):
- **Ringkasan WO**: dibuat vs ditutup kemarin; urgent yang ditangani; urgent
  yang masih terbuka; PM jatuh tempo vs selesai; PM terlewat.
- **Kejadian semalam** (dari log book): PLN padam & durasi genset run, insiden,
  banjir/bocor, alarm.
- **SLA breach** hari ini & yang berisiko.
- **Kamar OOO/OOS** saat ini + alasan + sejak kapan (yang menahan penjualan
  kamar — perhatian utama FO/GM).
- **Aset kritis down** / baru pulih; aset yang berubah merah (rekomendasi
  ganti).
- **Kepatuhan**: sertifikat/izin/kontrak jatuh tempo &lt; 30 hari.
- **Utilitas**: konsumsi listrik/air kemarin & anomali (bila ada).
- **Rencana hari ini**: kunjungan vendor terjadwal; beban PM per teknisi;
  pekerjaan yang butuh koordinasi lintas divisi (mis. PPM kamar → FO blok
  kamar).
- **Guest-impacting** terbuka: hal yang bisa memicu komplain tamu.

Rekap difilter per properti (dan versi konsolidasi untuk corporate). Satu
tombol **"Cetak untuk briefing"** menghasilkan lembar rapi berisi poin di
atas; GM cukup membuka satu halaman, bukan menyisir banyak menu.

---

## 7. Use case utama (ringkas — 24)

Pelaporan & WO (v1): **UC-01** HK lapor defect + foto kamera (offline OK) ·
**UC-02** teknisi ambil/ditugaskan, kerjakan, tag done + foto after ·
**UC-03** dept head verifikasi / tolak duplikat / reopen · **UC-04** WO
dilempar antar departemen.

Aset: **UC-05** registrasi aset & QR · **UC-06** import Excel massal ·
**UC-07** scan QR → kartu aset / lapor · **UC-08** pindah lokasi ·
**UC-09** disposal dengan approval · **UC-10** kartu keputusan
ganti-vs-perbaiki.

Checklist & PM: **UC-11** dept head membuat/merevisi checklist (builder,
draft→active, versioning) · **UC-12** jadwal kategori "semua AC bulanan" →
usulan sebaran tanggal + PIC → review → aktifkan (124 WO) · **UC-13**
eksekusi checklist mobile; item fail → WO korektif otomatis · **UC-14** PM
meter-based (genset 250 jam, mobil 5.000 km) · **UC-15** skip PM kamar
occupied → auto-reschedule · **UC-16** PPM kamar quarterly terkoordinasi FO.

Kompetensi & vendor: **UC-17** penugasan dibatasi skill (genset hanya
certified); teknisi tanpa skill tidak bisa ambil (ditolak server) ·
**UC-18** kunjungan vendor kontrak + berita acara + rating · **UC-19**
klaim garansi.

Notifikasi: **UC-20** engineering broadcast "lift 2 OOS" ke FO+HK dengan
wajib-konfirmasi; eskalasi bila 15 menit tak dikonfirmasi · **UC-21** suhu
freezer di luar ambang → critical ke chef + engineering real-time.

Multi-property: **UC-22** super_admin membuka dashboard konsolidasi,
membandingkan PM compliance 3 hotel · **UC-23** cluster engineer berpindah
properti dari aplikasi yang sama · **UC-24** template checklist korporat
didorong ke semua properti.

(Detail langkah per use case v1 & v2 pada dokumen terdahulu tetap berlaku;
dokumen ini menggantikan strukturnya.)

---

## 8. Aplikasi mobile (Android + iOS)

**Pengguna**: technician, reporter (HK/FO), dept head (fungsi ringkas).

**Layar**: login (**pilih properti hanya bila user multi-akses** — selain itu
langsung ke Hari ini) · Hari ini (tugas per zona) · eksekusi checklist (kartu
per item, OK/Fail besar, input angka + ambang, foto inline, draft auto-save) ·
lapor defect (kamera → lokasi/QR → **aset auto-terisi via QR / daftar pendek**
→ kategori → kirim) · detail WO + tag as done (**termasuk bagian input biaya:
part, material + foto nota, tenaga**) · scan QR · kartu aset (ringkas) · catat
meter (**aset + meteran utilitas listrik/air, dengan foto meteran**) · lonceng
notifikasi + composer warning · kalender pribadi · profil (skill & sertifikat
saya).

**Teknis**:
- **Offline-first**: DB lokal (SQLite); antrean mutasi (laporan, hasil
  checklist, foto, meter) dikirim saat online; sinkronisasi delta
  (`updated_since`) untuk data master; indikator "belum tersinkron" yang
  jujur.
- **Kamera**: pakai kamera internal aplikasi — bukan picker — sehingga foto
  dipastikan diambil saat itu; kompresi di perangkat (~1600px) sebelum
  upload; EXIF GPS di-strip di server.
- **Push**: FCM + APNs; topic `property_{id}_dept_{name}` untuk broadcast,
  token personal untuk penugasan; notifikasi critical memakai channel
  prioritas tinggi (heads-up + suara).
- **Keamanan**: token akses pendek + refresh token di secure storage
  (Keystore/Keychain); auto-logout idle; PIN cepat ganti user untuk HP
  operasional bersama; certificate pinning.

## 9. Aplikasi web PHP (dashboard/admin/monitoring)

**Pengguna**: dept head, property_admin, viewer/GM, super_admin.

**Layar**: **rekap harian / morning briefing (cetak PDF)** · dashboard
departemen & properti · dashboard konsolidasi korporat · **dashboard energi
(KWH & biaya utilitas)** · kalender penuh + review usulan rencana PM · daftar
& kartu aset (CRUD, import, cetak QR) · **detail WO + panel biaya (input
vendor + unggah invoice)** · checklist builder + preview ponsel · jadwal PM ·
kompetensi teknisi (matriks skill + sertifikat) · vendor & kontrak · dokumen
& kepatuhan (daftar expiry) · sparepart · **meteran utilitas (registri +
pembacaan bulanan)** · laporan + ekspor · broadcast center · log book · admin
(user, role, master, konfigurasi, properti) · monitoring teknis
(generator_log, antrean push, kesehatan sistem).

**API (dipakai mobile)** — kelompok endpoint:
`auth` (login, refresh, logout, pilih properti) · `sync` (master delta:
locations, assets ringkas, categories, checklists aktif) · `wo` (list
milikku, detail, ambil, mulai, waiting, done+foto, skip) · `checklist`
(submit hasil per item, draft) · `report` (buat defect + foto) · `meter` ·
`notifications` (list, read, ack) · `broadcasts` (kirim, receipts) ·
`costs` (tambah rincian biaya + foto nota ke WO) · `utility` (daftar meteran,
kirim pembacaan + foto) · `qr/{code}` (resolve aset/lokasi). Semua respons
dibatasi `property_id` token; versi API di path (`/api/v1/...`).

---

## 10. Lampiran — pustaka checklist siap pakai

Hasil audit ulang terhadap taksonomi §3: **32 checklist** siap pakai
(tambahan di luar versi awal ditandai ★, termasuk 4 checklist sipil &
finishing). Semua menjadi master data awal dan dapat direvisi lewat checklist
builder (§F5).

### Engineering
1. **Genset — mingguan**: level solar/oli/coolant/air aki; tegangan aki
   *(≥ 12,4 V)*; panel tanpa alarm; tidak ada rembesan; test run 10–15 mnt;
   catat jam mesin; ruang bersih + APAR.
2. **Genset — servis 250 jam/6 bulan**: ganti oli+filter, filter solar &
   udara, belt, baut mounting, tes berbeban ≥ 30 mnt + parameter.
3. ★ **Genset/ATS — simulasi padam PLN (3-bulanan)**: black start, waktu
   start *(≤ 10 dtk)*, ATS pindah otomatis, beban tiap fasa, kembali normal.
4. ★ **Chiller — log harian**: suhu air masuk/keluar *(angka)*, tekanan
   suction/discharge, ampere kompresor, level oli, alarm, jam operasi.
5. ★ **Cooling tower — mingguan**: kondisi fill & basin, level & kualitas
   air (dosis kimia), fan & belt, strainer, tidak ada lumut/kerak.
6. ★ **AHU — bulanan**: filter (bersihkan/ganti), belt & pulley, bearing
   motor, koil bersih, drain pan, vibrasi, suhu supply *(angka)*.
7. **AC split/FCU — bulanan**: cuci filter; suhu supply *(16–20°C)*; arus
   kompresor; drainase; bunyi; thermostat; isolasi pipa; bracket outdoor.
8. ★ **Lift & eskalator — internal harian/mingguan**: ride test tiap unit
   (leveling, pintu, bunyi); intercom & alarm darurat berfungsi; lampu
   kabin; ARD test (mingguan); ruang mesin: suhu, bersih, log vendor.
   (Servis bulanan = WO vendor kontrak, engineering mendampingi.)
9. ★ **Panel listrik & trafo — bulanan**: indikator & metering normal,
   beban per fasa *(angka, ketimpangan ≤ 20%)*, suhu ruang panel, tidak ada
   bunyi/bau abnormal, kebersihan & akses; **tahunan**: thermography +
   pengencangan terminasi (vendor).
10. ★ **UPS gedung — 3-bulanan**: self-test, estimasi runtime *(angka,
    menit)*, suhu ruang, umur baterai vs jadwal ganti, alarm log.
11. ★ **Pompa air (transfer/booster/sump) — mingguan**: auto start-stop di
    tekanan setting *(angka, bar)*, ampere, seal tidak bocor, vibrasi/bunyi,
    pressure tank, sump pit bersih & float switch.
12. ★ **Water heater / boiler — bulanan**: suhu output *(angka, 55–60°C)*,
    safety valve test, tidak bocor, anoda/scale (per 6 bulan), tekanan.
13. ★ **STP/WTP — log harian**: pH *(6–9)*, sisa chlorine, debit, blower &
    pompa dosing jalan, tidak berbau menyengat; **bulanan**: uji lab baku
    mutu.
14. ★ **Tandon & air domestik — 6-bulanan**: kuras & bersihkan roof tank/
    GWT *(foto sebelum-sesudah)*, uji lab air bersih, tutup tank rapat.
15. **Fire & life safety — rute bulanan**: APAR per unit (tekanan, segel,
    akses); hydrant box lengkap; emergency lamp & exit sign tes tombol;
    pintu/tangga darurat bebas hambatan. **Mingguan**: jockey pump auto
    start-stop *(bar)*. ★ **6-bulanan**: tes MCFA per zona + PA/paging
    darurat terdengar di semua area (vendor + internal).
16. **Kolam renang & jacuzzi — harian**: pH *(7,2–7,6)*, free chlorine
    *(1–3 ppm)*, kejernihan, skimmer, tekanan filter *(backwash bila >
    ambang)*, alat rescue.
17. ★ **Laundry — bulanan**: lint trap dryer bersih *(risiko kebakaran —
    foto)*, belt & bearing, steam trap, level & kebocoran, emergency stop.
18. ★ **Bangunan — 6-bulanan**: atap & talang, waterproofing, sealant
    fasad, plafon bernoda air (indikasi bocor), railing balkon kokoh.
19. **PPM kamar — 3-bulanan (30 titik)**: pintu & card reader; kran/shower/
    air panas ≤ 30 dtk; flush; sealant; exhaust; semua saklar-stopkontak-
    lampu; TV+remote; telepon; Wi-Fi *(bar)*; safe box; minibar *(≤ 7°C)*;
    AC (suhu, bunyi, bocor); furnitur & laci; gorden; jendela+kunci; smoke
    detector tes; kondisi cat/karpet.

### IT
20. **CCTV & access control — bulanan**: semua kamera live *(per unit)*,
    playback acak, retensi *(≥ 30 hari)*, HDD health, ★ pintu access
    control tes fail-safe/fail-secure, baterai door lock kamar dari sistem
    *(daftar < 20%)*.
21. **Server room & backup — bulanan**: suhu *(18–24°C)*, UPS rack test +
    runtime, restore test 1 file, storage *(≤ 80%)*, patch, akses fisik,
    kebersihan & kabel rapi.
22. ★ **Jaringan & telefoni — bulanan**: daftar AP down, speed test 3 titik
    publik *(angka)*, uplink ISP failover test, PABX: tes saluran keluar &
    **nomor darurat**, waiting call FO.

### Kitchen
23. **HACCP suhu — harian 2×**: tiap cold room *(0–5°C)*, tiap freezer
    *(≤ −18°C)*, rinse dishwasher *(≥ 82°C)*.
24. **Exhaust & grease — mingguan/bulanan**: grease trap kuras *(foto)*;
    filter hood cuci; motor fan; nozzle suppression tidak terhalang +
    tekanan tabung; duct visual (pembersihan menyeluruh 3-bulanan vendor).
25. ★ **Sanitasi es & minuman — bulanan**: ice maker dibersihkan &
    disanitasi *(foto)*, bin es, mesin kopi descaling, post-mix/draft line
    cleaning.

### Lainnya
26. **Kendaraan — bulanan + per 5.000 km**: oli, rem, ban, lampu, wiper,
    aki, AC, P3K; catat odometer *(meter)*; STNK/KIR dari dokumen aset;
    servis berkala = WO vendor.
27. **Gym — mingguan**: treadmill (belt, lubrikasi, emergency stop per
    unit), kabel & pulley *(foto bila aus)*, baut/pin, sauna-steam sensor
    suhu *(angka)*, disinfeksi.
28. ★ **Peralatan housekeeping — bulanan**: vacuum (filter, sikat, kabel),
    scrubber (baterai, brush pad, squeegee), high-pressure washer, trolley
    (roda, rem), kursi roda.

### Sipil &amp; finishing (baru)
29. ★ **Inspeksi finishing kamar & koridor — 6-bulanan** *(scope lokasi)*:
    cat tembok (mengelupas/noda/retak rambut), plitur kusen-pintu (kusam/
    gores), sealant kamar mandi (jamur/lepas), nat keramik, plafon (noda
    air = indikasi bocor), wallpaper, list profil. Temuan → WO korektif sipil
    + foto.
30. ★ **Cat ulang terjadwal — siklus 18–36 bulan** *(scope lokasi)*: cat
    ulang koridor / kamar / fasad per zona; item: persiapan permukaan,
    dempul retak, jumlah lapis, hasil rata *(foto sebelum-sesudah)*.
31. ★ **Poles marmer & lantai batu — 3-bulanan** *(area publik)*: kondisi
    kilap lobby/koridor, crystallization/poles ulang, nat, tidak licin.
32. ★ **Waterproofing area basah — 6-bulanan**: atap, balkon, area kolam,
    kamar mandi lantai atas; uji genang bila perlu; sealant &amp; floor drain.

---

## 11. Non-fungsional

**Keamanan**: otorisasi role+departemen+properti dicek server di tiap
endpoint; token mobile pendek + refresh, secure storage, pinning; foto &
dokumen lewat gateway ber-otorisasi; audit trail immutable (history,
broadcast_receipts, perubahan master aset & checklist); backup MySQL harian
+ uji restore bulanan (masuk checklist IT!); password kebijakan minimal;
akun nonaktif otomatis saat resign (admin).

**Skalabilitas**: 1 properti ≈ 1.500–4.000 aset, 300–800 WO/bulan; 10
properti masih ringan untuk satu MySQL dengan indeks
`(property_id, status, due_date)` dll; foto/dokumen di storage terpisah;
generator idempoten dengan lock per properti; API pagination + delta sync;
arsip WO > 2 tahun ke tabel arsip.

**Keandalan**: mode offline mobile adalah buffer saat server down;
`generator_log` + alarm bila generator gagal; antrean push dengan retry.

---

## 12. Migrasi & roadmap

**Migrasi dari v1 (aplikasi PHP berjalan saat ini)**:
`rooms→locations`, `defects→work_orders (type=corrective)`, role lama
dipetakan (chief→dept_head Engineering, engineering→technician,
housekeeping→reporter, admin→property_admin), semua tabel diberi
`property_id` = properti pertama. Aplikasi web v1 tetap dipakai selama
transisi.

**Fase 1 — Fondasi (5–7 minggu)**: skema multi-property + corporate viewer +
migrasi; refactor backend PHP ke struktur 3 lapis class-based (per
[ARSITEKTUR-BACKEND-PHP.md](ARSITEKTUR-BACKEND-PHP.md)); API v1 (auth, WO,
laporan, foto, biaya); **aplikasi Android** rilis pertama (lapor defect +
tugas saya + tag done + input biaya + push); web: admin & dashboard diperluas
+ rekap harian morning briefing.
**Fase 2 — Aset & preventif (6–8 minggu)**: registri aset (+ nomor akuntansi)
+ QR + import (termasuk in-room per unit); checklist builder + versioning;
jadwal berulang + auto-generate kategori + usulan sebaran & PIC; kalender;
eksekusi checklist Android offline; kompetensi & mesin penugasan; meteran
utilitas + dashboard energi.
**Fase 3 — Pendalaman (5–7 minggu)**: vendor/kontrak/kepatuhan; sparepart;
kesehatan aset & kartu keputusan; broadcast antar divisi lengkap + acknowledge
& eskalasi; laporan korporat; log book; **rilis iOS penuh**; WhatsApp gateway
(opsional).

**Onboarding**: mulai 1 properti, departemen engineering, aset kritis
(< 100 unit) selama 1 bulan → IT → kitchen → PPM kamar → properti
berikutnya memakai template yang sudah matang.

---

## 13. Keputusan final (dikonfirmasi 5 Juli 2026)

1. **Mobile: native** — Android (Kotlin) + iOS (Swift), dua codebase.
   Konsekuensi: dua tim/skill, tapi akses kamera, offline, dan push paling
   optimal. Rilis Android dulu (Fase 1), iOS menyusul (Fase 3).
2. **Backend: plain PHP** (bukan Laravel), tetapi **terstruktur rapi 3 lapis,
   class-based dengan inheritance**, satu file per halaman, satu CSS global.
   Detail konvensi ada di [ARSITEKTUR-BACKEND-PHP.md](ARSITEKTUR-BACKEND-PHP.md).
3. **Multi-property + corporate viewer aktif sejak Fase 1.** Skema
   `property_id` dan dashboard konsolidasi dibangun di awal.
4. **Notifikasi: push (FCM/APNs) sebagai kanal utama.** WhatsApp gateway
   opsional, ditambahkan hanya bila memungkinkan (Fase 3+), tidak memblok.
5. **Approval biaya: WO dengan total biaya > Rp 5.000.000 wajib di-approve**
   (dept head/GM) sebelum ditutup. Nilai ambang dapat diubah per properti
   (default Rp 5jt).
6. **Penomoran aset mengikuti fixed-asset register akuntansi.** Kolom
   `assets.accounting_asset_no` menyimpan nomor aset akuntansi sebagai acuan;
   `asset_code` (untuk QR/operasional) dipetakan ke nomor tersebut. Saat
   registrasi/import, nomor akuntansi diisi dan divalidasi unik.
7. **Aset in-room per unit didata sekarang** (mulai Fase 2): TV, minibar,
   safe box, hair dryer per kamar dicatat sebagai aset — bukan sekadar item
   PPM. Import massal per tipe × daftar kamar disediakan agar pendataan cepat.
