11package user
22
33import (
4+ "api-shiners/pkg/auth"
5+ "api-shiners/pkg/config"
6+ "api-shiners/pkg/entities"
47 "context"
58 "encoding/json"
9+ "errors"
610 "fmt"
7- "log"
811 "time"
912
10- "api-shiners/pkg/config"
11- "api-shiners/pkg/entities"
12-
1313 "github.com/google/uuid"
1414)
1515
1616type UserService interface {
1717 GetAllUsers () ([]entities.User , error )
1818 GetUserByID (id uuid.UUID ) (entities.User , error )
19+ SetUserRole (ctx context.Context , userID uuid.UUID , roleName string ) (* entities.User , error )
1920}
2021
2122type userService struct {
2223 userRepo UserRepository
24+ authRepo auth.AuthRepository
2325}
2426
25- func NewUserService (userRepo UserRepository ) UserService {
26- return & userService {userRepo : userRepo }
27+ // ✅ Constructor tunggal — wajib dipakai
28+ func NewUserService (userRepo UserRepository , authRepo auth.AuthRepository ) UserService {
29+ return & userService {
30+ userRepo : userRepo ,
31+ authRepo : authRepo ,
32+ }
2733}
2834
2935// ===== GET ALL USERS (dengan caching Redis opsional) =====
@@ -33,15 +39,13 @@ func (s *userService) GetAllUsers() ([]entities.User, error) {
3339
3440 var users []entities.User
3541
36- // 🔹 Coba ambil dari Redis (jika aktif)
42+ // 🔹 Coba ambil dari Redis
3743 if config .RedisClient != nil {
3844 val , err := config .RedisClient .Get (ctx , cacheKey ).Result ()
3945 if err == nil && val != "" {
4046 if err := json .Unmarshal ([]byte (val ), & users ); err == nil {
4147 return users , nil
4248 }
43- } else if err != nil && err .Error () != "redis: client is closed" {
44- log .Println ("⚠️ Redis not available or not running, skip caching..." )
4549 }
4650 }
4751
@@ -51,51 +55,83 @@ func (s *userService) GetAllUsers() ([]entities.User, error) {
5155 return nil , err
5256 }
5357
54- // 🔹 Simpan ke cache (jika Redis aktif)
58+ // 🔹 Simpan ke Redis
5559 if config .RedisClient != nil {
5660 data , _ := json .Marshal (users )
57- err := config .RedisClient .Set (ctx , cacheKey , data , 5 * time .Minute ).Err ()
58- if err != nil {
59- log .Println ("⚠️ Failed to cache users:" , err )
60- }
61+ config .RedisClient .Set (ctx , cacheKey , data , 5 * time .Minute )
6162 }
6263
6364 return users , nil
6465}
6566
66- // ===== GET USER BY ID (dengan caching Redis opsional) =====
67+ // ===== GET USER BY ID =====
6768func (s * userService ) GetUserByID (id uuid.UUID ) (entities.User , error ) {
6869 ctx := context .Background ()
6970 cacheKey := fmt .Sprintf ("user:%s" , id .String ())
7071
7172 var user entities.User
7273
73- // 🔹 Coba ambil dari Redis (jika aktif)
7474 if config .RedisClient != nil {
7575 val , err := config .RedisClient .Get (ctx , cacheKey ).Result ()
7676 if err == nil && val != "" {
7777 if err := json .Unmarshal ([]byte (val ), & user ); err == nil {
7878 return user , nil
7979 }
80- } else if err != nil && err .Error () != "redis: client is closed" {
81- log .Println ("⚠️ Redis not available or not running, skip caching..." )
8280 }
8381 }
8482
85- // 🔹 Ambil dari DB
8683 user , err := s .userRepo .GetByID (id )
8784 if err != nil {
8885 return entities.User {}, err
8986 }
9087
91- // 🔹 Simpan ke Redis (jika aktif)
9288 if config .RedisClient != nil {
9389 data , _ := json .Marshal (user )
94- err := config .RedisClient .Set (ctx , cacheKey , data , 10 * time .Minute ).Err ()
95- if err != nil {
96- log .Println ("⚠️ Failed to cache user:" , err )
97- }
90+ config .RedisClient .Set (ctx , cacheKey , data , 10 * time .Minute )
9891 }
9992
10093 return user , nil
10194}
95+
96+ // ===== SET USER ROLE =====
97+ func (s * userService ) SetUserRole (ctx context.Context , userID uuid.UUID , roleName string ) (* entities.User , error ) {
98+ // Cek dependency dulu
99+ if s .userRepo == nil || s .authRepo == nil {
100+ return nil , errors .New ("userRepo atau authRepo belum diinisialisasi dengan benar" )
101+ }
102+
103+ // 1. Cari user berdasarkan ID
104+ user , err := s .userRepo .GetByID (userID )
105+ if err != nil {
106+ return nil , errors .New ("user not found" )
107+ }
108+
109+ // 2. Cari role berdasarkan nama
110+ role , err := s .authRepo .FindRoleByName (ctx , roleName )
111+ if err != nil {
112+ return nil , errors .New ("role not found" )
113+ }
114+
115+ // 3. Hapus semua role lama user
116+ if err := s .authRepo .RemoveAllRolesFromUser (ctx , user .ID ); err != nil {
117+ return nil , fmt .Errorf ("failed to clear old roles: %v" , err )
118+ }
119+
120+ // 4. Tambahkan role baru
121+ userRole := & entities.UserRole {
122+ UserID : user .ID ,
123+ RoleID : role .ID ,
124+ }
125+ if err := s .authRepo .AssignUserRole (ctx , userRole ); err != nil {
126+ return nil , err
127+ }
128+
129+ // 5. Ambil ulang user untuk dikembalikan (dengan role terbaru)
130+ updatedUser , err := s .userRepo .GetByID (userID )
131+ if err != nil {
132+ return nil , err
133+ }
134+
135+ return & updatedUser , nil
136+ }
137+
0 commit comments