Initial commit
This commit is contained in:
206
12-fase1-step1-core-foundation-spec.md
Normal file
206
12-fase1-step1-core-foundation-spec.md
Normal file
@ -0,0 +1,206 @@
|
||||
# Fase 1 — Step 1: Core Foundation (Spesifikasi Implementasi)
|
||||
|
||||
Dokumen ini memecah Step 1 menjadi paket kerja per service, API, schema, dan acceptance detail agar bisa langsung jadi ticket development.
|
||||
|
||||
## 1) Service yang Dibangun Dulu (Urutan Implementasi)
|
||||
|
||||
1. `shared` — tracing, idempotency key store, error envelope, request context
|
||||
2. `identity` — admin auth + device auth + RBAC baseline
|
||||
3. `merchant` — merchant onboarding dasar
|
||||
4. `location` — outlet dan terminal
|
||||
5. `device-tms` — registrasi device dan binding
|
||||
6. `core-db` — migrasi schema MVP + seed data
|
||||
7. `ingress` — endpoint admin yang membutuhkan service di atas
|
||||
|
||||
## 2) Kontrak Data dan ID Standard
|
||||
|
||||
### 2.1 ID
|
||||
- `merchant_id`, `outlet_id`, `terminal_id`, `device_id`, `binding_id`, `transaction_id`, `notification_id`
|
||||
- format rekomendasi: ULID/UUID v4
|
||||
|
||||
### 2.2 Standard Trace/Event
|
||||
- Setiap request HTTP dan MQTT message harus membawa:
|
||||
- `request_id` (wajib di inbound entry API / webhook / mqtt)
|
||||
- `trace_id` (inherit antar service)
|
||||
- `event_id` (untuk emission / audit event)
|
||||
|
||||
### 2.3 Idempotency
|
||||
- Table `idempotency_keys` baru:
|
||||
- `id`
|
||||
- `scope` (`merchant_create`, `outlet_create`, `terminal_create`, dll)
|
||||
- `key` (unique)
|
||||
- `response_hash`
|
||||
- `created_at`, `expires_at`
|
||||
- Rule: hit yang sama + key sama => response deterministic dari cache/replay.
|
||||
|
||||
## 3) Skema DB (MVP Step 1) — Detail Migrasi
|
||||
|
||||
### 3.1 Tabel Inti yang Harus Ada
|
||||
- `merchants`
|
||||
- `outlets`
|
||||
- `terminals`
|
||||
- `devices`
|
||||
- `device_bindings`
|
||||
- `device_heartbeats`
|
||||
- `transactions`
|
||||
- `transaction_events`
|
||||
- `notifications`
|
||||
- `audit_logs`
|
||||
- `users`
|
||||
- `roles`
|
||||
- `idempotency_keys` (tambah)
|
||||
|
||||
### 3.2 Field Wajib Step 1 per Tabel
|
||||
|
||||
#### `merchants`
|
||||
- id, merchant_code, legal_name, brand_name
|
||||
- status, onboarding_status
|
||||
- settlement_account_reference, settlement_account_type, fee_profile_id
|
||||
- created_at, updated_at
|
||||
|
||||
#### `outlets`
|
||||
- id, merchant_id(FK), outlet_code, name, address, status
|
||||
- created_at, updated_at
|
||||
|
||||
#### `terminals`
|
||||
- id, outlet_id(FK), terminal_code, qr_mode, partner_reference, status
|
||||
- created_at, updated_at
|
||||
|
||||
#### `devices`
|
||||
- id, device_code, serial_number, vendor, model
|
||||
- communication_mode, capability_profile_json, auth_method, status
|
||||
- last_seen_at, firmware_version
|
||||
- created_at, updated_at
|
||||
|
||||
#### `device_bindings`
|
||||
- id, device_id(FK), merchant_id(FK), outlet_id(FK), terminal_id(FK)
|
||||
- active_flag, bound_at, unbound_at
|
||||
- unique index: (`device_id`, `active_flag` where active_flag=true)
|
||||
|
||||
#### `device_heartbeats`
|
||||
- id, device_id(FK), received_at
|
||||
- network_strength, battery_level, firmware_version, state, payload_json
|
||||
|
||||
#### `transactions`
|
||||
- id, transaction_code, merchant_id(FK), outlet_id(FK), terminal_id(FK), device_id(FK)
|
||||
- qr_mode, initiation_mode, partner_reference, amount, currency, status, created_at, paid_at, expired_at, updated_at
|
||||
|
||||
#### `transaction_events`
|
||||
- id, transaction_id(FK), event_type, source, payload_json, created_at
|
||||
|
||||
#### `notifications`
|
||||
- id, transaction_id(FK), device_id(FK), delivery_channel, payload_type
|
||||
- delivery_status, retry_count, ack_status, sent_at, ack_at
|
||||
|
||||
#### `audit_logs`
|
||||
- id, actor_type, actor_id, action, entity_type, entity_id
|
||||
- before_json, after_json, source_ip, created_at
|
||||
|
||||
#### `users` / `roles` (minimal)
|
||||
- users: id, name, email, password_hash, role_id, status, created_at
|
||||
- roles: id, name, permissions_json, created_at
|
||||
|
||||
### 3.3 Index Prioritas Step 1
|
||||
- `device_bindings(device_id, active_flag)`
|
||||
- `transactions(partner_reference)`
|
||||
- `transactions(merchant_id, created_at)`
|
||||
- `transactions(status, created_at)`
|
||||
- `notifications(device_id, delivery_status)`
|
||||
- `device_heartbeats(device_id, received_at)`
|
||||
- `audit_logs(entity_type, entity_id, created_at)`
|
||||
|
||||
## 4) Modul API Step 1 (Spesifikasi Ringkas)
|
||||
|
||||
### 4.1 Admin/Auth
|
||||
- `POST /auth/login` (bila auth service belum ada, temporary token stub boleh pakai untuk sprint 1)
|
||||
- `POST /auth/token/refresh` (opsional)
|
||||
- Validasi RBAC untuk endpoint admin:
|
||||
- `admin` minimal bisa akses semua CRUD Fase 1
|
||||
- Error standar:
|
||||
- `UNAUTHORIZED`, `FORBIDDEN`, `VALIDATION_ERROR`
|
||||
|
||||
### 4.2 Merchant
|
||||
- `POST /admin/merchants`
|
||||
- body:
|
||||
- `legal_name`, `brand_name`, `settlement_account_reference`, `settlement_account_type`, `fee_profile_id`
|
||||
- `settlement_account_type` contoh: `merchant_virtual_account`, `merchant_bank_account`, `partner_payout_reference`
|
||||
- `payout_mode` (opsional): `merchant_direct` (default), `manual`
|
||||
- `merchant_direct` = payout diarahkan via reference payout merchant
|
||||
- `manual` = pencairan dibantu operasional, belum otomatis
|
||||
- validasi: `legal_name` required
|
||||
- idempotency: `Idempotency-Key` optional untuk create
|
||||
- `GET /admin/merchants`
|
||||
- `GET /admin/merchants/{merchantId}`
|
||||
- `PATCH /admin/merchants/{merchantId}`
|
||||
- `DELETE /admin/merchants/{merchantId}` (opsional; bisa soft delete via status=inactive)
|
||||
|
||||
### 4.3 Outlet
|
||||
- `POST /admin/merchants/{merchantId}/outlets`
|
||||
- `GET /admin/outlets`
|
||||
- `GET /admin/outlets/{outletId}`
|
||||
- `PATCH /admin/outlets/{outletId}`
|
||||
|
||||
### 4.4 Terminal
|
||||
- `POST /admin/outlets/{outletId}/terminals`
|
||||
- `GET /admin/terminals`
|
||||
- `GET /admin/terminals/{terminalId}`
|
||||
- `PATCH /admin/terminals/{terminalId}`
|
||||
|
||||
### 4.5 Device & Binding
|
||||
- `POST /admin/devices`
|
||||
- `GET /admin/devices`
|
||||
- `GET /admin/devices/{deviceId}`
|
||||
- `PATCH /admin/devices/{deviceId}`
|
||||
- `POST /admin/devices/{deviceId}/bind`
|
||||
- body: `{ merchant_id, outlet_id, terminal_id }`
|
||||
- rule: endpoint ini membuat record `device_bindings` baru dan menonaktifkan binding aktif lama
|
||||
- `POST /admin/devices/{deviceId}/unbind`
|
||||
- body: `{ reason }`
|
||||
|
||||
## 5) Acceptance Criteria per Paket
|
||||
|
||||
### 5.1 Merchant/Location
|
||||
- merchant, outlet, terminal bisa dibuat, diubah, list, detail
|
||||
- semua response memuat `request_id`
|
||||
- duplikasi create request dengan idempotency key yang sama menghasilkan resource yang sama
|
||||
|
||||
### 5.2 Device Binding
|
||||
- bind mengikat hanya satu binding aktif/device pada saat yang sama
|
||||
- unbind membuat binding aktif jadi nonaktif dan merekam `unbound_at`
|
||||
- binding referensi invalid menyebabkan endpoint device/transaction terkait ditolak di tahap berikutnya
|
||||
|
||||
### 5.3 Observability/Platform
|
||||
- semua response error mengikuti envelope:
|
||||
- `code`, `message`, `details`, `request_id`
|
||||
- log audit tersimpan saat create/update pada merchant, device, bind/unbind
|
||||
|
||||
### 5.4 Operasional
|
||||
- `last_seen_at` device berubah saat heartbeat valid (step 2 nantinya lebih lengkap)
|
||||
- pipeline dasar bisa menjalankan 10 request bersamaan tanpa crash (smoke test)
|
||||
|
||||
## 6) Definisi File/Artefak
|
||||
|
||||
### 6.1 Yang Harus Dibuat di Step 1
|
||||
- `12-fase1-step1-core-foundation-spec.md` (dokumen ini)
|
||||
- `DECISIONS_LOG.md` (dibuat bersama)
|
||||
- migration file untuk tabel Step 1
|
||||
- endpoint handlers sesuai list di atas
|
||||
- seed file:
|
||||
- 2 merchant
|
||||
- 2 outlet + 2 terminal
|
||||
- 3 devices (static, dynamic-mqtt, dynamic-api)
|
||||
|
||||
### 6.2 Testing Wajib (manual smoke, tanpa alat tambahan)
|
||||
- login/admin auth
|
||||
- CRUD merchant
|
||||
- CRUD outlet/terminal
|
||||
- bind/unbind device
|
||||
- seed device bisa dilihat di GET list
|
||||
|
||||
## 7) Handover ke Step 2
|
||||
|
||||
Step 2 tidak dimulai sampai:
|
||||
- endpoint binding dan auth stabil
|
||||
- transaksi memiliki struktur minimal `transactions + transaction_events`
|
||||
- event/error format terstandardisasi
|
||||
- idempotency baseline aktif
|
||||
Reference in New Issue
Block a user