# Quick Start Guide - Menu Module Access System ## 🚀 Langkah-langkah Setup ### 1. Jalankan Migration ```bash # Connect ke PostgreSQL dan jalankan migration psql -U your_username -d your_database -f docs/migrations/004_add_menu_module_access_system.sql ``` ### 2. Setup Data Master #### a. Buat Modules untuk Artikel ```sql INSERT INTO master_modules (name, description, path_url, action_type, status_id, is_active) VALUES ('Lihat Artikel', 'Melihat daftar dan detail artikel', '/api/articles', 'view', 1, true), ('Buat Artikel', 'Membuat artikel baru', '/api/articles', 'create', 1, true), ('Edit Artikel', 'Mengedit artikel yang ada', '/api/articles/:id', 'edit', 1, true), ('Hapus Artikel', 'Menghapus artikel', '/api/articles/:id', 'delete', 1, true), ('Approve Artikel', 'Menyetujui artikel', '/api/articles/:id/approve', 'approve', 1, true); -- Dapatkan ID modules yang baru dibuat untuk step selanjutnya ``` #### b. Buat Menu Artikel ```sql INSERT INTO master_menus (name, description, module_id, icon, "group", position, status_id, is_active) VALUES ('Artikel', 'Manajemen Artikel', 1, 'article-icon', 'Konten', 1, 1, true); -- Dapatkan menu_id untuk step selanjutnya (misal: menu_id = 10) ``` #### c. Hubungkan Menu dengan Modules ```sql -- Asumsikan menu_id = 10, dan module_ids = 1,2,3,4,5 INSERT INTO menu_modules (menu_id, module_id, position, is_active) VALUES (10, 1, 1, true), -- Lihat (10, 2, 2, true), -- Buat (10, 3, 3, true), -- Edit (10, 4, 4, true), -- Hapus (10, 5, 5, true); -- Approve ``` #### d. Berikan Akses ke User Levels ```sql -- Admin Pusat (user_level_id = 1) - Full Access INSERT INTO user_level_module_accesses (user_level_id, module_id, can_access, is_active) VALUES (1, 1, true, true), -- Lihat (1, 2, true, true), -- Buat (1, 3, true, true), -- Edit (1, 4, true, true), -- Hapus (1, 5, true, true); -- Approve -- Editor (user_level_id = 2) - Lihat, Buat, Edit saja INSERT INTO user_level_module_accesses (user_level_id, module_id, can_access, is_active) VALUES (2, 1, true, true), -- Lihat (2, 2, true, true), -- Buat (2, 3, true, true); -- Edit -- Viewer (user_level_id = 3) - Lihat saja INSERT INTO user_level_module_accesses (user_level_id, module_id, can_access, is_active) VALUES (3, 1, true, true); -- Lihat ``` ### 3. Implementasi di Code #### a. Tambahkan Routes dengan Middleware Buat file baru atau update: `app/router/article.routes.go` ```go package router import ( "netidhub-saas-be/app/database" "netidhub-saas-be/app/middleware" "netidhub-saas-be/app/module/articles/controller" "github.com/gofiber/fiber/v2" ) func SetupArticleRoutes(app *fiber.App, db *database.Database, ctrl controller.ArticleController) { // Initialize middlewares authMw := middleware.NewUserMiddleware(db) moduleAccessMw := middleware.NewModuleAccessMiddleware(db) // Article routes group articles := app.Group("/api/articles") // GET /api/articles - View (module_id = 1) articles.Get("/", authMw.ValidateToken(), moduleAccessMw.CheckModuleAccess(uint(1)), ctrl.GetAll, ) // GET /api/articles/:id - View detail (module_id = 1) articles.Get("/:id", authMw.ValidateToken(), moduleAccessMw.CheckModuleAccess(uint(1)), ctrl.GetOne, ) // POST /api/articles - Create (module_id = 2) articles.Post("/", authMw.ValidateToken(), moduleAccessMw.CheckModuleAccess(uint(2)), ctrl.Create, ) // PUT /api/articles/:id - Edit (module_id = 3) articles.Put("/:id", authMw.ValidateToken(), moduleAccessMw.CheckModuleAccess(uint(3)), ctrl.Update, ) // DELETE /api/articles/:id - Delete (module_id = 4) articles.Delete("/:id", authMw.ValidateToken(), moduleAccessMw.CheckModuleAccess(uint(4)), ctrl.Delete, ) // POST /api/articles/:id/approve - Approve (module_id = 5) articles.Post("/:id/approve", authMw.ValidateToken(), moduleAccessMw.CheckModuleAccess(uint(5)), ctrl.Approve, ) } ``` #### b. Register Routes di Main Router Update `app/router/api.go`: ```go // Import article routes import ( articleController "netidhub-saas-be/app/module/articles/controller" ) // Di dalam fungsi RegisterRoutes func RegisterRoutes(app *fiber.App, db *database.Database) { // ... existing routes ... // Article routes with module access control articleCtrl := articleController.NewArticleController(articleService) SetupArticleRoutes(app, db, articleCtrl) } ``` ### 4. Testing #### Test 1: User dengan Full Access (Admin) ```bash # Login sebagai admin (user_level_id = 1) curl -X POST http://localhost:3000/api/auth/login \ -H "Content-Type: application/json" \ -d '{ "username": "admin", "password": "password" }' # Copy token dari response TOKEN="your_admin_token_here" # Test akses semua endpoint - Semua harus berhasil curl -H "Authorization: Bearer $TOKEN" http://localhost:3000/api/articles curl -X POST -H "Authorization: Bearer $TOKEN" http://localhost:3000/api/articles -d '{"title":"Test"}' curl -X PUT -H "Authorization: Bearer $TOKEN" http://localhost:3000/api/articles/1 -d '{"title":"Updated"}' curl -X DELETE -H "Authorization: Bearer $TOKEN" http://localhost:3000/api/articles/1 curl -X POST -H "Authorization: Bearer $TOKEN" http://localhost:3000/api/articles/1/approve ``` #### Test 2: User dengan Limited Access (Editor) ```bash # Login sebagai editor (user_level_id = 2) curl -X POST http://localhost:3000/api/auth/login \ -H "Content-Type: application/json" \ -d '{ "username": "editor", "password": "password" }' TOKEN="your_editor_token_here" # Test akses - View, Create, Edit harus berhasil curl -H "Authorization: Bearer $TOKEN" http://localhost:3000/api/articles # ✓ Berhasil curl -X POST -H "Authorization: Bearer $TOKEN" http://localhost:3000/api/articles -d '{"title":"Test"}' # ✓ Berhasil curl -X PUT -H "Authorization: Bearer $TOKEN" http://localhost:3000/api/articles/1 -d '{"title":"Updated"}' # ✓ Berhasil # Test akses - Delete dan Approve harus ditolak curl -X DELETE -H "Authorization: Bearer $TOKEN" http://localhost:3000/api/articles/1 # ✗ 403 Forbidden curl -X POST -H "Authorization: Bearer $TOKEN" http://localhost:3000/api/articles/1/approve # ✗ 403 Forbidden ``` #### Test 3: Check Access via API ```bash # Check apakah user level 2 bisa akses module 4 (Delete) curl -X POST http://localhost:3000/api/user-level-module-accesses/check-access \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "user_level_id": 2, "module_id": 4 }' # Expected response: # { # "success": true, # "messages": ["Access check completed"], # "data": { # "has_access": false # } # } ``` ### 5. Manage Access via API #### Berikan Akses Baru ```bash # Berikan akses Delete ke Editor (user_level_id = 2, module_id = 4) curl -X POST http://localhost:3000/api/user-level-module-accesses \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "user_level_id": 2, "module_id": 4, "can_access": true }' ``` #### Berikan Akses Multiple Modules Sekaligus ```bash # Berikan akses ke banyak modul sekaligus (batch) curl -X POST http://localhost:3000/api/user-level-module-accesses/batch \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "user_level_id": 4, "module_ids": [1, 2, 3], "can_access": true }' ``` #### Lihat Akses User Level ```bash # Lihat semua akses untuk user_level_id = 2 curl -H "Authorization: Bearer $ADMIN_TOKEN" \ "http://localhost:3000/api/user-level-module-accesses/user-level/2" ``` #### Cabut Akses ```bash # Update akses menjadi false (cabut akses) curl -X PUT http://localhost:3000/api/user-level-module-accesses/123 \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "can_access": false }' ``` ## 📋 Checklist Implementation - [ ] Migration script sudah dijalankan - [ ] Tabel `menu_modules` dan `user_level_module_accesses` sudah ada - [ ] Modules sudah dibuat di `master_modules` - [ ] Menu sudah dibuat di `master_menus` - [ ] Menu-Module sudah dihubungkan di `menu_modules` - [ ] User Level Access sudah dikonfigurasi di `user_level_module_accesses` - [ ] Middleware `ModuleAccessMiddleware` sudah diterapkan di routes - [ ] Testing berhasil untuk berbagai user level - [ ] Dokumentasi internal sudah diupdate ## 🎯 Tips & Best Practices 1. **Konsisten dengan Action Type**: Gunakan standar `view`, `create`, `edit`, `delete`, `approve`, `export` 2. **Batch Operations**: Gunakan endpoint batch untuk setup awal atau bulk changes 3. **Soft Delete**: Gunakan `is_active=false` daripada hard delete 4. **Audit Log**: Log setiap perubahan access control untuk audit trail 5. **Default Deny**: Jika tidak ada record = tidak ada akses (secure by default) ## ❓ Troubleshooting ### Error: "User tidak valid" - Pastikan middleware auth (`ValidateToken()`) dipanggil sebelum `CheckModuleAccess()` - Pastikan user sudah login dan token valid ### Error: "Module tidak ditemukan" - Cek module_id yang digunakan di middleware - Pastikan module exists dan `is_active = true` ### Error: "Anda tidak memiliki akses ke modul ini" - Cek `user_level_module_accesses` untuk user level tersebut - Pastikan `can_access = true` dan `is_active = true` ### User Level tidak sesuai - Cek `user_roles.user_level_id` untuk user tersebut - Pastikan relasi users -> user_roles -> user_levels sudah benar ## 📚 Selanjutnya Baca dokumentasi lengkap di: [MENU_MODULE_ACCESS_SYSTEM.md](./MENU_MODULE_ACCESS_SYSTEM.md)