feat (crud): add person, person-contact, person-address

This commit is contained in:
dpurbosakti
2025-08-25 14:07:14 +07:00
parent c3132fe2b7
commit 280d373576
45 changed files with 2536 additions and 49 deletions
@@ -66,6 +66,50 @@ CREATE TABLE "public"."DivisionPosition" (
CONSTRAINT "uni_DivisionPosition_Code" UNIQUE ("Code"), CONSTRAINT "uni_DivisionPosition_Code" UNIQUE ("Code"),
CONSTRAINT "fk_DivisionPosition_Division" FOREIGN KEY ("Division_Id") REFERENCES "public"."Division" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION CONSTRAINT "fk_DivisionPosition_Division" FOREIGN KEY ("Division_Id") REFERENCES "public"."Division" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
); );
-- Create "Person" table
CREATE TABLE "public"."Person" (
"Id" bigserial NOT NULL,
"CreatedAt" timestamptz NULL,
"UpdatedAt" timestamptz NULL,
"DeletedAt" timestamptz NULL,
"Name" character varying(150) NOT NULL,
"BirthDate" timestamptz NULL,
"BirthRegency_Code" character varying(4) NULL,
"Gender_Code" character varying(10) NULL,
"ResidentIdentityNumber" character varying(16) NULL,
"Religion_Code" character varying(10) NULL,
"Education_Code" character varying(10) NULL,
"Ocupation_Code" character varying(15) NULL,
"Ocupation_Name" character varying(50) NULL,
"Ethnic_Code" character varying(15) NULL,
PRIMARY KEY ("Id")
);
-- Create "PersonAddress" table
CREATE TABLE "public"."PersonAddress" (
"Id" bigserial NOT NULL,
"CreatedAt" timestamptz NULL,
"UpdatedAt" timestamptz NULL,
"DeletedAt" timestamptz NULL,
"Person_Id" bigint NULL,
"Address" character varying(150) NULL,
"Rt" character varying(2) NULL,
"Rw" character varying(2) NULL,
"Village_Code" character varying(10) NULL,
PRIMARY KEY ("Id"),
CONSTRAINT "fk_Person_Addresses" FOREIGN KEY ("Person_Id") REFERENCES "public"."Person" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
);
-- Create "PersonContact" table
CREATE TABLE "public"."PersonContact" (
"Id" bigserial NOT NULL,
"CreatedAt" timestamptz NULL,
"UpdatedAt" timestamptz NULL,
"DeletedAt" timestamptz NULL,
"Person_Id" bigint NULL,
"Type_Code" character varying(10) NULL,
"Value" character varying(100) NULL,
PRIMARY KEY ("Id"),
CONSTRAINT "fk_Person_Contacts" FOREIGN KEY ("Person_Id") REFERENCES "public"."Person" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
);
-- Create "Installation" table -- Create "Installation" table
CREATE TABLE "public"."Installation" ( CREATE TABLE "public"."Installation" (
"Id" serial NOT NULL, "Id" serial NOT NULL,
@@ -0,0 +1,2 @@
-- Modify "PersonContact" table
ALTER TABLE "public"."PersonContact" ALTER COLUMN "Type_Code" TYPE character varying(15);
+3 -2
View File
@@ -1,2 +1,3 @@
h1:BeM3qkN2alMJypXIeFt15SbwthvdFivDIoB6gVZayPM= h1:0EV4fJWckR7Ma3cBvARIaNvZvwO/9rXVWEknYQ5KuS8=
20250820083721.sql h1:I3MicNCsXGQJLAWD6axmyvjKZHEObHbF5WKfhQf1ijQ= 20250825054027.sql h1:zRUeuuP4bDLf96Cb38D/l9ivBAQC745XRao0rxbzdVI=
20250825060522.sql h1:NiE1fVzydcg8Y8ytSHgt0DkkauQFveNXv42BoG5m+bI=
+1 -1
View File
@@ -15,6 +15,7 @@ require (
github.com/karincake/lepet v0.0.1 github.com/karincake/lepet v0.0.1
github.com/karincake/risoles v0.0.3 github.com/karincake/risoles v0.0.3
github.com/karincake/semprit v0.0.3 github.com/karincake/semprit v0.0.3
github.com/rs/zerolog v1.33.0
golang.org/x/crypto v0.41.0 golang.org/x/crypto v0.41.0
gorm.io/driver/postgres v1.5.11 gorm.io/driver/postgres v1.5.11
gorm.io/gorm v1.25.12 gorm.io/gorm v1.25.12
@@ -39,7 +40,6 @@ require (
github.com/mattn/go-sqlite3 v1.14.28 // indirect github.com/mattn/go-sqlite3 v1.14.28 // indirect
github.com/microsoft/go-mssqldb v1.7.2 // indirect github.com/microsoft/go-mssqldb v1.7.2 // indirect
github.com/nxadm/tail v1.4.11 // indirect github.com/nxadm/tail v1.4.11 // indirect
github.com/rs/zerolog v1.33.0 // indirect
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
golang.org/x/sync v0.16.0 // indirect golang.org/x/sync v0.16.0 // indirect
golang.org/x/sys v0.35.0 // indirect golang.org/x/sys v0.35.0 // indirect
@@ -0,0 +1,68 @@
package division
import (
ecore "simrs-vx/internal/domain/base-entities/core"
)
type CreateDto struct {
Code string `json:"code"`
Name string `json:"name"`
Parent_Id *int16 `json:"parent_id"`
}
type ReadListDto struct {
Code string `json:"code"`
Name string `json:"name"`
Parent_Id *int16 `json:"parent_id"`
Page int `json:"page"`
PageSize int `json:"page_size"`
NoPagination int `json:"no_pagination"`
}
type ReadDetailDto struct {
Id uint16 `json:"id"`
Code string `json:"code"`
Name string `json:"name"`
Parent_Id *int16 `json:"parent_id"`
}
type UpdateDto struct {
Id uint16 `json:"id"`
CreateDto
}
type DeleteDto struct {
Id uint16 `json:"id"`
}
type MetaDto struct {
PageNumber int `json:"page_number"`
PageSize int `json:"page_size"`
Count int `json:"count"`
}
type ResponseDto struct {
ecore.SmallMain
Code string `json:"code"`
Name string `json:"name"`
Parent_Id *int16 `json:"parent_id"`
}
func (d Division) ToResponse() ResponseDto {
resp := ResponseDto{
Code: d.Code,
Name: d.Name,
Parent_Id: d.Parent_Id,
}
resp.SmallMain = d.SmallMain
return resp
}
func ToResponseList(users []Division) []ResponseDto {
resp := make([]ResponseDto, len(users))
for i, u := range users {
resp[i] = u.ToResponse()
}
return resp
}
@@ -0,0 +1,12 @@
package division
import (
ecore "simrs-vx/internal/domain/base-entities/core"
)
type Division struct {
ecore.SmallMain // adjust this according to the needs
Code string `json:"code" gorm:"unique;size:10"`
Name string `json:"name" gorm:"size:50"`
Parent_Id *int16 `json:"parent_id"`
}
@@ -0,0 +1,72 @@
package personaddress
import (
ecore "simrs-vx/internal/domain/base-entities/core"
)
type CreateDto struct {
Person_Id uint `json:"person_id"`
Address string `json:"address"`
Rt string `json:"rt"`
Rw string `json:"rw"`
Village_Code string `json:"village_code"`
}
type ReadListDto struct {
Page int `json:"page"`
PageSize int `json:"page_size"`
NoPagination int `json:"no_pagination"`
}
type ReadDetailDto struct {
Id uint `json:"id"`
Person_Id uint `json:"person_id"`
Address string `json:"address"`
Rt string `json:"rt"`
Rw string `json:"rw"`
Village_Code string `json:"village_code"`
}
type UpdateDto struct {
Id uint `json:"id"`
CreateDto
}
type DeleteDto struct {
Id uint `json:"id"`
}
type MetaDto struct {
PageNumber int `json:"page_number"`
PageSize int `json:"page_size"`
Count int `json:"count"`
}
type ResponseDto struct {
ecore.Main
Person_Id uint `json:"person_id"`
Address string `json:"address"`
Rt string `json:"rt"`
Rw string `json:"rw"`
Village_Code string `json:"village_code"`
}
func (d PersonAddress) ToResponse() ResponseDto {
resp := ResponseDto{
Person_Id: d.Person_Id,
Address: d.Address,
Rt: d.Rt,
Rw: d.Rw,
Village_Code: d.Village_Code,
}
resp.Main = d.Main
return resp
}
func ToResponseList(users []PersonAddress) []ResponseDto {
resp := make([]ResponseDto, len(users))
for i, u := range users {
resp[i] = u.ToResponse()
}
return resp
}
@@ -0,0 +1,14 @@
package personaddress
import (
ecore "simrs-vx/internal/domain/base-entities/core"
)
type PersonAddress struct {
ecore.Main // adjust this according to the needs
Person_Id uint `json:"person_id"`
Address string `json:"address" gorm:"size:150"`
Rt string `json:"rt" gorm:"size:2"`
Rw string `json:"rw" gorm:"size:2"`
Village_Code string `json:"village_code" gorm:"size:10"`
}
@@ -0,0 +1,65 @@
package personcontact
import (
ecore "simrs-vx/internal/domain/base-entities/core"
erp "simrs-vx/internal/domain/references/person"
)
type CreateDto struct {
Person_Id uint `json:"person_id"`
Type_Code erp.ContactTypeCode `json:"type_code"`
Value string `json:"value"`
}
type ReadListDto struct {
Page int `json:"page"`
PageSize int `json:"page_size"`
NoPagination int `json:"no_pagination"`
}
type ReadDetailDto struct {
Id uint `json:"id"`
Person_Id uint `json:"person_id"`
Type_Code erp.ContactTypeCode `json:"type_code"`
Value string `json:"value"`
}
type UpdateDto struct {
Id uint `json:"id"`
CreateDto
}
type DeleteDto struct {
Id uint `json:"id"`
}
type MetaDto struct {
PageNumber int `json:"page_number"`
PageSize int `json:"page_size"`
Count int `json:"count"`
}
type ResponseDto struct {
ecore.Main
Person_Id uint `json:"person_id"`
Type_Code erp.ContactTypeCode `json:"type_code"`
Value string `json:"value"`
}
func (u *PersonContact) ToResponse() ResponseDto {
resp := ResponseDto{
Person_Id: u.Person_Id,
Type_Code: u.Type_Code,
Value: u.Value,
}
resp.Main = u.Main
return resp
}
func ToResponseList(users []PersonContact) []ResponseDto {
resp := make([]ResponseDto, len(users))
for i, u := range users {
resp[i] = u.ToResponse()
}
return resp
}
@@ -0,0 +1,13 @@
package personcontact
import (
ecore "simrs-vx/internal/domain/base-entities/core"
erp "simrs-vx/internal/domain/references/person"
)
type PersonContact struct {
ecore.Main // adjust this according to the needs
Person_Id uint `json:"person_id"`
Type_Code erp.ContactTypeCode `json:"type_code" gorm:"size:15"`
Value string `json:"value" gorm:"size:100"`
}
+100
View File
@@ -0,0 +1,100 @@
package person
import (
ecore "simrs-vx/internal/domain/base-entities/core"
epa "simrs-vx/internal/domain/main-entities/person-address"
epc "simrs-vx/internal/domain/main-entities/person-contact"
erp "simrs-vx/internal/domain/references/person"
"time"
)
type CreateDto struct {
Name string `json:"name"`
BirthDate *time.Time `json:"birthDate,omitempty"`
BirthRegency_Code *string `json:"birthRegency_code"`
Gender_Code *erp.GenderCode `json:"gender_code"`
ResidentIdentityNumber *string `json:"residentIdentityNumber"`
Religion_Code *erp.ReligionCode `json:"religion_code"`
Education_Code *erp.EducationCode `json:"education_code"`
Ocupation_Code *erp.OcupationCode `json:"occupation_code"`
Ocupation_Name *string `json:"occupation_name"`
Ethnic_Code *erp.EthnicCode `json:"ethnic_code"`
}
type ReadListDto struct {
Page int `json:"page"`
PageSize int `json:"page_size"`
NoPagination int `json:"no_pagination"`
}
type ReadDetailDto struct {
Id uint `json:"id"`
Name string `json:"name"`
BirthDate *time.Time `json:"birthDate,omitempty"`
BirthRegency_Code *string `json:"birthRegency_code"`
Gender_Code *erp.GenderCode `json:"gender_code"`
ResidentIdentityNumber *string `json:"residentIdentityNumber"`
Religion_Code *erp.ReligionCode `json:"religion_code"`
Education_Code *erp.EducationCode `json:"education_code"`
Ocupation_Code *erp.OcupationCode `json:"occupation_code"`
Ocupation_Name *string `json:"occupation_name"`
Ethnic_Code *erp.EthnicCode `json:"ethnic_code"`
}
type UpdateDto struct {
Id uint `json:"id"`
CreateDto
}
type DeleteDto struct {
Id uint `json:"id"`
}
type MetaDto struct {
PageNumber int `json:"page_number"`
PageSize int `json:"page_size"`
Count int `json:"count"`
}
type ResponseDto struct {
ecore.Main
Name string `json:"name"`
BirthDate *time.Time `json:"birthDate,omitempty"`
BirthRegency_Code *string `json:"birthRegency_code"`
Gender_Code *erp.GenderCode `json:"gender_code"`
ResidentIdentityNumber *string `json:"residentIdentityNumber"`
Religion_Code *erp.ReligionCode `json:"religion_code"`
Education_Code *erp.EducationCode `json:"education_code"`
Ocupation_Code *erp.OcupationCode `json:"occupation_code"`
Ocupation_Name *string `json:"occupation_name"`
Ethnic_Code *erp.EthnicCode `json:"ethnic_code"`
Addresses *[]epa.PersonAddress `json:"addresses,omitempty"`
Contacts *[]epc.PersonContact `json:"contacts,omitempty"`
}
func (u *Person) ToResponse() ResponseDto {
resp := ResponseDto{
Name: u.Name,
BirthDate: u.BirthDate,
BirthRegency_Code: u.BirthRegency_Code,
Gender_Code: u.Gender_Code,
ResidentIdentityNumber: u.ResidentIdentityNumber,
Religion_Code: u.Religion_Code,
Education_Code: u.Education_Code,
Ocupation_Code: u.Ocupation_Code,
Ocupation_Name: u.Ocupation_Name,
Ethnic_Code: u.Ethnic_Code,
Addresses: u.Addresses,
Contacts: u.Contacts,
}
resp.Main = u.Main
return resp
}
func ToResponseList(users []Person) []ResponseDto {
resp := make([]ResponseDto, len(users))
for i, u := range users {
resp[i] = u.ToResponse()
}
return resp
}
@@ -0,0 +1,26 @@
package person
import (
ecore "simrs-vx/internal/domain/base-entities/core"
epa "simrs-vx/internal/domain/main-entities/person-address"
epc "simrs-vx/internal/domain/main-entities/person-contact"
erp "simrs-vx/internal/domain/references/person"
"time"
)
type Person struct {
ecore.Main // adjust this according to the needs
Name string `json:"name" gorm:"not null;size:150"`
BirthDate *time.Time `json:"birthDate,omitempty"`
BirthRegency_Code *string `json:"birthRegency_code" gorm:"size:4"`
Gender_Code *erp.GenderCode `json:"gender_code" gorm:"size:10"`
ResidentIdentityNumber *string `json:"residentIdentityNumber" gorm:"size:16"`
Religion_Code *erp.ReligionCode `json:"religion_code" gorm:"size:10"`
Education_Code *erp.EducationCode `json:"education_code" gorm:"size:10"`
Ocupation_Code *erp.OcupationCode `json:"occupation_code" gorm:"size:15"`
Ocupation_Name *string `json:"occupation_name" gorm:"size:50"`
Ethnic_Code *erp.EthnicCode `json:"ethnic_code" gorm:"size:15"`
Addresses *[]epa.PersonAddress `json:"addresses" gorm:"foreignKey:Person_Id"`
Contacts *[]epc.PersonContact `json:"contacts" gorm:"foreignKey:Person_Id"`
}
+50 -26
View File
@@ -6,17 +6,19 @@ type (
MaritalStatusCode string MaritalStatusCode string
ReligionCode string ReligionCode string
EducationCode string EducationCode string
ProfessionCode string OcupationCode string
AgeGroupCode string AgeGroupCode string
AgeGroupForMedicineCode string AgeGroupForMedicineCode string
RelativeCode string RelativeCode string
ContactTypeCode string
EthnicCode string
) )
const ( const (
GCMale GenderCode = "male" GCMale GenderCode = "male"
GCFemale GenderCode = "female" GCFemale GenderCode = "female"
GCOther GenderCode = "other" GCNotStated GenderCode = "not-stated"
GCUnknown GenderCode = "unknown" GCUnknown GenderCode = "unknown"
) )
const ( const (
@@ -44,7 +46,6 @@ const (
RCHindu ReligionCode = "hindu" RCHindu ReligionCode = "hindu"
RCBudha ReligionCode = "budha" RCBudha ReligionCode = "budha"
RCKonghucu ReligionCode = "konghucu" RCKonghucu ReligionCode = "konghucu"
RCPenghayat ReligionCode = "penghayat"
) )
const ( const (
@@ -63,12 +64,14 @@ const (
) )
const ( const (
PCTidakBekerja ProfessionCode = "-" OCTidakBekerja OcupationCode = "tidak-bekerja"
PCPns ProfessionCode = "pns" OCPns OcupationCode = "pns"
PCTniPolri ProfessionCode = "tni-polri" OCTniPolisi OcupationCode = "polisi"
PCBumn ProfessionCode = "bumn" OCTni OcupationCode = "tni"
PCWiraswasta ProfessionCode = "wiraswasta" OCGuru OcupationCode = "guru"
PCLainlain ProfessionCode = "lainnya" OCWiraswasta OcupationCode = "wiraswasta"
OCKarySwasta OcupationCode = "kary-swasta"
OCLainlain OcupationCode = "lainnya"
) )
const ( const (
@@ -107,12 +110,19 @@ const (
RCMPamanNenek RelativeCode = "nenek" RCMPamanNenek RelativeCode = "nenek"
) )
const (
CTPhone ContactTypeCode = "phone"
CTMPhone ContactTypeCode = "m-phone"
CTEmail ContactTypeCode = "email"
CTFax ContactTypeCode = "fax"
)
func GetGenderCodes() map[GenderCode]string { func GetGenderCodes() map[GenderCode]string {
return map[GenderCode]string{ return map[GenderCode]string{
GCMale: "Laki-laki", GCMale: "Laki-laki",
GCFemale: "Perempuan", GCFemale: "Perempuan",
GCOther: "Lainnya", GCNotStated: "Tidak disebutkan",
GCUnknown: "Tidak diketahui", GCUnknown: "Tidak diketahui",
} }
} }
@@ -146,7 +156,6 @@ func GetReligionCodes() map[ReligionCode]string {
RCHindu: "Hindu", RCHindu: "Hindu",
RCBudha: "Budha", RCBudha: "Budha",
RCKonghucu: "Konghucu", RCKonghucu: "Konghucu",
RCPenghayat: "Penghayat",
} }
} }
@@ -167,14 +176,16 @@ func GetEducationCodes() map[EducationCode]string {
} }
} }
func GetProfessions() map[ProfessionCode]string { func GetProfessions() map[OcupationCode]string {
return map[ProfessionCode]string{ return map[OcupationCode]string{
PCTidakBekerja: "Tidak Bekerja", OCTidakBekerja: "Tidak Bekerja",
PCPns: "PNS", OCPns: "PNS",
PCTniPolri: "TNI/POLRI", OCTniPolisi: "Polisi",
PCBumn: "BUMN", OCTni: "TNI",
PCWiraswasta: "Pegawai Swasta / Wirausaha", OCGuru: "Guru",
PCLainlain: "Lain-lain", OCWiraswasta: "Wiraswasta",
OCKarySwasta: "Kary Swasta",
OCLainlain: "Lain-lain",
} }
} }
@@ -220,6 +231,15 @@ func GetRelativeCodes() map[RelativeCode]string {
} }
} }
func GetContactTypeCodes() map[ContactTypeCode]string {
return map[ContactTypeCode]string{
CTPhone: "Telepon",
CTMPhone: "Telepon Seluler",
CTEmail: "Email",
CTFax: "Fax",
}
}
func (obj GenderCode) String() string { func (obj GenderCode) String() string {
return GetGenderCodes()[obj] return GetGenderCodes()[obj]
} }
@@ -239,7 +259,7 @@ func (obj EducationCode) String() string {
return GetEducationCodes()[obj] return GetEducationCodes()[obj]
} }
func (obj ProfessionCode) String() string { func (obj OcupationCode) String() string {
return GetProfessions()[obj] return GetProfessions()[obj]
} }
@@ -250,3 +270,7 @@ func (obj AgeGroupCode) String() string {
func (obj RelativeCode) String() string { func (obj RelativeCode) String() string {
return GetRelativeCodes()[obj] return GetRelativeCodes()[obj]
} }
func (obj ContactTypeCode) String() string {
return GetContactTypeCodes()[obj]
}
@@ -5,6 +5,11 @@ import (
/******************** main / transaction ********************/ /******************** main / transaction ********************/
auth "simrs-vx/internal/interface/main-handler/authentication" auth "simrs-vx/internal/interface/main-handler/authentication"
/******************** actor ********************/
person "simrs-vx/internal/interface/main-handler/person"
personaddress "simrs-vx/internal/interface/main-handler/person-address"
personcontact "simrs-vx/internal/interface/main-handler/person-contact"
user "simrs-vx/internal/interface/main-handler/user" user "simrs-vx/internal/interface/main-handler/user"
/******************** external ********************/ /******************** external ********************/
@@ -54,6 +59,7 @@ func SetRoutes() http.Handler {
// r.HandleFunc("POST /v1/authentication/logout", auth.Logout) // r.HandleFunc("POST /v1/authentication/logout", auth.Logout)
hk.Route("POST /v1/authentication/logout", r, auth.GuardMW, auth.Logout) hk.Route("POST /v1/authentication/logout", r, auth.GuardMW, auth.Logout)
/******************** actor ********************/
hk.GroupRoutes("/v1/user", r, hk.MapHandlerFunc{ hk.GroupRoutes("/v1/user", r, hk.MapHandlerFunc{
"GET /": user.O.GetList, "GET /": user.O.GetList,
"GET /{id}": user.O.GetDetail, "GET /{id}": user.O.GetDetail,
@@ -63,6 +69,9 @@ func SetRoutes() http.Handler {
"PATCH /{id}/block": user.O.Block, "PATCH /{id}/block": user.O.Block,
"PATCH /{id}/active": user.O.Active, "PATCH /{id}/active": user.O.Active,
}) })
hc.RegCrud(r, "/v1/person", person.O)
hc.RegCrud(r, "/v1/person-address", personaddress.O)
hc.RegCrud(r, "/v1/person-contact", personcontact.O)
/******************** sources ********************/ /******************** sources ********************/
hc.RegCrud(r, "/v1/division", division.O) hc.RegCrud(r, "/v1/division", division.O)
@@ -0,0 +1,71 @@
package personaddress
import (
"net/http"
rw "github.com/karincake/risoles"
sf "github.com/karincake/semprit"
// ua "github.com/karincake/tumpeng/auth/svc"
e "simrs-vx/internal/domain/main-entities/person-address"
u "simrs-vx/internal/use-case/main-use-case/person-address"
)
type myBase struct{}
var O myBase
func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
dto := e.CreateDto{}
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
res, err := u.Create(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
dto := e.ReadListDto{}
sf.UrlQueryParam(&dto, *r.URL)
res, err := u.ReadList(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
id := rw.ValidateInt(w, "id", r.PathValue("id"))
if id <= 0 {
return
}
dto := e.ReadDetailDto{}
dto.Id = uint(id)
res, err := u.ReadDetail(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) Update(w http.ResponseWriter, r *http.Request) {
id := rw.ValidateInt(w, "id", r.PathValue("id"))
if id <= 0 {
return
}
dto := e.UpdateDto{}
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
dto.Id = uint(id)
res, err := u.Update(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
id := rw.ValidateInt(w, "id", r.PathValue("id"))
if id <= 0 {
return
}
dto := e.DeleteDto{}
dto.Id = uint(id)
res, err := u.Delete(dto)
rw.DataResponse(w, res, err)
}
@@ -0,0 +1,71 @@
package personcontact
import (
"net/http"
rw "github.com/karincake/risoles"
sf "github.com/karincake/semprit"
// ua "github.com/karincake/tumpeng/auth/svc"
e "simrs-vx/internal/domain/main-entities/person-contact"
u "simrs-vx/internal/use-case/main-use-case/person-contact"
)
type myBase struct{}
var O myBase
func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
dto := e.CreateDto{}
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
res, err := u.Create(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
dto := e.ReadListDto{}
sf.UrlQueryParam(&dto, *r.URL)
res, err := u.ReadList(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
id := rw.ValidateInt(w, "id", r.PathValue("id"))
if id <= 0 {
return
}
dto := e.ReadDetailDto{}
dto.Id = uint(id)
res, err := u.ReadDetail(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) Update(w http.ResponseWriter, r *http.Request) {
id := rw.ValidateInt(w, "id", r.PathValue("id"))
if id <= 0 {
return
}
dto := e.UpdateDto{}
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
dto.Id = uint(id)
res, err := u.Update(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
id := rw.ValidateInt(w, "id", r.PathValue("id"))
if id <= 0 {
return
}
dto := e.DeleteDto{}
dto.Id = uint(id)
res, err := u.Delete(dto)
rw.DataResponse(w, res, err)
}
@@ -0,0 +1,71 @@
package person
import (
"net/http"
rw "github.com/karincake/risoles"
sf "github.com/karincake/semprit"
// ua "github.com/karincake/tumpeng/auth/svc"
e "simrs-vx/internal/domain/main-entities/person"
u "simrs-vx/internal/use-case/main-use-case/person"
)
type myBase struct{}
var O myBase
func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
dto := e.CreateDto{}
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
res, err := u.Create(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
dto := e.ReadListDto{}
sf.UrlQueryParam(&dto, *r.URL)
res, err := u.ReadList(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
id := rw.ValidateInt(w, "id", r.PathValue("id"))
if id <= 0 {
return
}
dto := e.ReadDetailDto{}
dto.Id = uint(id)
res, err := u.ReadDetail(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) Update(w http.ResponseWriter, r *http.Request) {
id := rw.ValidateInt(w, "id", r.PathValue("id"))
if id <= 0 {
return
}
dto := e.UpdateDto{}
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
dto.Id = uint(id)
res, err := u.Update(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
id := rw.ValidateInt(w, "id", r.PathValue("id"))
if id <= 0 {
return
}
dto := e.DeleteDto{}
dto.Id = uint(id)
res, err := u.Delete(dto)
rw.DataResponse(w, res, err)
}
@@ -9,6 +9,9 @@ import (
division "simrs-vx/internal/domain/main-entities/division" division "simrs-vx/internal/domain/main-entities/division"
divisionposition "simrs-vx/internal/domain/main-entities/division-position" divisionposition "simrs-vx/internal/domain/main-entities/division-position"
installation "simrs-vx/internal/domain/main-entities/installation" installation "simrs-vx/internal/domain/main-entities/installation"
person "simrs-vx/internal/domain/main-entities/person"
personaddress "simrs-vx/internal/domain/main-entities/person-address"
personcontact "simrs-vx/internal/domain/main-entities/person-contact"
province "simrs-vx/internal/domain/main-entities/province" province "simrs-vx/internal/domain/main-entities/province"
regency "simrs-vx/internal/domain/main-entities/regency" regency "simrs-vx/internal/domain/main-entities/regency"
unit "simrs-vx/internal/domain/main-entities/unit" unit "simrs-vx/internal/domain/main-entities/unit"
@@ -57,6 +60,9 @@ func GetEntities() []any {
&district.District{}, &district.District{},
&regency.Regency{}, &regency.Regency{},
&province.Province{}, &province.Province{},
&person.Person{},
&personaddress.PersonAddress{},
&personcontact.PersonContact{},
} }
} }
@@ -63,8 +63,8 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Di
} }
event.Status = "failed" event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{ event.ErrInfo = pl.ErrorInfo{
Code: "data-create-fail", Code: "data-get-fail",
Detail: "Database insert failed", Detail: "Database get failed",
Raw: err, Raw: err,
} }
return nil, nil, pl.SetLogError(event, input) return nil, nil, pl.SetLogError(event, input)
@@ -65,8 +65,8 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Di
} }
event.Status = "failed" event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{ event.ErrInfo = pl.ErrorInfo{
Code: "data-create-fail", Code: "data-get-fail",
Detail: "Database insert failed", Detail: "Database get failed",
Raw: err, Raw: err,
} }
return nil, nil, pl.SetLogError(event, input) return nil, nil, pl.SetLogError(event, input)
@@ -53,7 +53,6 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Di
tx = tx. tx = tx.
Model(&e.Division{}). Model(&e.Division{}).
Preload("Installation").
Scopes(gh.Filter(input)). Scopes(gh.Filter(input)).
Count(&count). Count(&count).
Scopes(gh.Paginate(input, &pagination)). Scopes(gh.Paginate(input, &pagination)).
@@ -65,8 +64,8 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Di
} }
event.Status = "failed" event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{ event.ErrInfo = pl.ErrorInfo{
Code: "data-create-fail", Code: "data-get-fail",
Detail: "Database insert failed", Detail: "Database get failed",
Raw: err, Raw: err,
} }
return nil, nil, pl.SetLogError(event, input) return nil, nil, pl.SetLogError(event, input)
@@ -53,7 +53,6 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.In
tx = tx. tx = tx.
Model(&e.Installation{}). Model(&e.Installation{}).
Preload("Installation").
Scopes(gh.Filter(input)). Scopes(gh.Filter(input)).
Count(&count). Count(&count).
Scopes(gh.Paginate(input, &pagination)). Scopes(gh.Paginate(input, &pagination)).
@@ -65,8 +64,8 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.In
} }
event.Status = "failed" event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{ event.ErrInfo = pl.ErrorInfo{
Code: "data-create-fail", Code: "data-get-fail",
Detail: "Database insert failed", Detail: "Database get failed",
Raw: err, Raw: err,
} }
return nil, nil, pl.SetLogError(event, input) return nil, nil, pl.SetLogError(event, input)
@@ -0,0 +1,275 @@
package personaddress
import (
e "simrs-vx/internal/domain/main-entities/person-address"
"strconv"
dg "github.com/karincake/apem/db-gorm-pg"
d "github.com/karincake/dodol"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
"gorm.io/gorm"
)
const source = "person-address"
func Create(input e.CreateDto) (*d.Data, error) {
data := e.PersonAddress{}
event := pl.Event{
Feature: "Create",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "create")
err := dg.I.Transaction(func(tx *gorm.DB) error {
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
return err
}
if resData, err := CreateData(input, &event, tx); err != nil {
return err
} else {
data = *resData
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
return err
}
pl.SetLogInfo(&event, nil, "complete")
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.II{
"source": source,
"structure": "single-data",
"status": "created",
},
Data: data.ToResponse(),
}, nil
}
func ReadList(input e.ReadListDto) (*d.Data, error) {
var data *e.PersonAddress
var dataList []e.PersonAddress
var metaList *e.MetaDto
var err error
event := pl.Event{
Feature: "ReadList",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "readList")
err = dg.I.Transaction(func(tx *gorm.DB) error {
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, data); err != nil {
return err
}
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, data); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.IS{
"source": source,
"structure": "list-data",
"status": "fetched",
"page_number": strconv.Itoa(metaList.PageNumber),
"page_size": strconv.Itoa(metaList.PageSize),
"record_totalCount": strconv.Itoa(metaList.Count),
},
Data: e.ToResponseList(dataList),
}, nil
}
func ReadDetail(input e.ReadDetailDto) (*d.Data, error) {
var data *e.PersonAddress
var err error
event := pl.Event{
Feature: "ReadDetail",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "readDetail")
err = dg.I.Transaction(func(tx *gorm.DB) error {
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunReadDetailMiddleware(readDetailPreMw, &input, data); err != nil {
return err
}
if data, err = ReadDetailData(input, &event, tx); err != nil {
return err
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunReadDetailMiddleware(readDetailPostMw, &input, data); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.IS{
"source": source,
"structure": "single-data",
"status": "fetched",
},
Data: data.ToResponse(),
}, nil
}
func Update(input e.UpdateDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: input.Id}
var data *e.PersonAddress
var err error
event := pl.Event{
Feature: "Update",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "update")
err = dg.I.Transaction(func(tx *gorm.DB) error {
pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail")
if data, err = ReadDetailData(rdDto, &event, tx); err != nil {
return err
}
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunUpdateMiddleware(readDetailPreMw, &rdDto, data); err != nil {
return err
}
if err := UpdateData(input, data, &event, tx); err != nil {
return err
}
pl.SetLogInfo(&event, nil, "complete")
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunUpdateMiddleware(readDetailPostMw, &rdDto, data); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.IS{
"source": source,
"structure": "single-data",
"status": "updated",
},
Data: data.ToResponse(),
}, nil
}
func Delete(input e.DeleteDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: input.Id}
var data *e.PersonAddress
var err error
event := pl.Event{
Feature: "Delete",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "delete")
err = dg.I.Transaction(func(tx *gorm.DB) error {
pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail")
if data, err = ReadDetailData(rdDto, &event, tx); err != nil {
return err
}
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunDeleteMiddleware(readDetailPreMw, &rdDto, data); err != nil {
return err
}
if err := DeleteData(data, &event, tx); err != nil {
return err
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunDeleteMiddleware(readDetailPostMw, &rdDto, data); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.IS{
"source": source,
"structure": "single-data",
"status": "deleted",
},
Data: data.ToResponse(),
}, nil
}
@@ -0,0 +1,25 @@
/*
DESCRIPTION:
Any functions that are used internally by the use-case
*/
package personaddress
import (
e "simrs-vx/internal/domain/main-entities/person-address"
)
func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.PersonAddress) {
var inputSrc *e.CreateDto
if inputT, ok := any(input).(*e.CreateDto); ok {
inputSrc = inputT
} else {
inputTemp := any(input).(*e.UpdateDto)
inputSrc = &inputTemp.CreateDto
}
data.Person_Id = inputSrc.Person_Id
data.Address = inputSrc.Address
data.Rt = inputSrc.Rt
data.Rw = inputSrc.Rw
data.Village_Code = inputSrc.Village_Code
}
@@ -0,0 +1,149 @@
package personaddress
import (
e "simrs-vx/internal/domain/main-entities/person-address"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
dg "github.com/karincake/apem/db-gorm-pg"
gh "github.com/karincake/getuk"
"gorm.io/gorm"
)
func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.PersonAddress, error) {
pl.SetLogInfo(event, nil, "started", "DBCreate")
data := e.PersonAddress{}
setData(&input, &data)
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if err := tx.Create(&data).Error; err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-create-fail",
Detail: "Database insert failed",
Raw: err,
}
return nil, pl.SetLogError(event, input)
}
pl.SetLogInfo(event, nil, "complete")
return &data, nil
}
func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.PersonAddress, *e.MetaDto, error) {
pl.SetLogInfo(event, input, "started", "DBReadList")
data := []e.PersonAddress{}
pagination := gh.Pagination{}
count := int64(0)
meta := e.MetaDto{}
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
tx = tx.
Model(&e.PersonAddress{}).
Scopes(gh.Filter(input)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-get-fail",
Detail: "Database get failed",
Raw: err,
}
return nil, nil, pl.SetLogError(event, input)
}
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
pl.SetLogInfo(event, nil, "complete")
return data, &meta, nil
}
func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.PersonAddress, error) {
pl.SetLogInfo(event, input, "started", "DBReadDetail")
data := e.PersonAddress{}
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if err := tx.First(&data, input.Id).Error; err != nil {
if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil {
return nil, processedErr
}
}
pl.SetLogInfo(event, nil, "complete")
return &data, nil
}
func UpdateData(input e.UpdateDto, data *e.PersonAddress, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, data, "started", "DBUpdate")
setData(&input, data)
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if err := tx.Save(&data).Error; err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-update-fail",
Detail: "Database update failed",
Raw: err,
}
return pl.SetLogError(event, input)
}
pl.SetLogInfo(event, nil, "complete")
return nil
}
func DeleteData(data *e.PersonAddress, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, data, "started", "DBDelete")
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if err := tx.Delete(&data).Error; err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-delete-fail",
Detail: "Database delete failed",
Raw: err,
}
return pl.SetLogError(event, data)
}
pl.SetLogInfo(event, nil, "complete")
return nil
}
@@ -0,0 +1,103 @@
package personaddress
import (
e "simrs-vx/internal/domain/main-entities/person-address"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
"gorm.io/gorm"
)
type middlewareRunner struct {
Event *pl.Event
Tx *gorm.DB
MwType pu.MWType
}
// NewMiddlewareExecutor creates a new middleware executor
func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner {
return &middlewareRunner{
Event: event,
Tx: tx,
}
}
// ExecuteCreateMiddleware executes create middleware
func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.PersonAddress) error {
for _, middleware := range middlewares {
logData := pu.GetLogData(input, data)
pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
if err := middleware.Func(input, data, me.Tx); err != nil {
return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
}
pl.SetLogInfo(me.Event, nil, "complete")
}
return nil
}
func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.PersonAddress) error {
for _, middleware := range middlewares {
logData := pu.GetLogData(input, data)
pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
if err := middleware.Func(input, data, me.Tx); err != nil {
return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
}
pl.SetLogInfo(me.Event, nil, "complete")
}
return nil
}
func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.PersonAddress) error {
for _, middleware := range middlewares {
logData := pu.GetLogData(input, data)
pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
if err := middleware.Func(input, data, me.Tx); err != nil {
return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
}
pl.SetLogInfo(me.Event, nil, "complete")
}
return nil
}
func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.PersonAddress) error {
for _, middleware := range middlewares {
logData := pu.GetLogData(input, data)
pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
if err := middleware.Func(input, data, me.Tx); err != nil {
return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
}
pl.SetLogInfo(me.Event, nil, "complete")
}
return nil
}
func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.PersonAddress) error {
for _, middleware := range middlewares {
logData := pu.GetLogData(input, data)
pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
if err := middleware.Func(input, data, me.Tx); err != nil {
return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
}
pl.SetLogInfo(me.Event, nil, "complete")
}
return nil
}
func (me *middlewareRunner) setMwType(mwType pu.MWType) {
me.MwType = mwType
}
@@ -0,0 +1,9 @@
package personaddress
// example of middleware
// func init() {
// createPreMw = append(createPreMw,
// CreateMw{Name: "modif-input", Func: pm.ModifInput},
// CreateMw{Name: "check-data", Func: pm.CheckData},
// )
// }
@@ -0,0 +1,44 @@
/*
DESCRIPTION:
A sample, part of the package that contains type, constants, and/or variables.
In this sample it also provides type and variable regarding the needs of the
middleware to separate from main use-case which has the basic CRUD
functionality. The purpose of this is to make the code more maintainable.
*/
package personaddress
import (
"gorm.io/gorm"
e "simrs-vx/internal/domain/main-entities/person-address"
)
type createMw struct {
Name string
Func func(input *e.CreateDto, data *e.PersonAddress, tx *gorm.DB) error
}
type readListMw struct {
Name string
Func func(input *e.ReadListDto, data *e.PersonAddress, tx *gorm.DB) error
}
type readDetailMw struct {
Name string
Func func(input *e.ReadDetailDto, data *e.PersonAddress, tx *gorm.DB) error
}
type UpdateMw = readDetailMw
type DeleteMw = readDetailMw
var createPreMw []createMw // preprocess middleware
var createPostMw []createMw // postprocess middleware
var readListPreMw []readListMw // ..
var readListPostMw []readListMw // ..
var readDetailPreMw []readDetailMw
var readDetailPostMw []readDetailMw
var updatePreMw []readDetailMw
var updatePostMw []readDetailMw
var deletePreMw []readDetailMw
var deletePostMw []readDetailMw
@@ -0,0 +1,275 @@
package personcontact
import (
e "simrs-vx/internal/domain/main-entities/person-contact"
"strconv"
dg "github.com/karincake/apem/db-gorm-pg"
d "github.com/karincake/dodol"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
"gorm.io/gorm"
)
const source = "person-contact"
func Create(input e.CreateDto) (*d.Data, error) {
data := e.PersonContact{}
event := pl.Event{
Feature: "Create",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "create")
err := dg.I.Transaction(func(tx *gorm.DB) error {
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
return err
}
if resData, err := CreateData(input, &event, tx); err != nil {
return err
} else {
data = *resData
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
return err
}
pl.SetLogInfo(&event, nil, "complete")
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.II{
"source": source,
"structure": "single-data",
"status": "created",
},
Data: data.ToResponse(),
}, nil
}
func ReadList(input e.ReadListDto) (*d.Data, error) {
var data *e.PersonContact
var dataList []e.PersonContact
var metaList *e.MetaDto
var err error
event := pl.Event{
Feature: "ReadList",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "readList")
err = dg.I.Transaction(func(tx *gorm.DB) error {
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, data); err != nil {
return err
}
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, data); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.IS{
"source": source,
"structure": "list-data",
"status": "fetched",
"page_number": strconv.Itoa(metaList.PageNumber),
"page_size": strconv.Itoa(metaList.PageSize),
"record_totalCount": strconv.Itoa(metaList.Count),
},
Data: e.ToResponseList(dataList),
}, nil
}
func ReadDetail(input e.ReadDetailDto) (*d.Data, error) {
var data *e.PersonContact
var err error
event := pl.Event{
Feature: "ReadDetail",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "readDetail")
err = dg.I.Transaction(func(tx *gorm.DB) error {
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunReadDetailMiddleware(readDetailPreMw, &input, data); err != nil {
return err
}
if data, err = ReadDetailData(input, &event, tx); err != nil {
return err
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunReadDetailMiddleware(readDetailPostMw, &input, data); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.IS{
"source": source,
"structure": "single-data",
"status": "fetched",
},
Data: data.ToResponse(),
}, nil
}
func Update(input e.UpdateDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: input.Id}
var data *e.PersonContact
var err error
event := pl.Event{
Feature: "Update",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "update")
err = dg.I.Transaction(func(tx *gorm.DB) error {
pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail")
if data, err = ReadDetailData(rdDto, &event, tx); err != nil {
return err
}
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunUpdateMiddleware(readDetailPreMw, &rdDto, data); err != nil {
return err
}
if err := UpdateData(input, data, &event, tx); err != nil {
return err
}
pl.SetLogInfo(&event, nil, "complete")
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunUpdateMiddleware(readDetailPostMw, &rdDto, data); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.IS{
"source": source,
"structure": "single-data",
"status": "updated",
},
Data: data.ToResponse(),
}, nil
}
func Delete(input e.DeleteDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: input.Id}
var data *e.PersonContact
var err error
event := pl.Event{
Feature: "Delete",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "delete")
err = dg.I.Transaction(func(tx *gorm.DB) error {
pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail")
if data, err = ReadDetailData(rdDto, &event, tx); err != nil {
return err
}
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunDeleteMiddleware(readDetailPreMw, &rdDto, data); err != nil {
return err
}
if err := DeleteData(data, &event, tx); err != nil {
return err
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunDeleteMiddleware(readDetailPostMw, &rdDto, data); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.IS{
"source": source,
"structure": "single-data",
"status": "deleted",
},
Data: data.ToResponse(),
}, nil
}
@@ -0,0 +1,23 @@
/*
DESCRIPTION:
Any functions that are used internally by the use-case
*/
package personcontact
import (
e "simrs-vx/internal/domain/main-entities/person-contact"
)
func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.PersonContact) {
var inputSrc *e.CreateDto
if inputT, ok := any(input).(*e.CreateDto); ok {
inputSrc = inputT
} else {
inputTemp := any(input).(*e.UpdateDto)
inputSrc = &inputTemp.CreateDto
}
data.Person_Id = inputSrc.Person_Id
data.Type_Code = inputSrc.Type_Code
data.Value = inputSrc.Value
}
@@ -0,0 +1,149 @@
package personcontact
import (
e "simrs-vx/internal/domain/main-entities/person-contact"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
dg "github.com/karincake/apem/db-gorm-pg"
gh "github.com/karincake/getuk"
"gorm.io/gorm"
)
func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.PersonContact, error) {
pl.SetLogInfo(event, nil, "started", "DBCreate")
data := e.PersonContact{}
setData(&input, &data)
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if err := tx.Create(&data).Error; err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-create-fail",
Detail: "Database insert failed",
Raw: err,
}
return nil, pl.SetLogError(event, input)
}
pl.SetLogInfo(event, nil, "complete")
return &data, nil
}
func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.PersonContact, *e.MetaDto, error) {
pl.SetLogInfo(event, input, "started", "DBReadList")
data := []e.PersonContact{}
pagination := gh.Pagination{}
count := int64(0)
meta := e.MetaDto{}
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
tx = tx.
Model(&e.PersonContact{}).
Scopes(gh.Filter(input)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-get-fail",
Detail: "Database get failed",
Raw: err,
}
return nil, nil, pl.SetLogError(event, input)
}
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
pl.SetLogInfo(event, nil, "complete")
return data, &meta, nil
}
func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.PersonContact, error) {
pl.SetLogInfo(event, input, "started", "DBReadDetail")
data := e.PersonContact{}
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if err := tx.First(&data, input.Id).Error; err != nil {
if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil {
return nil, processedErr
}
}
pl.SetLogInfo(event, nil, "complete")
return &data, nil
}
func UpdateData(input e.UpdateDto, data *e.PersonContact, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, data, "started", "DBUpdate")
setData(&input, data)
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if err := tx.Save(&data).Error; err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-update-fail",
Detail: "Database update failed",
Raw: err,
}
return pl.SetLogError(event, input)
}
pl.SetLogInfo(event, nil, "complete")
return nil
}
func DeleteData(data *e.PersonContact, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, data, "started", "DBDelete")
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if err := tx.Delete(&data).Error; err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-delete-fail",
Detail: "Database delete failed",
Raw: err,
}
return pl.SetLogError(event, data)
}
pl.SetLogInfo(event, nil, "complete")
return nil
}
@@ -0,0 +1,103 @@
package personcontact
import (
e "simrs-vx/internal/domain/main-entities/person-contact"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
"gorm.io/gorm"
)
type middlewareRunner struct {
Event *pl.Event
Tx *gorm.DB
MwType pu.MWType
}
// NewMiddlewareExecutor creates a new middleware executor
func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner {
return &middlewareRunner{
Event: event,
Tx: tx,
}
}
// ExecuteCreateMiddleware executes create middleware
func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.PersonContact) error {
for _, middleware := range middlewares {
logData := pu.GetLogData(input, data)
pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
if err := middleware.Func(input, data, me.Tx); err != nil {
return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
}
pl.SetLogInfo(me.Event, nil, "complete")
}
return nil
}
func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.PersonContact) error {
for _, middleware := range middlewares {
logData := pu.GetLogData(input, data)
pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
if err := middleware.Func(input, data, me.Tx); err != nil {
return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
}
pl.SetLogInfo(me.Event, nil, "complete")
}
return nil
}
func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.PersonContact) error {
for _, middleware := range middlewares {
logData := pu.GetLogData(input, data)
pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
if err := middleware.Func(input, data, me.Tx); err != nil {
return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
}
pl.SetLogInfo(me.Event, nil, "complete")
}
return nil
}
func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.PersonContact) error {
for _, middleware := range middlewares {
logData := pu.GetLogData(input, data)
pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
if err := middleware.Func(input, data, me.Tx); err != nil {
return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
}
pl.SetLogInfo(me.Event, nil, "complete")
}
return nil
}
func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.PersonContact) error {
for _, middleware := range middlewares {
logData := pu.GetLogData(input, data)
pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
if err := middleware.Func(input, data, me.Tx); err != nil {
return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
}
pl.SetLogInfo(me.Event, nil, "complete")
}
return nil
}
func (me *middlewareRunner) setMwType(mwType pu.MWType) {
me.MwType = mwType
}
@@ -0,0 +1,9 @@
package personcontact
// example of middleware
// func init() {
// createPreMw = append(createPreMw,
// CreateMw{Name: "modif-input", Func: pm.ModifInput},
// CreateMw{Name: "check-data", Func: pm.CheckData},
// )
// }
@@ -0,0 +1,44 @@
/*
DESCRIPTION:
A sample, part of the package that contains type, constants, and/or variables.
In this sample it also provides type and variable regarding the needs of the
middleware to separate from main use-case which has the basic CRUD
functionality. The purpose of this is to make the code more maintainable.
*/
package personcontact
import (
"gorm.io/gorm"
e "simrs-vx/internal/domain/main-entities/person-contact"
)
type createMw struct {
Name string
Func func(input *e.CreateDto, data *e.PersonContact, tx *gorm.DB) error
}
type readListMw struct {
Name string
Func func(input *e.ReadListDto, data *e.PersonContact, tx *gorm.DB) error
}
type readDetailMw struct {
Name string
Func func(input *e.ReadDetailDto, data *e.PersonContact, tx *gorm.DB) error
}
type UpdateMw = readDetailMw
type DeleteMw = readDetailMw
var createPreMw []createMw // preprocess middleware
var createPostMw []createMw // postprocess middleware
var readListPreMw []readListMw // ..
var readListPostMw []readListMw // ..
var readDetailPreMw []readDetailMw
var readDetailPostMw []readDetailMw
var updatePreMw []readDetailMw
var updatePostMw []readDetailMw
var deletePreMw []readDetailMw
var deletePostMw []readDetailMw
@@ -0,0 +1,275 @@
package person
import (
e "simrs-vx/internal/domain/main-entities/person"
"strconv"
dg "github.com/karincake/apem/db-gorm-pg"
d "github.com/karincake/dodol"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
"gorm.io/gorm"
)
const source = "person"
func Create(input e.CreateDto) (*d.Data, error) {
data := e.Person{}
event := pl.Event{
Feature: "Create",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "create")
err := dg.I.Transaction(func(tx *gorm.DB) error {
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
return err
}
if resData, err := CreateData(input, &event, tx); err != nil {
return err
} else {
data = *resData
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
return err
}
pl.SetLogInfo(&event, nil, "complete")
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.II{
"source": source,
"structure": "single-data",
"status": "created",
},
Data: data.ToResponse(),
}, nil
}
func ReadList(input e.ReadListDto) (*d.Data, error) {
var data *e.Person
var dataList []e.Person
var metaList *e.MetaDto
var err error
event := pl.Event{
Feature: "ReadList",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "readList")
err = dg.I.Transaction(func(tx *gorm.DB) error {
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, data); err != nil {
return err
}
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, data); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.IS{
"source": source,
"structure": "list-data",
"status": "fetched",
"page_number": strconv.Itoa(metaList.PageNumber),
"page_size": strconv.Itoa(metaList.PageSize),
"record_totalCount": strconv.Itoa(metaList.Count),
},
Data: e.ToResponseList(dataList),
}, nil
}
func ReadDetail(input e.ReadDetailDto) (*d.Data, error) {
var data *e.Person
var err error
event := pl.Event{
Feature: "ReadDetail",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "readDetail")
err = dg.I.Transaction(func(tx *gorm.DB) error {
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunReadDetailMiddleware(readDetailPreMw, &input, data); err != nil {
return err
}
if data, err = ReadDetailData(input, &event, tx); err != nil {
return err
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunReadDetailMiddleware(readDetailPostMw, &input, data); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.IS{
"source": source,
"structure": "single-data",
"status": "fetched",
},
Data: data.ToResponse(),
}, nil
}
func Update(input e.UpdateDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: input.Id}
var data *e.Person
var err error
event := pl.Event{
Feature: "Update",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "update")
err = dg.I.Transaction(func(tx *gorm.DB) error {
pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail")
if data, err = ReadDetailData(rdDto, &event, tx); err != nil {
return err
}
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunUpdateMiddleware(readDetailPreMw, &rdDto, data); err != nil {
return err
}
if err := UpdateData(input, data, &event, tx); err != nil {
return err
}
pl.SetLogInfo(&event, nil, "complete")
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunUpdateMiddleware(readDetailPostMw, &rdDto, data); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.IS{
"source": source,
"structure": "single-data",
"status": "updated",
},
Data: data.ToResponse(),
}, nil
}
func Delete(input e.DeleteDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: input.Id}
var data *e.Person
var err error
event := pl.Event{
Feature: "Delete",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "delete")
err = dg.I.Transaction(func(tx *gorm.DB) error {
pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail")
if data, err = ReadDetailData(rdDto, &event, tx); err != nil {
return err
}
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunDeleteMiddleware(readDetailPreMw, &rdDto, data); err != nil {
return err
}
if err := DeleteData(data, &event, tx); err != nil {
return err
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunDeleteMiddleware(readDetailPostMw, &rdDto, data); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.IS{
"source": source,
"structure": "single-data",
"status": "deleted",
},
Data: data.ToResponse(),
}, nil
}
@@ -0,0 +1,30 @@
/*
DESCRIPTION:
Any functions that are used internally by the use-case
*/
package person
import (
e "simrs-vx/internal/domain/main-entities/person"
)
func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Person) {
var inputSrc *e.CreateDto
if inputT, ok := any(input).(*e.CreateDto); ok {
inputSrc = inputT
} else {
inputTemp := any(input).(*e.UpdateDto)
inputSrc = &inputTemp.CreateDto
}
data.Name = inputSrc.Name
data.BirthDate = inputSrc.BirthDate
data.BirthRegency_Code = inputSrc.BirthRegency_Code
data.Gender_Code = inputSrc.Gender_Code
data.ResidentIdentityNumber = inputSrc.ResidentIdentityNumber
data.Religion_Code = inputSrc.Religion_Code
data.Education_Code = inputSrc.Education_Code
data.Ocupation_Code = inputSrc.Ocupation_Code
data.Ocupation_Name = inputSrc.Ocupation_Name
data.Ethnic_Code = inputSrc.Ethnic_Code
}
@@ -0,0 +1,151 @@
package person
import (
e "simrs-vx/internal/domain/main-entities/person"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
dg "github.com/karincake/apem/db-gorm-pg"
gh "github.com/karincake/getuk"
"gorm.io/gorm"
)
func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Person, error) {
pl.SetLogInfo(event, nil, "started", "DBCreate")
data := e.Person{}
setData(&input, &data)
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if err := tx.Create(&data).Error; err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-create-fail",
Detail: "Database insert failed",
Raw: err,
}
return nil, pl.SetLogError(event, input)
}
pl.SetLogInfo(event, nil, "complete")
return &data, nil
}
func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Person, *e.MetaDto, error) {
pl.SetLogInfo(event, input, "started", "DBReadList")
data := []e.Person{}
pagination := gh.Pagination{}
count := int64(0)
meta := e.MetaDto{}
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
tx = tx.
Model(&e.Person{}).
Scopes(gh.Filter(input)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-get-fail",
Detail: "Database get failed",
Raw: err,
}
return nil, nil, pl.SetLogError(event, input)
}
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
pl.SetLogInfo(event, nil, "complete")
return data, &meta, nil
}
func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Person, error) {
pl.SetLogInfo(event, input, "started", "DBReadDetail")
data := e.Person{}
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
tx = tx.Preload("Contacts").
Preload("Addresses")
if err := tx.First(&data, input.Id).Error; err != nil {
if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil {
return nil, processedErr
}
}
pl.SetLogInfo(event, nil, "complete")
return &data, nil
}
func UpdateData(input e.UpdateDto, data *e.Person, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, data, "started", "DBUpdate")
setData(&input, data)
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if err := tx.Save(&data).Error; err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-update-fail",
Detail: "Database update failed",
Raw: err,
}
return pl.SetLogError(event, input)
}
pl.SetLogInfo(event, nil, "complete")
return nil
}
func DeleteData(data *e.Person, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, data, "started", "DBDelete")
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if err := tx.Delete(&data).Error; err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-delete-fail",
Detail: "Database delete failed",
Raw: err,
}
return pl.SetLogError(event, data)
}
pl.SetLogInfo(event, nil, "complete")
return nil
}
@@ -0,0 +1,103 @@
package person
import (
e "simrs-vx/internal/domain/main-entities/person"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
"gorm.io/gorm"
)
type middlewareRunner struct {
Event *pl.Event
Tx *gorm.DB
MwType pu.MWType
}
// NewMiddlewareExecutor creates a new middleware executor
func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner {
return &middlewareRunner{
Event: event,
Tx: tx,
}
}
// ExecuteCreateMiddleware executes create middleware
func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.Person) error {
for _, middleware := range middlewares {
logData := pu.GetLogData(input, data)
pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
if err := middleware.Func(input, data, me.Tx); err != nil {
return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
}
pl.SetLogInfo(me.Event, nil, "complete")
}
return nil
}
func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.Person) error {
for _, middleware := range middlewares {
logData := pu.GetLogData(input, data)
pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
if err := middleware.Func(input, data, me.Tx); err != nil {
return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
}
pl.SetLogInfo(me.Event, nil, "complete")
}
return nil
}
func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Person) error {
for _, middleware := range middlewares {
logData := pu.GetLogData(input, data)
pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
if err := middleware.Func(input, data, me.Tx); err != nil {
return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
}
pl.SetLogInfo(me.Event, nil, "complete")
}
return nil
}
func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Person) error {
for _, middleware := range middlewares {
logData := pu.GetLogData(input, data)
pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
if err := middleware.Func(input, data, me.Tx); err != nil {
return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
}
pl.SetLogInfo(me.Event, nil, "complete")
}
return nil
}
func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Person) error {
for _, middleware := range middlewares {
logData := pu.GetLogData(input, data)
pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
if err := middleware.Func(input, data, me.Tx); err != nil {
return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
}
pl.SetLogInfo(me.Event, nil, "complete")
}
return nil
}
func (me *middlewareRunner) setMwType(mwType pu.MWType) {
me.MwType = mwType
}
@@ -0,0 +1,9 @@
package person
// example of middleware
// func init() {
// createPreMw = append(createPreMw,
// CreateMw{Name: "modif-input", Func: pm.ModifInput},
// CreateMw{Name: "check-data", Func: pm.CheckData},
// )
// }
@@ -0,0 +1,44 @@
/*
DESCRIPTION:
A sample, part of the package that contains type, constants, and/or variables.
In this sample it also provides type and variable regarding the needs of the
middleware to separate from main use-case which has the basic CRUD
functionality. The purpose of this is to make the code more maintainable.
*/
package person
import (
"gorm.io/gorm"
e "simrs-vx/internal/domain/main-entities/person"
)
type createMw struct {
Name string
Func func(input *e.CreateDto, data *e.Person, tx *gorm.DB) error
}
type readListMw struct {
Name string
Func func(input *e.ReadListDto, data *e.Person, tx *gorm.DB) error
}
type readDetailMw struct {
Name string
Func func(input *e.ReadDetailDto, data *e.Person, tx *gorm.DB) error
}
type UpdateMw = readDetailMw
type DeleteMw = readDetailMw
var createPreMw []createMw // preprocess middleware
var createPostMw []createMw // postprocess middleware
var readListPreMw []readListMw // ..
var readListPostMw []readListMw // ..
var readDetailPreMw []readDetailMw
var readDetailPostMw []readDetailMw
var updatePreMw []readDetailMw
var updatePostMw []readDetailMw
var deletePreMw []readDetailMw
var deletePostMw []readDetailMw
@@ -63,8 +63,8 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Pr
} }
event.Status = "failed" event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{ event.ErrInfo = pl.ErrorInfo{
Code: "data-create-fail", Code: "data-get-fail",
Detail: "Database insert failed", Detail: "Database get failed",
Raw: err, Raw: err,
} }
return nil, nil, pl.SetLogError(event, input) return nil, nil, pl.SetLogError(event, input)
@@ -63,8 +63,8 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Re
} }
event.Status = "failed" event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{ event.ErrInfo = pl.ErrorInfo{
Code: "data-create-fail", Code: "data-get-fail",
Detail: "Database insert failed", Detail: "Database get failed",
Raw: err, Raw: err,
} }
return nil, nil, pl.SetLogError(event, input) return nil, nil, pl.SetLogError(event, input)
+2 -2
View File
@@ -65,8 +65,8 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Un
} }
event.Status = "failed" event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{ event.ErrInfo = pl.ErrorInfo{
Code: "data-create-fail", Code: "data-get-fail",
Detail: "Database insert failed", Detail: "Database get failed",
Raw: err, Raw: err,
} }
return nil, nil, pl.SetLogError(event, input) return nil, nil, pl.SetLogError(event, input)
+2 -2
View File
@@ -64,8 +64,8 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Us
} }
event.Status = "failed" event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{ event.ErrInfo = pl.ErrorInfo{
Code: "data-create-fail", Code: "data-get-fail",
Detail: "Database insert failed", Detail: "Database get failed",
Raw: err, Raw: err,
} }
return nil, nil, pl.SetLogError(event, input) return nil, nil, pl.SetLogError(event, input)
@@ -63,8 +63,8 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Vi
} }
event.Status = "failed" event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{ event.ErrInfo = pl.ErrorInfo{
Code: "data-create-fail", Code: "data-get-fail",
Detail: "Database insert failed", Detail: "Database get failed",
Raw: err, Raw: err,
} }
return nil, nil, pl.SetLogError(event, input) return nil, nil, pl.SetLogError(event, input)