create province
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
teguh nugroho 2026-08-17 14:22:22 +07:00
parent fc232890a2
commit 1783bb2e7d
6 changed files with 104 additions and 10 deletions

View File

@ -3,6 +3,11 @@ package dto
type CreateProvinceRequest struct {
Name string `json:"name" binding:"required,min=2"`
}
type CreateProvinceResponse struct {
ID string `json:"id"`
Name string `json:"name"`
MerchantID *string `json:"merchant_id"`
}
type UpdateProvinceRequest struct {
Name string `json:"name" binding:"required,min=2"`

View File

@ -115,16 +115,21 @@ func (h *ProvinceHandler) Create(c *gin.Context) {
response.Error(c, http.StatusUnauthorized, err.Error())
return
}
var merchantid *string = nil
if userid.UsersRole_Relation.RoleKey != "SPM" {
merchantid = userid.MerchantID
}
createdBy := userid.ID
u := usecases.NewProvinceUsecase(h.Helper, *userid)
province, err := u.Create(req.Name, createdBy)
province, err := u.Create(req.Name, createdBy, merchantid)
if err != nil {
response.Error(c, http.StatusInternalServerError, err.Error())
return
}
response.Created(c, province)
var responseDTO dto.CreateProvinceResponse
h.Helper.MapStructToStruct(province, "json", &responseDTO, "json")
response.Created(c, responseDTO)
}
func (h *ProvinceHandler) Update(c *gin.Context) {

View File

@ -12,7 +12,7 @@ type ProvinceUsecaseInterface interface {
GetAll(page int, limit int) ([]domain.Province, int64, error)
GetList(dto.DataTableRequest) (dto.DataTableResponse, error)
GetByID(id string) (domain.Province, error)
Create(name string, createdBy string) (domain.Province, error)
Create(name string, createdBy string, merchantid *string) (domain.Province, error)
Update(id string, name string, updatedBy string) (domain.Province, error)
Delete(id string) error
}
@ -84,14 +84,15 @@ func (u *ProvinceUsecase) GetByID(id string) (domain.Province, error) {
return province, nil
}
func (u *ProvinceUsecase) Create(name string, createdBy string) (domain.Province, error) {
func (u *ProvinceUsecase) Create(name string, createdBy string, merchantid *string) (domain.Province, error) {
now := time.Now()
province := domain.Province{
Name: &name,
CreatedBy: &createdBy,
CreatedOn: &now,
UpdatedBy: &createdBy,
UpdatedOn: &now,
Name: &name,
MerchantID: merchantid,
CreatedBy: &createdBy,
CreatedOn: &now,
UpdatedBy: &createdBy,
UpdatedOn: &now,
}
db := u.Helper.GetDB("master")

View File

@ -5,6 +5,7 @@ import (
"cargo-erp-backend/internal/database"
"cargo-erp-backend/internal/domain"
"encoding/json"
"reflect"
"github.com/redis/go-redis/v9"
"go.uber.org/zap"
@ -23,6 +24,7 @@ type HelperInterface interface {
StructTobyte(data interface{}) ([]byte, error)
CloneStructWithoutField(input interface{}, field string) (map[string]interface{}, error)
GetAuthInfo(authinfo string) (*domain.User, error)
MapStructToStruct(source interface{}, source_tag string, target interface{}, target_tag string)
}
type Helper struct {
Conf config.ConfigInterface
@ -101,3 +103,45 @@ func (h *Helper) GetAuthInfo(authinfo string) (*domain.User, error) {
}
return &auth, nil
}
func (h *Helper) MapStructToStruct(source interface{}, source_tag string, target interface{}, target_tag string) {
srcVal := reflect.ValueOf(source)
if srcVal.Kind() == reflect.Ptr {
srcVal = srcVal.Elem()
}
srcType := srcVal.Type()
// 1. Kumpulkan data dari struct asal ke dalam map [nama_tag] -> value
jsonMap := make(map[string]reflect.Value)
for i := 0; i < srcVal.NumField(); i++ {
jsonTag := srcType.Field(i).Tag.Get(source_tag)
if jsonTag != "" && jsonTag != "-" {
jsonMap[jsonTag] = srcVal.Field(i)
}
}
tgtVal := reflect.ValueOf(target)
if tgtVal.Kind() != reflect.Ptr {
panic("target harus berupa pointer ke struct")
}
tgtVal = tgtVal.Elem()
tgtType := tgtVal.Type()
// 2. Isi struct tujuan dengan mencocokkan tag 'column'
for i := 0; i < tgtVal.NumField(); i++ {
columnTag := tgtType.Field(i).Tag.Get(target_tag)
if columnTag == "" {
continue
}
// Jika ada data di map yang cocok dengan tag column, pindahkan nilainya
if srcFieldVal, tersedia := jsonMap[columnTag]; tersedia {
targetField := tgtVal.Field(i)
// Pastikan tipe datanya sama atau bisa saling di-assign untuk menghindari panic
if targetField.CanSet() && srcFieldVal.Type().AssignableTo(targetField.Type()) {
targetField.Set(srcFieldVal)
}
}
}
}

View File

@ -667,3 +667,23 @@
{"level":"info","ts":"2026-08-17T13:35:11.788+0700","caller":"middleware/auth.go:62","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY5NTA4MTQsImlhdCI6MTc4Njk0NzIxNH0.HxvKTQ-yfKIN9Ur80sK7U_5XCKJpOuMeyKLw8FMfvdI"}
{"level":"info","ts":"2026-08-17T13:35:11.832+0700","caller":"middleware/auth.go:90","msg":"Set Auth : {\"blocked\":false,\"blocked_notes\":null,\"citys_relation\":null,\"created_by\":null,\"created_on\":\"2026-08-11T20:29:00.18279Z\",\"districts_relation\":null,\"email\":\"crackers.biscuits@gmail.com\",\"id\":\"19ff1031a11c0c013f60044f56\",\"is_active\":true,\"merchant_id\":null,\"merchant_relation\":null,\"merchants_relation\":null,\"nick_name\":\"Super Admin\",\"postal_codes_relation\":null,\"provinces_relation\":null,\"subdistricts_relation\":null,\"updated_by\":null,\"updated_on\":\"2026-08-11T20:29:00.18279Z\",\"users_role_id\":\"19fe813c54d12bf48f1d7c710e\",\"users_role_relation\":{\"created_by\":null,\"created_on\":\"2026-08-10T02:50:37.639811Z\",\"id\":\"19fe813c54d12bf48f1d7c710e\",\"merchant_id\":null,\"merchant_relation\":{\"active\":null,\"additional_information\":null,\"address\":null,\"city_id\":null,\"city_relation\":null,\"citys_relation\":null,\"created_by\":null,\"created_by_relation\":null,\"created_on\":null,\"district_id\":null,\"district_relation\":null,\"districts_relation\":null,\"email\":null,\"id\":\"\",\"modas_relation\":null,\"name\":null,\"package_types_relation\":null,\"postal_code\":null,\"postal_codes_relation\":null,\"province_id\":null,\"province_relation\":null,\"provinces_relation\":null,\"subdistrict_id\":null,\"subdistrict_relation\":null,\"subdistricts_relation\":null,\"telp\":null,\"updated_by\":null,\"updated_on\":null,\"users_roless_relation\":null,\"userss_relation\":null},\"name\":\"Super Admin\",\"role_key\":\"SPM\",\"updated_by\":null,\"updated_on\":\"2026-08-10T02:50:37.639811Z\",\"userss_relation\":null}}"}
{"level":"info","ts":"2026-08-17T13:35:11.902+0700","caller":"handlers/handlers.go:66","msg":"Request Success","status":200,"method":"POST","path":"/master-data/provinces/list","query":"","ip":"127.0.0.1","latency":0.116133708,"user-agent":"Apidog/1.0.0 (https://apidog.com)"}
{"level":"info","ts":"2026-08-17T13:40:44.901+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-17T13:40:44.995+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-17T13:40:44.995+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-17T13:40:45.068+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-17T13:40:45.184+0700","caller":"handlers/handlers.go:113","msg":"Starting Apps"}
{"level":"info","ts":"2026-08-17T13:40:49.381+0700","caller":"handlers/handlers.go:66","msg":"Request Success","status":200,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.2054965,"user-agent":"Apidog/1.0.0 (https://apidog.com)"}
{"level":"info","ts":"2026-08-17T13:40:53.476+0700","caller":"middleware/auth.go:62","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTA0YzE2NTIyYTIyNTJjYmFjYTI0ZCIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwNGMxNjUyMmEyMjUyY2JhY2EyNGQiLCJleHAiOjE3ODY5NTI0NDksImlhdCI6MTc4Njk0ODg0OX0.Zl6rY1vRR7pf7xkq3YU7L2cfNUsth9ZriJ3ANZVh14g"}
{"level":"info","ts":"2026-08-17T13:40:53.498+0700","caller":"middleware/auth.go:90","msg":"Set Auth : {\"blocked\":false,\"blocked_notes\":null,\"citys_relation\":null,\"created_by\":null,\"created_on\":\"2026-08-11T20:30:48.554654Z\",\"districts_relation\":null,\"email\":\"gcx@gmail.com\",\"id\":\"19ff104c16522a2252cbaca24d\",\"is_active\":true,\"merchant_id\":\"19ff111bca6c2c382d9eb43b3c\",\"merchant_relation\":null,\"merchants_relation\":null,\"nick_name\":\"Administrator\",\"postal_codes_relation\":null,\"provinces_relation\":null,\"subdistricts_relation\":null,\"updated_by\":null,\"updated_on\":\"2026-08-11T20:30:48.554654Z\",\"users_role_id\":\"19fe814c5350d67814c3e6057c\",\"users_role_relation\":{\"created_by\":null,\"created_on\":\"2026-08-10T02:51:43.16495Z\",\"id\":\"19fe814c5350d67814c3e6057c\",\"merchant_id\":null,\"merchant_relation\":{\"active\":null,\"additional_information\":null,\"address\":null,\"city_id\":null,\"city_relation\":null,\"citys_relation\":null,\"created_by\":null,\"created_by_relation\":null,\"created_on\":null,\"district_id\":null,\"district_relation\":null,\"districts_relation\":null,\"email\":null,\"id\":\"\",\"modas_relation\":null,\"name\":null,\"package_types_relation\":null,\"postal_code\":null,\"postal_codes_relation\":null,\"province_id\":null,\"province_relation\":null,\"provinces_relation\":null,\"subdistrict_id\":null,\"subdistrict_relation\":null,\"subdistricts_relation\":null,\"telp\":null,\"updated_by\":null,\"updated_on\":null,\"users_roless_relation\":null,\"userss_relation\":null},\"name\":\"Administrator\",\"role_key\":\"ADM_MERCHANT\",\"updated_by\":null,\"updated_on\":\"2026-08-10T02:51:43.16495Z\",\"userss_relation\":null}}"}
{"level":"info","ts":"2026-08-17T13:40:53.576+0700","caller":"handlers/handlers.go:66","msg":"Request Success","status":200,"method":"POST","path":"/master-data/provinces/list","query":"","ip":"127.0.0.1","latency":0.10019525,"user-agent":"Apidog/1.0.0 (https://apidog.com)"}
{"level":"info","ts":"2026-08-17T13:42:08.490+0700","caller":"middleware/auth.go:62","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTA0YzE2NTIyYTIyNTJjYmFjYTI0ZCIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwNGMxNjUyMmEyMjUyY2JhY2EyNGQiLCJleHAiOjE3ODY5NTI0NDksImlhdCI6MTc4Njk0ODg0OX0.Zl6rY1vRR7pf7xkq3YU7L2cfNUsth9ZriJ3ANZVh14g"}
{"level":"info","ts":"2026-08-17T13:42:08.517+0700","caller":"middleware/auth.go:90","msg":"Set Auth : {\"blocked\":false,\"blocked_notes\":null,\"citys_relation\":null,\"created_by\":null,\"created_on\":\"2026-08-11T20:30:48.554654Z\",\"districts_relation\":null,\"email\":\"gcx@gmail.com\",\"id\":\"19ff104c16522a2252cbaca24d\",\"is_active\":true,\"merchant_id\":\"19ff111bca6c2c382d9eb43b3c\",\"merchant_relation\":null,\"merchants_relation\":null,\"nick_name\":\"Administrator\",\"postal_codes_relation\":null,\"provinces_relation\":null,\"subdistricts_relation\":null,\"updated_by\":null,\"updated_on\":\"2026-08-11T20:30:48.554654Z\",\"users_role_id\":\"19fe814c5350d67814c3e6057c\",\"users_role_relation\":{\"created_by\":null,\"created_on\":\"2026-08-10T02:51:43.16495Z\",\"id\":\"19fe814c5350d67814c3e6057c\",\"merchant_id\":null,\"merchant_relation\":{\"active\":null,\"additional_information\":null,\"address\":null,\"city_id\":null,\"city_relation\":null,\"citys_relation\":null,\"created_by\":null,\"created_by_relation\":null,\"created_on\":null,\"district_id\":null,\"district_relation\":null,\"districts_relation\":null,\"email\":null,\"id\":\"\",\"modas_relation\":null,\"name\":null,\"package_types_relation\":null,\"postal_code\":null,\"postal_codes_relation\":null,\"province_id\":null,\"province_relation\":null,\"provinces_relation\":null,\"subdistrict_id\":null,\"subdistrict_relation\":null,\"subdistricts_relation\":null,\"telp\":null,\"updated_by\":null,\"updated_on\":null,\"users_roless_relation\":null,\"userss_relation\":null},\"name\":\"Administrator\",\"role_key\":\"ADM_MERCHANT\",\"updated_by\":null,\"updated_on\":\"2026-08-10T02:51:43.16495Z\",\"userss_relation\":null}}"}
{"level":"info","ts":"2026-08-17T13:42:08.626+0700","caller":"handlers/handlers.go:66","msg":"Request Success","status":201,"method":"POST","path":"/master-data/provinces/","query":"","ip":"127.0.0.1","latency":0.136740375,"user-agent":"Apidog/1.0.0 (https://apidog.com)"}
{"level":"info","ts":"2026-08-17T14:21:30.029+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-17T14:21:30.117+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-17T14:21:30.117+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-17T14:21:30.184+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-17T14:21:30.291+0700","caller":"handlers/handlers.go:113","msg":"Starting Apps"}
{"level":"info","ts":"2026-08-17T14:21:37.526+0700","caller":"middleware/auth.go:62","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTA0YzE2NTIyYTIyNTJjYmFjYTI0ZCIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwNGMxNjUyMmEyMjUyY2JhY2EyNGQiLCJleHAiOjE3ODY5NTI0NDksImlhdCI6MTc4Njk0ODg0OX0.Zl6rY1vRR7pf7xkq3YU7L2cfNUsth9ZriJ3ANZVh14g"}
{"level":"info","ts":"2026-08-17T14:21:37.550+0700","caller":"middleware/auth.go:90","msg":"Set Auth : {\"blocked\":false,\"blocked_notes\":null,\"citys_relation\":null,\"created_by\":null,\"created_on\":\"2026-08-11T20:30:48.554654Z\",\"districts_relation\":null,\"email\":\"gcx@gmail.com\",\"id\":\"19ff104c16522a2252cbaca24d\",\"is_active\":true,\"merchant_id\":\"19ff111bca6c2c382d9eb43b3c\",\"merchant_relation\":null,\"merchants_relation\":null,\"nick_name\":\"Administrator\",\"postal_codes_relation\":null,\"provinces_relation\":null,\"subdistricts_relation\":null,\"updated_by\":null,\"updated_on\":\"2026-08-11T20:30:48.554654Z\",\"users_role_id\":\"19fe814c5350d67814c3e6057c\",\"users_role_relation\":{\"created_by\":null,\"created_on\":\"2026-08-10T02:51:43.16495Z\",\"id\":\"19fe814c5350d67814c3e6057c\",\"merchant_id\":null,\"merchant_relation\":{\"active\":null,\"additional_information\":null,\"address\":null,\"city_id\":null,\"city_relation\":null,\"citys_relation\":null,\"created_by\":null,\"created_by_relation\":null,\"created_on\":null,\"district_id\":null,\"district_relation\":null,\"districts_relation\":null,\"email\":null,\"id\":\"\",\"modas_relation\":null,\"name\":null,\"package_types_relation\":null,\"postal_code\":null,\"postal_codes_relation\":null,\"province_id\":null,\"province_relation\":null,\"provinces_relation\":null,\"subdistrict_id\":null,\"subdistrict_relation\":null,\"subdistricts_relation\":null,\"telp\":null,\"updated_by\":null,\"updated_on\":null,\"users_roless_relation\":null,\"userss_relation\":null},\"name\":\"Administrator\",\"role_key\":\"ADM_MERCHANT\",\"updated_by\":null,\"updated_on\":\"2026-08-10T02:51:43.16495Z\",\"userss_relation\":null}}"}
{"level":"info","ts":"2026-08-17T14:21:37.621+0700","caller":"handlers/handlers.go:66","msg":"Request Success","status":201,"method":"POST","path":"/master-data/provinces/","query":"","ip":"127.0.0.1","latency":0.095641333,"user-agent":"Apidog/1.0.0 (https://apidog.com)"}

View File

@ -3339,3 +3339,22 @@
{"level":"info","ts":"2026-08-17T13:35:11.867+0700","caller":"logger/database.go:90","msg":"[GORM] query execution","line":"/Users/teguh/Documents/project/cargo/cargo-erp-deploy/app/backend/pkg/datatable/datatable.go:30","elapsed":0.023576584,"rows":1,"sql":"SELECT count(*) FROM \"province\" LEFT JOIN merchant ON province.merchant_id=merchant.id"}
{"level":"info","ts":"2026-08-17T13:35:11.879+0700","caller":"logger/database.go:90","msg":"[GORM] query execution","line":"/Users/teguh/Documents/project/cargo/cargo-erp-deploy/app/backend/pkg/datatable/datatable.go:65","elapsed":0.010291833,"rows":1,"sql":"SELECT count(*) FROM \"province\" LEFT JOIN merchant ON province.merchant_id=merchant.id"}
{"level":"info","ts":"2026-08-17T13:35:11.902+0700","caller":"logger/database.go:90","msg":"[GORM] query execution","line":"/Users/teguh/Documents/project/cargo/cargo-erp-deploy/app/backend/pkg/datatable/datatable.go:73","elapsed":0.022881709,"rows":10,"sql":"SELECT province.name AS name,merchant.id AS merchant_id,province.id AS id FROM \"province\" LEFT JOIN merchant ON province.merchant_id=merchant.id ORDER BY province.name ASC LIMIT 10 OFFSET 10"}
{"level":"info","ts":"2026-08-17T13:40:45.068+0700","caller":"database/redis.go:34","msg":"Parse config master"}
{"level":"info","ts":"2026-08-17T13:40:45.069+0700","caller":"database/redis.go:49","msg":"Connecting to Redis master"}
{"level":"info","ts":"2026-08-17T13:40:45.122+0700","caller":"database/redis.go:62","msg":"Connected"}
{"level":"info","ts":"2026-08-17T13:40:45.122+0700","caller":"database/redis.go:34","msg":"Parse config slave"}
{"level":"info","ts":"2026-08-17T13:40:45.122+0700","caller":"database/redis.go:49","msg":"Connecting to Redis slave"}
{"level":"info","ts":"2026-08-17T13:40:45.184+0700","caller":"database/redis.go:62","msg":"Connected"}
{"level":"info","ts":"2026-08-17T13:40:49.286+0700","caller":"logger/database.go:90","msg":"[GORM] query execution","line":"/Users/teguh/Documents/project/cargo/cargo-erp-deploy/app/backend/internal/usecases/auth.go:29","elapsed":0.039392583,"rows":1,"sql":"SELECT * FROM \"users_roles\" WHERE \"users_roles\".\"id\" = '19fe814c5350d67814c3e6057c'"}
{"level":"info","ts":"2026-08-17T13:40:49.288+0700","caller":"logger/database.go:90","msg":"[GORM] query execution","line":"/Users/teguh/Documents/project/cargo/cargo-erp-deploy/app/backend/internal/usecases/auth.go:29","elapsed":0.111769708,"rows":1,"sql":"SELECT * FROM \"users\" WHERE email='gcx@gmail.com'"}
{"level":"info","ts":"2026-08-17T13:40:53.540+0700","caller":"logger/database.go:90","msg":"[GORM] query execution","line":"/Users/teguh/Documents/project/cargo/cargo-erp-deploy/app/backend/pkg/datatable/datatable.go:30","elapsed":0.040591333,"rows":1,"sql":"SELECT count(*) FROM \"province\" LEFT JOIN merchant ON province.merchant_id=merchant.id"}
{"level":"info","ts":"2026-08-17T13:40:53.552+0700","caller":"logger/database.go:90","msg":"[GORM] query execution","line":"/Users/teguh/Documents/project/cargo/cargo-erp-deploy/app/backend/pkg/datatable/datatable.go:65","elapsed":0.010961375,"rows":1,"sql":"SELECT count(*) FROM \"province\" LEFT JOIN merchant ON province.merchant_id=merchant.id"}
{"level":"info","ts":"2026-08-17T13:40:53.576+0700","caller":"logger/database.go:90","msg":"[GORM] query execution","line":"/Users/teguh/Documents/project/cargo/cargo-erp-deploy/app/backend/pkg/datatable/datatable.go:73","elapsed":0.023504625,"rows":10,"sql":"SELECT province.name AS name,merchant.id AS merchant_id,province.id AS id FROM \"province\" LEFT JOIN merchant ON province.merchant_id=merchant.id ORDER BY province.name ASC LIMIT 10"}
{"level":"info","ts":"2026-08-17T13:42:08.624+0700","caller":"logger/database.go:90","msg":"[GORM] query execution","line":"/Users/teguh/Documents/project/cargo/cargo-erp-deploy/app/backend/internal/usecases/province.go:100","elapsed":0.092329541,"rows":1,"sql":"INSERT INTO \"province\" (\"name\",\"created_by\",\"created_on\",\"updated_by\",\"updated_on\",\"merchant_id\") VALUES ('tambahan','19ff104c16522a2252cbaca24d','2026-08-17 13:42:08.521','19ff104c16522a2252cbaca24d','2026-08-17 13:42:08.521','19ff111bca6c2c382d9eb43b3c') RETURNING \"id\""}
{"level":"info","ts":"2026-08-17T14:21:30.185+0700","caller":"database/redis.go:34","msg":"Parse config master"}
{"level":"info","ts":"2026-08-17T14:21:30.185+0700","caller":"database/redis.go:49","msg":"Connecting to Redis master"}
{"level":"info","ts":"2026-08-17T14:21:30.235+0700","caller":"database/redis.go:62","msg":"Connected"}
{"level":"info","ts":"2026-08-17T14:21:30.235+0700","caller":"database/redis.go:34","msg":"Parse config slave"}
{"level":"info","ts":"2026-08-17T14:21:30.235+0700","caller":"database/redis.go:49","msg":"Connecting to Redis slave"}
{"level":"info","ts":"2026-08-17T14:21:30.290+0700","caller":"database/redis.go:62","msg":"Connected"}
{"level":"info","ts":"2026-08-17T14:21:37.620+0700","caller":"logger/database.go:90","msg":"[GORM] query execution","line":"/Users/teguh/Documents/project/cargo/cargo-erp-deploy/app/backend/internal/usecases/province.go:100","elapsed":0.064875875,"rows":1,"sql":"INSERT INTO \"province\" (\"name\",\"created_by\",\"created_on\",\"updated_by\",\"updated_on\",\"merchant_id\") VALUES ('tambahan','19ff104c16522a2252cbaca24d','2026-08-17 14:21:37.555','19ff104c16522a2252cbaca24d','2026-08-17 14:21:37.555','19ff111bca6c2c382d9eb43b3c') RETURNING \"id\""}