kontenhumas-be/docs/PLAN_MENU_ACTION_ACCESS_SYS...

312 lines
10 KiB
Markdown
Raw Normal View History

# 📋 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`