Modul team mengelola anggota tim per store: role (Owner/Admin/CS/Gudang), permission, team chat internal, dan rotasi CS.
File kunci
| File | Baris | Peran |
|---|---|---|
app/Http/Controllers/TeamController.php | 830 | CRUD team member, role hierarchy, redistribusi rotator |
app/Http/Controllers/TeamchatController.php | 418 | Internal team chat (DM antar member) |
app/Models/UserStore.php | 46 | Pivot user↔store |
app/Models/TeamchatInbox.php | 30 | Pesan internal team |
app/Models/HandleGudang.php | 24 | Antrian handle gudang |
app/Models/VendorUser.php | 35 | User koneksi covendor (Sanctum) |
Role hierarchy
| Role | Akses |
|---|---|
Owner | Full access, tidak bisa dihapus |
Admin | Manage CS di bawahnya, tidak bisa hapus Admin paralel |
Customer Service | Chat handling, assign ke Admin |
Gudang | Handle gudang untuk chat |
UserStore field: store_id, user_id, is_owner (bool), role, admin_id (referensi CS→Admin), permission (array), default_device, status_feature (enabled/disabled).
Controller method utama
TeamController
| Method | Fungsi |
|---|---|
store | Create User + UserStore. Bila role=Gudang: tambahkan ke ChatList.id_gudang & HandleGudang.gudang_id |
update | Edit user + role. Bila CS → set admin_id |
destroy | Bulk delete + validasi hierarchy + redistribusi rotator + re-enable/disable per kuota paket |
getAdminOptionList | List admin untuk dropdown |
teamFeatureAccess | Hitung kuota member dari findAccessFeature(features, 'team_member') |
TeamchatController
| Method | Fungsi |
|---|---|
list | List member store (kecuali diri) + TeamchatInbox terakhir per pair |
getUnreads | Count pesan belum dibaca |
add | Simpan pesan + POST ke {url_engine}/update-teamchat |
listInbox | Load pesan per pair + mark read |
index | Render Teamchat/Index |
store | Create akun chat eksternal via http://localhost/chat/api_request |
Route
Web (routes/web.php:239)
Prefix /team:
| Method | Path | Fungsi |
|---|---|---|
| GET | /team | Index |
| GET | /team/create | Form create |
| POST | /team/store | Create |
| GET | /team/edit/{id} | Edit |
| POST | /team/update/{id} | Update |
| POST | /team/destroy | Delete |
Prefix /teamchat:
| Method | Path | Fungsi |
|---|---|---|
| GET | /teamchat | Index |
API (routes/api.php:333)
| Method | Path | Fungsi |
|---|---|---|
| POST | /team/list | List member |
| GET | /team/list_paginate | Paginate |
| GET | /teamchat/list | List chat |
| POST | /teamchat/add | Kirim pesan |
| GET | /teamchat/list-inbox | Inbox per pair |
| POST | /teamchat/mark_read | Mark read |
Integrasi
| Service | Endpoint | Untuk |
|---|---|---|
Engine WA (url_engine) | POST /update-teamchat | Push event realtime chat ke socket WA |
| External chat service | http://localhost/chat/api_request | Create akun chat eksternal (key 21aOfjTBLDhFx6AoMqH hardcoded) |
| Cron Downgrade | handleDowngradeTeamMember | Disable team member berlebih saat paket turun |
Temuan
destroybug (:508) —Store::where('user_id', $user->id)hanya jalan untuk Owner. Bisa return null untuk Admin/CS → fataldestroyset email null via rawDB::table('users')(:671-673) — bypass model, bisa bentrok dengan soft deletestoreassign permission tanpa validasi struktur (:319) — bisa inject permission tanpa batasTeamchatController::storekredensial hardcoded (:18-19) — passwordtime(), usernametime(). Lemahmark_readroute duplikat (api.php:663-664) —POST /mark_readterdaftar 2xUserRole&UserAspireMySQL kosong — warisan, tidak terpakaiHandleGudangtanpa SoftDeletes — beda dengan model sejenis