ubah struktur
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
teguh nugroho 2026-08-25 16:49:27 +07:00
parent df1ead1804
commit 8354634117
41 changed files with 2512 additions and 108 deletions

View File

@ -25,7 +25,7 @@ func main() {
db.RegisterCallback()
// tables := "basic_pricing"
// migrations.GenerateModel(&tables, db.Get("master"))
// migrations.GenerateModel(nil, db.Get("master"))
// os.Exit(0)
//redis

View File

@ -35,6 +35,8 @@ func NewDatabase(config config.ConfigInterface, logger *zap.Logger, app_logger *
}
}
func (d *Database) Connect() {
d.dbLock.Lock()
defer d.dbLock.Unlock()
db := make(map[string]*gorm.DB)
username := d.Config.Get("database.username").(string)
password := d.Config.Get("database.password").(string)
@ -89,6 +91,8 @@ func (d *Database) RegisterCallback() {
d.Config.RegisterOnChangeCallback(d.ReloadDB)
}
func (d *Database) Get(key string) *gorm.DB {
d.dbLock.RLock()
defer d.dbLock.RUnlock()
if v, ok := d.DB[key]; ok {
return v
}

View File

@ -12,8 +12,7 @@ const TableNameBasicPricing = "basic_pricing"
// BasicPricing mapped from table <basic_pricing>
type BasicPricing struct {
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"`
ID string `gorm:"column:id;type:character(26);primaryKey;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"`
CitySourceID *string `gorm:"column:city_source_id;type:character(26);index:basic_pricing_city_source_id_idx,priority:1" json:"city_source_id"`
DistrictSourceID *string `gorm:"column:district_source_id;type:character(26);index:basic_pricing_district_source_id_idx,priority:1" json:"district_source_id"`
@ -37,9 +36,9 @@ type BasicPricing struct {
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"`
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:id;references:id" json:"package_type_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"`

View File

@ -8,12 +8,12 @@ const TableNameBasicPricingComponent = "basic_pricing_component"
// BasicPricingComponent mapped from table <basic_pricing_component>
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);primaryKey;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"`
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"`
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"`
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

View File

@ -12,7 +12,7 @@ const TableNameCity = "city"
// City mapped from table <city>
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);primaryKey;default:generate_ulid()" json:"id"`
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"`
CreatedBy *string `gorm:"column:created_by;type:character(26);index:city_created_by_idx,priority:1" json:"created_by"`
@ -24,8 +24,8 @@ type City struct {
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"`
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"`

View File

@ -12,7 +12,7 @@ const TableNameCostComponent = "cost_component"
// CostComponent mapped from table <cost_component>
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);primaryKey;default:generate_ulid()" json:"id"`
Name *string `gorm:"column:name;type:character varying(255);index:cost_component_name_idx,priority:1" json:"name"`
MerchantID *string `gorm:"column:merchant_id;type:character(26);index:cost_component_merchant_id_idx,priority:1" json:"merchant_id"`
CreatedBy *string `gorm:"column:created_by;type:character(26);index:cost_component_created_by_idx,priority:1" json:"created_by"`
@ -22,10 +22,11 @@ type CostComponent struct {
Inc *int32 `gorm:"column:inc;type:integer" json:"inc"`
Code *string `gorm:"column:code;type:character varying(100)" json:"code"`
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"` // 0. Input 1. Formula
ComponentType int32 `gorm:"column:component_type;type:integer;not null;comment:0. Input 1. Formula" json:"component_type"` // 0. Input 1. Formula
UnitType int32 `gorm:"column:unit_type;type:integer;not null;comment:0 Number 1. Percent" json:"unit_type"` // 0 Number 1. Percent
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"`
Users_Relation User `gorm:"foreignKey:created_by;references:id" json:"users_relation"`
}
// TableName CostComponent's table name

View File

@ -12,7 +12,7 @@ const TableNameDistrict = "district"
// District mapped from table <district>
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);primaryKey;default:generate_ulid()" json:"id"`
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"`
CityID *string `gorm:"column:city_id;type:character(26);index:district_city_id_idx,priority:1" json:"city_id"`
@ -23,10 +23,10 @@ type District struct {
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"`
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"`
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"`

View File

@ -12,7 +12,7 @@ const TableNameMerchant = "merchant"
// Merchant mapped from table <merchant>
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);primaryKey;default:generate_ulid()" json:"id"`
Name *string `gorm:"column:name;type:character varying(255);index:merchant_name_idx,priority:3" json:"name"`
Address *string `gorm:"column:address;type:character varying(500);index:merchant_name_idx,priority:1" json:"address"`
Email *string `gorm:"column:email;type:character varying(200);index:merchant_name_idx,priority:2" json:"email"`
@ -32,11 +32,11 @@ type Merchant struct {
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"`
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"`

View File

@ -12,7 +12,7 @@ const TableNameModa = "moda"
// Moda mapped from table <moda>
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);primaryKey;default:generate_ulid()" json:"id"`
Name *string `gorm:"column:name;type:character varying(255);index:moda_name_idx,priority:1" json:"name"`
MerchantID *string `gorm:"column:merchant_id;type:character(26);index:moda_merchant_id_idx,priority:1" json:"merchant_id"`
CreatedBy *string `gorm:"column:created_by;type:character(26);index:moda_created_by_idx,priority:1" json:"created_by"`

View File

@ -12,14 +12,14 @@ const TableNamePackageType = "package_type"
// PackageType mapped from table <package_type>
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);primaryKey;default:generate_ulid()" json:"id"`
Name *string `gorm:"column:name;type:character varying(255);index:package_type_name_idx,priority:1" json:"name"`
MerchantID *string `gorm:"column:merchant_id;type:character(26);index:package_type_merchant_id_idx,priority:1" json:"merchant_id"`
CreatedBy *string `gorm:"column:created_by;type:character(26)" json:"created_by"`
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"`
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"`
BasicPricing_ById_Relation []BasicPricing `gorm:"foreignKey:package_type_id;references:id" json:"basic_pricing_by_id_relation"`
Merchant_Relation *Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
}

View File

@ -12,7 +12,7 @@ const TableNamePostalCode = "postal_code"
// PostalCode mapped from table <postal_code>
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);primaryKey;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"`
ProvinceID *string `gorm:"column:province_id;type:character(26);index:postal_code_province_id_idx,priority:1" json:"province_id"`
CityID *string `gorm:"column:city_id;type:character(26);index:postal_code_city_id_idx,priority:1" json:"city_id"`
@ -25,12 +25,12 @@ type PostalCode struct {
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"`
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"`
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

View File

@ -0,0 +1,42 @@
// 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
import (
"time"
)
const TableNameProjectBase = "project_base"
// ProjectBase mapped from table <project_base>
type ProjectBase struct {
ID string `gorm:"column:id;type:character(26);primaryKey;default:generate_ulid()" json:"id"`
ProjectName *string `gorm:"column:project_name;type:character varying(255)" json:"project_name"`
MarketingID *string `gorm:"column:marketing_id;type:character(26)" json:"marketing_id"`
/*
0. Open
1. Progress
2. Approved
3. Rejected
4. Canceled
5. Closed
*/
Status *int32 `gorm:"column:status;type:integer;comment:0. Open\n1. Progress\n2. Approved\n3. Rejected\n4. Canceled\n5. Closed" json:"status"`
Code *string `gorm:"column:code;type:character varying(20)" json:"code"`
CustomersID *string `gorm:"column:customers_id;type:character(26)" json:"customers_id"`
Notes *string `gorm:"column:notes;type:text" json:"notes"`
ProjectStart *time.Time `gorm:"column:project_start;type:timestamp without time zone" json:"project_start"`
ProjectEnd *time.Time `gorm:"column:project_end;type:timestamp without time zone" json:"project_end"`
Total *float32 `gorm:"column:total;type:real" json:"total"`
CreatedBy *string `gorm:"column:created_by;type:character(26)" json:"created_by"`
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"`
UpdatedOn *time.Time `gorm:"column:updated_on;type:timestamp without time zone;default:now()" json:"updated_on"`
}
// TableName ProjectBase's table name
func (*ProjectBase) TableName() string {
return TableNameProjectBase
}

View File

@ -12,7 +12,7 @@ const TableNameProvince = "province"
// Province mapped from table <province>
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);primaryKey;default:generate_ulid()" json:"id"`
Name *string `gorm:"column:name;type:character varying(255);index:province_name_idx,priority:1" json:"name"`
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"`
@ -26,7 +26,7 @@ type Province struct {
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"`
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"`
}

View File

@ -12,7 +12,7 @@ const TableNameSubdistrict = "subdistrict"
// Subdistrict mapped from table <subdistrict>
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);primaryKey;default:generate_ulid()" json:"id"`
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"`
CityID *string `gorm:"column:city_id;type:character(26);index:subdistrit_city_id_idx,priority:1" json:"city_id"`
@ -26,11 +26,11 @@ type Subdistrict struct {
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"`
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"`
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

View File

@ -12,7 +12,7 @@ const TableNameUser = "users"
// User mapped from table <users>
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);primaryKey;default:generate_ulid()" json:"id"`
MerchantID *string `gorm:"column:merchant_id;type:character(26);index:users_merchant_id_idx,priority:1" json:"merchant_id"`
NickName *string `gorm:"column:nick_name;type:character varying(100);index:users_nick_name_idx,priority:2" json:"nick_name"`
Email *string `gorm:"column:email;type:character varying(200);index:users_nick_name_idx,priority:1" json:"email"`

View File

@ -12,7 +12,7 @@ const TableNameUsers = "users_"
// Users mapped from table <users_>
type Users struct {
ID string `gorm:"column:id;type:uuid;not null;default:gen_random_uuid()" json:"id"`
ID string `gorm:"column:id;type:uuid;primaryKey;default:gen_random_uuid()" json:"id"`
MerchantID *string `gorm:"column:merchant_id;type:uuid;index:idx_users_merchant,priority:1" json:"merchant_id"`
Username string `gorm:"column:username;type:character varying(50);not null;index:idx_users_username,priority:1" json:"username"`
Email string `gorm:"column:email;type:character varying(100);not null" json:"email"`

View File

@ -12,7 +12,7 @@ const TableNameUsersRole = "users_roles"
// UsersRole mapped from table <users_roles>
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);primaryKey;default:generate_ulid()" json:"id"`
Name *string `gorm:"column:name;type:character varying(255)" json:"name"`
MerchantID *string `gorm:"column:merchant_id;type:character(26)" json:"merchant_id"`
CreatedBy *string `gorm:"column:created_by;type:character(26)" json:"created_by"`

View File

@ -12,25 +12,25 @@ type BasicPricingComponentResponse struct {
}
type CreateBasicPricingRequest struct {
Name string `json:"name" binding:"required,min=2"`
ProvinceSourceID string `json:"province_source_id"`
CitySourceID string `json:"city_source_id"`
DistrictSourceID string `json:"district_source_id"`
SubdistrictSourceID string `json:"subdistrict_source_id"`
PostalCodeSourceID string `json:"postal_code_source_id"`
ProvinceDestinationID string `json:"province_destination_id"`
CityDestinationID string `json:"city_destination_id"`
DistrictDestinationID string `json:"district_destination_id"`
SubdistrictDestinationID string `json:"subdistrict_destination_id"`
PostalCodeDestinationID string `json:"postal_code_destination_id"`
PackageTypeID string `json:"package_type_id"`
ModaID string `json:"moda_id"`
Components []BasicPricingComponentRequest `json:"components"`
ProvinceSourceID string `json:"province_source_id" binding:"required"`
CitySourceID string `json:"city_source_id" binding:"required"`
DistrictSourceID string `json:"district_source_id" binding:"required"`
SubdistrictSourceID string `json:"subdistrict_source_id" binding:"required"`
PostalCodeSourceID string `json:"postal_code_source_id" binding:"required"`
ProvinceDestinationID string `json:"province_destination_id" binding:"required"`
CityDestinationID string `json:"city_destination_id" binding:"required"`
DistrictDestinationID string `json:"district_destination_id" binding:"required"`
SubdistrictDestinationID string `json:"subdistrict_destination_id" binding:"required"`
PostalCodeDestinationID string `json:"postal_code_destination_id" binding:"required"`
PackageTypeID string `json:"package_type_id" binding:"required"`
ModaID string `json:"moda_id" binding:"required"`
LeadTime string `json:"lead_time"`
MinimumWeight float32 `json:"minimum_weight"`
Components []BasicPricingComponentRequest `json:"components" binding:"required,dive"`
}
type CreateBasicPricingResponse struct {
ID string `json:"id"`
Name *string `json:"name"`
ProvinceSourceID *string `json:"province_source_id"`
CitySourceID *string `json:"city_source_id"`
DistrictSourceID *string `json:"district_source_id"`
@ -43,13 +43,14 @@ type CreateBasicPricingResponse struct {
PostalCodeDestinationID *string `json:"postal_code_destination_id"`
PackageTypeID *string `json:"package_type_id"`
ModaID *string `json:"moda_id"`
LeadTime *string `json:"lead_time"`
MinimumWeight *float32 `json:"minimum_weight"`
MerchantID *string `json:"merchant_id"`
Components []BasicPricingComponentResponse `json:"components"`
}
type BasicPricingFilterAllRequest struct {
ID string `json:"id" form:"id"`
Name string `json:"name" form:"name"`
ProvinceSourceID string `json:"province_source_id" form:"province_source_id"`
CitySourceID string `json:"city_source_id" form:"city_source_id"`
DistrictSourceID string `json:"district_source_id" form:"district_source_id"`

View File

@ -5,6 +5,7 @@ type CreateCostComponentRequest struct {
Code string `json:"code" binding:"required"`
Value string `json:"value" binding:"required"`
ComponentType int32 `json:"component_type" binding:""`
UnitType int32 `json:"unit_type" binding:""`
}
type CreateCostComponentResponse struct {
@ -14,6 +15,7 @@ type CreateCostComponentResponse struct {
Inc *int32 `json:"inc"`
Value *string `json:"value"`
ComponentType *int32 `json:"component_type"`
UnitType *int32 `json:"unit_type"`
MerchantID *string `json:"merchant_id"`
}
@ -30,6 +32,7 @@ type UpdateCostComponentRequest struct {
Code string `json:"code" binding:"required"`
Value string `json:"value" binding:"required"`
ComponentType int32 `json:"component_type"`
UnitType int32 `json:"unit_type"`
}
type MatchCostComponentRequest struct {

View File

@ -43,7 +43,7 @@ func (h *BasicPricingHandler) GetAll(c *gin.Context) {
}
var req dto.BasicPricingFilterAllRequest
if err := c.ShouldBindQuery(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
response.Error(c, http.StatusBadRequest, err.Error())
return
}
u := usecases.NewBasicPricingUsecase(h.Helper, *userid)

View File

@ -49,7 +49,7 @@ func (h *CityHandler) GetAll(c *gin.Context) {
}
var req dto.CityFilterAllRequest
if err := c.ShouldBindQuery(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
response.Error(c, http.StatusBadRequest, err.Error())
return
}
u := usecases.NewCityUsecase(h.Helper, *userid)

View File

@ -45,7 +45,7 @@ func (h *CostComponentHandler) GetAll(c *gin.Context) {
}
var req dto.CostComponentFilterAllRequest
if err := c.ShouldBindQuery(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
response.Error(c, http.StatusBadRequest, err.Error())
return
}
u := usecases.NewCostComponentUsecase(h.Helper, *userid)
@ -121,7 +121,7 @@ func (h *CostComponentHandler) Create(c *gin.Context) {
createdBy := userid.ID
u := usecases.NewCostComponentUsecase(h.Helper, *userid)
component, err := u.Create(req.Name, req.Code, req.Value, req.ComponentType, createdBy, merchantid)
component, err := u.Create(req.Name, req.Code, req.Value, req.ComponentType, req.UnitType, createdBy, merchantid)
if err != nil {
response.Error(c, http.StatusInternalServerError, err.Error())
return
@ -147,7 +147,7 @@ func (h *CostComponentHandler) Update(c *gin.Context) {
updatedBy := userid.ID
u := usecases.NewCostComponentUsecase(h.Helper, *userid)
component, err := u.Update(id, req.Name, req.Code, req.Value, req.ComponentType, updatedBy)
component, err := u.Update(id, req.Name, req.Code, req.Value, req.ComponentType, req.UnitType, updatedBy)
if err != nil {
response.Error(c, http.StatusInternalServerError, err.Error())
return

View File

@ -49,7 +49,7 @@ func (h *DistrictHandler) GetAll(c *gin.Context) {
}
var req dto.DistrictFilterAllRequest
if err := c.ShouldBindQuery(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
response.Error(c, http.StatusBadRequest, err.Error())
return
}
u := usecases.NewDistrictUsecase(h.Helper, *userid)

View File

@ -49,7 +49,7 @@ func (h *PostalCodeHandler) GetAll(c *gin.Context) {
}
var req dto.PostalCodeFilterAllRequest
if err := c.ShouldBindQuery(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
response.Error(c, http.StatusBadRequest, err.Error())
return
}
u := usecases.NewPostalCodeUsecase(h.Helper, *userid)

View File

@ -49,7 +49,7 @@ func (h *ProvinceHandler) GetAll(c *gin.Context) {
}
var req dto.ProvinceFilterAllRequest
if err := c.ShouldBindQuery(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
response.Error(c, http.StatusBadRequest, err.Error())
return
}
u := usecases.NewProvinceUsecase(h.Helper, *userid)

View File

@ -49,7 +49,7 @@ func (h *SubdistrictHandler) GetAll(c *gin.Context) {
}
var req dto.SubdistrictFilterAllRequest
if err := c.ShouldBindQuery(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
response.Error(c, http.StatusBadRequest, err.Error())
return
}
u := usecases.NewSubdistrictUsecase(h.Helper, *userid)

View File

@ -50,13 +50,18 @@ func (m *AuthMiddleware) Check() gin.HandlerFunc {
c.Abort()
return
}
if len(authHeader) > 0 && len(value) > 0 && parts[1] != value {
if len(parts) > 1 && len(value) > 0 && parts[1] != value {
response.Error(c, http.StatusUnauthorized, "Unauthorized")
c.Abort()
return
}
token_string = value
}
if token_string == "" {
response.Error(c, http.StatusUnauthorized, "Unauthorized")
c.Abort()
return
}
ctx := context.Background()
redis_exist := make(map[string]string)
m.Helper.Log().Info("session_login : " + token_string)

View File

@ -26,7 +26,9 @@ func NewAuthUsecase(helper helpers.HelperInterface) AuthUsecaseInterface {
func (u *AuthUsecase) Login(email string, password string) (token string, err error) {
var user []domain.User
db := u.Helper.GetDB("slave")
db.Model(&user).Where("email=?", email).Preload("UsersRole_Relation").Find(&user)
if err := db.Model(&user).Where("email=?", email).Preload("UsersRole_Relation").Find(&user).Error; err != nil {
return "", fmt.Errorf("User Not Found")
}
for _, v := range user {
pass := u.Helper.StringFromPtr(v.Password)
if u.Helper.VerifyPassword(pass, password) {
@ -45,13 +47,13 @@ func (u *AuthUsecase) Login(email string, password string) (token string, err er
//
key := fmt.Sprintf("session_login:%v:*", v.ID)
iter := u.Helper.GetRedis("slave").Scan(ctx, 0, key, 1000).Iterator()
iter := u.Helper.GetRedis("master").Scan(ctx, 0, key, 1000).Iterator()
for iter.Next(ctx) {
keys := iter.Val()
keys_ex := strings.Split(keys, ":")
//change to del if using single login
if keys_ex[1] == v.ID {
u.Helper.GetRedis("slave").Expire(ctx, keys, time.Duration(t)*time.Second)
u.Helper.GetRedis("master").Expire(ctx, keys, time.Duration(t)*time.Second)
return keys_ex[2], 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 {
resp := dto.CreateBasicPricingResponse{
ID: pricing.ID,
Name: pricing.Name,
ProvinceSourceID: pricing.ProvinceSourceID,
CitySourceID: pricing.CitySourceID,
DistrictSourceID: pricing.DistrictSourceID,
@ -64,6 +63,8 @@ func (u *BasicPricingUsecase) toResponse(pricing domain.BasicPricing, components
PostalCodeDestinationID: pricing.PostalCodeDestinationID,
PackageTypeID: pricing.PackageTypeID,
ModaID: pricing.ModaID,
LeadTime: pricing.LeadTime,
MinimumWeight: pricing.MinimumWeight,
MerchantID: pricing.MerchantID,
}
resp.Components = make([]dto.BasicPricingComponentResponse, 0, len(components))
@ -96,7 +97,7 @@ func (u *BasicPricingUsecase) GetAll(filter dto.BasicPricingFilterAllRequest) ([
}
}
tx.Model(&domain.BasicPricing{}).Count(&total)
tx.Order("name ASC")
tx.Order("id ASC")
if err := tx.Find(&pricings).Error; err != nil {
return nil, 0, err
}
@ -127,12 +128,11 @@ func (u *BasicPricingUsecase) GetList(req dto.DataTableRequest) (dto.DataTableRe
Joins("LEFT JOIN province AS pd ON basic_pricing.province_destination_id=pd.id").
Joins("LEFT JOIN city AS cd ON basic_pricing.city_destination_id=cd.id").
Joins("LEFT JOIN merchant ON basic_pricing.merchant_id=merchant.id")
if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
tx = tx.Where("basic_pricing.merchant_id IS NULL OR basic_pricing.merchant_id=?", u.AuthUser.MerchantID)
}
dt := datatable.NewDatatable(tx, req)
coldef := make([]dto.DataTableColDef, 0)
coldef = append(coldef, dto.DataTableColDef{
Field: "basic_pricing.name",
Alias: "name",
})
coldef = append(coldef, dto.DataTableColDef{
Field: "basic_pricing.id",
Alias: "id",
@ -145,6 +145,9 @@ func (u *BasicPricingUsecase) GetList(req dto.DataTableRequest) (dto.DataTableRe
func (u *BasicPricingUsecase) GetByID(id string) (dto.CreateBasicPricingResponse, error) {
var pricing domain.BasicPricing
db := u.Helper.GetDB("slave")
if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
db = db.Where("merchant_id IS NULL OR merchant_id=?", u.AuthUser.MerchantID)
}
if err := db.Where("id = ?", id).First(&pricing).Error; err != nil {
return dto.CreateBasicPricingResponse{}, err
}
@ -166,7 +169,6 @@ func (u *BasicPricingUsecase) Create(req dto.CreateBasicPricingRequest, createdB
err := db.Transaction(func(tx *gorm.DB) error {
pricing = domain.BasicPricing{
Name: &req.Name,
ProvinceSourceID: strPtr(req.ProvinceSourceID),
CitySourceID: strPtr(req.CitySourceID),
DistrictSourceID: strPtr(req.DistrictSourceID),
@ -179,6 +181,8 @@ func (u *BasicPricingUsecase) Create(req dto.CreateBasicPricingRequest, createdB
PostalCodeDestinationID: strPtr(req.PostalCodeDestinationID),
PackageTypeID: strPtr(req.PackageTypeID),
ModaID: strPtr(req.ModaID),
LeadTime: strPtr(req.LeadTime),
MinimumWeight: float32Ptr(req.MinimumWeight),
MerchantID: merchantid,
CreatedBy: &createdBy,
CreatedOn: &now,
@ -222,7 +226,6 @@ func (u *BasicPricingUsecase) Update(id string, req dto.CreateBasicPricingReques
return err
}
now := time.Now()
pricing.Name = &req.Name
pricing.ProvinceSourceID = strPtr(req.ProvinceSourceID)
pricing.CitySourceID = strPtr(req.CitySourceID)
pricing.DistrictSourceID = strPtr(req.DistrictSourceID)
@ -235,6 +238,8 @@ func (u *BasicPricingUsecase) Update(id string, req dto.CreateBasicPricingReques
pricing.PostalCodeDestinationID = strPtr(req.PostalCodeDestinationID)
pricing.PackageTypeID = strPtr(req.PackageTypeID)
pricing.ModaID = strPtr(req.ModaID)
pricing.LeadTime = strPtr(req.LeadTime)
pricing.MinimumWeight = float32Ptr(req.MinimumWeight)
pricing.UpdatedBy = &updatedBy
pricing.UpdatedOn = &now
@ -292,3 +297,10 @@ func strPtr(s string) *string {
}
return &s
}
func float32Ptr(f float32) *float32 {
if f == 0 {
return nil
}
return &f
}

View File

@ -62,6 +62,9 @@ func (u *CityUsecase) GetList(req dto.DataTableRequest) (dto.DataTableResponse,
tx := db.Table("city").
Joins("INNER JOIN province ON city.province_id=province.id").
Joins("LEFT JOIN merchant ON city.merchant_id=merchant.id")
if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
tx = tx.Where("city.merchant_id IS NULL OR city.merchant_id=?", u.AuthUser.MerchantID)
}
dt := datatable.NewDatatable(tx, req)
coldef := make([]dto.DataTableColDef, 0)
coldef = append(coldef, dto.DataTableColDef{
@ -92,6 +95,9 @@ func (u *CityUsecase) GetList(req dto.DataTableRequest) (dto.DataTableResponse,
func (u *CityUsecase) GetByID(id string) (domain.City, error) {
var city domain.City
db := u.Helper.GetDB("slave")
if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
db = db.Where("merchant_id IS NULL OR merchant_id=?", u.AuthUser.MerchantID)
}
if err := db.Where("id = ?", id).First(&city).Error; err != nil {
return domain.City{}, err
}

View File

@ -16,8 +16,8 @@ type CostComponentUsecaseInterface interface {
GetAll(filter dto.CostComponentFilterAllRequest) ([]domain.CostComponent, int64, error)
GetList(dto.DataTableRequest) (dto.DataTableResponse, error)
GetByID(id string) (domain.CostComponent, error)
Create(name string, code string, value string, componentType int32, createdBy string, merchantid *string) (domain.CostComponent, error)
Update(id string, name string, code string, value string, componentType int32, updatedBy string) (domain.CostComponent, error)
Create(name string, code string, value string, componentType int32, unitType int32, createdBy string, merchantid *string) (domain.CostComponent, error)
Update(id string, name string, code string, value string, componentType int32, unitType int32, updatedBy string) (domain.CostComponent, error)
Delete(id string) error
SortDown(id string) error
SortUp(id string) error
@ -63,6 +63,9 @@ func (u *CostComponentUsecase) GetList(req dto.DataTableRequest) (dto.DataTableR
db := u.Helper.GetDB("slave")
tx := db.Table("cost_component").
Joins("LEFT JOIN merchant ON cost_component.merchant_id=merchant.id")
if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
tx = tx.Where("cost_component.merchant_id IS NULL OR cost_component.merchant_id=?", u.AuthUser.MerchantID)
}
dt := datatable.NewDatatable(tx, req)
coldef := make([]dto.DataTableColDef, 0)
coldef = append(coldef, dto.DataTableColDef{
@ -101,13 +104,16 @@ func (u *CostComponentUsecase) GetList(req dto.DataTableRequest) (dto.DataTableR
func (u *CostComponentUsecase) GetByID(id string) (domain.CostComponent, error) {
var component domain.CostComponent
db := u.Helper.GetDB("slave")
if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
db = db.Where("merchant_id IS NULL OR merchant_id=?", u.AuthUser.MerchantID)
}
if err := db.Where("id = ?", id).First(&component).Error; err != nil {
return domain.CostComponent{}, err
}
return component, nil
}
func (u *CostComponentUsecase) Create(name string, code string, value string, componentType int32, createdBy string, merchantid *string) (domain.CostComponent, error) {
func (u *CostComponentUsecase) Create(name string, code string, value string, componentType int32, unitType int32, createdBy string, merchantid *string) (domain.CostComponent, error) {
now := time.Now()
db := u.Helper.GetDB("master")
@ -128,7 +134,8 @@ func (u *CostComponentUsecase) Create(name string, code string, value string, co
Code: &code,
Inc: &inc,
Value: &value,
ComponentType: &componentType,
ComponentType: componentType,
UnitType: unitType,
MerchantID: merchantid,
CreatedBy: &createdBy,
CreatedOn: &now,
@ -144,7 +151,7 @@ func (u *CostComponentUsecase) Create(name string, code string, value string, co
return component, nil
}
func (u *CostComponentUsecase) Update(id string, name string, code string, value string, componentType int32, updatedBy string) (domain.CostComponent, error) {
func (u *CostComponentUsecase) Update(id string, name string, code string, value string, componentType int32, unitType int32, updatedBy string) (domain.CostComponent, error) {
var component domain.CostComponent
db := u.Helper.GetDB("master")
err := db.Transaction(func(tx *gorm.DB) error {
@ -159,7 +166,8 @@ func (u *CostComponentUsecase) Update(id string, name string, code string, value
component.Name = &name
component.Code = &code
component.Value = &value
component.ComponentType = &componentType
component.ComponentType = componentType
component.UnitType = unitType
component.UpdatedBy = &updatedBy
component.UpdatedOn = &now
return tx.Save(&component).Error

View File

@ -63,6 +63,9 @@ func (u *DistrictUsecase) GetList(req dto.DataTableRequest) (dto.DataTableRespon
Joins("LEFT JOIN city ON district.city_id=city.id").
Joins("LEFT JOIN province ON district.province_id=province.id").
Joins("LEFT JOIN merchant ON district.merchant_id=merchant.id")
if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
tx = tx.Where("district.merchant_id IS NULL OR district.merchant_id=?", u.AuthUser.MerchantID)
}
dt := datatable.NewDatatable(tx, req)
coldef := make([]dto.DataTableColDef, 0)
coldef = append(coldef, dto.DataTableColDef{
@ -101,6 +104,9 @@ func (u *DistrictUsecase) GetList(req dto.DataTableRequest) (dto.DataTableRespon
func (u *DistrictUsecase) GetByID(id string) (domain.District, error) {
var district domain.District
db := u.Helper.GetDB("slave")
if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
db = db.Where("merchant_id IS NULL OR merchant_id=?", u.AuthUser.MerchantID)
}
if err := db.Where("id = ?", id).First(&district).Error; err != nil {
return domain.District{}, err
}

View File

@ -65,6 +65,9 @@ func (u *PostalCodeUsecase) GetList(req dto.DataTableRequest) (dto.DataTableResp
Joins("LEFT JOIN city ON postal_code.city_id=city.id").
Joins("LEFT JOIN province ON postal_code.province_id=province.id").
Joins("LEFT JOIN merchant ON postal_code.merchant_id=merchant.id")
if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
tx = tx.Where("postal_code.merchant_id IS NULL OR postal_code.merchant_id=?", u.AuthUser.MerchantID)
}
dt := datatable.NewDatatable(tx, req)
coldef := make([]dto.DataTableColDef, 0)
coldef = append(coldef, dto.DataTableColDef{
@ -119,6 +122,9 @@ func (u *PostalCodeUsecase) GetList(req dto.DataTableRequest) (dto.DataTableResp
func (u *PostalCodeUsecase) GetByID(id string) (domain.PostalCode, error) {
var postalCode domain.PostalCode
db := u.Helper.GetDB("slave")
if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
db = db.Where("merchant_id IS NULL OR merchant_id=?", u.AuthUser.MerchantID)
}
if err := db.Where("id = ?", id).First(&postalCode).Error; err != nil {
return domain.PostalCode{}, err
}

View File

@ -61,6 +61,9 @@ func (u *ProvinceUsecase) GetList(req dto.DataTableRequest) (dto.DataTableRespon
var response dto.DataTableResponse
db := u.Helper.GetDB("slave")
tx := db.Table("province").Joins("LEFT JOIN merchant ON province.merchant_id=merchant.id")
if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
tx = tx.Where("province.merchant_id IS NULL OR province.merchant_id=?", u.AuthUser.MerchantID)
}
dt := datatable.NewDatatable(tx, req)
coldef := make([]dto.DataTableColDef, 0)
coldef = append(coldef, dto.DataTableColDef{
@ -88,6 +91,9 @@ func (u *ProvinceUsecase) GetByID(id string) (domain.Province, error) {
var province domain.Province
db := u.Helper.GetDB("slave")
if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
db = db.Where("merchant_id IS NULL OR merchant_id=?", u.AuthUser.MerchantID)
}
if err := db.Where("id = ?", id).First(&province).Error; err != nil {
return domain.Province{}, err

View File

@ -64,6 +64,9 @@ func (u *SubdistrictUsecase) GetList(req dto.DataTableRequest) (dto.DataTableRes
Joins("LEFT JOIN city ON subdistrict.city_id=city.id").
Joins("LEFT JOIN province ON subdistrict.province_id=province.id").
Joins("LEFT JOIN merchant ON subdistrict.merchant_id=merchant.id")
if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
tx = tx.Where("subdistrict.merchant_id IS NULL OR subdistrict.merchant_id=?", u.AuthUser.MerchantID)
}
dt := datatable.NewDatatable(tx, req)
coldef := make([]dto.DataTableColDef, 0)
coldef = append(coldef, dto.DataTableColDef{
@ -110,6 +113,9 @@ func (u *SubdistrictUsecase) GetList(req dto.DataTableRequest) (dto.DataTableRes
func (u *SubdistrictUsecase) GetByID(id string) (domain.Subdistrict, error) {
var subdistrict domain.Subdistrict
db := u.Helper.GetDB("slave")
if u.AuthUser.UsersRole_Relation == nil || u.AuthUser.UsersRole_Relation.RoleKey != "SPM" {
db = db.Where("merchant_id IS NULL OR merchant_id=?", u.AuthUser.MerchantID)
}
if err := db.Where("id = ?", id).First(&subdistrict).Error; err != nil {
return domain.Subdistrict{}, err
}

View File

@ -116,11 +116,11 @@ func GenerateModel(table *string, db *gorm.DB) {
WHERE
table_schema = 'public'
AND table_type = 'BASE TABLE'
AND table_name = '%v'
AND table_name = '%s'
ORDER BY table_name
`, table)
`, *table)
} else {
qInfo = fmt.Sprintf(`
qInfo = `
SELECT
table_name
FROM information_schema.tables
@ -128,8 +128,9 @@ func GenerateModel(table *string, db *gorm.DB) {
table_schema = 'public'
AND table_type = 'BASE TABLE'
ORDER BY table_name
`, table)
`
}
rows, err := sqlDB.Query(qInfo)
if err != nil {
log.Fatalf(

View File

@ -8,6 +8,11 @@ import (
"gorm.io/gorm"
)
var allowedDirections = map[string]bool{
"ASC": true,
"DESC": true,
}
type DatatableInterface interface {
Render(coldef []dto.DataTableColDef) dto.DataTableResponse
}
@ -35,38 +40,38 @@ func (d *Datatable) Render(coldef []dto.DataTableColDef) dto.DataTableResponse {
}
d.DB.Select(selectAlias)
//global filter
var g *gorm.DB
is_filtering := false
if len(d.Req.Search.Value) > 0 {
g := d.DB.Session(&gorm.Session{})
for _, vcol := range d.Req.Columns {
if vcol.Searchable {
for _, v := range coldef {
if v.Alias == vcol.Data {
g.Or(fmt.Sprintf("%v::TEXT ILIKE '%%%v%%'", v.Field, d.Req.Search.Value))
is_filtering = true
g = g.Or(fmt.Sprintf("%v::TEXT ILIKE ?", v.Field), "%"+d.Req.Search.Value+"%")
}
}
}
}
}
if is_filtering {
d.DB.Where(g)
}
//order
if len(d.Req.Order) > 0 {
for _, vOrder := range d.Req.Order {
dir := strings.ToUpper(vOrder.Dir)
if !allowedDirections[dir] {
dir = "ASC"
}
for _, vcol := range d.Req.Columns {
if vcol.Orderable && vOrder.Column == vcol.Data {
for _, v := range coldef {
if v.Alias == vcol.Data {
d.DB.Order(fmt.Sprintf("%v %v", v.Field, strings.ToUpper(vOrder.Dir)))
d.DB.Order(fmt.Sprintf("%v %v", v.Field, dir))
}
}
}
}
}
}
//order
//additional filter
if len(d.Req.AdditionalFilter) > 0 {
for k, vFilter := range d.Req.AdditionalFilter {
for _, v := range coldef {

View File

@ -404,12 +404,14 @@ func (i *Importer) insertBatch(db *gorm.DB, batch []RowData) error {
return nil
}
tableName := batch[0].TableName()
return db.Transaction(func(tx *gorm.DB) error {
for _, item := range batch {
if err := db.Table(tableName).Create(item).Error; err != nil {
if err := tx.Table(tableName).Create(item).Error; err != nil {
return err
}
}
return nil
})
}
func (i *Importer) GetTemplate() string {

View File

@ -50,10 +50,13 @@ func SuccessWithMessage(c *gin.Context, message string, data interface{}) {
}
func PaginatedResponse(c *gin.Context, items interface{}, total, page, limit int) {
totalPages := total / limit
var totalPages int
if limit > 0 {
totalPages = total / limit
if total%limit > 0 {
totalPages++
}
}
c.JSON(http.StatusOK, APIResponse{
Success: true,

View File

@ -1048,3 +1048,235 @@
{"level":"info","ts":"2026-08-25T12:59:46.984+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T12:59:46.985+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T12:59:47.175+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:14:48.905+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:14:49.655+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:14:49.656+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:14:50.058+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:15:55.756+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:15:55.928+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:15:55.929+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:15:56.098+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:16:13.221+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:16:13.379+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:16:13.379+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:16:13.535+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:16:30.865+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:16:31.623+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:16:31.623+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:16:32.508+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:16:47.362+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:16:47.920+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:16:47.921+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:16:48.250+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:17:05.930+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:17:06.129+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:17:06.129+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:17:06.765+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:17:33.486+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:17:33.712+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:17:33.712+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:17:34.047+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:20:29.250+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:20:29.512+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:20:29.512+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:20:29.676+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:21:15.117+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:21:15.476+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:21:15.476+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:21:15.662+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:22:05.356+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:22:06.303+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:22:06.303+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:22:07.186+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:22:51.156+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:22:52.053+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:22:52.054+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:22:52.909+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:23:27.987+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:23:28.145+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:23:28.145+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:23:28.315+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:24:02.151+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:24:02.363+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:24:02.363+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:24:02.541+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:25:06.526+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:25:06.713+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:25:06.713+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:25:06.898+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:25:22.623+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:25:22.799+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:25:22.799+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:25:22.967+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:28:46.586+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:28:46.782+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:28:46.782+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:28:46.974+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:29:20.091+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:29:20.260+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:29:20.260+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:29:20.421+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:36:08.766+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:36:09.029+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:36:09.029+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:36:09.518+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:37:58.514+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:37:59.251+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:37:59.251+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:38:00.042+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:38:09.140+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:38:09.582+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:38:09.583+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:38:09.917+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:42:52.351+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:42:53.643+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:42:53.643+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:42:55.049+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:43:31.819+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:43:32.058+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:43:32.059+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:43:32.255+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:44:02.710+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:44:03.252+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:44:03.252+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:44:03.647+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:47:02.439+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:47:03.295+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:47:03.296+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:47:04.880+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:49:36.189+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:49:36.510+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:49:36.511+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:49:37.138+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:49:55.323+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:49:58.710+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:49:58.710+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:50:00.916+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:51:37.751+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:51:38.008+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:51:38.008+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:51:38.273+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:52:06.324+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:52:06.852+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:52:06.853+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:52:07.375+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:53:27.885+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:53:28.074+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:53:28.074+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:53:28.299+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:54:17.404+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:54:18.640+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:54:18.640+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:54:19.319+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:54:38.440+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:54:39.691+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:54:39.692+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:54:41.254+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:55:11.531+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:55:11.994+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:55:11.994+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:55:12.167+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:56:58.728+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:56:58.913+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:56:58.913+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:56:59.083+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:58:06.304+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:58:06.706+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:58:06.706+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:58:06.870+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T14:58:34.609+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T14:58:34.823+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T14:58:34.823+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T14:58:35.016+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T15:01:16.370+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T15:01:16.836+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T15:01:16.837+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T15:01:17.014+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T15:05:48.205+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T15:05:48.560+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T15:05:48.560+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T15:05:48.909+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T15:08:12.741+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T15:08:12.920+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T15:08:12.920+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T15:08:13.111+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T15:09:25.951+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T15:09:26.138+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T15:09:26.139+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T15:09:26.313+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T15:10:41.344+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T15:10:41.523+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T15:10:41.523+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T15:10:41.676+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T15:12:23.489+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T15:12:23.679+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T15:12:23.679+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T15:12:23.837+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T15:16:40.136+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T15:16:40.375+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T15:16:40.375+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T15:16:40.565+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T15:17:13.469+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T15:17:13.791+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T15:17:13.792+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T15:17:14.026+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T15:22:31.915+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T15:22:32.452+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T15:22:32.452+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T15:22:32.723+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T15:23:00.067+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T15:23:00.741+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T15:23:00.746+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T15:23:01.028+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T15:45:13.752+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T15:45:13.958+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T15:45:13.958+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T15:45:14.131+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T15:55:39.519+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T15:55:39.833+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T15:55:39.834+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T15:55:40.004+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T16:03:01.742+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T16:03:01.972+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T16:03:01.972+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T16:03:02.374+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T16:03:22.197+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T16:03:22.377+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T16:03:22.378+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T16:03:22.538+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T16:04:01.900+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T16:04:02.146+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T16:04:02.146+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T16:04:02.360+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T16:05:09.131+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T16:05:09.316+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T16:05:09.316+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T16:05:09.486+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T16:05:53.427+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T16:05:53.663+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T16:05:53.663+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T16:05:53.882+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T16:06:36.142+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T16:06:36.330+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T16:06:36.330+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T16:06:36.492+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T16:07:11.030+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T16:07:11.228+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T16:07:11.228+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T16:07:11.420+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T16:11:57.834+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T16:11:58.181+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T16:11:58.182+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T16:11:58.464+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T16:12:10.325+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T16:12:10.610+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T16:12:10.610+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T16:12:10.769+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T16:14:02.898+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T16:14:03.099+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T16:14:03.099+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T16:14:03.296+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
{"level":"info","ts":"2026-08-25T16:16:53.911+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
{"level":"info","ts":"2026-08-25T16:16:54.090+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
{"level":"info","ts":"2026-08-25T16:16:54.090+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
{"level":"info","ts":"2026-08-25T16:16:54.250+0700","caller":"database/database.go:86","msg":"DB Connection Done"}

File diff suppressed because it is too large Load Diff