# 📋 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:**
```go
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:**
```go
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:**
```go
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()` - Use `AddMultiClientFilter()`
- [ ] Update repository `FindOne()` - Validate client access
- [ ] Update service untuk validate user has access to target client
- [ ] Update controller untuk support `?client_id=xxx` filter

**Changes Needed:**
```go
// 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 filtering
- `feedbacks` - Update filtering  
- `subscriptions` - Update filtering
- `magazines` - Update filtering
- `advertisements` - Update filtering
- `article_categories` - Update filtering
- `bookmarks` - Update filtering

**Pattern sama untuk semua:**
```go
// 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)

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

```bash
# 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:
1. ✅ Update `articles` (most used)
2. ✅ Update `users`
3. ✅ Update other modules one by one

---

## 📝 Template untuk Update Repository

```go
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

```go
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

```go
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:
1. Lihat `docs/examples/articles_controller_example.go` untuk contoh lengkap
2. Lihat `docs/MULTI_CLIENT_ACCESS_GUIDE.md` untuk penjelasan konsep
3. Check `docs/IMPLEMENTATION_SUMMARY.md` untuk overview

---

## 🎯 Estimated Timeline

- **Week 1:** Update module `clients` + Create `user_client_access` module
- **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.
