10 KiB
📋 Module Update Checklist untuk Multi-Client Support
Status Saat Ini
❌ Module BELUM disesuaikan dengan entity baru
✅ Entity sudah diupdate (Clients, Users, UserClientAccess)
✅ Middleware baru sudah dibuat (ClientMiddlewareV2)
✅ Utilities sudah dibuat (client_hierarchy, client_utils_v2)
🎯 Module yang PERLU Diupdate
Priority 1: CRITICAL (Harus diupdate dulu)
✅ 1. Module: clients (PARTIALLY DONE)
Status: Request & Response V2 sudah dibuat
TODO:
- Update
clients.repository.go- Add hierarchy queries - Update
clients.service.go- Add hierarchy logic - Update
clients.controller.go- Add new endpoints - Update
clients.mapper.go- Support new fields
Files Updated:
- ✅
request/clients.request.v2.go- NEW - ✅
response/clients.response.v2.go- NEW
New Endpoints Needed:
GET /api/v2/clients/:id/hierarchy // Get client tree
GET /api/v2/clients/:id/sub-clients // Get direct children
POST /api/v2/clients/:id/sub-clients // Create sub-client
PUT /api/v2/clients/:id/move // Move to different parent
GET /api/v2/clients/:id/stats // Get client statistics
POST /api/v2/clients/bulk-sub-clients // Bulk create sub-clients
⚠️ 2. Module: users
Impact: HIGH - Users sekarang bisa multi-client access
TODO:
- Add endpoint untuk get accessible clients
- Add endpoint untuk switch current client
- Update user creation untuk set is_super_admin
- Update user list untuk show client access info
New Endpoints Needed:
GET /api/v2/users/me/accessible-clients // Get my accessible clients
POST /api/v2/users/me/switch-client // Switch active client
GET /api/v2/users/:id/client-access // Get user's client access
POST /api/v2/users/:id/grant-client-access // Grant multi-client access
DELETE /api/v2/users/:id/revoke-client-access // Revoke client access
⚠️ 3. Module: user_client_access (NEW MODULE)
Status: NEED TO CREATE
Purpose: Manage many-to-many User ↔ Client relationships
Structure:
app/module/user_client_access/
├── user_client_access.module.go
├── controller/
│ └── user_client_access.controller.go
├── service/
│ └── user_client_access.service.go
├── repository/
│ └── user_client_access.repository.go
├── request/
│ └── user_client_access.request.go
└── response/
└── user_client_access.response.go
Endpoints:
GET /api/v2/user-client-access // List all access grants
POST /api/v2/user-client-access // Grant access
DELETE /api/v2/user-client-access/:id // Revoke access
GET /api/v2/user-client-access/user/:id // Get by user
GET /api/v2/user-client-access/client/:id // Get by client
Priority 2: MEDIUM (Update untuk consistency)
🔸 4. Module: articles
Impact: MEDIUM - Perlu support multi-client filtering
TODO:
- Update repository
GetAll()- UseAddMultiClientFilter() - Update repository
FindOne()- Validate client access - Update service untuk validate user has access to target client
- Update controller untuk support
?client_id=xxxfilter
Changes Needed:
// OLD
func (r *Repository) GetAll(clientId *uuid.UUID, req request.QueryRequest) {
query := r.DB.Model(&entity.Articles{})
if clientId != nil {
query = query.Where("client_id = ?", clientId)
}
}
// NEW
func (r *Repository) GetAll(c *fiber.Ctx, req request.QueryRequest) {
query := r.DB.Model(&entity.Articles{})
// Auto-filter by accessible clients
query = middlewareUtils.AddMultiClientFilter(query, c)
// Optional: specific client filter
if req.ClientId != nil {
// Validate access first
query = query.Where("client_id = ?", req.ClientId)
}
}
🔸 5. Module: user_roles
Impact: MEDIUM - Roles mungkin specific per client
TODO:
- Update untuk support multi-client role access
- Add logic untuk inherit roles dari parent client (optional)
🔸 6. Module: user_levels
Impact: MEDIUM - Levels mungkin berbeda per client
TODO:
- Update untuk support multi-client level definitions
- Add hierarchy logic untuk levels across clients
Priority 3: LOW (Optional updates)
Modules berikut juga punya ClientId field, tapi update bisa dilakukan bertahap:
schedules- Update filteringfeedbacks- Update filteringsubscriptions- Update filteringmagazines- Update filteringadvertisements- Update filteringarticle_categories- Update filteringbookmarks- Update filtering
Pattern sama untuk semua:
// Replace single-client filter
query = query.Where("client_id = ?", clientId)
// With multi-client filter
query = middlewareUtils.AddMultiClientFilter(query, c)
🚀 Quick Start Guide
Step 1: Update Module Clients (Paling Penting)
# 1. Buat file baru
touch app/module/clients/repository/clients.repository.v2.go
touch app/module/clients/service/clients.service.v2.go
touch app/module/clients/controller/clients.controller.v2.go
Step 2: Create UserClientAccess Module
# 2. Buat module baru
mkdir -p app/module/user_client_access/{controller,service,repository,request,response}
# Generate files (atau copy template)
Step 3: Update Existing Modules Bertahap
Update per module, testing setiap perubahan:
- ✅ Update
articles(most used) - ✅ Update
users - ✅ Update other modules one by one
📝 Template untuk Update Repository
package repository
import (
"netidhub-saas-be/app/database/entity"
middlewareUtils "netidhub-saas-be/utils/middleware"
"github.com/gofiber/fiber/v2"
"gorm.io/gorm"
)
type Repository struct {
DB *gorm.DB
}
// OLD VERSION (single-client)
func (r *Repository) GetAllOld(clientId *uuid.UUID, req request.QueryRequest) ([]entity.Model, error) {
query := r.DB.Model(&entity.Model{})
if clientId != nil {
query = query.Where("client_id = ?", clientId)
}
var results []entity.Model
query.Find(&results)
return results, nil
}
// NEW VERSION (multi-client)
func (r *Repository) GetAll(c *fiber.Ctx, req request.QueryRequest) ([]entity.Model, error) {
query := r.DB.Model(&entity.Model{})
// ✨ One line - auto multi-client filtering!
query = middlewareUtils.AddMultiClientFilter(query, c)
// Rest of your existing logic
var results []entity.Model
query.Find(&results)
return results, nil
}
📝 Template untuk Update Service
package service
import (
customMiddleware "netidhub-saas-be/app/middleware"
clientUtils "netidhub-saas-be/utils/client"
"github.com/gofiber/fiber/v2"
)
type Service struct {
repo Repository
}
// Before creating/updating, validate client access
func (s *Service) Create(c *fiber.Ctx, req request.CreateRequest) error {
userId := c.Locals(customMiddleware.UserIDContextKey).(uint)
isSuperAdmin := customMiddleware.IsSuperAdmin(c)
// If user specified a client, verify access
if req.ClientId != nil {
hasAccess, err := clientUtils.HasAccessToClient(
s.repo.DB,
userId,
*req.ClientId,
isSuperAdmin,
)
if err != nil || !hasAccess {
return fiber.NewError(403, "No access to this client")
}
}
// Continue with creation
return s.repo.Create(req)
}
📝 Template untuk Update Controller
package controller
import (
customMiddleware "netidhub-saas-be/app/middleware"
"github.com/gofiber/fiber/v2"
)
type Controller struct {
service Service
}
// List with multi-client support
func (ctrl *Controller) GetAll(c *fiber.Ctx) error {
var req request.QueryRequest
c.QueryParser(&req)
// Service/Repository will handle multi-client filtering
results, err := ctrl.service.GetAll(c, req)
if err != nil {
return c.Status(500).JSON(fiber.Map{
"success": false,
"message": "Failed to retrieve data",
})
}
// Show current context info (helpful for debugging)
isSuperAdmin := customMiddleware.IsSuperAdmin(c)
accessibleClients := customMiddleware.GetAccessibleClientIDs(c)
return c.JSON(fiber.Map{
"success": true,
"data": results,
"meta": fiber.Map{
"is_super_admin": isSuperAdmin,
"accessible_clients_count": len(accessibleClients),
},
})
}
✅ Testing Checklist
Untuk setiap module yang diupdate:
- Super Admin bisa lihat semua data (no client filter)
- Multi-client user hanya lihat data dari accessible clients
- Single-client user hanya lihat data dari 1 client (backward compat)
- Create data dengan client_id validation
- Update data dengan access check
- Delete data dengan access check
- Filter by client_id works correctly
- Performance tidak menurun significant
📊 Progress Tracking
| Module | Priority | Status | Updated By | Date |
|---|---|---|---|---|
| clients | P1 | 🟡 In Progress | - | - |
| users | P1 | ⚪ Not Started | - | - |
| user_client_access | P1 | ⚪ Not Started | - | - |
| articles | P2 | ⚪ Not Started | - | - |
| user_roles | P2 | ⚪ Not Started | - | - |
| user_levels | P2 | ⚪ Not Started | - | - |
| schedules | P3 | ⚪ Not Started | - | - |
| feedbacks | P3 | ⚪ Not Started | - | - |
| subscriptions | P3 | ⚪ Not Started | - | - |
Legend:
- ⚪ Not Started
- 🟡 In Progress
- 🟢 Completed
- 🔴 Blocked
🆘 Need Help?
Jika stuck atau ada pertanyaan:
- Lihat
docs/examples/articles_controller_example.gountuk contoh lengkap - Lihat
docs/MULTI_CLIENT_ACCESS_GUIDE.mduntuk penjelasan konsep - Check
docs/IMPLEMENTATION_SUMMARY.mduntuk overview
🎯 Estimated Timeline
- Week 1: Update module
clients+ Createuser_client_accessmodule - Week 2: Update module
users+articles - Week 3: Update remaining P2 modules
- Week 4: Update P3 modules + Testing
Total: ~1 month untuk full implementation semua modules.
Bisa lebih cepat jika dikerjakan parallel atau prioritas hanya module penting saja.