commit
This commit is contained in:
parent
0b52645074
commit
8855495bb4
27
.env.example
Normal file
27
.env.example
Normal file
@ -0,0 +1,27 @@
|
||||
# Database Configuration (Master - Write via PgBouncer)
|
||||
DB_HOST=145.79.11.200
|
||||
DB_PORT=6432
|
||||
DB_USER=cargo_admin
|
||||
DB_PASSWORD=your-password
|
||||
DB_NAME=cargo_erp
|
||||
DB_SSLMODE=disable
|
||||
|
||||
# Database Configuration (Slave - Read via PgBouncer Replicas)
|
||||
DB_READ_HOST=145.79.11.200
|
||||
DB_READ_PORT=6433
|
||||
|
||||
# Redis Configuration
|
||||
REDIS_URL=redis://:your-redis-password@145.79.11.200:6379
|
||||
|
||||
# JWT Configuration
|
||||
JWT_SECRET=your-secret-key-change-in-production
|
||||
|
||||
# Application Configuration
|
||||
APP_PORT=8080
|
||||
APP_ENV=development
|
||||
|
||||
# MinIO Configuration
|
||||
MINIO_ENDPOINT=145.79.11.200:9000
|
||||
MINIO_ACCESS_KEY=minio_admin
|
||||
MINIO_SECRET_KEY=Minio!2026qwe
|
||||
MINIO_BUCKET=cargo-attachments
|
||||
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
notes.txt
|
||||
_internal/
|
||||
**/*.json
|
||||
22
Dockerfile
Normal file
22
Dockerfile
Normal file
@ -0,0 +1,22 @@
|
||||
FROM golang:1.22-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY go.mod go.sum* ./
|
||||
RUN go mod download
|
||||
|
||||
COPY . .
|
||||
RUN go mod tidy
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o /app/server ./cmd/api
|
||||
|
||||
FROM alpine:latest
|
||||
|
||||
RUN apk --no-cache add ca-certificates wget
|
||||
|
||||
WORKDIR /root/
|
||||
|
||||
COPY --from=builder /app/server .
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
CMD ["./server"]
|
||||
35
cmd/api/internal/domain/city.go
Normal file
35
cmd/api/internal/domain/city.go
Normal file
@ -0,0 +1,35 @@
|
||||
// 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 TableNameCity = "city"
|
||||
|
||||
// City mapped from table <city>
|
||||
type City struct {
|
||||
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"`
|
||||
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"`
|
||||
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"`
|
||||
PostalCodes_Relation []PostalCode `gorm:"foreignKey:city_id;references:id" json:"postal_codes_relation"`
|
||||
Subdistricts_Relation []Subdistrict `gorm:"foreignKey:city_id;references:id" json:"subdistricts_relation"`
|
||||
Districts_Relation []District `gorm:"foreignKey:city_id;references:id" json:"districts_relation"`
|
||||
Province_Relation Province `gorm:"foreignKey:province_id;references:id" json:"province_relation"`
|
||||
Merchants_Relation []Merchant `gorm:"foreignKey:city_id;references:id" json:"merchants_relation"`
|
||||
CreatedBy_Relation User `gorm:"foreignKey:created_by;references:id" json:"created_by_relation"`
|
||||
Merchant_Relation Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
|
||||
}
|
||||
|
||||
// TableName City's table name
|
||||
func (*City) TableName() string {
|
||||
return TableNameCity
|
||||
}
|
||||
29
cmd/api/internal/domain/cost_component.go
Normal file
29
cmd/api/internal/domain/cost_component.go
Normal file
@ -0,0 +1,29 @@
|
||||
// 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 TableNameCostComponent = "cost_component"
|
||||
|
||||
// CostComponent mapped from table <cost_component>
|
||||
type CostComponent struct {
|
||||
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"`
|
||||
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"`
|
||||
Inc *string `gorm:"column:inc;type:character varying" json:"inc"`
|
||||
Code *string `gorm:"column:code;type:character varying(100)" json:"code"`
|
||||
}
|
||||
|
||||
// TableName CostComponent's table name
|
||||
func (*CostComponent) TableName() string {
|
||||
return TableNameCostComponent
|
||||
}
|
||||
36
cmd/api/internal/domain/district.go
Normal file
36
cmd/api/internal/domain/district.go
Normal file
@ -0,0 +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
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const TableNameDistrict = "district"
|
||||
|
||||
// District mapped from table <district>
|
||||
type District struct {
|
||||
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"`
|
||||
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"`
|
||||
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"`
|
||||
MerchantID *string `gorm:"column:merchant_id;type:character(26)" json:"merchant_id"`
|
||||
PostalCodes_Relation []PostalCode `gorm:"foreignKey:district_id;references:id" json:"postal_codes_relation"`
|
||||
Subdistricts_Relation []Subdistrict `gorm:"foreignKey:district_id;references:id" json:"subdistricts_relation"`
|
||||
Province_Relation Province `gorm:"foreignKey:province_id;references:id" json:"province_relation"`
|
||||
City_Relation City `gorm:"foreignKey:city_id;references:id" json:"city_relation"`
|
||||
Merchants_Relation []Merchant `gorm:"foreignKey:district_id;references:id" json:"merchants_relation"`
|
||||
CreatedBy_Relation User `gorm:"foreignKey:created_by;references:id" json:"created_by_relation"`
|
||||
Merchant_Relation Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
|
||||
}
|
||||
|
||||
// TableName District's table name
|
||||
func (*District) TableName() string {
|
||||
return TableNameDistrict
|
||||
}
|
||||
50
cmd/api/internal/domain/merchant.go
Normal file
50
cmd/api/internal/domain/merchant.go
Normal file
@ -0,0 +1,50 @@
|
||||
// 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 TableNameMerchant = "merchant"
|
||||
|
||||
// Merchant mapped from table <merchant>
|
||||
type Merchant struct {
|
||||
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"`
|
||||
Telp *string `gorm:"column:telp;type:character varying(50);index:merchant_name_idx,priority:4" json:"telp"`
|
||||
AdditionalInformation *string `gorm:"column:additional_information;type:jsonb;index:merchant_additional_information_idx,priority:1;default:{}" json:"additional_information"`
|
||||
Active *bool `gorm:"column:active;type:boolean;default:true" json:"active"`
|
||||
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"`
|
||||
ProvinceID *string `gorm:"column:province_id;type:character(26);index:merchant_province_id_idx,priority:1" json:"province_id"`
|
||||
CityID *string `gorm:"column:city_id;type:character(26);index:merchant_city_id_idx,priority:1" json:"city_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"`
|
||||
PostalCode *string `gorm:"column:postal_code;type:character(26);index:merchant_postal_code_idx,priority:1" json:"postal_code"`
|
||||
Province_Relation *Province `gorm:"foreignKey:province_id;references:id" json:"province_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"`
|
||||
Subdistrict_Relation *Subdistrict `gorm:"foreignKey:subdistrict_id;references:id" json:"subdistrict_relation"`
|
||||
UsersRoless_Relation []*UsersRole `gorm:"foreignKey:merchant_id;references:id" json:"users_roless_relation"`
|
||||
Modas_Relation []*Moda `gorm:"foreignKey:merchant_id;references:id" json:"modas_relation"`
|
||||
PackageTypes_Relation []*PackageType `gorm:"foreignKey:merchant_id;references:id" json:"package_types_relation"`
|
||||
Userss_Relation []*User `gorm:"foreignKey:merchant_id;references:id" json:"userss_relation"`
|
||||
CreatedBy_Relation *User `gorm:"foreignKey:created_by;references:id" json:"created_by_relation"`
|
||||
Provinces_Relation []*Province `gorm:"foreignKey:merchant_id;references:id" json:"provinces_relation"`
|
||||
Citys_Relation []*City `gorm:"foreignKey:merchant_id;references:id" json:"citys_relation"`
|
||||
Districts_Relation []*District `gorm:"foreignKey:merchant_id;references:id" json:"districts_relation"`
|
||||
Subdistricts_Relation []*Subdistrict `gorm:"foreignKey:merchant_id;references:id" json:"subdistricts_relation"`
|
||||
PostalCodes_Relation []*PostalCode `gorm:"foreignKey:merchant_id;references:id" json:"postal_codes_relation"`
|
||||
}
|
||||
|
||||
// TableName Merchant's table name
|
||||
func (*Merchant) TableName() string {
|
||||
return TableNameMerchant
|
||||
}
|
||||
28
cmd/api/internal/domain/moda.go
Normal file
28
cmd/api/internal/domain/moda.go
Normal file
@ -0,0 +1,28 @@
|
||||
// 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 TableNameModa = "moda"
|
||||
|
||||
// Moda mapped from table <moda>
|
||||
type Moda struct {
|
||||
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"`
|
||||
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"`
|
||||
Merchant_Relation Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
|
||||
}
|
||||
|
||||
// TableName Moda's table name
|
||||
func (*Moda) TableName() string {
|
||||
return TableNameModa
|
||||
}
|
||||
28
cmd/api/internal/domain/package_type.go
Normal file
28
cmd/api/internal/domain/package_type.go
Normal file
@ -0,0 +1,28 @@
|
||||
// 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 TableNamePackageType = "package_type"
|
||||
|
||||
// PackageType mapped from table <package_type>
|
||||
type PackageType struct {
|
||||
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"`
|
||||
Merchant_Relation Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
|
||||
}
|
||||
|
||||
// TableName PackageType's table name
|
||||
func (*PackageType) TableName() string {
|
||||
return TableNamePackageType
|
||||
}
|
||||
37
cmd/api/internal/domain/postal_code.go
Normal file
37
cmd/api/internal/domain/postal_code.go
Normal file
@ -0,0 +1,37 @@
|
||||
// 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 TableNamePostalCode = "postal_code"
|
||||
|
||||
// PostalCode mapped from table <postal_code>
|
||||
type PostalCode struct {
|
||||
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"`
|
||||
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"`
|
||||
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"`
|
||||
UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"`
|
||||
UpdatedOn *string `gorm:"column:updated_on;type:character varying" json:"updated_on"`
|
||||
MerchantID *string `gorm:"column:merchant_id;type:character(26)" json:"merchant_id"`
|
||||
Province_Relation Province `gorm:"foreignKey:province_id;references:id" json:"province_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"`
|
||||
Subdistrict_Relation Subdistrict `gorm:"foreignKey:subdistrict_id;references:id" json:"subdistrict_relation"`
|
||||
CreatedBy_Relation User `gorm:"foreignKey:created_by;references:id" json:"created_by_relation"`
|
||||
Merchant_Relation Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
|
||||
}
|
||||
|
||||
// TableName PostalCode's table name
|
||||
func (*PostalCode) TableName() string {
|
||||
return TableNamePostalCode
|
||||
}
|
||||
34
cmd/api/internal/domain/province.go
Normal file
34
cmd/api/internal/domain/province.go
Normal file
@ -0,0 +1,34 @@
|
||||
// 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 TableNameProvince = "province"
|
||||
|
||||
// Province mapped from table <province>
|
||||
type Province struct {
|
||||
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"`
|
||||
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"`
|
||||
MerchantID *string `gorm:"column:merchant_id;type:character(26)" json:"merchant_id"`
|
||||
PostalCodes_Relation []PostalCode `gorm:"foreignKey:province_id;references:id" json:"postal_codes_relation"`
|
||||
Subdistricts_Relation []Subdistrict `gorm:"foreignKey:province_id;references:id" json:"subdistricts_relation"`
|
||||
Districts_Relation []District `gorm:"foreignKey:province_id;references:id" json:"districts_relation"`
|
||||
Citys_Relation []City `gorm:"foreignKey:province_id;references:id" json:"citys_relation"`
|
||||
Merchants_Relation []Merchant `gorm:"foreignKey:province_id;references:id" json:"merchants_relation"`
|
||||
CreatedBy_Relation User `gorm:"foreignKey:created_by;references:id" json:"created_by_relation"`
|
||||
Merchant_Relation Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
|
||||
}
|
||||
|
||||
// TableName Province's table name
|
||||
func (*Province) TableName() string {
|
||||
return TableNameProvince
|
||||
}
|
||||
37
cmd/api/internal/domain/subdistrict.go
Normal file
37
cmd/api/internal/domain/subdistrict.go
Normal file
@ -0,0 +1,37 @@
|
||||
// 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 TableNameSubdistrict = "subdistrict"
|
||||
|
||||
// Subdistrict mapped from table <subdistrict>
|
||||
type Subdistrict struct {
|
||||
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"`
|
||||
DistrictID *string `gorm:"column:district_id;type:character(26);index:subdistrit_district_id_idx,priority:1" json:"district_id"`
|
||||
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"`
|
||||
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"`
|
||||
MerchantID *string `gorm:"column:merchant_id;type:character(26)" json:"merchant_id"`
|
||||
PostalCodes_Relation []PostalCode `gorm:"foreignKey:subdistrict_id;references:id" json:"postal_codes_relation"`
|
||||
Province_Relation Province `gorm:"foreignKey:province_id;references:id" json:"province_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"`
|
||||
Merchants_Relation []Merchant `gorm:"foreignKey:subdistrict_id;references:id" json:"merchants_relation"`
|
||||
CreatedBy_Relation User `gorm:"foreignKey:created_by;references:id" json:"created_by_relation"`
|
||||
Merchant_Relation Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
|
||||
}
|
||||
|
||||
// TableName Subdistrict's table name
|
||||
func (*Subdistrict) TableName() string {
|
||||
return TableNameSubdistrict
|
||||
}
|
||||
41
cmd/api/internal/domain/users.go
Normal file
41
cmd/api/internal/domain/users.go
Normal file
@ -0,0 +1,41 @@
|
||||
// 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 TableNameUser = "users"
|
||||
|
||||
// User mapped from table <users>
|
||||
type User struct {
|
||||
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"`
|
||||
Password *string `gorm:"column:password;type:character varying(300)" json:"password"`
|
||||
IsActive *bool `gorm:"column:is_active;type:boolean;default:true" json:"is_active"`
|
||||
UsersRoleID *string `gorm:"column:users_role_id;type:character(26)" json:"users_role_id"`
|
||||
Blocked *bool `gorm:"column:blocked;type:boolean" json:"blocked"`
|
||||
BlockedNotes *string `gorm:"column:blocked_notes;type:character varying(500)" json:"blocked_notes"`
|
||||
CreatedBy *string `gorm:"column:created_by;type:character(26);index:users_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"`
|
||||
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"`
|
||||
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"`
|
||||
Merchants_Relation []Merchant `gorm:"foreignKey:created_by;references:id" json:"merchants_relation"`
|
||||
Provinces_Relation []Province `gorm:"foreignKey:created_by;references:id" json:"provinces_relation"`
|
||||
Citys_Relation []City `gorm:"foreignKey:created_by;references:id" json:"citys_relation"`
|
||||
Districts_Relation []District `gorm:"foreignKey:created_by;references:id" json:"districts_relation"`
|
||||
Subdistricts_Relation []Subdistrict `gorm:"foreignKey:created_by;references:id" json:"subdistricts_relation"`
|
||||
PostalCodes_Relation []PostalCode `gorm:"foreignKey:created_by;references:id" json:"postal_codes_relation"`
|
||||
}
|
||||
|
||||
// TableName User's table name
|
||||
func (*User) TableName() string {
|
||||
return TableNameUser
|
||||
}
|
||||
29
cmd/api/internal/domain/users_.go
Normal file
29
cmd/api/internal/domain/users_.go
Normal file
@ -0,0 +1,29 @@
|
||||
// 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 TableNameUsers = "users_"
|
||||
|
||||
// Users mapped from table <users_>
|
||||
type Users struct {
|
||||
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"`
|
||||
Password string `gorm:"column:password;type:character varying(200);not null" json:"password"`
|
||||
Role string `gorm:"column:role;type:character varying(20);not null;default:cashier" json:"role"`
|
||||
IsActive *bool `gorm:"column:is_active;type:boolean;default:true" json:"is_active"`
|
||||
CreatedAt *time.Time `gorm:"column:created_at;type:timestamp without time zone;default:now()" json:"created_at"`
|
||||
UpdatedAt *time.Time `gorm:"column:updated_at;type:timestamp without time zone;default:now()" json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName Users's table name
|
||||
func (*Users) TableName() string {
|
||||
return TableNameUsers
|
||||
}
|
||||
30
cmd/api/internal/domain/users_roles.go
Normal file
30
cmd/api/internal/domain/users_roles.go
Normal file
@ -0,0 +1,30 @@
|
||||
// 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 TableNameUsersRole = "users_roles"
|
||||
|
||||
// UsersRole mapped from table <users_roles>
|
||||
type UsersRole struct {
|
||||
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"`
|
||||
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"`
|
||||
RoleKey string `gorm:"column:role_key;type:character varying(20);not null" json:"role_key"`
|
||||
Merchant_Relation Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
|
||||
Userss_Relation []User `gorm:"foreignKey:users_role_id;references:id" json:"userss_relation"`
|
||||
}
|
||||
|
||||
// TableName UsersRole's table name
|
||||
func (*UsersRole) TableName() string {
|
||||
return TableNameUsersRole
|
||||
}
|
||||
35
cmd/api/main.go
Normal file
35
cmd/api/main.go
Normal file
@ -0,0 +1,35 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"cargo-erp-backend/internal/config"
|
||||
"cargo-erp-backend/internal/database"
|
||||
"cargo-erp-backend/internal/handlers"
|
||||
"cargo-erp-backend/internal/logger"
|
||||
"cargo-erp-backend/pkg/helpers"
|
||||
)
|
||||
|
||||
func main() {
|
||||
//load config
|
||||
AppConfig := config.NewConfig()
|
||||
AppConfig.Load()
|
||||
|
||||
//logger load
|
||||
LoggerApp := logger.NewLogger(AppConfig)
|
||||
LoggerApp.Init()
|
||||
DBLogger := LoggerApp.Get("DB")
|
||||
APPLogger := LoggerApp.Get("APP")
|
||||
|
||||
//db connection
|
||||
db := database.NewDatabase(AppConfig, DBLogger, APPLogger)
|
||||
db.Connect()
|
||||
db.RegisterCallback()
|
||||
|
||||
//redis
|
||||
redisDB := database.NewRedis(AppConfig, DBLogger)
|
||||
redisDB.Connect()
|
||||
redisDB.RegisterCallback()
|
||||
// migrations.GenerateModel(nil, db.Get("master"))
|
||||
Helper := helpers.NewHelper(AppConfig, db, APPLogger, redisDB)
|
||||
app := handlers.NewHandlers(Helper)
|
||||
app.Run()
|
||||
}
|
||||
72
go.mod
Normal file
72
go.mod
Normal file
@ -0,0 +1,72 @@
|
||||
module cargo-erp-backend
|
||||
|
||||
go 1.24
|
||||
|
||||
require (
|
||||
github.com/fsnotify/fsnotify v1.9.0
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2
|
||||
github.com/redis/go-redis/v9 v9.22.0
|
||||
github.com/spf13/viper v1.21.0
|
||||
go.uber.org/zap v1.28.0
|
||||
golang.org/x/crypto v0.40.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||
gorm.io/driver/postgres v1.5.9
|
||||
gorm.io/gen v0.3.28
|
||||
gorm.io/gorm v1.25.12
|
||||
)
|
||||
|
||||
require (
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/bytedance/sonic v1.9.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.14.0 // indirect
|
||||
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect
|
||||
github.com/jackc/pgx/v5 v5.5.5 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.1 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/rogpeppe/go-internal v1.10.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
||||
github.com/spf13/afero v1.15.0 // indirect
|
||||
github.com/spf13/cast v1.10.0 // indirect
|
||||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/multierr v1.10.0 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect
|
||||
golang.org/x/mod v0.26.0 // indirect
|
||||
golang.org/x/net v0.42.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
golang.org/x/sys v0.34.0 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
golang.org/x/tools v0.35.0 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gorm.io/datatypes v1.2.4 // indirect
|
||||
gorm.io/driver/mysql v1.5.7 // indirect
|
||||
gorm.io/hints v1.1.0 // indirect
|
||||
gorm.io/plugin/dbresolver v1.5.3 // indirect
|
||||
)
|
||||
222
go.sum
Normal file
222
go.sum
Normal file
@ -0,0 +1,222 @@
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
||||
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
||||
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
|
||||
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
||||
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
|
||||
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
|
||||
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
||||
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA=
|
||||
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
|
||||
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
|
||||
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
|
||||
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
|
||||
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
|
||||
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE=
|
||||
github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/redis/go-redis/v9 v9.22.0 h1:laDvpYXTJtZLloinw1fA5Kqd6HAEH2XKxOkG/PDq2F0=
|
||||
github.com/redis/go-redis/v9 v9.22.0/go.mod h1:y2g0Wj8rQvuK0ELM+oxSudcLtC09JScs98I/X9gRWY4=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
|
||||
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
||||
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
|
||||
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
||||
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
|
||||
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs=
|
||||
github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.28.0 h1:IZzaP1Fv73/T/pBMLk4VutPl36uNC+OSUh3JLG3FIjo=
|
||||
go.uber.org/zap v1.28.0/go.mod h1:rDLpOi171uODNm/mxFcuYWxDsqWSAVkFdX4XojSKg/Q=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
|
||||
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
|
||||
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
|
||||
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o=
|
||||
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
|
||||
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
|
||||
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
|
||||
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
|
||||
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/datatypes v1.2.4 h1:uZmGAcK/QZ0uyfCuVg0VQY1ZmV9h1fuG0tMwKByO1z4=
|
||||
gorm.io/datatypes v1.2.4/go.mod h1:f4BsLcFAX67szSv8svwLRjklArSHAvHLeE3pXAS5DZI=
|
||||
gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
|
||||
gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
|
||||
gorm.io/driver/postgres v1.5.9 h1:DkegyItji119OlcaLjqN11kHoUgZ/j13E0jkJZgD6A8=
|
||||
gorm.io/driver/postgres v1.5.9/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
|
||||
gorm.io/driver/sqlite v1.1.6/go.mod h1:W8LmC/6UvVbHKah0+QOC7Ja66EaZXHwUTjgXY8YNWX8=
|
||||
gorm.io/driver/sqlite v1.4.3 h1:HBBcZSDnWi5BW3B3rwvVTc510KGkBkexlOg0QrmLUuU=
|
||||
gorm.io/driver/sqlite v1.4.3/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI=
|
||||
gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0=
|
||||
gorm.io/driver/sqlserver v1.4.1/go.mod h1:DJ4P+MeZbc5rvY58PnmN1Lnyvb5gw5NPzGshHDnJLig=
|
||||
gorm.io/gen v0.3.28 h1:wnTvsd0a22Qsa06Am8oEjKy8KIB3+kowZx4MzijZ6wc=
|
||||
gorm.io/gen v0.3.28/go.mod h1:bJdK2/7BJaRdLBY7Vf8+FxWLC5WWYRfG+ZY3NQT/AbU=
|
||||
gorm.io/gorm v1.21.15/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
||||
gorm.io/gorm v1.22.2/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
|
||||
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
|
||||
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
||||
gorm.io/hints v1.1.0 h1:Lp4z3rxREufSdxn4qmkK3TLDltrM10FLTHiuqwDPvXw=
|
||||
gorm.io/hints v1.1.0/go.mod h1:lKQ0JjySsPBj3uslFzY3JhYDtqEwzm+G1hv8rWujB6Y=
|
||||
gorm.io/plugin/dbresolver v1.5.3 h1:wFwINGZZmttuu9h7XpvbDHd8Lf9bb8GNzp/NpAMV2wU=
|
||||
gorm.io/plugin/dbresolver v1.5.3/go.mod h1:TSrVhaUg2DZAWP3PrHlDlITEJmNOkL0tFTjvTEsQ4XE=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
67
internal/config/config.go
Normal file
67
internal/config/config.go
Normal file
@ -0,0 +1,67 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type ConfigInterface interface {
|
||||
Load()
|
||||
RegisterOnChangeCallback(f func())
|
||||
Get(key string) interface{}
|
||||
}
|
||||
type Config struct {
|
||||
cbLock sync.Mutex
|
||||
Callbacks []func()
|
||||
Env string
|
||||
}
|
||||
|
||||
func NewConfig() ConfigInterface {
|
||||
return &Config{}
|
||||
}
|
||||
func (c *Config) Load() {
|
||||
pathConfig := "./../config.json"
|
||||
realPath, err := filepath.Abs(pathConfig)
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
viper.SetConfigName("config")
|
||||
viper.SetConfigType("json")
|
||||
viper.AddConfigPath(path.Dir(realPath))
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
log.Fatalf("Failed To Read Configuration File: %v", err)
|
||||
}
|
||||
c.SetEnv()
|
||||
viper.WatchConfig()
|
||||
viper.OnConfigChange(func(e fsnotify.Event) {
|
||||
c.SetEnv()
|
||||
log.Printf("Configuration File Changed : %s", e.Name)
|
||||
c.cbLock.Lock()
|
||||
for _, callback := range c.Callbacks {
|
||||
if callback != nil {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
c.cbLock.Unlock()
|
||||
})
|
||||
}
|
||||
func (c *Config) RegisterOnChangeCallback(f func()) {
|
||||
c.cbLock.Lock()
|
||||
defer c.cbLock.Unlock()
|
||||
c.Callbacks = append(c.Callbacks, f)
|
||||
}
|
||||
func (c *Config) SetEnv() {
|
||||
envString := viper.GetString("env")
|
||||
log.Println(envString)
|
||||
c.Env = envString
|
||||
}
|
||||
func (c *Config) Get(key string) interface{} {
|
||||
envString := fmt.Sprintf("%v.%v", "config", c.Env)
|
||||
return viper.Get(fmt.Sprintf("%v.%v", envString, key))
|
||||
}
|
||||
115
internal/database/database.go
Normal file
115
internal/database/database.go
Normal file
@ -0,0 +1,115 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"cargo-erp-backend/internal/config"
|
||||
"cargo-erp-backend/internal/logger"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type DatabaseInterface interface {
|
||||
Connect()
|
||||
Close()
|
||||
Get(key string) *gorm.DB
|
||||
RegisterCallback()
|
||||
}
|
||||
type Database struct {
|
||||
Config config.ConfigInterface
|
||||
DB map[string]*gorm.DB
|
||||
dbLock sync.RWMutex
|
||||
Logger *zap.Logger
|
||||
AppLogger *zap.Logger
|
||||
}
|
||||
|
||||
func NewDatabase(config config.ConfigInterface, logger *zap.Logger, app_logger *zap.Logger) DatabaseInterface {
|
||||
return &Database{
|
||||
Config: config,
|
||||
Logger: logger,
|
||||
AppLogger: app_logger,
|
||||
}
|
||||
}
|
||||
func (d *Database) Connect() {
|
||||
db := make(map[string]*gorm.DB)
|
||||
username := d.Config.Get("database.username").(string)
|
||||
password := d.Config.Get("database.password").(string)
|
||||
dbname := d.Config.Get("database.database").(string)
|
||||
host_master := fmt.Sprintf("%v", d.Config.Get("database.master.host"))
|
||||
port_master := fmt.Sprintf("%v", d.Config.Get("database.master.port"))
|
||||
ssl_master := d.Config.Get("database.master.ssl")
|
||||
dsnMaster := fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=%s",
|
||||
url.PathEscape(username),
|
||||
url.PathEscape(password),
|
||||
host_master,
|
||||
port_master,
|
||||
dbname,
|
||||
ssl_master,
|
||||
)
|
||||
d.AppLogger.Info("Connect To Master DB")
|
||||
gormLogger := logger.NewGormZapLogger(d.Logger, 5*time.Second)
|
||||
dbMaster, err := gorm.Open(postgres.Open(dsnMaster), &gorm.Config{
|
||||
Logger: gormLogger,
|
||||
})
|
||||
if err != nil {
|
||||
d.AppLogger.Fatal(err.Error())
|
||||
return
|
||||
}
|
||||
db["master"] = dbMaster
|
||||
d.AppLogger.Info("DB Master Connected")
|
||||
|
||||
host_slave := fmt.Sprintf("%v", d.Config.Get("database.slave.host"))
|
||||
port_slave := fmt.Sprintf("%v", d.Config.Get("database.slave.port"))
|
||||
ssl_slave := d.Config.Get("database.slave.ssl")
|
||||
dsnSlave := fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=%s",
|
||||
url.PathEscape(username),
|
||||
url.PathEscape(password),
|
||||
host_slave,
|
||||
port_slave,
|
||||
dbname,
|
||||
ssl_slave,
|
||||
)
|
||||
d.AppLogger.Info("Connect To Slave DB")
|
||||
dbSlave, err := gorm.Open(postgres.Open(dsnSlave), &gorm.Config{
|
||||
Logger: gormLogger,
|
||||
})
|
||||
if err != nil {
|
||||
d.AppLogger.Fatal(err.Error())
|
||||
return
|
||||
}
|
||||
db["slave"] = dbSlave
|
||||
d.DB = db
|
||||
d.AppLogger.Info("DB Connection Done")
|
||||
}
|
||||
func (d *Database) RegisterCallback() {
|
||||
d.Config.RegisterOnChangeCallback(d.ReloadDB)
|
||||
}
|
||||
func (d *Database) Get(key string) *gorm.DB {
|
||||
if v, ok := d.DB[key]; ok {
|
||||
return v
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (d *Database) Close() {
|
||||
d.dbLock.Lock()
|
||||
defer d.dbLock.Unlock()
|
||||
d.AppLogger.Info("Close Database Connection Start")
|
||||
for k, db := range d.DB {
|
||||
if db != nil {
|
||||
sqlDb, _ := db.DB()
|
||||
sqlDb.Close()
|
||||
d.AppLogger.Info(fmt.Sprintf("Close Database Connection %s", k))
|
||||
}
|
||||
}
|
||||
d.AppLogger.Info("Close Database Connection Done")
|
||||
}
|
||||
func (d *Database) ReloadDB() {
|
||||
d.AppLogger.Info("Reload Connecting Database")
|
||||
d.Close()
|
||||
d.Connect()
|
||||
d.AppLogger.Info("Reload Connecting Database Done")
|
||||
}
|
||||
93
internal/database/redis.go
Normal file
93
internal/database/redis.go
Normal file
@ -0,0 +1,93 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"cargo-erp-backend/internal/config"
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type RedisInterface interface {
|
||||
Connect()
|
||||
Get(key string) *redis.Client
|
||||
RegisterCallback()
|
||||
}
|
||||
type Redis struct {
|
||||
Config config.ConfigInterface
|
||||
Logger *zap.Logger
|
||||
DB map[string]*redis.Client
|
||||
}
|
||||
|
||||
func NewRedis(config config.ConfigInterface, logger *zap.Logger) RedisInterface {
|
||||
return &Redis{
|
||||
Config: config,
|
||||
Logger: logger,
|
||||
}
|
||||
}
|
||||
func (r *Redis) Connect() {
|
||||
redisConfig := r.Config.Get("redis")
|
||||
dbRedis := make(map[string]*redis.Client)
|
||||
if v, ok := redisConfig.(map[string]interface{}); ok {
|
||||
for kNode, vNode := range v {
|
||||
r.Logger.Info("Parse config " + kNode)
|
||||
if params, ok := vNode.(map[string]interface{}); ok {
|
||||
password := ""
|
||||
host := ""
|
||||
port := ""
|
||||
if val, ok := params["password"]; ok {
|
||||
password = fmt.Sprintf("%v", val)
|
||||
}
|
||||
if val, ok := params["host"]; ok {
|
||||
host = fmt.Sprintf("%v", val)
|
||||
}
|
||||
if val, ok := params["port"]; ok {
|
||||
port = fmt.Sprintf("%v", val)
|
||||
}
|
||||
url := fmt.Sprintf("redis://:%v@%v:%v", password, host, port)
|
||||
r.Logger.Info(fmt.Sprintf("Connecting to Redis %v", kNode))
|
||||
opts, err := redis.ParseURL(url)
|
||||
if err != nil {
|
||||
r.Logger.Error(fmt.Sprintf("unable to parse redis URL %v", err.Error()))
|
||||
} else {
|
||||
client := redis.NewClient(opts)
|
||||
|
||||
if err := client.Ping(context.Background()).Err(); err != nil {
|
||||
r.Logger.Error(fmt.Sprintf("unable to connect to redis: %v", err.Error()))
|
||||
} else {
|
||||
dbRedis[kNode] = client
|
||||
}
|
||||
}
|
||||
r.Logger.Info("Connected")
|
||||
} else {
|
||||
r.Logger.Fatal("Parse paramater redis config error")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
r.Logger.Fatal("Parse paramater redis config error")
|
||||
}
|
||||
r.DB = dbRedis
|
||||
}
|
||||
|
||||
func (r *Redis) Close() {
|
||||
for k, v := range r.DB {
|
||||
r.Logger.Info(fmt.Sprintf("Close Connection %v", k))
|
||||
v.Close()
|
||||
r.Logger.Info("Close Connection Done")
|
||||
}
|
||||
r.DB = make(map[string]*redis.Client)
|
||||
}
|
||||
func (r *Redis) RegisterCallback() {
|
||||
r.Config.RegisterOnChangeCallback(r.Reconnecting)
|
||||
}
|
||||
func (r *Redis) Reconnecting() {
|
||||
r.Close()
|
||||
r.Connect()
|
||||
}
|
||||
func (r *Redis) Get(key string) *redis.Client {
|
||||
if v, ok := r.DB[key]; ok {
|
||||
return v
|
||||
}
|
||||
return nil
|
||||
}
|
||||
35
internal/domain/city.go
Normal file
35
internal/domain/city.go
Normal file
@ -0,0 +1,35 @@
|
||||
// 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 TableNameCity = "city"
|
||||
|
||||
// City mapped from table <city>
|
||||
type City struct {
|
||||
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"`
|
||||
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"`
|
||||
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"`
|
||||
PostalCodes_Relation []PostalCode `gorm:"foreignKey:city_id;references:id" json:"postal_codes_relation"`
|
||||
Subdistricts_Relation []Subdistrict `gorm:"foreignKey:city_id;references:id" json:"subdistricts_relation"`
|
||||
Districts_Relation []District `gorm:"foreignKey:city_id;references:id" json:"districts_relation"`
|
||||
Province_Relation Province `gorm:"foreignKey:province_id;references:id" json:"province_relation"`
|
||||
Merchants_Relation []Merchant `gorm:"foreignKey:city_id;references:id" json:"merchants_relation"`
|
||||
CreatedBy_Relation User `gorm:"foreignKey:created_by;references:id" json:"created_by_relation"`
|
||||
Merchant_Relation Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
|
||||
}
|
||||
|
||||
// TableName City's table name
|
||||
func (*City) TableName() string {
|
||||
return TableNameCity
|
||||
}
|
||||
29
internal/domain/cost_component.go
Normal file
29
internal/domain/cost_component.go
Normal file
@ -0,0 +1,29 @@
|
||||
// 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 TableNameCostComponent = "cost_component"
|
||||
|
||||
// CostComponent mapped from table <cost_component>
|
||||
type CostComponent struct {
|
||||
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"`
|
||||
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"`
|
||||
Inc *string `gorm:"column:inc;type:character varying" json:"inc"`
|
||||
Code *string `gorm:"column:code;type:character varying(100)" json:"code"`
|
||||
}
|
||||
|
||||
// TableName CostComponent's table name
|
||||
func (*CostComponent) TableName() string {
|
||||
return TableNameCostComponent
|
||||
}
|
||||
36
internal/domain/district.go
Normal file
36
internal/domain/district.go
Normal file
@ -0,0 +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
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const TableNameDistrict = "district"
|
||||
|
||||
// District mapped from table <district>
|
||||
type District struct {
|
||||
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"`
|
||||
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"`
|
||||
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"`
|
||||
MerchantID *string `gorm:"column:merchant_id;type:character(26)" json:"merchant_id"`
|
||||
PostalCodes_Relation []PostalCode `gorm:"foreignKey:district_id;references:id" json:"postal_codes_relation"`
|
||||
Subdistricts_Relation []Subdistrict `gorm:"foreignKey:district_id;references:id" json:"subdistricts_relation"`
|
||||
Province_Relation Province `gorm:"foreignKey:province_id;references:id" json:"province_relation"`
|
||||
City_Relation City `gorm:"foreignKey:city_id;references:id" json:"city_relation"`
|
||||
Merchants_Relation []Merchant `gorm:"foreignKey:district_id;references:id" json:"merchants_relation"`
|
||||
CreatedBy_Relation User `gorm:"foreignKey:created_by;references:id" json:"created_by_relation"`
|
||||
Merchant_Relation Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
|
||||
}
|
||||
|
||||
// TableName District's table name
|
||||
func (*District) TableName() string {
|
||||
return TableNameDistrict
|
||||
}
|
||||
50
internal/domain/merchant.go
Normal file
50
internal/domain/merchant.go
Normal file
@ -0,0 +1,50 @@
|
||||
// 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 TableNameMerchant = "merchant"
|
||||
|
||||
// Merchant mapped from table <merchant>
|
||||
type Merchant struct {
|
||||
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"`
|
||||
Telp *string `gorm:"column:telp;type:character varying(50);index:merchant_name_idx,priority:4" json:"telp"`
|
||||
AdditionalInformation *string `gorm:"column:additional_information;type:jsonb;index:merchant_additional_information_idx,priority:1;default:{}" json:"additional_information"`
|
||||
Active *bool `gorm:"column:active;type:boolean;default:true" json:"active"`
|
||||
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"`
|
||||
ProvinceID *string `gorm:"column:province_id;type:character(26);index:merchant_province_id_idx,priority:1" json:"province_id"`
|
||||
CityID *string `gorm:"column:city_id;type:character(26);index:merchant_city_id_idx,priority:1" json:"city_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"`
|
||||
PostalCode *string `gorm:"column:postal_code;type:character(26);index:merchant_postal_code_idx,priority:1" json:"postal_code"`
|
||||
Province_Relation *Province `gorm:"foreignKey:province_id;references:id" json:"province_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"`
|
||||
Subdistrict_Relation *Subdistrict `gorm:"foreignKey:subdistrict_id;references:id" json:"subdistrict_relation"`
|
||||
UsersRoless_Relation []*UsersRole `gorm:"foreignKey:merchant_id;references:id" json:"users_roless_relation"`
|
||||
Modas_Relation []*Moda `gorm:"foreignKey:merchant_id;references:id" json:"modas_relation"`
|
||||
PackageTypes_Relation []*PackageType `gorm:"foreignKey:merchant_id;references:id" json:"package_types_relation"`
|
||||
Userss_Relation []*User `gorm:"foreignKey:merchant_id;references:id" json:"userss_relation"`
|
||||
CreatedBy_Relation *User `gorm:"foreignKey:created_by;references:id" json:"created_by_relation"`
|
||||
Provinces_Relation []*Province `gorm:"foreignKey:merchant_id;references:id" json:"provinces_relation"`
|
||||
Citys_Relation []*City `gorm:"foreignKey:merchant_id;references:id" json:"citys_relation"`
|
||||
Districts_Relation []*District `gorm:"foreignKey:merchant_id;references:id" json:"districts_relation"`
|
||||
Subdistricts_Relation []*Subdistrict `gorm:"foreignKey:merchant_id;references:id" json:"subdistricts_relation"`
|
||||
PostalCodes_Relation []*PostalCode `gorm:"foreignKey:merchant_id;references:id" json:"postal_codes_relation"`
|
||||
}
|
||||
|
||||
// TableName Merchant's table name
|
||||
func (*Merchant) TableName() string {
|
||||
return TableNameMerchant
|
||||
}
|
||||
28
internal/domain/moda.go
Normal file
28
internal/domain/moda.go
Normal file
@ -0,0 +1,28 @@
|
||||
// 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 TableNameModa = "moda"
|
||||
|
||||
// Moda mapped from table <moda>
|
||||
type Moda struct {
|
||||
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"`
|
||||
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"`
|
||||
Merchant_Relation Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
|
||||
}
|
||||
|
||||
// TableName Moda's table name
|
||||
func (*Moda) TableName() string {
|
||||
return TableNameModa
|
||||
}
|
||||
28
internal/domain/package_type.go
Normal file
28
internal/domain/package_type.go
Normal file
@ -0,0 +1,28 @@
|
||||
// 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 TableNamePackageType = "package_type"
|
||||
|
||||
// PackageType mapped from table <package_type>
|
||||
type PackageType struct {
|
||||
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"`
|
||||
Merchant_Relation Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
|
||||
}
|
||||
|
||||
// TableName PackageType's table name
|
||||
func (*PackageType) TableName() string {
|
||||
return TableNamePackageType
|
||||
}
|
||||
37
internal/domain/postal_code.go
Normal file
37
internal/domain/postal_code.go
Normal file
@ -0,0 +1,37 @@
|
||||
// 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 TableNamePostalCode = "postal_code"
|
||||
|
||||
// PostalCode mapped from table <postal_code>
|
||||
type PostalCode struct {
|
||||
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"`
|
||||
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"`
|
||||
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"`
|
||||
UpdatedBy *string `gorm:"column:updated_by;type:character(26)" json:"updated_by"`
|
||||
UpdatedOn *string `gorm:"column:updated_on;type:character varying" json:"updated_on"`
|
||||
MerchantID *string `gorm:"column:merchant_id;type:character(26)" json:"merchant_id"`
|
||||
Province_Relation Province `gorm:"foreignKey:province_id;references:id" json:"province_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"`
|
||||
Subdistrict_Relation Subdistrict `gorm:"foreignKey:subdistrict_id;references:id" json:"subdistrict_relation"`
|
||||
CreatedBy_Relation User `gorm:"foreignKey:created_by;references:id" json:"created_by_relation"`
|
||||
Merchant_Relation Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
|
||||
}
|
||||
|
||||
// TableName PostalCode's table name
|
||||
func (*PostalCode) TableName() string {
|
||||
return TableNamePostalCode
|
||||
}
|
||||
34
internal/domain/province.go
Normal file
34
internal/domain/province.go
Normal file
@ -0,0 +1,34 @@
|
||||
// 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 TableNameProvince = "province"
|
||||
|
||||
// Province mapped from table <province>
|
||||
type Province struct {
|
||||
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"`
|
||||
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"`
|
||||
MerchantID *string `gorm:"column:merchant_id;type:character(26)" json:"merchant_id"`
|
||||
PostalCodes_Relation []PostalCode `gorm:"foreignKey:province_id;references:id" json:"postal_codes_relation"`
|
||||
Subdistricts_Relation []Subdistrict `gorm:"foreignKey:province_id;references:id" json:"subdistricts_relation"`
|
||||
Districts_Relation []District `gorm:"foreignKey:province_id;references:id" json:"districts_relation"`
|
||||
Citys_Relation []City `gorm:"foreignKey:province_id;references:id" json:"citys_relation"`
|
||||
Merchants_Relation []Merchant `gorm:"foreignKey:province_id;references:id" json:"merchants_relation"`
|
||||
CreatedBy_Relation User `gorm:"foreignKey:created_by;references:id" json:"created_by_relation"`
|
||||
Merchant_Relation Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
|
||||
}
|
||||
|
||||
// TableName Province's table name
|
||||
func (*Province) TableName() string {
|
||||
return TableNameProvince
|
||||
}
|
||||
37
internal/domain/subdistrict.go
Normal file
37
internal/domain/subdistrict.go
Normal file
@ -0,0 +1,37 @@
|
||||
// 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 TableNameSubdistrict = "subdistrict"
|
||||
|
||||
// Subdistrict mapped from table <subdistrict>
|
||||
type Subdistrict struct {
|
||||
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"`
|
||||
DistrictID *string `gorm:"column:district_id;type:character(26);index:subdistrit_district_id_idx,priority:1" json:"district_id"`
|
||||
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"`
|
||||
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"`
|
||||
MerchantID *string `gorm:"column:merchant_id;type:character(26)" json:"merchant_id"`
|
||||
PostalCodes_Relation []PostalCode `gorm:"foreignKey:subdistrict_id;references:id" json:"postal_codes_relation"`
|
||||
Province_Relation Province `gorm:"foreignKey:province_id;references:id" json:"province_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"`
|
||||
Merchants_Relation []Merchant `gorm:"foreignKey:subdistrict_id;references:id" json:"merchants_relation"`
|
||||
CreatedBy_Relation User `gorm:"foreignKey:created_by;references:id" json:"created_by_relation"`
|
||||
Merchant_Relation Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
|
||||
}
|
||||
|
||||
// TableName Subdistrict's table name
|
||||
func (*Subdistrict) TableName() string {
|
||||
return TableNameSubdistrict
|
||||
}
|
||||
41
internal/domain/users.go
Normal file
41
internal/domain/users.go
Normal file
@ -0,0 +1,41 @@
|
||||
// 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 TableNameUser = "users"
|
||||
|
||||
// User mapped from table <users>
|
||||
type User struct {
|
||||
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"`
|
||||
Password *string `gorm:"column:password;type:character varying(300)" json:"password"`
|
||||
IsActive *bool `gorm:"column:is_active;type:boolean;default:true" json:"is_active"`
|
||||
UsersRoleID *string `gorm:"column:users_role_id;type:character(26)" json:"users_role_id"`
|
||||
Blocked *bool `gorm:"column:blocked;type:boolean" json:"blocked"`
|
||||
BlockedNotes *string `gorm:"column:blocked_notes;type:character varying(500)" json:"blocked_notes"`
|
||||
CreatedBy *string `gorm:"column:created_by;type:character(26);index:users_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"`
|
||||
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"`
|
||||
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"`
|
||||
Merchants_Relation []Merchant `gorm:"foreignKey:created_by;references:id" json:"merchants_relation"`
|
||||
Provinces_Relation []Province `gorm:"foreignKey:created_by;references:id" json:"provinces_relation"`
|
||||
Citys_Relation []City `gorm:"foreignKey:created_by;references:id" json:"citys_relation"`
|
||||
Districts_Relation []District `gorm:"foreignKey:created_by;references:id" json:"districts_relation"`
|
||||
Subdistricts_Relation []Subdistrict `gorm:"foreignKey:created_by;references:id" json:"subdistricts_relation"`
|
||||
PostalCodes_Relation []PostalCode `gorm:"foreignKey:created_by;references:id" json:"postal_codes_relation"`
|
||||
}
|
||||
|
||||
// TableName User's table name
|
||||
func (*User) TableName() string {
|
||||
return TableNameUser
|
||||
}
|
||||
30
internal/domain/users_roles.go
Normal file
30
internal/domain/users_roles.go
Normal file
@ -0,0 +1,30 @@
|
||||
// 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 TableNameUsersRole = "users_roles"
|
||||
|
||||
// UsersRole mapped from table <users_roles>
|
||||
type UsersRole struct {
|
||||
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"`
|
||||
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"`
|
||||
RoleKey string `gorm:"column:role_key;type:character varying(20);not null" json:"role_key"`
|
||||
Merchant_Relation Merchant `gorm:"foreignKey:merchant_id;references:id" json:"merchant_relation"`
|
||||
Userss_Relation []User `gorm:"foreignKey:users_role_id;references:id" json:"userss_relation"`
|
||||
}
|
||||
|
||||
// TableName UsersRole's table name
|
||||
func (*UsersRole) TableName() string {
|
||||
return TableNameUsersRole
|
||||
}
|
||||
10
internal/handlers/dto/auth.go
Normal file
10
internal/handlers/dto/auth.go
Normal file
@ -0,0 +1,10 @@
|
||||
package dto
|
||||
|
||||
type AuthRequest struct {
|
||||
Email string `json:"email" form:"email" binding:"required,email"`
|
||||
Password string `json:"password" form:"password" binding:"required,min=5"`
|
||||
}
|
||||
|
||||
type AuthResponse struct {
|
||||
Token string `json:"token"`
|
||||
}
|
||||
83
internal/handlers/handlers.go
Normal file
83
internal/handlers/handlers.go
Normal file
@ -0,0 +1,83 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"cargo-erp-backend/internal/handlers/router/auth"
|
||||
"cargo-erp-backend/pkg/helpers"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type HandlersInfterface interface {
|
||||
Run()
|
||||
}
|
||||
type Handlers struct {
|
||||
Helper helpers.HelperInterface
|
||||
}
|
||||
|
||||
func NewHandlers(helper helpers.HelperInterface) HandlersInfterface {
|
||||
return &Handlers{
|
||||
Helper: helper,
|
||||
}
|
||||
}
|
||||
func (h *Handlers) ZapLoggerMiddleware(logger *zap.Logger) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
start := time.Now()
|
||||
path := c.Request.URL.Path
|
||||
query := c.Request.URL.RawQuery
|
||||
|
||||
// Lanjutkan eksekusi ke handler utama
|
||||
c.Next()
|
||||
|
||||
// Hitung durasi response eksekusi
|
||||
latency := time.Since(start)
|
||||
status := c.Writer.Status()
|
||||
|
||||
// Siapkan field data log terstruktur
|
||||
fields := []zap.Field{
|
||||
zap.Int("status", status),
|
||||
zap.String("method", c.Request.Method),
|
||||
zap.String("path", path),
|
||||
zap.String("query", query),
|
||||
zap.String("ip", c.ClientIP()),
|
||||
zap.Duration("latency", latency),
|
||||
zap.String("user-agent", c.Request.UserAgent()),
|
||||
}
|
||||
|
||||
// Jika ada error internal dari Gin, masukkan ke log
|
||||
if len(c.Errors) > 0 {
|
||||
for _, e := range c.Errors.Errors() {
|
||||
logger.Error(e, fields...)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Tentukan level log berdasarkan HTTP Status Code
|
||||
if status >= 500 {
|
||||
logger.Error("Server Error", fields...)
|
||||
} else if status >= 400 {
|
||||
logger.Warn("Client Error", fields...)
|
||||
} else {
|
||||
logger.Info("Request Success", fields...)
|
||||
}
|
||||
}
|
||||
}
|
||||
func (h *Handlers) Run() {
|
||||
host := fmt.Sprintf("%v", h.Helper.Config().Get("app.host"))
|
||||
port := fmt.Sprintf("%v", h.Helper.Config().Get("app.port"))
|
||||
r := gin.Default()
|
||||
r.Use(h.ZapLoggerMiddleware(h.Helper.Log()))
|
||||
r.Use(gin.Recovery())
|
||||
r.GET("/ping", func(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "pong",
|
||||
})
|
||||
})
|
||||
//auth
|
||||
auth.NewAuthHandler(h.Helper, r).Router()
|
||||
h.Helper.Log().Info("Starting Apps")
|
||||
r.Run(fmt.Sprintf("%v:%v", host, port))
|
||||
}
|
||||
77
internal/handlers/router/auth/auth.go
Normal file
77
internal/handlers/router/auth/auth.go
Normal file
@ -0,0 +1,77 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"cargo-erp-backend/internal/handlers/dto"
|
||||
"cargo-erp-backend/internal/middleware"
|
||||
"cargo-erp-backend/internal/usecases"
|
||||
"cargo-erp-backend/pkg/helpers"
|
||||
"cargo-erp-backend/pkg/response"
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type AuthHandlerInterface interface {
|
||||
Router()
|
||||
}
|
||||
type AuthHandler struct {
|
||||
Helper helpers.HelperInterface
|
||||
Engine *gin.Engine
|
||||
}
|
||||
|
||||
func NewAuthHandler(helper helpers.HelperInterface, e *gin.Engine) AuthHandlerInterface {
|
||||
return &AuthHandler{
|
||||
Helper: helper,
|
||||
Engine: e,
|
||||
}
|
||||
}
|
||||
func (h *AuthHandler) Router() {
|
||||
h.Engine.POST("login", h.Login)
|
||||
h.Engine.POST("logout", middleware.NewAuthMiddleware(h.Helper).Check(), h.Logout)
|
||||
}
|
||||
func (h *AuthHandler) Login(c *gin.Context) {
|
||||
u := usecases.NewAuthUsecase(h.Helper)
|
||||
var parameter dto.AuthRequest
|
||||
if err := c.BindJSON(¶meter); err != nil {
|
||||
response.Error(c, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
token, err := u.Login(parameter.Email, parameter.Password)
|
||||
if err != nil {
|
||||
response.Error(c, http.StatusUnauthorized, err.Error())
|
||||
return
|
||||
}
|
||||
cookieName := fmt.Sprintf("%v", h.Helper.Config().Get("cookie.name"))
|
||||
exp_time := fmt.Sprintf("%v", h.Helper.Config().Get("cookie.expiry_time"))
|
||||
t, _ := strconv.Atoi(exp_time)
|
||||
c.SetCookie(
|
||||
cookieName, // name
|
||||
token, // value
|
||||
t, // max age: 30 menit
|
||||
"/", // path
|
||||
"", // domain
|
||||
false, // secure
|
||||
true, // httpOnly
|
||||
)
|
||||
|
||||
response.Success(c, map[string]interface{}{"token": token})
|
||||
}
|
||||
func (h *AuthHandler) Logout(c *gin.Context) {
|
||||
auth_key := c.MustGet("auth_key")
|
||||
ctx := context.Background()
|
||||
h.Helper.GetRedis("master").Del(ctx, fmt.Sprintf("%v", auth_key))
|
||||
cookieName := fmt.Sprintf("%v", h.Helper.Config().Get("cookie.name"))
|
||||
c.SetCookie(
|
||||
cookieName, // name
|
||||
"", // value
|
||||
-3600, // max age: 30 menit
|
||||
"/", // path
|
||||
"", // domain
|
||||
false, // secure
|
||||
true, // httpOnly
|
||||
)
|
||||
response.Success(c, map[string]interface{}{"message": "You are logged out"})
|
||||
}
|
||||
92
internal/logger/database.go
Normal file
92
internal/logger/database.go
Normal file
@ -0,0 +1,92 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
gormlogger "gorm.io/gorm/logger"
|
||||
"gorm.io/gorm/utils"
|
||||
)
|
||||
|
||||
// GormZapLogger adalah custom logger GORM yang menggunakan Zap
|
||||
type GormZapLogger struct {
|
||||
ZapLogger *zap.Logger
|
||||
LogLevel gormlogger.LogLevel
|
||||
SlowThreshold time.Duration
|
||||
}
|
||||
|
||||
// NewGormZapLogger menginisialisasi logger baru
|
||||
func NewGormZapLogger(zapLog *zap.Logger, slowThreshold time.Duration) *GormZapLogger {
|
||||
return &GormZapLogger{
|
||||
ZapLogger: zapLog,
|
||||
LogLevel: gormlogger.Info, // Atur default ke Info, bisa disesuaikan
|
||||
SlowThreshold: slowThreshold, // Waktu batas query dianggap lambat (misal 200ms)
|
||||
}
|
||||
}
|
||||
|
||||
// LogMode mengubah level log GORM
|
||||
func (l *GormZapLogger) LogMode(level gormlogger.LogLevel) gormlogger.Interface {
|
||||
newLogger := *l
|
||||
newLogger.LogLevel = level
|
||||
return &newLogger
|
||||
}
|
||||
|
||||
// Info mencetak log informasi biasa
|
||||
func (l *GormZapLogger) Info(ctx context.Context, msg string, data ...interface{}) {
|
||||
if l.LogLevel >= gormlogger.Info {
|
||||
l.ZapLogger.Sugar().Infof(msg, data...)
|
||||
}
|
||||
}
|
||||
|
||||
// Warn mencetak log peringatan
|
||||
func (l *GormZapLogger) Warn(ctx context.Context, msg string, data ...interface{}) {
|
||||
if l.LogLevel >= gormlogger.Warn {
|
||||
l.ZapLogger.Sugar().Warnf(msg, data...)
|
||||
}
|
||||
}
|
||||
|
||||
// Error mencetak log kesalahan
|
||||
func (l *GormZapLogger) Error(ctx context.Context, msg string, data ...interface{}) {
|
||||
if l.LogLevel >= gormlogger.Error {
|
||||
l.ZapLogger.Sugar().Errorf(msg, data...)
|
||||
}
|
||||
}
|
||||
|
||||
// Trace mencetak log internal query SQL dari GORM
|
||||
func (l *GormZapLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
|
||||
if l.LogLevel <= gormlogger.Silent {
|
||||
return
|
||||
}
|
||||
|
||||
elapsed := time.Since(begin)
|
||||
sql, rows := fc()
|
||||
|
||||
// Ambil lokasi file baris kode Go yang mengeksekusi query ini
|
||||
line := utils.FileWithLineNum()
|
||||
|
||||
// Siapkan fields bawaan Zap agar log terstruktur dengan baik
|
||||
fields := []zap.Field{
|
||||
zap.String("line", line),
|
||||
zap.Duration("elapsed", elapsed),
|
||||
zap.Int64("rows", rows),
|
||||
zap.String("sql", sql),
|
||||
}
|
||||
|
||||
switch {
|
||||
// Kasus 1: Terjadi Error dan Error tersebut BUKAN Record NotFound
|
||||
case err != nil && l.LogLevel >= gormlogger.Error && !errors.Is(err, gorm.ErrRecordNotFound):
|
||||
fields = append(fields, zap.Error(err))
|
||||
l.ZapLogger.Error("[GORM] query error", fields...)
|
||||
|
||||
// Kasus 2: Query berjalan lambat melewati batas SlowThreshold
|
||||
case elapsed > l.SlowThreshold && l.SlowThreshold != 0 && l.LogLevel >= gormlogger.Warn:
|
||||
l.ZapLogger.Warn("[GORM] slow query warning", fields...)
|
||||
|
||||
// Kasus 3: Log info query normal
|
||||
case l.LogLevel >= gormlogger.Info:
|
||||
l.ZapLogger.Info("[GORM] query execution", fields...)
|
||||
}
|
||||
}
|
||||
151
internal/logger/logger.go
Normal file
151
internal/logger/logger.go
Normal file
@ -0,0 +1,151 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"cargo-erp-backend/internal/config"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
"gopkg.in/natefinch/lumberjack.v2"
|
||||
)
|
||||
|
||||
type LoggerInterface interface {
|
||||
Init()
|
||||
Get(key string) *zap.Logger
|
||||
}
|
||||
type Logger struct {
|
||||
Config config.ConfigInterface
|
||||
Logger map[string]*zap.Logger
|
||||
}
|
||||
|
||||
func NewLogger(config config.ConfigInterface) LoggerInterface {
|
||||
return &Logger{
|
||||
Config: config,
|
||||
}
|
||||
}
|
||||
func (l *Logger) Init() {
|
||||
log.Println("initial database logger")
|
||||
l.Logger = make(map[string]*zap.Logger)
|
||||
l.Logger["DB"] = nil
|
||||
l.Logger["APP"] = nil
|
||||
if v, ok := l.Config.Get("database.logger").(map[string]interface{}); ok {
|
||||
if val, ok := v["filename"]; ok {
|
||||
if filename, ok := val.(string); ok {
|
||||
file_location, err := filepath.Abs(filename)
|
||||
MaxSize := 10
|
||||
MaxBackups := 5
|
||||
MaxAge := 30
|
||||
Compress := true
|
||||
if err == nil {
|
||||
if s, ok := v["MaxSize"]; ok {
|
||||
size, err := strconv.Atoi(fmt.Sprintf("%v", s))
|
||||
if err != nil {
|
||||
MaxSize = size
|
||||
}
|
||||
}
|
||||
if s, ok := v["max_backups"]; ok {
|
||||
size, err := strconv.Atoi(fmt.Sprintf("%v", s))
|
||||
if err != nil {
|
||||
MaxBackups = size
|
||||
}
|
||||
}
|
||||
if s, ok := v["max_age"]; ok {
|
||||
size, err := strconv.Atoi(fmt.Sprintf("%v", s))
|
||||
if err != nil {
|
||||
MaxAge = size
|
||||
}
|
||||
}
|
||||
if s, ok := v["compress"]; ok {
|
||||
if sv, ok := s.(bool); ok {
|
||||
Compress = sv
|
||||
}
|
||||
}
|
||||
}
|
||||
l.Logger["DB"] = l.NewLog(file_location, MaxSize, MaxBackups, MaxAge, Compress)
|
||||
}
|
||||
}
|
||||
}
|
||||
if v, ok := l.Config.Get("logger").(map[string]interface{}); ok {
|
||||
if val, ok := v["filename"]; ok {
|
||||
if filename, ok := val.(string); ok {
|
||||
file_location, err := filepath.Abs(filename)
|
||||
MaxSize := 10
|
||||
MaxBackups := 5
|
||||
MaxAge := 30
|
||||
Compress := true
|
||||
if err == nil {
|
||||
if s, ok := v["MaxSize"]; ok {
|
||||
size, err := strconv.Atoi(fmt.Sprintf("%v", s))
|
||||
if err != nil {
|
||||
MaxSize = size
|
||||
}
|
||||
}
|
||||
if s, ok := v["max_backups"]; ok {
|
||||
size, err := strconv.Atoi(fmt.Sprintf("%v", s))
|
||||
if err != nil {
|
||||
MaxBackups = size
|
||||
}
|
||||
}
|
||||
if s, ok := v["max_age"]; ok {
|
||||
size, err := strconv.Atoi(fmt.Sprintf("%v", s))
|
||||
if err != nil {
|
||||
MaxAge = size
|
||||
}
|
||||
}
|
||||
if s, ok := v["compress"]; ok {
|
||||
if sv, ok := s.(bool); ok {
|
||||
Compress = sv
|
||||
}
|
||||
}
|
||||
}
|
||||
l.Logger["APP"] = l.NewLog(file_location, MaxSize, MaxBackups, MaxAge, Compress)
|
||||
if l.Logger["DB"] == nil {
|
||||
l.Logger["DB"] = l.Logger["APP"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func (l *Logger) Get(key string) *zap.Logger {
|
||||
if v, ok := l.Logger[key]; ok {
|
||||
return v
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (l *Logger) NewLog(filename string, max_size int, max_backup int, max_age int, compress bool) *zap.Logger {
|
||||
lumberjackLogger := &lumberjack.Logger{
|
||||
Filename: filename, // Lokasi file
|
||||
MaxSize: max_size, // Megabytes sebelum rotasi
|
||||
MaxBackups: max_backup, // Jumlah file cadangan
|
||||
MaxAge: max_age, // Retention dalam HARI
|
||||
Compress: compress, // Otomatis kompres ke file .gz
|
||||
}
|
||||
encoderConfig := zap.NewProductionEncoderConfig()
|
||||
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder // Format waktu: 2026-08-13T...
|
||||
jsonEncoder := zapcore.NewJSONEncoder(encoderConfig)
|
||||
consoleEncoder := zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig())
|
||||
// Hanya meloloskan level DEBUG dan INFO
|
||||
isInfoOrDebug := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
|
||||
return lvl == zap.DebugLevel || lvl == zap.InfoLevel
|
||||
})
|
||||
|
||||
// Hanya meloloskan level WARN, ERROR, PANIC, FATAL
|
||||
isErrorOrHigher := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
|
||||
return lvl >= zap.WarnLevel
|
||||
})
|
||||
core := zapcore.NewTee(
|
||||
zapcore.NewCore(jsonEncoder, zapcore.AddSync(lumberjackLogger), isInfoOrDebug),
|
||||
// Masuk ke file error (Ganti os.Stderr dengan errorFileLogger Anda)
|
||||
zapcore.NewCore(jsonEncoder, zapcore.AddSync(lumberjackLogger), isErrorOrHigher),
|
||||
|
||||
// CONSOLE LOGS (Terminal): Biasanya ingin melihat semua level dari DEBUG sampai FATAL
|
||||
zapcore.NewCore(consoleEncoder, zapcore.AddSync(os.Stdout), zap.DebugLevel),
|
||||
)
|
||||
logger := zap.New(core, zap.AddCaller())
|
||||
defer logger.Sync()
|
||||
return logger
|
||||
}
|
||||
95
internal/middleware/auth.go
Normal file
95
internal/middleware/auth.go
Normal file
@ -0,0 +1,95 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"cargo-erp-backend/pkg/helpers"
|
||||
"cargo-erp-backend/pkg/response"
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
type AuthMiddlewareInterface interface {
|
||||
Check() gin.HandlerFunc
|
||||
}
|
||||
type AuthMiddleware struct {
|
||||
Helper helpers.HelperInterface
|
||||
}
|
||||
|
||||
func NewAuthMiddleware(helper helpers.HelperInterface) AuthMiddlewareInterface {
|
||||
return &AuthMiddleware{
|
||||
Helper: helper,
|
||||
}
|
||||
}
|
||||
func (m *AuthMiddleware) Check() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
// rechecking auth header
|
||||
authHeader := c.GetHeader("Authorization")
|
||||
authData := ""
|
||||
authKey := ""
|
||||
err_auth_header := false
|
||||
if authHeader == "" {
|
||||
err_auth_header = true
|
||||
}
|
||||
|
||||
parts := strings.Fields(authHeader)
|
||||
token_string := ""
|
||||
if len(parts) != 2 || !strings.EqualFold(parts[0], "Bearer") {
|
||||
err_auth_header = true
|
||||
} else {
|
||||
token_string = parts[1]
|
||||
}
|
||||
if err_auth_header {
|
||||
cookieName := fmt.Sprintf("%v", m.Helper.Config().Get("cookie.name"))
|
||||
value, err := c.Cookie(cookieName)
|
||||
if err != nil {
|
||||
response.Error(c, http.StatusUnauthorized, "Unauthorized")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
if len(authHeader) > 0 && len(value) > 0 && parts[1] != value {
|
||||
response.Error(c, http.StatusUnauthorized, "Unauthorized")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
token_string = value
|
||||
}
|
||||
ctx := context.Background()
|
||||
redis_exist := make(map[string]string)
|
||||
m.Helper.Log().Info("session_login : " + token_string)
|
||||
iter := m.Helper.GetRedis("slave").Scan(ctx, 0, "session_login:*:"+token_string, 1000).Iterator()
|
||||
for iter.Next(ctx) {
|
||||
keys := iter.Val()
|
||||
|
||||
value, err := m.Helper.GetRedis("slave").Get(ctx, keys).Result()
|
||||
if err != nil {
|
||||
if err == redis.Nil {
|
||||
continue
|
||||
}
|
||||
|
||||
}
|
||||
redis_exist[keys] = value
|
||||
}
|
||||
if err := iter.Err(); err != nil {
|
||||
response.Error(c, http.StatusUnauthorized, "Unauthorized")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
if len(redis_exist) != 1 {
|
||||
response.Error(c, http.StatusUnauthorized, "Unauthorized")
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
for k, v := range redis_exist {
|
||||
authData = v
|
||||
authKey = k
|
||||
}
|
||||
m.Helper.Log().Info("Set Auth : " + authData)
|
||||
c.Set("auth", authData)
|
||||
c.Set("auth_key", authKey)
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
73
internal/usecases/auth.go
Normal file
73
internal/usecases/auth.go
Normal file
@ -0,0 +1,73 @@
|
||||
package usecases
|
||||
|
||||
import (
|
||||
"cargo-erp-backend/internal/domain"
|
||||
"cargo-erp-backend/pkg/helpers"
|
||||
"cargo-erp-backend/pkg/jwt"
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AuthUsecaseInterface interface {
|
||||
Login(email string, password string) (token string, err error)
|
||||
}
|
||||
type AuthUsecase struct {
|
||||
Helper helpers.HelperInterface
|
||||
}
|
||||
|
||||
func NewAuthUsecase(helper helpers.HelperInterface) AuthUsecaseInterface {
|
||||
return &AuthUsecase{
|
||||
Helper: helper,
|
||||
}
|
||||
}
|
||||
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).Find(&user)
|
||||
for _, v := range user {
|
||||
pass := u.Helper.StringFromPtr(v.Password)
|
||||
if u.Helper.VerifyPassword(pass, password) {
|
||||
ctx := context.Background()
|
||||
rd := u.Helper.GetRedis("master")
|
||||
secretJwt := jwt.NewJWT(u.Helper.Config(), u.Helper.Log())
|
||||
token, err := secretJwt.GenerateToken(v.ID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
extime_str := fmt.Sprintf("%v", u.Helper.Config().Get("jwt.expiry_time"))
|
||||
t, err := strconv.Atoi(extime_str)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
//
|
||||
key := fmt.Sprintf("session_login:%v:*", v.ID)
|
||||
iter := u.Helper.GetRedis("slave").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)
|
||||
return keys_ex[2], nil
|
||||
}
|
||||
}
|
||||
|
||||
key = fmt.Sprintf("session_login:%v:%v", v.ID, token)
|
||||
clonner, err := u.Helper.CloneStructWithoutField(v, "password")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
bdata, _ := u.Helper.StructTobyte(clonner)
|
||||
status := rd.Set(ctx, key, bdata, time.Duration(t)*time.Second)
|
||||
if status.Err() != nil {
|
||||
return "", status.Err()
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("User Not Found")
|
||||
}
|
||||
100
migrations/001_init.sql
Normal file
100
migrations/001_init.sql
Normal file
@ -0,0 +1,100 @@
|
||||
-- Cargo ERP Database Schema
|
||||
|
||||
-- Provinces table
|
||||
CREATE TABLE IF NOT EXISTS provinces (
|
||||
id SERIAL PRIMARY KEY,
|
||||
code VARCHAR(10) NOT NULL UNIQUE,
|
||||
name VARCHAR(100) NOT NULL
|
||||
);
|
||||
|
||||
-- Cities table
|
||||
CREATE TABLE IF NOT EXISTS cities (
|
||||
id SERIAL PRIMARY KEY,
|
||||
code VARCHAR(10) NOT NULL,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
province_id INTEGER REFERENCES provinces(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- Districts table
|
||||
CREATE TABLE IF NOT EXISTS districts (
|
||||
id SERIAL PRIMARY KEY,
|
||||
code VARCHAR(10) NOT NULL,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
city_id INTEGER REFERENCES cities(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- Subdistricts table
|
||||
CREATE TABLE IF NOT EXISTS subdistricts (
|
||||
id SERIAL PRIMARY KEY,
|
||||
code VARCHAR(10) NOT NULL,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
district_id INTEGER REFERENCES districts(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- Merchants table
|
||||
CREATE TABLE IF NOT EXISTS merchants (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
code VARCHAR(50) NOT NULL UNIQUE,
|
||||
address TEXT NOT NULL,
|
||||
phone VARCHAR(20) NOT NULL,
|
||||
email VARCHAR(255) NOT NULL,
|
||||
province_id INTEGER REFERENCES provinces(id),
|
||||
city_id INTEGER REFERENCES cities(id),
|
||||
district_id INTEGER REFERENCES districts(id),
|
||||
subdistrict_id INTEGER REFERENCES subdistricts(id),
|
||||
postcode VARCHAR(10),
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'active',
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Users table
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
merchant_id INTEGER REFERENCES merchants(id) ON DELETE SET NULL,
|
||||
username VARCHAR(100) NOT NULL UNIQUE,
|
||||
email VARCHAR(255) NOT NULL UNIQUE,
|
||||
password VARCHAR(255) NOT NULL,
|
||||
role VARCHAR(20) NOT NULL CHECK (role IN ('admin', 'administrasi', 'warehouse', 'cashier')),
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Orders table
|
||||
CREATE TABLE IF NOT EXISTS orders (
|
||||
id SERIAL PRIMARY KEY,
|
||||
merchant_id INTEGER NOT NULL REFERENCES merchants(id) ON DELETE CASCADE,
|
||||
order_number VARCHAR(50) NOT NULL UNIQUE,
|
||||
customer_name VARCHAR(255) NOT NULL,
|
||||
customer_phone VARCHAR(20) NOT NULL,
|
||||
pickup_address TEXT NOT NULL,
|
||||
delivery_address TEXT NOT NULL,
|
||||
pickup_subdistrict_id INTEGER REFERENCES subdistricts(id),
|
||||
delivery_subdistrict_id INTEGER REFERENCES subdistricts(id),
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'picked_up', 'in_transit', 'delivered', 'cancelled')),
|
||||
weight DECIMAL(10,2) NOT NULL,
|
||||
price DECIMAL(15,2) NOT NULL,
|
||||
notes TEXT,
|
||||
created_by INTEGER REFERENCES users(id),
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE INDEX IF NOT EXISTS idx_cities_province_id ON cities(province_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_districts_city_id ON districts(city_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_subdistricts_district_id ON subdistricts(district_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_merchants_status ON merchants(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_users_username ON users(username);
|
||||
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
|
||||
CREATE INDEX IF NOT EXISTS idx_orders_merchant_id ON orders(merchant_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_orders_order_number ON orders(order_number);
|
||||
CREATE INDEX IF NOT EXISTS idx_orders_status ON orders(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_orders_created_at ON orders(created_at);
|
||||
|
||||
-- Insert sample admin user (password: admin123)
|
||||
-- The password hash below is for "admin123" with bcrypt cost 10
|
||||
INSERT INTO users (username, email, password, role) VALUES
|
||||
('admin', 'admin@cargo-erp.com', '$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy', 'admin')
|
||||
ON CONFLICT (username) DO NOTHING;
|
||||
223
migrations/generatemodel.go
Normal file
223
migrations/generatemodel.go
Normal file
@ -0,0 +1,223 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"gorm.io/gen"
|
||||
"gorm.io/gen/field"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Struktur untuk menampung metadata Foreign Key dari database
|
||||
type ForeignKeyMeta struct {
|
||||
TableName string
|
||||
ColumnName string
|
||||
RefTable string
|
||||
RefColumn string
|
||||
}
|
||||
|
||||
func GenerateModel(table *string, db *gorm.DB) {
|
||||
currentDir, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Fatalf("Gagal mendapatkan working directory: %v", err)
|
||||
}
|
||||
|
||||
// Folder penampung sementara kueri (akan dihapus di akhir)
|
||||
queryOutPath := filepath.Join(currentDir, "internal", "domain", "query_utils")
|
||||
// Target folder Struct Model murni Anda
|
||||
modelOutPath := filepath.Join(currentDir, "internal", "domain")
|
||||
|
||||
_ = os.MkdirAll(queryOutPath, os.ModePerm)
|
||||
_ = os.MkdirAll(modelOutPath, os.ModePerm)
|
||||
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
log.Fatalf("Gagal mengambil instance sql.DB: %v", err)
|
||||
}
|
||||
|
||||
fkMetas := fetchForeignKeys(sqlDB)
|
||||
log.Printf("Berhasil mendeteksi %d relasi Foreign Key fisik di database.\n", len(fkMetas))
|
||||
|
||||
g := gen.NewGenerator(gen.Config{
|
||||
OutPath: queryOutPath,
|
||||
ModelPkgPath: modelOutPath,
|
||||
Mode: gen.WithoutContext,
|
||||
|
||||
FieldWithIndexTag: true,
|
||||
FieldWithTypeTag: true,
|
||||
FieldNullable: true,
|
||||
FieldSignable: true,
|
||||
})
|
||||
g.UseDB(db)
|
||||
|
||||
rows, err := sqlDB.Query("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'")
|
||||
if err != nil {
|
||||
log.Fatalf("Gagal mengambil daftar tabel: %v", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var tableNames []string
|
||||
for rows.Next() {
|
||||
var tName string
|
||||
if err := rows.Scan(&tName); err == nil && !strings.HasPrefix(tName, "gorm_") {
|
||||
tableNames = append(tableNames, tName)
|
||||
}
|
||||
}
|
||||
|
||||
// Map untuk mengumpulkan seluruh konfigurasi gen.ModelOpt dari tiap tabel
|
||||
tableRelationOpts := make(map[string][]gen.ModelOpt)
|
||||
|
||||
// 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(
|
||||
field.BelongsTo,
|
||||
propertyName,
|
||||
g.GenerateModel(fk.RefTable),
|
||||
&field.RelateConfig{
|
||||
GORMTag: field.GormTag{
|
||||
"foreignKey": []string{fk.ColumnName},
|
||||
"references": []string{fk.RefColumn},
|
||||
},
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
// B. Relasi HAS MANY
|
||||
if fk.RefTable == tName {
|
||||
// KUSTOMISASI 1: Tambahkan akhiran _Relation pada properti jamak
|
||||
propertyName := fmt.Sprintf("%ss_Relation", snakeToPascalCase(fk.TableName))
|
||||
|
||||
relationOptions = append(relationOptions, gen.FieldRelate(
|
||||
field.HasMany,
|
||||
propertyName,
|
||||
g.GenerateModel(fk.TableName),
|
||||
&field.RelateConfig{
|
||||
GORMTag: field.GormTag{
|
||||
"foreignKey": []string{fk.ColumnName},
|
||||
"references": []string{fk.RefColumn},
|
||||
},
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
tableRelationOpts[tName] = relationOptions
|
||||
}
|
||||
|
||||
var finalModels []any
|
||||
allTableModels := make(map[string]any)
|
||||
|
||||
for _, tName := range tableNames {
|
||||
opts := tableRelationOpts[tName]
|
||||
compiledModel := g.GenerateModel(tName, opts...)
|
||||
allTableModels[tName] = compiledModel
|
||||
finalModels = append(finalModels, compiledModel)
|
||||
}
|
||||
|
||||
if table != nil && *table != "" {
|
||||
if specModel, ok := allTableModels[*table]; ok {
|
||||
g.ApplyBasic(specModel)
|
||||
} else {
|
||||
log.Fatalf("Tabel %s tidak ditemukan di database!", *table)
|
||||
}
|
||||
} else {
|
||||
g.ApplyBasic(finalModels...)
|
||||
}
|
||||
|
||||
// Eksekusi pembuatan file standar GORM Gen (.gen.go)
|
||||
g.Execute()
|
||||
|
||||
// Bersihkan utility kueri yang tidak dibutuhkan
|
||||
_ = os.RemoveAll(queryOutPath)
|
||||
|
||||
// KUSTOMISASI 2: Hilangkan ekstensi ".gen.go" menjadi ".go" murni
|
||||
err = renameGeneratedFiles(modelOutPath)
|
||||
if err != nil {
|
||||
log.Printf("Peringatan: Gagal mengubah nama beberapa file model: %v\n", err)
|
||||
}
|
||||
|
||||
log.Println("Selesai! Model berhasil dibuat dengan format nama tanpa .gen dan field bertanda _Relation.")
|
||||
}
|
||||
|
||||
// Fungsi untuk mencari berkas .gen.go dan mengubah namanya menjadi .go murni
|
||||
func renameGeneratedFiles(dir string) error {
|
||||
files, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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 err := os.Rename(oldPath, newPath); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Fungsi pembantu menarik metadata FK Postgres
|
||||
func fetchForeignKeys(db *sql.DB) []ForeignKeyMeta {
|
||||
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.constraint_column_usage AS ccu
|
||||
ON ccu.constraint_name = tc.constraint_name
|
||||
AND ccu.table_schema = tc.table_schema
|
||||
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
|
||||
for rows.Next() {
|
||||
var m ForeignKeyMeta
|
||||
if err := rows.Scan(&m.TableName, &m.ColumnName, &m.RefTable, &m.RefColumn); err == nil {
|
||||
metas = append(metas, m)
|
||||
}
|
||||
}
|
||||
return metas
|
||||
}
|
||||
|
||||
func snakeToPascalCase(s string) string {
|
||||
parts := strings.Split(s, "_")
|
||||
for i, part := range parts {
|
||||
if len(part) > 0 {
|
||||
parts[i] = strings.ToUpper(part[:1]) + part[1:]
|
||||
}
|
||||
}
|
||||
return strings.Join(parts, "")
|
||||
}
|
||||
92
pkg/helpers/helpers.go
Normal file
92
pkg/helpers/helpers.go
Normal file
@ -0,0 +1,92 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"cargo-erp-backend/internal/config"
|
||||
"cargo-erp-backend/internal/database"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type HelperInterface interface {
|
||||
GetDB(key string) *gorm.DB
|
||||
GetRedis(key string) *redis.Client
|
||||
Config() config.ConfigInterface
|
||||
Log() *zap.Logger
|
||||
HashPassword(password string) string
|
||||
VerifyPassword(hashedPassword, password string) bool
|
||||
StringFromPtr(ptr *string) string
|
||||
StructTobyte(data interface{}) ([]byte, error)
|
||||
CloneStructWithoutField(input interface{}, field string) (map[string]interface{}, error)
|
||||
}
|
||||
type Helper struct {
|
||||
Conf config.ConfigInterface
|
||||
DB database.DatabaseInterface
|
||||
Logger *zap.Logger
|
||||
RedisDB database.RedisInterface
|
||||
}
|
||||
|
||||
func NewHelper(config config.ConfigInterface, db database.DatabaseInterface, logger *zap.Logger, dbredis database.RedisInterface) HelperInterface {
|
||||
return &Helper{
|
||||
Conf: config,
|
||||
DB: db,
|
||||
Logger: logger,
|
||||
RedisDB: dbredis,
|
||||
}
|
||||
}
|
||||
func (h *Helper) GetDB(key string) *gorm.DB {
|
||||
return h.DB.Get(key)
|
||||
}
|
||||
func (h *Helper) GetRedis(key string) *redis.Client {
|
||||
return h.RedisDB.Get(key)
|
||||
}
|
||||
func (h *Helper) Config() config.ConfigInterface {
|
||||
return h.Conf
|
||||
}
|
||||
func (h *Helper) Log() *zap.Logger {
|
||||
return h.Logger
|
||||
}
|
||||
func (h *Helper) HashPassword(password string) string {
|
||||
bytes, _ := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
return string(bytes)
|
||||
}
|
||||
func (h *Helper) VerifyPassword(hashedPassword, password string) bool {
|
||||
err := bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
|
||||
return err == nil
|
||||
}
|
||||
func (h *Helper) StringFromPtr(ptr *string) string {
|
||||
if ptr == nil {
|
||||
return ""
|
||||
}
|
||||
return *ptr
|
||||
}
|
||||
func (h *Helper) StructTobyte(data interface{}) ([]byte, error) {
|
||||
var output []byte
|
||||
s, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return output, err
|
||||
}
|
||||
output = s
|
||||
return output, nil
|
||||
}
|
||||
func (h *Helper) CloneStructWithoutField(input interface{}, field string) (map[string]interface{}, error) {
|
||||
|
||||
data, err := json.Marshal(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result map[string]interface{}
|
||||
|
||||
if err := json.Unmarshal(data, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(field) > 0 {
|
||||
delete(result, field)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
85
pkg/jwt/jwt.go
Normal file
85
pkg/jwt/jwt.go
Normal file
@ -0,0 +1,85 @@
|
||||
package jwt
|
||||
|
||||
import (
|
||||
"cargo-erp-backend/internal/config"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type JWTinterface interface {
|
||||
GenerateToken(secret string) (string, error)
|
||||
VerifyToken(tokenString string) (*Claims, error)
|
||||
}
|
||||
type JWT struct {
|
||||
Config config.ConfigInterface
|
||||
Log *zap.Logger
|
||||
}
|
||||
|
||||
func NewJWT(config config.ConfigInterface, logger *zap.Logger) JWTinterface {
|
||||
return &JWT{
|
||||
Config: config,
|
||||
Log: logger,
|
||||
}
|
||||
}
|
||||
|
||||
type Claims struct {
|
||||
UserID string `json:"uid"`
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
func (j *JWT) GenerateToken(tokenUser string) (string, error) {
|
||||
secret := fmt.Sprintf("%v", j.Config.Get("jwt.secret"))
|
||||
expiry_time_string := fmt.Sprintf("%v", j.Config.Get("jwt.expiry_time"))
|
||||
expiry_time, err := strconv.Atoi(expiry_time_string)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
claims := Claims{
|
||||
UserID: tokenUser,
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
Issuer: "cargo-platform",
|
||||
Subject: tokenUser,
|
||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||
ExpiresAt: jwt.NewNumericDate(
|
||||
time.Now().Add(time.Duration(expiry_time) * time.Second),
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
token := jwt.NewWithClaims(
|
||||
jwt.SigningMethodHS256,
|
||||
claims,
|
||||
)
|
||||
return token.SignedString([]byte(secret))
|
||||
}
|
||||
func (j *JWT) VerifyToken(tokenString string) (*Claims, error) {
|
||||
secret := fmt.Sprintf("%v", j.Config.Get("jwt.secret"))
|
||||
token, err := jwt.ParseWithClaims(
|
||||
tokenString,
|
||||
&Claims{},
|
||||
func(token *jwt.Token) (interface{}, error) {
|
||||
|
||||
if token.Method != jwt.SigningMethodHS256 {
|
||||
return nil, fmt.Errorf("invalid signing method")
|
||||
}
|
||||
|
||||
return []byte(secret), nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
claims, ok := token.Claims.(*Claims)
|
||||
|
||||
if !ok || !token.Valid {
|
||||
return nil, fmt.Errorf("invalid token")
|
||||
}
|
||||
|
||||
return claims, nil
|
||||
}
|
||||
68
pkg/response/response.go
Normal file
68
pkg/response/response.go
Normal file
@ -0,0 +1,68 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type APIResponse struct {
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Data interface{} `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
type PaginatedData struct {
|
||||
Items interface{} `json:"items"`
|
||||
Total int `json:"total"`
|
||||
Page int `json:"page"`
|
||||
Limit int `json:"limit"`
|
||||
TotalPages int `json:"total_pages"`
|
||||
}
|
||||
|
||||
func Success(c *gin.Context, data interface{}) {
|
||||
c.JSON(http.StatusOK, APIResponse{
|
||||
Success: true,
|
||||
Data: data,
|
||||
})
|
||||
}
|
||||
|
||||
func Created(c *gin.Context, data interface{}) {
|
||||
c.JSON(http.StatusCreated, APIResponse{
|
||||
Success: true,
|
||||
Data: data,
|
||||
})
|
||||
}
|
||||
|
||||
func Error(c *gin.Context, code int, message string) {
|
||||
c.JSON(code, APIResponse{
|
||||
Success: false,
|
||||
Message: message,
|
||||
})
|
||||
}
|
||||
|
||||
func SuccessWithMessage(c *gin.Context, message string, data interface{}) {
|
||||
c.JSON(http.StatusOK, APIResponse{
|
||||
Success: true,
|
||||
Message: message,
|
||||
Data: data,
|
||||
})
|
||||
}
|
||||
|
||||
func PaginatedResponse(c *gin.Context, items interface{}, total, page, limit int) {
|
||||
totalPages := total / limit
|
||||
if total%limit > 0 {
|
||||
totalPages++
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, APIResponse{
|
||||
Success: true,
|
||||
Data: PaginatedData{
|
||||
Items: items,
|
||||
Total: total,
|
||||
Page: page,
|
||||
Limit: limit,
|
||||
TotalPages: totalPages,
|
||||
},
|
||||
})
|
||||
}
|
||||
458
storage/logs/app.log
Normal file
458
storage/logs/app.log
Normal file
@ -0,0 +1,458 @@
|
||||
{"level":"info","ts":"2026-08-13T21:46:17.630+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-13T21:46:17.787+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-13T21:46:17.941+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-13T21:46:17.941+0700","caller":"handlers/handlers.go:36","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-13T21:46:43.223+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-13T21:46:43.494+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-13T21:46:43.618+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-13T21:46:43.618+0700","caller":"handlers/handlers.go:36","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-13T22:00:01.955+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-13T22:00:02.256+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-13T22:00:02.487+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-13T22:00:02.487+0700","caller":"handlers/handlers.go:38","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-13T22:15:06.240+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-13T22:15:06.365+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-13T22:15:06.445+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-13T22:15:06.445+0700","caller":"handlers/handlers.go:40","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-13T22:27:50.679+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-13T22:27:50.768+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-13T22:27:50.851+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-13T22:27:50.851+0700","caller":"handlers/handlers.go:85","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-13T22:28:27.312+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-13T22:28:27.404+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-13T22:28:27.475+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-13T22:28:27.476+0700","caller":"handlers/handlers.go:84","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-13T22:29:31.604+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-13T22:29:31.689+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-13T22:29:31.760+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-13T22:29:31.760+0700","caller":"handlers/handlers.go:85","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-13T22:30:59.523+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-13T22:30:59.609+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-13T22:30:59.703+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-13T22:30:59.703+0700","caller":"handlers/handlers.go:90","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-13T22:31:13.213+0700","caller":"handlers/handlers.go:72","msg":"Request Success","status":200,"method":"GET","path":"/ping","query":"","ip":"127.0.0.1","latency":0.002712167,"user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:153.0) Gecko/20100101 Firefox/153.0"}
|
||||
{"level":"warn","ts":"2026-08-13T22:31:13.526+0700","caller":"handlers/handlers.go:70","msg":"Client Error","status":404,"method":"GET","path":"/favicon.ico","query":"","ip":"127.0.0.1","latency":0.000858875,"user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:153.0) Gecko/20100101 Firefox/153.0"}
|
||||
{"level":"info","ts":"2026-08-13T22:31:20.833+0700","caller":"handlers/handlers.go:72","msg":"Request Success","status":200,"method":"GET","path":"/login","query":"","ip":"127.0.0.1","latency":0.002228875,"user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:153.0) Gecko/20100101 Firefox/153.0"}
|
||||
{"level":"warn","ts":"2026-08-13T22:31:20.869+0700","caller":"handlers/handlers.go:70","msg":"Client Error","status":404,"method":"GET","path":"/favicon.ico","query":"","ip":"127.0.0.1","latency":0.000000417,"user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:153.0) Gecko/20100101 Firefox/153.0"}
|
||||
{"level":"info","ts":"2026-08-13T23:00:21.130+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-13T23:00:21.243+0700","caller":"database/database.go:74","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-13T23:00:21.342+0700","caller":"database/database.go:84","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-13T23:01:44.195+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-13T23:01:44.278+0700","caller":"database/database.go:74","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-13T23:01:44.366+0700","caller":"database/database.go:84","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-13T23:05:29.670+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-13T23:05:29.755+0700","caller":"database/database.go:74","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-13T23:05:29.831+0700","caller":"database/database.go:84","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-13T23:07:40.483+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-13T23:07:40.584+0700","caller":"database/database.go:74","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-13T23:07:40.663+0700","caller":"database/database.go:84","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-13T23:13:19.014+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"fatal","ts":"2026-08-13T23:13:19.082+0700","caller":"database/database.go:58","msg":"failed to connect to `host=145.79.11.200 user=cargo database=cargo_erp`: server error (FATAL: bouncer config error (SQLSTATE 08P01))"}
|
||||
{"level":"info","ts":"2026-08-13T23:14:16.466+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"fatal","ts":"2026-08-13T23:14:16.562+0700","caller":"database/database.go:58","msg":"failed to connect to `host=145.79.11.200 user=cargo_admin database=cargo_erp`: failed SASL auth (FATAL: SASL authentication failed (SQLSTATE 08P01))"}
|
||||
{"level":"info","ts":"2026-08-13T23:14:35.650+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"fatal","ts":"2026-08-13T23:14:35.734+0700","caller":"database/database.go:58","msg":"failed to connect to `host=145.79.11.200 user=cargo database=cargo_erp`: server error (FATAL: bouncer config error (SQLSTATE 08P01))"}
|
||||
{"level":"info","ts":"2026-08-13T23:15:10.765+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"fatal","ts":"2026-08-13T23:15:10.824+0700","caller":"database/database.go:58","msg":"failed to connect to `host=145.79.11.200 user=cargo database=cargo_erp`: server error (FATAL: bouncer config error (SQLSTATE 08P01))"}
|
||||
{"level":"info","ts":"2026-08-13T23:15:20.833+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-13T23:15:20.917+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-13T23:15:20.918+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-13T23:15:21.006+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-13T23:16:39.066+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-13T23:16:39.173+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-13T23:16:39.173+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-13T23:16:39.252+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-13T23:18:32.972+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-13T23:18:33.064+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-13T23:18:33.064+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-13T23:18:33.142+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-13T23:22:52.364+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-13T23:22:52.450+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-13T23:22:52.451+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-13T23:22:52.528+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-13T23:25:38.058+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-13T23:25:38.157+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-13T23:25:38.157+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-13T23:25:49.271+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-13T23:25:49.370+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-13T23:25:49.370+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-13T23:25:49.457+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-14T00:09:28.596+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-14T00:09:28.682+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-14T00:09:28.682+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-14T00:09:28.760+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-14T00:11:14.945+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-14T00:11:15.037+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-14T00:11:15.037+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-14T00:11:15.125+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-14T00:14:12.844+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-14T00:14:12.933+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-14T00:14:12.934+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-14T00:14:13.014+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-14T00:16:03.378+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-14T00:16:03.472+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-14T00:16:03.472+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-14T00:16:03.564+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T10:33:04.359+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T10:33:04.796+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T10:33:04.797+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T10:33:05.036+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T10:33:05.036+0700","caller":"handlers/handlers.go:93","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-15T10:35:31.431+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T10:35:31.521+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T10:35:31.521+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T10:35:31.617+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T10:35:31.617+0700","caller":"handlers/handlers.go:93","msg":"Starting Apps"}
|
||||
{"level":"error","ts":"2026-08-15T10:36:29.127+0700","caller":"handlers/handlers.go:64","msg":"Key: 'AuthRequest.Email' Error:Field validation for 'Email' failed on the 'required' tag\nKey: 'AuthRequest.Password' Error:Field validation for 'Password' failed on the 'required' tag","status":400,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.0028055,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"error","ts":"2026-08-15T10:36:45.528+0700","caller":"handlers/handlers.go:64","msg":"Key: 'AuthRequest.Password' Error:Field validation for 'Password' failed on the 'required' tag","status":400,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.004973209,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T10:37:31.365+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T10:37:31.451+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T10:37:31.451+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T10:37:31.535+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T10:37:31.535+0700","caller":"handlers/handlers.go:93","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-15T10:37:34.953+0700","caller":"handlers/handlers.go:75","msg":"Request Success","status":200,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.032455291,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T10:54:09.472+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T10:54:09.555+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T10:54:09.555+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T10:54:09.631+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T10:54:09.631+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"error","ts":"2026-08-15T10:54:13.941+0700","caller":"handlers/handlers.go:60","msg":"Server Error","status":500,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.044428542,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T10:57:14.222+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T10:57:14.313+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T10:57:14.313+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T10:57:14.410+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T10:57:14.410+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"warn","ts":"2026-08-15T10:57:17.986+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":400,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.03831625,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T11:09:37.233+0700","caller":"database/database.go:108","msg":"Reload Connecting Database"}
|
||||
{"level":"info","ts":"2026-08-15T11:09:37.235+0700","caller":"database/database.go:97","msg":"Close Database Connection Start"}
|
||||
{"level":"info","ts":"2026-08-15T11:09:37.238+0700","caller":"database/database.go:102","msg":"Close Database Connection master"}
|
||||
{"level":"info","ts":"2026-08-15T11:09:37.239+0700","caller":"database/database.go:102","msg":"Close Database Connection slave"}
|
||||
{"level":"info","ts":"2026-08-15T11:09:37.239+0700","caller":"database/database.go:105","msg":"Close Database Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T11:09:37.239+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T11:09:37.352+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T11:09:37.352+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T11:09:37.430+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T11:11:40.726+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T11:11:40.829+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T11:11:40.829+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T11:11:40.973+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T11:11:40.973+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-15T11:12:09.727+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T11:12:09.812+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T11:12:09.812+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T11:12:09.898+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T11:12:09.898+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-15T21:41:50.394+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:41:50.668+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T21:41:50.668+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:41:50.840+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T21:42:17.260+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:42:17.351+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T21:42:17.351+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:42:17.428+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T21:43:45.063+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:43:45.199+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T21:43:45.199+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:43:45.292+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T21:44:12.818+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:44:12.918+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T21:44:12.918+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:44:12.992+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T21:44:31.989+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:44:32.077+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T21:44:32.077+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:44:32.162+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T21:45:18.090+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:45:18.217+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T21:45:18.217+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:45:18.296+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T21:45:18.419+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-15T21:46:06.762+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:46:06.985+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T21:46:06.985+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:46:07.079+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T21:46:07.198+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"warn","ts":"2026-08-15T21:46:33.811+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":400,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.147348833,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T21:49:20.652+0700","caller":"database/database.go:108","msg":"Reload Connecting Database"}
|
||||
{"level":"info","ts":"2026-08-15T21:49:20.656+0700","caller":"database/database.go:97","msg":"Close Database Connection Start"}
|
||||
{"level":"info","ts":"2026-08-15T21:49:20.661+0700","caller":"database/database.go:102","msg":"Close Database Connection slave"}
|
||||
{"level":"info","ts":"2026-08-15T21:49:20.661+0700","caller":"database/database.go:102","msg":"Close Database Connection master"}
|
||||
{"level":"info","ts":"2026-08-15T21:49:20.661+0700","caller":"database/database.go:105","msg":"Close Database Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T21:49:20.662+0700","caller":"database/database.go:52","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:49:20.771+0700","caller":"database/database.go:62","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T21:49:20.771+0700","caller":"database/database.go:75","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:49:20.993+0700","caller":"database/database.go:85","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T21:56:53.219+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:56:53.360+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T21:56:53.360+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:56:53.443+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T21:56:53.659+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-15T21:57:14.361+0700","caller":"database/database.go:111","msg":"Reload Connecting Database"}
|
||||
{"level":"info","ts":"2026-08-15T21:57:14.365+0700","caller":"database/database.go:100","msg":"Close Database Connection Start"}
|
||||
{"level":"info","ts":"2026-08-15T21:57:14.369+0700","caller":"database/database.go:105","msg":"Close Database Connection master"}
|
||||
{"level":"info","ts":"2026-08-15T21:57:14.370+0700","caller":"database/database.go:105","msg":"Close Database Connection slave"}
|
||||
{"level":"info","ts":"2026-08-15T21:57:14.370+0700","caller":"database/database.go:108","msg":"Close Database Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T21:57:14.371+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:57:14.521+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T21:57:14.521+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:57:14.601+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T21:57:14.601+0700","caller":"database/database.go:114","msg":"Reload Connecting Database Done"}
|
||||
{"level":"info","ts":"2026-08-15T21:57:21.394+0700","caller":"database/database.go:111","msg":"Reload Connecting Database"}
|
||||
{"level":"info","ts":"2026-08-15T21:57:21.396+0700","caller":"database/database.go:100","msg":"Close Database Connection Start"}
|
||||
{"level":"info","ts":"2026-08-15T21:57:21.396+0700","caller":"database/database.go:105","msg":"Close Database Connection master"}
|
||||
{"level":"info","ts":"2026-08-15T21:57:21.397+0700","caller":"database/database.go:105","msg":"Close Database Connection slave"}
|
||||
{"level":"info","ts":"2026-08-15T21:57:21.397+0700","caller":"database/database.go:108","msg":"Close Database Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T21:57:21.397+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:57:21.544+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T21:57:21.545+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T21:57:21.642+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T21:57:21.642+0700","caller":"database/database.go:114","msg":"Reload Connecting Database Done"}
|
||||
{"level":"warn","ts":"2026-08-15T21:57:38.325+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.132527625,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"warn","ts":"2026-08-15T22:00:08.985+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.183630167,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T22:00:52.456+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:00:52.576+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T22:00:52.576+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:00:52.654+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T22:00:52.785+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-15T22:00:55.679+0700","caller":"handlers/handlers.go:64","msg":"Request Success","status":200,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.135076584,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T22:01:45.193+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:01:45.291+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T22:01:45.291+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:01:45.365+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T22:01:45.570+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"warn","ts":"2026-08-15T22:01:51.501+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.031749625,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"warn","ts":"2026-08-15T22:02:26.847+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.069505792,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T22:04:05.942+0700","caller":"handlers/handlers.go:64","msg":"Request Success","status":200,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.148913625,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T22:09:54.081+0700","caller":"database/database.go:111","msg":"Reload Connecting Database"}
|
||||
{"level":"info","ts":"2026-08-15T22:09:54.085+0700","caller":"database/database.go:100","msg":"Close Database Connection Start"}
|
||||
{"level":"info","ts":"2026-08-15T22:09:54.090+0700","caller":"database/database.go:105","msg":"Close Database Connection master"}
|
||||
{"level":"info","ts":"2026-08-15T22:09:54.090+0700","caller":"database/database.go:105","msg":"Close Database Connection slave"}
|
||||
{"level":"info","ts":"2026-08-15T22:09:54.090+0700","caller":"database/database.go:108","msg":"Close Database Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T22:09:54.091+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:09:54.211+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T22:09:54.211+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:09:54.305+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T22:09:54.305+0700","caller":"database/database.go:114","msg":"Reload Connecting Database Done"}
|
||||
{"level":"info","ts":"2026-08-15T22:43:30.370+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:43:30.798+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T22:43:30.799+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:43:30.877+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T22:43:31.003+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-15T22:43:35.544+0700","caller":"handlers/handlers.go:64","msg":"Request Success","status":200,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.146430833,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"warn","ts":"2026-08-15T22:44:04.550+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.015486292,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"warn","ts":"2026-08-15T22:44:50.975+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.025776708,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T22:46:11.954+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:46:12.051+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T22:46:12.054+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:46:12.130+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T22:46:12.233+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"warn","ts":"2026-08-15T22:46:14.780+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.017874792,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T22:51:47.045+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:51:47.135+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T22:51:47.135+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:51:47.203+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T22:51:47.324+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"warn","ts":"2026-08-15T22:51:51.438+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.024666291,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T22:51:58.922+0700","caller":"handlers/handlers.go:64","msg":"Request Success","status":200,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.144759625,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"warn","ts":"2026-08-15T22:52:14.778+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.065118833,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T22:55:01.888+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:55:02.013+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T22:55:02.013+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:55:02.113+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T22:55:02.250+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"warn","ts":"2026-08-15T22:55:05.639+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.016216792,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T22:56:00.788+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:56:00.907+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T22:56:00.907+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:56:00.991+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T22:56:01.137+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"warn","ts":"2026-08-15T22:56:03.126+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.016038125,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T22:56:30.984+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:56:31.084+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T22:56:31.084+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:56:31.154+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T22:56:31.263+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"warn","ts":"2026-08-15T22:56:36.131+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.018368625,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T22:57:26.021+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:57:26.349+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T22:57:26.349+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:57:26.469+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T22:57:26.589+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"warn","ts":"2026-08-15T22:57:28.380+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.010972333,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T22:58:34.166+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:58:34.264+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T22:58:34.264+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T22:58:34.352+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T22:58:34.462+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-15T22:58:36.784+0700","caller":"middleware/auth.go:43","msg":"Session : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MTI3MTgsImlhdCI6MTc4NjgwOTExOH0.G_EigVQilWqK_HVIehF9n7aAu-8T_ANKQg6Kge2JUxA"}
|
||||
{"level":"warn","ts":"2026-08-15T22:58:36.796+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.012448291,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T23:00:12.979+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:00:13.068+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T23:00:13.068+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:00:13.151+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T23:00:13.270+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-15T23:00:15.329+0700","caller":"handlers/handlers.go:64","msg":"Request Success","status":200,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.141631917,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T23:00:26.344+0700","caller":"middleware/auth.go:44","msg":"Session : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MTMyMTUsImlhdCI6MTc4NjgwOTYxNX0.RyfPuq_BNl6RU8msz_LWC_ZzReo71_VlLzcjnELomBU"}
|
||||
{"level":"info","ts":"2026-08-15T23:01:16.688+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:01:16.771+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T23:01:16.771+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:01:16.886+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T23:01:17.001+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-15T23:01:19.639+0700","caller":"middleware/auth.go:44","msg":"Session : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MTMyMTUsImlhdCI6MTc4NjgwOTYxNX0.RyfPuq_BNl6RU8msz_LWC_ZzReo71_VlLzcjnELomBU"}
|
||||
{"level":"info","ts":"2026-08-15T23:01:36.822+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:01:36.910+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T23:01:36.910+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:01:36.991+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T23:01:37.098+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-15T23:01:38.777+0700","caller":"middleware/auth.go:44","msg":"Session : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MTMyMTUsImlhdCI6MTc4NjgwOTYxNX0.RyfPuq_BNl6RU8msz_LWC_ZzReo71_VlLzcjnELomBU"}
|
||||
{"level":"info","ts":"2026-08-15T23:02:12.263+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:02:12.370+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T23:02:12.371+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:02:12.447+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T23:02:12.562+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-15T23:02:15.161+0700","caller":"middleware/auth.go:44","msg":"Session : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MTMyMTUsImlhdCI6MTc4NjgwOTYxNX0.RyfPuq_BNl6RU8msz_LWC_ZzReo71_VlLzcjnELomBU"}
|
||||
{"level":"info","ts":"2026-08-15T23:02:38.791+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:02:38.869+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T23:02:38.869+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:02:38.937+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T23:02:39.067+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-15T23:02:41.220+0700","caller":"middleware/auth.go:44","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MTMyMTUsImlhdCI6MTc4NjgwOTYxNX0.RyfPuq_BNl6RU8msz_LWC_ZzReo71_VlLzcjnELomBU"}
|
||||
{"level":"info","ts":"2026-08-15T23:02:56.824+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:02:56.914+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T23:02:56.914+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:02:56.988+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T23:02:57.104+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-15T23:02:58.684+0700","caller":"middleware/auth.go:44","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MTMyMTUsImlhdCI6MTc4NjgwOTYxNX0.RyfPuq_BNl6RU8msz_LWC_ZzReo71_VlLzcjnELomBU"}
|
||||
{"level":"info","ts":"2026-08-15T23:16:20.283+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:16:20.369+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T23:16:20.369+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:16:20.452+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T23:18:31.629+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:18:31.719+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T23:18:31.719+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:18:31.789+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T23:18:31.903+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-15T23:18:39.291+0700","caller":"handlers/handlers.go:64","msg":"Request Success","status":200,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.140461083,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T23:20:19.696+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:20:19.784+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T23:20:19.785+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:20:19.857+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T23:20:19.962+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"warn","ts":"2026-08-15T23:20:22.753+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.1520805,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T23:22:36.618+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:22:36.732+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T23:22:36.732+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:22:36.808+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T23:22:36.921+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-15T23:22:41.571+0700","caller":"handlers/handlers.go:64","msg":"Request Success","status":200,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.14289375,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T23:23:53.871+0700","caller":"middleware/auth.go:44","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MTQ1NjEsImlhdCI6MTc4NjgxMDk2MX0.no9KKVGl_khgBf8tGE8FAl9_zBdcWkEUiUFzmFmOacc"}
|
||||
{"level":"info","ts":"2026-08-15T23:25:24.065+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:25:24.147+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T23:25:24.147+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:25:24.214+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T23:25:24.320+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-15T23:25:26.242+0700","caller":"middleware/auth.go:43","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MTQ1NjEsImlhdCI6MTc4NjgxMDk2MX0.no9KKVGl_khgBf8tGE8FAl9_zBdcWkEUiUFzmFmOacc"}
|
||||
{"level":"info","ts":"2026-08-15T23:25:26.255+0700","caller":"middleware/auth.go:55","msg":"Set Auth : {\"id\":\"19ff1031a11c0c013f60044f56\",\"merchant_id\":null,\"nick_name\":\"Super Admin\",\"email\":\"crackers.biscuits@gmail.com\",\"password\":\"$2a$10$A0R8A2CDxxcQuGbTW/r2merI4rymcbe27Wh5kPH..qNMJUzmtAb/e\",\"is_active\":true,\"users_role_id\":\"19fe813c54d12bf48f1d7c710e\",\"blocked\":false,\"blocked_notes\":null,\"created_by\":null,\"created_on\":\"2026-08-11T20:29:00.18279Z\",\"updated_by\":null,\"updated_on\":\"2026-08-11T20:29:00.18279Z\",\"merchant_relation\":null,\"users_role_relation\":{\"id\":\"\",\"name\":null,\"merchant_id\":null,\"created_by\":null,\"created_on\":null,\"updated_by\":null,\"updated_on\":null,\"role_key\":\"\",\"merchant_relation\":{\"id\":\"\",\"name\":null,\"address\":null,\"email\":null,\"telp\":null,\"additional_information\":null,\"active\":null,\"created_by\":null,\"created_on\":null,\"updated_by\":null,\"updated_on\":null,\"province_id\":null,\"city_id\":null,\"district_id\":null,\"subdistrict_id\":null,\"postal_code\":null,\"province_relation\":null,\"city_relation\":null,\"district_relation\":null,\"subdistrict_relation\":null,\"users_roless_relation\":null,\"modas_relation\":null,\"package_types_relation\":null,\"userss_relation\":null,\"created_by_relation\":null,\"provinces_relation\":null,\"citys_relation\":null,\"districts_relation\":null,\"subdistricts_relation\":null,\"postal_codes_relation\":null},\"userss_relation\":null},\"merchants_relation\":null,\"provinces_relation\":null,\"citys_relation\":null,\"districts_relation\":null,\"subdistricts_relation\":null,\"postal_codes_relation\":null}"}
|
||||
{"level":"info","ts":"2026-08-15T23:25:26.257+0700","caller":"handlers/handlers.go:64","msg":"Request Success","status":200,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.014630542,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T23:30:07.616+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:30:07.728+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T23:30:07.728+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:30:07.806+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T23:30:07.936+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-15T23:30:12.541+0700","caller":"middleware/auth.go:43","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MTQ1NjEsImlhdCI6MTc4NjgxMDk2MX0.no9KKVGl_khgBf8tGE8FAl9_zBdcWkEUiUFzmFmOacc"}
|
||||
{"level":"info","ts":"2026-08-15T23:30:12.551+0700","caller":"middleware/auth.go:55","msg":"Set Auth : {\"id\":\"19ff1031a11c0c013f60044f56\",\"merchant_id\":null,\"nick_name\":\"Super Admin\",\"email\":\"crackers.biscuits@gmail.com\",\"password\":\"$2a$10$A0R8A2CDxxcQuGbTW/r2merI4rymcbe27Wh5kPH..qNMJUzmtAb/e\",\"is_active\":true,\"users_role_id\":\"19fe813c54d12bf48f1d7c710e\",\"blocked\":false,\"blocked_notes\":null,\"created_by\":null,\"created_on\":\"2026-08-11T20:29:00.18279Z\",\"updated_by\":null,\"updated_on\":\"2026-08-11T20:29:00.18279Z\",\"merchant_relation\":null,\"users_role_relation\":{\"id\":\"\",\"name\":null,\"merchant_id\":null,\"created_by\":null,\"created_on\":null,\"updated_by\":null,\"updated_on\":null,\"role_key\":\"\",\"merchant_relation\":{\"id\":\"\",\"name\":null,\"address\":null,\"email\":null,\"telp\":null,\"additional_information\":null,\"active\":null,\"created_by\":null,\"created_on\":null,\"updated_by\":null,\"updated_on\":null,\"province_id\":null,\"city_id\":null,\"district_id\":null,\"subdistrict_id\":null,\"postal_code\":null,\"province_relation\":null,\"city_relation\":null,\"district_relation\":null,\"subdistrict_relation\":null,\"users_roless_relation\":null,\"modas_relation\":null,\"package_types_relation\":null,\"userss_relation\":null,\"created_by_relation\":null,\"provinces_relation\":null,\"citys_relation\":null,\"districts_relation\":null,\"subdistricts_relation\":null,\"postal_codes_relation\":null},\"userss_relation\":null},\"merchants_relation\":null,\"provinces_relation\":null,\"citys_relation\":null,\"districts_relation\":null,\"subdistricts_relation\":null,\"postal_codes_relation\":null}"}
|
||||
{"level":"info","ts":"2026-08-15T23:30:12.566+0700","caller":"handlers/handlers.go:64","msg":"Request Success","status":200,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.024830708,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T23:30:21.452+0700","caller":"middleware/auth.go:43","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MTQ1NjEsImlhdCI6MTc4NjgxMDk2MX0.no9KKVGl_khgBf8tGE8FAl9_zBdcWkEUiUFzmFmOacc"}
|
||||
{"level":"warn","ts":"2026-08-15T23:30:21.472+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.020868,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T23:30:23.607+0700","caller":"middleware/auth.go:43","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MTQ1NjEsImlhdCI6MTc4NjgxMDk2MX0.no9KKVGl_khgBf8tGE8FAl9_zBdcWkEUiUFzmFmOacc"}
|
||||
{"level":"warn","ts":"2026-08-15T23:30:23.625+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.017106458,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T23:36:21.508+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:36:21.606+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T23:36:21.606+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:36:21.701+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T23:36:21.807+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-15T23:37:59.688+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:37:59.767+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-15T23:37:59.767+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-15T23:37:59.842+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-15T23:37:59.948+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-15T23:39:05.986+0700","caller":"handlers/handlers.go:64","msg":"Request Success","status":200,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.152333541,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T23:39:18.222+0700","caller":"middleware/auth.go:43","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MTU1NDUsImlhdCI6MTc4NjgxMTk0NX0.U-AGAkbba7kij5iIPjV7x7VY6TUJ3ehO1UN4qqjMM7k"}
|
||||
{"level":"info","ts":"2026-08-15T23:39:18.233+0700","caller":"middleware/auth.go:79","msg":"Set Auth : {\"id\":\"19ff1031a11c0c013f60044f56\",\"merchant_id\":null,\"nick_name\":\"Super Admin\",\"email\":\"crackers.biscuits@gmail.com\",\"password\":\"$2a$10$A0R8A2CDxxcQuGbTW/r2merI4rymcbe27Wh5kPH..qNMJUzmtAb/e\",\"is_active\":true,\"users_role_id\":\"19fe813c54d12bf48f1d7c710e\",\"blocked\":false,\"blocked_notes\":null,\"created_by\":null,\"created_on\":\"2026-08-11T20:29:00.18279Z\",\"updated_by\":null,\"updated_on\":\"2026-08-11T20:29:00.18279Z\",\"merchant_relation\":null,\"users_role_relation\":{\"id\":\"\",\"name\":null,\"merchant_id\":null,\"created_by\":null,\"created_on\":null,\"updated_by\":null,\"updated_on\":null,\"role_key\":\"\",\"merchant_relation\":{\"id\":\"\",\"name\":null,\"address\":null,\"email\":null,\"telp\":null,\"additional_information\":null,\"active\":null,\"created_by\":null,\"created_on\":null,\"updated_by\":null,\"updated_on\":null,\"province_id\":null,\"city_id\":null,\"district_id\":null,\"subdistrict_id\":null,\"postal_code\":null,\"province_relation\":null,\"city_relation\":null,\"district_relation\":null,\"subdistrict_relation\":null,\"users_roless_relation\":null,\"modas_relation\":null,\"package_types_relation\":null,\"userss_relation\":null,\"created_by_relation\":null,\"provinces_relation\":null,\"citys_relation\":null,\"districts_relation\":null,\"subdistricts_relation\":null,\"postal_codes_relation\":null},\"userss_relation\":null},\"merchants_relation\":null,\"provinces_relation\":null,\"citys_relation\":null,\"districts_relation\":null,\"subdistricts_relation\":null,\"postal_codes_relation\":null}"}
|
||||
{"level":"info","ts":"2026-08-15T23:39:18.247+0700","caller":"handlers/handlers.go:64","msg":"Request Success","status":200,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.024412875,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-15T23:39:20.977+0700","caller":"middleware/auth.go:43","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MTU1NDUsImlhdCI6MTc4NjgxMTk0NX0.U-AGAkbba7kij5iIPjV7x7VY6TUJ3ehO1UN4qqjMM7k"}
|
||||
{"level":"warn","ts":"2026-08-15T23:39:20.997+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.020748084,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-16T00:15:07.911+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-16T00:15:08.007+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-16T00:15:08.007+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-16T00:15:08.078+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-16T00:15:08.194+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-16T00:28:48.223+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-16T00:28:48.343+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-16T00:28:48.358+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-16T00:28:48.457+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-16T00:28:48.560+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-16T00:28:52.225+0700","caller":"handlers/handlers.go:64","msg":"Request Success","status":200,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.146153875,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-16T00:29:06.165+0700","caller":"middleware/auth.go:43","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MTg1MzIsImlhdCI6MTc4NjgxNDkzMn0.La4ZzjebMg4OaAcLd-CBWR1HgVZnqpKuo3y_DyFbhm0"}
|
||||
{"level":"warn","ts":"2026-08-16T00:29:06.199+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.033537125,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-16T00:31:49.605+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-16T00:31:49.711+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-16T00:31:49.711+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-16T00:31:49.784+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-16T00:31:49.888+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-16T00:31:52.717+0700","caller":"middleware/auth.go:43","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MTg1MzIsImlhdCI6MTc4NjgxNDkzMn0.La4ZzjebMg4OaAcLd-CBWR1HgVZnqpKuo3y_DyFbhm0"}
|
||||
{"level":"warn","ts":"2026-08-16T00:31:52.740+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.022636333,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-16T00:32:38.076+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-16T00:32:38.197+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-16T00:32:38.197+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-16T00:32:38.287+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-16T00:32:38.399+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-16T00:32:42.956+0700","caller":"middleware/auth.go:43","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MTg1MzIsImlhdCI6MTc4NjgxNDkzMn0.La4ZzjebMg4OaAcLd-CBWR1HgVZnqpKuo3y_DyFbhm0"}
|
||||
{"level":"warn","ts":"2026-08-16T00:32:42.978+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.022303667,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-16T00:37:33.768+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-16T00:37:33.851+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-16T00:37:33.851+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-16T00:37:33.920+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-16T00:37:34.026+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-16T00:37:36.633+0700","caller":"middleware/auth.go:44","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MTg1MzIsImlhdCI6MTc4NjgxNDkzMn0.La4ZzjebMg4OaAcLd-CBWR1HgVZnqpKuo3y_DyFbhm0"}
|
||||
{"level":"info","ts":"2026-08-16T00:56:59.720+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-16T00:56:59.810+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-16T00:56:59.810+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-16T00:56:59.887+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-16T00:57:00.001+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-16T00:57:46.069+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-16T00:57:46.161+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-16T00:57:46.161+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-16T00:57:46.233+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-16T00:57:46.334+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-16T00:57:50.872+0700","caller":"middleware/auth.go:62","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MTg1MzIsImlhdCI6MTc4NjgxNDkzMn0.La4ZzjebMg4OaAcLd-CBWR1HgVZnqpKuo3y_DyFbhm0"}
|
||||
{"level":"info","ts":"2026-08-16T00:57:50.895+0700","caller":"middleware/auth.go:90","msg":"Set Auth : {\"blocked\":false,\"blocked_notes\":null,\"citys_relation\":null,\"created_by\":null,\"created_on\":\"2026-08-11T20:29:00.18279Z\",\"districts_relation\":null,\"email\":\"crackers.biscuits@gmail.com\",\"id\":\"19ff1031a11c0c013f60044f56\",\"is_active\":true,\"merchant_id\":null,\"merchant_relation\":null,\"merchants_relation\":null,\"nick_name\":\"Super Admin\",\"postal_codes_relation\":null,\"provinces_relation\":null,\"subdistricts_relation\":null,\"updated_by\":null,\"updated_on\":\"2026-08-11T20:29:00.18279Z\",\"users_role_id\":\"19fe813c54d12bf48f1d7c710e\",\"users_role_relation\":{\"created_by\":null,\"created_on\":null,\"id\":\"\",\"merchant_id\":null,\"merchant_relation\":{\"active\":null,\"additional_information\":null,\"address\":null,\"city_id\":null,\"city_relation\":null,\"citys_relation\":null,\"created_by\":null,\"created_by_relation\":null,\"created_on\":null,\"district_id\":null,\"district_relation\":null,\"districts_relation\":null,\"email\":null,\"id\":\"\",\"modas_relation\":null,\"name\":null,\"package_types_relation\":null,\"postal_code\":null,\"postal_codes_relation\":null,\"province_id\":null,\"province_relation\":null,\"provinces_relation\":null,\"subdistrict_id\":null,\"subdistrict_relation\":null,\"subdistricts_relation\":null,\"telp\":null,\"updated_by\":null,\"updated_on\":null,\"users_roless_relation\":null,\"userss_relation\":null},\"name\":null,\"role_key\":\"\",\"updated_by\":null,\"updated_on\":null,\"userss_relation\":null}}"}
|
||||
{"level":"info","ts":"2026-08-16T00:57:50.911+0700","caller":"handlers/handlers.go:64","msg":"Request Success","status":200,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.038014083,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-16T00:57:53.419+0700","caller":"middleware/auth.go:62","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MTg1MzIsImlhdCI6MTc4NjgxNDkzMn0.La4ZzjebMg4OaAcLd-CBWR1HgVZnqpKuo3y_DyFbhm0"}
|
||||
{"level":"warn","ts":"2026-08-16T00:57:53.429+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.010037542,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-16T01:06:48.679+0700","caller":"middleware/auth.go:62","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MTg1MzIsImlhdCI6MTc4NjgxNDkzMn0.La4ZzjebMg4OaAcLd-CBWR1HgVZnqpKuo3y_DyFbhm0"}
|
||||
{"level":"warn","ts":"2026-08-16T01:06:48.704+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.025659833,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-16T01:07:01.070+0700","caller":"handlers/handlers.go:64","msg":"Request Success","status":200,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.165668709,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-16T01:07:05.663+0700","caller":"handlers/handlers.go:64","msg":"Request Success","status":200,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.099613708,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-16T01:07:41.632+0700","caller":"middleware/auth.go:62","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MjA4MjUsImlhdCI6MTc4NjgxNzIyNX0.00s8ApCLAmsJwbHVyAYyDjwRV3ht4Pu8YmzQFaRymnQ"}
|
||||
{"level":"info","ts":"2026-08-16T01:07:41.662+0700","caller":"middleware/auth.go:90","msg":"Set Auth : {\"blocked\":false,\"blocked_notes\":null,\"citys_relation\":null,\"created_by\":null,\"created_on\":\"2026-08-11T20:29:00.18279Z\",\"districts_relation\":null,\"email\":\"crackers.biscuits@gmail.com\",\"id\":\"19ff1031a11c0c013f60044f56\",\"is_active\":true,\"merchant_id\":null,\"merchant_relation\":null,\"merchants_relation\":null,\"nick_name\":\"Super Admin\",\"postal_codes_relation\":null,\"provinces_relation\":null,\"subdistricts_relation\":null,\"updated_by\":null,\"updated_on\":\"2026-08-11T20:29:00.18279Z\",\"users_role_id\":\"19fe813c54d12bf48f1d7c710e\",\"users_role_relation\":{\"created_by\":null,\"created_on\":null,\"id\":\"\",\"merchant_id\":null,\"merchant_relation\":{\"active\":null,\"additional_information\":null,\"address\":null,\"city_id\":null,\"city_relation\":null,\"citys_relation\":null,\"created_by\":null,\"created_by_relation\":null,\"created_on\":null,\"district_id\":null,\"district_relation\":null,\"districts_relation\":null,\"email\":null,\"id\":\"\",\"modas_relation\":null,\"name\":null,\"package_types_relation\":null,\"postal_code\":null,\"postal_codes_relation\":null,\"province_id\":null,\"province_relation\":null,\"provinces_relation\":null,\"subdistrict_id\":null,\"subdistrict_relation\":null,\"subdistricts_relation\":null,\"telp\":null,\"updated_by\":null,\"updated_on\":null,\"users_roless_relation\":null,\"userss_relation\":null},\"name\":null,\"role_key\":\"\",\"updated_by\":null,\"updated_on\":null,\"userss_relation\":null}}"}
|
||||
{"level":"info","ts":"2026-08-16T01:07:41.676+0700","caller":"handlers/handlers.go:64","msg":"Request Success","status":200,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.044218125,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-16T01:07:47.376+0700","caller":"middleware/auth.go:62","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MjA4MjUsImlhdCI6MTc4NjgxNzIyNX0.00s8ApCLAmsJwbHVyAYyDjwRV3ht4Pu8YmzQFaRymnQ"}
|
||||
{"level":"warn","ts":"2026-08-16T01:07:47.399+0700","caller":"handlers/handlers.go:62","msg":"Client Error","status":401,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.02364325,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-16T01:08:29.877+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-16T01:08:29.969+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-16T01:08:29.969+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-16T01:08:30.043+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-16T01:08:30.145+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-16T01:08:33.218+0700","caller":"handlers/handlers.go:64","msg":"Request Success","status":200,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.123252208,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-16T01:08:35.002+0700","caller":"handlers/handlers.go:64","msg":"Request Success","status":200,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.108842167,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-16T01:08:55.108+0700","caller":"database/database.go:53","msg":"Connect To Master DB"}
|
||||
{"level":"info","ts":"2026-08-16T01:08:55.196+0700","caller":"database/database.go:63","msg":"DB Master Connected"}
|
||||
{"level":"info","ts":"2026-08-16T01:08:55.196+0700","caller":"database/database.go:76","msg":"Connect To Slave DB"}
|
||||
{"level":"info","ts":"2026-08-16T01:08:55.267+0700","caller":"database/database.go:86","msg":"DB Connection Done"}
|
||||
{"level":"info","ts":"2026-08-16T01:08:55.372+0700","caller":"handlers/handlers.go:81","msg":"Starting Apps"}
|
||||
{"level":"info","ts":"2026-08-16T01:08:55.959+0700","caller":"handlers/handlers.go:64","msg":"Request Success","status":200,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.128654042,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-16T01:09:49.767+0700","caller":"middleware/auth.go:62","msg":"session_login : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIxOWZmMTAzMWExMWMwYzAxM2Y2MDA0NGY1NiIsImlzcyI6ImNhcmdvLXBsYXRmb3JtIiwic3ViIjoiMTlmZjEwMzFhMTFjMGMwMTNmNjAwNDRmNTYiLCJleHAiOjE3ODY4MjA5MTMsImlhdCI6MTc4NjgxNzMxM30.2bT0Odo8WsWMuBD5NX4e1pV0_WEFxz3_e8IDazDpxvo"}
|
||||
{"level":"info","ts":"2026-08-16T01:09:49.793+0700","caller":"middleware/auth.go:90","msg":"Set Auth : {\"blocked\":false,\"blocked_notes\":null,\"citys_relation\":null,\"created_by\":null,\"created_on\":\"2026-08-11T20:29:00.18279Z\",\"districts_relation\":null,\"email\":\"crackers.biscuits@gmail.com\",\"id\":\"19ff1031a11c0c013f60044f56\",\"is_active\":true,\"merchant_id\":null,\"merchant_relation\":null,\"merchants_relation\":null,\"nick_name\":\"Super Admin\",\"postal_codes_relation\":null,\"provinces_relation\":null,\"subdistricts_relation\":null,\"updated_by\":null,\"updated_on\":\"2026-08-11T20:29:00.18279Z\",\"users_role_id\":\"19fe813c54d12bf48f1d7c710e\",\"users_role_relation\":{\"created_by\":null,\"created_on\":null,\"id\":\"\",\"merchant_id\":null,\"merchant_relation\":{\"active\":null,\"additional_information\":null,\"address\":null,\"city_id\":null,\"city_relation\":null,\"citys_relation\":null,\"created_by\":null,\"created_by_relation\":null,\"created_on\":null,\"district_id\":null,\"district_relation\":null,\"districts_relation\":null,\"email\":null,\"id\":\"\",\"modas_relation\":null,\"name\":null,\"package_types_relation\":null,\"postal_code\":null,\"postal_codes_relation\":null,\"province_id\":null,\"province_relation\":null,\"provinces_relation\":null,\"subdistrict_id\":null,\"subdistrict_relation\":null,\"subdistricts_relation\":null,\"telp\":null,\"updated_by\":null,\"updated_on\":null,\"users_roless_relation\":null,\"userss_relation\":null},\"name\":null,\"role_key\":\"\",\"updated_by\":null,\"updated_on\":null,\"userss_relation\":null}}"}
|
||||
{"level":"info","ts":"2026-08-16T01:09:49.806+0700","caller":"handlers/handlers.go:64","msg":"Request Success","status":200,"method":"POST","path":"/logout","query":"","ip":"127.0.0.1","latency":0.040288125,"user-agent":"insomnia/13.1.0"}
|
||||
{"level":"info","ts":"2026-08-16T01:09:56.587+0700","caller":"handlers/handlers.go:64","msg":"Request Success","status":200,"method":"POST","path":"/login","query":"","ip":"127.0.0.1","latency":0.1347395,"user-agent":"insomnia/13.1.0"}
|
||||
3126
storage/logs/db.log
Normal file
3126
storage/logs/db.log
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user