Merge pull request #21 from dikstub-rssa/encounter-13

Encounter 13
This commit is contained in:
Munawwirul Jamal
2025-09-12 09:39:57 +07:00
committed by GitHub
co-authored by GitHub
126 changed files with 6062 additions and 173 deletions
@@ -0,0 +1,96 @@
-- Create "Appointment" table
CREATE TABLE "public"."Appointment" (
"Id" bigserial NOT NULL,
"CreatedAt" timestamptz NULL,
"UpdatedAt" timestamptz NULL,
"DeletedAt" timestamptz NULL,
"PracticeSchedule_Id" bigint NULL,
"Patient_Id" bigint NULL,
"Person_ResidentIdentityNumber" character varying(16) NULL,
"Person_Name" character varying(100) NULL,
"Person_PhoneNumber" character varying(30) NULL,
"PaymentMethod_Code" character varying(10) NULL,
"RefNumber" character varying(20) NULL,
PRIMARY KEY ("Id"),
CONSTRAINT "fk_Appointment_Patient" FOREIGN KEY ("Patient_Id") REFERENCES "public"."Patient" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "fk_Appointment_PracticeSchedule" FOREIGN KEY ("PracticeSchedule_Id") REFERENCES "public"."PracticeSchedule" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
);
-- Modify "Encounter" table
ALTER TABLE "public"."Encounter" ADD COLUMN "Appointment_Doctor_Id" bigint NULL, ADD COLUMN "Appointment_Id" bigint NULL, ADD COLUMN "EarlyEducation" text NULL, ADD COLUMN "MedicalDischargeEducation" text NULL, ADD COLUMN "AdmDischargeEducation" text NULL, ADD COLUMN "DischargeReason" text NULL, ADD CONSTRAINT "fk_Encounter_Appointment" FOREIGN KEY ("Appointment_Id") REFERENCES "public"."Appointment" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_Encounter_Appointment_Doctor" FOREIGN KEY ("Appointment_Doctor_Id") REFERENCES "public"."Doctor" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION;
-- Create "Adime" table
CREATE TABLE "public"."Adime" (
"Id" bigserial NOT NULL,
"CreatedAt" timestamptz NULL,
"UpdatedAt" timestamptz NULL,
"DeletedAt" timestamptz NULL,
"Encounter_Id" bigint NULL,
"Employee_Id" bigint NULL,
"Time" timestamptz NULL,
"Value" text NULL,
PRIMARY KEY ("Id"),
CONSTRAINT "fk_Adime_Employee" FOREIGN KEY ("Employee_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "fk_Adime_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
);
-- Create "Ambulatory" table
CREATE TABLE "public"."Ambulatory" (
"Id" bigserial NOT NULL,
"CreatedAt" timestamptz NULL,
"UpdatedAt" timestamptz NULL,
"DeletedAt" timestamptz NULL,
"Encounter_Id" bigint NULL,
"Class_Code" character varying(10) NULL,
PRIMARY KEY ("Id"),
CONSTRAINT "fk_Ambulatory_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
);
-- Create "Emergency" table
CREATE TABLE "public"."Emergency" (
"Id" bigserial NOT NULL,
"CreatedAt" timestamptz NULL,
"UpdatedAt" timestamptz NULL,
"DeletedAt" timestamptz NULL,
"Encounter_Id" bigint NULL,
"Class_Code" character varying(10) NULL,
PRIMARY KEY ("Id"),
CONSTRAINT "fk_Emergency_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
);
-- Create "Inpatient" table
CREATE TABLE "public"."Inpatient" (
"Id" bigserial NOT NULL,
"CreatedAt" timestamptz NULL,
"UpdatedAt" timestamptz NULL,
"DeletedAt" timestamptz NULL,
"Encounter_Id" bigint NULL,
"Class_Code" character varying(10) NULL,
"Infra_Id" integer NULL,
PRIMARY KEY ("Id"),
CONSTRAINT "fk_Inpatient_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "fk_Inpatient_Infra" FOREIGN KEY ("Infra_Id") REFERENCES "public"."Infra" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
);
-- Create "Sbar" table
CREATE TABLE "public"."Sbar" (
"Id" bigserial NOT NULL,
"CreatedAt" timestamptz NULL,
"UpdatedAt" timestamptz NULL,
"DeletedAt" timestamptz NULL,
"Encounter_Id" bigint NULL,
"Employee_Id" bigint NULL,
"Time" timestamptz NULL,
"Value" text NULL,
PRIMARY KEY ("Id"),
CONSTRAINT "fk_Sbar_Employee" FOREIGN KEY ("Employee_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "fk_Sbar_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
);
-- Create "Soapi" table
CREATE TABLE "public"."Soapi" (
"Id" bigserial NOT NULL,
"CreatedAt" timestamptz NULL,
"UpdatedAt" timestamptz NULL,
"DeletedAt" timestamptz NULL,
"Encounter_Id" bigint NULL,
"Employee_Id" bigint NULL,
"Time" timestamptz NULL,
"Value" text NULL,
PRIMARY KEY ("Id"),
CONSTRAINT "fk_Soapi_Employee" FOREIGN KEY ("Employee_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "fk_Soapi_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
);
@@ -0,0 +1,2 @@
-- Modify "Encounter" table
ALTER TABLE "public"."Encounter" DROP COLUMN "Assignment_Doctor_Id";
@@ -0,0 +1,2 @@
-- Modify "Encounter" table
ALTER TABLE "public"."Encounter" ADD COLUMN "DischargeMethod_Code" character varying(10) NULL;
@@ -0,0 +1,2 @@
-- Modify "Encounter" table
ALTER TABLE "public"."Encounter" DROP COLUMN "DischardeMethod_Code";
@@ -0,0 +1,2 @@
-- Modify "Encounter" table
ALTER TABLE "public"."Encounter" ADD COLUMN "Status_Code" character varying(10) NULL;
+8 -3
View File
@@ -1,3 +1,8 @@
h1:G2T3Gv3jMXqZDaBw/lSU8IhowMI3z//r+ZtHxndsLc4=
20250904105930.sql h1:Vv4vCurl7m7/ZB6TjRpkubHpQ4RYwSUn0QHdzfoGpzY=
20250904141448.sql h1:FYCHH9Os4KkrZMDu/jR8FMP+wLMRW+Mb0PkLU/9BRDg=
h1:dw8c/C5xz/Do+p93EVuqfaZWYja1GO1VsbM7vuCJYGo=
20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k=
20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0=
20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI=
20250908062323.sql h1:oXl6Z143tOpIl4EfP4B8JNU8LrMvVmHEtCgAfiB4gs8=
20250908073811.sql h1:m2aNXfnGxnLq1+rVWrh4f60q7fhyhV3gEwNu/OIqQlE=
20250908073839.sql h1:cPk54xjLdMs26uY8ZHjNWLuyfAMzV7Zb0/9oJQrsw04=
20250910055902.sql h1:fnLqf63sb0R02rzoj1Gnncp32NW/bUcBAMLyV4qF968=
+1 -1
View File
@@ -15,6 +15,7 @@ require (
github.com/karincake/lepet v0.0.1
github.com/karincake/risoles v0.0.3
github.com/karincake/semprit v0.0.3
github.com/karincake/serabi v0.0.14
github.com/rs/zerolog v1.33.0
golang.org/x/crypto v0.41.0
gorm.io/driver/postgres v1.5.11
@@ -34,7 +35,6 @@ require (
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/karincake/serabi v0.0.14 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-sqlite3 v1.14.28 // indirect
@@ -0,0 +1,86 @@
package adime
import (
ecore "simrs-vx/internal/domain/base-entities/core"
eem "simrs-vx/internal/domain/main-entities/employee"
ee "simrs-vx/internal/domain/main-entities/encounter"
pa "simrs-vx/pkg/auth-helper"
"time"
)
type CreateDto struct {
Encounter_Id *uint `json:"encounter_id"`
Employee_Id *uint `json:"-"`
Time *time.Time `json:"time"`
Value *string `json:"value"`
pa.AuthInfo
}
type ReadListDto struct {
FilterDto
Includes string `json:"includes"`
Preloads []string `json:"-"`
}
type FilterDto struct {
Encounter_Id *uint `json:"encounter_id"`
Employee_Id *uint `json:"employee_id"`
Time *time.Time `json:"time"`
Value *string `json:"value"`
Page int `json:"page"`
PageSize int `json:"page_size"`
NoPagination int `json:"no_pagination"`
}
type ReadDetailDto struct {
Id uint16 `json:"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.Main
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty"`
Employee_Id *uint `json:"employee_id"`
Employee *eem.Employee `json:"employee,omitempty"`
Time *time.Time `json:"time"`
Value *string `json:"value"`
}
func (d Adime) ToResponse() ResponseDto {
resp := ResponseDto{
Encounter_Id: d.Encounter_Id,
Encounter: d.Encounter,
Employee_Id: d.Employee_Id,
Employee: d.Employee,
Time: d.Time,
Value: d.Value,
}
resp.Main = d.Main
return resp
}
func ToResponseList(data []Adime) []ResponseDto {
resp := make([]ResponseDto, len(data))
for i, u := range data {
resp[i] = u.ToResponse()
}
return resp
}
@@ -0,0 +1,18 @@
package adime
import (
ecore "simrs-vx/internal/domain/base-entities/core"
eem "simrs-vx/internal/domain/main-entities/employee"
ee "simrs-vx/internal/domain/main-entities/encounter"
"time"
)
type Adime struct {
ecore.Main // adjust this according to the needs
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
Employee_Id *uint `json:"employee_id"`
Employee *eem.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"`
Time *time.Time `json:"time"`
Value *string `json:"value"`
}
@@ -0,0 +1,67 @@
package ambulatory
import (
ecore "simrs-vx/internal/domain/base-entities/core"
ee "simrs-vx/internal/domain/main-entities/encounter"
ere "simrs-vx/internal/domain/references/encounter"
)
type CreateDto struct {
Encounter_Id *uint `json:"encounter_id"`
Class_Code ere.AmbulatoryClassCode `json:"class_code" validate:"maxLength=10"`
}
type ReadListDto struct {
FilterDto
Includes string `json:"includes"`
Preloads []string `json:"-"`
}
type FilterDto struct {
Encounter_Id *uint `json:"encounter_id"`
Class_Code ere.AmbulatoryClassCode `json:"class_code"`
Page int `json:"page"`
PageSize int `json:"page_size"`
NoPagination int `json:"no_pagination"`
}
type ReadDetailDto struct {
Id uint16 `json:"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.Main
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty"`
Class_Code ere.AmbulatoryClassCode `json:"class_code"`
}
func (d Ambulatory) ToResponse() ResponseDto {
resp := ResponseDto{}
resp.Main = d.Main
return resp
}
func ToResponseList(data []Ambulatory) []ResponseDto {
resp := make([]ResponseDto, len(data))
for i, u := range data {
resp[i] = u.ToResponse()
}
return resp
}
@@ -0,0 +1,15 @@
package ambulatory
import (
ecore "simrs-vx/internal/domain/base-entities/core"
ee "simrs-vx/internal/domain/main-entities/encounter"
ere "simrs-vx/internal/domain/references/encounter"
)
type Ambulatory struct {
ecore.Main // adjust this according to the needs
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
Class_Code ere.AmbulatoryClassCode `json:"class_code" gorm:"size:10"`
}
@@ -0,0 +1,88 @@
package appointment
import (
ecore "simrs-vx/internal/domain/base-entities/core"
ep "simrs-vx/internal/domain/main-entities/patient"
eps "simrs-vx/internal/domain/main-entities/practice-schedule"
erc "simrs-vx/internal/domain/references/common"
)
type CreateDto struct {
PracticeSchedule_Id *uint `json:"practiceSchedule_id"`
Patient_Id *uint `json:"patient_id"`
Person_ResidentIdentityNumber string `json:"person_residentIdentityNumber"`
Person_Name string `json:"person_name"`
Person_PhoneNumber string `json:"person_phoneNumber"`
PaymentMethod_Code erc.PaymentMethodCode `json:"paymentMethod_code"`
RefNumber string `json:"refNumber"`
}
type ReadListDto struct {
PracticeSchedule_Id *uint `json:"practiceSchedule_id"`
Patient_Id *uint `json:"patient_id"`
Person_ResidentIdentityNumber string `json:"person_residentIdentityNumber"`
Person_Name string `json:"person_name"`
Person_PhoneNumber string `json:"person_phoneNumber"`
PaymentMethod_Code erc.PaymentMethodCode `json:"paymentMethod_code"`
RefNumber string `json:"refNumber"`
Page int `json:"page"`
PageSize int `json:"page_size"`
NoPagination int `json:"no_pagination"`
}
type ReadDetailDto struct {
Id uint16 `json:"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.Main
PracticeSchedule_Id *uint `json:"practiceSchedule_id"`
PracticeSchedule *eps.PracticeSchedule `json:"practiceSchedule,omitempty"`
Patient_Id *uint `json:"patient_id"`
Patient *ep.Patient `json:"patient,omitempty"`
Person_ResidentIdentityNumber string `json:"person_residentIdentityNumber"`
Person_Name string `json:"person_name"`
Person_PhoneNumber string `json:"person_phoneNumber"`
PaymentMethod_Code erc.PaymentMethodCode `json:"paymentMethod_code"`
RefNumber string `json:"refNumber"`
}
func (d Appointment) ToResponse() ResponseDto {
resp := ResponseDto{
PracticeSchedule_Id: d.PracticeSchedule_Id,
PracticeSchedule: d.PracticeSchedule,
Patient_Id: d.Patient_Id,
Patient: d.Patient,
Person_ResidentIdentityNumber: d.Person_ResidentIdentityNumber,
Person_Name: d.Person_Name,
Person_PhoneNumber: d.Person_PhoneNumber,
PaymentMethod_Code: d.PaymentMethod_Code,
RefNumber: d.RefNumber,
}
resp.Main = d.Main
return resp
}
func ToResponseList(data []Appointment) []ResponseDto {
resp := make([]ResponseDto, len(data))
for i, u := range data {
resp[i] = u.ToResponse()
}
return resp
}
@@ -0,0 +1,21 @@
package appointment
import (
ecore "simrs-vx/internal/domain/base-entities/core"
ep "simrs-vx/internal/domain/main-entities/patient"
eps "simrs-vx/internal/domain/main-entities/practice-schedule"
erc "simrs-vx/internal/domain/references/common"
)
type Appointment struct {
ecore.Main // adjust this according to the needs
PracticeSchedule_Id *uint `json:"practiceSchedule_id"`
PracticeSchedule *eps.PracticeSchedule `json:"practiceSchedule,omitempty" gorm:"foreignKey:PracticeSchedule_Id;references:Id"`
Patient_Id *uint `json:"patient_id"`
Patient *ep.Patient `json:"patient,omitempty" gorm:"foreignKey:Patient_Id;references:Id"`
Person_ResidentIdentityNumber string `json:"person_residentIdentityNumber" gorm:"size:16"`
Person_Name string `json:"person_name" gorm:"size:100"`
Person_PhoneNumber string `json:"person_phoneNumber" gorm:"size:30"`
PaymentMethod_Code erc.PaymentMethodCode `json:"paymentMethod_code" gorm:"size:10"`
RefNumber string `json:"refNumber" gorm:"size:20"`
}
@@ -0,0 +1,67 @@
package emergency
import (
ecore "simrs-vx/internal/domain/base-entities/core"
ee "simrs-vx/internal/domain/main-entities/encounter"
ere "simrs-vx/internal/domain/references/encounter"
)
type CreateDto struct {
Encounter_Id *uint `json:"encounter_id"`
Class_Code ere.EmergencyClassCode `json:"class_code" validate:"maxLength=10"`
}
type ReadListDto struct {
FilterDto
Includes string `json:"includes"`
Preloads []string `json:"-"`
}
type FilterDto struct {
Encounter_Id *uint `json:"encounter_id"`
Class_Code ere.EmergencyClassCode `json:"class_code"`
Page int `json:"page"`
PageSize int `json:"page_size"`
NoPagination int `json:"no_pagination"`
}
type ReadDetailDto struct {
Id uint16 `json:"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.Main
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty"`
Class_Code ere.EmergencyClassCode `json:"class_code"`
}
func (d Emergency) ToResponse() ResponseDto {
resp := ResponseDto{}
resp.Main = d.Main
return resp
}
func ToResponseList(data []Emergency) []ResponseDto {
resp := make([]ResponseDto, len(data))
for i, u := range data {
resp[i] = u.ToResponse()
}
return resp
}
@@ -0,0 +1,15 @@
package emergency
import (
ecore "simrs-vx/internal/domain/base-entities/core"
ee "simrs-vx/internal/domain/main-entities/encounter"
ere "simrs-vx/internal/domain/references/encounter"
)
type Emergency struct {
ecore.Main // adjust this according to the needs
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
Class_Code ere.EmergencyClassCode `json:"class_code" gorm:"size:10"`
}
+89 -62
View File
@@ -2,28 +2,31 @@ package encounter
import (
ecore "simrs-vx/internal/domain/base-entities/core"
ea "simrs-vx/internal/domain/main-entities/appointment"
ed "simrs-vx/internal/domain/main-entities/doctor"
ep "simrs-vx/internal/domain/main-entities/patient"
es "simrs-vx/internal/domain/main-entities/specialist"
ess "simrs-vx/internal/domain/main-entities/subspecialist"
eu "simrs-vx/internal/domain/main-entities/unit"
erc "simrs-vx/internal/domain/references/common"
ere "simrs-vx/internal/domain/references/encounter"
"time"
)
type CreateDto struct {
Patient_Id *uint `json:"patient_id"`
Patient *ep.Patient `json:"patient,omitempty"`
RegisteredAt *time.Time `json:"registeredAt"`
Class_Code ere.EncounterClassCode `json:"class_code" validate:"maxLength=10"`
Unit_Id *uint `json:"unit_id"`
Specialist_Id *uint16 `json:"specialist_id"`
Subspecialist_Id *uint16 `json:"subspecialist_id"`
VisitDate time.Time `json:"visitDate"`
Assignment_Doctor_Id *uint `json:"assignment_doctor_id"`
Responsible_Doctor_Id *uint `json:"responsible_doctor_id"`
DischardeMethod_Code ere.DischargeMethodCode `json:"dischardeMethod_code" validate:"maxLength=10"`
RefSource_Name *string `json:"refSource_name" validate:"maxLength=100"`
Patient_Id *uint `json:"patient_id"`
RegisteredAt *time.Time `json:"registeredAt"`
Class_Code ere.EncounterClassCode `json:"class_code" validate:"maxLength=10"`
SubClass_Code *string `json:"subClass_code" validate:"maxLength=10"` // for sub
Infra_Id *uint16 `json:"infra_id"` // for inpatient
Unit_Id *uint `json:"unit_id"`
Specialist_Id *uint16 `json:"specialist_id"`
Subspecialist_Id *uint16 `json:"subspecialist_id"`
VisitDate time.Time `json:"visitDate"`
Appointment_Doctor_Id *uint `json:"appointment_doctor_id"`
Responsible_Doctor_Id *uint `json:"responsible_doctor_id"`
RefSource_Name *string `json:"refSource_name" validate:"maxLength=100"`
Appointment_Id *uint `json:"appointment_id"`
}
type ReadListDto struct {
@@ -33,18 +36,23 @@ type ReadListDto struct {
}
type FilterDto struct {
Patient_Id *uint `json:"patient_id"`
Patient *ep.Patient `json:"patient,omitempty"`
RegisteredAt *time.Time `json:"registeredAt"`
Class_Code ere.EncounterClassCode `json:"class_code" validate:"maxLength=10"`
Unit_Id *uint `json:"unit_id"`
Specialist_Id *uint16 `json:"specialist_id"`
Subspecialist_Id *uint16 `json:"subspecialist_id"`
VisitDate time.Time `json:"visitDate"`
Assignment_Doctor_Id *uint `json:"assignment_doctor_id"`
Responsible_Doctor_Id *uint `json:"responsible_doctor_id"`
DischardeMethod_Code ere.DischargeMethodCode `json:"dischardeMethod_code" validate:"maxLength=10"`
RefSource_Name *string `json:"refSource_name" validate:"maxLength=100"`
Patient_Id *uint `json:"patient_id"`
Patient *ep.Patient `json:"patient,omitempty"`
RegisteredAt *time.Time `json:"registeredAt"`
Class_Code ere.EncounterClassCode `json:"class_code" validate:"maxLength=10"`
Unit_Id *uint `json:"unit_id"`
Specialist_Id *uint16 `json:"specialist_id"`
Subspecialist_Id *uint16 `json:"subspecialist_id"`
VisitDate time.Time `json:"visitDate"`
Appoinment_Doctor_Id *uint `json:"appointment_doctor_id"`
Responsible_Doctor_Id *uint `json:"responsible_doctor_id"`
DischargeMethod_Code ere.DischargeMethodCode `json:"dischargeMethod_code" validate:"maxLength=10"`
RefSource_Name *string `json:"refSource_name" validate:"maxLength=100"`
Appointment_Id *uint `json:"appointment_id"`
EarlyEducation *string `json:"earlyEducation"`
MedicalDischargeEducation *string `json:"medicalDischargeEducation"`
AdmDischargeEducation *string `json:"admDischargeEducation"`
DischargeReason *string `json:"dischargeReason"`
Page int `json:"page"`
PageSize int `json:"page_size"`
@@ -52,10 +60,7 @@ type FilterDto struct {
}
type ReadDetailDto struct {
Id uint16 `json:"id"`
Code string `json:"code"`
Name string `json:"name"`
Parent_Id *int16 `json:"parent_id"`
Id uint16 `json:"id"`
}
type UpdateDto struct {
@@ -72,47 +77,69 @@ type MetaDto struct {
PageSize int `json:"page_size"`
Count int `json:"count"`
}
type DischargeDto struct {
Id uint `json:"id"`
DischargeMethod_Code *ere.DischargeMethodCode `json:"dischargeMethod_code" validate:"maxLength=10"`
EarlyEducation *string `json:"earlyEducation"`
MedicalDischargeEducation *string `json:"medicalDischargeEducation"`
AdmDischargeEducation *string `json:"admDischargeEducation"`
DischargeReason *string `json:"dischargeReason"`
}
type ResponseDto struct {
ecore.Main
Patient_Id *uint `json:"patient_id"`
Patient *ep.Patient `json:"patient,omitempty"`
RegisteredAt *time.Time `json:"registeredAt"`
Class_Code ere.EncounterClassCode `json:"class_code"`
Unit_Id *uint `json:"unit_id"`
Specialist_Id *uint16 `json:"specialist_id"`
Specialist *es.Specialist `json:"specialist,omitempty"`
Subspecialist_Id *uint16 `json:"subspecialist_id"`
Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty"`
Unit *eu.Unit `json:"unit,omitempty"`
VisitDate time.Time `json:"visitDate"`
Assignment_Doctor_Id *uint `json:"assignment_doctor_id"`
Assignment_Doctor *ed.Doctor `json:"assignment_doctor,omitempty"`
Responsible_Doctor_Id *uint `json:"responsible_doctor_id"`
Responsible_Doctor *ed.Doctor `json:"responsible_doctor,omitempty"`
DischardeMethod_Code ere.DischargeMethodCode `json:"dischardeMethod_code`
RefSource_Name *string `json:"refSource_name"`
Patient_Id *uint `json:"patient_id"`
Patient *ep.Patient `json:"patient,omitempty"`
RegisteredAt *time.Time `json:"registeredAt"`
Class_Code ere.EncounterClassCode `json:"class_code"`
Unit_Id *uint `json:"unit_id"`
Specialist_Id *uint16 `json:"specialist_id"`
Specialist *es.Specialist `json:"specialist,omitempty"`
Subspecialist_Id *uint16 `json:"subspecialist_id"`
Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty"`
Unit *eu.Unit `json:"unit,omitempty"`
VisitDate time.Time `json:"visitDate"`
Appointment_Doctor_Id *uint `json:"assignment_doctor_id"`
Appointment_Doctor *ed.Doctor `json:"assignment_doctor,omitempty"`
Responsible_Doctor_Id *uint `json:"responsible_doctor_id"`
Responsible_Doctor *ed.Doctor `json:"responsible_doctor,omitempty"`
DischargeMethod_Code *ere.DischargeMethodCode `json:"dischargeMethod_code"`
RefSource_Name *string `json:"refSource_name"`
Appointment_Id *uint `json:"appointment_id"`
Appointment *ea.Appointment `json:"appointment,omitempty"`
EarlyEducation *string `json:"earlyEducation"`
MedicalDischargeEducation *string `json:"medicalDischargeEducation"`
AdmDischargeEducation *string `json:"admDischargeEducation"`
DischargeReason *string `json:"dischargeReason"`
Status_Code erc.DataStatusCode `json:"status_code"`
}
func (d Encounter) ToResponse() ResponseDto {
resp := ResponseDto{
Patient_Id: d.Patient_Id,
Patient: d.Patient,
RegisteredAt: d.RegisteredAt,
Class_Code: d.Class_Code,
Unit_Id: d.Unit_Id,
Unit: d.Unit,
Specialist_Id: d.Specialist_Id,
Specialist: d.Specialist,
Subspecialist_Id: d.Subspecialist_Id,
Subspecialist: d.Subspecialist,
VisitDate: d.VisitDate,
Assignment_Doctor_Id: d.Assignment_Doctor_Id,
Assignment_Doctor: d.Assignment_Doctor,
Responsible_Doctor_Id: d.Responsible_Doctor_Id,
Responsible_Doctor: d.Responsible_Doctor,
DischardeMethod_Code: d.DischardeMethod_Code,
RefSource_Name: d.RefSource_Name,
Patient_Id: d.Patient_Id,
Patient: d.Patient,
RegisteredAt: d.RegisteredAt,
Class_Code: d.Class_Code,
Unit_Id: d.Unit_Id,
Unit: d.Unit,
Specialist_Id: d.Specialist_Id,
Specialist: d.Specialist,
Subspecialist_Id: d.Subspecialist_Id,
Subspecialist: d.Subspecialist,
VisitDate: d.VisitDate,
Appointment_Doctor_Id: d.Appointment_Doctor_Id,
Appointment_Doctor: d.Appointment_Doctor,
Responsible_Doctor_Id: d.Responsible_Doctor_Id,
Responsible_Doctor: d.Responsible_Doctor,
DischargeMethod_Code: d.DischargeMethod_Code,
RefSource_Name: d.RefSource_Name,
Appointment_Id: d.Appointment_Id,
Appointment: d.Appointment,
EarlyEducation: d.EarlyEducation,
MedicalDischargeEducation: d.MedicalDischargeEducation,
AdmDischargeEducation: d.AdmDischargeEducation,
DischargeReason: d.DischargeReason,
Status_Code: d.Status_Code,
}
resp.Main = d.Main
return resp
@@ -2,32 +2,45 @@ package encounter
import (
ecore "simrs-vx/internal/domain/base-entities/core"
ea "simrs-vx/internal/domain/main-entities/appointment"
ed "simrs-vx/internal/domain/main-entities/doctor"
ep "simrs-vx/internal/domain/main-entities/patient"
es "simrs-vx/internal/domain/main-entities/specialist"
ess "simrs-vx/internal/domain/main-entities/subspecialist"
eu "simrs-vx/internal/domain/main-entities/unit"
erc "simrs-vx/internal/domain/references/common"
ere "simrs-vx/internal/domain/references/encounter"
"time"
)
type Encounter struct {
ecore.Main // adjust this according to the needs
Patient_Id *uint `json:"patient_id"`
Patient *ep.Patient `json:"patient,omitempty" gorm:"foreignKey:Patient_Id;references:Id"`
RegisteredAt *time.Time `json:"registeredAt"`
Class_Code ere.EncounterClassCode `json:"class_code" gorm:"not null;size:10"`
Unit_Id *uint `json:"unit_id"`
Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Id;references:Id"`
Specialist_Id *uint16 `json:"specialist_id"`
Specialist *es.Specialist `json:"specialist,omitempty" gorm:"foreignKey:Specialist_Id;references:Id"`
Subspecialist_Id *uint16 `json:"subspecialist_id"`
Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty" gorm:"foreignKey:Subspecialist_Id;references:Id"`
VisitDate time.Time `json:"visitDate"`
Assignment_Doctor_Id *uint `json:"assignment_doctor_id"`
Assignment_Doctor *ed.Doctor `json:"assignment_doctor,omitempty" gorm:"foreignKey:Assignment_Doctor_Id;references:Id"`
Responsible_Doctor_Id *uint `json:"responsible_doctor_id"`
Responsible_Doctor *ed.Doctor `json:"responsible_doctor,omitempty" gorm:"foreignKey:Responsible_Doctor_Id;references:Id"`
DischardeMethod_Code ere.DischargeMethodCode `json:"dischardeMethod_code" gorm:"size:10"`
RefSource_Name *string `json:"refSource_name" gorm:"size:100"`
ecore.Main // adjust this according to the needs
Patient_Id *uint `json:"patient_id"`
Patient *ep.Patient `json:"patient,omitempty" gorm:"foreignKey:Patient_Id;references:Id"`
RegisteredAt *time.Time `json:"registeredAt"`
Class_Code ere.EncounterClassCode `json:"class_code" gorm:"not null;size:10"`
Unit_Id *uint `json:"unit_id"`
Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Id;references:Id"`
Specialist_Id *uint16 `json:"specialist_id"`
Specialist *es.Specialist `json:"specialist,omitempty" gorm:"foreignKey:Specialist_Id;references:Id"`
Subspecialist_Id *uint16 `json:"subspecialist_id"`
Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty" gorm:"foreignKey:Subspecialist_Id;references:Id"`
VisitDate time.Time `json:"visitDate"`
Appointment_Doctor_Id *uint `json:"appointment_doctor_id"`
Appointment_Doctor *ed.Doctor `json:"appointment_doctor,omitempty" gorm:"foreignKey:Appointment_Doctor_Id;references:Id"`
Responsible_Doctor_Id *uint `json:"responsible_doctor_id"`
Responsible_Doctor *ed.Doctor `json:"responsible_doctor,omitempty" gorm:"foreignKey:Responsible_Doctor_Id;references:Id"`
DischargeMethod_Code *ere.DischargeMethodCode `json:"dischargeMethod_code" gorm:"size:10"`
RefSource_Name *string `json:"refSource_name" gorm:"size:100"`
Appointment_Id *uint `json:"appointment_id"`
Appointment *ea.Appointment `json:"appointment,omitempty" gorm:"foreignKey:Appointment_Id;references:Id"`
EarlyEducation *string `json:"earlyEducation"`
MedicalDischargeEducation *string `json:"medicalDischargeEducation"`
AdmDischargeEducation *string `json:"admDischargeEducation"`
DischargeReason *string `json:"dischargeReason"`
Status_Code erc.DataStatusCode `json:"status_code" gorm:"size:10"`
}
func (d Encounter) IsDone() bool {
return d.Status_Code == erc.DSCDone
}
@@ -0,0 +1,78 @@
package inpatient
import (
ecore "simrs-vx/internal/domain/base-entities/core"
ee "simrs-vx/internal/domain/main-entities/encounter"
ei "simrs-vx/internal/domain/main-entities/infra"
ere "simrs-vx/internal/domain/references/encounter"
)
type CreateDto struct {
Encounter_Id *uint `json:"encounter_id"`
Class_Code ere.InpatientClassCode `json:"class_code" validate:"maxLength=10"`
Infra_Id *uint16 `json:"infra_id"`
}
type ReadListDto struct {
FilterDto
Includes string `json:"includes"`
Preloads []string `json:"-"`
}
type FilterDto struct {
Encounter_Id *uint `json:"encounter_id"`
Class_Code ere.InpatientClassCode `json:"class_code"`
Infra_Id *uint16 `json:"infra_id"`
Page int `json:"page"`
PageSize int `json:"page_size"`
NoPagination int `json:"no_pagination"`
}
type ReadDetailDto struct {
Id uint16 `json:"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.Main
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty"`
Class_Code ere.InpatientClassCode `json:"class_code"`
Infra_Id *uint16 `json:"infra_id"`
Infra *ei.Infra `json:"infra,omitempty"`
}
func (d Inpatient) ToResponse() ResponseDto {
resp := ResponseDto{
Encounter_Id: d.Encounter_Id,
Encounter: d.Encounter,
Class_Code: d.Class_Code,
Infra_Id: d.Infra_Id,
Infra: d.Infra,
}
resp.Main = d.Main
return resp
}
func ToResponseList(data []Inpatient) []ResponseDto {
resp := make([]ResponseDto, len(data))
for i, u := range data {
resp[i] = u.ToResponse()
}
return resp
}
@@ -0,0 +1,18 @@
package inpatient
import (
ecore "simrs-vx/internal/domain/base-entities/core"
ee "simrs-vx/internal/domain/main-entities/encounter"
ei "simrs-vx/internal/domain/main-entities/infra"
ere "simrs-vx/internal/domain/references/encounter"
)
type Inpatient struct {
ecore.Main // adjust this according to the needs
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
Class_Code ere.InpatientClassCode `json:"class_code" gorm:"size:10"`
Infra_Id *uint16 `json:"infra_id"`
Infra *ei.Infra `json:"infra,omitempty" gorm:"foreignKey:Infra_Id;references:Id"`
}
+86
View File
@@ -0,0 +1,86 @@
package sbar
import (
ecore "simrs-vx/internal/domain/base-entities/core"
eem "simrs-vx/internal/domain/main-entities/employee"
ee "simrs-vx/internal/domain/main-entities/encounter"
pa "simrs-vx/pkg/auth-helper"
"time"
)
type CreateDto struct {
Encounter_Id *uint `json:"encounter_id"`
Employee_Id *uint `json:"-"`
Time *time.Time `json:"time"`
Value *string `json:"value"`
pa.AuthInfo
}
type ReadListDto struct {
FilterDto
Includes string `json:"includes"`
Preloads []string `json:"-"`
}
type FilterDto struct {
Encounter_Id *uint `json:"encounter_id"`
Employee_Id *uint `json:"employee_id"`
Time *time.Time `json:"time"`
Value *string `json:"value"`
Page int `json:"page"`
PageSize int `json:"page_size"`
NoPagination int `json:"no_pagination"`
}
type ReadDetailDto struct {
Id uint16 `json:"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.Main
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty"`
Employee_Id *uint `json:"employee_id"`
Employee *eem.Employee `json:"employee,omitempty"`
Time *time.Time `json:"time"`
Value *string `json:"value"`
}
func (d Sbar) ToResponse() ResponseDto {
resp := ResponseDto{
Encounter_Id: d.Encounter_Id,
Encounter: d.Encounter,
Employee_Id: d.Employee_Id,
Employee: d.Employee,
Time: d.Time,
Value: d.Value,
}
resp.Main = d.Main
return resp
}
func ToResponseList(data []Sbar) []ResponseDto {
resp := make([]ResponseDto, len(data))
for i, u := range data {
resp[i] = u.ToResponse()
}
return resp
}
@@ -0,0 +1,18 @@
package sbar
import (
ecore "simrs-vx/internal/domain/base-entities/core"
eem "simrs-vx/internal/domain/main-entities/employee"
ee "simrs-vx/internal/domain/main-entities/encounter"
"time"
)
type Sbar struct {
ecore.Main // adjust this according to the needs
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
Employee_Id *uint `json:"employee_id"`
Employee *eem.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"`
Time *time.Time `json:"time"`
Value *string `json:"value"`
}
@@ -0,0 +1,86 @@
package soapi
import (
ecore "simrs-vx/internal/domain/base-entities/core"
eem "simrs-vx/internal/domain/main-entities/employee"
ee "simrs-vx/internal/domain/main-entities/encounter"
pa "simrs-vx/pkg/auth-helper"
"time"
)
type CreateDto struct {
Encounter_Id *uint `json:"encounter_id"`
Employee_Id *uint `json:"-"`
Time *time.Time `json:"time"`
Value *string `json:"value"`
pa.AuthInfo
}
type ReadListDto struct {
FilterDto
Includes string `json:"includes"`
Preloads []string `json:"-"`
}
type FilterDto struct {
Encounter_Id *uint `json:"encounter_id"`
Employee_Id *uint `json:"employee_id"`
Time *time.Time `json:"time"`
Value *string `json:"value"`
Page int `json:"page"`
PageSize int `json:"page_size"`
NoPagination int `json:"no_pagination"`
}
type ReadDetailDto struct {
Id uint16 `json:"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.Main
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty"`
Employee_Id *uint `json:"employee_id"`
Employee *eem.Employee `json:"employee,omitempty"`
Time *time.Time `json:"time"`
Value *string `json:"value"`
}
func (d Soapi) ToResponse() ResponseDto {
resp := ResponseDto{
Encounter_Id: d.Encounter_Id,
Encounter: d.Encounter,
Employee_Id: d.Employee_Id,
Employee: d.Employee,
Time: d.Time,
Value: d.Value,
}
resp.Main = d.Main
return resp
}
func ToResponseList(data []Soapi) []ResponseDto {
resp := make([]ResponseDto, len(data))
for i, u := range data {
resp[i] = u.ToResponse()
}
return resp
}
@@ -0,0 +1,18 @@
package soapi
import (
ecore "simrs-vx/internal/domain/base-entities/core"
eem "simrs-vx/internal/domain/main-entities/employee"
ee "simrs-vx/internal/domain/main-entities/encounter"
"time"
)
type Soapi struct {
ecore.Main // adjust this according to the needs
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
Employee_Id *uint `json:"employee_id"`
Employee *eem.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"`
Time *time.Time `json:"time"`
Value *string `json:"value"`
}
@@ -1,9 +1,11 @@
// Package clinical mostly about SOAPI
package clinical
type (
SubjectCode string
ObjectCode string
AssessmentCode string
PlanCode string
InstructionCode string
)
@@ -31,8 +33,47 @@ const (
ACLateDiag AssessmentCode = "late-diag" // Diagnosis Akhir
ACSecDiag AssessmentCode = "sec-diag" // Diagnosis Sekunder
PCPlan PlanCode = "plan" // Rencana
ICDetail InstructionCode = "detail" // Detail instruksi
ICMedAct InstructionCode = "med-act" // Tindakan medis
ICMedication InstructionCode = "medication" // Obat
ICMaterial InstructionCode = "material" // BMHP
)
type Soapi struct {
// Subject
PrimaryComplaint string `json:"pri-compl"`
SecondaryComplaint string `json:"sec-compl"`
CurrentDiseaseHistory string `json:"cur-disea-hist"`
PastDiseaseHistory string `json:"pas-disea-hist"`
FamilyDiseaseHistory string `json:"fam-disea-hist"`
AllergyHistory string `json:"alg-hist"`
AllergyReaction string `json:"alg-react"`
MedicationHistory string `json:"med-hist"`
// Object
ConsciousnessLevel string `json:"consc-level"`
ConsciousnessLevelDet string `json:"consc-level-det"`
SystolicBloodPressure string `json:"syst-bp"`
DiastolicBloodPressure string `json:"diast-bp"`
HeartRate string `json:"hear-rt"`
Temperature string `json:"temp"`
SpO2 string `json:"spo2"`
Weight string `json:"weight"`
Height string `json:"height"`
// Assessment
EarlyDiagnosis string `json:"early-diag"`
LateDiagnosis string `json:"late-diag"`
SecondaryDiag string `json:"sec-diag"`
// Plan
Plan string `json:"plan"`
// Instruction
InstructionDetail string `json:"detail"`
MedicalAction string `json:"med-act"`
Medication string `json:"medication"`
Material string `json:"material"`
}
@@ -9,17 +9,14 @@ type (
EmergencyClassCode string
OutpatientClassCode string
CheckupScopeCode string
AmbulatoryClassCode string
InpatientClassCode string
)
const (
ECOutpatient EncounterClassCode = "outpatient"
ECAmbulatory EncounterClassCode = "ambulatory"
ECEmergency EncounterClassCode = "emergency"
ECInpatient EncounterClassCode = "inpatient"
ECDraft EncounterClassCode = "draft"
ECDone EncounterClassCode = "done"
ECCancel EncounterClassCode = "cancel"
ECSkip EncounterClassCode = "skip"
QSCWait QueueStatusCode = "wait" // Tunggu
QSCProc QueueStatusCode = "proc" // Proses
@@ -27,8 +24,13 @@ const (
QSCCancel QueueStatusCode = "cancel" // Dibatalkan
QSCSkip QueueStatusCode = "skip" // Dilewati
DMCHome DischargeMethodCode = "home" // Rumah
DMCHomeReq DischargeMethodCode = "home-request" // Rumah (Dibutuhkan)
DMCHome DischargeMethodCode = "home" // Rumah
DMCHomeReq DischargeMethodCode = "home-request" // Rumah (Dibutuhkan)
DMCConsulation DischargeMethodCode = "consulation" // Konsultasi Lanjutan
DMCInpatient DischargeMethodCode = "inpatient" // Inpatient
DMCExtRef DischargeMethodCode = "external-ref" // Rujuk Eksternal
DMCIntRef DischargeMethodCode = "internal-ref" // Rujuk Internal
DMCDeath DischargeMethodCode = "death" // Meninggal
TCAmbulance TransportationCode = "ambulance"
TCCar TransportationCode = "car"
@@ -55,11 +57,18 @@ const (
CSCPLab CheckupScopeCode = "pa-lab" // Patology Anatomy Laboratorium
CSCRad CheckupScopeCode = "radiology" // Radiology
ACCReg AmbulatoryClassCode = "reg" // Regular
ACCRme AmbulatoryClassCode = "rme" // Rehab Medik
ICCIp InpatientClassCode = "ip" // Regular Rawat Inap
ICCICU InpatientClassCode = "icu" // ICU
ICCHCU InpatientClassCode = "hcu" // HCU
ICCVK InpatientClassCode = "vk" // Verlos kamer
)
func (ec EncounterClassCode) Code() string {
switch ec {
case ECAmbulatory, ECOutpatient:
case ECAmbulatory:
return "AMB"
case ECInpatient:
return "IMP"
@@ -0,0 +1,80 @@
package adime
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/adime"
u "simrs-vx/internal/use-case/main-use-case/adime"
pa "simrs-vx/pkg/auth-helper"
d "github.com/karincake/dodol"
)
type myBase struct{}
var O myBase
func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
authInfo, err := pa.GetAuthInfo(r)
if err != nil {
rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
}
dto := e.CreateDto{}
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
dto.AuthInfo = *authInfo
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 = uint16(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 = uint16(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 = uint16(id)
res, err := u.Delete(dto)
rw.DataResponse(w, res, err)
}
@@ -9,16 +9,10 @@ import (
m "simrs-vx/internal/domain/main-entities/user"
s "simrs-vx/internal/use-case/main-use-case/authentication"
pa "simrs-vx/pkg/auth-helper"
)
type authKey string
const akInfo authKey = "authInfo"
type AuthKey struct{}
// var Position m.Position
func Login(w http.ResponseWriter, r *http.Request) {
var input m.LoginDto
if !(rw.ValidateStructByIOR(w, r.Body, &input)) {
@@ -35,12 +29,12 @@ func Login(w http.ResponseWriter, r *http.Request) {
}
func Logout(w http.ResponseWriter, r *http.Request) {
ctxVal := r.Context().Value(AuthKey{})
ctxVal := r.Context().Value(pa.AuthKey{})
if ctxVal == nil {
rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "logout skiped. the request is done wihtout authorization."}, nil)
return
}
authInfo := ctxVal.(*s.AuthInfo)
authInfo := ctxVal.(*pa.AuthInfo)
s.RevokeToken(authInfo.Uuid)
rw.WriteJSON(w, http.StatusOK, d.IS{"message": "logged out"}, nil)
}
@@ -52,7 +46,7 @@ func GuardMW(next http.Handler) http.Handler {
rw.WriteJSON(w, http.StatusUnauthorized, err.(d.FieldError), nil)
return
}
ctx := context.WithValue(r.Context(), AuthKey{}, accessDetail)
ctx := context.WithValue(r.Context(), pa.AuthKey{}, accessDetail)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
@@ -0,0 +1,80 @@
package encounter
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/encounter"
u "simrs-vx/internal/use-case/main-use-case/encounter"
)
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 = uint16(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 = uint16(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 = uint16(id)
res, err := u.Delete(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) CheckOut(w http.ResponseWriter, r *http.Request) {
dto := e.DischargeDto{}
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
res, err := u.CheckOut(dto)
rw.DataResponse(w, res, err)
}
@@ -4,11 +4,15 @@ import (
"net/http"
/******************** main / transaction ********************/
adime "simrs-vx/internal/interface/main-handler/adime"
auth "simrs-vx/internal/interface/main-handler/authentication"
counter "simrs-vx/internal/interface/main-handler/counter"
encounter "simrs-vx/internal/interface/main-handler/encounter"
medicicinemix "simrs-vx/internal/interface/main-handler/medicine-mix"
medicicinemixitem "simrs-vx/internal/interface/main-handler/medicine-mix-item"
practiceschedule "simrs-vx/internal/interface/main-handler/practice-schedule"
sbar "simrs-vx/internal/interface/main-handler/sbar"
soapi "simrs-vx/internal/interface/main-handler/soapi"
/******************** actor ********************/
doctor "simrs-vx/internal/interface/main-handler/doctor"
@@ -115,7 +119,18 @@ func SetRoutes() http.Handler {
"DELETE /{id}": patient.O.Delete,
"GET /by-identifier": patient.O.Search,
})
hk.GroupRoutes("/v1/encounter", r, hk.MapHandlerFunc{
"GET /": encounter.O.GetList,
"GET /{id}": encounter.O.GetDetail,
"POST /": encounter.O.Create,
"PATCH /{id}": encounter.O.Update,
"DELETE /{id}": encounter.O.Delete,
"PATCH /{id}/checkout": encounter.O.CheckOut,
})
hc.RegCrud(r, "/v1/soapi", auth.GuardMW, soapi.O)
hc.RegCrud(r, "/v1/adime", auth.GuardMW, adime.O)
hc.RegCrud(r, "/v1/sbar", auth.GuardMW, sbar.O)
hc.RegCrud(r, "/v1/person", person.O)
hc.RegCrud(r, "/v1/person-address", personaddress.O)
hc.RegCrud(r, "/v1/person-contact", personcontact.O)
@@ -0,0 +1,80 @@
package sbar
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/sbar"
u "simrs-vx/internal/use-case/main-use-case/sbar"
pa "simrs-vx/pkg/auth-helper"
d "github.com/karincake/dodol"
)
type myBase struct{}
var O myBase
func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
authInfo, err := pa.GetAuthInfo(r)
if err != nil {
rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
}
dto := e.CreateDto{}
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
dto.AuthInfo = *authInfo
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 = uint16(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 = uint16(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 = uint16(id)
res, err := u.Delete(dto)
rw.DataResponse(w, res, err)
}
@@ -0,0 +1,80 @@
package soapi
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/soapi"
u "simrs-vx/internal/use-case/main-use-case/soapi"
pa "simrs-vx/pkg/auth-helper"
d "github.com/karincake/dodol"
)
type myBase struct{}
var O myBase
func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
authInfo, err := pa.GetAuthInfo(r)
if err != nil {
rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
}
dto := e.CreateDto{}
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
dto.AuthInfo = *authInfo
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 = uint16(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 = uint16(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 = uint16(id)
res, err := u.Delete(dto)
rw.DataResponse(w, res, err)
}
+14
View File
@@ -5,6 +5,9 @@ import (
"io"
"os"
"os/exec"
adime "simrs-vx/internal/domain/main-entities/adime"
ambulatory "simrs-vx/internal/domain/main-entities/ambulatory"
appointment "simrs-vx/internal/domain/main-entities/appointment"
counter "simrs-vx/internal/domain/main-entities/counter"
device "simrs-vx/internal/domain/main-entities/device"
diagnosesrc "simrs-vx/internal/domain/main-entities/diagnose-src"
@@ -13,10 +16,12 @@ import (
divisionposition "simrs-vx/internal/domain/main-entities/division-position"
doctor "simrs-vx/internal/domain/main-entities/doctor"
doctorfee "simrs-vx/internal/domain/main-entities/doctor-fee"
emergency "simrs-vx/internal/domain/main-entities/emergency"
employee "simrs-vx/internal/domain/main-entities/employee"
encounter "simrs-vx/internal/domain/main-entities/encounter"
ethnic "simrs-vx/internal/domain/main-entities/ethnic"
infra "simrs-vx/internal/domain/main-entities/infra"
inpatient "simrs-vx/internal/domain/main-entities/inpatient"
installation "simrs-vx/internal/domain/main-entities/installation"
insurancecompany "simrs-vx/internal/domain/main-entities/insurance-company"
item "simrs-vx/internal/domain/main-entities/item"
@@ -47,6 +52,8 @@ import (
province "simrs-vx/internal/domain/main-entities/province"
regency "simrs-vx/internal/domain/main-entities/regency"
room "simrs-vx/internal/domain/main-entities/room"
sbar "simrs-vx/internal/domain/main-entities/sbar"
soapi "simrs-vx/internal/domain/main-entities/soapi"
specialist "simrs-vx/internal/domain/main-entities/specialist"
specialistintern "simrs-vx/internal/domain/main-entities/specialist-intern"
subspecialist "simrs-vx/internal/domain/main-entities/subspecialist"
@@ -131,12 +138,19 @@ func GetEntities() []any {
&language.Language{},
&personrelative.PersonRelative{},
&patient.Patient{},
&appointment.Appointment{},
&encounter.Encounter{},
&laborant.Laborant{},
&specialist.Specialist{},
&subspecialist.Subspecialist{},
&specialistintern.SpecialistIntern{},
&room.Room{},
&soapi.Soapi{},
&sbar.Sbar{},
&adime.Adime{},
&emergency.Emergency{},
&inpatient.Inpatient{},
&ambulatory.Ambulatory{},
}
}
@@ -0,0 +1,298 @@
package adime
import (
"errors"
"strconv"
e "simrs-vx/internal/domain/main-entities/adime"
ee "simrs-vx/internal/domain/main-entities/employee"
ue "simrs-vx/internal/use-case/main-use-case/employee"
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 = "adime"
func Create(input e.CreateDto) (*d.Data, error) {
data := e.Adime{}
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 !input.AuthInfo.IsDoctor() && !input.AuthInfo.IsNurse() {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "auth-forbidden",
Detail: "user position is not allowed",
Raw: errors.New("authentication failed"),
}
return pl.SetLogError(&event, input)
}
employee, err := ue.ReadDetailData(ee.ReadDetailDto{User_Id: &input.AuthInfo.User_Id}, &event, tx)
if err != nil {
return err
}
input.Employee_Id = &employee.Id
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.Adime
var dataList []e.Adime
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 len(input.Includes) > 0 {
input.Preloads = pu.GetPreloads(input.Includes)
}
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.Adime
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.Adime
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.Adime
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,24 @@
/*
DESCRIPTION:
Any functions that are used internally by the use-case
*/
package adime
import (
e "simrs-vx/internal/domain/main-entities/adime"
)
func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Adime) {
var inputSrc *e.CreateDto
if inputT, ok := any(input).(*e.CreateDto); ok {
inputSrc = inputT
} else {
inputTemp := any(input).(*e.UpdateDto)
inputSrc = &inputTemp.CreateDto
}
data.Encounter_Id = inputSrc.Encounter_Id
data.Employee_Id = inputSrc.Employee_Id
data.Time = inputSrc.Time
data.Value = inputSrc.Value
}
@@ -0,0 +1,155 @@
package adime
import (
e "simrs-vx/internal/domain/main-entities/adime"
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.Adime, error) {
pl.SetLogInfo(event, nil, "started", "DBCreate")
data := e.Adime{}
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.Adime, *e.MetaDto, error) {
pl.SetLogInfo(event, input, "started", "DBReadList")
data := []e.Adime{}
pagination := gh.Pagination{}
count := int64(0)
meta := e.MetaDto{}
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if len(input.Preloads) > 0 {
for _, preload := range input.Preloads {
tx = tx.Preload(preload)
}
}
tx = tx.
Model(&e.Adime{}).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.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.Adime, error) {
pl.SetLogInfo(event, input, "started", "DBReadDetail")
data := e.Adime{}
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.Adime, 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.Adime, 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 adime
import (
e "simrs-vx/internal/domain/main-entities/adime"
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.Adime) 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.Adime) 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.Adime) 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.Adime) 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.Adime) 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 adime
// 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,36 @@
package adime
import (
"gorm.io/gorm"
e "simrs-vx/internal/domain/main-entities/adime"
)
type createMw struct {
Name string
Func func(input *e.CreateDto, data *e.Adime, tx *gorm.DB) error
}
type readListMw struct {
Name string
Func func(input *e.ReadListDto, data *e.Adime, tx *gorm.DB) error
}
type readDetailMw struct {
Name string
Func func(input *e.ReadDetailDto, data *e.Adime, 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,278 @@
package ambulatory
import (
e "simrs-vx/internal/domain/main-entities/ambulatory"
"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 = "ambulatory"
func Create(input e.CreateDto) (*d.Data, error) {
data := e.Ambulatory{}
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.Ambulatory
var dataList []e.Ambulatory
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 len(input.Includes) > 0 {
input.Preloads = pu.GetPreloads(input.Includes)
}
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.Ambulatory
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: uint16(input.Id)}
var data *e.Ambulatory
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: uint16(input.Id)}
var data *e.Ambulatory
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,38 @@
/*
DESCRIPTION:
Any functions that are used internally by the use-case
*/
package ambulatory
import (
"errors"
e "simrs-vx/internal/domain/main-entities/ambulatory"
ere "simrs-vx/internal/domain/references/encounter"
)
func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Ambulatory) {
var inputSrc *e.CreateDto
if inputT, ok := any(input).(*e.CreateDto); ok {
inputSrc = inputT
} else {
inputTemp := any(input).(*e.UpdateDto)
inputSrc = &inputTemp.CreateDto
}
data.Encounter_Id = inputSrc.Encounter_Id
data.Class_Code = inputSrc.Class_Code
}
func CheckClassCode(input *string) (ere.AmbulatoryClassCode, error) {
if input != nil {
subCode := ere.AmbulatoryClassCode(*input)
switch subCode {
case ere.ACCReg, ere.ACCRme:
return subCode, nil
default:
return "", errors.New("unknown sub class code")
}
}
return "", errors.New("sub class code is nil")
}
@@ -0,0 +1,155 @@
package ambulatory
import (
e "simrs-vx/internal/domain/main-entities/ambulatory"
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.Ambulatory, error) {
pl.SetLogInfo(event, nil, "started", "DBCreate")
data := e.Ambulatory{}
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.Ambulatory, *e.MetaDto, error) {
pl.SetLogInfo(event, input, "started", "DBReadList")
data := []e.Ambulatory{}
pagination := gh.Pagination{}
count := int64(0)
meta := e.MetaDto{}
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if len(input.Preloads) > 0 {
for _, preload := range input.Preloads {
tx = tx.Preload(preload)
}
}
tx = tx.
Model(&e.Ambulatory{}).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.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.Ambulatory, error) {
pl.SetLogInfo(event, input, "started", "DBReadDetail")
data := e.Ambulatory{}
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.Ambulatory, 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.Ambulatory, 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 ambulatory
import (
e "simrs-vx/internal/domain/main-entities/ambulatory"
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.Ambulatory) 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.Ambulatory) 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.Ambulatory) 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.Ambulatory) 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.Ambulatory) 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 ambulatory
// 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 ambulatory
import (
"gorm.io/gorm"
e "simrs-vx/internal/domain/main-entities/ambulatory"
)
type createMw struct {
Name string
Func func(input *e.CreateDto, data *e.Ambulatory, tx *gorm.DB) error
}
type readListMw struct {
Name string
Func func(input *e.ReadListDto, data *e.Ambulatory, tx *gorm.DB) error
}
type readDetailMw struct {
Name string
Func func(input *e.ReadDetailDto, data *e.Ambulatory, 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
@@ -16,10 +16,11 @@ import (
a "github.com/karincake/apem"
ms "github.com/karincake/apem/ms-redis"
pa "simrs-vx/pkg/auth-helper"
el "simrs-vx/pkg/logger"
p "simrs-vx/pkg/password"
mu "simrs-vx/internal/domain/main-entities/user"
eu "simrs-vx/internal/domain/main-entities/user"
erc "simrs-vx/internal/domain/references/common"
)
@@ -31,9 +32,9 @@ func init() {
// Generates token and store in redis at one place
// just return the error code
func GenToken(input mu.LoginDto) (*d.Data, error) {
func GenToken(input eu.LoginDto) (*d.Data, error) {
// Get User
user := &mu.User{Name: input.Name}
user := &eu.User{Name: input.Name}
// if input.Position_Code != "" {
// user.Position_Code = input.Position_Code
// }
@@ -94,7 +95,7 @@ func GenToken(input mu.LoginDto) (*d.Data, error) {
atClaims["user_id"] = user.Id
atClaims["user_name"] = user.Name
// atClaims["user_email"] = user.Email
// atClaims["user_position_code"] = user.Position_Code
atClaims["user_position_code"] = user.Position_Code
// atClaims["user_ref_id"] = user.Ref_Id
atClaims["exp"] = atExpires
atClaims["uuid"] = aUuid
@@ -129,7 +130,7 @@ func GenToken(input mu.LoginDto) (*d.Data, error) {
"user_id": strconv.Itoa(int(user.Id)),
"user_name": user.Name,
// "user_email": user.Email,
// "user_position_code": user.Position_Code,
"user_position_code": user.Position_Code,
// "user_ref_id": user.Ref_Id,
"accessToken": ats,
},
@@ -167,7 +168,7 @@ func VerifyToken(r *http.Request, tokenType TokenType) (data *jwt.Token, errCode
return token, "", ""
}
func ExtractToken(r *http.Request, tokenType TokenType) (data *AuthInfo, err error) {
func ExtractToken(r *http.Request, tokenType TokenType) (data *pa.AuthInfo, err error) {
token, errCode, errDetail := VerifyToken(r, tokenType)
if errCode != "" {
return nil, d.FieldError{Code: errCode, Message: el.GenMessage(errCode, errDetail)}
@@ -196,17 +197,17 @@ func ExtractToken(r *http.Request, tokenType TokenType) (data *AuthInfo, err err
// tmp := v.(float64)
// ref_id = int(tmp)
// }
// position_code := ""
// if v, exist := claims["user_position_code"]; exist && v != nil {
// position_code = v.(string)
// }
data = &AuthInfo{
position_code := ""
if v, exist := claims["user_position_code"]; exist && v != nil {
position_code = v.(string)
}
data = &pa.AuthInfo{
Uuid: accessUuid,
User_Id: int(user_id),
User_Id: uint(user_id),
User_Name: user_name,
// User_Email: user_email,
// User_Ref_Id: ref_id,
// User_Position_Code: position_code,
User_Position_Code: position_code,
}
return
}
@@ -5,15 +5,6 @@ type TokenType string
const AccessToken = "Access"
const RefreshToken = "Refresh"
type AuthInfo struct {
Uuid string
User_Id int
User_Name string
// User_Email string
// User_Ref_Id int
// User_Position_Code string
}
type AuthCfg struct {
AtSecretKey string `yaml:"atSecretKey"`
RtSecretKey string `yaml:"rtSecretKey"`
@@ -58,7 +58,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Co
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -64,7 +64,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.De
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -58,7 +58,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Di
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -57,7 +57,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Di
Count(&count).
Scopes(gh.Paginate(input, &pagination))
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -65,7 +65,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Di
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -58,7 +58,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Di
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -64,7 +64,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Do
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -64,7 +64,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Do
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -0,0 +1,278 @@
package emergency
import (
e "simrs-vx/internal/domain/main-entities/emergency"
"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 = "emergency"
func Create(input e.CreateDto) (*d.Data, error) {
data := e.Emergency{}
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.Emergency
var dataList []e.Emergency
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 len(input.Includes) > 0 {
input.Preloads = pu.GetPreloads(input.Includes)
}
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.Emergency
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: uint16(input.Id)}
var data *e.Emergency
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: uint16(input.Id)}
var data *e.Emergency
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,38 @@
/*
DESCRIPTION:
Any functions that are used internally by the use-case
*/
package emergency
import (
"errors"
e "simrs-vx/internal/domain/main-entities/emergency"
ere "simrs-vx/internal/domain/references/encounter"
)
func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Emergency) {
var inputSrc *e.CreateDto
if inputT, ok := any(input).(*e.CreateDto); ok {
inputSrc = inputT
} else {
inputTemp := any(input).(*e.UpdateDto)
inputSrc = &inputTemp.CreateDto
}
data.Encounter_Id = inputSrc.Encounter_Id
data.Class_Code = inputSrc.Class_Code
}
func CheckClassCode(input *string) (ere.EmergencyClassCode, error) {
if input != nil {
subCode := ere.EmergencyClassCode(*input)
switch subCode {
case ere.ECCEmg, ere.ECCEon:
return subCode, nil
default:
return "", errors.New("unknown sub class code")
}
}
return "", errors.New("sub class code is nil")
}
@@ -0,0 +1,155 @@
package emergency
import (
e "simrs-vx/internal/domain/main-entities/emergency"
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.Emergency, error) {
pl.SetLogInfo(event, nil, "started", "DBCreate")
data := e.Emergency{}
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.Emergency, *e.MetaDto, error) {
pl.SetLogInfo(event, input, "started", "DBReadList")
data := []e.Emergency{}
pagination := gh.Pagination{}
count := int64(0)
meta := e.MetaDto{}
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if len(input.Preloads) > 0 {
for _, preload := range input.Preloads {
tx = tx.Preload(preload)
}
}
tx = tx.
Model(&e.Emergency{}).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.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.Emergency, error) {
pl.SetLogInfo(event, input, "started", "DBReadDetail")
data := e.Emergency{}
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.Emergency, 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.Emergency, 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 emergency
import (
e "simrs-vx/internal/domain/main-entities/emergency"
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.Emergency) 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.Emergency) 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.Emergency) 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.Emergency) 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.Emergency) 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 emergency
// 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 emergency
import (
"gorm.io/gorm"
e "simrs-vx/internal/domain/main-entities/emergency"
)
type createMw struct {
Name string
Func func(input *e.CreateDto, data *e.Emergency, tx *gorm.DB) error
}
type readListMw struct {
Name string
Func func(input *e.ReadListDto, data *e.Emergency, tx *gorm.DB) error
}
type readDetailMw struct {
Name string
Func func(input *e.ReadDetailDto, data *e.Emergency, 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
@@ -65,7 +65,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Em
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -0,0 +1,399 @@
package encounter
import (
"errors"
"strconv"
ea "simrs-vx/internal/domain/main-entities/ambulatory"
ee "simrs-vx/internal/domain/main-entities/emergency"
e "simrs-vx/internal/domain/main-entities/encounter"
ei "simrs-vx/internal/domain/main-entities/inpatient"
ua "simrs-vx/internal/use-case/main-use-case/ambulatory"
ue "simrs-vx/internal/use-case/main-use-case/emergency"
ui "simrs-vx/internal/use-case/main-use-case/inpatient"
ere "simrs-vx/internal/domain/references/encounter"
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 = "encounter"
func Create(input e.CreateDto) (*d.Data, error) {
data := e.Encounter{}
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
}
switch input.Class_Code {
case ere.ECAmbulatory:
subCode, err := ua.CheckClassCode(input.SubClass_Code)
if err != nil {
return err
}
ambCreate := ea.CreateDto{
Encounter_Id: &data.Id,
Class_Code: subCode,
}
_, err = ua.CreateData(ambCreate, &event, tx)
if err != nil {
return err
}
case ere.ECEmergency:
subCode, err := ue.CheckClassCode(input.SubClass_Code)
if err != nil {
return err
}
emerCreate := ee.CreateDto{
Encounter_Id: &data.Id,
Class_Code: subCode,
}
_, err = ue.CreateData(emerCreate, &event, tx)
if err != nil {
return err
}
case ere.ECInpatient:
subCode, err := ui.CheckClassCode(input.SubClass_Code)
if err != nil {
return err
}
inpCreate := ei.CreateDto{
Encounter_Id: &data.Id,
Class_Code: subCode,
Infra_Id: input.Infra_Id,
}
_, err = ui.CreateData(inpCreate, &event, tx)
if err != nil {
return err
}
default:
return errors.New("invalid encounter class code")
}
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.Encounter
var dataList []e.Encounter
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 len(input.Includes) > 0 {
input.Preloads = pu.GetPreloads(input.Includes)
}
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.Encounter
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: uint16(input.Id)}
var data *e.Encounter
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
}
if data.IsDone() {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-state-mismatch",
Detail: "encounter is done",
Raw: errors.New("encounter is done"),
}
return pl.SetLogError(&event, input)
}
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: uint16(input.Id)}
var data *e.Encounter
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
}
func CheckOut(input e.DischargeDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: uint16(input.Id)}
var data *e.Encounter
var err error
event := pl.Event{
Feature: "CheckOut",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "checkOut")
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
}
if data.IsDone() {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-state-mismatch",
Detail: "encounter is done",
Raw: errors.New("encounter is done"),
}
return pl.SetLogError(&event, input)
}
if err := checkSoapiByDocExists(data.Id, &event, tx); err != nil {
return err
}
if err := UpdateDischargeData(input, data, &event, tx); err != nil {
return err
}
pl.SetLogInfo(&event, nil, "complete")
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.IS{
"source": source,
"structure": "single-data",
"status": "checkOut",
},
Data: data.ToResponse(),
}, nil
}
@@ -0,0 +1,100 @@
/*
DESCRIPTION:
Any functions that are used internally by the use-case
*/
package encounter
import (
"errors"
e "simrs-vx/internal/domain/main-entities/encounter"
es "simrs-vx/internal/domain/main-entities/soapi"
pl "simrs-vx/pkg/logger"
erc "simrs-vx/internal/domain/references/common"
ero "simrs-vx/internal/domain/references/organization"
"gorm.io/gorm"
)
func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Encounter) {
var inputSrc *e.CreateDto
if inputT, ok := any(input).(*e.CreateDto); ok {
inputSrc = inputT
} else {
inputTemp := any(input).(*e.UpdateDto)
inputSrc = &inputTemp.CreateDto
}
data.Patient_Id = inputSrc.Patient_Id
data.RegisteredAt = inputSrc.RegisteredAt
data.Class_Code = inputSrc.Class_Code
data.Unit_Id = inputSrc.Unit_Id
data.Specialist_Id = inputSrc.Specialist_Id
data.Subspecialist_Id = inputSrc.Subspecialist_Id
data.VisitDate = inputSrc.VisitDate
data.Appointment_Doctor_Id = inputSrc.Appointment_Doctor_Id
data.Responsible_Doctor_Id = inputSrc.Responsible_Doctor_Id
data.RefSource_Name = inputSrc.RefSource_Name
data.Appointment_Id = inputSrc.Appointment_Id
data.Status_Code = erc.DSCNew
}
func setDataUpdate(src e.UpdateDto, dst *e.Encounter) {
dst.Appointment_Doctor_Id = src.Appointment_Doctor_Id
dst.Responsible_Doctor_Id = src.Responsible_Doctor_Id
dst.Unit_Id = src.Unit_Id
dst.Specialist_Id = src.Specialist_Id
dst.Subspecialist_Id = src.Subspecialist_Id
dst.VisitDate = src.VisitDate
}
func setDataDischarge(src e.DischargeDto, dst *e.Encounter) {
dst.DischargeMethod_Code = src.DischargeMethod_Code
dst.EarlyEducation = src.EarlyEducation
dst.MedicalDischargeEducation = src.MedicalDischargeEducation
dst.AdmDischargeEducation = src.AdmDischargeEducation
dst.DischargeReason = src.DischargeReason
dst.Status_Code = erc.DSCDone
}
func checkSoapiByDocExists(encounter_id uint, event *pl.Event, tx *gorm.DB) error {
pl.SetLogInfo(event, nil, "started", "checkSoapiByDocExists")
var soapies []es.Soapi
err := tx.
Preload("Employee").
Preload("Employee.User").
Where("\"Encounter_Id\" = ?", encounter_id).Find(&soapies).Error
if err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-get-fail",
Detail: "get soapi failed",
Raw: err,
}
return pl.SetLogError(event, nil)
}
if len(soapies) == 0 {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-notFound",
Detail: "no soapi found for encounter",
Raw: errors.New("soapi not found"),
}
return pl.SetLogError(event, nil)
}
for _, s := range soapies {
if s.Employee != nil && s.Employee.User != nil && s.Employee.User.Position_Code == ero.UPCDoc {
return nil
}
}
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-update-fail",
Detail: "no soapi written by a doctor found",
Raw: errors.New("all soapi employees are not doctors"),
}
return pl.SetLogError(event, nil)
}
@@ -0,0 +1,180 @@
package encounter
import (
e "simrs-vx/internal/domain/main-entities/encounter"
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.Encounter, error) {
pl.SetLogInfo(event, nil, "started", "DBCreate")
data := e.Encounter{}
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.Encounter, *e.MetaDto, error) {
pl.SetLogInfo(event, input, "started", "DBReadList")
data := []e.Encounter{}
pagination := gh.Pagination{}
count := int64(0)
meta := e.MetaDto{}
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if len(input.Preloads) > 0 {
for _, preload := range input.Preloads {
tx = tx.Preload(preload)
}
}
tx = tx.
Model(&e.Encounter{}).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.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.Encounter, error) {
pl.SetLogInfo(event, input, "started", "DBReadDetail")
data := e.Encounter{}
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.Encounter, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, data, "started", "DBUpdate")
setDataUpdate(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.Encounter, 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
}
func UpdateDischargeData(input e.DischargeDto, data *e.Encounter, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, data, "started", "DBUpdateDischarge")
setDataDischarge(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
}
@@ -0,0 +1,103 @@
package encounter
import (
e "simrs-vx/internal/domain/main-entities/encounter"
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.Encounter) 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.Encounter) 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.Encounter) 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.Encounter) 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.Encounter) 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 encounter
// 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 encounter
import (
"gorm.io/gorm"
e "simrs-vx/internal/domain/main-entities/encounter"
)
type createMw struct {
Name string
Func func(input *e.CreateDto, data *e.Encounter, tx *gorm.DB) error
}
type readListMw struct {
Name string
Func func(input *e.ReadListDto, data *e.Encounter, tx *gorm.DB) error
}
type readDetailMw struct {
Name string
Func func(input *e.ReadDetailDto, data *e.Encounter, 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
@@ -58,7 +58,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Et
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
+1 -1
View File
@@ -64,7 +64,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.In
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -0,0 +1,278 @@
package inpatient
import (
e "simrs-vx/internal/domain/main-entities/inpatient"
"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 = "ambulatory"
func Create(input e.CreateDto) (*d.Data, error) {
data := e.Inpatient{}
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.Inpatient
var dataList []e.Inpatient
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 len(input.Includes) > 0 {
input.Preloads = pu.GetPreloads(input.Includes)
}
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.Inpatient
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: uint16(input.Id)}
var data *e.Inpatient
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: uint16(input.Id)}
var data *e.Inpatient
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,38 @@
/*
DESCRIPTION:
Any functions that are used internally by the use-case
*/
package inpatient
import (
"errors"
e "simrs-vx/internal/domain/main-entities/inpatient"
ere "simrs-vx/internal/domain/references/encounter"
)
func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Inpatient) {
var inputSrc *e.CreateDto
if inputT, ok := any(input).(*e.CreateDto); ok {
inputSrc = inputT
} else {
inputTemp := any(input).(*e.UpdateDto)
inputSrc = &inputTemp.CreateDto
}
data.Encounter_Id = inputSrc.Encounter_Id
data.Class_Code = inputSrc.Class_Code
}
func CheckClassCode(input *string) (ere.InpatientClassCode, error) {
if input != nil {
subCode := ere.InpatientClassCode(*input)
switch subCode {
case ere.ICCHCU, ere.ICCICU, ere.ICCVK, ere.ICCIp:
return subCode, nil
default:
return "", errors.New("unknown sub class code")
}
}
return "", errors.New("sub class code is nil")
}
@@ -0,0 +1,155 @@
package inpatient
import (
e "simrs-vx/internal/domain/main-entities/inpatient"
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.Inpatient, error) {
pl.SetLogInfo(event, nil, "started", "DBCreate")
data := e.Inpatient{}
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.Inpatient, *e.MetaDto, error) {
pl.SetLogInfo(event, input, "started", "DBReadList")
data := []e.Inpatient{}
pagination := gh.Pagination{}
count := int64(0)
meta := e.MetaDto{}
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if len(input.Preloads) > 0 {
for _, preload := range input.Preloads {
tx = tx.Preload(preload)
}
}
tx = tx.
Model(&e.Inpatient{}).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.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.Inpatient, error) {
pl.SetLogInfo(event, input, "started", "DBReadDetail")
data := e.Inpatient{}
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.Inpatient, 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.Inpatient, 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 inpatient
import (
e "simrs-vx/internal/domain/main-entities/inpatient"
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.Inpatient) 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.Inpatient) 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.Inpatient) 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.Inpatient) 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.Inpatient) 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 inpatient
// 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 inpatient
import (
"gorm.io/gorm"
e "simrs-vx/internal/domain/main-entities/inpatient"
)
type createMw struct {
Name string
Func func(input *e.CreateDto, data *e.Inpatient, tx *gorm.DB) error
}
type readListMw struct {
Name string
Func func(input *e.ReadListDto, data *e.Inpatient, tx *gorm.DB) error
}
type readDetailMw struct {
Name string
Func func(input *e.ReadDetailDto, data *e.Inpatient, 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
@@ -58,7 +58,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.In
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -64,7 +64,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.In
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -64,7 +64,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.It
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
+1 -1
View File
@@ -64,7 +64,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.It
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -64,7 +64,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.La
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -58,7 +58,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.La
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -64,7 +64,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Ma
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -58,7 +58,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Mc
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -64,7 +64,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Mc
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -64,7 +64,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Me
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -64,7 +64,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Me
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -58,7 +58,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Me
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -58,7 +58,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Me
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -64,7 +64,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Me
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -58,7 +58,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Me
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -64,7 +64,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Me
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
+1 -1
View File
@@ -64,7 +64,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Nu
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -64,7 +64,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Nu
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -67,7 +67,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Pa
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -58,7 +58,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Pe
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -58,7 +58,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Pe
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -58,7 +58,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Pe
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -67,7 +67,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Pe
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -64,7 +64,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Ph
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -58,7 +58,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Ph
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Debug().Find(&data).Error; err != nil {
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}

Some files were not shown because too many files have changed in this diff Show More