Dashboard Widget — User Master Enhancement
Tujuan Dokumen
Dokumen ini menganalisis struktur user master yang ada saat ini (tconfuser, tconfgroup, tconfusergroup) dan menentukan apakah perlu penambahan kolom atau tabel baru untuk mendukung sistem role-based dashboard yang didefinisikan di dashboard-widget-architecture.md.
Struktur User Master yang Ada Saat Ini
Dari hasil review kode (UserModel.cs, UserService.cs, ConfGroupModel.cs, GetAdministrativeToolsData.cs), skema yang relevan adalah sebagai berikut:
tconfuser tconfusergroup tconfgroup
───────────────────── ────────────────── ──────────────────────
userid (PK) ─────┐ userid (FK → tconfuser) groupid (PK)
usernama └───► groupid (FK → tconfgroup) groupkode
useremail groupnama
en_id groupactive ('Y'/'N')
user_branch_id group_is_cost ('Y'/'N')
user_cc_id groupdefault ('Y'/'N')
user_xemp_id
user_sp_id
useractive ('Y'/'N')
force_change_pass
is_2fa
... (field lainnya)
Karakteristik Penting
-
Many-to-many: Satu user dapat tergabung dalam banyak group (
tconfusergroup). Ini digunakan untuk menu access control yang granular — misalnya user bisa punya group "Finance Read-Only" sekaligus "AR Full Access". -
tconfgroup= menu permission group, bukan jabatan/role bisnis. Fieldgroupnamaberisi nama teknis seperti "Finance-AR-Full", bukan "Finance Manager". Ia mengontrolenablestatus,visiblewebstatus,insertstatus,deletestatus, dst. dimenuc_conf. -
group_is_cost: flag khusus yang menentukan apakah group ini adalah cost center group — tidak ada kaitannya dengan dashboard role. -
groupdefault: menandai group default yang di-assign saat user baru dibuat — bukan "primary role" dalam konteks bisnis. -
Tidak ada field "jabatan" atau "level" di
tconfuser— tidak adauser_level,user_role,user_position, atau sejenisnya yang bisa langsung dipakai sebagai dashboard role selector.
Masalah Jika Reuse tconfgroup untuk Dashboard Role
Reusing tconfgroup sebagai dashboard role tidak disarankan karena:
| Masalah | Penjelasan |
|---|---|
| Semantic mismatch | Group adalah menu permission set, bukan jabatan. Satu user bisa punya 3-5 group sekaligus — mana yang jadi dashboard role? |
| Many-to-many ambiguity | Tidak ada cara deterministik memilih "satu" dashboard role dari multiple group tanpa logika tambahan yang rumit |
| Coupling yang buruk | Perubahan struktur group (untuk kebutuhan menu access) akan berdampak ke dashboard — dua concern yang seharusnya terpisah |
| Granularity berbeda | Group bisa sangat teknis dan granular ("AR-Create-Only", "PO-Approve"); dashboard role perlu abstraksi level lebih tinggi ("Finance Manager") |
Tidak ada field drc_role_code yang cocok | groupkode dan groupnama tidak dirancang sebagai role code untuk dashboard config |
Rekomendasi: Tambah Kolom user_dashboard_role di tconfuser
Pendekatan yang Dipilih
Tambahkan satu kolom baru user_dashboard_role di tabel tconfuser, berisi kode role dashboard yang mengacu ke drc_role_code di dashboard_role_config.
ALTER TABLE tconfuser
ADD COLUMN user_dashboard_role VARCHAR(50) DEFAULT NULL;
-- NULL = user tidak mendapat dashboard khusus, fallback ke dashboard default (OPERATOR)
-- Contoh nilai: 'EXECUTIVE', 'FINANCE_MGR', 'SALES_MGR', 'MANUFACTURE_MGR', dst.
Alasan Memilih Kolom Tunggal (bukan Tabel Baru)
| Pertimbangan | Penjelasan |
|---|---|
| Satu user = satu dashboard | Tidak ada kebutuhan user melihat lebih dari satu dashboard sekaligus — ini berbeda dengan menu access yang memang bisa multi-group |
| Tetap sederhana | Kolom tunggal cukup; tidak perlu tabel junction baru hanya untuk satu relasi 1:1 |
| Konsisten dengan pola existing | tconfuser sudah memiliki banyak kolom single-value preference (en_id, user_branch_id, is_2fa, dll.) |
| Mudah di-query | SELECT user_dashboard_role FROM tconfuser WHERE userid = @userid — tidak perlu join tambahan saat login |
| Independen dari group | Perubahan group permission tidak mempengaruhi dashboard role, dan sebaliknya |
Perubahan yang Dibutuhkan
1. Database
-- Migration
ALTER TABLE tconfuser
ADD COLUMN user_dashboard_role VARCHAR(50) DEFAULT NULL;
-- Seed default berdasarkan pemetaan group yang sudah ada (opsional, satu kali)
-- Ini hanya estimasi awal — administrator tetap harus verifikasi per user
UPDATE tconfuser SET user_dashboard_role = 'OPERATOR'
WHERE user_dashboard_role IS NULL;
2. UserModel.cs
Tambah satu property:
// NeuronLibrary/Models/Administrative Tools/UserModel.cs
public string user_dashboard_role { get; set; }
3. UserService.cs — GetUser() dan GetUserMobile()
Tambah kolom user_dashboard_role ke SELECT query:
sql = @"select
u.userid,
usernama,
...
u.user_dashboard_role, -- ← tambahan
...
from tconfuser u
...";
4. GetAdministrativeToolsData.cs — GetUserDetail()
Sama — tambah user_dashboard_role ke kolom yang di-fetch saat load user context.
5. CreateUser() dan UpdateUser() di UserService.cs
Tambah parameter user_dashboard_role ke INSERT dan UPDATE statement:
// INSERT
sql = @"insert into tconfuser
(userid, usernama, ..., user_dashboard_role, ...)
values (@userid, @usernama, ..., @user_dashboard_role, ...)";
p.Add("@user_dashboard_role", dr_user.user_dashboard_role, DbType.String);
// UPDATE
sql = @"update tconfuser set
usernama = @usernama,
...,
user_dashboard_role = @user_dashboard_role
where userid = @userid";
6. Halaman User Management (Employee.razor / User Create)
Tambah field dropdown "Dashboard Role" di form create/edit user:
<DxFormLayoutItem Caption="Dashboard Role:" ColSpanMd="6">
<DxComboBox Data="@dt_dashboard_roles"
@bind-Value="@dr_user.user_dashboard_role"
NullText="-- Default (Operator) --"
TextFieldName="RoleName"
ValueFieldName="RoleCode" />
</DxFormLayoutItem>
Data source dt_dashboard_roles dibaca dari dashboard_role_config (distinct drc_role_code) atau dari sebuah lookup tabel/enum statis.
Alur Resolusi Dashboard Role Saat Login
flowchart TD
A[User Login] --> B[Load user dari tconfuser]
B --> C{user_dashboard_role\nNULL?}
C -->|NULL| D[Gunakan role default: OPERATOR]
C -->|Ada nilai| E[Gunakan user_dashboard_role]
D --> F[Load widget config\ndari dashboard_role_config\nwhere drc_role_code = role]
E --> F
F --> G{Ada widget aktif?}
G -->|Ya| H[Render DashboardContainer\ndengan widget yang dikonfigurasi]
G -->|Tidak| I[Render empty dashboard\natau pesan 'No dashboard configured']
Di Program.cs / CustomAuthenticationStateProvider, setelah user berhasil login, user_dashboard_role disimpan ke claim atau GlobalParam dan diteruskan ke DashboardContainer sebagai parameter RoleCode.
Mapping Awal Role Code ke Jabatan
Tabel ini digunakan sebagai referensi saat Administrator men-assign user_dashboard_role ke masing-masing user:
user_dashboard_role | Target Jabatan | Dashboard yang Ditampilkan |
|---|---|---|
EXECUTIVE | Direktur, Owner, CEO | Executive Dashboard (13 widget) |
FINANCE_MGR | Manajer Keuangan, Finance Controller | Finance Manager Dashboard (10 widget) |
SALES_MGR | Manajer Penjualan, Sales Director | Sales Manager Dashboard (11 widget) |
WAREHOUSE_MGR | Manajer Gudang, Manajer Operasional | Warehouse/Ops Dashboard (9 widget) |
PROCUREMENT_MGR | Manajer Pembelian, Purchasing Head | Procurement Dashboard (8 widget) |
MANUFACTURE_MGR | Manajer Produksi, Plant Manager | Manufacturing Dashboard (12 widget) |
HR_MGR | Manajer HR, HRD Head | HR Dashboard (9 widget) |
SUPERVISOR | Supervisor (semua fungsi) | Supervisor Dashboard (subset, configurable) |
OPERATOR | Staff, Entry-level, Kasir | Operator Dashboard (4 widget) |
Note: Role ini independen dari
tconfgroup. Seorang user bisa punya groupAR-Full-Access(untuk menu access) sekaligususer_dashboard_role = 'FINANCE_MGR'(untuk dashboard). Keduanya tidak saling mempengaruhi.
Pertimbangan: Apakah Perlu Tabel dashboard_role_master?
Saat ini drc_role_code di dashboard_role_config adalah VARCHAR free-text. Pertanyaannya apakah perlu tabel master untuk role code itu sendiri.
Rekomendasi: Tidak perlu di Phase 1, cukup pakai enum / lookup statis di aplikasi. Alasan:
- Role dashboard berjumlah sedikit (9 role) dan jarang berubah
- Menambah tabel master berarti menambah CRUD page lagi
- Validasi bisa dilakukan di level aplikasi (dropdown di form user hanya menampilkan nilai valid)
Jika ke depan dibutuhkan multi-tenant dengan role dashboard custom per tenant, baru pertimbangkan tabel dashboard_role_master.
Dampak ke Bagian Lain Sistem
| Area | Dampak | Tindakan |
|---|---|---|
tconfuser DB | Tambah kolom | ALTER TABLE migration |
UserModel.cs | Tambah property | 1 baris kode |
UserService.cs | Update SELECT/INSERT/UPDATE | ~10 baris kode |
GetAdministrativeToolsData.cs | Update SELECT | ~2 baris kode |
CustomAuthenticationStateProvider | Baca dan simpan role ke claims | ~5 baris kode |
| Halaman User Management (razor) | Tambah dropdown field | ~10 baris UI |
DashboardContainer.razor | Terima RoleCode dari context | Sudah dirancang |
dashboard_role_config (DB) | Tidak berubah | - |
Menu access / tconfgroup | Tidak berubah sama sekali | - |
Perubahan terlokalisasi dan tidak mempengaruhi logika existing apapun — karena kolom baru user_dashboard_role bersifat additive dan nullable.
Summary Keputusan
| Pertanyaan | Jawaban |
|---|---|
Apakah tconfgroup bisa dipakai sebagai dashboard role? | Tidak — semantic dan strukturnya tidak sesuai |
| Apakah perlu tabel baru untuk dashboard role? | Tidak — cukup satu kolom baru di tconfuser |
| Kolom apa yang ditambahkan? | user_dashboard_role VARCHAR(50) DEFAULT NULL di tconfuser |
| Apa yang terjadi jika NULL? | Fallback ke role OPERATOR (dashboard minimal) |
| Apakah menu access terpengaruh? | Tidak — kedua sistem sepenuhnya independen |
| Siapa yang assign dashboard role ke user? | Administrator, via halaman User Management |
| Kapan role dibaca? | Saat login, disimpan ke auth claims/session |