Kontak pelanggan per store. SoftDeletes aktif. Inkonsistensi address vs addresses dan tipe tags (string vs UUID).
Definisi model
app/Models/Customer.php
| Properti | Nilai | Sumber |
|---|---|---|
| Collection | customers (diverifikasi via Rule::unique('customers', 'wa')) | ContactController.php:191,588,1883 |
$guarded | [] | Customer.php:15 |
| SoftDeletes | ✅ | Customer.php:13 |
| Casts | ❌ (commented out) | Customer.php:20-22 — // 'tags' => 'array' |
| Primary key | UUID string | Customer.php:16-18,24-30 |
Field
| Field | Tipe | Default | Sumber |
|---|---|---|---|
id | string UUID | generated | Customer.php:28 |
name | string | — | ContactController.php:217, OrderController.php:1989 |
email | string/null | null | ContactController.php:217, ShortlinkController.php:240 |
wa | string (+62.../62...) | — | ContactController.php:207,631,1896, OrderController.php:1988 |
store_id | string | — | ContactController.php:208, OrderController.php:1990 (scope tenant) |
addresses | object/null | null | ContactController.php:209,633,1897 |
other_addresses | object/null | null | :1898 |
address | string/null | null | ShortlinkController.php:243 legacy |
other | array | [] | ContactController.php:210, OrderController.php:1991 |
segment_id | string/null | null | ContactController.php:211,635,1613,1655,1992 |
profilepic | string/null | null | ContactController.php:212,635, OrderController.php:1993 |
latest_contact | string/null | null | ContactController.php:213,636, OrderController.php:1994 |
category | string | 'private' | ContactController.php:214,637 ('private'/'group') |
tags | array (string/UUID) | [] | ContactController.php:215,638,1902,1693,983, OrderController.php:1996 |
type | string | 'Customer' | ContactController.php:216,628,639, OrderController.php:1997 |
city | object/null | null | ShortlinkController.php:247 |
subdistrict | object/null | null | ShortlinkController.php:248 |
province | object/null | null | ShortlinkController.php:250 |
status | string | 'active' | ContactController.php:1988,1990,2033,2037 ('active'/'archive') |
rating | integer | — | ContactController.php:2095 |
deleted_at | datetime | — | SoftDeletes |
created_at | datetime | auto | — |
updated_at | datetime | auto | — |
Relasi
| Nama | Tipe | FK | Sumber |
|---|---|---|---|
orders | hasMany | Order.customer_id ← id | Customer.php:33-35 |
broadcast_submit_log | hasMany | BroadcastLog.customer_id ← id | :37-39 |
segment | belongsTo | Segment.id ← segment_id | :41-43 |
product | belongsTo | Product.id ← product_id | :45-47 (select name only) |
chats | manual query | ChatList.where('customer_id', $id).orWhere('nohp', $wa) | :49-55 |
latestChat | first | chats()->orderBy('waktu','desc')->first() | :57-59 |
Index & constraint
- Tidak ada index di model
- Validation:
Rule::unique('customers', 'wa')->where('store_id', $store->id)diContactController.php:191,588,1883— validasi aplikasi, bukan DB constraint. Race condition bisa bocor. - Primary key: UUID string
Contoh dokumen
{
"_id": ObjectId("..."),
"id": "uuid-customer",
"wa": "+6281234567890",
"name": "Budi",
"store_id": "<store.id>",
"other": [],
"segment_id": null,
"profilepic": null,
"latest_contact": null,
"category": "private",
"tags": ["<tag.id-1>", "<tag.id-2>"],
"type": "Customer",
"status": "active",
"rating": 0,
"created_at": ISODate("..."),
"updated_at": ISODate("...")
}Seeder
RefactorTagInCustomer.php— migrasi tags dari string ke UUIDCustomerJsonSeeder.php— export ke JSONImportCustomerTagsSeeder.php— re-import tags
Referensi
- Kontak Module — fitur dari sisi user
app/Models/Customer.php— modelapp/Http/Controllers/ContactController.php— controller 2.403 baris