coba last
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
teguh nugroho 2026-08-22 21:20:28 +07:00
parent 43bb3e1dd0
commit 216825cb2f
32 changed files with 7545 additions and 323 deletions

View File

@ -5,9 +5,7 @@ import (
"cargo-erp-backend/internal/database" "cargo-erp-backend/internal/database"
"cargo-erp-backend/internal/handlers" "cargo-erp-backend/internal/handlers"
"cargo-erp-backend/internal/logger" "cargo-erp-backend/internal/logger"
"cargo-erp-backend/migrations"
"cargo-erp-backend/pkg/helpers" "cargo-erp-backend/pkg/helpers"
"os"
) )
func main() { func main() {
@ -25,16 +23,12 @@ func main() {
db := database.NewDatabase(AppConfig, DBLogger, APPLogger) db := database.NewDatabase(AppConfig, DBLogger, APPLogger)
db.Connect() db.Connect()
db.RegisterCallback() db.RegisterCallback()
//
migrations.GenerateModel(nil, db.Get("master"))
os.Exit(0)
//redis //redis
redisDB := database.NewRedis(AppConfig, DBLogger) redisDB := database.NewRedis(AppConfig, DBLogger)
redisDB.Connect() redisDB.Connect()
redisDB.RegisterCallback() redisDB.RegisterCallback()
//
Helper := helpers.NewHelper(AppConfig, db, APPLogger, redisDB) Helper := helpers.NewHelper(AppConfig, db, APPLogger, redisDB)
app := handlers.NewHandlers(Helper) app := handlers.NewHandlers(Helper)
app.Run() app.Run()

View File

@ -1,10 +1,18 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package domain package domain
import "time" import (
"time"
)
const TableNameBasicPricing = "basic_pricing" const TableNameBasicPricing = "basic_pricing"
// BasicPricing mapped from table <basic_pricing>
type BasicPricing struct { type BasicPricing struct {
Name *string `gorm:"column:name;type:character varying(255)" json:"name"`
ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"` ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"`
ProvinceSourceID *string `gorm:"column:province_source_id;type:character(26);index:basic_pricing_province_source_id_idx,priority:1" json:"province_source_id"` ProvinceSourceID *string `gorm:"column:province_source_id;type:character(26);index:basic_pricing_province_source_id_idx,priority:1" json:"province_source_id"`
CitySourceID *string `gorm:"column:city_source_id;type:character(26);index:basic_pricing_city_source_id_idx,priority:1" json:"city_source_id"` CitySourceID *string `gorm:"column:city_source_id;type:character(26);index:basic_pricing_city_source_id_idx,priority:1" json:"city_source_id"`
@ -16,16 +24,31 @@ type BasicPricing struct {
DistrictDestinationID *string `gorm:"column:district_destination_id;type:character(26);index:basic_pricing_district_destination_id_idx,priority:1" json:"district_destination_id"` DistrictDestinationID *string `gorm:"column:district_destination_id;type:character(26);index:basic_pricing_district_destination_id_idx,priority:1" json:"district_destination_id"`
SubdistrictDestinationID *string `gorm:"column:subdistrict_destination_id;type:character(26)" json:"subdistrict_destination_id"` SubdistrictDestinationID *string `gorm:"column:subdistrict_destination_id;type:character(26)" json:"subdistrict_destination_id"`
PostalCodeDestinationID *string `gorm:"column:postal_code_destination_id;type:character(26);index:basic_pricing_postal_code_destination_id_idx,priority:1" json:"postal_code_destination_id"` PostalCodeDestinationID *string `gorm:"column:postal_code_destination_id;type:character(26);index:basic_pricing_postal_code_destination_id_idx,priority:1" json:"postal_code_destination_id"`
MerchantID *string `gorm:"column:merchant_id;type:character(26);index:basic_pricing_merchant_id_idx,priority:1" json:"merchant_id"` MerchantID *string `gorm:"column:merchant_id;type:character(26);index:basic_pricing_area_merchant_id_idx,priority:1" json:"merchant_id"`
CreatedBy *string `gorm:"column:created_by;type:character(26);index:basic_pricing_created_by_idx,priority:1" json:"created_by"` CreatedBy *string `gorm:"column:created_by;type:character(26);index:basic_pricing_area_created_by_idx,priority:1" json:"created_by"`
CreatedOn *time.Time `gorm:"column:created_on;type:timestamp without time zone;default:now()" json:"created_on"` CreatedOn *time.Time `gorm:"column:created_on;type:timestamp without time zone;default:now()" json:"created_on"`
UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"` UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"`
UpdatedOn *time.Time `gorm:"column:updated_on;type:timestamp without time zone;default:now()" json:"updated_on"` UpdatedOn *time.Time `gorm:"column:updated_on;type:timestamp without time zone;default:now()" json:"updated_on"`
PackageTypeID *string `gorm:"column:package_type_id;type:character(26);index:basic_pricing_package_type_id_idx,priority:1" json:"package_type_id"` PackageTypeID *string `gorm:"column:package_type_id;type:character(26);index:basic_pricing_package_type_id_idx,priority:1" json:"package_type_id"`
ModaID *string `gorm:"column:moda_id;type:character(26);index:basic_pricing_moda_id_idx,priority:1" json:"moda_id"` ModaID *string `gorm:"column:moda_id;type:character(26);index:basic_pricing_moda_id_idx,priority:1" json:"moda_id"`
Name *string `gorm:"column:name;type:character varying(255);index:basic_pricing_name_idx,priority:1" json:"name"` CityDestination_Relation *City `gorm:"foreignKey:city_destination_id;references:id" json:"city_destination_relation"`
CitySource_Relation *City `gorm:"foreignKey:city_source_id;references:id" json:"city_source_relation"`
DistrictDestination_Relation *District `gorm:"foreignKey:district_destination_id;references:id" json:"district_destination_relation"`
DistrictSource_Relation *District `gorm:"foreignKey:district_source_id;references:id" json:"district_source_relation"`
Merchant_Relation *Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
Moda_Relation *Moda `gorm:"foreignKey:moda_id;references:id" json:"moda_relation"`
PackageType_Relation *PackageType `gorm:"foreignKey:package_type_id;references:id" json:"package_type_relation"`
PostalCodeDestination_Relation *PostalCode `gorm:"foreignKey:postal_code_destination_id;references:id" json:"postal_code_destination_relation"`
PostalCodeSource_Relation *PostalCode `gorm:"foreignKey:postal_code_source_id;references:id" json:"postal_code_source_relation"`
ProvinceDestination_Relation *Province `gorm:"foreignKey:province_destination_id;references:id" json:"province_destination_relation"`
ProvinceSource_Relation *Province `gorm:"foreignKey:province_source_id;references:id" json:"province_source_relation"`
SubdistrictDestination_Relation *Subdistrict `gorm:"foreignKey:subdistrict_destination_id;references:id" json:"subdistrict_destination_relation"`
SubdistrictSource_Relation *Subdistrict `gorm:"foreignKey:subdistrict_source_id;references:id" json:"subdistrict_source_relation"`
Users_Relation *User `gorm:"foreignKey:created_by;references:id" json:"users_relation"`
BasicPricingComponent_ByBasicPricing_Relation []BasicPricingComponent `gorm:"foreignKey:basic_pricing_id;references:id" json:"basic_pricing_component_by_basic_pricing_relation"`
} }
// TableName BasicPricing's table name
func (*BasicPricing) TableName() string { func (*BasicPricing) TableName() string {
return TableNameBasicPricing return TableNameBasicPricing
} }

View File

@ -1,14 +1,22 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package domain package domain
const TableNameBasicPricingComponent = "basic_pricing_component" const TableNameBasicPricingComponent = "basic_pricing_component"
// BasicPricingComponent mapped from table <basic_pricing_component>
type BasicPricingComponent struct { type BasicPricingComponent struct {
ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"` ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"`
CostComponentID *string `gorm:"column:cost_component_id;type:character(26);index:basic_pricing_component_cost_component_id_idx,priority:1" json:"cost_component_id"` CostComponentID *string `gorm:"column:cost_component_id;type:character(26);index:basic_pricing_component_cost_component_id_idx,priority:1" json:"cost_component_id"`
Value *float32 `gorm:"column:value;type:real" json:"value"` Value *float32 `gorm:"column:value;type:real" json:"value"`
BasicPricingID *string `gorm:"column:basic_pricing_id;type:character(26);index:basic_pricing_component_basic_pricing_id_idx,priority:1" json:"basic_pricing_id"` BasicPricingID *string `gorm:"column:basic_pricing_id;type:character(26);index:basic_pricing_component_basic_pricing_id_idx,priority:1" json:"basic_pricing_id"`
BasicPricing_Relation *BasicPricing `gorm:"foreignKey:basic_pricing_id;references:id" json:"basic_pricing_relation"`
CostComponent_Relation *CostComponent `gorm:"foreignKey:cost_component_id;references:id" json:"cost_component_relation"`
} }
// TableName BasicPricingComponent's table name
func (*BasicPricingComponent) TableName() string { func (*BasicPricingComponent) TableName() string {
return TableNameBasicPricingComponent return TableNameBasicPricingComponent
} }

View File

@ -1,21 +1,38 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package domain package domain
import "time" import (
"time"
)
const TableNameCity = "city" const TableNameCity = "city"
// City mapped from table <city>
type City struct { type City struct {
ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"` ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"`
Name *string `gorm:"column:name;type:character varying(255);index:city_name_idx,priority:1" json:"name"` Name *string `gorm:"column:name;type:character varying(255);index:city_name_idx,priority:1" json:"name"`
ProvinceID *string `gorm:"column:province_id;type:character(26);index:city_province_id_idx,priority:1" json:"province_id"` ProvinceID *string `gorm:"column:province_id;type:character(26);index:city_province_id_idx,priority:1" json:"province_id"`
MerchantID *string `gorm:"column:merchant_id;type:character(26)" json:"merchant_id"`
Port *string `gorm:"column:port;type:character varying(255)" json:"port"`
CreatedBy *string `gorm:"column:created_by;type:character(26);index:city_created_by_idx,priority:1" json:"created_by"` CreatedBy *string `gorm:"column:created_by;type:character(26);index:city_created_by_idx,priority:1" json:"created_by"`
CreatedOn *time.Time `gorm:"column:created_on;type:timestamp without time zone" json:"created_on"` CreatedOn *time.Time `gorm:"column:created_on;type:timestamp without time zone" json:"created_on"`
UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"` UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"`
UpdatedOn *time.Time `gorm:"column:updated_on;type:timestamp without time zone" json:"updated_on"` UpdatedOn *time.Time `gorm:"column:updated_on;type:timestamp without time zone" json:"updated_on"`
MerchantID *string `gorm:"column:merchant_id;type:character(26)" json:"merchant_id"`
Port *string `gorm:"column:port;type:character varying(255)" json:"port"`
BasicPricing_ByCityDestination_Relation []BasicPricing `gorm:"foreignKey:city_destination_id;references:id" json:"basic_pricing_by_city_destination_relation"`
BasicPricing_ByCitySource_Relation []BasicPricing `gorm:"foreignKey:city_source_id;references:id" json:"basic_pricing_by_city_source_relation"`
Merchant_Relation *Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
Province_Relation *Province `gorm:"foreignKey:province_id;references:id" json:"province_relation"`
Users_Relation *User `gorm:"foreignKey:created_by;references:id" json:"users_relation"`
District_ByCity_Relation []District `gorm:"foreignKey:city_id;references:id" json:"district_by_city_relation"`
Merchant_ByCity_Relation []Merchant `gorm:"foreignKey:city_id;references:id" json:"merchant_by_city_relation"`
PostalCode_ByCity_Relation []PostalCode `gorm:"foreignKey:city_id;references:id" json:"postal_code_by_city_relation"`
Subdistrict_ByCity_Relation []Subdistrict `gorm:"foreignKey:city_id;references:id" json:"subdistrict_by_city_relation"`
} }
// TableName City's table name
func (*City) TableName() string { func (*City) TableName() string {
return TableNameCity return TableNameCity
} }

View File

@ -1,9 +1,16 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package domain package domain
import "time" import (
"time"
)
const TableNameCostComponent = "cost_component" const TableNameCostComponent = "cost_component"
// CostComponent mapped from table <cost_component>
type CostComponent struct { type CostComponent struct {
ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"` ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"`
Name *string `gorm:"column:name;type:character varying(255);index:cost_component_name_idx,priority:1" json:"name"` Name *string `gorm:"column:name;type:character varying(255);index:cost_component_name_idx,priority:1" json:"name"`
@ -15,9 +22,13 @@ type CostComponent struct {
Inc *int32 `gorm:"column:inc;type:integer" json:"inc"` Inc *int32 `gorm:"column:inc;type:integer" json:"inc"`
Code *string `gorm:"column:code;type:character varying(100)" json:"code"` Code *string `gorm:"column:code;type:character varying(100)" json:"code"`
Value *string `gorm:"column:value;type:character varying(255)" json:"value"` Value *string `gorm:"column:value;type:character varying(255)" json:"value"`
ComponentType *int32 `gorm:"column:component_type;type:integer;comment:0.Input 1.Formula" json:"component_type"` ComponentType *int32 `gorm:"column:component_type;type:integer;comment:0. Input 1. Formula" json:"component_type"` // 0. Input 1. Formula
BasicPricingComponent_ByCostComponent_Relation []BasicPricingComponent `gorm:"foreignKey:cost_component_id;references:id" json:"basic_pricing_component_by_cost_component_relation"`
Merchant_Relation *Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
Users_Relation *User `gorm:"foreignKey:created_by;references:id" json:"users_relation"`
} }
// TableName CostComponent's table name
func (*CostComponent) TableName() string { func (*CostComponent) TableName() string {
return TableNameCostComponent return TableNameCostComponent
} }

View File

@ -1,21 +1,38 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package domain package domain
import "time" import (
"time"
)
const TableNameDistrict = "district" const TableNameDistrict = "district"
// District mapped from table <district>
type District struct { type District struct {
ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"` ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"`
Name *string `gorm:"column:name;type:character varying(255);index:district_name_idx,priority:1" json:"name"` Name *string `gorm:"column:name;type:character varying(255);index:district_name_idx,priority:1" json:"name"`
ProvinceID *string `gorm:"column:province_id;type:character(26);index:district_province_id_idx,priority:1" json:"province_id"` ProvinceID *string `gorm:"column:province_id;type:character(26);index:district_province_id_idx,priority:1" json:"province_id"`
CityID *string `gorm:"column:city_id;type:character(26);index:district_city_id_idx,priority:1" json:"city_id"` CityID *string `gorm:"column:city_id;type:character(26);index:district_city_id_idx,priority:1" json:"city_id"`
MerchantID *string `gorm:"column:merchant_id;type:character(26)" json:"merchant_id"`
CreatedBy *string `gorm:"column:created_by;type:character(26);index:district_created_by_idx,priority:1" json:"created_by"` CreatedBy *string `gorm:"column:created_by;type:character(26);index:district_created_by_idx,priority:1" json:"created_by"`
CreatedOn *time.Time `gorm:"column:created_on;type:timestamp without time zone" json:"created_on"` CreatedOn *time.Time `gorm:"column:created_on;type:timestamp without time zone" json:"created_on"`
UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"` UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"`
UpdatedOn *time.Time `gorm:"column:updated_on;type:timestamp without time zone" json:"updated_on"` UpdatedOn *time.Time `gorm:"column:updated_on;type:timestamp without time zone" json:"updated_on"`
MerchantID *string `gorm:"column:merchant_id;type:character(26)" json:"merchant_id"`
BasicPricing_ByDistrictDestination_Relation []BasicPricing `gorm:"foreignKey:district_destination_id;references:id" json:"basic_pricing_by_district_destination_relation"`
BasicPricing_ByDistrictSource_Relation []BasicPricing `gorm:"foreignKey:district_source_id;references:id" json:"basic_pricing_by_district_source_relation"`
City_Relation *City `gorm:"foreignKey:city_id;references:id" json:"city_relation"`
Merchant_Relation *Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
Province_Relation *Province `gorm:"foreignKey:province_id;references:id" json:"province_relation"`
Users_Relation *User `gorm:"foreignKey:created_by;references:id" json:"users_relation"`
Merchant_ByDistrict_Relation []Merchant `gorm:"foreignKey:district_id;references:id" json:"merchant_by_district_relation"`
PostalCode_ByDistrict_Relation []PostalCode `gorm:"foreignKey:district_id;references:id" json:"postal_code_by_district_relation"`
Subdistrict_ByDistrict_Relation []Subdistrict `gorm:"foreignKey:district_id;references:id" json:"subdistrict_by_district_relation"`
} }
// TableName District's table name
func (*District) TableName() string { func (*District) TableName() string {
return TableNameDistrict return TableNameDistrict
} }

View File

@ -1,9 +1,16 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package domain package domain
import "time" import (
"time"
)
const TableNameMerchant = "merchant" const TableNameMerchant = "merchant"
// Merchant mapped from table <merchant>
type Merchant struct { type Merchant struct {
ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"` ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"`
Name *string `gorm:"column:name;type:character varying(255);index:merchant_name_idx,priority:3" json:"name"` Name *string `gorm:"column:name;type:character varying(255);index:merchant_name_idx,priority:3" json:"name"`
@ -21,8 +28,25 @@ type Merchant struct {
DistrictID *string `gorm:"column:district_id;type:character(26);index:merchant_district_id_idx,priority:1" json:"district_id"` DistrictID *string `gorm:"column:district_id;type:character(26);index:merchant_district_id_idx,priority:1" json:"district_id"`
SubdistrictID *string `gorm:"column:subdistrict_id;type:character(26);index:merchant_subdistrict_id_idx,priority:1" json:"subdistrict_id"` SubdistrictID *string `gorm:"column:subdistrict_id;type:character(26);index:merchant_subdistrict_id_idx,priority:1" json:"subdistrict_id"`
PostalCode *string `gorm:"column:postal_code;type:character(26);index:merchant_postal_code_idx,priority:1" json:"postal_code"` PostalCode *string `gorm:"column:postal_code;type:character(26);index:merchant_postal_code_idx,priority:1" json:"postal_code"`
BasicPricing_ByMerchant_Relation []BasicPricing `gorm:"foreignKey:merchant_id;references:id" json:"basic_pricing_by_merchant_relation"`
City_ByMerchant_Relation []City `gorm:"foreignKey:merchant_id;references:id" json:"city_by_merchant_relation"`
CostComponent_ByMerchant_Relation []CostComponent `gorm:"foreignKey:merchant_id;references:id" json:"cost_component_by_merchant_relation"`
District_ByMerchant_Relation []District `gorm:"foreignKey:merchant_id;references:id" json:"district_by_merchant_relation"`
City_Relation *City `gorm:"foreignKey:city_id;references:id" json:"city_relation"`
District_Relation *District `gorm:"foreignKey:district_id;references:id" json:"district_relation"`
Province_Relation *Province `gorm:"foreignKey:province_id;references:id" json:"province_relation"`
Subdistrict_Relation *Subdistrict `gorm:"foreignKey:subdistrict_id;references:id" json:"subdistrict_relation"`
Users_Relation *User `gorm:"foreignKey:created_by;references:id" json:"users_relation"`
Moda_ByMerchant_Relation []Moda `gorm:"foreignKey:merchant_id;references:id" json:"moda_by_merchant_relation"`
PackageType_ByMerchant_Relation []PackageType `gorm:"foreignKey:merchant_id;references:id" json:"package_type_by_merchant_relation"`
PostalCode_ByMerchant_Relation []PostalCode `gorm:"foreignKey:merchant_id;references:id" json:"postal_code_by_merchant_relation"`
Province_ByMerchant_Relation []Province `gorm:"foreignKey:merchant_id;references:id" json:"province_by_merchant_relation"`
Subdistrict_ByMerchant_Relation []Subdistrict `gorm:"foreignKey:merchant_id;references:id" json:"subdistrict_by_merchant_relation"`
Users_ByMerchant_Relation []User `gorm:"foreignKey:merchant_id;references:id" json:"users_by_merchant_relation"`
UsersRoles_ByMerchant_Relation []UsersRole `gorm:"foreignKey:merchant_id;references:id" json:"users_roles_by_merchant_relation"`
} }
// TableName Merchant's table name
func (*Merchant) TableName() string { func (*Merchant) TableName() string {
return TableNameMerchant return TableNameMerchant
} }

View File

@ -1,9 +1,16 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package domain package domain
import "time" import (
"time"
)
const TableNameModa = "moda" const TableNameModa = "moda"
// Moda mapped from table <moda>
type Moda struct { type Moda struct {
ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"` ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"`
Name *string `gorm:"column:name;type:character varying(255);index:moda_name_idx,priority:1" json:"name"` Name *string `gorm:"column:name;type:character varying(255);index:moda_name_idx,priority:1" json:"name"`
@ -12,8 +19,11 @@ type Moda struct {
CreatedOn *time.Time `gorm:"column:created_on;type:timestamp without time zone;default:now()" json:"created_on"` CreatedOn *time.Time `gorm:"column:created_on;type:timestamp without time zone;default:now()" json:"created_on"`
UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"` UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"`
UpdatedOn *time.Time `gorm:"column:updated_on;type:timestamp without time zone;default:now()" json:"updated_on"` UpdatedOn *time.Time `gorm:"column:updated_on;type:timestamp without time zone;default:now()" json:"updated_on"`
BasicPricing_ByModa_Relation []BasicPricing `gorm:"foreignKey:moda_id;references:id" json:"basic_pricing_by_moda_relation"`
Merchant_Relation *Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
} }
// TableName Moda's table name
func (*Moda) TableName() string { func (*Moda) TableName() string {
return TableNameModa return TableNameModa
} }

View File

@ -1,9 +1,16 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package domain package domain
import "time" import (
"time"
)
const TableNamePackageType = "package_type" const TableNamePackageType = "package_type"
// PackageType mapped from table <package_type>
type PackageType struct { type PackageType struct {
ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"` ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"`
Name *string `gorm:"column:name;type:character varying(255);index:package_type_name_idx,priority:1" json:"name"` Name *string `gorm:"column:name;type:character varying(255);index:package_type_name_idx,priority:1" json:"name"`
@ -12,8 +19,11 @@ type PackageType struct {
CreatedOn *time.Time `gorm:"column:created_on;type:timestamp without time zone;default:now()" json:"created_on"` CreatedOn *time.Time `gorm:"column:created_on;type:timestamp without time zone;default:now()" json:"created_on"`
UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"` UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"`
UpdatedOn *time.Time `gorm:"column:updated_on;type:timestamp without time zone" json:"updated_on"` UpdatedOn *time.Time `gorm:"column:updated_on;type:timestamp without time zone" json:"updated_on"`
BasicPricing_ByPackageType_Relation []BasicPricing `gorm:"foreignKey:package_type_id;references:id" json:"basic_pricing_by_package_type_relation"`
Merchant_Relation *Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
} }
// TableName PackageType's table name
func (*PackageType) TableName() string { func (*PackageType) TableName() string {
return TableNamePackageType return TableNamePackageType
} }

View File

@ -1,9 +1,16 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package domain package domain
import "time" import (
"time"
)
const TableNamePostalCode = "postal_code" const TableNamePostalCode = "postal_code"
// PostalCode mapped from table <postal_code>
type PostalCode struct { type PostalCode struct {
ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"` ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"`
PostalCode *string `gorm:"column:postal_code;type:character varying(255);index:postal_code_postal_code_idx,priority:1" json:"postal_code"` PostalCode *string `gorm:"column:postal_code;type:character varying(255);index:postal_code_postal_code_idx,priority:1" json:"postal_code"`
@ -11,13 +18,22 @@ type PostalCode struct {
CityID *string `gorm:"column:city_id;type:character(26);index:postal_code_city_id_idx,priority:1" json:"city_id"` CityID *string `gorm:"column:city_id;type:character(26);index:postal_code_city_id_idx,priority:1" json:"city_id"`
DistrictID *string `gorm:"column:district_id;type:character(26);index:postal_code_district_id_idx,priority:1" json:"district_id"` DistrictID *string `gorm:"column:district_id;type:character(26);index:postal_code_district_id_idx,priority:1" json:"district_id"`
SubdistrictID *string `gorm:"column:subdistrict_id;type:character(26);index:postal_code_subdistrict_id_idx,priority:1" json:"subdistrict_id"` SubdistrictID *string `gorm:"column:subdistrict_id;type:character(26);index:postal_code_subdistrict_id_idx,priority:1" json:"subdistrict_id"`
MerchantID *string `gorm:"column:merchant_id;type:character(26)" json:"merchant_id"`
CreatedBy *string `gorm:"column:created_by;type:character(26);index:postal_code_created_by_idx,priority:1" json:"created_by"` CreatedBy *string `gorm:"column:created_by;type:character(26);index:postal_code_created_by_idx,priority:1" json:"created_by"`
CreatedOn *time.Time `gorm:"column:created_on;type:timestamp without time zone" json:"created_on"` CreatedOn *time.Time `gorm:"column:created_on;type:timestamp without time zone" json:"created_on"`
UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"` UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"`
UpdatedOn *string `gorm:"column:updated_on;type:character varying" json:"updated_on"` UpdatedOn *time.Time `gorm:"column:updated_on;type:timestamp without time zone" json:"updated_on"`
MerchantID *string `gorm:"column:merchant_id;type:character(26)" json:"merchant_id"`
BasicPricing_ByPostalCodeDestination_Relation []BasicPricing `gorm:"foreignKey:postal_code_destination_id;references:id" json:"basic_pricing_by_postal_code_destination_relation"`
BasicPricing_ByPostalCodeSource_Relation []BasicPricing `gorm:"foreignKey:postal_code_source_id;references:id" json:"basic_pricing_by_postal_code_source_relation"`
City_Relation *City `gorm:"foreignKey:city_id;references:id" json:"city_relation"`
District_Relation *District `gorm:"foreignKey:district_id;references:id" json:"district_relation"`
Merchant_Relation *Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
Province_Relation *Province `gorm:"foreignKey:province_id;references:id" json:"province_relation"`
Subdistrict_Relation *Subdistrict `gorm:"foreignKey:subdistrict_id;references:id" json:"subdistrict_relation"`
Users_Relation *User `gorm:"foreignKey:created_by;references:id" json:"users_relation"`
} }
// TableName PostalCode's table name
func (*PostalCode) TableName() string { func (*PostalCode) TableName() string {
return TableNamePostalCode return TableNamePostalCode
} }

View File

@ -1,19 +1,36 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package domain package domain
import "time" import (
"time"
)
const TableNameProvince = "province" const TableNameProvince = "province"
// Province mapped from table <province>
type Province struct { type Province struct {
ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"` ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"`
Name *string `gorm:"column:name;type:character varying(255);index:province_name_idx,priority:1" json:"name"` Name *string `gorm:"column:name;type:character varying(255);index:province_name_idx,priority:1" json:"name"`
MerchantID *string `gorm:"column:merchant_id;type:character(26)" json:"merchant_id"`
CreatedBy *string `gorm:"column:created_by;type:character(26);index:province_created_by_idx,priority:1" json:"created_by"` CreatedBy *string `gorm:"column:created_by;type:character(26);index:province_created_by_idx,priority:1" json:"created_by"`
CreatedOn *time.Time `gorm:"column:created_on;type:timestamp without time zone" json:"created_on"` CreatedOn *time.Time `gorm:"column:created_on;type:timestamp without time zone" json:"created_on"`
UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"` UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"`
UpdatedOn *time.Time `gorm:"column:updated_on;type:timestamp without time zone" json:"updated_on"` UpdatedOn *time.Time `gorm:"column:updated_on;type:timestamp without time zone" json:"updated_on"`
MerchantID *string `gorm:"column:merchant_id;type:character(26)" json:"merchant_id"`
BasicPricing_ByProvinceDestination_Relation []BasicPricing `gorm:"foreignKey:province_destination_id;references:id" json:"basic_pricing_by_province_destination_relation"`
BasicPricing_ByProvinceSource_Relation []BasicPricing `gorm:"foreignKey:province_source_id;references:id" json:"basic_pricing_by_province_source_relation"`
City_ByProvince_Relation []City `gorm:"foreignKey:province_id;references:id" json:"city_by_province_relation"`
District_ByProvince_Relation []District `gorm:"foreignKey:province_id;references:id" json:"district_by_province_relation"`
Merchant_ByProvince_Relation []Merchant `gorm:"foreignKey:province_id;references:id" json:"merchant_by_province_relation"`
PostalCode_ByProvince_Relation []PostalCode `gorm:"foreignKey:province_id;references:id" json:"postal_code_by_province_relation"`
Merchant_Relation *Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
Users_Relation *User `gorm:"foreignKey:created_by;references:id" json:"users_relation"`
Subdistrict_ByProvince_Relation []Subdistrict `gorm:"foreignKey:province_id;references:id" json:"subdistrict_by_province_relation"`
} }
// TableName Province's table name
func (*Province) TableName() string { func (*Province) TableName() string {
return TableNameProvince return TableNameProvince
} }

View File

@ -1,22 +1,39 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package domain package domain
import "time" import (
"time"
)
const TableNameSubdistrict = "subdistrict" const TableNameSubdistrict = "subdistrict"
// Subdistrict mapped from table <subdistrict>
type Subdistrict struct { type Subdistrict struct {
ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"` ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"`
Name *string `gorm:"column:name;type:character varying(255);index:subdistrit_name_idx,priority:1" json:"name"` Name *string `gorm:"column:name;type:character varying(255);index:subdistrit_name_idx,priority:1" json:"name"`
ProvinceID *string `gorm:"column:province_id;type:character(26);index:subdistrit_province_id_idx,priority:1" json:"province_id"` ProvinceID *string `gorm:"column:province_id;type:character(26);index:subdistrit_province_id_idx,priority:1" json:"province_id"`
CityID *string `gorm:"column:city_id;type:character(26);index:subdistrit_city_id_idx,priority:1" json:"city_id"` CityID *string `gorm:"column:city_id;type:character(26);index:subdistrit_city_id_idx,priority:1" json:"city_id"`
DistrictID *string `gorm:"column:district_id;type:character(26);index:subdistrit_district_id_idx,priority:1" json:"district_id"` DistrictID *string `gorm:"column:district_id;type:character(26);index:subdistrit_district_id_idx,priority:1" json:"district_id"`
MerchantID *string `gorm:"column:merchant_id;type:character(26)" json:"merchant_id"`
CreatedBy *string `gorm:"column:created_by;type:character(26);index:subdistrit_created_by_idx,priority:1" json:"created_by"` CreatedBy *string `gorm:"column:created_by;type:character(26);index:subdistrit_created_by_idx,priority:1" json:"created_by"`
CreatedOn *time.Time `gorm:"column:created_on;type:timestamp without time zone" json:"created_on"` CreatedOn *time.Time `gorm:"column:created_on;type:timestamp without time zone" json:"created_on"`
UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"` UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"`
UpdatedOn *time.Time `gorm:"column:updated_on;type:timestamp without time zone" json:"updated_on"` UpdatedOn *time.Time `gorm:"column:updated_on;type:timestamp without time zone" json:"updated_on"`
MerchantID *string `gorm:"column:merchant_id;type:character(26)" json:"merchant_id"`
BasicPricing_BySubdistrictDestination_Relation []BasicPricing `gorm:"foreignKey:subdistrict_destination_id;references:id" json:"basic_pricing_by_subdistrict_destination_relation"`
BasicPricing_BySubdistrictSource_Relation []BasicPricing `gorm:"foreignKey:subdistrict_source_id;references:id" json:"basic_pricing_by_subdistrict_source_relation"`
Merchant_BySubdistrict_Relation []Merchant `gorm:"foreignKey:subdistrict_id;references:id" json:"merchant_by_subdistrict_relation"`
PostalCode_BySubdistrict_Relation []PostalCode `gorm:"foreignKey:subdistrict_id;references:id" json:"postal_code_by_subdistrict_relation"`
City_Relation *City `gorm:"foreignKey:city_id;references:id" json:"city_relation"`
District_Relation *District `gorm:"foreignKey:district_id;references:id" json:"district_relation"`
Merchant_Relation *Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
Province_Relation *Province `gorm:"foreignKey:province_id;references:id" json:"province_relation"`
Users_Relation *User `gorm:"foreignKey:created_by;references:id" json:"users_relation"`
} }
// TableName Subdistrict's table name
func (*Subdistrict) TableName() string { func (*Subdistrict) TableName() string {
return TableNameSubdistrict return TableNameSubdistrict
} }

View File

@ -1,9 +1,16 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package domain package domain
import "time" import (
"time"
)
const TableNameUser = "users" const TableNameUser = "users"
// User mapped from table <users>
type User struct { type User struct {
ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"` ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"`
MerchantID *string `gorm:"column:merchant_id;type:character(26);index:users_merchant_id_idx,priority:1" json:"merchant_id"` MerchantID *string `gorm:"column:merchant_id;type:character(26);index:users_merchant_id_idx,priority:1" json:"merchant_id"`
@ -18,9 +25,19 @@ type User struct {
CreatedOn *time.Time `gorm:"column:created_on;type:timestamp without time zone;default:now()" json:"created_on"` CreatedOn *time.Time `gorm:"column:created_on;type:timestamp without time zone;default:now()" json:"created_on"`
UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"` UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"`
UpdatedOn *time.Time `gorm:"column:updated_on;type:timestamp without time zone;default:now()" json:"updated_on"` UpdatedOn *time.Time `gorm:"column:updated_on;type:timestamp without time zone;default:now()" json:"updated_on"`
UsersRole_Relation UsersRole `gorm:"foreignKey:UsersRoleID;references:ID" json:"users_role_relation"` BasicPricing_ByCreatedBy_Relation []BasicPricing `gorm:"foreignKey:created_by;references:id" json:"basic_pricing_by_created_by_relation"`
City_ByCreatedBy_Relation []City `gorm:"foreignKey:created_by;references:id" json:"city_by_created_by_relation"`
CostComponent_ByCreatedBy_Relation []CostComponent `gorm:"foreignKey:created_by;references:id" json:"cost_component_by_created_by_relation"`
District_ByCreatedBy_Relation []District `gorm:"foreignKey:created_by;references:id" json:"district_by_created_by_relation"`
Merchant_ByCreatedBy_Relation []Merchant `gorm:"foreignKey:created_by;references:id" json:"merchant_by_created_by_relation"`
PostalCode_ByCreatedBy_Relation []PostalCode `gorm:"foreignKey:created_by;references:id" json:"postal_code_by_created_by_relation"`
Province_ByCreatedBy_Relation []Province `gorm:"foreignKey:created_by;references:id" json:"province_by_created_by_relation"`
Subdistrict_ByCreatedBy_Relation []Subdistrict `gorm:"foreignKey:created_by;references:id" json:"subdistrict_by_created_by_relation"`
Merchant_Relation *Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
UsersRole_Relation *UsersRole `gorm:"foreignKey:users_role_id;references:id" json:"users_role_relation"`
} }
// TableName User's table name
func (*User) TableName() string { func (*User) TableName() string {
return TableNameUser return TableNameUser
} }

View File

@ -1,9 +1,16 @@
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
// Code generated by gorm.io/gen. DO NOT EDIT.
package domain package domain
import "time" import (
"time"
)
const TableNameUsersRole = "users_roles" const TableNameUsersRole = "users_roles"
// UsersRole mapped from table <users_roles>
type UsersRole struct { type UsersRole struct {
ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"` ID string `gorm:"column:id;type:character(26);not null;default:generate_ulid()" json:"id"`
Name *string `gorm:"column:name;type:character varying(255)" json:"name"` Name *string `gorm:"column:name;type:character varying(255)" json:"name"`
@ -13,8 +20,11 @@ type UsersRole struct {
UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"` UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"`
UpdatedOn *time.Time `gorm:"column:updated_on;type:timestamp without time zone;default:now()" json:"updated_on"` UpdatedOn *time.Time `gorm:"column:updated_on;type:timestamp without time zone;default:now()" json:"updated_on"`
RoleKey string `gorm:"column:role_key;type:character varying(20);not null" json:"role_key"` RoleKey string `gorm:"column:role_key;type:character varying(20);not null" json:"role_key"`
Users_ByUsersRole_Relation []User `gorm:"foreignKey:users_role_id;references:id" json:"users_by_users_role_relation"`
Merchant_Relation *Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
} }
// TableName UsersRole's table name
func (*UsersRole) TableName() string { func (*UsersRole) TableName() string {
return TableNameUsersRole return TableNameUsersRole
} }

View File

@ -107,7 +107,7 @@ func (h *BasicPricingHandler) Create(c *gin.Context) {
return return
} }
var merchantid *string = nil var merchantid *string = nil
if userid.UsersRole_Relation.RoleKey != "SPM" { if userid.UsersRole_Relation == nil || userid.UsersRole_Relation.RoleKey != "SPM" {
merchantid = userid.MerchantID merchantid = userid.MerchantID
} }
createdBy := userid.ID createdBy := userid.ID

View File

@ -119,7 +119,7 @@ func (h *CityHandler) Create(c *gin.Context) {
return return
} }
var merchantid *string = nil var merchantid *string = nil
if userid.UsersRole_Relation.RoleKey != "SPM" { if userid.UsersRole_Relation == nil || userid.UsersRole_Relation.RoleKey != "SPM" {
merchantid = userid.MerchantID merchantid = userid.MerchantID
} }
createdBy := userid.ID createdBy := userid.ID

View File

@ -115,7 +115,7 @@ func (h *CostComponentHandler) Create(c *gin.Context) {
return return
} }
var merchantid *string = nil var merchantid *string = nil
if userid.UsersRole_Relation.RoleKey != "SPM" { if userid.UsersRole_Relation == nil || userid.UsersRole_Relation.RoleKey != "SPM" {
merchantid = userid.MerchantID merchantid = userid.MerchantID
} }
createdBy := userid.ID createdBy := userid.ID

View File

@ -119,7 +119,7 @@ func (h *DistrictHandler) Create(c *gin.Context) {
return return
} }
var merchantid *string = nil var merchantid *string = nil
if userid.UsersRole_Relation.RoleKey != "SPM" { if userid.UsersRole_Relation == nil || userid.UsersRole_Relation.RoleKey != "SPM" {
merchantid = userid.MerchantID merchantid = userid.MerchantID
} }
createdBy := userid.ID createdBy := userid.ID

View File

@ -119,7 +119,7 @@ func (h *PostalCodeHandler) Create(c *gin.Context) {
return return
} }
var merchantid *string = nil var merchantid *string = nil
if userid.UsersRole_Relation.RoleKey != "SPM" { if userid.UsersRole_Relation == nil || userid.UsersRole_Relation.RoleKey != "SPM" {
merchantid = userid.MerchantID merchantid = userid.MerchantID
} }
createdBy := userid.ID createdBy := userid.ID

View File

@ -119,7 +119,7 @@ func (h *ProvinceHandler) Create(c *gin.Context) {
return return
} }
var merchantid *string = nil var merchantid *string = nil
if userid.UsersRole_Relation.RoleKey != "SPM" { if userid.UsersRole_Relation == nil || userid.UsersRole_Relation.RoleKey != "SPM" {
merchantid = userid.MerchantID merchantid = userid.MerchantID
} }
createdBy := userid.ID createdBy := userid.ID

View File

@ -119,7 +119,7 @@ func (h *SubdistrictHandler) Create(c *gin.Context) {
return return
} }
var merchantid *string = nil var merchantid *string = nil
if userid.UsersRole_Relation.RoleKey != "SPM" { if userid.UsersRole_Relation == nil || userid.UsersRole_Relation.RoleKey != "SPM" {
merchantid = userid.MerchantID merchantid = userid.MerchantID
} }
createdBy := userid.ID createdBy := userid.ID

View File

@ -97,7 +97,6 @@ func (h *PostalCodeImportHandler) ValidateRow(row []string, rowNumber int) (impo
h.lastSubdistrictName = subdistrictName h.lastSubdistrictName = subdistrictName
now := time.Now() now := time.Now()
nowStr := now.Format("2006-01-02 15:04:05")
pc := &domain.PostalCode{ pc := &domain.PostalCode{
PostalCode: &postalCode, PostalCode: &postalCode,
ProvinceID: &province.ID, ProvinceID: &province.ID,
@ -108,7 +107,7 @@ func (h *PostalCodeImportHandler) ValidateRow(row []string, rowNumber int) (impo
CreatedBy: &h.UserData.ID, CreatedBy: &h.UserData.ID,
CreatedOn: &now, CreatedOn: &now,
UpdatedBy: &h.UserData.ID, UpdatedBy: &h.UserData.ID,
UpdatedOn: &nowStr, UpdatedOn: &now,
} }
return pc, nil return pc, nil

View File

@ -51,7 +51,6 @@ func (u *BasicPricingUsecase) loadComponents(pricingIDs []string) (map[string][]
func (u *BasicPricingUsecase) toResponse(pricing domain.BasicPricing, components []domain.BasicPricingComponent) dto.CreateBasicPricingResponse { func (u *BasicPricingUsecase) toResponse(pricing domain.BasicPricing, components []domain.BasicPricingComponent) dto.CreateBasicPricingResponse {
resp := dto.CreateBasicPricingResponse{ resp := dto.CreateBasicPricingResponse{
ID: pricing.ID, ID: pricing.ID,
Name: pricing.Name,
ProvinceSourceID: pricing.ProvinceSourceID, ProvinceSourceID: pricing.ProvinceSourceID,
CitySourceID: pricing.CitySourceID, CitySourceID: pricing.CitySourceID,
DistrictSourceID: pricing.DistrictSourceID, DistrictSourceID: pricing.DistrictSourceID,
@ -83,7 +82,7 @@ func (u *BasicPricingUsecase) GetAll(filter dto.BasicPricingFilterAllRequest) ([
db := u.Helper.GetDB("slave") db := u.Helper.GetDB("slave")
tx := db.Model(&pricings) tx := db.Model(&pricings)
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
tx.Where(db.Where("merchant_id IS NULL").Or("merchant_id=?", u.AuthUser.MerchantID)) tx.Where(db.Where("merchant_id IS NULL").Or("merchant_id=?", u.AuthUser.MerchantID))
} }
v := reflect.ValueOf(filter) v := reflect.ValueOf(filter)
@ -215,7 +214,7 @@ func (u *BasicPricingUsecase) Update(id string, req dto.CreateBasicPricingReques
err := db.Transaction(func(tx *gorm.DB) error { err := db.Transaction(func(tx *gorm.DB) error {
q := tx q := tx
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
q = tx.Where("merchant_id=?", u.AuthUser.MerchantID) q = tx.Where("merchant_id=?", u.AuthUser.MerchantID)
} }
if err := q.Where("id = ?", id).First(&pricing).Error; err != nil { if err := q.Where("id = ?", id).First(&pricing).Error; err != nil {
@ -269,7 +268,7 @@ func (u *BasicPricingUsecase) Delete(id string) error {
db := u.Helper.GetDB("master") db := u.Helper.GetDB("master")
return db.Transaction(func(tx *gorm.DB) error { return db.Transaction(func(tx *gorm.DB) error {
q := tx q := tx
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
q = tx.Where("merchant_id=?", u.AuthUser.MerchantID) q = tx.Where("merchant_id=?", u.AuthUser.MerchantID)
} }
var pricing domain.BasicPricing var pricing domain.BasicPricing

View File

@ -36,7 +36,7 @@ func (u *CityUsecase) GetAll(filter dto.CityFilterAllRequest) ([]domain.City, in
db := u.Helper.GetDB("slave") db := u.Helper.GetDB("slave")
tx := db.Model(&cities) tx := db.Model(&cities)
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
tx.Where(db.Where("merchant_id IS NULL").Or("merchant_id=?", u.AuthUser.MerchantID)) tx.Where(db.Where("merchant_id IS NULL").Or("merchant_id=?", u.AuthUser.MerchantID))
} }
v := reflect.ValueOf(filter) v := reflect.ValueOf(filter)
@ -127,7 +127,7 @@ func (u *CityUsecase) Update(id string, name string, provinceID string, port str
db := u.Helper.GetDB("master") db := u.Helper.GetDB("master")
err := db.Transaction(func(tx *gorm.DB) error { err := db.Transaction(func(tx *gorm.DB) error {
q := tx q := tx
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
q = tx.Where("merchant_id=?", u.AuthUser.MerchantID) q = tx.Where("merchant_id=?", u.AuthUser.MerchantID)
} }
if err := q.Where("id = ?", id).First(&city).Error; err != nil { if err := q.Where("id = ?", id).First(&city).Error; err != nil {
@ -149,7 +149,7 @@ func (u *CityUsecase) Update(id string, name string, provinceID string, port str
func (u *CityUsecase) Delete(id string) error { func (u *CityUsecase) Delete(id string) error {
db := u.Helper.GetDB("master") db := u.Helper.GetDB("master")
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
db.Where("merchant_id=?", u.AuthUser.MerchantID) db.Where("merchant_id=?", u.AuthUser.MerchantID)
} }
if err := db.Delete(&domain.City{}, "id = ?", id).Error; err != nil { if err := db.Delete(&domain.City{}, "id = ?", id).Error; err != nil {

View File

@ -38,7 +38,7 @@ func (u *CostComponentUsecase) GetAll(filter dto.CostComponentFilterAllRequest)
db := u.Helper.GetDB("slave") db := u.Helper.GetDB("slave")
tx := db.Model(&components) tx := db.Model(&components)
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
tx.Where(db.Where("merchant_id IS NULL").Or("merchant_id=?", u.AuthUser.MerchantID)) tx.Where(db.Where("merchant_id IS NULL").Or("merchant_id=?", u.AuthUser.MerchantID))
} }
v := reflect.ValueOf(filter) v := reflect.ValueOf(filter)
@ -116,7 +116,7 @@ func (u *CostComponentUsecase) Create(name string, code string, value string, co
err := db.Transaction(func(tx *gorm.DB) error { err := db.Transaction(func(tx *gorm.DB) error {
var maxInc int64 var maxInc int64
q := tx.Model(&domain.CostComponent{}) q := tx.Model(&domain.CostComponent{})
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
q = q.Where("merchant_id=?", u.AuthUser.MerchantID) q = q.Where("merchant_id=?", u.AuthUser.MerchantID)
} }
q.Select("COALESCE(MAX(inc),0)").Row().Scan(&maxInc) q.Select("COALESCE(MAX(inc),0)").Row().Scan(&maxInc)
@ -149,7 +149,7 @@ func (u *CostComponentUsecase) Update(id string, name string, code string, value
db := u.Helper.GetDB("master") db := u.Helper.GetDB("master")
err := db.Transaction(func(tx *gorm.DB) error { err := db.Transaction(func(tx *gorm.DB) error {
q := tx q := tx
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
q = tx.Where("merchant_id=?", u.AuthUser.MerchantID) q = tx.Where("merchant_id=?", u.AuthUser.MerchantID)
} }
if err := q.Where("id = ?", id).First(&component).Error; err != nil { if err := q.Where("id = ?", id).First(&component).Error; err != nil {
@ -172,7 +172,7 @@ func (u *CostComponentUsecase) Update(id string, name string, code string, value
func (u *CostComponentUsecase) Delete(id string) error { func (u *CostComponentUsecase) Delete(id string) error {
db := u.Helper.GetDB("master") db := u.Helper.GetDB("master")
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
db.Where("merchant_id=?", u.AuthUser.MerchantID) db.Where("merchant_id=?", u.AuthUser.MerchantID)
} }
if err := db.Delete(&domain.CostComponent{}, "id = ?", id).Error; err != nil { if err := db.Delete(&domain.CostComponent{}, "id = ?", id).Error; err != nil {
@ -183,7 +183,7 @@ func (u *CostComponentUsecase) Delete(id string) error {
func (u *CostComponentUsecase) SortDown(id string) error { func (u *CostComponentUsecase) SortDown(id string) error {
db := u.Helper.GetDB("master") db := u.Helper.GetDB("master")
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
var olData domain.CostComponent var olData domain.CostComponent
err := db.Model(&olData).Where("id=?", id).Where("merchant_id=?", u.AuthUser.MerchantID).First(&olData).Error err := db.Model(&olData).Where("id=?", id).Where("merchant_id=?", u.AuthUser.MerchantID).First(&olData).Error
@ -240,7 +240,7 @@ func (u *CostComponentUsecase) SortDown(id string) error {
func (u *CostComponentUsecase) SortUp(id string) error { func (u *CostComponentUsecase) SortUp(id string) error {
db := u.Helper.GetDB("master") db := u.Helper.GetDB("master")
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
var olData domain.CostComponent var olData domain.CostComponent
err := db.Model(&olData).Where("id=?", id).Where("merchant_id=?", u.AuthUser.MerchantID).First(&olData).Error err := db.Model(&olData).Where("id=?", id).Where("merchant_id=?", u.AuthUser.MerchantID).First(&olData).Error

View File

@ -36,7 +36,7 @@ func (u *DistrictUsecase) GetAll(filter dto.DistrictFilterAllRequest) ([]domain.
db := u.Helper.GetDB("slave") db := u.Helper.GetDB("slave")
tx := db.Model(&districts) tx := db.Model(&districts)
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
tx.Where(db.Where("merchant_id IS NULL").Or("merchant_id=?", u.AuthUser.MerchantID)) tx.Where(db.Where("merchant_id IS NULL").Or("merchant_id=?", u.AuthUser.MerchantID))
} }
v := reflect.ValueOf(filter) v := reflect.ValueOf(filter)
@ -136,7 +136,7 @@ func (u *DistrictUsecase) Update(id string, name string, provinceID string, city
db := u.Helper.GetDB("master") db := u.Helper.GetDB("master")
err := db.Transaction(func(tx *gorm.DB) error { err := db.Transaction(func(tx *gorm.DB) error {
q := tx q := tx
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
q = tx.Where("merchant_id=?", u.AuthUser.MerchantID) q = tx.Where("merchant_id=?", u.AuthUser.MerchantID)
} }
if err := q.Where("id = ?", id).First(&district).Error; err != nil { if err := q.Where("id = ?", id).First(&district).Error; err != nil {
@ -158,7 +158,7 @@ func (u *DistrictUsecase) Update(id string, name string, provinceID string, city
func (u *DistrictUsecase) Delete(id string) error { func (u *DistrictUsecase) Delete(id string) error {
db := u.Helper.GetDB("master") db := u.Helper.GetDB("master")
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
db.Where("merchant_id=?", u.AuthUser.MerchantID) db.Where("merchant_id=?", u.AuthUser.MerchantID)
} }
if err := db.Delete(&domain.District{}, "id = ?", id).Error; err != nil { if err := db.Delete(&domain.District{}, "id = ?", id).Error; err != nil {

View File

@ -36,7 +36,7 @@ func (u *PostalCodeUsecase) GetAll(filter dto.PostalCodeFilterAllRequest) ([]dom
db := u.Helper.GetDB("slave") db := u.Helper.GetDB("slave")
tx := db.Model(&postalCodes) tx := db.Model(&postalCodes)
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
tx.Where(db.Where("merchant_id IS NULL").Or("merchant_id=?", u.AuthUser.MerchantID)) tx.Where(db.Where("merchant_id IS NULL").Or("merchant_id=?", u.AuthUser.MerchantID))
} }
v := reflect.ValueOf(filter) v := reflect.ValueOf(filter)
@ -127,7 +127,6 @@ func (u *PostalCodeUsecase) GetByID(id string) (domain.PostalCode, error) {
func (u *PostalCodeUsecase) Create(postalCode string, provinceID string, cityID string, districtID string, subdistrictID string, createdBy string, merchantid *string) (domain.PostalCode, error) { func (u *PostalCodeUsecase) Create(postalCode string, provinceID string, cityID string, districtID string, subdistrictID string, createdBy string, merchantid *string) (domain.PostalCode, error) {
now := time.Now() now := time.Now()
nowStr := now.Format("2006-01-02 15:04:05")
db := u.Helper.GetDB("master") db := u.Helper.GetDB("master")
var pc domain.PostalCode var pc domain.PostalCode
@ -142,7 +141,7 @@ func (u *PostalCodeUsecase) Create(postalCode string, provinceID string, cityID
CreatedBy: &createdBy, CreatedBy: &createdBy,
CreatedOn: &now, CreatedOn: &now,
UpdatedBy: &createdBy, UpdatedBy: &createdBy,
UpdatedOn: &nowStr, UpdatedOn: &now,
} }
return tx.Create(&pc).Error return tx.Create(&pc).Error
}) })
@ -157,21 +156,20 @@ func (u *PostalCodeUsecase) Update(id string, postalCode string, provinceID stri
db := u.Helper.GetDB("master") db := u.Helper.GetDB("master")
err := db.Transaction(func(tx *gorm.DB) error { err := db.Transaction(func(tx *gorm.DB) error {
q := tx q := tx
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
q = tx.Where("merchant_id=?", u.AuthUser.MerchantID) q = tx.Where("merchant_id=?", u.AuthUser.MerchantID)
} }
if err := q.Where("id = ?", id).First(&pc).Error; err != nil { if err := q.Where("id = ?", id).First(&pc).Error; err != nil {
return err return err
} }
now := time.Now() now := time.Now()
nowStr := now.Format("2006-01-02 15:04:05")
pc.PostalCode = &postalCode pc.PostalCode = &postalCode
pc.ProvinceID = &provinceID pc.ProvinceID = &provinceID
pc.CityID = &cityID pc.CityID = &cityID
pc.DistrictID = &districtID pc.DistrictID = &districtID
pc.SubdistrictID = &subdistrictID pc.SubdistrictID = &subdistrictID
pc.UpdatedBy = &updatedBy pc.UpdatedBy = &updatedBy
pc.UpdatedOn = &nowStr pc.UpdatedOn = &now
return tx.Save(&pc).Error return tx.Save(&pc).Error
}) })
if err != nil { if err != nil {
@ -182,7 +180,7 @@ func (u *PostalCodeUsecase) Update(id string, postalCode string, provinceID stri
func (u *PostalCodeUsecase) Delete(id string) error { func (u *PostalCodeUsecase) Delete(id string) error {
db := u.Helper.GetDB("master") db := u.Helper.GetDB("master")
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
db.Where("merchant_id=?", u.AuthUser.MerchantID) db.Where("merchant_id=?", u.AuthUser.MerchantID)
} }
if err := db.Delete(&domain.PostalCode{}, "id = ?", id).Error; err != nil { if err := db.Delete(&domain.PostalCode{}, "id = ?", id).Error; err != nil {

View File

@ -36,7 +36,7 @@ func (u *ProvinceUsecase) GetAll(filter dto.ProvinceFilterAllRequest) ([]domain.
db := u.Helper.GetDB("slave") db := u.Helper.GetDB("slave")
tx := db.Model(&provinces) tx := db.Model(&provinces)
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
tx.Where(db.Where("merchant_id IS NULL").Or("merchant_id=?", u.AuthUser.MerchantID)) tx.Where(db.Where("merchant_id IS NULL").Or("merchant_id=?", u.AuthUser.MerchantID))
} }
v := reflect.ValueOf(filter) v := reflect.ValueOf(filter)
@ -123,7 +123,7 @@ func (u *ProvinceUsecase) Update(id string, name string, updatedBy string) (doma
db := u.Helper.GetDB("master") db := u.Helper.GetDB("master")
err := db.Transaction(func(tx *gorm.DB) error { err := db.Transaction(func(tx *gorm.DB) error {
q := tx q := tx
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
q = tx.Where("merchant_id=?", u.AuthUser.MerchantID) q = tx.Where("merchant_id=?", u.AuthUser.MerchantID)
} }
if err := q.Where("id = ?", id).First(&province).Error; err != nil { if err := q.Where("id = ?", id).First(&province).Error; err != nil {
@ -143,7 +143,7 @@ func (u *ProvinceUsecase) Update(id string, name string, updatedBy string) (doma
func (u *ProvinceUsecase) Delete(id string) error { func (u *ProvinceUsecase) Delete(id string) error {
db := u.Helper.GetDB("master") db := u.Helper.GetDB("master")
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
db.Where("merchant_id=?", u.AuthUser.MerchantID) db.Where("merchant_id=?", u.AuthUser.MerchantID)
} }
if err := db.Delete(&domain.Province{}, "id = ?", id).Error; err != nil { if err := db.Delete(&domain.Province{}, "id = ?", id).Error; err != nil {

View File

@ -36,7 +36,7 @@ func (u *SubdistrictUsecase) GetAll(filter dto.SubdistrictFilterAllRequest) ([]d
db := u.Helper.GetDB("slave") db := u.Helper.GetDB("slave")
tx := db.Model(&subdistricts) tx := db.Model(&subdistricts)
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
tx.Where(db.Where("merchant_id IS NULL").Or("merchant_id=?", u.AuthUser.MerchantID)) tx.Where(db.Where("merchant_id IS NULL").Or("merchant_id=?", u.AuthUser.MerchantID))
} }
v := reflect.ValueOf(filter) v := reflect.ValueOf(filter)
@ -146,7 +146,7 @@ func (u *SubdistrictUsecase) Update(id string, name string, provinceID string, c
db := u.Helper.GetDB("master") db := u.Helper.GetDB("master")
err := db.Transaction(func(tx *gorm.DB) error { err := db.Transaction(func(tx *gorm.DB) error {
q := tx q := tx
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
q = tx.Where("merchant_id=?", u.AuthUser.MerchantID) q = tx.Where("merchant_id=?", u.AuthUser.MerchantID)
} }
if err := q.Where("id = ?", id).First(&subdistrict).Error; err != nil { if err := q.Where("id = ?", id).First(&subdistrict).Error; err != nil {
@ -169,7 +169,7 @@ func (u *SubdistrictUsecase) Update(id string, name string, provinceID string, c
func (u *SubdistrictUsecase) Delete(id string) error { func (u *SubdistrictUsecase) Delete(id string) error {
db := u.Helper.GetDB("master") db := u.Helper.GetDB("master")
if u.AuthUser.UsersRole_Relation.RoleKey != "SPM" { if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
db.Where("merchant_id=?", u.AuthUser.MerchantID) db.Where("merchant_id=?", u.AuthUser.MerchantID)
} }
if err := db.Delete(&domain.Subdistrict{}, "id = ?", id).Error; err != nil { if err := db.Delete(&domain.Subdistrict{}, "id = ?", id).Error; err != nil {

View File

@ -6,6 +6,7 @@ import (
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
"sort"
"strings" "strings"
"gorm.io/gen" "gorm.io/gen"
@ -13,39 +14,86 @@ import (
"gorm.io/gorm" "gorm.io/gorm"
) )
// Struktur untuk menampung metadata Foreign Key dari database // ForeignKeyMeta menyimpan metadata Foreign Key dari PostgreSQL.
type ForeignKeyMeta struct { type ForeignKeyMeta struct {
ConstraintName string
TableName string TableName string
ColumnName string ColumnName string
RefTable string RefTable string
RefColumn string RefColumn string
Ordinal int
} }
// GenerateModel membuat model GORM dari seluruh tabel public.
func GenerateModel(table *string, db *gorm.DB) { func GenerateModel(table *string, db *gorm.DB) {
currentDir, err := os.Getwd() currentDir, err := os.Getwd()
if err != nil { if err != nil {
log.Fatalf("Gagal mendapatkan working directory: %v", err) log.Fatalf(
"Gagal mendapatkan working directory: %v",
err,
)
} }
// Folder penampung sementara kueri (akan dihapus di akhir) // Folder sementara untuk generated query.
queryOutPath := filepath.Join(currentDir, "internal", "domain", "query_utils") queryOutPath := filepath.Join(
// Target folder Struct Model murni Anda currentDir,
modelOutPath := filepath.Join(currentDir, "internal", "domain") "internal",
"domain",
"query_utils",
)
_ = os.MkdirAll(queryOutPath, os.ModePerm) // Folder model.
_ = os.MkdirAll(modelOutPath, os.ModePerm) modelOutPath := filepath.Join(
currentDir,
"internal",
"domain",
)
if err := os.MkdirAll(queryOutPath, os.ModePerm); err != nil {
log.Fatalf(
"Gagal membuat folder query_utils: %v",
err,
)
}
if err := os.MkdirAll(modelOutPath, os.ModePerm); err != nil {
log.Fatalf(
"Gagal membuat folder domain: %v",
err,
)
}
// ---------------------------------------------------------
// SQL DB
// ---------------------------------------------------------
sqlDB, err := db.DB() sqlDB, err := db.DB()
if err != nil { if err != nil {
log.Fatalf("Gagal mengambil instance sql.DB: %v", err) log.Fatalf(
"Gagal mengambil instance sql.DB: %v",
err,
)
} }
// ---------------------------------------------------------
// Foreign Keys
// ---------------------------------------------------------
fkMetas := fetchForeignKeys(sqlDB) fkMetas := fetchForeignKeys(sqlDB)
log.Printf("Berhasil mendeteksi %d relasi Foreign Key fisik di database.\n", len(fkMetas))
log.Printf(
"Berhasil mendeteksi %d kolom Foreign Key fisik di database.",
len(fkMetas),
)
// ---------------------------------------------------------
// GORM Gen
// ---------------------------------------------------------
g := gen.NewGenerator(gen.Config{ g := gen.NewGenerator(gen.Config{
OutPath: queryOutPath, OutPath: queryOutPath,
ModelPkgPath: modelOutPath, ModelPkgPath: modelOutPath,
Mode: gen.WithoutContext, Mode: gen.WithoutContext,
FieldWithIndexTag: true, FieldWithIndexTag: true,
@ -53,174 +101,721 @@ func GenerateModel(table *string, db *gorm.DB) {
FieldNullable: true, FieldNullable: true,
FieldSignable: true, FieldSignable: true,
}) })
g.UseDB(db) g.UseDB(db)
rows, err := sqlDB.Query("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'") // ---------------------------------------------------------
// Get tables
// ---------------------------------------------------------
rows, err := sqlDB.Query(`
SELECT
table_name
FROM information_schema.tables
WHERE
table_schema = 'public'
AND table_type = 'BASE TABLE'
ORDER BY table_name
`)
if err != nil { if err != nil {
log.Fatalf("Gagal mengambil daftar tabel: %v", err) log.Fatalf(
"Gagal mengambil daftar tabel: %v",
err,
)
} }
defer rows.Close() defer rows.Close()
var tableNames []string var tableNames []string
for rows.Next() { for rows.Next() {
var tName string var tName string
if err := rows.Scan(&tName); err == nil && !strings.HasPrefix(tName, "gorm_") {
tableNames = append(tableNames, tName) if err := rows.Scan(&tName); err != nil {
} log.Printf(
"Gagal membaca nama tabel: %v",
err,
)
continue
} }
// Map untuk mengumpulkan seluruh konfigurasi gen.ModelOpt dari tiap tabel // Jangan generate tabel internal GORM.
tableRelationOpts := make(map[string][]gen.ModelOpt) if strings.HasPrefix(tName, "gorm_") {
continue
// Isi opsi relasi berdasarkan foreign key yang terdeteksi
for _, tName := range tableNames {
var relationOptions []gen.ModelOpt
for _, fk := range fkMetas {
// A. Relasi BELONGS TO
if fk.TableName == tName {
baseName := snakeToPascalCase(strings.TrimSuffix(fk.ColumnName, "_id"))
if baseName == "" {
baseName = snakeToPascalCase(fk.RefTable)
} }
// KUSTOMISASI 1: Tambahkan akhiran _Relation pada properti
propertyName := fmt.Sprintf("%s_Relation", baseName)
relationOptions = append(relationOptions, gen.FieldRelate( tableNames = append(
tableNames,
tName,
)
}
if err := rows.Err(); err != nil {
log.Fatalf(
"Gagal membaca daftar tabel: %v",
err,
)
}
log.Printf(
"Berhasil menemukan %d tabel.",
len(tableNames),
)
// ---------------------------------------------------------
// Group FK
//
// Satu constraint = satu relationship.
//
// Ini penting untuk composite FK.
// ---------------------------------------------------------
fkGroups := groupForeignKeys(fkMetas)
// ---------------------------------------------------------
// Relationship options per table
// ---------------------------------------------------------
tableRelationOpts := make(
map[string][]gen.ModelOpt,
)
// Digunakan untuk mencegah relationship yang benar-benar
// identik dibuat lebih dari satu kali.
//
// key:
//
// source table
// relation type
// property
// target table
// foreign keys
// references
//
seenRelations := make(
map[string]bool,
)
// ---------------------------------------------------------
// Build relationships
// ---------------------------------------------------------
for _, group := range fkGroups {
if len(group) == 0 {
continue
}
// Pastikan urutan composite FK konsisten.
sort.Slice(
group,
func(i, j int) bool {
return group[i].Ordinal < group[j].Ordinal
},
)
first := group[0]
// Pastikan source dan target table memang ada.
if !containsString(
tableNames,
first.TableName,
) {
log.Printf(
"WARNING: source table %s tidak ditemukan.",
first.TableName,
)
continue
}
if !containsString(
tableNames,
first.RefTable,
) {
log.Printf(
"WARNING: referenced table %s tidak ditemukan.",
first.RefTable,
)
continue
}
// -----------------------------------------------------
// Collect FK columns
// -----------------------------------------------------
foreignKeys := make(
[]string,
0,
len(group),
)
references := make(
[]string,
0,
len(group),
)
for _, fk := range group {
foreignKeys = append(
foreignKeys,
fk.ColumnName,
)
references = append(
references,
fk.RefColumn,
)
}
// -----------------------------------------------------
// BELONGS TO
// -----------------------------------------------------
belongsProperty := belongsToPropertyName(first)
belongsRelationKey := buildRelationKey(
first.TableName,
"belongs_to",
belongsProperty,
first.RefTable,
foreignKeys,
references,
)
if !seenRelations[belongsRelationKey] {
seenRelations[belongsRelationKey] = true
log.Printf(
"BELONGS TO: %s (%s) -> %s (%s) [%s]",
first.TableName,
strings.Join(foreignKeys, ", "),
first.RefTable,
strings.Join(references, ", "),
belongsProperty,
)
relation := gen.FieldRelate(
field.BelongsTo, field.BelongsTo,
propertyName, belongsProperty,
g.GenerateModel(fk.RefTable), g.GenerateModel(first.RefTable),
&field.RelateConfig{ &field.RelateConfig{
GORMTag: field.GormTag{ GORMTag: field.GormTag{
"foreignKey": []string{fk.ColumnName}, "foreignKey": foreignKeys,
"references": []string{fk.RefColumn}, "references": references,
}, },
}, },
)) )
tableRelationOpts[first.TableName] =
append(
tableRelationOpts[first.TableName],
relation,
)
} }
// B. Relasi HAS MANY // -----------------------------------------------------
if fk.RefTable == tName { // HAS MANY
// KUSTOMISASI 1: Tambahkan akhiran _Relation pada properti jamak // -----------------------------------------------------
propertyName := fmt.Sprintf("%ss_Relation", snakeToPascalCase(fk.TableName))
relationOptions = append(relationOptions, gen.FieldRelate( hasManyProperty := hasManyPropertyName(first)
hasManyRelationKey := buildRelationKey(
first.RefTable,
"has_many",
hasManyProperty,
first.TableName,
foreignKeys,
references,
)
if !seenRelations[hasManyRelationKey] {
seenRelations[hasManyRelationKey] = true
log.Printf(
"HAS MANY: %s -> %s (%s) [%s]",
first.RefTable,
first.TableName,
strings.Join(foreignKeys, ", "),
hasManyProperty,
)
relation := gen.FieldRelate(
field.HasMany, field.HasMany,
propertyName, hasManyProperty,
g.GenerateModel(fk.TableName), g.GenerateModel(first.TableName),
&field.RelateConfig{ &field.RelateConfig{
GORMTag: field.GormTag{ GORMTag: field.GormTag{
"foreignKey": []string{fk.ColumnName}, "foreignKey": foreignKeys,
"references": []string{fk.RefColumn}, "references": references,
}, },
}, },
)) )
tableRelationOpts[first.RefTable] =
append(
tableRelationOpts[first.RefTable],
relation,
)
} }
} }
tableRelationOpts[tName] = relationOptions
} // ---------------------------------------------------------
// Generate final models
// ---------------------------------------------------------
var finalModels []any var finalModels []any
allTableModels := make(map[string]any)
// Simpan generated model berdasarkan table.
//
// Kita tidak menggunakan gen.Model karena type tersebut
// memang tidak diekspos oleh gorm/gen.
//
// GenerateModel tetap dipanggil di sini untuk menghasilkan
// final model dengan relation options.
//
// Tidak ada kebutuhan untuk menyimpan return type-nya.
for _, tName := range tableNames { for _, tName := range tableNames {
opts := tableRelationOpts[tName] opts := tableRelationOpts[tName]
compiledModel := g.GenerateModel(tName, opts...)
allTableModels[tName] = compiledModel compiledModel := g.GenerateModel(
finalModels = append(finalModels, compiledModel) tName,
opts...,
)
finalModels = append(
finalModels,
compiledModel,
)
} }
// ---------------------------------------------------------
// ApplyBasic
// ---------------------------------------------------------
if table != nil && *table != "" { if table != nil && *table != "" {
if specModel, ok := allTableModels[*table]; ok { targetTable := strings.TrimSpace(*table)
g.ApplyBasic(specModel)
} else { if !containsString(
log.Fatalf("Tabel %s tidak ditemukan di database!", *table) tableNames,
} targetTable,
} else { ) {
g.ApplyBasic(finalModels...) log.Fatalf(
"Tabel %s tidak ditemukan di database!",
targetTable,
)
} }
// Eksekusi pembuatan file standar GORM Gen (.gen.go) // Generate model khusus table yang diminta.
specModel := g.GenerateModel(
targetTable,
tableRelationOpts[targetTable]...,
)
g.ApplyBasic(specModel)
log.Printf(
"Hanya generate model: %s",
targetTable,
)
} else {
g.ApplyBasic(
finalModels...,
)
log.Printf(
"Generate seluruh %d model.",
len(finalModels),
)
}
// ---------------------------------------------------------
// Execute
// ---------------------------------------------------------
g.Execute() g.Execute()
// Bersihkan utility kueri yang tidak dibutuhkan // ---------------------------------------------------------
_ = os.RemoveAll(queryOutPath) // Remove query utility
// ---------------------------------------------------------
// KUSTOMISASI 2: Hilangkan ekstensi ".gen.go" menjadi ".go" murni if err := os.RemoveAll(queryOutPath); err != nil {
err = renameGeneratedFiles(modelOutPath) log.Printf(
if err != nil { "Peringatan: gagal menghapus query_utils: %v",
log.Printf("Peringatan: Gagal mengubah nama beberapa file model: %v\n", err) err,
)
} }
log.Println("Selesai! Model berhasil dibuat dengan format nama tanpa .gen dan field bertanda _Relation.") // ---------------------------------------------------------
// Rename .gen.go -> .go
// ---------------------------------------------------------
if err := renameGeneratedFiles(modelOutPath); err != nil {
log.Printf(
"Peringatan: gagal mengubah nama file model: %v",
err,
)
}
log.Println(
"Selesai! Model berhasil dibuat.",
)
} }
// Fungsi untuk mencari berkas .gen.go dan mengubah namanya menjadi .go murni // -------------------------------------------------------------
func renameGeneratedFiles(dir string) error { // Group Foreign Keys
// -------------------------------------------------------------
//
// Satu constraint_name dianggap sebagai satu relationship.
//
// Contoh:
//
// FK:
// company_id -> company.id
// user_id -> user.id
//
// Jika berbeda constraint:
//
// fk_order_company
// fk_order_user
//
// maka akan menjadi dua relationship.
//
// Composite FK:
//
// FK (company_id, order_id)
// -> orders (company_id, id)
//
// menjadi satu relationship.
//
// -------------------------------------------------------------
func groupForeignKeys(
metas []ForeignKeyMeta,
) [][]ForeignKeyMeta {
groups := make(
map[string][]ForeignKeyMeta,
)
for _, meta := range metas {
key := fmt.Sprintf(
"%s|%s",
meta.TableName,
meta.ConstraintName,
)
groups[key] = append(
groups[key],
meta,
)
}
result := make(
[][]ForeignKeyMeta,
0,
len(groups),
)
for _, group := range groups {
sort.Slice(
group,
func(i, j int) bool {
return group[i].Ordinal < group[j].Ordinal
},
)
result = append(
result,
group,
)
}
// Untuk deterministic output.
sort.Slice(
result,
func(i, j int) bool {
if result[i][0].TableName != result[j][0].TableName {
return result[i][0].TableName <
result[j][0].TableName
}
return result[i][0].ConstraintName <
result[j][0].ConstraintName
},
)
return result
}
// -------------------------------------------------------------
// Build unique relation key
// -------------------------------------------------------------
func buildRelationKey(
sourceTable string,
relationType string,
propertyName string,
targetTable string,
foreignKeys []string,
references []string,
) string {
return strings.Join(
[]string{
sourceTable,
relationType,
propertyName,
targetTable,
strings.Join(foreignKeys, ","),
strings.Join(references, ","),
},
"|",
)
}
// -------------------------------------------------------------
// BelongsTo property name
// -------------------------------------------------------------
//
// user_id
// -> User_Relation
//
// customer_id
// -> Customer_Relation
//
// company_id
// -> Company_Relation
//
// -------------------------------------------------------------
func belongsToPropertyName(fk ForeignKeyMeta) string {
name := strings.TrimSuffix(
fk.ColumnName,
"_id",
)
if name == "" || name == fk.ColumnName {
name = fk.RefTable
}
return snakeToPascalCase(name) + "_Relation"
}
// -------------------------------------------------------------
// HasMany property name
// -------------------------------------------------------------
//
// orders -> Orders_Relation
//
// -------------------------------------------------------------
func hasManyPropertyName(fk ForeignKeyMeta) string {
tableName := snakeToPascalCase(fk.TableName)
columnName := strings.TrimSuffix(
fk.ColumnName,
"_id",
)
columnName = snakeToPascalCase(columnName)
return tableName +
"_By" +
columnName +
"_Relation"
}
// -------------------------------------------------------------
// Fetch Foreign Keys
// -------------------------------------------------------------
func fetchForeignKeys(
db *sql.DB,
) []ForeignKeyMeta {
query := `
SELECT
tc.constraint_name,
kcu.table_name,
kcu.column_name,
ccu.table_name AS referenced_table_name,
ccu.column_name AS referenced_column_name,
kcu.ordinal_position
FROM information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu
ON tc.constraint_name = kcu.constraint_name
AND tc.table_schema = kcu.table_schema
JOIN information_schema.referential_constraints AS rc
ON tc.constraint_name = rc.constraint_name
AND tc.table_schema = rc.constraint_schema
JOIN information_schema.key_column_usage AS ccu
ON rc.unique_constraint_name = ccu.constraint_name
AND rc.unique_constraint_schema = ccu.table_schema
AND kcu.ordinal_position = ccu.ordinal_position
WHERE
tc.constraint_type = 'FOREIGN KEY'
AND tc.table_schema = 'public'
ORDER BY
kcu.table_name,
tc.constraint_name,
kcu.ordinal_position
`
rows, err := db.Query(query)
if err != nil {
log.Printf(
"Gagal membaca metadata Foreign Key: %v",
err,
)
return nil
}
defer rows.Close()
var metas []ForeignKeyMeta
for rows.Next() {
var m ForeignKeyMeta
err := rows.Scan(
&m.ConstraintName,
&m.TableName,
&m.ColumnName,
&m.RefTable,
&m.RefColumn,
&m.Ordinal,
)
if err != nil {
log.Printf(
"Gagal membaca metadata Foreign Key: %v",
err,
)
continue
}
metas = append(
metas,
m,
)
}
if err := rows.Err(); err != nil {
log.Printf(
"Error membaca Foreign Key rows: %v",
err,
)
}
return metas
}
// -------------------------------------------------------------
// Rename generated files
// -------------------------------------------------------------
func renameGeneratedFiles(
dir string,
) error {
files, err := os.ReadDir(dir) files, err := os.ReadDir(dir)
if err != nil { if err != nil {
return err return err
} }
for _, file := range files { for _, file := range files {
if !file.IsDir() && strings.HasSuffix(file.Name(), ".gen.go") {
oldPath := filepath.Join(dir, file.Name())
newName := strings.Replace(file.Name(), ".gen.go", ".go", 1)
newPath := filepath.Join(dir, newName)
// Proses penggantian nama file fisik if file.IsDir() {
if err := os.Rename(oldPath, newPath); err != nil { continue
}
if !strings.HasSuffix(
file.Name(),
".gen.go",
) {
continue
}
oldPath := filepath.Join(
dir,
file.Name(),
)
newName := strings.TrimSuffix(
file.Name(),
".gen.go",
) + ".go"
newPath := filepath.Join(
dir,
newName,
)
if err := os.Rename(
oldPath,
newPath,
); err != nil {
return err return err
} }
} }
}
return nil return nil
} }
// Fungsi pembantu menarik metadata FK Postgres // -------------------------------------------------------------
func fetchForeignKeys(db *sql.DB) []ForeignKeyMeta { // Contains string
query := ` // -------------------------------------------------------------
SELECT
kcu.table_name AS table_name,
kcu.column_name AS column_name,
ccu.table_name AS referenced_table_name,
ccu.column_name AS referenced_column_name
FROM
information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu
ON tc.constraint_name = kcu.constraint_name
AND tc.table_schema = kcu.table_schema
JOIN information_schema.referential_constraints AS rc
ON tc.constraint_name = rc.constraint_name
AND tc.table_schema = rc.constraint_schema
JOIN information_schema.key_column_usage AS ccu
ON rc.unique_constraint_name = ccu.constraint_name
AND rc.unique_constraint_schema = ccu.table_schema
AND kcu.ordinal_position = ccu.ordinal_position
WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_schema = 'public';
`
rows, err := db.Query(query)
if err != nil {
log.Printf("Gagal membaca metadata Foreign Key: %v\n", err)
return nil
}
defer rows.Close()
var metas []ForeignKeyMeta func containsString(
for rows.Next() { items []string,
var m ForeignKeyMeta target string,
if err := rows.Scan(&m.TableName, &m.ColumnName, &m.RefTable, &m.RefColumn); err == nil { ) bool {
metas = append(metas, m)
for _, item := range items {
if item == target {
return true
} }
} }
return metas
return false
} }
func snakeToPascalCase(s string) string { // -------------------------------------------------------------
parts := strings.Split(s, "_") // snake_case -> PascalCase
// -------------------------------------------------------------
func snakeToPascalCase(
s string,
) string {
parts := strings.Split(
s,
"_",
)
for i, part := range parts { for i, part := range parts {
if len(part) > 0 {
parts[i] = strings.ToUpper(part[:1]) + part[1:] if len(part) == 0 {
continue
} }
parts[i] =
strings.ToUpper(part[:1]) +
part[1:]
} }
return strings.Join(parts, "")
return strings.Join(
parts,
"",
)
} }

View File

@ -987,3 +987,60 @@
{"level":"info","ts":"2026-08-22T14:10:17.638+0700","caller":"database/database.go:63","msg":"DB Master Connected"} {"level":"info","ts":"2026-08-22T14:10:17.638+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-22T14:10:17.639+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"} {"level":"info","ts":"2026-08-22T14:10:17.639+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-22T14:10:18.026+0700","caller":"database/database.go:86","msg":"DB Connection Done"} {"level":"info","ts":"2026-08-22T14:10:18.026+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-22T16:00:27.930+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-22T16:00:28.331+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-22T16:00:28.331+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-22T16:00:28.718+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-22T16:13:57.624+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-22T16:13:58.069+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-22T16:13:58.069+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-22T16:13:58.497+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-22T16:13:59.004+0700","caller":"handlers/handlers.go:126","msg":"Starting Apps"}
{"level":"info","ts":"2026-08-22T16:19:42.648+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-22T16:19:42.997+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-22T16:19:42.998+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-22T16:19:43.301+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-22T16:20:10.870+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-22T16:20:11.214+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-22T16:20:11.215+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-22T16:20:11.620+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-22T16:32:25.370+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-22T16:32:25.737+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-22T16:32:25.737+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-22T16:32:26.099+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-22T16:36:51.952+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-22T16:36:52.266+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-22T16:36:52.266+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-22T16:36:52.663+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-22T16:39:24.432+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-22T16:39:24.876+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-22T16:39:24.877+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-22T16:39:25.268+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-22T16:42:14.525+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-22T16:42:14.949+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-22T16:42:14.949+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-22T16:42:15.269+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-22T17:13:40.107+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-22T17:13:40.517+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-22T17:13:40.518+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-22T17:13:40.916+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-22T17:15:34.611+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-22T17:15:34.937+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-22T17:15:34.937+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-22T17:15:35.284+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-22T20:35:17.399+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-22T20:35:18.202+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-22T20:35:18.203+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-22T20:35:18.631+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-22T20:35:42.736+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-22T20:35:43.227+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-22T20:35:43.227+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-22T20:35:43.827+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-22T20:47:25.960+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-22T20:47:26.088+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-22T20:47:26.088+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-22T20:47:27.110+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-22T20:58:52.616+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-22T20:58:52.772+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-22T20:58:52.773+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-22T20:58:52.926+0700","caller":"database/database.go:86","msg":"DB Connection Done"}

File diff suppressed because it is too large Load Diff