From 73e4374366fd09a354080e7330ed638a18d655aa Mon Sep 17 00:00:00 2001 From: vanilia Date: Wed, 22 Oct 2025 15:28:26 +0700 Subject: [PATCH] move request validation to spesific folder --- .../main-handler/encounter/handler.go | 44 +----------- .../encounter/request-validation.go | 53 +++++++++++++++ .../use-case/main-use-case/encounter/case.go | 55 +-------------- .../main-use-case/encounter/helper.go | 67 ++++++++++++++++++- 4 files changed, 124 insertions(+), 95 deletions(-) create mode 100644 internal/interface/main-handler/encounter/request-validation.go diff --git a/internal/interface/main-handler/encounter/handler.go b/internal/interface/main-handler/encounter/handler.go index 3493ab27..df3320ef 100644 --- a/internal/interface/main-handler/encounter/handler.go +++ b/internal/interface/main-handler/encounter/handler.go @@ -1,7 +1,6 @@ package encounter import ( - "fmt" "net/http" rw "github.com/karincake/risoles" @@ -13,8 +12,6 @@ import ( u "simrs-vx/internal/use-case/main-use-case/encounter" erc "simrs-vx/internal/domain/references/common" - ere "simrs-vx/internal/domain/references/encounter" - pa "simrs-vx/pkg/auth-helper" d "github.com/karincake/dodol" @@ -85,8 +82,6 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { } func (obj myBase) CheckOut(w http.ResponseWriter, r *http.Request) { - const dataValidationFail = "data-validation-fail" - dto := e.DischargeDto{} id := rw.ValidateInt(w, "id", r.PathValue("id")) if id <= 0 { @@ -98,43 +93,8 @@ func (obj myBase) CheckOut(w http.ResponseWriter, r *http.Request) { } // validate request body - { - switch *dto.Discharge_Method_Code { - case ere.DMCDeath: - if dto.DeathCause == nil { - rw.DataResponse(w, nil, d.FieldError{ - Code: dataValidationFail, - Message: "deathCause required if discharge_method_code is death", - }) - return - } - case ere.DMCConsulPoly, ere.DMCConsulExecutive: - if dto.InternalReferences == nil { - rw.DataResponse(w, nil, d.FieldError{ - Code: dataValidationFail, - Message: fmt.Sprintf("internalReferences required if discharge_method_code is %s", *dto.Discharge_Method_Code), - }) - return - } - - for _, v := range *dto.InternalReferences { - if v.Unit_Id == nil { - rw.DataResponse(w, nil, d.FieldError{ - Code: dataValidationFail, - Message: "internalReferences.unit_id required", - }) - return - } - - if v.Doctor_Id == nil { - rw.DataResponse(w, nil, d.FieldError{ - Code: dataValidationFail, - Message: "internalReferences.doctor_id required", - }) - return - } - } - } + if valid := validateRequestCheckout(w, dto); !valid { + return } dto.Id = uint(id) diff --git a/internal/interface/main-handler/encounter/request-validation.go b/internal/interface/main-handler/encounter/request-validation.go new file mode 100644 index 00000000..182dd12e --- /dev/null +++ b/internal/interface/main-handler/encounter/request-validation.go @@ -0,0 +1,53 @@ +package encounter + +import ( + "fmt" + "net/http" + e "simrs-vx/internal/domain/main-entities/encounter" + ere "simrs-vx/internal/domain/references/encounter" + + d "github.com/karincake/dodol" + rw "github.com/karincake/risoles" +) + +func validateRequestCheckout(w http.ResponseWriter, i e.DischargeDto) (valid bool) { + const dataValidationFail = "" + + switch *i.Discharge_Method_Code { + case ere.DMCDeath: + if i.DeathCause == nil { + rw.DataResponse(w, nil, d.FieldError{ + Code: dataValidationFail, + Message: "deathCause required if discharge_method_code is death", + }) + return + } + case ere.DMCConsulPoly, ere.DMCConsulExecutive: + if i.InternalReferences == nil { + rw.DataResponse(w, nil, d.FieldError{ + Code: dataValidationFail, + Message: fmt.Sprintf("internalReferences required if discharge_method_code is %s", *i.Discharge_Method_Code), + }) + return + } + + for _, v := range *i.InternalReferences { + if v.Unit_Id == nil { + rw.DataResponse(w, nil, d.FieldError{ + Code: dataValidationFail, + Message: "internalReferences.unit_id required", + }) + return + } + + if v.Doctor_Id == nil { + rw.DataResponse(w, nil, d.FieldError{ + Code: dataValidationFail, + Message: "internalReferences.doctor_id required", + }) + return + } + } + } + return true +} diff --git a/internal/use-case/main-use-case/encounter/case.go b/internal/use-case/main-use-case/encounter/case.go index 5f31e371..04eedfff 100644 --- a/internal/use-case/main-use-case/encounter/case.go +++ b/internal/use-case/main-use-case/encounter/case.go @@ -2,8 +2,6 @@ package encounter import ( "errors" - "fmt" - uir "simrs-vx/internal/use-case/main-use-case/internal-reference" "strconv" ea "simrs-vx/internal/domain/main-entities/ambulatory" @@ -419,59 +417,12 @@ func CheckOut(input e.DischargeDto) (*d.Data, error) { switch *input.Discharge_Method_Code { case ere.DMCDeath: // insert data death-cause - if _, err := udc.CreateData(edc.CreateDto{ - Encounter_Id: &input.Id, - Value: input.DeathCause, - }, &event, tx); err != nil { + if _, err = udc.CreateData(edc.CreateDto{Encounter_Id: &input.Id, Value: input.DeathCause}, &event, tx); err != nil { return err } - case ere.DMCConsulPoly, ere.DMCConsulExecutive: - unitIDs := make(map[uint16]struct{}) - doctorIDs := make(map[uint]struct{}) - - for _, ref := range *input.InternalReferences { - if ref.Unit_Id != nil { - unitIDs[*ref.Unit_Id] = struct{}{} - } - if ref.Doctor_Id != nil { - doctorIDs[*ref.Doctor_Id] = struct{}{} - } - } - - // validate unitIds - if len(unitIDs) > 0 { - var ids []uint16 - for id := range unitIDs { - ids = append(ids, id) - } - - units, err := getUnits(ids, &event, tx) - if err != nil { - return fmt.Errorf("failed to fetch units: %w", err) - } - if len(units) != len(ids) { - return fmt.Errorf("unit_id not found") - } - } - - // validate doctorIds - if len(doctorIDs) > 0 { - var ids []uint - for id := range doctorIDs { - ids = append(ids, id) - } - - doctors, err := getDoctors(ids, &event, tx) - if err != nil { - return fmt.Errorf("failed to fetch doctors: %w", err) - } - if len(doctors) != len(ids) { - return fmt.Errorf("doctor_id not found") - } - } - - if err := uir.CreateBulkData(*input.InternalReferences, input.Id, &event, tx); err != nil { + // bulk insert internal-references + if err = createInternalReferences(input, &event, tx); err != nil { return err } } diff --git a/internal/use-case/main-use-case/encounter/helper.go b/internal/use-case/main-use-case/encounter/helper.go index dda042e3..41fd6a51 100644 --- a/internal/use-case/main-use-case/encounter/helper.go +++ b/internal/use-case/main-use-case/encounter/helper.go @@ -7,6 +7,7 @@ package encounter import ( "errors" "fmt" + uir "simrs-vx/internal/use-case/main-use-case/internal-reference" "strings" "time" @@ -141,7 +142,9 @@ func createMedication(encounter_id uint, event *pl.Event, tx *gorm.DB) error { return err } - prescriptionItem, _, err := upi.ReadListData(epi.ReadListDto{FilterDto: epi.FilterDto{Prescription_Id: &prescription.Id}, Includes: "medicineMix"}, event, tx) + prescriptionItem, _, err := upi.ReadListData(epi.ReadListDto{ + FilterDto: epi.FilterDto{Prescription_Id: &prescription.Id}, + Includes: "medicineMix,medicineMix-MixItems"}, event, tx) if err != nil { return err } @@ -324,6 +327,68 @@ func setDataUpdateStatus(src e.UpdateStatusDto, dst *e.Encounter) { dst.Status_Code = src.StatusCode } +func createInternalReferences(input e.DischargeDto, event *pl.Event, tx *gorm.DB) error { + unitIDs := make(map[uint16]struct{}) + doctorIDs := make(map[uint]struct{}) + + for _, ref := range *input.InternalReferences { + if ref.Unit_Id != nil { + unitIDs[*ref.Unit_Id] = struct{}{} + } + if ref.Doctor_Id != nil { + doctorIDs[*ref.Doctor_Id] = struct{}{} + } + } + + // validate unitIds + if len(unitIDs) > 0 { + var ids []uint16 + for id := range unitIDs { + ids = append(ids, id) + } + + units, err := getUnits(ids, event, tx) + if err != nil { + return fmt.Errorf("failed to fetch units: %w", err) + } + if len(units) != len(ids) { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-validation-fail", + Detail: "unit_id not found", + } + return pl.SetLogError(event, nil) + } + } + + // validate doctorIds + if len(doctorIDs) > 0 { + var ids []uint + for id := range doctorIDs { + ids = append(ids, id) + } + + doctors, err := getDoctors(ids, event, tx) + if err != nil { + return fmt.Errorf("failed to fetch doctors: %w", err) + } + if len(doctors) != len(ids) { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-validation-fail", + Detail: "doctor_id not found", + } + return pl.SetLogError(event, nil) + } + } + + if err := uir.CreateBulkData(*input.InternalReferences, input.Id, event, tx); err != nil { + return err + } + + return nil +} + func getUnits(unitIds []uint16, event *pl.Event, tx *gorm.DB) ([]eu.Unit, error) { pl.SetLogInfo(event, nil, "started", "getUnits") var units []eu.Unit