312 lines
10 KiB
Markdown
312 lines
10 KiB
Markdown
|
|
# 📋 Plan: Menu & Action Access Control System
|
|||
|
|
|
|||
|
|
## 🎯 Tujuan
|
|||
|
|
|
|||
|
|
Membangun sistem akses kontrol yang memungkinkan:
|
|||
|
|
1. **1 Menu memiliki banyak Actions** - Satu menu dapat memiliki berbagai action (view table, create, edit, delete, approve, export, dll)
|
|||
|
|
2. **User Level dapat di-assign Menu** - Setiap user level dapat di-assign menu apa saja yang bisa diakses
|
|||
|
|
3. **User Level dapat di-assign Actions per Menu** - Setiap user level dapat di-assign action apa saja yang bisa dilakukan di setiap menu (contoh: Creator hanya bisa create dan edit, Approver bisa delete)
|
|||
|
|
|
|||
|
|
## 🔍 Analisis Kebutuhan
|
|||
|
|
|
|||
|
|
### Use Case 1: Menu "Content Management"
|
|||
|
|
- **Actions yang tersedia:**
|
|||
|
|
- `view` - Melihat daftar content
|
|||
|
|
- `create` - Membuat content baru
|
|||
|
|
- `edit` - Mengedit content yang ada
|
|||
|
|
- `delete` - Menghapus content
|
|||
|
|
- `approve` - Approve content
|
|||
|
|
- `export` - Export data content
|
|||
|
|
|
|||
|
|
### Use Case 2: User Level "Creator"
|
|||
|
|
- **Menu yang bisa diakses:** Content Management
|
|||
|
|
- **Actions yang bisa dilakukan:**
|
|||
|
|
- ✅ `view` - Bisa melihat daftar
|
|||
|
|
- ✅ `create` - Bisa membuat baru
|
|||
|
|
- ✅ `edit` - Bisa mengedit
|
|||
|
|
- ❌ `delete` - Tidak bisa menghapus
|
|||
|
|
- ❌ `approve` - Tidak bisa approve
|
|||
|
|
- ❌ `export` - Tidak bisa export
|
|||
|
|
|
|||
|
|
### Use Case 3: User Level "Approver"
|
|||
|
|
- **Menu yang bisa diakses:** Content Management
|
|||
|
|
- **Actions yang bisa dilakukan:**
|
|||
|
|
- ✅ `view` - Bisa melihat daftar
|
|||
|
|
- ❌ `create` - Tidak bisa membuat baru
|
|||
|
|
- ❌ `edit` - Tidak bisa mengedit
|
|||
|
|
- ✅ `delete` - Bisa menghapus
|
|||
|
|
- ✅ `approve` - Bisa approve
|
|||
|
|
- ✅ `export` - Bisa export
|
|||
|
|
|
|||
|
|
## 🏗️ Arsitektur Sistem
|
|||
|
|
|
|||
|
|
### Opsi 1: Menu-Action Based (Recommended) ⭐
|
|||
|
|
|
|||
|
|
**Konsep:**
|
|||
|
|
- Menu memiliki Actions langsung (bukan melalui Module)
|
|||
|
|
- User Level memiliki akses ke Menu
|
|||
|
|
- User Level memiliki akses ke Actions di dalam Menu
|
|||
|
|
|
|||
|
|
**Struktur Database:**
|
|||
|
|
|
|||
|
|
#### 1. `master_menus` (Existing - Enhanced)
|
|||
|
|
```sql
|
|||
|
|
-- Sudah ada, tidak perlu perubahan
|
|||
|
|
-- Menu seperti: "Content Management", "User Management", "Settings"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2. `menu_actions` (New)
|
|||
|
|
```sql
|
|||
|
|
CREATE TABLE menu_actions (
|
|||
|
|
id SERIAL PRIMARY KEY,
|
|||
|
|
menu_id INT NOT NULL,
|
|||
|
|
action_code VARCHAR(50) NOT NULL, -- 'view', 'create', 'edit', 'delete', 'approve', 'export'
|
|||
|
|
action_name VARCHAR(255) NOT NULL, -- 'View Content', 'Create Content', etc.
|
|||
|
|
description TEXT NULL,
|
|||
|
|
path_url VARCHAR(255) NULL, -- Optional: untuk routing frontend
|
|||
|
|
http_method VARCHAR(10) NULL, -- Optional: 'GET', 'POST', 'PUT', 'DELETE'
|
|||
|
|
position INT NULL,
|
|||
|
|
is_active BOOLEAN DEFAULT TRUE,
|
|||
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|||
|
|
updated_at TIMESTAMP DEFAULT NOW(),
|
|||
|
|
FOREIGN KEY (menu_id) REFERENCES master_menus(id) ON DELETE CASCADE,
|
|||
|
|
UNIQUE(menu_id, action_code)
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
CREATE INDEX idx_menu_actions_menu_id ON menu_actions(menu_id);
|
|||
|
|
CREATE INDEX idx_menu_actions_action_code ON menu_actions(action_code);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 3. `user_level_menu_accesses` (New)
|
|||
|
|
```sql
|
|||
|
|
CREATE TABLE user_level_menu_accesses (
|
|||
|
|
id SERIAL PRIMARY KEY,
|
|||
|
|
user_level_id INT NOT NULL,
|
|||
|
|
menu_id INT NOT NULL,
|
|||
|
|
can_access BOOLEAN DEFAULT TRUE,
|
|||
|
|
client_id UUID NULL,
|
|||
|
|
is_active BOOLEAN DEFAULT TRUE,
|
|||
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|||
|
|
updated_at TIMESTAMP DEFAULT NOW(),
|
|||
|
|
FOREIGN KEY (user_level_id) REFERENCES user_levels(id) ON DELETE CASCADE,
|
|||
|
|
FOREIGN KEY (menu_id) REFERENCES master_menus(id) ON DELETE CASCADE,
|
|||
|
|
UNIQUE(user_level_id, menu_id, client_id)
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
CREATE INDEX idx_user_level_menu_accesses_user_level_id ON user_level_menu_accesses(user_level_id);
|
|||
|
|
CREATE INDEX idx_user_level_menu_accesses_menu_id ON user_level_menu_accesses(menu_id);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 4. `user_level_menu_action_accesses` (New)
|
|||
|
|
```sql
|
|||
|
|
CREATE TABLE user_level_menu_action_accesses (
|
|||
|
|
id SERIAL PRIMARY KEY,
|
|||
|
|
user_level_id INT NOT NULL,
|
|||
|
|
menu_id INT NOT NULL,
|
|||
|
|
action_code VARCHAR(50) NOT NULL,
|
|||
|
|
can_access BOOLEAN DEFAULT TRUE,
|
|||
|
|
client_id UUID NULL,
|
|||
|
|
is_active BOOLEAN DEFAULT TRUE,
|
|||
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|||
|
|
updated_at TIMESTAMP DEFAULT NOW(),
|
|||
|
|
FOREIGN KEY (user_level_id) REFERENCES user_levels(id) ON DELETE CASCADE,
|
|||
|
|
FOREIGN KEY (menu_id) REFERENCES master_menus(id) ON DELETE CASCADE,
|
|||
|
|
FOREIGN KEY (menu_id, action_code) REFERENCES menu_actions(menu_id, action_code) ON DELETE CASCADE,
|
|||
|
|
UNIQUE(user_level_id, menu_id, action_code, client_id)
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
CREATE INDEX idx_user_level_menu_action_accesses_user_level_id ON user_level_menu_action_accesses(user_level_id);
|
|||
|
|
CREATE INDEX idx_user_level_menu_action_accesses_menu_id ON user_level_menu_action_accesses(menu_id);
|
|||
|
|
CREATE INDEX idx_user_level_menu_action_accesses_action_code ON user_level_menu_action_accesses(action_code);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Relasi:**
|
|||
|
|
```
|
|||
|
|
master_menus (1) ─────< (N) menu_actions
|
|||
|
|
│ │
|
|||
|
|
│ │
|
|||
|
|
│ (1) │ (N)
|
|||
|
|
│ │
|
|||
|
|
∨ ∨
|
|||
|
|
user_level_menu_accesses user_level_menu_action_accesses
|
|||
|
|
│ │
|
|||
|
|
│ (N) │ (N)
|
|||
|
|
│ │
|
|||
|
|
∨ ∨
|
|||
|
|
user_levels (1) ──────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Keuntungan:**
|
|||
|
|
- ✅ Lebih sederhana dan intuitif
|
|||
|
|
- ✅ Langsung ke point: Menu → Actions
|
|||
|
|
- ✅ Mudah di-manage: assign menu, lalu assign actions
|
|||
|
|
- ✅ Tidak perlu konsep "Module" yang membingungkan
|
|||
|
|
- ✅ Frontend lebih mudah: cek menu access, lalu cek action access
|
|||
|
|
|
|||
|
|
**Kekurangan:**
|
|||
|
|
- ❌ Perlu migration dari sistem Module yang ada
|
|||
|
|
- ❌ Perlu refactor middleware dan service yang sudah ada
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Opsi 2: Keep Module, Enhance Structure
|
|||
|
|
|
|||
|
|
**Konsep:**
|
|||
|
|
- Tetap menggunakan Module, tapi Module sekarang lebih spesifik ke Menu
|
|||
|
|
- Module = Action di dalam Menu
|
|||
|
|
- User Level memiliki akses ke Menu
|
|||
|
|
- User Level memiliki akses ke Module (Action) di dalam Menu
|
|||
|
|
|
|||
|
|
**Struktur Database:**
|
|||
|
|
|
|||
|
|
#### 1. `master_menus` (Existing)
|
|||
|
|
```sql
|
|||
|
|
-- Tidak berubah
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2. `master_modules` (Existing - Enhanced)
|
|||
|
|
```sql
|
|||
|
|
-- Tetap ada, tapi sekarang lebih spesifik:
|
|||
|
|
-- Module sekarang = Action di dalam Menu
|
|||
|
|
-- action_type menjadi lebih penting
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 3. `menu_modules` (Existing - Enhanced)
|
|||
|
|
```sql
|
|||
|
|
-- Tetap ada, relasi Menu dengan Module (Action)
|
|||
|
|
-- Tapi sekarang lebih strict: 1 module hanya untuk 1 menu
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 4. `user_level_menu_accesses` (New)
|
|||
|
|
```sql
|
|||
|
|
-- Sama seperti Opsi 1
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 5. `user_level_module_accesses` (Existing)
|
|||
|
|
```sql
|
|||
|
|
-- Tetap ada, tapi sekarang lebih spesifik:
|
|||
|
|
-- Module = Action di dalam Menu
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Keuntungan:**
|
|||
|
|
- ✅ Tidak perlu migration besar-besaran
|
|||
|
|
- ✅ Bisa reuse struktur yang sudah ada
|
|||
|
|
- ✅ Lebih fleksibel (module bisa digunakan oleh banyak menu)
|
|||
|
|
|
|||
|
|
**Kekurangan:**
|
|||
|
|
- ❌ Konsep "Module" masih membingungkan
|
|||
|
|
- ❌ Lebih kompleks: Menu → Module → Action
|
|||
|
|
- ❌ Perlu mapping yang lebih kompleks
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎯 Rekomendasi: Opsi 1 (Menu-Action Based)
|
|||
|
|
|
|||
|
|
**Alasan:**
|
|||
|
|
1. **Lebih intuitif** - Langsung ke point: Menu punya Actions
|
|||
|
|
2. **Lebih mudah di-manage** - Admin langsung assign menu dan actions
|
|||
|
|
3. **Lebih mudah di-frontend** - Cek menu access, lalu cek action access
|
|||
|
|
4. **Lebih scalable** - Mudah ditambah menu baru dengan actions baru
|
|||
|
|
5. **Lebih maintainable** - Struktur lebih jelas dan mudah dipahami
|
|||
|
|
|
|||
|
|
## 📝 Implementation Plan
|
|||
|
|
|
|||
|
|
### Phase 1: Database Schema
|
|||
|
|
1. ✅ Buat tabel `menu_actions`
|
|||
|
|
2. ✅ Buat tabel `user_level_menu_accesses`
|
|||
|
|
3. ✅ Buat tabel `user_level_menu_action_accesses`
|
|||
|
|
4. ✅ Buat migration script
|
|||
|
|
5. ✅ Migrate data dari `master_modules` dan `menu_modules` ke `menu_actions` (jika perlu)
|
|||
|
|
|
|||
|
|
### Phase 2: Backend Entities & Repositories
|
|||
|
|
1. ✅ Buat entity `MenuActions`
|
|||
|
|
2. ✅ Buat entity `UserLevelMenuAccesses`
|
|||
|
|
3. ✅ Buat entity `UserLevelMenuActionAccesses`
|
|||
|
|
4. ✅ Buat repository untuk masing-masing entity
|
|||
|
|
5. ✅ Buat service untuk masing-masing entity
|
|||
|
|
|
|||
|
|
### Phase 3: Backend API Endpoints
|
|||
|
|
1. ✅ CRUD API untuk `menu_actions`
|
|||
|
|
2. ✅ CRUD API untuk `user_level_menu_accesses`
|
|||
|
|
3. ✅ CRUD API untuk `user_level_menu_action_accesses`
|
|||
|
|
4. ✅ API untuk get menu actions by menu_id
|
|||
|
|
5. ✅ API untuk get user level menu accesses
|
|||
|
|
6. ✅ API untuk get user level menu action accesses
|
|||
|
|
|
|||
|
|
### Phase 4: Backend Middleware
|
|||
|
|
1. ✅ Buat middleware `CheckMenuAccess` - cek apakah user level bisa akses menu
|
|||
|
|
2. ✅ Buat middleware `CheckMenuActionAccess` - cek apakah user level bisa akses action di menu
|
|||
|
|
3. ✅ Update existing middleware untuk menggunakan struktur baru
|
|||
|
|
|
|||
|
|
### Phase 5: Frontend Services
|
|||
|
|
1. ✅ Buat service untuk `menu_actions`
|
|||
|
|
2. ✅ Buat service untuk `user_level_menu_accesses`
|
|||
|
|
3. ✅ Buat service untuk `user_level_menu_action_accesses`
|
|||
|
|
4. ✅ Update existing services
|
|||
|
|
|
|||
|
|
### Phase 6: Frontend UI - Menu Management
|
|||
|
|
1. ✅ Update halaman Menu Management untuk menampilkan Actions
|
|||
|
|
2. ✅ Tambah form untuk manage Actions di setiap Menu
|
|||
|
|
3. ✅ Tambah UI untuk assign Actions ke Menu
|
|||
|
|
|
|||
|
|
### Phase 7: Frontend UI - User Level Management
|
|||
|
|
1. ✅ Update halaman User Level Management
|
|||
|
|
2. ✅ Tambah tab "Menu Access" untuk assign menu ke user level
|
|||
|
|
3. ✅ Tambah tab "Action Access" untuk assign actions per menu ke user level
|
|||
|
|
4. ✅ Update form User Level untuk include menu dan action access
|
|||
|
|
|
|||
|
|
### Phase 8: Frontend UI - Permission Check
|
|||
|
|
1. ✅ Buat hook `useMenuAccess` untuk cek menu access
|
|||
|
|
2. ✅ Buat hook `useMenuActionAccess` untuk cek action access
|
|||
|
|
3. ✅ Update components untuk menggunakan hooks
|
|||
|
|
4. ✅ Hide/show UI elements berdasarkan permission
|
|||
|
|
|
|||
|
|
### Phase 9: Testing & Documentation
|
|||
|
|
1. ✅ Test semua API endpoints
|
|||
|
|
2. ✅ Test middleware
|
|||
|
|
3. ✅ Test frontend UI
|
|||
|
|
4. ✅ Update documentation
|
|||
|
|
|
|||
|
|
## 🔄 Migration Strategy
|
|||
|
|
|
|||
|
|
### Option A: Clean Slate (Recommended)
|
|||
|
|
- Buat struktur baru dari awal
|
|||
|
|
- Data lama tetap ada tapi tidak digunakan
|
|||
|
|
- Migrate data secara bertahap jika perlu
|
|||
|
|
|
|||
|
|
### Option B: Gradual Migration
|
|||
|
|
- Keep struktur lama dan baru berjalan bersamaan
|
|||
|
|
- Migrate data dari lama ke baru
|
|||
|
|
- Deprecate struktur lama setelah semua ter-migrate
|
|||
|
|
|
|||
|
|
## 📊 Comparison: Current vs Proposed
|
|||
|
|
|
|||
|
|
### Current System
|
|||
|
|
```
|
|||
|
|
Menu → Module (via menu_modules) → User Level Access (via user_level_module_accesses)
|
|||
|
|
```
|
|||
|
|
- Module adalah entitas terpisah
|
|||
|
|
- Module bisa digunakan oleh banyak menu
|
|||
|
|
- Akses diberikan ke Module, bukan ke Menu + Action
|
|||
|
|
|
|||
|
|
### Proposed System
|
|||
|
|
```
|
|||
|
|
Menu → Actions (via menu_actions) → User Level Menu Access → User Level Action Access
|
|||
|
|
```
|
|||
|
|
- Actions langsung di dalam Menu
|
|||
|
|
- Actions spesifik untuk Menu tertentu
|
|||
|
|
- Akses diberikan ke Menu dan Actions secara terpisah
|
|||
|
|
|
|||
|
|
## ✅ Next Steps
|
|||
|
|
|
|||
|
|
1. **Review & Approval** - Review plan ini dengan tim
|
|||
|
|
2. **Decision** - Pilih antara Opsi 1 atau Opsi 2
|
|||
|
|
3. **Database Design** - Finalize database schema
|
|||
|
|
4. **Implementation** - Mulai implementasi sesuai phase yang sudah direncanakan
|
|||
|
|
|
|||
|
|
## 📚 Reference
|
|||
|
|
|
|||
|
|
- Current system: `docs/MENU_MODULE_ACCESS_SYSTEM.md`
|
|||
|
|
- Implementation summary: `docs/IMPLEMENTATION_SUMMARY_MENU_MODULE_ACCESS.md`
|
|||
|
|
|