# Sprint — Aplikasi Mobile LPK TIP (Flutter)

**Aplikasi:** LPK TIP v2 — Mobile Companion (Flutter + API Laravel)
**Tanggal:** 2026-08-14 · **Status:** BACKEND M0–M5 ✅ · **FLUTTER M0–M4 ✅** (build APK debug sukses)
**Acuan backend:** `lpk-laravel` (Laravel 13 + Livewire 4 + MySQL `trocon_lpk_v2`)

---

## 1. Ringkasan & Tujuan

Aplikasi mobile sebagai **pendamping lapangan** untuk karyawan PT. Trocon Indah Perkasa:
cek material via QR, absensi lokasi aman, lihat stok & dashboard — **tanpa membawa semua modul web**.

- **Platform:** Flutter (Android & iOS)
- **Backend:** REST API baru di Laravel (auth token + resource JSON)
- **Desain:** enterprise profesional, light-mode, warna korporat TIP (brand `#294be2`), font IBM Plex Sans
- **Prinsip:** ringan, offline-friendly (cache), anti-manipulasi (lokasi & foto)

---

## 2. Arsitektur

```
[Flutter App] ── HTTPS ──> [Laravel API /api/v1]
     │                          │
     │  Sanctum Token           ├─ Auth (login QR/NIK+password)
     ├─ Local cache (sqflite)   ├─ QR material
     ├─ Geolocator + Map        ├─ Absensi (geotag + foto)
     └─ Notifikasi push (ops.)  └─ Dashboard & stok
```

- **Auth:** Laravel Sanctum (token bearer) — login `username/NIK` + password (hash kompatibel legacy sudah ada).
- **Versioning:** `/api/v1/...` · format respons JSON: `{ "success": true, "data": {...}, "message": "..." }`
- **Error:** HTTP status + `message` Bahasa Indonesia; rate limit & throttle.
- **Keamanan:** CORS terbatas, `Accept: application/json`, log aktivitas (reuse `UserLog`).

---

## 3. Scope Fitur Mobile (MVP)

| # | Fitur | Ket |
|---|---|---|
| M1 | **Login** | username/NIK + password, token Sanctum, ganti password |
| M2 | **Scan QR Material** | kamera scan QR (kode `LPK-TIP|...`) → detail material + **stok aktual** (per gudang & total) |
| M3 | **Data Barang / Material / Stok** | daftar material (search, filter jenis/grup) + stok per gudang + history mutasi ringkas |
| M4 | **Absensi Geotagging** | pilih periode/shift → **ambil lokasi (maps) + foto selfie** → kirim; **anti fake location** |
| M5 | **Dashboard** | ringkas: greeting, KPI (material, stok menipis, absensi hari ini), notifikasi |

### Di luar scope MVP (tetap di web)
Periode payroll, generate gaji, BKK, transfer, PO/PR, solar, master data, admin — semua **tetap di web**; mobile hanya konsumsi/laporan.

---

## 4. Spesifikasi API (draft)

### Auth
| Method | Endpoint | Fungsi |
|---|---|---|
| POST | `/api/v1/auth/login` | body: `username`/`nik`, `password` → `{ token, user }` |
| POST | `/api/v1/auth/logout` | revoke token |
| GET | `/api/v1/me` | profil + shift + proyek |

### Material & Stok
| Method | Endpoint | Fungsi |
|---|---|---|
| GET | `/api/v1/materials?search=&type_id=&group_id=&page=` | list material (kode, nama, spec, unit, harga, stok) |
| GET | `/api/v1/materials/{code}` | detail (stok per gudang + total) |
| GET | `/api/v1/materials/{code}/movements?limit=` | riwayat mutasi stok terakhir |
| GET | `/api/v1/materials/qr-check?code=` | validasi hasil scan QR |

### Absensi (geotagging)
| Method | Endpoint | Fungsi |
|---|---|---|
| GET | `/api/v1/attendance/config` | periode aktif, shift, jadwal, **lokasi wajib** (radius kantor/proyek) |
| POST | `/api/v1/attendance/check-in` | multipart: `photo` (selfie), `latitude`, `longitude`, `accuracy`, `timestamp`, `device_info` |
| POST | `/api/v1/attendance/check-out` | idem |
| GET | `/api/v1/attendance/history?month=` | riwayat absensi + status |

### Dashboard
| Method | Endpoint | Fungsi |
|---|---|---|
| GET | `/api/v1/dashboard/summary` | KPI: material, stok menipis, absensi hari ini, notifikasi unread |
| GET | `/api/v1/notifications?unread_only=` | daftar notifikasi (reuse tabel `notifications`) |

> Detail lengkap request/response akan didokumentasikan di `docs/API-MOBILE.md` saat Sprint M1.

---

## 5. Anti Fake Location & Validitas Absensi

| Ancaman | Mitigasi |
|---|---|
| Lokasi palsu (emulator/GPS spoof) | Kirim **`accuracy`**, **provider**, **`mock_location`** dari platform; backend tolak bila akurasi > 100m / `isMocked` |
| Foto bukan asli | **Selfie wajib** (kamera depan), simpan exif **waktu & lokasi** di metadata; backend simpan path + hash |
| Absen jauh dari lokasi | Backend validasi jarak ke **pusat lokasi terdaftar** (kantor/proyek/shift) dgn radius konfigurasi |
| Waktu dipalsukan | Gunakan **timestamp server** (bukan device) utk pencatatan; bandingkan dgn toleransi |
| Absen ganda | Lock per user per hari per tipe (check-in/out), cek di backend (transaction) |
| Device tidak dikenal | Catat `device_info` (ID perangkat) & tampilkan di riwayat |

**Alur:** pilih lokasi (maps pilih / auto GPS) → validasi radius → foto selfie (wajah) → kirim → server verifikasi → simpan + notif.

---

## 6. Desain Enterprise & Profesional

- **Design system**: warna TIP (`brand` scale), IBM Plex Sans, komponen reusable (button, card, tabel, badge, empty state, loading skeleton).
- **Layout**: Material 3 disesuaikan korporat (bukan playful) — nav bottom: **Beranda, Material, Absen, Profil**.
- **Light-mode only** (konsisten web).
- **Loading**: skeleton + spinner; **offline**: cache list material (sqflite) utk akses cepat; scan tetap online utk stok real-time.
- **Kualitas**: hapus emoji, ikon SVG (flutter_icon/heroicons), Bahasa Indonesia, aksesibilitas (contrast, tap area ≥ 44px).

---

## 7. Rekomendasi Fitur Tambahan (Fase Lanjutan)

| Prioritas | Fitur | Nilai |
|---|---|---|
| ⭐⭐⭐ | **Notifikasi push** (FCM) — SPB/transfer/broadcast | real-time |
| ⭐⭐⭐ | **Pengajuan SPB / Permintaan Material dari lapangan** | alur kerja cepat |
| ⭐⭐⭐ | **Persetujuan / approval** (SPB, transfer) di mobile | mobilitas |
| ⭐⭐ | **Rekap absensi & LPK bulanan** (PDF) | laporan |
| ⭐⭐ | **Peta lokasi proyek & gudang** (koordinat) + jarak terdekat | logistik |
| ⭐⭐ | **Transfer barang ringkas** (pindah stok dgn scan) | efisiensi gudang |
| ⭐⭐ | **Foto/evidence upload** (pemakaian, retur) | audit trail |
| ⭐ | **Riwayat mutasi & kartu stok per gudang** | kontrol |
| ⭐ | **Multi-bahasa / offline penuh** | skalabilitas |
| ⭐ | **QR label cetak dari handphone** (koneksi printer) | label lapangan |

---

## 8. Roadmap Sprint

| Sprint | Lingkup | Deliverable |
|---|---|---|
| **M0** | Setup | ✅ Sanctum + `routes/api.php` (`/api/v1`), `ApiResponse` standar JSON, AuthController (login username/NIK, logout, me), rate limit login, 5 test API |
| **Flutter** | Aplikasi | ✅ Repo `lpk-mobile` (git terpisah): `ApiClient` (dio + token secure), design system TIP, Login, Shell (bottom-nav 5 tab), Dashboard, Material (list/detail), Scan QR (`mobile_scanner`), Absensi (geolocator + selfie) — `flutter analyze` 0 error, `flutter build apk --debug` ✅ |
| **M1** | Auth + Dashboard | ✅ Login/logout/token, profil, `dashboard/summary` (KPI + stok menipis + absensi + unread), `notifications` (list/filter/read/read-all) — 5 test |
| **M2** | Material & Stok | ✅ `materials` (list/search/filter+paginasi+stok total), `materials/{code}` (detail + stok per gudang), `movements` (riwayat), `qr-check` (parse QR) — 5 test |
| **M3** | Scan QR | ✅ `qr-check` (parse QR label `LPK-TIP\|CODE\|NAMA` / kode polos → detail + stok real-time), `docs/API-MOBILE.md`, test tambahan |
| **M4** | Absensi Geotagging | ✅ `attendance/config`, `attendance/check` (in/out, photo selfie, anti-fake: mock/accuracy/radius/ganda), `attendance/history`, master Lokasi Absensi (MasterCrud + menu) — 7 test |
| **M5** | Polish & Rilis | ✅ Rate limit semua API (120/menit/user + login 10/menit), audit login/logout via `user_logs`, JSON error 404/429, test keamanan — **MVP backend siap** |

**Estimasi:** ± 6–8 minggu (1–2 developer) utk MVP M1–M5.
**Kriteria terima:** seluruh API teruji (feature test), aplikasi lolos UAT checklist (login → scan → absen → dashboard), tanpa emoji, light-mode.

---

## 9. Catatan Integrasi Backend (yang perlu disiapkan di lpk-laravel)

- [x] `config/sanctum.php` + tabel `personal_access_tokens` (migrasi)
- [x] Rute `/api/v1/*` (prefix `api/v1`) + middleware `auth:sanctum` + throttling login (10/menit)
- [x] Endpoint login validasi `username`/`nik` (via `employees.nik` → `users.employee_id`) + hash legacy compatible
- [x] `MaterialController` API: list/detail/movements/qr-check
- [x] Tabel `attendance_locations` (nama, lat/long, radius) + master (MasterCrud + menu "Lokasi Absensi")
- [x] Absensi mobile: kolom `photo_path`, `latitude`, `longitude`, `accuracy`, `attendance_type`, `is_mocked`, `is_mobile`, `device_info` di `attendances` (migrasi) + validasi server (haversine `Geo`, mock, akurasi, ganda)
- [x] Resource/transformers utk material, stok, absensi, dashboard
- [x] Test API (feature test) — 29 test API (M0–M5), total suite 107
- [x] Rate limiter 'api' (120/menit/user) + throttle login (10/menit) + audit `user_logs`
