From 7d0f42aba252753507ba2c7c017921a9683be23d Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Thu, 13 Nov 2025 04:30:12 +0700 Subject: [PATCH 01/42] feat/dockerize: added the Dockerfile --- Dockerfile-main-api | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Dockerfile-main-api diff --git a/Dockerfile-main-api b/Dockerfile-main-api new file mode 100644 index 00000000..821cd4a2 --- /dev/null +++ b/Dockerfile-main-api @@ -0,0 +1,12 @@ +FROM golang:1.24.10 AS builder +WORKDIR /src +COPY go.mod go.sum ./ +RUN go mod download +COPY . . +RUN CGO_ENABLED=0 GOOS=linux go build -o ./cmd/main-api/main-api ./cmd/main-api/main.go + +FROM alpine:latest +WORKDIR /app +COPY --from=builder /src/cmd/main-api/main-api . +COPY --from=builder /src/cmd/main-api/config.yml . +CMD ["./main-api"] From b09c9f183c4a34709c004a4253008b4152fae664 Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Fri, 28 Nov 2025 09:16:38 +0700 Subject: [PATCH 02/42] feat/sync-setting: + moved infra/sync-cfg to infra/sync-consumer-cfg + adjut anything related to old infra/sync + infra/sync is now have new setting for the sync --- cmd/main-api/config.yml-example | 8 +-- cmd/simgos-sync-api/config.yml-example | 10 +++- .../authentication/authentication.go | 9 ++++ internal/infra/sync-cfg/sync-cfg.go | 6 +-- internal/infra/sync-cfg/tycovar.go | 14 +++-- internal/infra/sync-consumer-cfg/sync-cfg.go | 15 ++++++ internal/infra/sync-consumer-cfg/tycovar.go | 11 ++++ .../main-handler/authentication/handler.go | 19 +++++++ .../interface/main-handler/main-handler.go | 4 +- .../interface/simgos-sync-handler/old/.keep | 0 .../old/authentication/authentication.go | 52 +++++++++++++++++++ .../simgos-sync-handler.go | 7 ++- internal/lib/sync-credential/helper.go | 23 ++++++++ .../division/middleware-runner.go | 2 +- .../use-case/main-use-case/encounter/case.go | 4 +- .../main-use-case/encounter/helper.go | 2 +- .../encounter/middleware-runner.go | 2 +- .../installation/middleware-runner.go | 2 +- .../patient/middleware-runner.go | 2 +- .../specialist/middleware-runner.go | 2 +- .../subspecialist/middleware-runner.go | 2 +- .../main-use-case/unit/middleware-runner.go | 2 +- .../simgos-sync-plugin/new/division/plugin.go | 4 +- .../new/encounter/plugin.go | 4 +- .../new/installation/plugin.go | 4 +- .../simgos-sync-plugin/new/patient/plugin.go | 4 +- .../new/specialist/plugin.go | 4 +- .../new/subspecialist/plugin.go | 4 +- .../simgos-sync-plugin/new/unit/plugin.go | 4 +- 29 files changed, 187 insertions(+), 39 deletions(-) create mode 100644 internal/domain/sync-entities/authentication/authentication.go create mode 100644 internal/infra/sync-consumer-cfg/sync-cfg.go create mode 100644 internal/infra/sync-consumer-cfg/tycovar.go create mode 100644 internal/interface/simgos-sync-handler/old/.keep create mode 100644 internal/interface/simgos-sync-handler/old/authentication/authentication.go create mode 100644 internal/lib/sync-credential/helper.go diff --git a/cmd/main-api/config.yml-example b/cmd/main-api/config.yml-example index 30351abf..3f5caa33 100644 --- a/cmd/main-api/config.yml-example +++ b/cmd/main-api/config.yml-example @@ -69,9 +69,11 @@ bpjsCfg: baseUrl: syncUrlCfg: - enable: false - host: - prefix: new-to-old + enable: false + targetHost: + prefix: new-to-old + source: new-app + secretKey: new-world-order!! docsCfg: path: ../../assets/docs/ \ No newline at end of file diff --git a/cmd/simgos-sync-api/config.yml-example b/cmd/simgos-sync-api/config.yml-example index 98544958..96e4a6d2 100644 --- a/cmd/simgos-sync-api/config.yml-example +++ b/cmd/simgos-sync-api/config.yml-example @@ -34,4 +34,12 @@ langCfg: corsCfg: allowedOrigin: - allowedMethod: GET, POST, PUT, PATCH, DELETE, OPTIONS \ No newline at end of file + allowedMethod: GET, POST, PUT, PATCH, DELETE, OPTIONS + +syncPartnerCfg: + oldSource + oldSecretKey + oldHost + newSource + newSecretKey + newHost \ No newline at end of file diff --git a/internal/domain/sync-entities/authentication/authentication.go b/internal/domain/sync-entities/authentication/authentication.go new file mode 100644 index 00000000..f2448d9d --- /dev/null +++ b/internal/domain/sync-entities/authentication/authentication.go @@ -0,0 +1,9 @@ +package authentication + +type SyncKey struct{} + +type CredentialDto struct { + Source string `json:"X-Sync-Source"` + SecretKey string `json:"X-Sync-SecretKey"` + UserName string `json:"X-Sync-UserName"` +} diff --git a/internal/infra/sync-cfg/sync-cfg.go b/internal/infra/sync-cfg/sync-cfg.go index a6a5d703..8e0e0f5a 100644 --- a/internal/infra/sync-cfg/sync-cfg.go +++ b/internal/infra/sync-cfg/sync-cfg.go @@ -8,8 +8,8 @@ import ( func SetConfig() { a.ParseSingleCfg(&O) - if O.Host == "" || O.Prefix == "" { - panic("config sync host and prefix empty") + if O.NewSecretKey == "" || O.NewHost == "" || O.OldSecretKey == "" || O.OldHost == "" { + panic("secret key and host of the sync partner config can not be empty") } - lo.I.Println("sync url config loaded, status: DONE!!") + lo.I.Println("sync partner config loaded, status: DONE!!") } diff --git a/internal/infra/sync-cfg/tycovar.go b/internal/infra/sync-cfg/tycovar.go index 6ae230fb..ebc3ca19 100644 --- a/internal/infra/sync-cfg/tycovar.go +++ b/internal/infra/sync-cfg/tycovar.go @@ -1,9 +1,13 @@ package synccfg -var O SyncUrlCfg = SyncUrlCfg{} +var O PartnerCfg = PartnerCfg{} // old -type SyncUrlCfg struct { - Prefix string `yaml:"prefix"` - Host string `yaml:"host"` - Enable bool `yaml:"enable"` +// Used by sync itself, so any partner should be stated here +type PartnerCfg struct { + OldSource string `yaml:"oldSource"` + OldSecretKey string `yaml:"oldSecretKey"` + OldHost string `yaml:"oldHost"` + NewSource string `yaml:"newSource"` + NewSecretKey string `yaml:"newSecretKey"` + NewHost string `yaml:"newHost"` } diff --git a/internal/infra/sync-consumer-cfg/sync-cfg.go b/internal/infra/sync-consumer-cfg/sync-cfg.go new file mode 100644 index 00000000..8ea63dac --- /dev/null +++ b/internal/infra/sync-consumer-cfg/sync-cfg.go @@ -0,0 +1,15 @@ +package synccfg + +import ( + a "github.com/karincake/apem" + lo "github.com/karincake/apem/loggero" +) + +func SetConfig() { + a.ParseSingleCfg(&O) + + if O.TargetHost == "" || O.Prefix == "" { + panic("config sync host and prefix empty") + } + lo.I.Println("sync url config loaded, status: DONE!!") +} diff --git a/internal/infra/sync-consumer-cfg/tycovar.go b/internal/infra/sync-consumer-cfg/tycovar.go new file mode 100644 index 00000000..1a5cba26 --- /dev/null +++ b/internal/infra/sync-consumer-cfg/tycovar.go @@ -0,0 +1,11 @@ +package synccfg + +var O SyncUrlCfg = SyncUrlCfg{} // old + +type SyncUrlCfg struct { + Prefix string `yaml:"prefix"` + TargetHost string `yaml:"targetHost"` + Enable bool `yaml:"enable"` + Source string `yaml:"source"` + SecretKey string `yaml:"secretKey"` +} diff --git a/internal/interface/main-handler/authentication/handler.go b/internal/interface/main-handler/authentication/handler.go index 243ba9cd..f412e482 100644 --- a/internal/interface/main-handler/authentication/handler.go +++ b/internal/interface/main-handler/authentication/handler.go @@ -13,6 +13,8 @@ import ( mf "simrs-vx/internal/domain/main-entities/user-fes" pa "simrs-vx/internal/lib/auth" s "simrs-vx/internal/use-case/main-use-case/authentication" + + esga "simrs-vx/internal/domain/sync-entities/authentication" ) func Login(w http.ResponseWriter, r *http.Request) { @@ -67,6 +69,23 @@ func Logout(w http.ResponseWriter, r *http.Request) { func GuardMW(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Check if it's from sync + credential := esga.CredentialDto{} + credential.Source = r.Header.Get("X-Sync-Source") + credential.SecretKey = r.Header.Get("X-Sync-SecretKey") + credential.UserName = r.Header.Get("X-Sync-UserName") + if credential.Source != "" || credential.SecretKey != "" || credential.UserName != "" { + ctx := context.WithValue(r.Context(), esga.SyncKey{}, credential) + next.ServeHTTP(w, r.WithContext(ctx)) + // TO DO: + // 1 Get user info manually (not by using token), based on credential.UserName + // 2 To cover the point 1, Adjust /use-case/main-use-case/authentication to have the function + // 3 Any DTO that is used in the sync, add flag Sync (tru/false), set it true if it is from sync + + return + } + + // Normal flow goes here accessDetail, err := s.ExtractToken(r, s.AccessToken) if err != nil { rw.WriteJSON(w, http.StatusUnauthorized, err.(d.FieldError), nil) diff --git a/internal/interface/main-handler/main-handler.go b/internal/interface/main-handler/main-handler.go index 7b919e5f..c8f3fd00 100644 --- a/internal/interface/main-handler/main-handler.go +++ b/internal/interface/main-handler/main-handler.go @@ -63,7 +63,7 @@ import ( gs "simrs-vx/internal/infra/gorm-setting" minio "simrs-vx/internal/infra/minio" ssdb "simrs-vx/internal/infra/ss-db" - simgossync "simrs-vx/internal/infra/sync-cfg" + sync "simrs-vx/internal/infra/sync-consumer-cfg" /******************** pkg ********************/ cmw "simrs-vx/pkg/cors-manager-mw" @@ -135,7 +135,7 @@ func SetRoutes() http.Handler { a.RegisterExtCall(mh.I.SetClient) a.RegisterExtCall(ibpjs.SetConfig) a.RegisterExtCall(validation.RegisterValidation) - a.RegisterExtCall(simgossync.SetConfig) + a.RegisterExtCall(sync.SetConfig) a.RegisterExtCall(docscfg.ParseCfg) r := http.NewServeMux() diff --git a/internal/interface/simgos-sync-handler/old/.keep b/internal/interface/simgos-sync-handler/old/.keep new file mode 100644 index 00000000..e69de29b diff --git a/internal/interface/simgos-sync-handler/old/authentication/authentication.go b/internal/interface/simgos-sync-handler/old/authentication/authentication.go new file mode 100644 index 00000000..282e1ea6 --- /dev/null +++ b/internal/interface/simgos-sync-handler/old/authentication/authentication.go @@ -0,0 +1,52 @@ +package authentication + +import ( + "context" + "net/http" + + d "github.com/karincake/dodol" + rw "github.com/karincake/risoles" + + sc "simrs-vx/internal/lib/sync-credential" + + e "simrs-vx/internal/domain/sync-entities/authentication" + is "simrs-vx/internal/infra/sync-cfg" +) + +func NewGuardMW(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // check the data format + input := e.CredentialDto{} + if success := sc.CheckCredentialData(&input, r, w); !success { + return + } + + // check the validity + if input.Source != is.O.NewSource || input.SecretKey != is.O.NewSecretKey { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "invalid consumer credential"}, nil) + return + } + + ctx := context.WithValue(r.Context(), e.SyncKey{}, input) + next.ServeHTTP(w, r.WithContext(ctx)) + }) +} + +func OldGuardMW(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // check the data format + input := e.CredentialDto{} + if success := sc.CheckCredentialData(&input, r, w); !success { + return + } + + // check the validity + if input.Source != is.O.OldSource || input.SecretKey != is.O.OldSecretKey { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "invalid consumer credential"}, nil) + return + } + + ctx := context.WithValue(r.Context(), e.SyncKey{}, input) + next.ServeHTTP(w, r.WithContext(ctx)) + }) +} diff --git a/internal/interface/simgos-sync-handler/simgos-sync-handler.go b/internal/interface/simgos-sync-handler/simgos-sync-handler.go index ccfa6cda..bd675978 100644 --- a/internal/interface/simgos-sync-handler/simgos-sync-handler.go +++ b/internal/interface/simgos-sync-handler/simgos-sync-handler.go @@ -6,6 +6,7 @@ import ( /******************** infra ********************/ gs "simrs-vx/internal/infra/gorm-setting" simgosdb "simrs-vx/internal/infra/simgos-db" + sync "simrs-vx/internal/infra/sync-consumer-cfg" /******************** pkg ********************/ cmw "simrs-vx/pkg/cors-manager-mw" @@ -27,6 +28,8 @@ import ( "simrs-vx/internal/interface/simgos-sync-handler/new/specialist" "simrs-vx/internal/interface/simgos-sync-handler/new/subspecialist" "simrs-vx/internal/interface/simgos-sync-handler/new/unit" + + oauth "simrs-vx/internal/interface/simgos-sync-handler/old/authentication" // just a reminder, an openauth ) func SetRoutes() http.Handler { @@ -34,6 +37,7 @@ func SetRoutes() http.Handler { a.RegisterExtCall(gs.Adjust) a.RegisterExtCall(zlc.Adjust) a.RegisterExtCall(lh.Populate) + a.RegisterExtCall(sync.SetConfig) a.RegisterExtCall(simgosdb.SetInstance) r := http.NewServeMux() @@ -66,7 +70,8 @@ func SetRoutes() http.Handler { }) /******************** SvcToNew ******************/ - //prefixold := "/old-to-new" + prefixold := "/old-to-new" + hk.GroupRoutes(prefixold+"/v1/patient", r, oauth.OldGuardMW, hk.MapHandlerFunc{}) // FINISH THIS return cmw.SetCors(handlerlogger.SetLog(r)) } diff --git a/internal/lib/sync-credential/helper.go b/internal/lib/sync-credential/helper.go new file mode 100644 index 00000000..e6c5952f --- /dev/null +++ b/internal/lib/sync-credential/helper.go @@ -0,0 +1,23 @@ +package authentication + +import ( + "net/http" + + d "github.com/karincake/dodol" + rw "github.com/karincake/risoles" + sr "github.com/karincake/serabi" + + e "simrs-vx/internal/domain/sync-entities/authentication" +) + +func CheckCredentialData(input *e.CredentialDto, r *http.Request, w http.ResponseWriter) bool { + input.Source = r.Header.Get("X-Sync-Source") + input.SecretKey = r.Header.Get("X-Sync-SecretKey") + input.UserName = r.Header.Get("X-Sync-UserName") + if err := sr.Validate(input); err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.II{"errors": err}, nil) + return false + } + return true + +} diff --git a/internal/use-case/main-use-case/division/middleware-runner.go b/internal/use-case/main-use-case/division/middleware-runner.go index 51c90d77..76e1c873 100644 --- a/internal/use-case/main-use-case/division/middleware-runner.go +++ b/internal/use-case/main-use-case/division/middleware-runner.go @@ -6,7 +6,7 @@ import ( "gorm.io/gorm" - sync "simrs-vx/internal/infra/sync-cfg" + sync "simrs-vx/internal/infra/sync-consumer-cfg" e "simrs-vx/internal/domain/main-entities/division" esync "simrs-vx/internal/domain/sync-entities/log" diff --git a/internal/use-case/main-use-case/encounter/case.go b/internal/use-case/main-use-case/encounter/case.go index 25d74859..438ad45c 100644 --- a/internal/use-case/main-use-case/encounter/case.go +++ b/internal/use-case/main-use-case/encounter/case.go @@ -834,7 +834,7 @@ func RequestSwitchUnit(input e.SwitchUnitDto) (*d.Data, error) { event.Status = "failed" event.ErrInfo = pl.ErrorInfo{ Code: "missing-soapi", - Detail: fmt.Sprintf("Missing soapi from latest responsible doctor"), + Detail: "Missing soapi from latest responsible doctor", } return pl.SetLogError(&event, input) } @@ -919,7 +919,7 @@ func ApproveSwitchUnit(input e.ApproveUnitDto) (*d.Data, error) { event.Status = "failed" event.ErrInfo = pl.ErrorInfo{ Code: "missing-soapi", - Detail: fmt.Sprintf("Missing soapi from latest responsible doctor"), + Detail: "Missing soapi from latest responsible doctor", } return pl.SetLogError(&event, input) } diff --git a/internal/use-case/main-use-case/encounter/helper.go b/internal/use-case/main-use-case/encounter/helper.go index 3b215c36..ff4e0af1 100644 --- a/internal/use-case/main-use-case/encounter/helper.go +++ b/internal/use-case/main-use-case/encounter/helper.go @@ -601,7 +601,7 @@ func getSoapiEncounterAdm(enc e.Encounter, event *pl.Event) (dataSoapi []es.Crea event.Status = "failed" event.ErrInfo = pl.ErrorInfo{ Code: "missing-soapi", - Detail: fmt.Sprintf("Missing required Soapi types"), + Detail: "Missing required Soapi types", } return nil, pl.SetLogError(event, enc) } diff --git a/internal/use-case/main-use-case/encounter/middleware-runner.go b/internal/use-case/main-use-case/encounter/middleware-runner.go index ef1cb283..1837c42e 100644 --- a/internal/use-case/main-use-case/encounter/middleware-runner.go +++ b/internal/use-case/main-use-case/encounter/middleware-runner.go @@ -6,7 +6,7 @@ import ( "gorm.io/gorm" - sync "simrs-vx/internal/infra/sync-cfg" + sync "simrs-vx/internal/infra/sync-consumer-cfg" e "simrs-vx/internal/domain/main-entities/encounter" esync "simrs-vx/internal/domain/sync-entities/log" diff --git a/internal/use-case/main-use-case/installation/middleware-runner.go b/internal/use-case/main-use-case/installation/middleware-runner.go index b85e3236..b2ff8cb4 100644 --- a/internal/use-case/main-use-case/installation/middleware-runner.go +++ b/internal/use-case/main-use-case/installation/middleware-runner.go @@ -6,7 +6,7 @@ import ( "gorm.io/gorm" - sync "simrs-vx/internal/infra/sync-cfg" + sync "simrs-vx/internal/infra/sync-consumer-cfg" e "simrs-vx/internal/domain/main-entities/installation" esync "simrs-vx/internal/domain/sync-entities/log" diff --git a/internal/use-case/main-use-case/patient/middleware-runner.go b/internal/use-case/main-use-case/patient/middleware-runner.go index 1ea1623d..0e085514 100644 --- a/internal/use-case/main-use-case/patient/middleware-runner.go +++ b/internal/use-case/main-use-case/patient/middleware-runner.go @@ -6,7 +6,7 @@ import ( "gorm.io/gorm" - sync "simrs-vx/internal/infra/sync-cfg" + sync "simrs-vx/internal/infra/sync-consumer-cfg" e "simrs-vx/internal/domain/main-entities/patient" esync "simrs-vx/internal/domain/sync-entities/log" diff --git a/internal/use-case/main-use-case/specialist/middleware-runner.go b/internal/use-case/main-use-case/specialist/middleware-runner.go index 9a10d624..e2799b61 100644 --- a/internal/use-case/main-use-case/specialist/middleware-runner.go +++ b/internal/use-case/main-use-case/specialist/middleware-runner.go @@ -6,7 +6,7 @@ import ( "gorm.io/gorm" - sync "simrs-vx/internal/infra/sync-cfg" + sync "simrs-vx/internal/infra/sync-consumer-cfg" e "simrs-vx/internal/domain/main-entities/specialist" esync "simrs-vx/internal/domain/sync-entities/log" diff --git a/internal/use-case/main-use-case/subspecialist/middleware-runner.go b/internal/use-case/main-use-case/subspecialist/middleware-runner.go index ad1eba08..3e5c0dce 100644 --- a/internal/use-case/main-use-case/subspecialist/middleware-runner.go +++ b/internal/use-case/main-use-case/subspecialist/middleware-runner.go @@ -6,7 +6,7 @@ import ( "gorm.io/gorm" - sync "simrs-vx/internal/infra/sync-cfg" + sync "simrs-vx/internal/infra/sync-consumer-cfg" e "simrs-vx/internal/domain/main-entities/subspecialist" esync "simrs-vx/internal/domain/sync-entities/log" diff --git a/internal/use-case/main-use-case/unit/middleware-runner.go b/internal/use-case/main-use-case/unit/middleware-runner.go index 979548bc..a02bb9cf 100644 --- a/internal/use-case/main-use-case/unit/middleware-runner.go +++ b/internal/use-case/main-use-case/unit/middleware-runner.go @@ -6,7 +6,7 @@ import ( "gorm.io/gorm" - sync "simrs-vx/internal/infra/sync-cfg" + sync "simrs-vx/internal/infra/sync-consumer-cfg" e "simrs-vx/internal/domain/main-entities/unit" esync "simrs-vx/internal/domain/sync-entities/log" diff --git a/internal/use-case/simgos-sync-plugin/new/division/plugin.go b/internal/use-case/simgos-sync-plugin/new/division/plugin.go index 54c1403c..b67f19d6 100644 --- a/internal/use-case/simgos-sync-plugin/new/division/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/division/plugin.go @@ -7,7 +7,7 @@ import ( "io" "net/http" - sync "simrs-vx/internal/infra/sync-cfg" + sync "simrs-vx/internal/infra/sync-consumer-cfg" e "simrs-vx/internal/domain/main-entities/division" elog "simrs-vx/internal/domain/sync-entities/log" @@ -163,5 +163,5 @@ func Delete(input *e.DeleteDto) error { } func getPrefixEndpoint() string { - return fmt.Sprintf("%s%s/v1/division", sync.O.Host, sync.O.Prefix) + return fmt.Sprintf("%s%s/v1/division", sync.O.TargetHost, sync.O.Prefix) } diff --git a/internal/use-case/simgos-sync-plugin/new/encounter/plugin.go b/internal/use-case/simgos-sync-plugin/new/encounter/plugin.go index 617f2e93..bba5da31 100644 --- a/internal/use-case/simgos-sync-plugin/new/encounter/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/encounter/plugin.go @@ -2,7 +2,7 @@ package encounter import ( "fmt" - sync "simrs-vx/internal/infra/sync-cfg" + sync "simrs-vx/internal/infra/sync-consumer-cfg" helper "simrs-vx/internal/use-case/simgos-sync-plugin/new" e "simrs-vx/internal/domain/main-entities/encounter" @@ -50,5 +50,5 @@ func Cancel(input *e.Encounter) error { } func getPrefixEndpoint() string { - return fmt.Sprintf("%s%s/v1/encounter", sync.O.Host, sync.O.Prefix) + return fmt.Sprintf("%s%s/v1/encounter", sync.O.TargetHost, sync.O.Prefix) } diff --git a/internal/use-case/simgos-sync-plugin/new/installation/plugin.go b/internal/use-case/simgos-sync-plugin/new/installation/plugin.go index f2495139..6f1c12d6 100644 --- a/internal/use-case/simgos-sync-plugin/new/installation/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/installation/plugin.go @@ -7,7 +7,7 @@ import ( "io" "net/http" - sync "simrs-vx/internal/infra/sync-cfg" + sync "simrs-vx/internal/infra/sync-consumer-cfg" e "simrs-vx/internal/domain/main-entities/installation" elog "simrs-vx/internal/domain/sync-entities/log" @@ -163,5 +163,5 @@ func Delete(input *e.DeleteDto) error { } func getPrefixEndpoint() string { - return fmt.Sprintf("%s%s/v1/installation", sync.O.Host, sync.O.Prefix) + return fmt.Sprintf("%s%s/v1/installation", sync.O.TargetHost, sync.O.Prefix) } diff --git a/internal/use-case/simgos-sync-plugin/new/patient/plugin.go b/internal/use-case/simgos-sync-plugin/new/patient/plugin.go index 309e1d18..6f03299a 100644 --- a/internal/use-case/simgos-sync-plugin/new/patient/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/patient/plugin.go @@ -9,7 +9,7 @@ import ( d "github.com/karincake/dodol" - sync "simrs-vx/internal/infra/sync-cfg" + sync "simrs-vx/internal/infra/sync-consumer-cfg" e "simrs-vx/internal/domain/main-entities/patient" elog "simrs-vx/internal/domain/sync-entities/log" @@ -203,5 +203,5 @@ func GenerateNomrPatient() (*string, error) { } func getPrefixEndpoint() string { - return fmt.Sprintf("%s%s/v1/patient", sync.O.Host, sync.O.Prefix) + return fmt.Sprintf("%s%s/v1/patient", sync.O.TargetHost, sync.O.Prefix) } diff --git a/internal/use-case/simgos-sync-plugin/new/specialist/plugin.go b/internal/use-case/simgos-sync-plugin/new/specialist/plugin.go index 892d7a17..370a66dd 100644 --- a/internal/use-case/simgos-sync-plugin/new/specialist/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/specialist/plugin.go @@ -7,7 +7,7 @@ import ( "io" "net/http" - sync "simrs-vx/internal/infra/sync-cfg" + sync "simrs-vx/internal/infra/sync-consumer-cfg" e "simrs-vx/internal/domain/main-entities/specialist" elog "simrs-vx/internal/domain/sync-entities/log" @@ -163,5 +163,5 @@ func Delete(input *e.DeleteDto) error { } func getPrefixEndpoint() string { - return fmt.Sprintf("%s%s/v1/specialist", sync.O.Host, sync.O.Prefix) + return fmt.Sprintf("%s%s/v1/specialist", sync.O.TargetHost, sync.O.Prefix) } diff --git a/internal/use-case/simgos-sync-plugin/new/subspecialist/plugin.go b/internal/use-case/simgos-sync-plugin/new/subspecialist/plugin.go index 15d6f650..5fa831d1 100644 --- a/internal/use-case/simgos-sync-plugin/new/subspecialist/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/subspecialist/plugin.go @@ -7,7 +7,7 @@ import ( "io" "net/http" - sync "simrs-vx/internal/infra/sync-cfg" + sync "simrs-vx/internal/infra/sync-consumer-cfg" e "simrs-vx/internal/domain/main-entities/subspecialist" elog "simrs-vx/internal/domain/sync-entities/log" @@ -163,5 +163,5 @@ func Delete(input *e.DeleteDto) error { } func getPrefixEndpoint() string { - return fmt.Sprintf("%s%s/v1/subspecialist", sync.O.Host, sync.O.Prefix) + return fmt.Sprintf("%s%s/v1/subspecialist", sync.O.TargetHost, sync.O.Prefix) } diff --git a/internal/use-case/simgos-sync-plugin/new/unit/plugin.go b/internal/use-case/simgos-sync-plugin/new/unit/plugin.go index e854d898..36d240b5 100644 --- a/internal/use-case/simgos-sync-plugin/new/unit/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/unit/plugin.go @@ -7,7 +7,7 @@ import ( "io" "net/http" - sync "simrs-vx/internal/infra/sync-cfg" + sync "simrs-vx/internal/infra/sync-consumer-cfg" e "simrs-vx/internal/domain/main-entities/unit" elog "simrs-vx/internal/domain/sync-entities/log" @@ -163,5 +163,5 @@ func Delete(input *e.DeleteDto) error { } func getPrefixEndpoint() string { - return fmt.Sprintf("%s%s/v1/unit", sync.O.Host, sync.O.Prefix) + return fmt.Sprintf("%s%s/v1/unit", sync.O.TargetHost, sync.O.Prefix) } From 1cc8702109a2f5cb03fb99066cd3999ca5fd0bab Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Fri, 28 Nov 2025 10:00:29 +0700 Subject: [PATCH 03/42] feat/sync-setting: TODO to get credential --- .../main-handler/authentication/handler.go | 13 +++++++------ internal/lib/auth/tycovar.go | 1 + .../use-case/main-use-case/authentication/case.go | 6 ++++++ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/internal/interface/main-handler/authentication/handler.go b/internal/interface/main-handler/authentication/handler.go index f412e482..f0625af7 100644 --- a/internal/interface/main-handler/authentication/handler.go +++ b/internal/interface/main-handler/authentication/handler.go @@ -75,13 +75,14 @@ func GuardMW(next http.Handler) http.Handler { credential.SecretKey = r.Header.Get("X-Sync-SecretKey") credential.UserName = r.Header.Get("X-Sync-UserName") if credential.Source != "" || credential.SecretKey != "" || credential.UserName != "" { - ctx := context.WithValue(r.Context(), esga.SyncKey{}, credential) + // TODO: ngecall fungsi untuk dapat dari DB menlengkapi authinfo + accessDetail, err := s.GetAuthInfoByUserName(credential.UserName) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, err.(d.FieldError), nil) + return + } + ctx := context.WithValue(r.Context(), pa.AuthKey{}, accessDetail) next.ServeHTTP(w, r.WithContext(ctx)) - // TO DO: - // 1 Get user info manually (not by using token), based on credential.UserName - // 2 To cover the point 1, Adjust /use-case/main-use-case/authentication to have the function - // 3 Any DTO that is used in the sync, add flag Sync (tru/false), set it true if it is from sync - return } diff --git a/internal/lib/auth/tycovar.go b/internal/lib/auth/tycovar.go index 117d0c73..0ce3b0fc 100644 --- a/internal/lib/auth/tycovar.go +++ b/internal/lib/auth/tycovar.go @@ -22,6 +22,7 @@ type AuthInfo struct { Pharmachist_Code *string Intern_Position_Code *string Roles []string + Sync bool // User_DivisionPositions []DivisionPosition } diff --git a/internal/use-case/main-use-case/authentication/case.go b/internal/use-case/main-use-case/authentication/case.go index db83d315..2f47c43d 100644 --- a/internal/use-case/main-use-case/authentication/case.go +++ b/internal/use-case/main-use-case/authentication/case.go @@ -179,6 +179,12 @@ func VerifyToken(r *http.Request, tokenType TokenType) (data *jwt.Token, errCode return token, "", "" } +func GetAuthInfoByUserName(userName string) (data *pa.AuthInfo, err error) { + // disini isi var `data` + // return error jika terjadi apa2 + return +} + func ExtractToken(r *http.Request, tokenType TokenType) (data *pa.AuthInfo, err error) { token, errCode, errDetail := VerifyToken(r, tokenType) if errCode != "" { From 856bcd8f3d1e60a259d36be7938c3f3d32c288c9 Mon Sep 17 00:00:00 2001 From: poetrasapoetra Date: Fri, 28 Nov 2025 12:53:44 +0700 Subject: [PATCH 04/42] Sync old-to-new patient handler --- .../domain/simgos-entities/patient/dto.go | 273 ++++++++++++++++++ .../old/patient/handler.go | 88 ++++++ .../simgos-sync-handler.go | 5 + 3 files changed, 366 insertions(+) create mode 100644 internal/domain/simgos-entities/patient/dto.go create mode 100644 internal/interface/simgos-sync-handler/old/patient/handler.go diff --git a/internal/domain/simgos-entities/patient/dto.go b/internal/domain/simgos-entities/patient/dto.go new file mode 100644 index 00000000..77fe7449 --- /dev/null +++ b/internal/domain/simgos-entities/patient/dto.go @@ -0,0 +1,273 @@ +package patient + +import ( + "fmt" + e "simrs-vx/internal/domain/main-entities/patient" + pr "simrs-vx/internal/domain/main-entities/person" + pa "simrs-vx/internal/domain/main-entities/person-address" + pc "simrs-vx/internal/domain/main-entities/person-contact" + cm "simrs-vx/internal/domain/references/common" + rf "simrs-vx/internal/domain/references/person" + + "time" +) + +type MPasienDto struct { + Id uint `json:"id" gorm:"primaryKey;autoIncrement;column:id"` + Nomr string `json:"nomr" gorm:"uniqueIndex;column:nomr"` + Title string `json:"title" gorm:"column:title"` + Nama string `json:"nama" gorm:"column:nama"` + Tempat string `json:"tempat" gorm:"column:tempat"` + Tgllahir string `json:"tgllahir" gorm:"column:tgllahir"` + Jeniskelamin string `json:"jeniskelamin" gorm:"column:jeniskelamin"` + Alamat string `json:"alamat" gorm:"column:alamat"` + Kelurahan uint64 `json:"kelurahan" gorm:"column:kelurahan"` + Kdkecamatan uint `json:"kdkecamatan" gorm:"column:kdkecamatan"` + Kota uint `json:"kota" gorm:"column:kota"` + Kdprovinsi uint `json:"kdprovinsi" gorm:"column:kdprovinsi"` + Notelp string `json:"notelp" gorm:"column:notelp"` + Noktp string `json:"noktp" gorm:"column:noktp"` + SuamiOrtu *string `json:"suami_ortu" gorm:"column:suami_ortu"` + Pekerjaan string `json:"pekerjaan" gorm:"column:pekerjaan"` + Status uint `json:"status" gorm:"column:status"` + Agama uint `json:"agama" gorm:"column:agama"` + Pendidikan uint `json:"pendidikan" gorm:"column:pendidikan"` + Kdcarabayar *uint `json:"kdcarabayar" gorm:"column:kdcarabayar"` + Nip *string `json:"nip" gorm:"column:nip"` + Tgldaftar string `json:"tgldaftar" gorm:"column:tgldaftar"` + AlamatKtp string `json:"alamat_ktp" gorm:"column:alamat_ktp"` + ParentNomr *string `json:"parent_nomr" gorm:"column:parent_nomr"` + Kepercayaan string `json:"kepercayaan" gorm:"column:kepercayaan"` + PenanggungjawabNama string `json:"penanggungjawab_nama" gorm:"column:penanggungjawab_nama"` + PenanggungjawabHubungan string `json:"penanggungjawab_hubungan" gorm:"column:penanggungjawab_hubungan"` + PenanggungjawabAlamat string `json:"penanggungjawab_alamat" gorm:"column:penanggungjawab_alamat"` + PenanggungjawabPhone string `json:"penanggungjawab_phone" gorm:"column:penanggungjawab_phone"` + NoKartu string `json:"no_kartu" gorm:"column:no_kartu"` + JnsPasien string `json:"jns_pasien" gorm:"column:jns_pasien"` + Nk *string `json:"nk" gorm:"column:nk"` + Kdprovider *string `json:"kdprovider" gorm:"column:kdprovider"` + Nmprovider *string `json:"nmprovider" gorm:"column:nmprovider"` + Kelas *uint `json:"kelas" gorm:"column:kelas"` + Sim *string `json:"sim" gorm:"column:sim"` + Paspor *string `json:"paspor" gorm:"column:paspor"` + Disabilitas *string `json:"disabilitas" gorm:"column:disabilitas"` + Bahasa string `json:"bahasa" gorm:"column:bahasa"` + HambatanKomunikasi string `json:"hambatan_komunikasi" gorm:"column:hambatan_komunikasi"` + Kebangsaan string `json:"kebangsaan" gorm:"column:kebangsaan"` + Notelprumah1 string `json:"notelprumah1" gorm:"column:notelprumah1"` + Notelprumah2 *string `json:"notelprumah2" gorm:"column:notelprumah2"` + Notelpkantor string `json:"notelpkantor" gorm:"column:notelpkantor"` + NoHp *string `json:"no_hp" gorm:"column:no_hp"` + AsalMasuk *string `json:"asal_masuk" gorm:"column:asal_masuk"` + Diagnosa *string `json:"diagnosa" gorm:"column:diagnosa"` + DiagnosaUtama *string `json:"diagnosa_utama" gorm:"column:diagnosa_utama"` + Suku string `json:"suku" gorm:"column:suku"` + AgamaLain string `json:"agama_lain" gorm:"column:agama_lain"` + StDisabilitas uint `json:"stDisabilitas" gorm:"column:st_disabilitas"` + TxtKelurahan string `json:"txt_kelurahan" gorm:"column:txt_kelurahan"` + TxtKecamatan string `json:"txt_kecamatan" gorm:"column:txt_kecamatan"` + TxtKota string `json:"txt_kota" gorm:"column:txt_kota"` + TxtProvinsi string `json:"txt_provinsi" gorm:"column:txt_provinsi"` + TxtStatus string `json:"txt_status" gorm:"column:txt_status"` + TxtAgama string `json:"txt_agama" gorm:"column:txt_agama"` + TxtPendidikan string `json:"txt_pendidikan" gorm:"column:txt_pendidikan"` + NamaAyah string `json:"nama_ayah" gorm:"column:nama_ayah"` + NamaIbu string `json:"nama_ibu" gorm:"column:nama_ibu"` + PendidikanAyah string `json:"pendidikan_ayah" gorm:"column:pendidikan_ayah"` + PendidikanIbu string `json:"pendidikan_ibu" gorm:"column:pendidikan_ibu"` + StIdentitasOrtu int `json:"st_identitas_ortu" gorm:"column:st_identitas_ortu"` + NomrBaru *string `json:"nomr_baru" gorm:"column:nomr_baru"` + KtpFile *string `json:"ktp_file" gorm:"column:ktp_file"` + KkFile *string `json:"kk_file" gorm:"column:kk_file"` + CreatedAt *time.Time `json:"created_at" gorm:"column:created_at"` + UpdatedAt *time.Time `json:"updated_at" gorm:"column:updated_at"` + NoKk *string `json:"no_kk" gorm:"column:no_kk"` + NoktpBaru string `json:"noktp_baru" gorm:"column:noktp_baru"` +} + +func (mp MPasienDto) ToPatient() e.Patient { + + patient := e.Patient{ + Person_Id: &mp.Id, + NewBornStatus: mp.ParentNomr != nil, + RegisteredAt: parseTimeDateOnly(mp.Tgldaftar), + RegisteredBy_User_Name: mp.Nip, + Number: &mp.Nomr, + Parent_Number: mp.ParentNomr, + // Status_Code: getActiveStatus(mp.Status), + // mp.Status is marital status + // Parent + } + + // person + gc := getGender(mp.Jeniskelamin) + rc := getReligion(mp.Agama) + ec := getEducation(mp.Pendidikan) + mc := getMaritalStatus(mp.Status) + bc := getBirthRegencyCode(mp.Tempat) + et := getEthnicCode(mp.Suku) + lc := getLanguageCode(mp.Bahasa) + + person := pr.Person{ + Name: mp.Nama, + FrontTitle: &mp.Title, + BirthDate: parseTimeDateOnly(mp.Tgllahir), + BirthRegency_Code: &bc, + Gender_Code: &gc, + ResidentIdentityNumber: nilEmptyString(*mp.Nip), + PassportNumber: nilEmptyString(*mp.Paspor), + DrivingLicenseNumber: nilEmptyString(*mp.Sim), + Religion_Code: &rc, + Education_Code: &ec, + Ocupation_Name: &mp.Pekerjaan, + MaritalStatus_Code: &mc, + Nationality: &mp.Kebangsaan, + Ethnic_Code: &et, + Language_Code: &lc, + CommunicationIssueStatus: mp.HambatanKomunikasi == "Y", + Disability: mp.Disabilitas, + ResidentIdentityFileUrl: mp.KtpFile, + FamilyIdentityFileUrl: mp.KkFile, + // EndTitle + // Confidence + // Ocupation_Code + } + var addresses []pa.PersonAddress + if mp.Alamat != "" { + vc := fmt.Sprintf("%d", mp.Kelurahan) + addresses = append(addresses, pa.PersonAddress{ + Address: mp.Alamat, + LocationType_Code: rf.ALTCDom, + Village_Code: &vc, + }) + } + if mp.AlamatKtp != "" { + addresses = append(addresses, pa.PersonAddress{ + Address: mp.AlamatKtp, + LocationType_Code: rf.ALTCIdn, + }) + } + + var contacts []pc.PersonContact + + if mp.NoHp != nil { + + } + + person.Addresses = &addresses + person.Contacts = &contacts + patient.Person = &person + return patient +} + +func getActiveStatus(s uint) cm.ActiveStatusCode { + if s == 1 { + return cm.SCActive + } + return cm.SCInactive +} + +func nilEmptyString(s string) *string { + if s == "" { + return nil + } + return &s +} + +func getGender(g string) rf.GenderCode { + if g == "L" { + return rf.GCMale + } else if g == "P" { + return rf.GCFemale + } + return rf.GCUnknown + +} + +func getReligion(r uint) rf.ReligionCode { + switch r { + case 1: + return rf.RCIslam + case 2: + return rf.RCProtestan + case 3: + return rf.RCKatolik + case 4: + return rf.RCHindu + case 5: + return rf.RCBudha + case 6: + return rf.RCKonghucu + default: + // 9 "Lainnya" + // 0 "Tidak diketahui" + return "" + } +} + +func getEducation(e uint) rf.EducationCode { + switch e { + case 0: + return rf.ECTS + case 1: + return rf.ECSD + case 2: + return rf.ECSLTP + case 3: + return rf.ECSLTA + case 4: + return rf.ECD3 + case 5: + return rf.ECS1 + case 6: + return rf.ECOther + case 7: + return rf.ECUnkown + default: + return rf.ECUnkown + } +} + +func getMaritalStatus(m uint) rf.MaritalStatusCode { + switch m { + case 1: + return rf.MaritalStatusSingle // S + case 2: + return rf.MaritalStatusMarried // M + case 3: + return rf.MaritalStatusWidowed // W + case 4: + return rf.MaritalStatusDivorced // D + default: + return "" // unknown + } +} + +func getBirthRegencyCode(r string) string { + if r != "" { + // TODO get from database + } + return "3574" +} + +func getEthnicCode(s string) string { + if s != "" { + // TODO check database + } + return "jawa" +} + +func getLanguageCode(s string) string { + if s != "" { + // TODO check database + } + return "jawa" +} + +func parseTimeDateOnly(d string) *time.Time { + do, err := time.Parse("2006-01-02", d) + if err == nil { + return &do + } + return nil +} diff --git a/internal/interface/simgos-sync-handler/old/patient/handler.go b/internal/interface/simgos-sync-handler/old/patient/handler.go new file mode 100644 index 00000000..970111e0 --- /dev/null +++ b/internal/interface/simgos-sync-handler/old/patient/handler.go @@ -0,0 +1,88 @@ +package patient + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + + rw "github.com/karincake/risoles" + + p "simrs-vx/internal/domain/simgos-entities/patient" +) + +type myBase struct{} + +var O myBase + +const baseUrl string = "http://localhost:8000/v1/" + +func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { + dto := p.MPasienDto{} + if !rw.ValidateStructByIOR(w, r.Body, &dto) { + return + } + // translate m_pasien ke Patient + patient := dto.ToPatient() + jsonPatient, err := json.Marshal(patient) + if err != nil { + fmt.Println(err) + } + // fmt.Println(string(jsonPatient)) + // kirim request ke api sim-baru + reqBody := bytes.NewBuffer(jsonPatient) + err = send(http.MethodPost, baseUrl+"patient", reqBody) + if err != nil { + fmt.Println("request error:", err) + } + +} +func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { + dto := p.MPasienDto{} + if !rw.ValidateStructByIOR(w, r.Body, &dto) { + return + } + patient := dto.ToPatient() + jsonPatient, err := json.Marshal(patient) + if err != nil { + fmt.Println(err) + } + reqBody := bytes.NewBuffer(jsonPatient) + err = send(http.MethodPatch, fmt.Sprintf("%s%s%v", baseUrl, "patient/", patient.Id), reqBody) + if err != nil { + fmt.Println("request error:", err) + } +} +func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { + dto := p.MPasienDto{} + if !rw.ValidateStructByIOR(w, r.Body, &dto) { + return + } + patient := dto.ToPatient() + jsonPatient, err := json.Marshal(patient) + if err != nil { + fmt.Println(err) + } + reqBody := bytes.NewBuffer(jsonPatient) + err = send(http.MethodDelete, fmt.Sprintf("%s%s%v", baseUrl, "patient/", patient.Id), reqBody) + if err != nil { + fmt.Println("request error:", err) + } +} +func (obj myBase) CreateLog(w http.ResponseWriter, r *http.Request) { + +} + +func send(method string, url string, body *bytes.Buffer) error { + req, err := http.NewRequest(method, url, body) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + return nil +} diff --git a/internal/interface/simgos-sync-handler/simgos-sync-handler.go b/internal/interface/simgos-sync-handler/simgos-sync-handler.go index 2a67b7e9..a23e110c 100644 --- a/internal/interface/simgos-sync-handler/simgos-sync-handler.go +++ b/internal/interface/simgos-sync-handler/simgos-sync-handler.go @@ -8,6 +8,7 @@ import ( /******************** infra ********************/ gs "simrs-vx/internal/infra/gorm-setting" simgosdb "simrs-vx/internal/infra/simgos-db" + /******************** pkg ********************/ cmw "simrs-vx/pkg/cors-manager-mw" lh "simrs-vx/pkg/lang-helper" @@ -20,6 +21,7 @@ import ( "simrs-vx/internal/interface/main-handler/home" division "simrs-vx/internal/interface/simgos-sync-handler/division" installation "simrs-vx/internal/interface/simgos-sync-handler/installation" + oldPatient "simrs-vx/internal/interface/simgos-sync-handler/old/patient" patient "simrs-vx/internal/interface/simgos-sync-handler/patient" specialist "simrs-vx/internal/interface/simgos-sync-handler/specialist" subspecialist "simrs-vx/internal/interface/simgos-sync-handler/subspecialist" @@ -48,5 +50,8 @@ func SetRoutes() http.Handler { hc.SyncCrud(r, prefix+"/v1/patient", patient.O) r.HandleFunc(fmt.Sprintf("GET %s/v1/patient-nomr-generator", prefix), patient.O.GenerateNomr) + /*********** Source old-to-new ****************/ + oldPrefix := "/old-to-new" + hc.SyncCrud(r, oldPrefix+"/v1/patient", oldPatient.O) return cmw.SetCors(handlerlogger.SetLog(r)) } From 708bceccdd61348279ed83a6bd4477c7bd29f5af Mon Sep 17 00:00:00 2001 From: vanilia Date: Fri, 28 Nov 2025 16:43:01 +0700 Subject: [PATCH 05/42] validate auth from old app and fill auth info --- cmd/main-api/config.yml-example | 3 +- internal/infra/sync-cfg/tycovar.go | 4 +- internal/infra/sync-consumer-cfg/tycovar.go | 5 +- .../main-handler/authentication/handler.go | 36 +++-- .../simgos-sync-handler.go | 2 +- .../main-use-case/authentication/case.go | 4 +- .../main-use-case/authentication/helper.go | 73 ++++++++- .../simgos-sync-plugin/new/division/plugin.go | 140 +----------------- .../new/installation/plugin.go | 140 +----------------- .../simgos-sync-plugin/new/patient/plugin.go | 135 +---------------- .../new/specialist/plugin.go | 140 +----------------- .../new/subspecialist/plugin.go | 140 +----------------- .../simgos-sync-plugin/new/unit/plugin.go | 140 +----------------- .../new/encounter/helper.go | 4 +- pkg/dualtrx-helper/dualtrx-helper.go | 5 +- 15 files changed, 138 insertions(+), 833 deletions(-) diff --git a/cmd/main-api/config.yml-example b/cmd/main-api/config.yml-example index 3f5caa33..5915c46c 100644 --- a/cmd/main-api/config.yml-example +++ b/cmd/main-api/config.yml-example @@ -72,7 +72,8 @@ syncUrlCfg: enable: false targetHost: prefix: new-to-old - source: new-app + oldSource: new-app + newSource: new-app secretKey: new-world-order!! docsCfg: diff --git a/internal/infra/sync-cfg/tycovar.go b/internal/infra/sync-cfg/tycovar.go index ebc3ca19..a7534f82 100644 --- a/internal/infra/sync-cfg/tycovar.go +++ b/internal/infra/sync-cfg/tycovar.go @@ -1,9 +1,9 @@ package synccfg -var O PartnerCfg = PartnerCfg{} // old +var O SyncPartnerCfg = SyncPartnerCfg{} // old // Used by sync itself, so any partner should be stated here -type PartnerCfg struct { +type SyncPartnerCfg struct { OldSource string `yaml:"oldSource"` OldSecretKey string `yaml:"oldSecretKey"` OldHost string `yaml:"oldHost"` diff --git a/internal/infra/sync-consumer-cfg/tycovar.go b/internal/infra/sync-consumer-cfg/tycovar.go index 1a5cba26..f60cc588 100644 --- a/internal/infra/sync-consumer-cfg/tycovar.go +++ b/internal/infra/sync-consumer-cfg/tycovar.go @@ -1,11 +1,12 @@ package synccfg -var O SyncUrlCfg = SyncUrlCfg{} // old +var O SyncUrlCfg = SyncUrlCfg{} // new type SyncUrlCfg struct { Prefix string `yaml:"prefix"` TargetHost string `yaml:"targetHost"` Enable bool `yaml:"enable"` - Source string `yaml:"source"` + OldSource string `yaml:"oldSource"` + NewSource string `yaml:"newSource"` SecretKey string `yaml:"secretKey"` } diff --git a/internal/interface/main-handler/authentication/handler.go b/internal/interface/main-handler/authentication/handler.go index f0625af7..ffaf145b 100644 --- a/internal/interface/main-handler/authentication/handler.go +++ b/internal/interface/main-handler/authentication/handler.go @@ -9,12 +9,13 @@ import ( sp "github.com/karincake/semprit" sr "github.com/karincake/serabi" + is "simrs-vx/internal/infra/sync-consumer-cfg" + pa "simrs-vx/internal/lib/auth" + m "simrs-vx/internal/domain/main-entities/user" mf "simrs-vx/internal/domain/main-entities/user-fes" - pa "simrs-vx/internal/lib/auth" - s "simrs-vx/internal/use-case/main-use-case/authentication" - esga "simrs-vx/internal/domain/sync-entities/authentication" + s "simrs-vx/internal/use-case/main-use-case/authentication" ) func Login(w http.ResponseWriter, r *http.Request) { @@ -68,6 +69,10 @@ func Logout(w http.ResponseWriter, r *http.Request) { } func GuardMW(next http.Handler) http.Handler { + var ( + accessDetail *pa.AuthInfo + err error + ) return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Check if it's from sync credential := esga.CredentialDto{} @@ -75,23 +80,26 @@ func GuardMW(next http.Handler) http.Handler { credential.SecretKey = r.Header.Get("X-Sync-SecretKey") credential.UserName = r.Header.Get("X-Sync-UserName") if credential.Source != "" || credential.SecretKey != "" || credential.UserName != "" { - // TODO: ngecall fungsi untuk dapat dari DB menlengkapi authinfo - accessDetail, err := s.GetAuthInfoByUserName(credential.UserName) + // validate secretKey and source + if credential.SecretKey != is.O.SecretKey || credential.Source != is.O.OldSource { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "invalid consumer credential"}, nil) + return + } + + accessDetail, err = s.GetAuthInfoByUserName(credential.UserName) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, err.(d.FieldError), nil) + return + } + } else { + // Normal flow goes here + accessDetail, err = s.ExtractToken(r, s.AccessToken) if err != nil { rw.WriteJSON(w, http.StatusUnauthorized, err.(d.FieldError), nil) return } - ctx := context.WithValue(r.Context(), pa.AuthKey{}, accessDetail) - next.ServeHTTP(w, r.WithContext(ctx)) - return } - // Normal flow goes here - accessDetail, err := s.ExtractToken(r, s.AccessToken) - if err != nil { - rw.WriteJSON(w, http.StatusUnauthorized, err.(d.FieldError), nil) - return - } ctx := context.WithValue(r.Context(), pa.AuthKey{}, accessDetail) next.ServeHTTP(w, r.WithContext(ctx)) }) diff --git a/internal/interface/simgos-sync-handler/simgos-sync-handler.go b/internal/interface/simgos-sync-handler/simgos-sync-handler.go index 81b1c48b..f120b1cb 100644 --- a/internal/interface/simgos-sync-handler/simgos-sync-handler.go +++ b/internal/interface/simgos-sync-handler/simgos-sync-handler.go @@ -6,7 +6,7 @@ import ( /******************** infra ********************/ gs "simrs-vx/internal/infra/gorm-setting" simgosdb "simrs-vx/internal/infra/simgos-db" - sync "simrs-vx/internal/infra/sync-consumer-cfg" + sync "simrs-vx/internal/infra/sync-cfg" /******************** pkg ********************/ cmw "simrs-vx/pkg/cors-manager-mw" diff --git a/internal/use-case/main-use-case/authentication/case.go b/internal/use-case/main-use-case/authentication/case.go index 2f47c43d..04a88c9b 100644 --- a/internal/use-case/main-use-case/authentication/case.go +++ b/internal/use-case/main-use-case/authentication/case.go @@ -180,9 +180,7 @@ func VerifyToken(r *http.Request, tokenType TokenType) (data *jwt.Token, errCode } func GetAuthInfoByUserName(userName string) (data *pa.AuthInfo, err error) { - // disini isi var `data` - // return error jika terjadi apa2 - return + return getAuthByUserName(userName) } func ExtractToken(r *http.Request, tokenType TokenType) (data *pa.AuthInfo, err error) { diff --git a/internal/use-case/main-use-case/authentication/helper.go b/internal/use-case/main-use-case/authentication/helper.go index 7af3afa5..d8c54751 100644 --- a/internal/use-case/main-use-case/authentication/helper.go +++ b/internal/use-case/main-use-case/authentication/helper.go @@ -2,6 +2,7 @@ package authentication import ( "fmt" + pa "simrs-vx/internal/lib/auth" "strconv" "time" @@ -10,10 +11,13 @@ import ( dg "github.com/karincake/apem/db-gorm-pg" ms "github.com/karincake/apem/ms-redis" d "github.com/karincake/dodol" + gh "github.com/karincake/getuk" l "github.com/karincake/lepet" pl "simrs-vx/pkg/logger" + erg "simrs-vx/internal/domain/references/organization" + edp "simrs-vx/internal/domain/main-entities/division-position" ed "simrs-vx/internal/domain/main-entities/doctor" ee "simrs-vx/internal/domain/main-entities/employee" @@ -26,7 +30,6 @@ import ( essp "simrs-vx/internal/domain/main-entities/subspecialist-position" eup "simrs-vx/internal/domain/main-entities/unit-position" eu "simrs-vx/internal/domain/main-entities/user" - erg "simrs-vx/internal/domain/references/organization" udp "simrs-vx/internal/use-case/main-use-case/division-position" uip "simrs-vx/internal/use-case/main-use-case/installation-position" @@ -334,3 +337,71 @@ func populateRoles(user *eu.User, input eu.LoginDto, atClaims jwt.MapClaims, out return nil } + +func getAuthByUserName(username string) (auth *pa.AuthInfo, err error) { + // get employee + emp := ee.Employee{} + if err = dg.I. + Joins(`JOIN "User" u ON u."Id" = "Employee"."User_Id"`). + Where(`u."Name" = ?`, username). + Scopes(gh.Preload("User")). + First(&emp).Error; err != nil { + return nil, err + } + + auth = &pa.AuthInfo{ + User_Id: *emp.User_Id, + User_Name: emp.User.Name, + User_ContractPosition_Code: string(emp.User.ContractPosition_Code), + Employee_Position_Code: strPtr(string(*emp.Position_Code)), + Employee_Id: &emp.Id, + Sync: true, + } + + // set map table + tableMap := map[erg.EmployeePositionCode]string{ + erg.EPCDoc: "Doctor", + erg.EPCNur: "Nurse", + erg.EPCMwi: "Midwife", + erg.EPCNut: "Nutritionist", + erg.EPCLab: "Laborant", + erg.EPCPha: "Pharmachist", + } + + table := tableMap[*emp.Position_Code] + if table == "" { + return + } + + type CodeResult struct { + Code string + } + var result CodeResult + + err = dg.I.Table(table). + Select("Code"). + Where("\"Employee_Id\" = ?", emp.Id). + First(&result).Error + if err != nil { + return nil, err + } + + // set map for code + setterMap := map[erg.EmployeePositionCode]func(string){ + erg.EPCDoc: func(v string) { auth.Doctor_Code = &v }, + erg.EPCNur: func(v string) { auth.Nurse_Code = &v }, + erg.EPCMwi: func(v string) { auth.Midwife_Code = &v }, + erg.EPCNut: func(v string) { auth.Nutritionist_Code = &v }, + erg.EPCLab: func(v string) { auth.Laborant_Code = &v }, + erg.EPCPha: func(v string) { auth.Pharmachist_Code = &v }, + } + + setter := setterMap[*emp.Position_Code] + setter(result.Code) + + return +} + +func strPtr(s string) *string { + return &s +} diff --git a/internal/use-case/simgos-sync-plugin/new/division/plugin.go b/internal/use-case/simgos-sync-plugin/new/division/plugin.go index b67f19d6..f4d6a34b 100644 --- a/internal/use-case/simgos-sync-plugin/new/division/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/division/plugin.go @@ -1,165 +1,35 @@ package division import ( - "bytes" - "encoding/json" "fmt" - "io" - "net/http" + helper "simrs-vx/internal/use-case/simgos-sync-plugin/new" sync "simrs-vx/internal/infra/sync-consumer-cfg" e "simrs-vx/internal/domain/main-entities/division" elog "simrs-vx/internal/domain/sync-entities/log" - - d "github.com/karincake/dodol" ) func Create(input *e.CreateDto) error { - endpoint := getPrefixEndpoint() - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", getPrefixEndpoint()) } func CreateLog(input *elog.SimxLogDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := prefixEndpoint + "/log" - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", endpoint) } func Update(input *e.UpdateDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, *input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("PATCH", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "PATCH", endpoint) } func Delete(input *e.DeleteDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, *input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("DELETE", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "DELETE", endpoint) } func getPrefixEndpoint() string { diff --git a/internal/use-case/simgos-sync-plugin/new/installation/plugin.go b/internal/use-case/simgos-sync-plugin/new/installation/plugin.go index 6f1c12d6..40f0c153 100644 --- a/internal/use-case/simgos-sync-plugin/new/installation/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/installation/plugin.go @@ -1,165 +1,35 @@ package installation import ( - "bytes" - "encoding/json" "fmt" - "io" - "net/http" sync "simrs-vx/internal/infra/sync-consumer-cfg" + helper "simrs-vx/internal/use-case/simgos-sync-plugin/new" e "simrs-vx/internal/domain/main-entities/installation" elog "simrs-vx/internal/domain/sync-entities/log" - - d "github.com/karincake/dodol" ) func Create(input *e.CreateDto) error { - endpoint := getPrefixEndpoint() - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", getPrefixEndpoint()) } func CreateLog(input *elog.SimxLogDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := prefixEndpoint + "/log" - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", endpoint) } func Update(input *e.UpdateDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, *input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("PATCH", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "PATCH", endpoint) } func Delete(input *e.DeleteDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, *input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("DELETE", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "DELETE", endpoint) } func getPrefixEndpoint() string { diff --git a/internal/use-case/simgos-sync-plugin/new/patient/plugin.go b/internal/use-case/simgos-sync-plugin/new/patient/plugin.go index 6f03299a..7678da47 100644 --- a/internal/use-case/simgos-sync-plugin/new/patient/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/patient/plugin.go @@ -1,11 +1,11 @@ package patient import ( - "bytes" "encoding/json" "fmt" "io" "net/http" + helper "simrs-vx/internal/use-case/simgos-sync-plugin/new" d "github.com/karincake/dodol" @@ -16,150 +16,25 @@ import ( ) func Create(input *e.Patient) error { - endpoint := getPrefixEndpoint() - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", getPrefixEndpoint()) } func CreateLog(input *elog.SimxLogDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := prefixEndpoint + "/log" - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", endpoint) } func Update(input *e.Patient) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("PATCH", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "PATCH", endpoint) } func Delete(input *e.DeleteDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("DELETE", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "DELETE", endpoint) } func GenerateNomrPatient() (*string, error) { diff --git a/internal/use-case/simgos-sync-plugin/new/specialist/plugin.go b/internal/use-case/simgos-sync-plugin/new/specialist/plugin.go index 370a66dd..29da9d0a 100644 --- a/internal/use-case/simgos-sync-plugin/new/specialist/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/specialist/plugin.go @@ -1,165 +1,35 @@ package specialist import ( - "bytes" - "encoding/json" "fmt" - "io" - "net/http" + helper "simrs-vx/internal/use-case/simgos-sync-plugin/new" sync "simrs-vx/internal/infra/sync-consumer-cfg" e "simrs-vx/internal/domain/main-entities/specialist" elog "simrs-vx/internal/domain/sync-entities/log" - - d "github.com/karincake/dodol" ) func Create(input *e.CreateDto) error { - endpoint := getPrefixEndpoint() - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", getPrefixEndpoint()) } func CreateLog(input *elog.SimxLogDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := prefixEndpoint + "/log" - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", endpoint) } func Update(input *e.UpdateDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, *input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("PATCH", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "PATCH", endpoint) } func Delete(input *e.DeleteDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, *input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("DELETE", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "DELETE", endpoint) } func getPrefixEndpoint() string { diff --git a/internal/use-case/simgos-sync-plugin/new/subspecialist/plugin.go b/internal/use-case/simgos-sync-plugin/new/subspecialist/plugin.go index 5fa831d1..0167936c 100644 --- a/internal/use-case/simgos-sync-plugin/new/subspecialist/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/subspecialist/plugin.go @@ -1,165 +1,35 @@ package subspecialist import ( - "bytes" - "encoding/json" "fmt" - "io" - "net/http" + helper "simrs-vx/internal/use-case/simgos-sync-plugin/new" sync "simrs-vx/internal/infra/sync-consumer-cfg" e "simrs-vx/internal/domain/main-entities/subspecialist" elog "simrs-vx/internal/domain/sync-entities/log" - - d "github.com/karincake/dodol" ) func Create(input *e.CreateDto) error { - endpoint := getPrefixEndpoint() - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", getPrefixEndpoint()) } func CreateLog(input *elog.SimxLogDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := prefixEndpoint + "/log" - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", endpoint) } func Update(input *e.UpdateDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, *input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("PATCH", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "PATCH", endpoint) } func Delete(input *e.DeleteDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, *input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("DELETE", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "DELETE", endpoint) } func getPrefixEndpoint() string { diff --git a/internal/use-case/simgos-sync-plugin/new/unit/plugin.go b/internal/use-case/simgos-sync-plugin/new/unit/plugin.go index 36d240b5..f646f450 100644 --- a/internal/use-case/simgos-sync-plugin/new/unit/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/unit/plugin.go @@ -1,165 +1,35 @@ package unit import ( - "bytes" - "encoding/json" "fmt" - "io" - "net/http" + helper "simrs-vx/internal/use-case/simgos-sync-plugin/new" sync "simrs-vx/internal/infra/sync-consumer-cfg" e "simrs-vx/internal/domain/main-entities/unit" elog "simrs-vx/internal/domain/sync-entities/log" - - d "github.com/karincake/dodol" ) func Create(input *e.CreateDto) error { - endpoint := getPrefixEndpoint() - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", getPrefixEndpoint()) } func CreateLog(input *elog.SimxLogDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := prefixEndpoint + "/log" - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", endpoint) } func Update(input *e.UpdateDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, *input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("PATCH", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "PATCH", endpoint) } func Delete(input *e.DeleteDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, *input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("DELETE", endpoint, bytes.NewReader(jsonData)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "DELETE", endpoint) } func getPrefixEndpoint() string { diff --git a/internal/use-case/simgos-sync-use-case/new/encounter/helper.go b/internal/use-case/simgos-sync-use-case/new/encounter/helper.go index bbbc8687..3a190d56 100644 --- a/internal/use-case/simgos-sync-use-case/new/encounter/helper.go +++ b/internal/use-case/simgos-sync-use-case/new/encounter/helper.go @@ -381,9 +381,7 @@ func updatePatientCaraBayar(input etp.TPendaftaran, event *pl.Event, dbx ...*gor if err := tx.Model(&ep.MPasien{}). Where("\"nomr\" = ?", input.Nomr). - Updates(map[string]interface{}{ - "kdcarabayar": input.Kdcarabayar, - }).Error; err != nil { + Update("kdcarabayar", input.Kdcarabayar).Error; err != nil { event.Status = "failed" event.ErrInfo = pl.ErrorInfo{ Code: "update-fail", diff --git a/pkg/dualtrx-helper/dualtrx-helper.go b/pkg/dualtrx-helper/dualtrx-helper.go index 2f16203c..144337c5 100644 --- a/pkg/dualtrx-helper/dualtrx-helper.go +++ b/pkg/dualtrx-helper/dualtrx-helper.go @@ -11,9 +11,12 @@ type Dualtx struct { } func NewDualtx() *Dualtx { + simgosTx := dg.IS["simrs"].Begin() + simgosTx.Exec(`SET LOCAL simx.sync_source = 'new'`) + return &Dualtx{ Sync: dg.I.Begin(), - Simgos: dg.IS["simrs"].Begin(), + Simgos: simgosTx, } } From 0decd8330a178933a3a5e5bb79563b553baa87ee Mon Sep 17 00:00:00 2001 From: poetrasapoetra Date: Fri, 28 Nov 2025 17:26:58 +0700 Subject: [PATCH 06/42] Change Address --- internal/domain/simgos-entities/m-pasien/dto.go | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/internal/domain/simgos-entities/m-pasien/dto.go b/internal/domain/simgos-entities/m-pasien/dto.go index 77fe7449..b117655d 100644 --- a/internal/domain/simgos-entities/m-pasien/dto.go +++ b/internal/domain/simgos-entities/m-pasien/dto.go @@ -1,10 +1,11 @@ -package patient +package m_pasien import ( "fmt" e "simrs-vx/internal/domain/main-entities/patient" pr "simrs-vx/internal/domain/main-entities/person" pa "simrs-vx/internal/domain/main-entities/person-address" + pab "simrs-vx/internal/domain/main-entities/person-address/base" pc "simrs-vx/internal/domain/main-entities/person-contact" cm "simrs-vx/internal/domain/references/common" rf "simrs-vx/internal/domain/references/person" @@ -136,15 +137,19 @@ func (mp MPasienDto) ToPatient() e.Patient { if mp.Alamat != "" { vc := fmt.Sprintf("%d", mp.Kelurahan) addresses = append(addresses, pa.PersonAddress{ - Address: mp.Alamat, - LocationType_Code: rf.ALTCDom, - Village_Code: &vc, + PersonAddress: pab.PersonAddress{ + Address: mp.Alamat, + LocationType_Code: rf.ALTCDom, + Village_Code: &vc, + }, }) } if mp.AlamatKtp != "" { addresses = append(addresses, pa.PersonAddress{ - Address: mp.AlamatKtp, - LocationType_Code: rf.ALTCIdn, + PersonAddress: pab.PersonAddress{ + Address: mp.AlamatKtp, + LocationType_Code: rf.ALTCIdn, + }, }) } From af6ff9294801d0386b398a0a6c91e7df26b20bdc Mon Sep 17 00:00:00 2001 From: poetrasapoetra Date: Fri, 28 Nov 2025 17:29:12 +0700 Subject: [PATCH 07/42] Add header to handler --- .../simgos-sync-handler/old/patient/handler.go | 14 ++++++++++---- .../simgos-sync-handler/simgos-sync-handler.go | 10 ++++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/internal/interface/simgos-sync-handler/old/patient/handler.go b/internal/interface/simgos-sync-handler/old/patient/handler.go index 970111e0..44d202a9 100644 --- a/internal/interface/simgos-sync-handler/old/patient/handler.go +++ b/internal/interface/simgos-sync-handler/old/patient/handler.go @@ -6,9 +6,10 @@ import ( "fmt" "net/http" - rw "github.com/karincake/risoles" + p "simrs-vx/internal/domain/simgos-entities/m-pasien" + cfg "simrs-vx/internal/infra/sync-cfg" - p "simrs-vx/internal/domain/simgos-entities/patient" + rw "github.com/karincake/risoles" ) type myBase struct{} @@ -47,8 +48,11 @@ func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { if err != nil { fmt.Println(err) } + // fmt.Println(string(jsonPatient)) + url := fmt.Sprintf("%s%s%v", baseUrl, "patient/", *patient.Person_Id) + fmt.Println(url) reqBody := bytes.NewBuffer(jsonPatient) - err = send(http.MethodPatch, fmt.Sprintf("%s%s%v", baseUrl, "patient/", patient.Id), reqBody) + err = send(http.MethodPatch, url, reqBody) if err != nil { fmt.Println("request error:", err) } @@ -64,7 +68,7 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { fmt.Println(err) } reqBody := bytes.NewBuffer(jsonPatient) - err = send(http.MethodDelete, fmt.Sprintf("%s%s%v", baseUrl, "patient/", patient.Id), reqBody) + err = send(http.MethodDelete, fmt.Sprintf("%s%s%v", baseUrl, "patient/", *patient.Person_Id), reqBody) if err != nil { fmt.Println("request error:", err) } @@ -79,6 +83,8 @@ func send(method string, url string, body *bytes.Buffer) error { return err } req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Sync-Source", cfg.O.OldSource) + req.Header.Set("X-Sync-SecretKey", cfg.O.NewSecretKey) resp, err := http.DefaultClient.Do(req) if err != nil { return err diff --git a/internal/interface/simgos-sync-handler/simgos-sync-handler.go b/internal/interface/simgos-sync-handler/simgos-sync-handler.go index 17b5bd1e..7d7887f0 100644 --- a/internal/interface/simgos-sync-handler/simgos-sync-handler.go +++ b/internal/interface/simgos-sync-handler/simgos-sync-handler.go @@ -6,7 +6,7 @@ import ( /******************** infra ********************/ gs "simrs-vx/internal/infra/gorm-setting" simgosdb "simrs-vx/internal/infra/simgos-db" - sync "simrs-vx/internal/infra/sync-consumer-cfg" + sync "simrs-vx/internal/infra/sync-cfg" /******************** pkg ********************/ cmw "simrs-vx/pkg/cors-manager-mw" @@ -29,6 +29,8 @@ import ( "simrs-vx/internal/interface/simgos-sync-handler/new/subspecialist" "simrs-vx/internal/interface/simgos-sync-handler/new/unit" + oldpatient "simrs-vx/internal/interface/simgos-sync-handler/old/patient" + oauth "simrs-vx/internal/interface/simgos-sync-handler/old/authentication" // just a reminder, an openauth ) @@ -71,6 +73,10 @@ func SetRoutes() http.Handler { /******************** SvcToNew ******************/ prefixold := "/old-to-new" - hk.GroupRoutes(prefixold+"/v1/patient", r, oauth.OldGuardMW, hk.MapHandlerFunc{}) // FINISH THIS + hk.GroupRoutes(prefixold+"/v1/patient", r, oauth.OldGuardMW, hk.MapHandlerFunc{ + "POST /": oldpatient.O.Create, + "PATCH /{id}": oldpatient.O.Update, + "DELETE /{id}": oldpatient.O.Delete, + }) // FINISH THIS return cmw.SetCors(handlerlogger.SetLog(r)) } From 6a49f09180bb7a0f11182f6ebf784a975539b024 Mon Sep 17 00:00:00 2001 From: poetrasapoetra Date: Fri, 28 Nov 2025 19:43:53 +0700 Subject: [PATCH 08/42] Fix update patient --- .../domain/simgos-entities/m-pasien/dto.go | 3 +- .../old/patient/handler.go | 28 +++++++++++++------ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/internal/domain/simgos-entities/m-pasien/dto.go b/internal/domain/simgos-entities/m-pasien/dto.go index b117655d..68a2d068 100644 --- a/internal/domain/simgos-entities/m-pasien/dto.go +++ b/internal/domain/simgos-entities/m-pasien/dto.go @@ -89,6 +89,7 @@ type MPasienDto struct { func (mp MPasienDto) ToPatient() e.Patient { patient := e.Patient{ + // TODO get patient person_id from database Person_Id: &mp.Id, NewBornStatus: mp.ParentNomr != nil, RegisteredAt: parseTimeDateOnly(mp.Tgldaftar), @@ -115,7 +116,7 @@ func (mp MPasienDto) ToPatient() e.Patient { BirthDate: parseTimeDateOnly(mp.Tgllahir), BirthRegency_Code: &bc, Gender_Code: &gc, - ResidentIdentityNumber: nilEmptyString(*mp.Nip), + ResidentIdentityNumber: nilEmptyString(mp.Noktp), PassportNumber: nilEmptyString(*mp.Paspor), DrivingLicenseNumber: nilEmptyString(*mp.Sim), Religion_Code: &rc, diff --git a/internal/interface/simgos-sync-handler/old/patient/handler.go b/internal/interface/simgos-sync-handler/old/patient/handler.go index 44d202a9..b794de07 100644 --- a/internal/interface/simgos-sync-handler/old/patient/handler.go +++ b/internal/interface/simgos-sync-handler/old/patient/handler.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "fmt" + "io" "net/http" p "simrs-vx/internal/domain/simgos-entities/m-pasien" @@ -16,8 +17,6 @@ type myBase struct{} var O myBase -const baseUrl string = "http://localhost:8000/v1/" - func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { dto := p.MPasienDto{} if !rw.ValidateStructByIOR(w, r.Body, &dto) { @@ -32,7 +31,7 @@ func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { // fmt.Println(string(jsonPatient)) // kirim request ke api sim-baru reqBody := bytes.NewBuffer(jsonPatient) - err = send(http.MethodPost, baseUrl+"patient", reqBody) + err = send(http.MethodPost, "patient", reqBody) if err != nil { fmt.Println("request error:", err) } @@ -44,12 +43,21 @@ func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { return } patient := dto.ToPatient() - jsonPatient, err := json.Marshal(patient) + // TODO DELETE BELOW, + var ( + personId uint = 68 + patientId uint = 34 + ) + patient.Person_Id = &personId + patient.Id = patientId + patient.Person.Id = personId + // TODO DELETE ABOVE + jsonPatient, err := json.MarshalIndent(patient, "", " ") if err != nil { fmt.Println(err) } - // fmt.Println(string(jsonPatient)) - url := fmt.Sprintf("%s%s%v", baseUrl, "patient/", *patient.Person_Id) + fmt.Println(string(jsonPatient)) + url := fmt.Sprintf("%s%v", "patient/", patient.Id) fmt.Println(url) reqBody := bytes.NewBuffer(jsonPatient) err = send(http.MethodPatch, url, reqBody) @@ -68,7 +76,7 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { fmt.Println(err) } reqBody := bytes.NewBuffer(jsonPatient) - err = send(http.MethodDelete, fmt.Sprintf("%s%s%v", baseUrl, "patient/", *patient.Person_Id), reqBody) + err = send(http.MethodDelete, fmt.Sprintf("%s%v", "patient/", *patient.Person_Id), reqBody) if err != nil { fmt.Println("request error:", err) } @@ -77,7 +85,8 @@ func (obj myBase) CreateLog(w http.ResponseWriter, r *http.Request) { } -func send(method string, url string, body *bytes.Buffer) error { +func send(method string, endpoint string, body *bytes.Buffer) error { + var url string = cfg.O.NewHost + endpoint req, err := http.NewRequest(method, url, body) if err != nil { return err @@ -85,10 +94,13 @@ func send(method string, url string, body *bytes.Buffer) error { req.Header.Set("Content-Type", "application/json") req.Header.Set("X-Sync-Source", cfg.O.OldSource) req.Header.Set("X-Sync-SecretKey", cfg.O.NewSecretKey) + req.Header.Set("X-Sync-UserName", "dave") resp, err := http.DefaultClient.Do(req) if err != nil { return err } defer resp.Body.Close() + respBody, _ := io.ReadAll(resp.Body) + fmt.Println(resp.StatusCode, string(respBody), method, url) return nil } From 721b549e59ee772da472f75a1a7ad4fb9c24a2c7 Mon Sep 17 00:00:00 2001 From: vanilia Date: Mon, 1 Dec 2025 12:33:13 +0700 Subject: [PATCH 09/42] update entity encounter and apply sync from old source --- .../domain/main-entities/encounter/dto.go | 55 +++++++----- internal/domain/main-entities/patient/dto.go | 1 + .../interface/main-handler/patient/handler.go | 16 ++++ .../use-case/main-use-case/encounter/case.go | 47 ++-------- .../main-use-case/encounter/helper.go | 89 ++++++++++++------- .../use-case/main-use-case/encounter/lib.go | 9 +- .../encounter/middleware-runner.go | 9 +- .../use-case/main-use-case/patient/case.go | 35 +------- .../patient/middleware-runner.go | 9 +- 9 files changed, 141 insertions(+), 129 deletions(-) diff --git a/internal/domain/main-entities/encounter/dto.go b/internal/domain/main-entities/encounter/dto.go index 8dd9a0a1..a2551ab7 100644 --- a/internal/domain/main-entities/encounter/dto.go +++ b/internal/domain/main-entities/encounter/dto.go @@ -34,28 +34,39 @@ import ( ) type CreateDto struct { - 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_Code *string `json:"infra_code"` // for inpatient - Unit_Code *string `json:"unit_code"` - Specialist_Code *string `json:"specialist_code"` - Subspecialist_Code *string `json:"subspecialist_code"` - VisitDate time.Time `json:"visitDate"` - PaymentMethod_Code ere.AllPaymentMethodCode `json:"paymentMethod_code" gorm:"size:10"` - InsuranceCompany_Code *string `json:"insuranceCompany_code"` - Member_Number *string `json:"member_number" validate:"maxLength=20"` - Ref_Number *string `json:"ref_number" validate:"maxLength=20"` - Trx_Number *string `json:"trx_number" validate:"maxLength=20"` - Appointment_Doctor_Code *string `json:"appointment_doctor_code"` - Adm_Employee_Id *uint `json:"-"` - Responsible_Doctor_Code *string `json:"responsible_doctor_code"` - RefSource_Name *string `json:"refSource_name" validate:"maxLength=100"` - Appointment_Id *uint `json:"appointment_id"` - RefTypeCode ere.RefTypeCode `json:"refTypeCode"` - NewStatus bool `json:"newStatus"` - VclaimReference *TRujukan `json:"vclaimReference"` + 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_Code *string `json:"infra_code"` // for inpatient + Unit_Code *string `json:"unit_code"` + Specialist_Code *string `json:"specialist_code"` + Subspecialist_Code *string `json:"subspecialist_code"` + VisitDate time.Time `json:"visitDate"` + StartedAt *time.Time `json:"startedAt"` + FinishedAt *time.Time `json:"finishedAt"` + PaymentMethod_Code ere.AllPaymentMethodCode `json:"paymentMethod_code" gorm:"size:10"` + InsuranceCompany_Code *string `json:"insuranceCompany_code"` + Member_Number *string `json:"member_number" validate:"maxLength=20"` + RefTypeCode ere.RefTypeCode `json:"refTypeCode"` + Ref_Number *string `json:"ref_number" validate:"maxLength=20"` + Trx_Number *string `json:"trx_number" validate:"maxLength=20"` + Appointment_Doctor_Code *string `json:"appointment_doctor_code"` + Adm_Employee_Id *uint `json:"-"` + Responsible_Doctor_Code *string `json:"responsible_doctor_code"` + Responsible_Nurse_Code *string `json:"responsible_nurse_code"` + Discharge_Method_Code *ere.DischargeMethodCode `json:"discharge_method_code" gorm:"size:16"` + 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"` + Status_Code erc.DataStatusCode `json:"status_code" gorm:"size:10"` + Discharge_Date *time.Time `json:"discharge_date"` + DeathCause *edc.DeathCause `json:"deathCause"` + NewStatus bool `json:"newStatus"` + VclaimReference *TRujukan `json:"vclaimReference"` Id uint `json:"-"` RecentEncounterAdm *Encounter `json:"-"` // if subClass_Code is rehab diff --git a/internal/domain/main-entities/patient/dto.go b/internal/domain/main-entities/patient/dto.go index 6418c6ac..248a7164 100644 --- a/internal/domain/main-entities/patient/dto.go +++ b/internal/domain/main-entities/patient/dto.go @@ -60,6 +60,7 @@ type UpdateDto struct { type DeleteDto struct { Id uint `json:"id"` + pa.AuthInfo } type SearchDto struct { diff --git a/internal/interface/main-handler/patient/handler.go b/internal/interface/main-handler/patient/handler.go index 41fca562..653a06cc 100644 --- a/internal/interface/main-handler/patient/handler.go +++ b/internal/interface/main-handler/patient/handler.go @@ -63,7 +63,15 @@ func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { return } + + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + dto.Id = uint(id) + dto.AuthInfo = *authInfo + res, err := u.Update(dto) rw.DataResponse(w, res, err) } @@ -75,7 +83,15 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { } dto := e.DeleteDto{} + + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + dto.Id = uint(id) + dto.AuthInfo = *authInfo + res, err := u.Delete(dto) rw.DataResponse(w, res, err) } diff --git a/internal/use-case/main-use-case/encounter/case.go b/internal/use-case/main-use-case/encounter/case.go index bc4ba1ba..19c9da70 100644 --- a/internal/use-case/main-use-case/encounter/case.go +++ b/internal/use-case/main-use-case/encounter/case.go @@ -94,7 +94,7 @@ func Create(input e.CreateDto) (*d.Data, error) { input.NewStatus, err = identifyPatientStatus(input) input.Adm_Employee_Id = input.AuthInfo.Employee_Id - mwRunner := newMiddlewareRunner(&event) + mwRunner := newMiddlewareRunner(&event, input.Sync) err = dg.I.Transaction(func(tx *gorm.DB) error { // create encounter @@ -158,7 +158,6 @@ func Create(input e.CreateDto) (*d.Data, error) { } func ReadList(input e.ReadListDto) (*d.Data, error) { - var data *e.Encounter var dataList []e.Encounter var metaList *e.MetaDto var err error @@ -172,23 +171,9 @@ func ReadList(input e.ReadListDto) (*d.Data, error) { pl.SetLogInfo(&event, input, "started", "readList") err = dg.I.Transaction(func(tx *gorm.DB) error { - mwRunner := newMiddlewareRunner(&event) - mwRunner.setMwType(pu.MWTPre) - // Run pre-middleware - if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, data); err != nil { - return err - } - if dataList, metaList, err = ReadListData(input, &event, tx); err != nil { return err } - - mwRunner.setMwType(pu.MWTPost) - // Run post-middleware - if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, data); err != nil { - return err - } - return nil }) @@ -223,23 +208,9 @@ func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { pl.SetLogInfo(&event, input, "started", "readDetail") err = dg.I.Transaction(func(tx *gorm.DB) error { - mwRunner := newMiddlewareRunner(&event) - 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 }) @@ -277,7 +248,7 @@ func Update(input e.UpdateDto) (*d.Data, error) { } input.Adm_Employee_Id = input.AuthInfo.Employee_Id - mwRunner := newMiddlewareRunner(&event) + mwRunner := newMiddlewareRunner(&event, input.Sync) err = dg.I.Transaction(func(tx *gorm.DB) error { pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") @@ -352,7 +323,7 @@ func Delete(input e.DeleteDto) (*d.Data, error) { return nil, err } - mwRunner := newMiddlewareRunner(&event) + mwRunner := newMiddlewareRunner(&event, input.Sync) err = dg.I.Transaction(func(tx *gorm.DB) error { pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") @@ -436,7 +407,7 @@ func CheckOut(input e.DischargeDto) (*d.Data, error) { return nil, err } - mwRunner := newMiddlewareRunner(&event) + mwRunner := newMiddlewareRunner(&event, input.Sync) err = dg.I.Transaction(func(tx *gorm.DB) error { pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") @@ -561,7 +532,7 @@ func UpdateStatusCode(input e.UpdateStatusDto) (*d.Data, error) { return nil, err } - mwRunner := newMiddlewareRunner(&event) + mwRunner := newMiddlewareRunner(&event, input.Sync) err = dg.I.Transaction(func(tx *gorm.DB) error { pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") @@ -664,7 +635,7 @@ func CheckIn(input e.CheckinDto) (*d.Data, error) { input.StartedAt = &now } - mwRunner := newMiddlewareRunner(&event) + mwRunner := newMiddlewareRunner(&event, input.Sync) err = dg.I.Transaction(func(tx *gorm.DB) error { pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") @@ -767,7 +738,7 @@ func RequestSwitchUnit(input e.SwitchUnitDto) (*d.Data, error) { } input.Src_Nurse_Code = input.AuthInfo.Nurse_Code - mwRunner := newMiddlewareRunner(&event) + mwRunner := newMiddlewareRunner(&event, input.Sync) err = dg.I.Transaction(func(tx *gorm.DB) error { pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") @@ -861,7 +832,7 @@ func ApproveSwitchUnit(input e.ApproveCancelUnitDto) (*d.Data, error) { return nil, err } - mwRunner := newMiddlewareRunner(&event) + mwRunner := newMiddlewareRunner(&event, input.Sync) err = dg.I.Transaction(func(tx *gorm.DB) error { pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") @@ -976,7 +947,7 @@ func CancelSwitchUnit(input e.ApproveCancelUnitDto) (*d.Data, error) { return nil, err } - mwRunner := newMiddlewareRunner(&event) + mwRunner := newMiddlewareRunner(&event, input.Sync) err = dg.I.Transaction(func(tx *gorm.DB) error { pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") diff --git a/internal/use-case/main-use-case/encounter/helper.go b/internal/use-case/main-use-case/encounter/helper.go index 02ade837..f606eb7c 100644 --- a/internal/use-case/main-use-case/encounter/helper.go +++ b/internal/use-case/main-use-case/encounter/helper.go @@ -65,44 +65,71 @@ import ( us "simrs-vx/internal/use-case/main-use-case/soapi" ) -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 - data.Status_Code = erc.DSCNew - } 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_Code = inputSrc.Unit_Code - data.Specialist_Code = inputSrc.Specialist_Code - data.Subspecialist_Code = inputSrc.Subspecialist_Code - data.VisitDate = inputSrc.VisitDate - data.PaymentMethod_Code = inputSrc.PaymentMethod_Code - data.InsuranceCompany_Code = inputSrc.InsuranceCompany_Code - data.Member_Number = inputSrc.Member_Number - data.Ref_Number = inputSrc.Ref_Number - data.Trx_Number = inputSrc.Trx_Number - data.Appointment_Doctor_Code = inputSrc.Appointment_Doctor_Code - data.Adm_Employee_Id = inputSrc.Adm_Employee_Id - data.Responsible_Doctor_Code = inputSrc.Responsible_Doctor_Code - data.RefSource_Name = inputSrc.RefSource_Name - data.Appointment_Id = inputSrc.Appointment_Id - data.RefType_Code = &inputSrc.RefTypeCode - data.NewStatus = inputSrc.NewStatus +func setDataCreate(input *e.CreateDto, data *e.Encounter) { + data.Patient_Id = input.Patient_Id + data.RegisteredAt = input.RegisteredAt + data.Class_Code = input.Class_Code + data.Unit_Code = input.Unit_Code + data.Specialist_Code = input.Specialist_Code + data.Subspecialist_Code = input.Subspecialist_Code + data.VisitDate = input.VisitDate + data.PaymentMethod_Code = input.PaymentMethod_Code + data.InsuranceCompany_Code = input.InsuranceCompany_Code + data.Member_Number = input.Member_Number + data.RefType_Code = &input.RefTypeCode + data.Ref_Number = input.Ref_Number + data.Trx_Number = input.Trx_Number + data.Appointment_Doctor_Code = input.Appointment_Doctor_Code + data.Adm_Employee_Id = input.Adm_Employee_Id + data.RefSource_Name = input.RefSource_Name + data.Appointment_Id = input.Appointment_Id + data.Status_Code = erc.DSCNew + data.NewStatus = input.NewStatus } func setDataUpdate(src e.UpdateDto, dst *e.Encounter) { - dst.Appointment_Doctor_Code = src.Appointment_Doctor_Code - dst.Responsible_Doctor_Code = src.Responsible_Doctor_Code dst.Unit_Code = src.Unit_Code dst.Specialist_Code = src.Specialist_Code dst.Subspecialist_Code = src.Subspecialist_Code dst.VisitDate = src.VisitDate + dst.Appointment_Doctor_Code = src.Appointment_Doctor_Code + dst.Adm_Employee_Id = src.Adm_Employee_Id + dst.Appointment_Id = src.Appointment_Id + dst.RefSource_Name = src.RefSource_Name + dst.Trx_Number = src.Trx_Number + dst.Ref_Number = src.Ref_Number + dst.Member_Number = src.Member_Number +} + +func setDataUpdateFromSource(input *e.UpdateDto, data *e.Encounter) { + data.Patient_Id = input.Patient_Id + data.RegisteredAt = input.RegisteredAt + data.Unit_Code = input.Unit_Code + data.Specialist_Code = input.Specialist_Code + data.Subspecialist_Code = input.Subspecialist_Code + data.VisitDate = input.VisitDate + data.StartedAt = input.StartedAt + data.FinishedAt = input.FinishedAt + data.PaymentMethod_Code = input.PaymentMethod_Code + data.InsuranceCompany_Code = input.InsuranceCompany_Code + data.Member_Number = input.Member_Number + data.RefType_Code = &input.RefTypeCode + data.Ref_Number = input.Ref_Number + data.Trx_Number = input.Trx_Number + data.Appointment_Doctor_Code = input.Appointment_Doctor_Code + data.Adm_Employee_Id = input.Adm_Employee_Id + data.Responsible_Doctor_Code = input.Responsible_Doctor_Code + data.Discharge_Method_Code = input.Discharge_Method_Code + data.RefSource_Name = input.RefSource_Name + data.Appointment_Id = input.Appointment_Id + data.EarlyEducation = input.EarlyEducation + data.MedicalDischargeEducation = input.MedicalDischargeEducation + data.AdmDischargeEducation = input.AdmDischargeEducation + data.DischargeReason = input.DischargeReason + data.Status_Code = input.Status_Code + data.Discharge_Date = input.Discharge_Date + data.NewStatus = input.NewStatus + data.Responsible_Nurse_Code = input.Responsible_Nurse_Code } func setDataDischarge(src e.DischargeDto, dst *e.Encounter) { diff --git a/internal/use-case/main-use-case/encounter/lib.go b/internal/use-case/main-use-case/encounter/lib.go index 0b14b925..4a02973a 100644 --- a/internal/use-case/main-use-case/encounter/lib.go +++ b/internal/use-case/main-use-case/encounter/lib.go @@ -25,7 +25,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Encount pl.SetLogInfo(event, nil, "started", "DBCreate") data := e.Encounter{} - setData(&input, &data) + setDataCreate(&input, &data) var tx *gorm.DB if len(dbx) > 0 { @@ -109,7 +109,12 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e func UpdateData(input e.UpdateDto, data *e.Encounter, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, data, "started", "DBUpdate") - setDataUpdate(input, data) + + if input.Sync { + setDataUpdateFromSource(&input, data) + } else { + setDataUpdate(input, data) + } var tx *gorm.DB if len(dbx) > 0 { diff --git a/internal/use-case/main-use-case/encounter/middleware-runner.go b/internal/use-case/main-use-case/encounter/middleware-runner.go index 4481443b..da62fdb6 100644 --- a/internal/use-case/main-use-case/encounter/middleware-runner.go +++ b/internal/use-case/main-use-case/encounter/middleware-runner.go @@ -20,10 +20,15 @@ type middlewareRunner struct { } // NewMiddlewareExecutor creates a new middleware executor -func newMiddlewareRunner(event *pl.Event) *middlewareRunner { +func newMiddlewareRunner(event *pl.Event, syncFromOldSource bool) *middlewareRunner { + activateSync := sync.O.Enable + if syncFromOldSource { + activateSync = false + } + return &middlewareRunner{ Event: event, - SyncOn: sync.O.Enable, + SyncOn: activateSync, } } diff --git a/internal/use-case/main-use-case/patient/case.go b/internal/use-case/main-use-case/patient/case.go index 24aa4394..7362bf7a 100644 --- a/internal/use-case/main-use-case/patient/case.go +++ b/internal/use-case/main-use-case/patient/case.go @@ -37,7 +37,7 @@ func Create(input e.CreateDto) (*d.Data, error) { // Start log pl.SetLogInfo(&event, input, "started", "create") - mwRunner := newMiddlewareRunner(&event) + mwRunner := newMiddlewareRunner(&event, input.Sync) // check if user has employee position if !input.AuthInfo.HasEmployeePosition() { @@ -143,7 +143,6 @@ func Create(input e.CreateDto) (*d.Data, error) { } func ReadList(input e.ReadListDto) (*d.Data, error) { - var data *e.Patient var dataList []e.Patient var metaList *e.MetaDto var err error @@ -157,23 +156,9 @@ func ReadList(input e.ReadListDto) (*d.Data, error) { pl.SetLogInfo(&event, input, "started", "readList") err = dg.I.Transaction(func(tx *gorm.DB) error { - mwRunner := newMiddlewareRunner(&event) - mwRunner.setMwType(pu.MWTPre) - // Run pre-middleware - if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, data); err != nil { - return err - } - if dataList, metaList, err = ReadListData(input, &event, tx); err != nil { return err } - - mwRunner.setMwType(pu.MWTPost) - // Run post-middleware - if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, data); err != nil { - return err - } - return nil }) @@ -208,23 +193,9 @@ func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { pl.SetLogInfo(&event, input, "started", "readDetail") err = dg.I.Transaction(func(tx *gorm.DB) error { - mwRunner := newMiddlewareRunner(&event) - 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 }) @@ -254,7 +225,7 @@ func Update(input e.UpdateDto) (*d.Data, error) { // Start log pl.SetLogInfo(&event, input, "started", "update") - mwRunner := newMiddlewareRunner(&event) + mwRunner := newMiddlewareRunner(&event, input.Sync) err = dg.I.Transaction(func(tx *gorm.DB) error { pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") @@ -343,7 +314,7 @@ func Delete(input e.DeleteDto) (*d.Data, error) { // Start log pl.SetLogInfo(&event, input, "started", "delete") - mwRunner := newMiddlewareRunner(&event) + mwRunner := newMiddlewareRunner(&event, input.Sync) err = dg.I.Transaction(func(tx *gorm.DB) error { pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") diff --git a/internal/use-case/main-use-case/patient/middleware-runner.go b/internal/use-case/main-use-case/patient/middleware-runner.go index 0e085514..0cc10e27 100644 --- a/internal/use-case/main-use-case/patient/middleware-runner.go +++ b/internal/use-case/main-use-case/patient/middleware-runner.go @@ -20,10 +20,15 @@ type middlewareRunner struct { } // NewMiddlewareExecutor creates a new middleware executor -func newMiddlewareRunner(event *pl.Event) *middlewareRunner { +func newMiddlewareRunner(event *pl.Event, syncFromOldSource bool) *middlewareRunner { + activateSync := sync.O.Enable + if syncFromOldSource { + activateSync = false + } + return &middlewareRunner{ Event: event, - SyncOn: sync.O.Enable, + SyncOn: activateSync, } } From c3c130558d62e3d74df8a89c4c034db5b623074a Mon Sep 17 00:00:00 2001 From: vanilia Date: Mon, 1 Dec 2025 16:31:06 +0700 Subject: [PATCH 10/42] on going soapi --- .../simgos-sync-use-case/new/soapi/case.go | 197 ++++++++++++++++++ .../simgos-sync-use-case/new/soapi/helper.go | 56 +++++ .../simgos-sync-use-case/new/soapi/lib.go | 188 +++++++++++++++++ .../new/soapi/middleware-runner.go | 104 +++++++++ .../new/soapi/middleware.go | 9 + .../simgos-sync-use-case/new/soapi/tycovar.go | 44 ++++ 6 files changed, 598 insertions(+) create mode 100644 internal/use-case/simgos-sync-use-case/new/soapi/case.go create mode 100644 internal/use-case/simgos-sync-use-case/new/soapi/helper.go create mode 100644 internal/use-case/simgos-sync-use-case/new/soapi/lib.go create mode 100644 internal/use-case/simgos-sync-use-case/new/soapi/middleware-runner.go create mode 100644 internal/use-case/simgos-sync-use-case/new/soapi/middleware.go create mode 100644 internal/use-case/simgos-sync-use-case/new/soapi/tycovar.go diff --git a/internal/use-case/simgos-sync-use-case/new/soapi/case.go b/internal/use-case/simgos-sync-use-case/new/soapi/case.go new file mode 100644 index 00000000..488e0f64 --- /dev/null +++ b/internal/use-case/simgos-sync-use-case/new/soapi/case.go @@ -0,0 +1,197 @@ +package soapi + +import ( + pl "simrs-vx/pkg/logger" + + d "github.com/karincake/dodol" + "gorm.io/gorm" + + db "simrs-vx/pkg/dualtrx-helper" + + e "simrs-vx/internal/domain/main-entities/division" + esimgos "simrs-vx/internal/domain/simgos-entities/m-unit" + esync "simrs-vx/internal/domain/sync-entities/division" + elog "simrs-vx/internal/domain/sync-entities/log" +) + +const source = "division" + +func Create(input e.CreateDto) (*d.Data, error) { + var ( + sgData *esimgos.MUnit + syncLink *esync.DivisionLink + err error + ) + + event := pl.Event{ + Feature: "Create", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "create") + + err = db.WithDualTx(func(tx *db.Dualtx) error { + // STEP 1: Insert to simgos + sgData, err = CreateSimgosData(input, &event, tx.Simgos) + if err != nil { + return err + } + + // STEP 2: Insert to Link + syncLink, err = CreateLinkData(*input.Id, sgData.KodeUnit, &event, tx.Sync) + if err != nil { + return err + } + + return nil + }) + + if err != nil { + if syncLink != nil { + go func() { _ = DeleteLinkData(syncLink, &event) }() + } + return nil, err + } + + pl.SetLogInfo(&event, nil, "complete") + + return &d.Data{ + Meta: d.II{ + "source": source, + "structure": "single-data", + "status": "created", + }, + }, nil +} + +func CreateSimxLog(input elog.SimxLogDto) (*d.Data, error) { + event := pl.Event{ + Feature: "Create", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "create") + + tx := db.NewTx() + err := tx.Sync.Transaction(func(tx *gorm.DB) error { + // Insert to Log + if err := CreateLogData(input, &event, tx); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + pl.SetLogInfo(&event, nil, "complete") + + return &d.Data{ + Meta: d.II{ + "source": source, + "structure": "single-data", + "status": "created", + }, + }, nil +} + +func Update(input e.UpdateDto) (*d.Data, error) { + event := pl.Event{ + Feature: "Update", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "update") + + // STEP 1: Get Link + syncLink, err := ReadDetailLinkData(*input.Id, &event) + if err != nil { + return nil, err + } + + tx := db.NewTx() + err = tx.Simgos.Transaction(func(tx *gorm.DB) error { + // Step 2: Update Simgos + if err = UpdateSimgosData(input, syncLink, &event, tx); err != nil { + return err + } + + return nil + }) + + pl.SetLogInfo(&event, nil, "complete") + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "updated", + }, + }, nil +} + +func Delete(input e.DeleteDto) (*d.Data, error) { + var isLinkDeleted bool + + event := pl.Event{ + Feature: "Delete", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "delete") + + // STEP 1: Get Link + syncLink, err := ReadDetailLinkData(*input.Id, &event) + if err != nil { + return nil, err + } + + // STEP 2: Get Simgos + sgData, err := ReadDetailSimgosData(uint16(syncLink.Simgos_Id), &event) + if err != nil { + return nil, err + } + + err = db.WithDualTx(func(tx *db.Dualtx) error { + // STEP 3: Delete Simgos + err = HardDeleteSimgosData(sgData, &event, tx.Simgos) + if err != nil { + return err + } + + // STEP 4: Delete Link + err = DeleteLinkData(syncLink, &event, tx.Sync) + if err != nil { + return err + } + + isLinkDeleted = true + return nil + }) + + if err != nil { + if isLinkDeleted { + go func() { + _, _ = CreateLinkData(uint(*input.Id), sgData.KodeUnit, &event) + }() + } + return nil, err + } + + pl.SetLogInfo(&event, nil, "complete") + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "deleted", + }, + }, nil + +} diff --git a/internal/use-case/simgos-sync-use-case/new/soapi/helper.go b/internal/use-case/simgos-sync-use-case/new/soapi/helper.go new file mode 100644 index 00000000..55eaa0f9 --- /dev/null +++ b/internal/use-case/simgos-sync-use-case/new/soapi/helper.go @@ -0,0 +1,56 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package soapi + +import ( + "encoding/json" + erc "simrs-vx/internal/domain/references/common" + + e "simrs-vx/internal/domain/main-entities/soapi" + esimgos "simrs-vx/internal/domain/simgos-entities/t-diagnosadanterapi" + esyncLog "simrs-vx/internal/domain/sync-entities/log" + esync "simrs-vx/internal/domain/sync-entities/soapi" +) + +func setDataSimgos[T *e.CreateDto | *e.UpdateDto](input T) (data esimgos.DiagnosaDanTerapi) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.NamaUnit = inputSrc.Name + return +} + +func setDataSimxLog(input *esyncLog.SimxLogDto) (data esync.DivisionSimxLog) { + // encode to JSON + jsonData, _ := json.MarshalIndent(input.Payload, "", " ") + jsonString := string(jsonData) + + var status erc.ProcessStatusCode + if input.IsSuccess { + status = erc.PSCSuccess + } else { + status = erc.PSCFailed + if input.ErrMessage != nil { + data.ErrMessage = input.ErrMessage + } + } + + data.Value = &jsonString + data.Date = &now + data.Status = status + + return +} + +func setDataSimxLink(simxId, simgosId uint) (data esync.DivisionLink) { + data.Simx_Id = simxId + data.Simgos_Id = simgosId + return +} diff --git a/internal/use-case/simgos-sync-use-case/new/soapi/lib.go b/internal/use-case/simgos-sync-use-case/new/soapi/lib.go new file mode 100644 index 00000000..7abdfe0a --- /dev/null +++ b/internal/use-case/simgos-sync-use-case/new/soapi/lib.go @@ -0,0 +1,188 @@ +package soapi + +import ( + plh "simrs-vx/pkg/lib-helper" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + "time" + + dg "github.com/karincake/apem/db-gorm-pg" + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/division" + esimgos "simrs-vx/internal/domain/simgos-entities/m-unit" + esync "simrs-vx/internal/domain/sync-entities/division" + esynclog "simrs-vx/internal/domain/sync-entities/log" +) + +var now = time.Now() + +func CreateSimgosData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*esimgos.MUnit, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := setDataSimgos(&input) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.IS["simrs"] + } + + if err := tx.Create(&data).Error; err != nil { + return nil, plh.HandleCreateError(input, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func ReadDetailSimgosData(simgosId uint16, event *pl.Event) (*esimgos.MUnit, error) { + pl.SetLogInfo(event, simgosId, "started", "DBReadDetail") + data := esimgos.MUnit{} + + var tx = dg.IS["simrs"] + + if err := tx. + Where("\"kode_unit\" = ?", simgosId). + First(&data).Error; err != nil { + if processedErr := pu.HandleReadError(err, event, source, simgosId, data); processedErr != nil { + return nil, processedErr + } + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func UpdateSimgosData(input e.UpdateDto, dataSimgos *esync.DivisionLink, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, input, "started", "DBUpdate") + + data := setDataSimgos(&input) + data.KodeUnit = dataSimgos.Simgos_Id + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.IS["simrs"] + } + + 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 HardDeleteSimgosData(data *esimgos.MUnit, 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.IS["simrs"] + } + + 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 CreateLinkData(simxId, simgosId uint, event *pl.Event, dbx ...*gorm.DB) (*esync.DivisionLink, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + data := setDataSimxLink(simxId, simgosId) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Create(&data).Error; err != nil { + return nil, plh.HandleCreateError(data, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func ReadDetailLinkData(simxId uint16, event *pl.Event) (*esync.DivisionLink, error) { + pl.SetLogInfo(event, simxId, "started", "DBReadDetail") + data := esync.DivisionLink{} + + var tx = dg.I + + if err := tx. + Where("\"Simx_Id\" = ?", simxId). + First(&data).Error; err != nil { + if processedErr := pu.HandleReadError(err, event, source, simxId, data); processedErr != nil { + return nil, processedErr + } + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func DeleteLinkData(data *esync.DivisionLink, 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 CreateLogData(input esynclog.SimxLogDto, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, nil, "started", "DBCreate") + data := setDataSimxLog(&input) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Create(&data).Error; err != nil { + return plh.HandleCreateError(input, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} diff --git a/internal/use-case/simgos-sync-use-case/new/soapi/middleware-runner.go b/internal/use-case/simgos-sync-use-case/new/soapi/middleware-runner.go new file mode 100644 index 00000000..74d8b1a8 --- /dev/null +++ b/internal/use-case/simgos-sync-use-case/new/soapi/middleware-runner.go @@ -0,0 +1,104 @@ +package soapi + +import ( + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/soapi" +) + +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.Soapi) 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.Soapi) 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.Soapi) 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.Soapi) 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.Soapi) 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 +} diff --git a/internal/use-case/simgos-sync-use-case/new/soapi/middleware.go b/internal/use-case/simgos-sync-use-case/new/soapi/middleware.go new file mode 100644 index 00000000..f2fecda5 --- /dev/null +++ b/internal/use-case/simgos-sync-use-case/new/soapi/middleware.go @@ -0,0 +1,9 @@ +package soapi + +// example of middleware +// func init() { +// createPreMw = append(createPreMw, +// CreateMw{Name: "modif-input", Func: pm.ModifInput}, +// CreateMw{Name: "check-data", Func: pm.CheckData}, +// ) +// } diff --git a/internal/use-case/simgos-sync-use-case/new/soapi/tycovar.go b/internal/use-case/simgos-sync-use-case/new/soapi/tycovar.go new file mode 100644 index 00000000..956193a4 --- /dev/null +++ b/internal/use-case/simgos-sync-use-case/new/soapi/tycovar.go @@ -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 soapi + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/soapi" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.Soapi, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.Soapi, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.Soapi, 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 From 4ef04ae084f3ba4a7008cfc0e0b360fd6f412939 Mon Sep 17 00:00:00 2001 From: vanilia Date: Mon, 1 Dec 2025 16:59:23 +0700 Subject: [PATCH 11/42] ongoing soapi --- .../simgos-sync-use-case/new/soapi/helper.go | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/internal/use-case/simgos-sync-use-case/new/soapi/helper.go b/internal/use-case/simgos-sync-use-case/new/soapi/helper.go index 55eaa0f9..5ef86ae3 100644 --- a/internal/use-case/simgos-sync-use-case/new/soapi/helper.go +++ b/internal/use-case/simgos-sync-use-case/new/soapi/helper.go @@ -7,27 +7,24 @@ package soapi import ( "encoding/json" erc "simrs-vx/internal/domain/references/common" + "strconv" e "simrs-vx/internal/domain/main-entities/soapi" + soapi "simrs-vx/internal/domain/references/clinical" esimgos "simrs-vx/internal/domain/simgos-entities/t-diagnosadanterapi" esyncLog "simrs-vx/internal/domain/sync-entities/log" esync "simrs-vx/internal/domain/sync-entities/soapi" ) -func setDataSimgos[T *e.CreateDto | *e.UpdateDto](input T) (data esimgos.DiagnosaDanTerapi) { - var inputSrc *e.CreateDto - if inputT, ok := any(input).(*e.CreateDto); ok { - inputSrc = inputT - } else { - inputTemp := any(input).(*e.UpdateDto) - inputSrc = &inputTemp.CreateDto - } +func setDataEarlyMedic(input e.Soapi) (data esimgos.DiagnosaDanTerapi) { + value := soapi.EarlyMedicValue{} + _ = json.Unmarshal([]byte(*input.Value), &value) - data.NamaUnit = inputSrc.Name + data.Idxdaftar = toPtr(uint(input.Employee_Id)) return } -func setDataSimxLog(input *esyncLog.SimxLogDto) (data esync.DivisionSimxLog) { +func setDataSimxLog(input *esyncLog.SimxLogDto) (data esync.SoapiSimxLog) { // encode to JSON jsonData, _ := json.MarshalIndent(input.Payload, "", " ") jsonString := string(jsonData) @@ -49,8 +46,17 @@ func setDataSimxLog(input *esyncLog.SimxLogDto) (data esync.DivisionSimxLog) { return } -func setDataSimxLink(simxId, simgosId uint) (data esync.DivisionLink) { +func setDataSimxLink(simxId, simgosId uint) (data esync.SoapiLink) { data.Simx_Id = simxId data.Simgos_Id = simgosId return } + +func toPtr(v uint) *uint { + return &v +} +func stringtouint(v string) *uint { + u, _ := strconv.Atoi(v) + point := uint(u) + return &point +} From 80ee7f54bc2e5b9fbd3938b8b46a6a41600276bc Mon Sep 17 00:00:00 2001 From: vanilia Date: Tue, 2 Dec 2025 14:34:39 +0700 Subject: [PATCH 12/42] add helper for t_diagnosadanterapi --- .../domain/references/clinical/clinical.go | 4 +- internal/infra/sync-cfg/sync-cfg.go | 2 +- internal/infra/sync-cfg/tycovar.go | 6 +- .../simgos-sync-plugin/new/division/plugin.go | 2 +- .../new/encounter/plugin.go | 2 +- .../new/installation/plugin.go | 2 +- .../simgos-sync-plugin/new/patient/plugin.go | 2 +- .../new/specialist/plugin.go | 2 +- .../simgos-sync-plugin/new/unit/plugin.go | 2 +- .../new/encounter/case.go | 5 +- .../simgos-sync-use-case/new/soapi/case.go | 2 +- .../simgos-sync-use-case/new/soapi/helper.go | 87 ++++++++++++++++--- 12 files changed, 92 insertions(+), 26 deletions(-) diff --git a/internal/domain/references/clinical/clinical.go b/internal/domain/references/clinical/clinical.go index 523cfdb7..39b2e56d 100644 --- a/internal/domain/references/clinical/clinical.go +++ b/internal/domain/references/clinical/clinical.go @@ -325,8 +325,8 @@ type SoapiSrc struct { type EarlyMedicValue struct { Vaccinated bool `json:"vaccinated,omitempty"` - CaseStatus string `json:"case-status,omitempty"` - EncounterStatus string `json:"encounter-status,omitempty"` + CaseStatus int `json:"case-status,omitempty"` + EncounterStatus int `json:"encounter-status,omitempty"` PrimaryComplain string `json:"pri-complain,omitempty"` CurrentDiseaseHistory string `json:"cur-disea-hist,omitempty"` SpO2 int `json:"spo2,omitempty"` diff --git a/internal/infra/sync-cfg/sync-cfg.go b/internal/infra/sync-cfg/sync-cfg.go index a6a5d703..8ea63dac 100644 --- a/internal/infra/sync-cfg/sync-cfg.go +++ b/internal/infra/sync-cfg/sync-cfg.go @@ -8,7 +8,7 @@ import ( func SetConfig() { a.ParseSingleCfg(&O) - if O.Host == "" || O.Prefix == "" { + if O.TargetHost == "" || O.Prefix == "" { panic("config sync host and prefix empty") } lo.I.Println("sync url config loaded, status: DONE!!") diff --git a/internal/infra/sync-cfg/tycovar.go b/internal/infra/sync-cfg/tycovar.go index 6ae230fb..199ee4d4 100644 --- a/internal/infra/sync-cfg/tycovar.go +++ b/internal/infra/sync-cfg/tycovar.go @@ -3,7 +3,7 @@ package synccfg var O SyncUrlCfg = SyncUrlCfg{} type SyncUrlCfg struct { - Prefix string `yaml:"prefix"` - Host string `yaml:"host"` - Enable bool `yaml:"enable"` + Prefix string `yaml:"prefix"` + TargetHost string `yaml:"targetHost"` + Enable bool `yaml:"enable"` } diff --git a/internal/use-case/simgos-sync-plugin/new/division/plugin.go b/internal/use-case/simgos-sync-plugin/new/division/plugin.go index 54c1403c..a116225c 100644 --- a/internal/use-case/simgos-sync-plugin/new/division/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/division/plugin.go @@ -163,5 +163,5 @@ func Delete(input *e.DeleteDto) error { } func getPrefixEndpoint() string { - return fmt.Sprintf("%s%s/v1/division", sync.O.Host, sync.O.Prefix) + return fmt.Sprintf("%s%s/v1/division", sync.O.TargetHost, sync.O.Prefix) } diff --git a/internal/use-case/simgos-sync-plugin/new/encounter/plugin.go b/internal/use-case/simgos-sync-plugin/new/encounter/plugin.go index a6334fdb..cc5a45bb 100644 --- a/internal/use-case/simgos-sync-plugin/new/encounter/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/encounter/plugin.go @@ -68,5 +68,5 @@ func CancelSwitchUnit(input *e.ApproveCancelUnitDto) error { } func getPrefixEndpoint() string { - return fmt.Sprintf("%s%s/v1/encounter", sync.O.Host, sync.O.Prefix) + return fmt.Sprintf("%s%s/v1/encounter", sync.O.TargetHost, sync.O.Prefix) } diff --git a/internal/use-case/simgos-sync-plugin/new/installation/plugin.go b/internal/use-case/simgos-sync-plugin/new/installation/plugin.go index f2495139..386996ce 100644 --- a/internal/use-case/simgos-sync-plugin/new/installation/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/installation/plugin.go @@ -163,5 +163,5 @@ func Delete(input *e.DeleteDto) error { } func getPrefixEndpoint() string { - return fmt.Sprintf("%s%s/v1/installation", sync.O.Host, sync.O.Prefix) + return fmt.Sprintf("%s%s/v1/installation", sync.O.TargetHost, sync.O.Prefix) } diff --git a/internal/use-case/simgos-sync-plugin/new/patient/plugin.go b/internal/use-case/simgos-sync-plugin/new/patient/plugin.go index 309e1d18..90ce343f 100644 --- a/internal/use-case/simgos-sync-plugin/new/patient/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/patient/plugin.go @@ -203,5 +203,5 @@ func GenerateNomrPatient() (*string, error) { } func getPrefixEndpoint() string { - return fmt.Sprintf("%s%s/v1/patient", sync.O.Host, sync.O.Prefix) + return fmt.Sprintf("%s%s/v1/patient", sync.O.TargetHost, sync.O.Prefix) } diff --git a/internal/use-case/simgos-sync-plugin/new/specialist/plugin.go b/internal/use-case/simgos-sync-plugin/new/specialist/plugin.go index 892d7a17..a83b366a 100644 --- a/internal/use-case/simgos-sync-plugin/new/specialist/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/specialist/plugin.go @@ -163,5 +163,5 @@ func Delete(input *e.DeleteDto) error { } func getPrefixEndpoint() string { - return fmt.Sprintf("%s%s/v1/specialist", sync.O.Host, sync.O.Prefix) + return fmt.Sprintf("%s%s/v1/specialist", sync.O.TargetHost, sync.O.Prefix) } diff --git a/internal/use-case/simgos-sync-plugin/new/unit/plugin.go b/internal/use-case/simgos-sync-plugin/new/unit/plugin.go index e854d898..db8678f2 100644 --- a/internal/use-case/simgos-sync-plugin/new/unit/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/unit/plugin.go @@ -163,5 +163,5 @@ func Delete(input *e.DeleteDto) error { } func getPrefixEndpoint() string { - return fmt.Sprintf("%s%s/v1/unit", sync.O.Host, sync.O.Prefix) + return fmt.Sprintf("%s%s/v1/unit", sync.O.TargetHost, sync.O.Prefix) } diff --git a/internal/use-case/simgos-sync-use-case/new/encounter/case.go b/internal/use-case/simgos-sync-use-case/new/encounter/case.go index 59e7e345..969e8ff3 100644 --- a/internal/use-case/simgos-sync-use-case/new/encounter/case.go +++ b/internal/use-case/simgos-sync-use-case/new/encounter/case.go @@ -320,11 +320,14 @@ func UpdateStatus(input e.Encounter) (*d.Data, error) { tx := db.NewTx() err = tx.Simgos.Transaction(func(tx *gorm.DB) error { - // Step 2: Update Simgos + // Step 2: Update TPendaftaran if err = UpdateTPendaftaranData(input, simgos, "update-status", &event, tx); err != nil { return err } + // Step 3: Update TDiagnosadanterapi + // TODO: update diagnosadanterapi + return nil }) diff --git a/internal/use-case/simgos-sync-use-case/new/soapi/case.go b/internal/use-case/simgos-sync-use-case/new/soapi/case.go index 488e0f64..4124b7f6 100644 --- a/internal/use-case/simgos-sync-use-case/new/soapi/case.go +++ b/internal/use-case/simgos-sync-use-case/new/soapi/case.go @@ -14,7 +14,7 @@ import ( elog "simrs-vx/internal/domain/sync-entities/log" ) -const source = "division" +const source = "soapi" func Create(input e.CreateDto) (*d.Data, error) { var ( diff --git a/internal/use-case/simgos-sync-use-case/new/soapi/helper.go b/internal/use-case/simgos-sync-use-case/new/soapi/helper.go index 5ef86ae3..90dbd4ff 100644 --- a/internal/use-case/simgos-sync-use-case/new/soapi/helper.go +++ b/internal/use-case/simgos-sync-use-case/new/soapi/helper.go @@ -6,21 +6,88 @@ package soapi import ( "encoding/json" - erc "simrs-vx/internal/domain/references/common" + "fmt" + ere "simrs-vx/internal/domain/references/encounter" "strconv" - e "simrs-vx/internal/domain/main-entities/soapi" - soapi "simrs-vx/internal/domain/references/clinical" + ercl "simrs-vx/internal/domain/references/clinical" + erc "simrs-vx/internal/domain/references/common" + + es "simrs-vx/internal/domain/main-entities/soapi" + esimgos "simrs-vx/internal/domain/simgos-entities/t-diagnosadanterapi" esyncLog "simrs-vx/internal/domain/sync-entities/log" esync "simrs-vx/internal/domain/sync-entities/soapi" ) -func setDataEarlyMedic(input e.Soapi) (data esimgos.DiagnosaDanTerapi) { - value := soapi.EarlyMedicValue{} +func setDataEarlyMedic(input es.Soapi) (data esimgos.DiagnosaDanTerapi) { + value := ercl.EarlyMedicValue{} _ = json.Unmarshal([]byte(*input.Value), &value) - data.Idxdaftar = toPtr(uint(input.Employee_Id)) + data.Idxdaftar = *input.Encounter_Id + data.TekananDarah = fmt.Sprintf("%v/%v", value.SystolicBloodPressure, value.DiastolicBloodPressure) + + data.GolonganDarah = value.BloodType + if value.BloodType == "" { + data.GolonganDarah = "X" + } + + data.TinggiBadan = float64(value.Height) + data.BeratBadan = float64(value.Weight) + data.Diagnosa = value.EarlyMedicDiagnose + data.Terapi = value.Therapy + data.Anamnesa = value.PrimaryComplain + + if e := input.Encounter; e != nil { + if p := e.Patient; p != nil { + data.Nomr = *p.Number + } + + data.Tanggal = e.VisitDate + data.Kdpoly = stringtouint(*e.Unit_Code) + data.Kddokter = stringtouint(*e.Appointment_Doctor_Code) + + if e.Class_Code == ere.ECAmbulatory { + data.Rajal = 1 + } + + } + + if e := input.Employee; e != nil { + if u := e.User; u != nil { + data.Nip = u.Name + } + } + + // TODO : status, tindakan_mdeis (?) + data.KunjunganBl = uint(value.EncounterStatus) + data.KasusBl = uint(value.CaseStatus) + + data.PemeriksaanFisik = value.PhysicalExamination + data.RiwayatPasien = value.CurrentDiseaseHistory + + if value.Vaccinated { + data.SudahVaksin = "YA" + } else { + data.SudahVaksin = "TIDAK" + } + + data.DenyutJantung = strconv.Itoa(value.Pulse) + data.Pernapasan = strconv.Itoa(value.RespiratoryRate) + data.Suhu = strconv.Itoa(value.Temperature) + data.Sp02 = strconv.Itoa(value.SpO2) + + if o := value.ExpectedOutcome; len(o) > 0 { + expectedOutput := []string{} + + for _, v := range o { + expectedOutput = append(expectedOutput, v.Name) + } + + jsonData, _ := json.MarshalIndent(value.ExpectedOutcome, "", " ") + data.TargetCapaian = string(jsonData) + } + return } @@ -52,11 +119,7 @@ func setDataSimxLink(simxId, simgosId uint) (data esync.SoapiLink) { return } -func toPtr(v uint) *uint { - return &v -} -func stringtouint(v string) *uint { +func stringtouint(v string) uint { u, _ := strconv.Atoi(v) - point := uint(u) - return &point + return uint(u) } From 132ce5f5edcfa546bce43d3294ea6dea832e2098 Mon Sep 17 00:00:00 2001 From: vanilia Date: Wed, 3 Dec 2025 10:19:44 +0700 Subject: [PATCH 13/42] finish sync soapi early-medic --- internal/domain/main-entities/soapi/dto.go | 9 +- .../simgos-sync-handler/new/soapi/handler.go | 58 ++++++ .../simgos-sync-handler.go | 2 + internal/lib/auth/tycovar.go | 1 + internal/use-case/main-use-case/soapi/case.go | 170 +++++++++-------- .../use-case/main-use-case/soapi/helper.go | 2 +- internal/use-case/main-use-case/soapi/lib.go | 4 +- .../main-use-case/soapi/middleware-runner.go | 54 ++++-- .../main-use-case/soapi/middleware.go | 22 ++- .../use-case/main-use-case/soapi/tycovar.go | 27 ++- .../simgos-sync-plugin/new/soapi/plugin.go | 36 ++++ .../new/encounter/case.go | 14 +- .../simgos-sync-use-case/new/soapi/case.go | 123 +++++++++--- .../simgos-sync-use-case/new/soapi/helper.go | 128 ++++++++++--- .../simgos-sync-use-case/new/soapi/lib.go | 180 ++++++++++++++++-- .../new/soapi/middleware.go | 8 - 16 files changed, 646 insertions(+), 192 deletions(-) create mode 100644 internal/interface/simgos-sync-handler/new/soapi/handler.go create mode 100644 internal/use-case/simgos-sync-plugin/new/soapi/plugin.go diff --git a/internal/domain/main-entities/soapi/dto.go b/internal/domain/main-entities/soapi/dto.go index 94094df7..bc847b3b 100644 --- a/internal/domain/main-entities/soapi/dto.go +++ b/internal/domain/main-entities/soapi/dto.go @@ -37,16 +37,19 @@ type FilterDto struct { } type ReadDetailDto struct { - Id uint16 `json:"id"` + Id uint `json:"id"` + Includes string `json:"includes"` } type UpdateDto struct { - Id uint16 `json:"id"` + Id uint `json:"id"` CreateDto + pa.AuthInfo } type DeleteDto struct { - Id uint16 `json:"id"` + Id uint `json:"id"` + pa.AuthInfo } type MetaDto struct { diff --git a/internal/interface/simgos-sync-handler/new/soapi/handler.go b/internal/interface/simgos-sync-handler/new/soapi/handler.go new file mode 100644 index 00000000..3a52a581 --- /dev/null +++ b/internal/interface/simgos-sync-handler/new/soapi/handler.go @@ -0,0 +1,58 @@ +package soapi + +import ( + "net/http" + + rw "github.com/karincake/risoles" + // ua "github.com/karincake/tumpeng/auth/svc" + + e "simrs-vx/internal/domain/main-entities/soapi" + esync "simrs-vx/internal/domain/sync-entities/log" + + u "simrs-vx/internal/use-case/simgos-sync-use-case/new/soapi" +) + +type myBase struct{} + +var O myBase + +func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { + dto := e.Soapi{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + res, err := u.Create(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) CreateLog(w http.ResponseWriter, r *http.Request) { + dto := esync.SimxLogDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + res, err := u.CreateSimxLog(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { + dto := e.Soapi{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + + res, err := u.Update(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.DeleteDto{} + dto.Id = uint(id) + + res, err := u.Delete(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/interface/simgos-sync-handler/simgos-sync-handler.go b/internal/interface/simgos-sync-handler/simgos-sync-handler.go index 5d52d40b..a892b931 100644 --- a/internal/interface/simgos-sync-handler/simgos-sync-handler.go +++ b/internal/interface/simgos-sync-handler/simgos-sync-handler.go @@ -24,6 +24,7 @@ import ( "simrs-vx/internal/interface/simgos-sync-handler/new/encounter" "simrs-vx/internal/interface/simgos-sync-handler/new/installation" "simrs-vx/internal/interface/simgos-sync-handler/new/patient" + "simrs-vx/internal/interface/simgos-sync-handler/new/soapi" "simrs-vx/internal/interface/simgos-sync-handler/new/specialist" "simrs-vx/internal/interface/simgos-sync-handler/new/subspecialist" "simrs-vx/internal/interface/simgos-sync-handler/new/unit" @@ -67,6 +68,7 @@ func SetRoutes() http.Handler { "PATCH /{id}/approve-switch-unit": encounter.O.ApproveSwitchUnit, "PATCH /{id}/cancel-switch-unit": encounter.O.CancelSwitchUnit, }) + hc.SyncCrud(r, prefixnew+"/v1/soapi", soapi.O) /******************** SvcToNew ******************/ //prefixold := "/old-to-new" diff --git a/internal/lib/auth/tycovar.go b/internal/lib/auth/tycovar.go index 117d0c73..0ce3b0fc 100644 --- a/internal/lib/auth/tycovar.go +++ b/internal/lib/auth/tycovar.go @@ -22,6 +22,7 @@ type AuthInfo struct { Pharmachist_Code *string Intern_Position_Code *string Roles []string + Sync bool // User_DivisionPositions []DivisionPosition } diff --git a/internal/use-case/main-use-case/soapi/case.go b/internal/use-case/main-use-case/soapi/case.go index 3dc8e195..8f4d29e2 100644 --- a/internal/use-case/main-use-case/soapi/case.go +++ b/internal/use-case/main-use-case/soapi/case.go @@ -2,6 +2,8 @@ package soapi import ( "errors" + erc "simrs-vx/internal/domain/references/common" + esync "simrs-vx/internal/domain/sync-entities/log" "strconv" e "simrs-vx/internal/domain/main-entities/soapi" @@ -27,53 +29,50 @@ func Create(input e.CreateDto) (*d.Data, error) { // Start log pl.SetLogInfo(&event, input, "started", "create") + mwRunner := newMiddlewareRunner(&event, input.Sync) + + 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 nil, pl.SetLogError(&event, input) + } 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) - } - - if input.AuthInfo.Employee_Id != nil { - v := uint(*input.AuthInfo.Employee_Id) - input.Employee_Id = &v - } else { - input.Employee_Id = nil - } - 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 { + // get detail for sync + soapiData, err := ReadDetailData(e.ReadDetailDto{ + Id: data.Id, + Includes: "Encounter,Employee"}, &event) + if err != nil { return err } - pl.SetLogInfo(&event, nil, "complete") + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err = mwRunner.ExecuteIfSyncOn(func() error { + return mwRunner.RunCreateMiddleware(createPostMw, soapiData) + }); err != nil { + return err + } return nil }) - if err != nil { + if err = runLogMiddleware(err, input, erc.CCCreate, mwRunner); err != nil { return nil, err } + pl.SetLogInfo(&event, nil, "complete") + return &d.Data{ Meta: d.II{ "source": source, @@ -85,7 +84,6 @@ func Create(input e.CreateDto) (*d.Data, error) { } func ReadList(input e.ReadListDto) (*d.Data, error) { - var data *e.Soapi var dataList []e.Soapi var metaList *e.MetaDto var err error @@ -99,23 +97,9 @@ func ReadList(input e.ReadListDto) (*d.Data, error) { pl.SetLogInfo(&event, input, "started", "readList") err = dg.I.Transaction(func(tx *gorm.DB) error { - mwRunner := newMiddlewareRunner(&event, tx) - mwRunner.setMwType(pu.MWTPre) - // Run pre-middleware - if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, data); err != nil { - return err - } - if dataList, metaList, err = ReadListData(input, &event, tx); err != nil { return err } - - mwRunner.setMwType(pu.MWTPost) - // Run post-middleware - if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, data); err != nil { - return err - } - return nil }) @@ -150,23 +134,9 @@ func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { 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 }) @@ -196,6 +166,7 @@ func Update(input e.UpdateDto) (*d.Data, error) { // Start log pl.SetLogInfo(&event, input, "started", "update") + mwRunner := newMiddlewareRunner(&event, input.Sync) err = dg.I.Transaction(func(tx *gorm.DB) error { pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") @@ -203,32 +174,35 @@ func Update(input e.UpdateDto) (*d.Data, error) { 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") + // get detail for sync + soapiData, err := ReadDetailData(e.ReadDetailDto{ + Id: data.Id, + Includes: "Encounter,Employee"}, &event) + if err != nil { + return err + } - mwRunner.setMwType(pu.MWTPost) - // Run post-middleware - if err := mwRunner.RunUpdateMiddleware(readDetailPostMw, &rdDto, data); err != nil { + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err = mwRunner.ExecuteIfSyncOn(func() error { + return mwRunner.RunUpdateMiddleware(updatePreMw, soapiData) + }); err != nil { return err } return nil }) - if err != nil { + if err = runLogMiddleware(err, input, erc.CCUpdate, mwRunner); err != nil { return nil, err } + pl.SetLogInfo(&event, nil, "complete") + return &d.Data{ Meta: d.IS{ "source": source, @@ -252,6 +226,7 @@ func Delete(input e.DeleteDto) (*d.Data, error) { // Start log pl.SetLogInfo(&event, input, "started", "delete") + mwRunner := newMiddlewareRunner(&event, input.Sync) err = dg.I.Transaction(func(tx *gorm.DB) error { pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") @@ -259,30 +234,27 @@ func Delete(input e.DeleteDto) (*d.Data, error) { 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 { + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err = mwRunner.ExecuteIfSyncOn(func() error { + return mwRunner.RunDeleteMiddleware(deletePreMw, &input) + }); err != nil { return err } return nil }) - if err != nil { + if err = runLogMiddleware(err, input, erc.CCDelete, mwRunner); err != nil { return nil, err } + pl.SetLogInfo(&event, nil, "complete") + return &d.Data{ Meta: d.IS{ "source": source, @@ -293,3 +265,39 @@ func Delete(input e.DeleteDto) (*d.Data, error) { }, nil } + +func runLogMiddleware(err error, input any, method erc.CrudCode, mwRunner *middlewareRunner) error { + var errMsg string + inputLog := esync.SimxLogDto{ + Payload: input, + Method: method, + } + + if err != nil { + // Run log-middleware + errMsg = err.Error() + inputLog.ErrMessage = &errMsg + inputLog.IsSuccess = false + + // create log failed + if errMiddleware := mwRunner.ExecuteIfSyncOn(func() error { + return mwRunner.RunCreateLogMiddleware(createSimxLogMw, &inputLog) + }); errMiddleware != nil { + return errMiddleware + } + + return err + } + + // create log success + inputLog.IsSuccess = true + err = mwRunner.ExecuteIfSyncOn(func() error { + return mwRunner.RunCreateLogMiddleware(createSimxLogMw, &inputLog) + }) + + if err != nil { + return err + } + + return nil +} diff --git a/internal/use-case/main-use-case/soapi/helper.go b/internal/use-case/main-use-case/soapi/helper.go index ae396270..c42b95d0 100644 --- a/internal/use-case/main-use-case/soapi/helper.go +++ b/internal/use-case/main-use-case/soapi/helper.go @@ -18,7 +18,7 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Soapi) { } data.Encounter_Id = inputSrc.Encounter_Id - data.Employee_Id = inputSrc.Employee_Id + data.Employee_Id = inputSrc.AuthInfo.Employee_Id data.Time = inputSrc.Time data.TypeCode = inputSrc.TypeCode data.Value = inputSrc.Value diff --git a/internal/use-case/main-use-case/soapi/lib.go b/internal/use-case/main-use-case/soapi/lib.go index 57bb5d23..85e94800 100644 --- a/internal/use-case/main-use-case/soapi/lib.go +++ b/internal/use-case/main-use-case/soapi/lib.go @@ -81,7 +81,9 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e tx = dg.I } - if err := tx.First(&data, input.Id).Error; err != nil { + if err := tx. + Scopes(gh.Preload(input.Includes)). + First(&data, input.Id).Error; err != nil { if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil { return nil, processedErr } diff --git a/internal/use-case/main-use-case/soapi/middleware-runner.go b/internal/use-case/main-use-case/soapi/middleware-runner.go index a840a33a..ffc49745 100644 --- a/internal/use-case/main-use-case/soapi/middleware-runner.go +++ b/internal/use-case/main-use-case/soapi/middleware-runner.go @@ -2,6 +2,8 @@ package soapi import ( e "simrs-vx/internal/domain/main-entities/soapi" + esync "simrs-vx/internal/domain/sync-entities/log" + sync "simrs-vx/internal/infra/sync-cfg" pl "simrs-vx/pkg/logger" pu "simrs-vx/pkg/use-case-helper" @@ -12,24 +14,45 @@ type middlewareRunner struct { Event *pl.Event Tx *gorm.DB MwType pu.MWType + SyncOn bool } // NewMiddlewareExecutor creates a new middleware executor -func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner { +func newMiddlewareRunner(event *pl.Event, syncFromOldSource bool) *middlewareRunner { + activateSync := sync.O.Enable + if syncFromOldSource { + activateSync = false + } + return &middlewareRunner{ - Event: event, - Tx: tx, + Event: event, + SyncOn: activateSync, } } // ExecuteCreateMiddleware executes create middleware -func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.Soapi) error { +func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.Soapi) error { for _, middleware := range middlewares { - logData := pu.GetLogData(input, data) + logData := pu.GetLogData(input, nil) pl.SetLogInfo(me.Event, logData, "started", middleware.Name) - if err := middleware.Func(input, data, me.Tx); err != nil { + if err := middleware.Func(input); 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) RunCreateLogMiddleware(middlewares []createLogMw, input *esync.SimxLogDto) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, nil) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input); err != nil { return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) } @@ -68,13 +91,13 @@ func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, return nil } -func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Soapi) error { +func (me *middlewareRunner) RunUpdateMiddleware(middlewares []updateMw, input *e.Soapi) error { for _, middleware := range middlewares { - logData := pu.GetLogData(input, data) + logData := pu.GetLogData(input, nil) pl.SetLogInfo(me.Event, logData, "started", middleware.Name) - if err := middleware.Func(input, data, me.Tx); err != nil { + if err := middleware.Func(input); err != nil { return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) } @@ -83,13 +106,13 @@ func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, inpu return nil } -func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Soapi) error { +func (me *middlewareRunner) RunDeleteMiddleware(middlewares []deleteMw, input *e.DeleteDto) error { for _, middleware := range middlewares { - logData := pu.GetLogData(input, data) + logData := pu.GetLogData(input, nil) pl.SetLogInfo(me.Event, logData, "started", middleware.Name) - if err := middleware.Func(input, data, me.Tx); err != nil { + if err := middleware.Func(input); err != nil { return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) } @@ -101,3 +124,10 @@ func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, inpu func (me *middlewareRunner) setMwType(mwType pu.MWType) { me.MwType = mwType } + +func (me *middlewareRunner) ExecuteIfSyncOn(fn func() error) error { + if !me.SyncOn { + return nil + } + return fn() +} diff --git a/internal/use-case/main-use-case/soapi/middleware.go b/internal/use-case/main-use-case/soapi/middleware.go index f2fecda5..049b0415 100644 --- a/internal/use-case/main-use-case/soapi/middleware.go +++ b/internal/use-case/main-use-case/soapi/middleware.go @@ -1,9 +1,17 @@ package soapi -// example of middleware -// func init() { -// createPreMw = append(createPreMw, -// CreateMw{Name: "modif-input", Func: pm.ModifInput}, -// CreateMw{Name: "check-data", Func: pm.CheckData}, -// ) -// } +import plugin "simrs-vx/internal/use-case/simgos-sync-plugin/new/soapi" + +func init() { + createPreMw = append(createPreMw, + createMw{Name: "sync-update-soapi", Func: plugin.Create}) + + createSimxLogMw = append(createSimxLogMw, + createLogMw{Name: "create-sync-log", Func: plugin.CreateLog}) + + updatePreMw = append(updatePreMw, + updateMw{Name: "sync-update-soapi", Func: plugin.Update}) + + deletePreMw = append(deletePreMw, + deleteMw{Name: "sync-delete-soapi", Func: plugin.Delete}) +} diff --git a/internal/use-case/main-use-case/soapi/tycovar.go b/internal/use-case/main-use-case/soapi/tycovar.go index 956193a4..aece45a5 100644 --- a/internal/use-case/main-use-case/soapi/tycovar.go +++ b/internal/use-case/main-use-case/soapi/tycovar.go @@ -12,11 +12,27 @@ import ( "gorm.io/gorm" e "simrs-vx/internal/domain/main-entities/soapi" + elog "simrs-vx/internal/domain/sync-entities/log" ) type createMw struct { Name string - Func func(input *e.CreateDto, data *e.Soapi, tx *gorm.DB) error + Func func(input *e.Soapi) error +} + +type createLogMw struct { + Name string + Func func(input *elog.SimxLogDto) error +} + +type updateMw struct { + Name string + Func func(input *e.Soapi) error +} + +type deleteMw struct { + Name string + Func func(input *e.DeleteDto) error } type readListMw struct { @@ -29,8 +45,8 @@ type readDetailMw struct { Func func(input *e.ReadDetailDto, data *e.Soapi, tx *gorm.DB) error } -type UpdateMw = readDetailMw -type DeleteMw = readDetailMw +type UpdateMw = updateMw +type DeleteMw = deleteMw var createPreMw []createMw // preprocess middleware var createPostMw []createMw // postprocess middleware @@ -38,7 +54,8 @@ var readListPreMw []readListMw // .. var readListPostMw []readListMw // .. var readDetailPreMw []readDetailMw var readDetailPostMw []readDetailMw -var updatePreMw []readDetailMw +var updatePreMw []updateMw var updatePostMw []readDetailMw -var deletePreMw []readDetailMw +var deletePreMw []deleteMw var deletePostMw []readDetailMw +var createSimxLogMw []createLogMw diff --git a/internal/use-case/simgos-sync-plugin/new/soapi/plugin.go b/internal/use-case/simgos-sync-plugin/new/soapi/plugin.go new file mode 100644 index 00000000..469384b7 --- /dev/null +++ b/internal/use-case/simgos-sync-plugin/new/soapi/plugin.go @@ -0,0 +1,36 @@ +package soapi + +import ( + "fmt" + sync "simrs-vx/internal/infra/sync-cfg" + helper "simrs-vx/internal/use-case/simgos-sync-plugin/new" + + e "simrs-vx/internal/domain/main-entities/soapi" + elog "simrs-vx/internal/domain/sync-entities/log" +) + +func Create(input *e.Soapi) error { + return helper.DoJsonRequest(input, "POST", getPrefixEndpoint()) +} + +func CreateLog(input *elog.SimxLogDto) error { + prefixEndpoint := getPrefixEndpoint() + endpoint := prefixEndpoint + "/log" + return helper.DoJsonRequest(input, "POST", endpoint) +} + +func Update(input *e.Soapi) error { + prefixEndpoint := getPrefixEndpoint() + endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, input.Id) + return helper.DoJsonRequest(input, "PATCH", endpoint) +} + +func Delete(input *e.DeleteDto) error { + prefixEndpoint := getPrefixEndpoint() + endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, input.Id) + return helper.DoJsonRequest(input, "DELETE", endpoint) +} + +func getPrefixEndpoint() string { + return fmt.Sprintf("%s%s/v1/encounter", sync.O.TargetHost, sync.O.Prefix) +} diff --git a/internal/use-case/simgos-sync-use-case/new/encounter/case.go b/internal/use-case/simgos-sync-use-case/new/encounter/case.go index 969e8ff3..5e353d1f 100644 --- a/internal/use-case/simgos-sync-use-case/new/encounter/case.go +++ b/internal/use-case/simgos-sync-use-case/new/encounter/case.go @@ -35,24 +35,24 @@ func Create(input e.Encounter) (*d.Data, error) { pl.SetLogInfo(&event, input, "started", "create") err = db.WithDualTx(func(tx *db.Dualtx) error { - // STEP 1: Insert to simgos + // STEP 1: Insert TPendaftaran sgData, err = CreateTPendaftaranData(input, &event, tx.Simgos) if err != nil { return err } - // STEP 2: Insert to Link - syncLink, err = CreateLinkData(input.Id, sgData.Idxdaftar, &event, tx.Sync) - if err != nil { - return err - } - // STEP 3: Update MPasien err = updatePatientCaraBayar(*sgData, &event, tx.Simgos) if err != nil { return err } + // STEP 2: Insert to Link + syncLink, err = CreateLinkData(input.Id, sgData.Idxdaftar, &event, tx.Sync) + if err != nil { + return err + } + return nil }) diff --git a/internal/use-case/simgos-sync-use-case/new/soapi/case.go b/internal/use-case/simgos-sync-use-case/new/soapi/case.go index 4124b7f6..d7e9bcc4 100644 --- a/internal/use-case/simgos-sync-use-case/new/soapi/case.go +++ b/internal/use-case/simgos-sync-use-case/new/soapi/case.go @@ -8,18 +8,19 @@ import ( db "simrs-vx/pkg/dualtrx-helper" - e "simrs-vx/internal/domain/main-entities/division" - esimgos "simrs-vx/internal/domain/simgos-entities/m-unit" - esync "simrs-vx/internal/domain/sync-entities/division" + e "simrs-vx/internal/domain/main-entities/soapi" + elog "simrs-vx/internal/domain/sync-entities/log" + esync "simrs-vx/internal/domain/sync-entities/soapi" + + ue "simrs-vx/internal/use-case/simgos-sync-use-case/new/encounter" ) const source = "soapi" -func Create(input e.CreateDto) (*d.Data, error) { +func Create(input e.Soapi) (*d.Data, error) { var ( - sgData *esimgos.MUnit - syncLink *esync.DivisionLink + syncLink *esync.SoapiLink err error ) @@ -31,15 +32,39 @@ func Create(input e.CreateDto) (*d.Data, error) { // Start log pl.SetLogInfo(&event, input, "started", "create") + // get encounter Link + eLink, err := ue.ReadDetailLinkData(*input.Encounter_Id, &event) + if err != nil { + return nil, err + } + + // get Tpendaftaran + tPendaftaran, err := ue.ReadTPendaftaranDetailData(eLink.Simgos_Id, &event) + if err != nil { + return nil, err + } + err = db.WithDualTx(func(tx *db.Dualtx) error { - // STEP 1: Insert to simgos - sgData, err = CreateSimgosData(input, &event, tx.Simgos) + // STEP 1: Insert to TDiagnosaDanTerapi + tDiagTherapy, err := CreateTDiagnosaDanTerapi(input, tPendaftaran, &event, tx.Simgos) if err != nil { return err } - // STEP 2: Insert to Link - syncLink, err = CreateLinkData(*input.Id, sgData.KodeUnit, &event, tx.Sync) + // STEP 2: Insert to TICD + _, err = CreateTIcd(input, tPendaftaran, &event, tx.Simgos) + if err != nil { + return err + } + + // STEP 3: Insert to TICD-CM + _, err = CreateTIcdCm(input, tPendaftaran, &event, tx.Simgos) + if err != nil { + return err + } + + // STEP 4: Insert to Link + syncLink, err = CreateLinkData(input.Id, tDiagTherapy.Idxterapi, &event, tx.Sync) if err != nil { return err } @@ -99,7 +124,7 @@ func CreateSimxLog(input elog.SimxLogDto) (*d.Data, error) { }, nil } -func Update(input e.UpdateDto) (*d.Data, error) { +func Update(input e.Soapi) (*d.Data, error) { event := pl.Event{ Feature: "Update", Source: source, @@ -108,16 +133,59 @@ func Update(input e.UpdateDto) (*d.Data, error) { // Start log pl.SetLogInfo(&event, input, "started", "update") - // STEP 1: Get Link - syncLink, err := ReadDetailLinkData(*input.Id, &event) + // Get Soapi Link + sLink, err := ReadDetailLinkData(input.Id, &event) + if err != nil { + return nil, err + } + + // Get TDiagnosadanTerapi + tDiagTherapy, err := ReadDetailTDiagnosaDanTerapi(sLink.Simgos_Id, &event) + if err != nil { + return nil, err + } + + // Get Encounter Link + eLink, err := ue.ReadDetailLinkData(*input.Encounter_Id, &event) + if err != nil { + return nil, err + } + + // Get TPendaftaran + tPendaftaran, err := ue.ReadTPendaftaranDetailData(eLink.Simgos_Id, &event) if err != nil { return nil, err } tx := db.NewTx() err = tx.Simgos.Transaction(func(tx *gorm.DB) error { - // Step 2: Update Simgos - if err = UpdateSimgosData(input, syncLink, &event, tx); err != nil { + // SET LOCAL + if err = tx.Exec(`SET LOCAL simx.sync_source = 'new'`).Error; err != nil { + return err + } + + // Step 1: Update TDiagnosaDanTerapi + if err = UpdateTDiagnosaDanTerapi(input, tDiagTherapy, &event, tx); err != nil { + return err + } + + // STEP 2: Delete TIcd + if err = HardDeleteTIcd(tDiagTherapy.Idxdaftar, &event, tx); err != nil { + return err + } + + // STEP 3: Delete TIcdCm + if err = HardDeleteTIcdCm(tDiagTherapy.Idxdaftar, &event, tx); err != nil { + return err + } + + // STEP 4: Insert TIcd + if _, err = CreateTIcd(input, tPendaftaran, &event, tx); err != nil { + return err + } + + // STEP 5: Insert TIcd-cm + if _, err = CreateTIcdCm(input, tPendaftaran, &event, tx); err != nil { return err } @@ -146,22 +214,31 @@ func Delete(input e.DeleteDto) (*d.Data, error) { // Start log pl.SetLogInfo(&event, input, "started", "delete") - // STEP 1: Get Link - syncLink, err := ReadDetailLinkData(*input.Id, &event) + // Get Soapi Link + syncLink, err := ReadDetailLinkData(input.Id, &event) if err != nil { return nil, err } - // STEP 2: Get Simgos - sgData, err := ReadDetailSimgosData(uint16(syncLink.Simgos_Id), &event) + // Get TDiagnosa&Terapi + tDiagTh, err := ReadDetailTDiagnosaDanTerapi(syncLink.Simgos_Id, &event) if err != nil { return nil, err } err = db.WithDualTx(func(tx *db.Dualtx) error { - // STEP 3: Delete Simgos - err = HardDeleteSimgosData(sgData, &event, tx.Simgos) - if err != nil { + // STEP 1: Delete TDiagnosa&Terapi Simgos + if err = HardDeleteTDiagnosaDanTerapi(tDiagTh, &event, tx.Simgos); err != nil { + return err + } + + // STEP 2: Delete TIcd + if err = HardDeleteTIcd(tDiagTh.Idxdaftar, &event, tx.Simgos); err != nil { + return err + } + + // STEP 3: Delete TIcdCm + if err = HardDeleteTIcdCm(tDiagTh.Idxdaftar, &event, tx.Simgos); err != nil { return err } @@ -178,7 +255,7 @@ func Delete(input e.DeleteDto) (*d.Data, error) { if err != nil { if isLinkDeleted { go func() { - _, _ = CreateLinkData(uint(*input.Id), sgData.KodeUnit, &event) + _, _ = CreateLinkData(input.Id, tDiagTh.Idxterapi, &event) }() } return nil, err diff --git a/internal/use-case/simgos-sync-use-case/new/soapi/helper.go b/internal/use-case/simgos-sync-use-case/new/soapi/helper.go index 90dbd4ff..65213761 100644 --- a/internal/use-case/simgos-sync-use-case/new/soapi/helper.go +++ b/internal/use-case/simgos-sync-use-case/new/soapi/helper.go @@ -9,24 +9,56 @@ import ( "fmt" ere "simrs-vx/internal/domain/references/encounter" "strconv" + "time" ercl "simrs-vx/internal/domain/references/clinical" erc "simrs-vx/internal/domain/references/common" es "simrs-vx/internal/domain/main-entities/soapi" - esimgos "simrs-vx/internal/domain/simgos-entities/t-diagnosadanterapi" + etdt "simrs-vx/internal/domain/simgos-entities/t-diagnosadanterapi" + eicd "simrs-vx/internal/domain/simgos-entities/t-icd" + eicdcm "simrs-vx/internal/domain/simgos-entities/t-icd-cm" + etp "simrs-vx/internal/domain/simgos-entities/t-pendaftaran" + esyncLog "simrs-vx/internal/domain/sync-entities/log" esync "simrs-vx/internal/domain/sync-entities/soapi" ) -func setDataEarlyMedic(input es.Soapi) (data esimgos.DiagnosaDanTerapi) { +func setDataCreateTDiagnosaDanTerapi(input es.Soapi, enc *etp.TPendaftaran) (data etdt.TDiagnosaDanTerapi) { + switch input.TypeCode { + case ercl.STCEEarlyMedic: + data.Idxdaftar = enc.Idxdaftar + data.Nomr = enc.Nomr + data.Kdpoly = enc.Kdpoly + data.Kddokter = enc.Kddokter + + if e := input.Encounter; e != nil { + data.Tanggal = e.VisitDate + if e.Class_Code == ere.ECAmbulatory { + data.Rajal = 1 + } + + } + + if e := input.Employee; e != nil { + if u := e.User; u != nil { + data.Nip = u.Name + } + } + + setEarlyMedicTDT(input, &data) + return + } + + return +} + +func setEarlyMedicTDT(input es.Soapi, data *etdt.TDiagnosaDanTerapi) { value := ercl.EarlyMedicValue{} _ = json.Unmarshal([]byte(*input.Value), &value) - data.Idxdaftar = *input.Encounter_Id data.TekananDarah = fmt.Sprintf("%v/%v", value.SystolicBloodPressure, value.DiastolicBloodPressure) - data.GolonganDarah = value.BloodType if value.BloodType == "" { data.GolonganDarah = "X" @@ -38,27 +70,6 @@ func setDataEarlyMedic(input es.Soapi) (data esimgos.DiagnosaDanTerapi) { data.Terapi = value.Therapy data.Anamnesa = value.PrimaryComplain - if e := input.Encounter; e != nil { - if p := e.Patient; p != nil { - data.Nomr = *p.Number - } - - data.Tanggal = e.VisitDate - data.Kdpoly = stringtouint(*e.Unit_Code) - data.Kddokter = stringtouint(*e.Appointment_Doctor_Code) - - if e.Class_Code == ere.ECAmbulatory { - data.Rajal = 1 - } - - } - - if e := input.Employee; e != nil { - if u := e.User; u != nil { - data.Nip = u.Name - } - } - // TODO : status, tindakan_mdeis (?) data.KunjunganBl = uint(value.EncounterStatus) data.KasusBl = uint(value.CaseStatus) @@ -79,14 +90,77 @@ func setDataEarlyMedic(input es.Soapi) (data esimgos.DiagnosaDanTerapi) { if o := value.ExpectedOutcome; len(o) > 0 { expectedOutput := []string{} - for _, v := range o { expectedOutput = append(expectedOutput, v.Name) } - jsonData, _ := json.MarshalIndent(value.ExpectedOutcome, "", " ") data.TargetCapaian = string(jsonData) } + return +} + +func setDataIcd(input es.Soapi, enc *etp.TPendaftaran) (data []eicd.TIcd) { + value := ercl.EarlyMedicValue{} + _ = json.Unmarshal([]byte(*input.Value), &value) + + var ( + visitDate time.Time + ambulatory uint16 + ) + + if e := input.Encounter; e != nil { + visitDate = e.VisitDate + if e.Class_Code == ere.ECAmbulatory { + ambulatory = 1 + } + + } + + if d := value.DiagnoseSrc; len(d) > 0 { + for _, v := range d { + data = append(data, eicd.TIcd{ + Nomr: enc.Nomr, + Idxdaftar: enc.Idxdaftar, + Kddokter: enc.Kddokter, + Icd: v.Code, + StatusRajal: ambulatory, + Tanggal: visitDate, + }) + } + } + + return +} + +func setDataIcdCm(input es.Soapi, enc *etp.TPendaftaran) (data []eicdcm.TIcdCm) { + value := ercl.EarlyMedicValue{} + _ = json.Unmarshal([]byte(*input.Value), &value) + + var ( + visitDate time.Time + ambulatory uint16 + ) + + if e := input.Encounter; e != nil { + visitDate = e.VisitDate + if e.Class_Code == ere.ECAmbulatory { + ambulatory = 1 + } + + } + + if p := value.ProcedureSrc; len(p) > 0 { + for _, v := range p { + data = append(data, eicdcm.TIcdCm{ + Nomr: enc.Nomr, + Idxdaftar: enc.Idxdaftar, + Kddokter: enc.Kddokter, + Icd: v.Code, + StatusRajal: ambulatory, + Tanggal: visitDate, + }) + } + } return } diff --git a/internal/use-case/simgos-sync-use-case/new/soapi/lib.go b/internal/use-case/simgos-sync-use-case/new/soapi/lib.go index 7abdfe0a..af27a791 100644 --- a/internal/use-case/simgos-sync-use-case/new/soapi/lib.go +++ b/internal/use-case/simgos-sync-use-case/new/soapi/lib.go @@ -1,6 +1,7 @@ package soapi import ( + "errors" plh "simrs-vx/pkg/lib-helper" pl "simrs-vx/pkg/logger" pu "simrs-vx/pkg/use-case-helper" @@ -9,18 +10,22 @@ import ( dg "github.com/karincake/apem/db-gorm-pg" "gorm.io/gorm" - e "simrs-vx/internal/domain/main-entities/division" - esimgos "simrs-vx/internal/domain/simgos-entities/m-unit" - esync "simrs-vx/internal/domain/sync-entities/division" + e "simrs-vx/internal/domain/main-entities/soapi" + + etdt "simrs-vx/internal/domain/simgos-entities/t-diagnosadanterapi" + eicd "simrs-vx/internal/domain/simgos-entities/t-icd" + eicdcm "simrs-vx/internal/domain/simgos-entities/t-icd-cm" + ep "simrs-vx/internal/domain/simgos-entities/t-pendaftaran" + esynclog "simrs-vx/internal/domain/sync-entities/log" + esync "simrs-vx/internal/domain/sync-entities/soapi" ) var now = time.Now() -func CreateSimgosData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*esimgos.MUnit, error) { +func CreateTDiagnosaDanTerapi(input e.Soapi, tdaftar *ep.TPendaftaran, event *pl.Event, dbx ...*gorm.DB) (*etdt.TDiagnosaDanTerapi, error) { pl.SetLogInfo(event, nil, "started", "DBCreate") - - data := setDataSimgos(&input) + data := setDataCreateTDiagnosaDanTerapi(input, tdaftar) var tx *gorm.DB if len(dbx) > 0 { @@ -37,14 +42,14 @@ func CreateSimgosData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*esi return &data, nil } -func ReadDetailSimgosData(simgosId uint16, event *pl.Event) (*esimgos.MUnit, error) { +func ReadDetailTDiagnosaDanTerapi(simgosId uint, event *pl.Event) (*etdt.TDiagnosaDanTerapi, error) { pl.SetLogInfo(event, simgosId, "started", "DBReadDetail") - data := esimgos.MUnit{} + data := etdt.TDiagnosaDanTerapi{} var tx = dg.IS["simrs"] if err := tx. - Where("\"kode_unit\" = ?", simgosId). + Where("\"idxterapi\" = ?", simgosId). First(&data).Error; err != nil { if processedErr := pu.HandleReadError(err, event, source, simgosId, data); processedErr != nil { return nil, processedErr @@ -55,11 +60,10 @@ func ReadDetailSimgosData(simgosId uint16, event *pl.Event) (*esimgos.MUnit, err return &data, nil } -func UpdateSimgosData(input e.UpdateDto, dataSimgos *esync.DivisionLink, event *pl.Event, dbx ...*gorm.DB) error { +func UpdateTDiagnosaDanTerapi(input e.Soapi, data *etdt.TDiagnosaDanTerapi, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, input, "started", "DBUpdate") - data := setDataSimgos(&input) - data.KodeUnit = dataSimgos.Simgos_Id + setEarlyMedicTDT(input, data) var tx *gorm.DB if len(dbx) > 0 { @@ -82,7 +86,7 @@ func UpdateSimgosData(input e.UpdateDto, dataSimgos *esync.DivisionLink, event * return nil } -func HardDeleteSimgosData(data *esimgos.MUnit, event *pl.Event, dbx ...*gorm.DB) error { +func HardDeleteTDiagnosaDanTerapi(data *etdt.TDiagnosaDanTerapi, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, data, "started", "DBDelete") var tx *gorm.DB @@ -107,7 +111,149 @@ func HardDeleteSimgosData(data *esimgos.MUnit, event *pl.Event, dbx ...*gorm.DB) return nil } -func CreateLinkData(simxId, simgosId uint, event *pl.Event, dbx ...*gorm.DB) (*esync.DivisionLink, error) { +func CreateTIcd(input e.Soapi, tdaftar *ep.TPendaftaran, event *pl.Event, dbx ...*gorm.DB) (*[]eicd.TIcd, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + data := setDataIcd(input, tdaftar) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.IS["simrs"] + } + + if err := tx.Create(&data).Error; err != nil { + return nil, plh.HandleCreateError(input, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func ReadListTIcd(idxdaftar string, event *pl.Event, dbx ...*gorm.DB) ([]eicd.TIcd, error) { + pl.SetLogInfo(event, idxdaftar, "started", "DBReadList") + data := []eicd.TIcd{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + tx = tx. + Model(&eicd.TIcd{}). + Where("idxdaftar = ?", idxdaftar) + + if err := tx.Find(&data).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, nil + } + return nil, plh.HandleListError(idxdaftar, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return data, nil +} + +func HardDeleteTIcd(idxdaftar uint, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, idxdaftar, "started", "DBDelete") + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.IS["simrs"] + } + + if err := tx. + Where("idxdaftar = ?", idxdaftar). + Delete(&eicd.TIcd{}).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-delete-fail", + Detail: "Database delete failed", + Raw: err, + } + return pl.SetLogError(event, idxdaftar) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} + +func CreateTIcdCm(input e.Soapi, tdaftar *ep.TPendaftaran, event *pl.Event, dbx ...*gorm.DB) (*[]eicdcm.TIcdCm, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + data := setDataIcdCm(input, tdaftar) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.IS["simrs"] + } + + if err := tx.Create(&data).Error; err != nil { + return nil, plh.HandleCreateError(input, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func ReadListTIcdCm(idxdaftar string, event *pl.Event, dbx ...*gorm.DB) ([]eicdcm.TIcdCm, error) { + pl.SetLogInfo(event, idxdaftar, "started", "DBReadList") + data := []eicdcm.TIcdCm{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + tx = tx. + Model(&eicdcm.TIcdCm{}). + Where("idxdaftar = ?", idxdaftar) + + if err := tx.Find(&data).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, nil + } + return nil, plh.HandleListError(idxdaftar, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return data, nil +} + +func HardDeleteTIcdCm(idxdaftar uint, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, idxdaftar, "started", "DBDelete") + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.IS["simrs"] + } + + if err := tx. + Where("idxdaftar = ?", idxdaftar). + Delete(&eicdcm.TIcdCm{}).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-delete-fail", + Detail: "Database delete failed", + Raw: err, + } + return pl.SetLogError(event, idxdaftar) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} + +func CreateLinkData(simxId, simgosId uint, event *pl.Event, dbx ...*gorm.DB) (*esync.SoapiLink, error) { pl.SetLogInfo(event, nil, "started", "DBCreate") data := setDataSimxLink(simxId, simgosId) @@ -126,9 +272,9 @@ func CreateLinkData(simxId, simgosId uint, event *pl.Event, dbx ...*gorm.DB) (*e return &data, nil } -func ReadDetailLinkData(simxId uint16, event *pl.Event) (*esync.DivisionLink, error) { +func ReadDetailLinkData(simxId uint, event *pl.Event) (*esync.SoapiLink, error) { pl.SetLogInfo(event, simxId, "started", "DBReadDetail") - data := esync.DivisionLink{} + data := esync.SoapiLink{} var tx = dg.I @@ -144,7 +290,7 @@ func ReadDetailLinkData(simxId uint16, event *pl.Event) (*esync.DivisionLink, er return &data, nil } -func DeleteLinkData(data *esync.DivisionLink, event *pl.Event, dbx ...*gorm.DB) error { +func DeleteLinkData(data *esync.SoapiLink, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, data, "started", "DBDelete") var tx *gorm.DB diff --git a/internal/use-case/simgos-sync-use-case/new/soapi/middleware.go b/internal/use-case/simgos-sync-use-case/new/soapi/middleware.go index f2fecda5..1fa07628 100644 --- a/internal/use-case/simgos-sync-use-case/new/soapi/middleware.go +++ b/internal/use-case/simgos-sync-use-case/new/soapi/middleware.go @@ -1,9 +1 @@ package soapi - -// example of middleware -// func init() { -// createPreMw = append(createPreMw, -// CreateMw{Name: "modif-input", Func: pm.ModifInput}, -// CreateMw{Name: "check-data", Func: pm.CheckData}, -// ) -// } From 547a54cbe4a93107c96af30f1c6599cdca5d163c Mon Sep 17 00:00:00 2001 From: poetrasapoetra Date: Wed, 3 Dec 2025 10:37:50 +0700 Subject: [PATCH 14/42] Fix CUD Patient --- .../domain/simgos-entities/m-pasien/dto.go | 26 ++- .../old/patient/handler.go | 82 ++------- .../simgos-sync-use-case/old/patient/case.go | 166 ++++++++++++++++++ .../old/patient/helper.go | 69 ++++++++ .../simgos-sync-use-case/old/patient/lib.go | 19 ++ .../old/patient/tycovar.go | 14 ++ 6 files changed, 290 insertions(+), 86 deletions(-) create mode 100644 internal/use-case/simgos-sync-use-case/old/patient/case.go create mode 100644 internal/use-case/simgos-sync-use-case/old/patient/helper.go create mode 100644 internal/use-case/simgos-sync-use-case/old/patient/lib.go create mode 100644 internal/use-case/simgos-sync-use-case/old/patient/tycovar.go diff --git a/internal/domain/simgos-entities/m-pasien/dto.go b/internal/domain/simgos-entities/m-pasien/dto.go index 68a2d068..8d2c3368 100644 --- a/internal/domain/simgos-entities/m-pasien/dto.go +++ b/internal/domain/simgos-entities/m-pasien/dto.go @@ -2,12 +2,12 @@ package m_pasien import ( "fmt" + ecore "simrs-vx/internal/domain/base-entities/core" e "simrs-vx/internal/domain/main-entities/patient" pr "simrs-vx/internal/domain/main-entities/person" pa "simrs-vx/internal/domain/main-entities/person-address" pab "simrs-vx/internal/domain/main-entities/person-address/base" pc "simrs-vx/internal/domain/main-entities/person-contact" - cm "simrs-vx/internal/domain/references/common" rf "simrs-vx/internal/domain/references/person" "time" @@ -89,8 +89,9 @@ type MPasienDto struct { func (mp MPasienDto) ToPatient() e.Patient { patient := e.Patient{ - // TODO get patient person_id from database - Person_Id: &mp.Id, + Main: ecore.Main{ + Id: mp.Id, + }, NewBornStatus: mp.ParentNomr != nil, RegisteredAt: parseTimeDateOnly(mp.Tgldaftar), RegisteredBy_User_Name: mp.Nip, @@ -116,9 +117,9 @@ func (mp MPasienDto) ToPatient() e.Patient { BirthDate: parseTimeDateOnly(mp.Tgllahir), BirthRegency_Code: &bc, Gender_Code: &gc, - ResidentIdentityNumber: nilEmptyString(mp.Noktp), - PassportNumber: nilEmptyString(*mp.Paspor), - DrivingLicenseNumber: nilEmptyString(*mp.Sim), + ResidentIdentityNumber: nilEmptyString(&mp.Noktp), + PassportNumber: nilEmptyString(mp.Paspor), + DrivingLicenseNumber: nilEmptyString(mp.Sim), Religion_Code: &rc, Education_Code: &ec, Ocupation_Name: &mp.Pekerjaan, @@ -166,18 +167,11 @@ func (mp MPasienDto) ToPatient() e.Patient { return patient } -func getActiveStatus(s uint) cm.ActiveStatusCode { - if s == 1 { - return cm.SCActive - } - return cm.SCInactive -} - -func nilEmptyString(s string) *string { - if s == "" { +func nilEmptyString(s *string) *string { + if s == nil { return nil } - return &s + return s } func getGender(g string) rf.GenderCode { diff --git a/internal/interface/simgos-sync-handler/old/patient/handler.go b/internal/interface/simgos-sync-handler/old/patient/handler.go index b794de07..4c697fd4 100644 --- a/internal/interface/simgos-sync-handler/old/patient/handler.go +++ b/internal/interface/simgos-sync-handler/old/patient/handler.go @@ -1,14 +1,10 @@ package patient import ( - "bytes" - "encoding/json" - "fmt" - "io" "net/http" p "simrs-vx/internal/domain/simgos-entities/m-pasien" - cfg "simrs-vx/internal/infra/sync-cfg" + uo "simrs-vx/internal/use-case/simgos-sync-use-case/old/patient" rw "github.com/karincake/risoles" ) @@ -22,85 +18,31 @@ func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { if !rw.ValidateStructByIOR(w, r.Body, &dto) { return } - // translate m_pasien ke Patient + + // mapping m_patient to patient patient := dto.ToPatient() - jsonPatient, err := json.Marshal(patient) - if err != nil { - fmt.Println(err) - } - // fmt.Println(string(jsonPatient)) - // kirim request ke api sim-baru - reqBody := bytes.NewBuffer(jsonPatient) - err = send(http.MethodPost, "patient", reqBody) - if err != nil { - fmt.Println("request error:", err) - } + res, err := uo.Create(patient) + rw.DataResponse(w, res, err) } + func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { + dto := p.MPasienDto{} if !rw.ValidateStructByIOR(w, r.Body, &dto) { return } patient := dto.ToPatient() - // TODO DELETE BELOW, - var ( - personId uint = 68 - patientId uint = 34 - ) - patient.Person_Id = &personId - patient.Id = patientId - patient.Person.Id = personId - // TODO DELETE ABOVE - jsonPatient, err := json.MarshalIndent(patient, "", " ") - if err != nil { - fmt.Println(err) - } - fmt.Println(string(jsonPatient)) - url := fmt.Sprintf("%s%v", "patient/", patient.Id) - fmt.Println(url) - reqBody := bytes.NewBuffer(jsonPatient) - err = send(http.MethodPatch, url, reqBody) - if err != nil { - fmt.Println("request error:", err) - } + res, err := uo.Update(patient) + rw.DataResponse(w, res, err) } + func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { dto := p.MPasienDto{} if !rw.ValidateStructByIOR(w, r.Body, &dto) { return } patient := dto.ToPatient() - jsonPatient, err := json.Marshal(patient) - if err != nil { - fmt.Println(err) - } - reqBody := bytes.NewBuffer(jsonPatient) - err = send(http.MethodDelete, fmt.Sprintf("%s%v", "patient/", *patient.Person_Id), reqBody) - if err != nil { - fmt.Println("request error:", err) - } -} -func (obj myBase) CreateLog(w http.ResponseWriter, r *http.Request) { - -} - -func send(method string, endpoint string, body *bytes.Buffer) error { - var url string = cfg.O.NewHost + endpoint - req, err := http.NewRequest(method, url, body) - if err != nil { - return err - } - req.Header.Set("Content-Type", "application/json") - req.Header.Set("X-Sync-Source", cfg.O.OldSource) - req.Header.Set("X-Sync-SecretKey", cfg.O.NewSecretKey) - req.Header.Set("X-Sync-UserName", "dave") - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - respBody, _ := io.ReadAll(resp.Body) - fmt.Println(resp.StatusCode, string(respBody), method, url) - return nil + res, err := uo.Delete(patient) + rw.DataResponse(w, res, err) } diff --git a/internal/use-case/simgos-sync-use-case/old/patient/case.go b/internal/use-case/simgos-sync-use-case/old/patient/case.go new file mode 100644 index 00000000..ae52e37a --- /dev/null +++ b/internal/use-case/simgos-sync-use-case/old/patient/case.go @@ -0,0 +1,166 @@ +package patient + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + + cfg "simrs-vx/internal/infra/sync-cfg" + pl "simrs-vx/pkg/logger" + + e "simrs-vx/internal/domain/main-entities/patient" + un "simrs-vx/internal/use-case/simgos-sync-use-case/new/patient" + + d "github.com/karincake/dodol" +) + +const source = "old-to-new-patient" + +var path = "patient" + +func Create(input e.Patient) (*d.Data, error) { + evt := pl.Event{ + Feature: "Create", + Source: source, + } + + pl.SetLogInfo(&evt, input, "started", "create") + + // create request body + jsonPatient, err := json.Marshal(input) + if err != nil { + return nil, pl.SetLogError(&evt, input) + } + reqBody := bytes.NewBuffer(jsonPatient) + // send data to main-api + resp, err := send(http.MethodPost, path, reqBody) + if err != nil { + return nil, pl.SetLogError(&evt, input) + } + // getting response + var data MainApiResp + err = json.Unmarshal(resp, &data) + if err != nil { + return nil, pl.SetLogError(&evt, string(resp)) + } + // create PatientLink + un.CreateLinkData(data.Data.Id, input.Id, &evt) + pl.SetLogInfo(&evt, nil, "complete") + return &d.Data{ + Meta: d.II{ + "source": source, + "structure": "single-data", + "status": "created", + }, + Data: input.ToResponse(), + }, nil +} + +func Update(input e.Patient) (*d.Data, error) { + evt := pl.Event{ + Feature: "Update", + Source: source, + } + pl.SetLogInfo(&evt, input, "started", "update") + + // get patient link from database + patientLink, err := ReadDetailLinkData(input.Id) + if err != nil { + return nil, pl.SetLogError(&evt, input) + } + + // get data patient from main-api + resp, err := send(http.MethodGet, fmt.Sprintf("%s%v", "patient/", patientLink.Simx_Id), nil) + if err != nil { + return nil, pl.SetLogError(&evt, input) + } + // unpack data from resp + var respData MainApiResp + err = json.Unmarshal(resp, &respData) + if err != nil { + return nil, pl.SetLogError(&evt, input) + } + + // copy data from simgos m_patient to simx Patient + preserve := map[string]bool{ + "Main.Id": true, + "Person.Id": true, + } + simxPatient := respData.Data + SetPatient(&simxPatient, &input, preserve) + + jsonPatient, err := json.Marshal(simxPatient) + if err != nil { + return nil, pl.SetLogError(&evt, input) + } + + // send data to main api + url := fmt.Sprintf("%s%v", "patient/", simxPatient.Id) + reqBody := bytes.NewBuffer(jsonPatient) + _, err = send(http.MethodPatch, url, reqBody) + if err != nil { + return nil, pl.SetLogError(&evt, input) + } + + pl.SetLogInfo(&evt, nil, "complete") + return &d.Data{ + Meta: d.II{ + "source": source, + "structure": "single-data", + "status": "updated", + }, + Data: input.ToResponse(), + }, nil +} + +func Delete(input e.Patient) (*d.Data, error) { + evt := pl.Event{ + Feature: "Delete", + Source: source, + } + pl.SetLogInfo(&evt, input, "started", "delete") + + // get patient link from database + patientLink, err := ReadDetailLinkData(input.Id) + if err != nil { + return nil, err + } + _, err = send(http.MethodDelete, fmt.Sprintf("%s%v", "patient/", patientLink.Simx_Id), nil) + if err != nil { + return nil, err + } + return &d.Data{ + Meta: d.II{ + "source": source, + "structure": "single-data", + "status": "deleted", + }, + Data: input.ToResponse(), + }, nil +} + +func send(method string, endpoint string, body *bytes.Buffer) ([]byte, error) { + var url string = cfg.O.NewHost + endpoint + var reader io.Reader = nil + if body != nil { + reader = body + } + req, err := http.NewRequest(method, url, reader) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Sync-Source", cfg.O.OldSource) + req.Header.Set("X-Sync-SecretKey", cfg.O.NewSecretKey) + // TODO get use username from patient, migreate database first + req.Header.Set("X-Sync-UserName", "dave") + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + respBody, _ := io.ReadAll(resp.Body) + return respBody, nil +} diff --git a/internal/use-case/simgos-sync-use-case/old/patient/helper.go b/internal/use-case/simgos-sync-use-case/old/patient/helper.go new file mode 100644 index 00000000..2d89bff9 --- /dev/null +++ b/internal/use-case/simgos-sync-use-case/old/patient/helper.go @@ -0,0 +1,69 @@ +package patient + +import ( + "reflect" + "strings" +) + +func SetPatient(dst, src interface{}, preserve map[string]bool) { + dv := reflect.ValueOf(dst).Elem() + sv := reflect.ValueOf(src).Elem() + + for i := 0; i < dv.NumField(); i++ { + f := dv.Type().Field(i) + fieldName := f.Name + + // skip preserved fields + if preserve[fieldName] { + continue + } + + df := dv.Field(i) + sf := sv.Field(i) + if !df.CanSet() { + // skip unexported skip + continue + } + + switch df.Kind() { + + case reflect.Struct: + nestedPreserve := map[string]bool{} + + for key := range preserve { + if strings.HasPrefix(key, fieldName+".") { + nestedPreserve[strings.TrimPrefix(key, fieldName+".")] = true + } + } + + SetPatient(df.Addr().Interface(), sf.Addr().Interface(), nestedPreserve) + case reflect.Pointer: + // Check if pointer points to a struct + if df.Type().Elem().Kind() == reflect.Struct { + if sf.IsNil() { + break + } + + // If dest pointer is nil, allocate it + if df.IsNil() { + df.Set(reflect.New(df.Type().Elem())) + } + + // Recurse into struct via Elem() + nestedPreserve := map[string]bool{} + for key := range preserve { + if strings.HasPrefix(key, fieldName+".") { + nestedPreserve[strings.TrimPrefix(key, fieldName+".")] = true + } + } + + SetPatient(df.Elem().Addr().Interface(), sf.Elem().Addr().Interface(), nestedPreserve) + } + default: + // Overwrite only when src has non-zero value + if !sf.IsZero() { + df.Set(sf) + } + } + } +} diff --git a/internal/use-case/simgos-sync-use-case/old/patient/lib.go b/internal/use-case/simgos-sync-use-case/old/patient/lib.go new file mode 100644 index 00000000..d6b5f470 --- /dev/null +++ b/internal/use-case/simgos-sync-use-case/old/patient/lib.go @@ -0,0 +1,19 @@ +package patient + +import ( + esync "simrs-vx/internal/domain/sync-entities/patient" + + dg "github.com/karincake/apem/db-gorm-pg" +) + +func ReadDetailLinkData(simgosId uint) (*esync.PatientLink, error) { + // log event + var data esync.PatientLink + var tx = dg.I + + if err := tx.Where("\"Simgos_Id\" = ?", simgosId).First(&data).Error; err != nil { + return nil, err + } + // log end event + return &data, nil +} diff --git a/internal/use-case/simgos-sync-use-case/old/patient/tycovar.go b/internal/use-case/simgos-sync-use-case/old/patient/tycovar.go new file mode 100644 index 00000000..15d99d0f --- /dev/null +++ b/internal/use-case/simgos-sync-use-case/old/patient/tycovar.go @@ -0,0 +1,14 @@ +package patient + +import e "simrs-vx/internal/domain/main-entities/patient" + +type MainApiResp struct { + Meta MetaData `json:"meta"` + Data e.Patient `json:"data"` +} + +type MetaData struct { + Source string `json:"source"` + Status string `json:"status"` + Structure string `json:"structure"` +} From 11ed6e3ad5d3053b1d249207b78239067807efc4 Mon Sep 17 00:00:00 2001 From: poetrasapoetra Date: Wed, 3 Dec 2025 10:48:19 +0700 Subject: [PATCH 15/42] Using username from m_pasien.nip --- .../simgos-sync-use-case/old/patient/case.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/internal/use-case/simgos-sync-use-case/old/patient/case.go b/internal/use-case/simgos-sync-use-case/old/patient/case.go index ae52e37a..09afa2bd 100644 --- a/internal/use-case/simgos-sync-use-case/old/patient/case.go +++ b/internal/use-case/simgos-sync-use-case/old/patient/case.go @@ -35,7 +35,7 @@ func Create(input e.Patient) (*d.Data, error) { } reqBody := bytes.NewBuffer(jsonPatient) // send data to main-api - resp, err := send(http.MethodPost, path, reqBody) + resp, err := send(http.MethodPost, path, reqBody, *input.RegisteredBy_User_Name) if err != nil { return nil, pl.SetLogError(&evt, input) } @@ -72,7 +72,7 @@ func Update(input e.Patient) (*d.Data, error) { } // get data patient from main-api - resp, err := send(http.MethodGet, fmt.Sprintf("%s%v", "patient/", patientLink.Simx_Id), nil) + resp, err := send(http.MethodGet, fmt.Sprintf("%s%v", "patient/", patientLink.Simx_Id), nil, *input.RegisteredBy_User_Name) if err != nil { return nil, pl.SetLogError(&evt, input) } @@ -99,7 +99,7 @@ func Update(input e.Patient) (*d.Data, error) { // send data to main api url := fmt.Sprintf("%s%v", "patient/", simxPatient.Id) reqBody := bytes.NewBuffer(jsonPatient) - _, err = send(http.MethodPatch, url, reqBody) + _, err = send(http.MethodPatch, url, reqBody, *input.RegisteredBy_User_Name) if err != nil { return nil, pl.SetLogError(&evt, input) } @@ -127,7 +127,7 @@ func Delete(input e.Patient) (*d.Data, error) { if err != nil { return nil, err } - _, err = send(http.MethodDelete, fmt.Sprintf("%s%v", "patient/", patientLink.Simx_Id), nil) + _, err = send(http.MethodDelete, fmt.Sprintf("%s%v", "patient/", patientLink.Simx_Id), nil, *input.RegisteredBy_User_Name) if err != nil { return nil, err } @@ -141,7 +141,7 @@ func Delete(input e.Patient) (*d.Data, error) { }, nil } -func send(method string, endpoint string, body *bytes.Buffer) ([]byte, error) { +func send(method string, endpoint string, body *bytes.Buffer, username string) ([]byte, error) { var url string = cfg.O.NewHost + endpoint var reader io.Reader = nil if body != nil { @@ -154,8 +154,7 @@ func send(method string, endpoint string, body *bytes.Buffer) ([]byte, error) { req.Header.Set("Content-Type", "application/json") req.Header.Set("X-Sync-Source", cfg.O.OldSource) req.Header.Set("X-Sync-SecretKey", cfg.O.NewSecretKey) - // TODO get use username from patient, migreate database first - req.Header.Set("X-Sync-UserName", "dave") + req.Header.Set("X-Sync-UserName", username) resp, err := http.DefaultClient.Do(req) if err != nil { return nil, err From 106fea0ac933d5ff6e5ec46edb4c269e0ebf2f41 Mon Sep 17 00:00:00 2001 From: vanilia Date: Wed, 3 Dec 2025 11:38:45 +0700 Subject: [PATCH 16/42] finish soapi --- .../simgos-entities/t-rekammedik/entity.go | 10 +- .../interface/main-handler/soapi/handler.go | 6 +- .../use-case/main-use-case/encounter/case.go | 10 +- .../use-case/main-use-case/encounter/lib.go | 5 +- .../new/encounter/case.go | 32 +++--- .../new/encounter/helper.go | 101 +++++++++++------- .../simgos-sync-use-case/new/encounter/lib.go | 53 +-------- 7 files changed, 102 insertions(+), 115 deletions(-) diff --git a/internal/domain/simgos-entities/t-rekammedik/entity.go b/internal/domain/simgos-entities/t-rekammedik/entity.go index 5df0ec83..8599db5d 100644 --- a/internal/domain/simgos-entities/t-rekammedik/entity.go +++ b/internal/domain/simgos-entities/t-rekammedik/entity.go @@ -5,14 +5,14 @@ import "time" type TRekammedik struct { TglKirim *time.Time `json:"tgl_kirim" gorm:"column:tgl_kirim"` TglTerima *time.Time `json:"tgl_terima" gorm:"column:tgl_terima"` - Idxdaftar int `json:"idxdaftar" gorm:"column:idxdaftar"` - Kdpoly int `json:"kdpoly" gorm:"column:kdpoly"` + Idxdaftar uint `json:"idxdaftar" gorm:"column:idxdaftar"` + Kdpoly uint `json:"kdpoly" gorm:"column:kdpoly"` Pengirim string `json:"pengirim" gorm:"column:pengirim"` Penerima string `json:"penerima" gorm:"column:penerima"` - Statusrm int `json:"statusrm" gorm:"column:statusrm"` + Statusrm uint `json:"statusrm" gorm:"column:statusrm"` PenerimaPoly string `json:"penerima_poly" gorm:"column:penerima_poly"` - JamKirimRm string `json:"jam_kirim_rm" gorm:"column:jam_kirim_rm"` - JamTerimaRm string `json:"jam_terima_rm" gorm:"column:jam_terima_rm"` + JamKirimRm *time.Time `json:"jam_kirim_rm" gorm:"column:jam_kirim_rm"` + JamTerimaRm *time.Time `json:"jam_terima_rm" gorm:"column:jam_terima_rm"` PjBerkasRm string `json:"pj_berkas_rm" gorm:"column:pj_berkas_rm"` StatusFisikBerkas string `json:"status_fisik_berkas" gorm:"column:status_fisik_berkas"` } diff --git a/internal/interface/main-handler/soapi/handler.go b/internal/interface/main-handler/soapi/handler.go index fe50b7d2..3683bb23 100644 --- a/internal/interface/main-handler/soapi/handler.go +++ b/internal/interface/main-handler/soapi/handler.go @@ -47,7 +47,7 @@ func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { return } dto := e.ReadDetailDto{} - dto.Id = uint16(id) + dto.Id = uint(id) res, err := u.ReadDetail(dto) rw.DataResponse(w, res, err) } @@ -62,7 +62,7 @@ func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { return } - dto.Id = uint16(id) + dto.Id = uint(id) res, err := u.Update(dto) rw.DataResponse(w, res, err) } @@ -74,7 +74,7 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { } dto := e.DeleteDto{} - dto.Id = uint16(id) + dto.Id = uint(id) res, err := u.Delete(dto) rw.DataResponse(w, res, err) } diff --git a/internal/use-case/main-use-case/encounter/case.go b/internal/use-case/main-use-case/encounter/case.go index 07f055a8..3d38dff7 100644 --- a/internal/use-case/main-use-case/encounter/case.go +++ b/internal/use-case/main-use-case/encounter/case.go @@ -554,7 +554,6 @@ func UpdateStatusCode(input e.UpdateStatusDto) (*d.Data, error) { // Start log pl.SetLogInfo(&event, input, "started", "update") - // TODO: Only "supervisi pendaftaran" could cancel encounter roleAllowed := []string{string(erg.EPCReg), string(erg.EPCNur), string(erg.EPCDoc)} err = validateAuth(input.AuthInfo, roleAllowed, "update-status-encounter", &event) if err != nil { @@ -604,9 +603,14 @@ func UpdateStatusCode(input e.UpdateStatusDto) (*d.Data, error) { return err } - if input.StatusCode == erc.DSCProcess || input.StatusCode == erc.DSCCancel { - data.Status_Code = input.StatusCode + // get data encounter + if data, err = ReadDetailData(e.ReadDetailDto{ + Id: input.Id, + Includes: "Adm_Employee.User"}, &event, tx); err != nil { + return err + } + if input.StatusCode == erc.DSCProcess || input.StatusCode == erc.DSCCancel { mwRunner.setMwType(pu.MWTPre) // Run pre-middleware if err := mwRunner.RunUpdateStatusMiddleware(updatestatusEncounter, data); err != nil { diff --git a/internal/use-case/main-use-case/encounter/lib.go b/internal/use-case/main-use-case/encounter/lib.go index 0b14b925..4e8540f1 100644 --- a/internal/use-case/main-use-case/encounter/lib.go +++ b/internal/use-case/main-use-case/encounter/lib.go @@ -216,7 +216,10 @@ func UpdateStatusData(input e.UpdateStatusDto, event *pl.Event, dbx ...*gorm.DB) if err := tx.Model(&e.Encounter{}). Where("\"Id\" = ?", input.Id). - Update("Status_Code", input.StatusCode).Error; err != nil { + Updates(map[string]interface{}{ + "Status_Code": input.StatusCode, + "Adm_Employee_Id": input.Employee_Id, + }).Error; err != nil { event.Status = "failed" event.ErrInfo = pl.ErrorInfo{ Code: "update-fail", diff --git a/internal/use-case/simgos-sync-use-case/new/encounter/case.go b/internal/use-case/simgos-sync-use-case/new/encounter/case.go index 5e353d1f..55c0a912 100644 --- a/internal/use-case/simgos-sync-use-case/new/encounter/case.go +++ b/internal/use-case/simgos-sync-use-case/new/encounter/case.go @@ -1,6 +1,7 @@ package encounter import ( + erc "simrs-vx/internal/domain/references/common" pl "simrs-vx/pkg/logger" d "github.com/karincake/dodol" @@ -9,7 +10,6 @@ import ( db "simrs-vx/pkg/dualtrx-helper" e "simrs-vx/internal/domain/main-entities/encounter" - etp "simrs-vx/internal/domain/simgos-entities/t-pendaftaran" synce "simrs-vx/internal/domain/sync-entities/encounter" syncir "simrs-vx/internal/domain/sync-entities/internal-reference" elog "simrs-vx/internal/domain/sync-entities/log" @@ -21,9 +21,7 @@ const source = "encounter" func Create(input e.Encounter) (*d.Data, error) { var ( - sgData *etp.TPendaftaran syncLink *synce.EncounterLink - err error ) event := pl.Event{ @@ -34,21 +32,27 @@ func Create(input e.Encounter) (*d.Data, error) { // Start log pl.SetLogInfo(&event, input, "started", "create") - err = db.WithDualTx(func(tx *db.Dualtx) error { + err := db.WithDualTx(func(tx *db.Dualtx) error { // STEP 1: Insert TPendaftaran - sgData, err = CreateTPendaftaranData(input, &event, tx.Simgos) + tPendaftaran, err := CreateTPendaftaranData(input, &event, tx.Simgos) + if err != nil { + return err + } + + // STEP 2: Insert TRekammedik + err = CreateTRekammedik(tPendaftaran, &event, tx.Simgos) if err != nil { return err } // STEP 3: Update MPasien - err = updatePatientCaraBayar(*sgData, &event, tx.Simgos) + err = updatePatientCaraBayar(*tPendaftaran, &event, tx.Simgos) if err != nil { return err } - // STEP 2: Insert to Link - syncLink, err = CreateLinkData(input.Id, sgData.Idxdaftar, &event, tx.Sync) + // STEP 4: Insert to Link + syncLink, err = CreateLinkData(input.Id, tPendaftaran.Idxdaftar, &event, tx.Sync) if err != nil { return err } @@ -281,8 +285,6 @@ func CheckOut(input e.Encounter) (*d.Data, error) { return err } - // TODO: Update TPemeriksaanHistory end_konsul if internal reference exist - return nil }) @@ -299,12 +301,12 @@ func CheckOut(input e.Encounter) (*d.Data, error) { func UpdateStatus(input e.Encounter) (*d.Data, error) { event := pl.Event{ - Feature: "Cancel", + Feature: "Update Status", Source: source, } // Start log - pl.SetLogInfo(&event, input, "started", "cancel") + pl.SetLogInfo(&event, input, "started", "update-status") // STEP 1: Get Link syncLink, err := ReadDetailLinkData(input.Id, &event) @@ -326,7 +328,11 @@ func UpdateStatus(input e.Encounter) (*d.Data, error) { } // Step 3: Update TDiagnosadanterapi - // TODO: update diagnosadanterapi + if input.Status_Code == erc.DSCCancel { + if err = updateCancelTDiagnosaTherapy(simgos.Idxdaftar, input, &event, tx); err != nil { + return err + } + } return nil }) diff --git a/internal/use-case/simgos-sync-use-case/new/encounter/helper.go b/internal/use-case/simgos-sync-use-case/new/encounter/helper.go index bbbc8687..5344c897 100644 --- a/internal/use-case/simgos-sync-use-case/new/encounter/helper.go +++ b/internal/use-case/simgos-sync-use-case/new/encounter/helper.go @@ -6,25 +6,29 @@ package encounter import ( "encoding/json" + pl "simrs-vx/pkg/logger" + "strconv" + + dg "github.com/karincake/apem/db-gorm-pg" + "gorm.io/gorm" + "gorm.io/gorm/clause" + erc "simrs-vx/internal/domain/references/common" ere "simrs-vx/internal/domain/references/encounter" erp "simrs-vx/internal/domain/references/person" - pl "simrs-vx/pkg/logger" - "strconv" e "simrs-vx/internal/domain/main-entities/encounter" epa "simrs-vx/internal/domain/main-entities/person-address" epc "simrs-vx/internal/domain/main-entities/person-contact" epr "simrs-vx/internal/domain/main-entities/person-relative" + ep "simrs-vx/internal/domain/simgos-entities/m-pasien" - etph "simrs-vx/internal/domain/simgos-entities/t-pemeriksaan-hist" + etdt "simrs-vx/internal/domain/simgos-entities/t-diagnosadanterapi" etp "simrs-vx/internal/domain/simgos-entities/t-pendaftaran" + etrm "simrs-vx/internal/domain/simgos-entities/t-rekammedik" + esync "simrs-vx/internal/domain/sync-entities/encounter" esyncLog "simrs-vx/internal/domain/sync-entities/log" - - dg "github.com/karincake/apem/db-gorm-pg" - "gorm.io/gorm" - "gorm.io/gorm/clause" ) func setDataCreateTPendaftaran(input *e.Encounter) (data etp.TPendaftaran, err error) { @@ -188,34 +192,6 @@ func setDataCheckOut(input e.Encounter, data *etp.TPendaftaran) { return } -func setDataRequestSwitchUnit(input e.Encounter, data *etp.TPendaftaran) (hist []etph.TPemeriksaanHist) { - if enc := input.InternalReferences; enc != nil { - for i, ref := range *enc { - hist = append(hist, etph.TPemeriksaanHist{ - Idxdaftar: &data.Idxdaftar, - Kdpoly: stringtouint(*ref.Unit_Code), - DokterPengonsul: stringtouint(*ref.SrcDoctor_Code), - DokterPenerima: stringtouint(*ref.Doctor_Code), - StartKonsul: &now, - }) - - // set user konsul - if n := input.Responsible_Nurse; n != nil { - if emp := n.Employee; emp != nil { - if u := emp.User; u != nil { - hist[i].UserKonsul = &u.Name - } - } - } - - // setaktif - aktif := uint16(1) - hist[i].StAktif = &aktif - } - } - return -} - func setKdrujuk(input *ere.RefTypeCode, data *etp.TPendaftaran) { switch *input { case ere.RTCGov: @@ -363,12 +339,6 @@ func generateNoKunjung() (int, error) { return lastNumber + 1, nil } -func stringtouint(v string) *uint { - u, _ := strconv.Atoi(v) - point := uint(u) - return &point -} - func updatePatientCaraBayar(input etp.TPendaftaran, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, nil, "started", "DBUpdate") @@ -417,3 +387,52 @@ func mapAddress(addresses *[]epa.PersonAddress, data *etp.TPendaftaran) { a := (*addresses)[0] data.PenanggungjawabAlamat = a.Address } + +func setDataTRekammedik(input *etp.TPendaftaran) (data etrm.TRekammedik) { + data.TglKirim = input.Tglreg + data.Idxdaftar = input.Idxdaftar + data.Kdpoly = input.Kdpoly + data.Pengirim = input.Nip + data.JamKirimRm = input.Tglreg + + return +} + +func updateCancelTDiagnosaTherapy(idxdaftar uint, enc e.Encounter, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, nil, "started", "DBUpdate") + + var ( + tx *gorm.DB + userBatal string + ) + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.IS["simrs"] + } + + if a := enc.Adm_Employee; a != nil { + if u := a.User; u != nil { + userBatal = u.Name + } + } + + if err := tx.Model(&etdt.TDiagnosaDanTerapi{}). + Where("idxdaftar = ?", idxdaftar). + Updates(map[string]interface{}{ + "status": "BATAL", + "user_batal": userBatal, + "tgl_batal": &now, + }).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "update-fail", + Detail: "Failed to update patient", + Raw: err, + } + return pl.SetLogError(event, idxdaftar) + } + + pl.SetLogInfo(event, idxdaftar, "complete") + return nil +} diff --git a/internal/use-case/simgos-sync-use-case/new/encounter/lib.go b/internal/use-case/simgos-sync-use-case/new/encounter/lib.go index 47d50802..35bf86ac 100644 --- a/internal/use-case/simgos-sync-use-case/new/encounter/lib.go +++ b/internal/use-case/simgos-sync-use-case/new/encounter/lib.go @@ -1,7 +1,6 @@ package encounter import ( - etph "simrs-vx/internal/domain/simgos-entities/t-pemeriksaan-hist" plh "simrs-vx/pkg/lib-helper" pl "simrs-vx/pkg/logger" pu "simrs-vx/pkg/use-case-helper" @@ -138,25 +137,6 @@ func CreateLinkData(simxId, simgosId uint, event *pl.Event, dbx ...*gorm.DB) (*e return &data, nil } -func CreateBulkLinkData(simxId, simgosId uint, event *pl.Event, dbx ...*gorm.DB) (*esync.EncounterLink, error) { - pl.SetLogInfo(event, nil, "started", "DBCreate") - data := setDataSimxLink(simxId, simgosId) - - var tx *gorm.DB - if len(dbx) > 0 { - tx = dbx[0] - } else { - tx = dg.I - } - - if err := tx.Create(&data).Error; err != nil { - return nil, plh.HandleCreateError(data, event, err) - } - - pl.SetLogInfo(event, nil, "complete") - return &data, nil -} - func ReadDetailLinkData(simxId uint, event *pl.Event) (*esync.EncounterLink, error) { pl.SetLogInfo(event, simxId, "started", "DBReadDetail") data := esync.EncounterLink{} @@ -218,10 +198,9 @@ func CreateLogData(input esynclog.SimxLogDto, event *pl.Event, dbx ...*gorm.DB) return nil } -func CreateBulkTPemeriksaanHistData(input e.Encounter, data *etp.TPendaftaran, event *pl.Event, dbx ...*gorm.DB) (hist []etph.TPemeriksaanHist, err error) { +func CreateTRekammedik(input *etp.TPendaftaran, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, nil, "started", "DBCreate") - - hist = setDataRequestSwitchUnit(input, data) + data := setDataTRekammedik(input) var tx *gorm.DB if len(dbx) > 0 { @@ -230,32 +209,8 @@ func CreateBulkTPemeriksaanHistData(input e.Encounter, data *etp.TPendaftaran, e tx = dg.IS["simrs"] } - if err := tx.Create(&hist).Error; err != nil { - return nil, plh.HandleCreateError(input, event, err) - } - - pl.SetLogInfo(event, nil, "complete") - return hist, nil -} - -func UpdateTPemeriksaanHistData(input e.ApproveCancelUnitDto, data *etph.TPemeriksaanHist, event *pl.Event, dbx ...*gorm.DB) error { - pl.SetLogInfo(event, input, "started", "DBUpdateTPemeriksaanHist") - - var tx *gorm.DB - if len(dbx) > 0 { - tx = dbx[0] - } else { - tx = dg.IS["simrs"] - } - - 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) + if err := tx.Create(&data).Error; err != nil { + return plh.HandleCreateError(input, event, err) } pl.SetLogInfo(event, nil, "complete") From 3b689e4723cfe06a08f1b9e1c93621369e2e297f Mon Sep 17 00:00:00 2001 From: vanilia Date: Wed, 3 Dec 2025 12:04:50 +0700 Subject: [PATCH 17/42] solve conflict --- internal/infra/sync-consumer-cfg/tycovar.go | 4 ++-- internal/interface/main-handler/authentication/handler.go | 2 +- internal/use-case/main-use-case/soapi/middleware-runner.go | 2 +- internal/use-case/simgos-sync-plugin/new/soapi/plugin.go | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/infra/sync-consumer-cfg/tycovar.go b/internal/infra/sync-consumer-cfg/tycovar.go index d2146c2b..5f245599 100644 --- a/internal/infra/sync-consumer-cfg/tycovar.go +++ b/internal/infra/sync-consumer-cfg/tycovar.go @@ -1,8 +1,8 @@ package synccfg -var O SyncConsumerUrlCfg = SyncConsumerUrlCfg{} // old +var O SyncUrlCfg = SyncUrlCfg{} // new -type SyncConsumerUrlCfg struct { +type SyncUrlCfg struct { Prefix string `yaml:"prefix"` TargetHost string `yaml:"targetHost"` Enable bool `yaml:"enable"` diff --git a/internal/interface/main-handler/authentication/handler.go b/internal/interface/main-handler/authentication/handler.go index ffaf145b..4bf5134b 100644 --- a/internal/interface/main-handler/authentication/handler.go +++ b/internal/interface/main-handler/authentication/handler.go @@ -81,7 +81,7 @@ func GuardMW(next http.Handler) http.Handler { credential.UserName = r.Header.Get("X-Sync-UserName") if credential.Source != "" || credential.SecretKey != "" || credential.UserName != "" { // validate secretKey and source - if credential.SecretKey != is.O.SecretKey || credential.Source != is.O.OldSource { + if credential.SecretKey != is.O.SecretKey || credential.Source != is.O.Source { rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "invalid consumer credential"}, nil) return } diff --git a/internal/use-case/main-use-case/soapi/middleware-runner.go b/internal/use-case/main-use-case/soapi/middleware-runner.go index ffc49745..fbe18503 100644 --- a/internal/use-case/main-use-case/soapi/middleware-runner.go +++ b/internal/use-case/main-use-case/soapi/middleware-runner.go @@ -3,7 +3,7 @@ package soapi import ( e "simrs-vx/internal/domain/main-entities/soapi" esync "simrs-vx/internal/domain/sync-entities/log" - sync "simrs-vx/internal/infra/sync-cfg" + sync "simrs-vx/internal/infra/sync-consumer-cfg" pl "simrs-vx/pkg/logger" pu "simrs-vx/pkg/use-case-helper" diff --git a/internal/use-case/simgos-sync-plugin/new/soapi/plugin.go b/internal/use-case/simgos-sync-plugin/new/soapi/plugin.go index 469384b7..8cc40723 100644 --- a/internal/use-case/simgos-sync-plugin/new/soapi/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/soapi/plugin.go @@ -2,7 +2,7 @@ package soapi import ( "fmt" - sync "simrs-vx/internal/infra/sync-cfg" + sync "simrs-vx/internal/infra/sync-consumer-cfg" helper "simrs-vx/internal/use-case/simgos-sync-plugin/new" e "simrs-vx/internal/domain/main-entities/soapi" From d3cc980f2674fd6adc8d1d4bb7f58b17350fe20a Mon Sep 17 00:00:00 2001 From: vanilia Date: Wed, 3 Dec 2025 12:09:12 +0700 Subject: [PATCH 18/42] solve conflict --- internal/infra/sync-consumer-cfg/tycovar.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/infra/sync-consumer-cfg/tycovar.go b/internal/infra/sync-consumer-cfg/tycovar.go index 5f245599..23fd0dcf 100644 --- a/internal/infra/sync-consumer-cfg/tycovar.go +++ b/internal/infra/sync-consumer-cfg/tycovar.go @@ -1,8 +1,8 @@ package synccfg -var O SyncUrlCfg = SyncUrlCfg{} // new +var O SyncConsumerUrlCfg = SyncConsumerUrlCfg{} // new -type SyncUrlCfg struct { +type SyncConsumerUrlCfg struct { Prefix string `yaml:"prefix"` TargetHost string `yaml:"targetHost"` Enable bool `yaml:"enable"` From c979a17407f57ca05cf635503bef00f2d9c08055 Mon Sep 17 00:00:00 2001 From: vanilia Date: Wed, 3 Dec 2025 12:13:07 +0700 Subject: [PATCH 19/42] solve conflict --- cmd/main-api/config.yml-example | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmd/main-api/config.yml-example b/cmd/main-api/config.yml-example index fcc2f53d..f5f03f10 100644 --- a/cmd/main-api/config.yml-example +++ b/cmd/main-api/config.yml-example @@ -69,8 +69,7 @@ syncUrlCfg: enable: false targetHost: prefix: new-to-old - oldSource: new-app - newSource: new-app + source: old-app secretKey: new-world-order!! docsCfg: From cbd1a76011996a1dd0fef8592d4692d491c2b470 Mon Sep 17 00:00:00 2001 From: vanilia Date: Wed, 3 Dec 2025 12:26:35 +0700 Subject: [PATCH 20/42] solve create trekammedik --- .../simgos-entities/t-rekammedik/entity.go | 10 +++++----- .../use-case/main-use-case/encounter/case.go | 3 ++- .../simgos-sync-use-case/new/encounter/case.go | 2 +- .../new/encounter/helper.go | 17 +++++++++++------ .../simgos-sync-use-case/new/encounter/lib.go | 4 ++-- 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/internal/domain/simgos-entities/t-rekammedik/entity.go b/internal/domain/simgos-entities/t-rekammedik/entity.go index 8599db5d..84cec1ef 100644 --- a/internal/domain/simgos-entities/t-rekammedik/entity.go +++ b/internal/domain/simgos-entities/t-rekammedik/entity.go @@ -8,13 +8,13 @@ type TRekammedik struct { Idxdaftar uint `json:"idxdaftar" gorm:"column:idxdaftar"` Kdpoly uint `json:"kdpoly" gorm:"column:kdpoly"` Pengirim string `json:"pengirim" gorm:"column:pengirim"` - Penerima string `json:"penerima" gorm:"column:penerima"` - Statusrm uint `json:"statusrm" gorm:"column:statusrm"` - PenerimaPoly string `json:"penerima_poly" gorm:"column:penerima_poly"` + Penerima *string `json:"penerima" gorm:"column:penerima"` + Statusrm *uint `json:"statusrm" gorm:"column:statusrm"` + PenerimaPoly *string `json:"penerima_poly" gorm:"column:penerima_poly"` JamKirimRm *time.Time `json:"jam_kirim_rm" gorm:"column:jam_kirim_rm"` JamTerimaRm *time.Time `json:"jam_terima_rm" gorm:"column:jam_terima_rm"` - PjBerkasRm string `json:"pj_berkas_rm" gorm:"column:pj_berkas_rm"` - StatusFisikBerkas string `json:"status_fisik_berkas" gorm:"column:status_fisik_berkas"` + PjBerkasRm *string `json:"pj_berkas_rm" gorm:"column:pj_berkas_rm"` + StatusFisikBerkas *string `json:"status_fisik_berkas" gorm:"column:status_fisik_berkas"` } func (TRekammedik) TableName() string { diff --git a/internal/use-case/main-use-case/encounter/case.go b/internal/use-case/main-use-case/encounter/case.go index 1ff2eb11..62a7c992 100644 --- a/internal/use-case/main-use-case/encounter/case.go +++ b/internal/use-case/main-use-case/encounter/case.go @@ -124,7 +124,8 @@ func Create(input e.CreateDto) (*d.Data, error) { dataEncounter, err := ReadDetailData(e.ReadDetailDto{ Id: data.Id, - Includes: "Adm_Employee.User,Patient.Person.Relatives," + + Includes: "Adm_Employee.User,Adm_Employee.Person," + + "Patient.Person.Relatives," + "Patient.Person.VclaimMember,VclaimReference," + "Patient.Person.Contacts,Patient.Person.Addresses"}, &event, tx) diff --git a/internal/use-case/simgos-sync-use-case/new/encounter/case.go b/internal/use-case/simgos-sync-use-case/new/encounter/case.go index 55c0a912..4258e4a3 100644 --- a/internal/use-case/simgos-sync-use-case/new/encounter/case.go +++ b/internal/use-case/simgos-sync-use-case/new/encounter/case.go @@ -40,7 +40,7 @@ func Create(input e.Encounter) (*d.Data, error) { } // STEP 2: Insert TRekammedik - err = CreateTRekammedik(tPendaftaran, &event, tx.Simgos) + err = CreateTRekammedik(input, tPendaftaran, &event, tx.Simgos) if err != nil { return err } diff --git a/internal/use-case/simgos-sync-use-case/new/encounter/helper.go b/internal/use-case/simgos-sync-use-case/new/encounter/helper.go index 8baa5a6f..97656afe 100644 --- a/internal/use-case/simgos-sync-use-case/new/encounter/helper.go +++ b/internal/use-case/simgos-sync-use-case/new/encounter/helper.go @@ -386,12 +386,17 @@ func mapAddress(addresses *[]epa.PersonAddress, data *etp.TPendaftaran) { data.PenanggungjawabAlamat = a.Address } -func setDataTRekammedik(input *etp.TPendaftaran) (data etrm.TRekammedik) { - data.TglKirim = input.Tglreg - data.Idxdaftar = input.Idxdaftar - data.Kdpoly = input.Kdpoly - data.Pengirim = input.Nip - data.JamKirimRm = input.Tglreg +func setDataTRekammedik(input e.Encounter, tdaftar *etp.TPendaftaran) (data etrm.TRekammedik) { + data.TglKirim = tdaftar.Tglreg + data.Idxdaftar = tdaftar.Idxdaftar + data.Kdpoly = tdaftar.Kdpoly + data.JamKirimRm = tdaftar.Tglreg + + if emp := input.Adm_Employee; emp != nil { + if p := emp.Person; p != nil { + data.Pengirim = p.Name + } + } return } diff --git a/internal/use-case/simgos-sync-use-case/new/encounter/lib.go b/internal/use-case/simgos-sync-use-case/new/encounter/lib.go index 35bf86ac..95f86ede 100644 --- a/internal/use-case/simgos-sync-use-case/new/encounter/lib.go +++ b/internal/use-case/simgos-sync-use-case/new/encounter/lib.go @@ -198,9 +198,9 @@ func CreateLogData(input esynclog.SimxLogDto, event *pl.Event, dbx ...*gorm.DB) return nil } -func CreateTRekammedik(input *etp.TPendaftaran, event *pl.Event, dbx ...*gorm.DB) error { +func CreateTRekammedik(input e.Encounter, tpendaftaran *etp.TPendaftaran, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, nil, "started", "DBCreate") - data := setDataTRekammedik(input) + data := setDataTRekammedik(input, tpendaftaran) var tx *gorm.DB if len(dbx) > 0 { From 7276b2a985106beebe85f97b3deb59429ce7e75d Mon Sep 17 00:00:00 2001 From: vanilia Date: Wed, 3 Dec 2025 14:02:29 +0700 Subject: [PATCH 21/42] fix soapi sync --- internal/use-case/main-use-case/soapi/case.go | 4 +-- .../main-use-case/soapi/middleware.go | 2 +- .../simgos-sync-plugin/new/soapi/plugin.go | 2 +- .../new/encounter/case.go | 30 +++++++++++++++++++ .../simgos-sync-use-case/new/patient/case.go | 5 ++++ 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/internal/use-case/main-use-case/soapi/case.go b/internal/use-case/main-use-case/soapi/case.go index 8f4d29e2..49f37ba7 100644 --- a/internal/use-case/main-use-case/soapi/case.go +++ b/internal/use-case/main-use-case/soapi/case.go @@ -51,7 +51,7 @@ func Create(input e.CreateDto) (*d.Data, error) { // get detail for sync soapiData, err := ReadDetailData(e.ReadDetailDto{ Id: data.Id, - Includes: "Encounter,Employee"}, &event) + Includes: "Encounter,Employee"}, &event, tx) if err != nil { return err } @@ -59,7 +59,7 @@ func Create(input e.CreateDto) (*d.Data, error) { mwRunner.setMwType(pu.MWTPre) // Run pre-middleware if err = mwRunner.ExecuteIfSyncOn(func() error { - return mwRunner.RunCreateMiddleware(createPostMw, soapiData) + return mwRunner.RunCreateMiddleware(createPreMw, soapiData) }); err != nil { return err } diff --git a/internal/use-case/main-use-case/soapi/middleware.go b/internal/use-case/main-use-case/soapi/middleware.go index 049b0415..548d27fd 100644 --- a/internal/use-case/main-use-case/soapi/middleware.go +++ b/internal/use-case/main-use-case/soapi/middleware.go @@ -4,7 +4,7 @@ import plugin "simrs-vx/internal/use-case/simgos-sync-plugin/new/soapi" func init() { createPreMw = append(createPreMw, - createMw{Name: "sync-update-soapi", Func: plugin.Create}) + createMw{Name: "sync-create-soapi", Func: plugin.Create}) createSimxLogMw = append(createSimxLogMw, createLogMw{Name: "create-sync-log", Func: plugin.CreateLog}) diff --git a/internal/use-case/simgos-sync-plugin/new/soapi/plugin.go b/internal/use-case/simgos-sync-plugin/new/soapi/plugin.go index 8cc40723..20fabfac 100644 --- a/internal/use-case/simgos-sync-plugin/new/soapi/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/soapi/plugin.go @@ -32,5 +32,5 @@ func Delete(input *e.DeleteDto) error { } func getPrefixEndpoint() string { - return fmt.Sprintf("%s%s/v1/encounter", sync.O.TargetHost, sync.O.Prefix) + return fmt.Sprintf("%s%s/v1/soapi", sync.O.TargetHost, sync.O.Prefix) } diff --git a/internal/use-case/simgos-sync-use-case/new/encounter/case.go b/internal/use-case/simgos-sync-use-case/new/encounter/case.go index 4258e4a3..05c77915 100644 --- a/internal/use-case/simgos-sync-use-case/new/encounter/case.go +++ b/internal/use-case/simgos-sync-use-case/new/encounter/case.go @@ -135,6 +135,11 @@ func Update(input e.Encounter) (*d.Data, error) { tx := db.NewTx() err = tx.Simgos.Transaction(func(tx *gorm.DB) error { + // SET LOCAL + if err = tx.Exec(`SET LOCAL simx.sync_source = 'new'`).Error; err != nil { + return err + } + // Step 2: Update Simgos if err = UpdateTPendaftaranData(input, simgos, "update", &event, tx); err != nil { return err @@ -238,6 +243,11 @@ func CheckIn(input e.Encounter) (*d.Data, error) { tx := db.NewTx() err = tx.Simgos.Transaction(func(tx *gorm.DB) error { + // SET LOCAL + if err = tx.Exec(`SET LOCAL simx.sync_source = 'new'`).Error; err != nil { + return err + } + // Step 2: Update Simgos if err = UpdateTPendaftaranData(input, simgos, "check-in", &event, tx); err != nil { return err @@ -280,6 +290,11 @@ func CheckOut(input e.Encounter) (*d.Data, error) { tx := db.NewTx() err = tx.Simgos.Transaction(func(tx *gorm.DB) error { + // SET LOCAL + if err = tx.Exec(`SET LOCAL simx.sync_source = 'new'`).Error; err != nil { + return err + } + // Step 2: Update Simgos if err = UpdateTPendaftaranData(input, simgos, "check-out", &event, tx); err != nil { return err @@ -322,6 +337,11 @@ func UpdateStatus(input e.Encounter) (*d.Data, error) { tx := db.NewTx() err = tx.Simgos.Transaction(func(tx *gorm.DB) error { + // SET LOCAL + if err = tx.Exec(`SET LOCAL simx.sync_source = 'new'`).Error; err != nil { + return err + } + // Step 2: Update TPendaftaran if err = UpdateTPendaftaranData(input, simgos, "update-status", &event, tx); err != nil { return err @@ -434,6 +454,11 @@ func ApproveSwitchUnit(input e.ApproveCancelUnitDto) (*d.Data, error) { tx := db.NewTx() err = tx.Simgos.Transaction(func(tx *gorm.DB) error { + // SET LOCAL + if err = tx.Exec(`SET LOCAL simx.sync_source = 'new'`).Error; err != nil { + return err + } + // Step 3: Update TPemeriksaanHist if err := utph.UpdateSimgosData(input, tPemeriksaanHist, "approve", &event, tx); err != nil { return err @@ -476,6 +501,11 @@ func CancelSwitchUnit(input e.ApproveCancelUnitDto) (*d.Data, error) { tx := db.NewTx() err = tx.Simgos.Transaction(func(tx *gorm.DB) error { + // SET LOCAL + if err = tx.Exec(`SET LOCAL simx.sync_source = 'new'`).Error; err != nil { + return err + } + // Step 3: Update TPemeriksaanHist if err := utph.UpdateSimgosData(input, tPemeriksaanHist, "cancel", &event, tx); err != nil { return err diff --git a/internal/use-case/simgos-sync-use-case/new/patient/case.go b/internal/use-case/simgos-sync-use-case/new/patient/case.go index a147524c..03497eed 100644 --- a/internal/use-case/simgos-sync-use-case/new/patient/case.go +++ b/internal/use-case/simgos-sync-use-case/new/patient/case.go @@ -122,6 +122,11 @@ func Update(input e.Patient) (*d.Data, error) { tx := db.NewTx() err = tx.Simgos.Transaction(func(tx *gorm.DB) error { + // SET LOCAL + if err = tx.Exec(`SET LOCAL simx.sync_source = 'new'`).Error; err != nil { + return err + } + // Step 3: Update Simgos if err = UpdateSimgosData(input, patientData, &event, tx); err != nil { return err From 5406a9b292155bc7fe183d531ea4ebfad73b8a77 Mon Sep 17 00:00:00 2001 From: vanilia Date: Thu, 4 Dec 2025 07:45:16 +0700 Subject: [PATCH 22/42] solve entity and finish soapi --- .../t-diagnosadanterapi/entity.go | 36 +++++++++---------- .../domain/simgos-entities/t-icd-cm/entity.go | 12 +++---- .../domain/simgos-entities/t-icd/entity.go | 12 +++---- internal/use-case/main-use-case/soapi/case.go | 2 +- .../simgos-sync-use-case/new/soapi/helper.go | 15 ++++---- 5 files changed, 39 insertions(+), 38 deletions(-) diff --git a/internal/domain/simgos-entities/t-diagnosadanterapi/entity.go b/internal/domain/simgos-entities/t-diagnosadanterapi/entity.go index 2e77d362..9579168c 100644 --- a/internal/domain/simgos-entities/t-diagnosadanterapi/entity.go +++ b/internal/domain/simgos-entities/t-diagnosadanterapi/entity.go @@ -11,29 +11,29 @@ type TDiagnosaDanTerapi struct { GolonganDarah string `json:"golongan_darah" gorm:"column:golongan_darah"` TinggiBadan float64 `json:"tinggi_badan" gorm:"column:tinggi_badan"` BeratBadan float64 `json:"berat_badan" gorm:"column:berat_badan"` - Diagnosa string `json:"diagnosa" gorm:"column:diagnosa"` - Komplikasi string `json:"komplikasi" gorm:"column:komplikasi"` - Terapi string `json:"terapi" gorm:"column:terapi"` - Anamnesa string `json:"anamnesa" gorm:"column:anamnesa"` + Diagnosa *string `json:"diagnosa" gorm:"column:diagnosa"` + Komplikasi *string `json:"komplikasi" gorm:"column:komplikasi"` + Terapi *string `json:"terapi" gorm:"column:terapi"` + Anamnesa *string `json:"anamnesa" gorm:"column:anamnesa"` Kdpoly uint `json:"kdpoly" gorm:"column:kdpoly"` Kddokter uint `json:"kddokter" gorm:"column:kddokter"` - Kdtujuanrujuk uint `json:"kdtujuanrujuk" gorm:"column:kdtujuanrujuk"` + Kdtujuanrujuk *uint `json:"kdtujuanrujuk" gorm:"column:kdtujuanrujuk"` Nip string `json:"nip" gorm:"column:nip"` - IcdCode string `json:"icd_code" gorm:"column:icd_code"` + IcdCode *string `json:"icd_code" gorm:"column:icd_code"` KunjunganBl uint `json:"kunjungan_bl" gorm:"column:kunjungan_bl"` KasusBl uint `json:"kasus_bl" gorm:"column:kasus_bl"` - Icdcm string `json:"icdcm" gorm:"column:icdcm"` - Icd9 string `json:"icd_9" gorm:"column:icd_9"` - Klb uint `json:"klb" gorm:"column:klb"` - Bedah uint `json:"bedah" gorm:"column:bedah"` - Jenis uint `json:"jenis" gorm:"column:jenis"` - Perawat string `json:"perawat" gorm:"column:perawat"` - Status string `json:"status" gorm:"column:status"` - PemeriksaanFisik string `json:"pemeriksaan_fisik" gorm:"column:pemeriksaan_fisik"` - RiwayatPasien string `json:"riwayat_pasien" gorm:"column:riwayat_pasien"` - TindakanMedis string `json:"tindakan_medis" gorm:"column:tindakan_medis"` + Icdcm *string `json:"icdcm" gorm:"column:icdcm"` + Icd9 *string `json:"icd_9" gorm:"column:icd_9"` + Klb *uint `json:"klb" gorm:"column:klb"` + Bedah *uint `json:"bedah" gorm:"column:bedah"` + Jenis *uint `json:"jenis" gorm:"column:jenis"` + Perawat *string `json:"perawat" gorm:"column:perawat"` + Status *string `json:"status" gorm:"column:status"` + PemeriksaanFisik *string `json:"pemeriksaan_fisik" gorm:"column:pemeriksaan_fisik"` + RiwayatPasien *string `json:"riwayat_pasien" gorm:"column:riwayat_pasien"` + TindakanMedis *string `json:"tindakan_medis" gorm:"column:tindakan_medis"` Rajal uint `json:"rajal" gorm:"column:rajal"` - UserBatal string `json:"user_batal" gorm:"column:user_batal"` + UserBatal *string `json:"user_batal" gorm:"column:user_batal"` TglBatal *time.Time `json:"tgl_batal" gorm:"column:tgl_batal"` SudahVaksin string `json:"sudah_vaksin" gorm:"column:sudah_vaksin"` CreatedAt time.Time `json:"created_at" gorm:"column:created_at"` @@ -41,7 +41,7 @@ type TDiagnosaDanTerapi struct { Pernapasan string `json:"pernapasan" gorm:"column:pernapasan"` Suhu string `json:"suhu" gorm:"column:suhu"` Sp02 string `json:"sp02" gorm:"column:sp02"` - TujuanPerawatan string `json:"tujuan_perawatan" gorm:"column:tujuan_perawatan"` + TujuanPerawatan *string `json:"tujuan_perawatan" gorm:"column:tujuan_perawatan"` TargetCapaian string `json:"target_capaian" gorm:"column:target_capaian"` } diff --git a/internal/domain/simgos-entities/t-icd-cm/entity.go b/internal/domain/simgos-entities/t-icd-cm/entity.go index 198b29ea..6ea7f935 100644 --- a/internal/domain/simgos-entities/t-icd-cm/entity.go +++ b/internal/domain/simgos-entities/t-icd-cm/entity.go @@ -7,15 +7,15 @@ type TIcdCm struct { Nomr string `json:"nomr" gorm:"column:nomr"` Idxdaftar uint `json:"idxdaftar" gorm:"column:idxdaftar"` Kddokter uint `json:"kddokter" gorm:"column:kddokter"` - Icd string `json:"icd" gorm:"column:icd"` - IcdVerified string `json:"icd_verified" gorm:"column:icd_verified"` + Icd *string `json:"icd" gorm:"column:icd"` + IcdVerified *string `json:"icd_verified" gorm:"column:icd_verified"` StatusRajal uint16 `json:"status_rajal" gorm:"column:status_rajal"` Tanggal time.Time `json:"tanggal" gorm:"column:tanggal"` - StatusVerif uint16 `json:"status_verif" gorm:"column:status_verif"` - IcdVerifiedOrder uint16 `json:"icd_verified_order" gorm:"column:icd_verified_order"` - IcdVerifBy string `json:"icd_verif_by" gorm:"column:icd_verif_by"` + StatusVerif *uint16 `json:"status_verif" gorm:"column:status_verif"` + IcdVerifiedOrder *uint16 `json:"icd_verified_order" gorm:"column:icd_verified_order"` + IcdVerifBy *string `json:"icd_verif_by" gorm:"column:icd_verif_by"` IcdVerifDate *time.Time `json:"icd_verif_date" gorm:"column:icd_verif_date"` - IcdActive uint16 `json:"icd_active" gorm:"column:icd_active"` + IcdActive *uint16 `json:"icd_active" gorm:"column:icd_active"` } func (TIcdCm) TableName() string { diff --git a/internal/domain/simgos-entities/t-icd/entity.go b/internal/domain/simgos-entities/t-icd/entity.go index f2191ecc..73ee49e1 100644 --- a/internal/domain/simgos-entities/t-icd/entity.go +++ b/internal/domain/simgos-entities/t-icd/entity.go @@ -8,15 +8,15 @@ type TIcd struct { Idxdaftar uint `json:"idxdaftar" gorm:"column:idxdaftar"` Kddokter uint `json:"kddokter" gorm:"column:kddokter"` Icd string `json:"icd" gorm:"column:icd"` - IcdVerified string `json:"icd_verified" gorm:"column:icd_verified"` + IcdVerified *string `json:"icd_verified" gorm:"column:icd_verified"` StatusRajal uint16 `json:"status_rajal" gorm:"column:status_rajal"` Tanggal time.Time `json:"tanggal" gorm:"column:tanggal"` - StatusVerif uint16 `json:"status_verif" gorm:"column:status_verif"` - IcdVerifiedOrder uint16 `json:"icd_verified_order" gorm:"column:icd_verified_order"` - IcdVerifBy string `json:"icd_verif_by" gorm:"column:icd_verif_by"` + StatusVerif *uint16 `json:"status_verif" gorm:"column:status_verif"` + IcdVerifiedOrder *uint16 `json:"icd_verified_order" gorm:"column:icd_verified_order"` + IcdVerifBy *string `json:"icd_verif_by" gorm:"column:icd_verif_by"` IcdVerifDate *time.Time `json:"icd_verif_date" gorm:"column:icd_verif_date"` - IcdActive uint16 `json:"icd_active" gorm:"column:icd_active"` - StSebabMati uint16 `json:"st_sebab_mati" gorm:"column:st_sebab_mati"` + IcdActive *uint16 `json:"icd_active" gorm:"column:icd_active"` + StSebabMati *uint16 `json:"st_sebab_mati" gorm:"column:st_sebab_mati"` } func (TIcd) TableName() string { diff --git a/internal/use-case/main-use-case/soapi/case.go b/internal/use-case/main-use-case/soapi/case.go index 49f37ba7..ebf1c7d8 100644 --- a/internal/use-case/main-use-case/soapi/case.go +++ b/internal/use-case/main-use-case/soapi/case.go @@ -51,7 +51,7 @@ func Create(input e.CreateDto) (*d.Data, error) { // get detail for sync soapiData, err := ReadDetailData(e.ReadDetailDto{ Id: data.Id, - Includes: "Encounter,Employee"}, &event, tx) + Includes: "Encounter,Employee.User"}, &event, tx) if err != nil { return err } diff --git a/internal/use-case/simgos-sync-use-case/new/soapi/helper.go b/internal/use-case/simgos-sync-use-case/new/soapi/helper.go index 65213761..b9d761a1 100644 --- a/internal/use-case/simgos-sync-use-case/new/soapi/helper.go +++ b/internal/use-case/simgos-sync-use-case/new/soapi/helper.go @@ -66,16 +66,16 @@ func setEarlyMedicTDT(input es.Soapi, data *etdt.TDiagnosaDanTerapi) { data.TinggiBadan = float64(value.Height) data.BeratBadan = float64(value.Weight) - data.Diagnosa = value.EarlyMedicDiagnose - data.Terapi = value.Therapy - data.Anamnesa = value.PrimaryComplain + data.Diagnosa = &value.EarlyMedicDiagnose + data.Terapi = &value.Therapy + data.Anamnesa = &value.PrimaryComplain // TODO : status, tindakan_mdeis (?) data.KunjunganBl = uint(value.EncounterStatus) data.KasusBl = uint(value.CaseStatus) - data.PemeriksaanFisik = value.PhysicalExamination - data.RiwayatPasien = value.CurrentDiseaseHistory + data.PemeriksaanFisik = &value.PhysicalExamination + data.RiwayatPasien = &value.CurrentDiseaseHistory if value.Vaccinated { data.SudahVaksin = "YA" @@ -93,7 +93,8 @@ func setEarlyMedicTDT(input es.Soapi, data *etdt.TDiagnosaDanTerapi) { for _, v := range o { expectedOutput = append(expectedOutput, v.Name) } - jsonData, _ := json.MarshalIndent(value.ExpectedOutcome, "", " ") + + jsonData, _ := json.Marshal(expectedOutput) data.TargetCapaian = string(jsonData) } return @@ -155,7 +156,7 @@ func setDataIcdCm(input es.Soapi, enc *etp.TPendaftaran) (data []eicdcm.TIcdCm) Nomr: enc.Nomr, Idxdaftar: enc.Idxdaftar, Kddokter: enc.Kddokter, - Icd: v.Code, + Icd: &v.Code, StatusRajal: ambulatory, Tanggal: visitDate, }) From d82e67ae5c579f36dd5dad044cdf26aab8397fa4 Mon Sep 17 00:00:00 2001 From: vanilia Date: Sat, 6 Dec 2025 04:20:40 +0700 Subject: [PATCH 23/42] add chemoplans entity in chemo protocol --- cmd/main-migration/migrations/20251205211957.sql | 2 ++ cmd/main-migration/migrations/atlas.sum | 5 +++-- internal/domain/main-entities/chemo-plan/dto.go | 8 ++------ internal/domain/main-entities/chemo-plan/entity.go | 3 --- internal/domain/main-entities/chemo-protocol/entity.go | 2 ++ 5 files changed, 9 insertions(+), 11 deletions(-) create mode 100644 cmd/main-migration/migrations/20251205211957.sql diff --git a/cmd/main-migration/migrations/20251205211957.sql b/cmd/main-migration/migrations/20251205211957.sql new file mode 100644 index 00000000..99677edd --- /dev/null +++ b/cmd/main-migration/migrations/20251205211957.sql @@ -0,0 +1,2 @@ +-- Modify "ChemoPlan" table +ALTER TABLE "public"."ChemoPlan" DROP CONSTRAINT "fk_ChemoPlan_Protocol", ADD CONSTRAINT "fk_ChemoProtocol_ChemoPlans" FOREIGN KEY ("Protocol_Id") REFERENCES "public"."ChemoProtocol" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION; diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 9b12364f..9e1a235c 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:2pGamYMy0LEZE7Du/0SEb8z5LrkmpNk199Yw0CJri+M= +h1:JgjOL5Bl+2zIlc2E1Lz/LhEJo/IGWouNe79ccswAcq8= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -144,4 +144,5 @@ h1:2pGamYMy0LEZE7Du/0SEb8z5LrkmpNk199Yw0CJri+M= 20251202160848.sql h1:Kd2/TziKSMezrt4XgbjQcYvY/Lo9rX0qw7/Lz0/oyKk= 20251202180207.sql h1:IHmSMIO3ia+YV5GULixbdlV1joaUAWtnjQHPd8+HKiM= 20251202231005.sql h1:lua0KKoeBptSfs/6ehZE6Azo6YUlNkOJwGFyb1HQWkY= -20251205073858.sql h1:GD692c2jC2mFr6esv3eQmxEpWOeIA860TGctwHAldfM= +20251205073858.sql h1:Ep03jQ9hJAJILDJfKVcmi3Z6fqmTHSq9gKQtwf070PE= +20251205211957.sql h1:RGkuUdSgt8BtypqGpji9VBBi1r85e2ez1aJILTB7zi0= diff --git a/internal/domain/main-entities/chemo-plan/dto.go b/internal/domain/main-entities/chemo-plan/dto.go index b3e89d80..ffd9803f 100644 --- a/internal/domain/main-entities/chemo-plan/dto.go +++ b/internal/domain/main-entities/chemo-plan/dto.go @@ -1,18 +1,17 @@ package chemo_plan import ( - ecp "simrs-vx/internal/domain/main-entities/chemo-protocol" - ere "simrs-vx/internal/domain/references/encounter" // std "time" + ere "simrs-vx/internal/domain/references/encounter" + // internal - domain - main-entities ecore "simrs-vx/internal/domain/base-entities/core" ) type CreateDto struct { Parent_Id *uint `json:"parent_id"` - Protocol_Id *uint `json:"protocol_id"` SeriesNumber *uint16 `json:"seriesNumber"` CycleNumber *uint `json:"cycleNumber"` PlanDate *time.Time `json:"planDate"` @@ -56,7 +55,6 @@ type ResponseDto struct { ecore.Main Parent_Id *uint `json:"parent_id"` // chemo.Id Protocol_Id *uint `json:"protocol_id"` - Protocol ecp.ChemoProtocol `json:"protocol,omitempty"` SeriesNumber *uint16 `json:"seriesNumber"` // series ke - CycleNumber *uint `json:"cycleNumber"` // cycle ke - PlanDate *time.Time `json:"planDate"` @@ -68,8 +66,6 @@ type ResponseDto struct { func (d ChemoPlan) ToResponse() ResponseDto { resp := ResponseDto{ Parent_Id: d.Parent_Id, - Protocol_Id: d.Protocol_Id, - Protocol: d.Protocol, SeriesNumber: d.SeriesNumber, CycleNumber: d.CycleNumber, PlanDate: d.PlanDate, diff --git a/internal/domain/main-entities/chemo-plan/entity.go b/internal/domain/main-entities/chemo-plan/entity.go index 08ac905d..1f3f3ca5 100644 --- a/internal/domain/main-entities/chemo-plan/entity.go +++ b/internal/domain/main-entities/chemo-plan/entity.go @@ -6,15 +6,12 @@ import ( ecore "simrs-vx/internal/domain/base-entities/core" ere "simrs-vx/internal/domain/references/encounter" - - ecp "simrs-vx/internal/domain/main-entities/chemo-protocol" ) type ChemoPlan struct { ecore.Main Parent_Id *uint `json:"parent_id"` // chemo.Id Protocol_Id *uint `json:"protocol_id"` - Protocol ecp.ChemoProtocol `json:"protocol,omitempty" gorm:"foreignKey:Protocol_Id;references:Id"` SeriesNumber *uint16 `json:"seriesNumber"` // series ke - CycleNumber *uint `json:"cycleNumber"` // cycle ke - PlanDate *time.Time `json:"planDate"` diff --git a/internal/domain/main-entities/chemo-protocol/entity.go b/internal/domain/main-entities/chemo-protocol/entity.go index e20f3592..63639f46 100644 --- a/internal/domain/main-entities/chemo-protocol/entity.go +++ b/internal/domain/main-entities/chemo-protocol/entity.go @@ -7,6 +7,7 @@ import ( erc "simrs-vx/internal/domain/references/common" ec "simrs-vx/internal/domain/main-entities/chemo" + ecp "simrs-vx/internal/domain/main-entities/chemo-plan" ) type ChemoProtocol struct { @@ -24,4 +25,5 @@ type ChemoProtocol struct { StartDate *time.Time `json:"startDate"` EndDate *time.Time `json:"endDate"` Status_Code erc.DataVerifiedCode `json:"status_code"` + ChemoPlans *[]ecp.ChemoPlan `json:"chemoPlans,omitempty" gorm:"foreignKey:Protocol_Id;references:Id"` } From c4103539c9cf5171996a1d0914918a8512d3c174 Mon Sep 17 00:00:00 2001 From: vanilia Date: Sat, 6 Dec 2025 04:45:05 +0700 Subject: [PATCH 24/42] adj chemoprotoc --- cmd/main-migration/migrations/20251205214433.sql | 2 ++ cmd/main-migration/migrations/atlas.sum | 5 +++-- internal/domain/main-entities/chemo-protocol/entity.go | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 cmd/main-migration/migrations/20251205214433.sql diff --git a/cmd/main-migration/migrations/20251205214433.sql b/cmd/main-migration/migrations/20251205214433.sql new file mode 100644 index 00000000..34343308 --- /dev/null +++ b/cmd/main-migration/migrations/20251205214433.sql @@ -0,0 +1,2 @@ +-- Modify "ChemoProtocol" table +ALTER TABLE "public"."ChemoProtocol" ADD COLUMN "Patient_Id" bigint NULL; diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 9e1a235c..176afc27 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:JgjOL5Bl+2zIlc2E1Lz/LhEJo/IGWouNe79ccswAcq8= +h1:8SotxMlqYq7PNXcyAsIzO4075hP1c39CA2efE7Jp1kk= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -145,4 +145,5 @@ h1:JgjOL5Bl+2zIlc2E1Lz/LhEJo/IGWouNe79ccswAcq8= 20251202180207.sql h1:IHmSMIO3ia+YV5GULixbdlV1joaUAWtnjQHPd8+HKiM= 20251202231005.sql h1:lua0KKoeBptSfs/6ehZE6Azo6YUlNkOJwGFyb1HQWkY= 20251205073858.sql h1:Ep03jQ9hJAJILDJfKVcmi3Z6fqmTHSq9gKQtwf070PE= -20251205211957.sql h1:RGkuUdSgt8BtypqGpji9VBBi1r85e2ez1aJILTB7zi0= +20251205211957.sql h1:zRHcvLY+nfLdUyMcfpgI8vYQcPzJUWbfjkc4cK0QGHU= +20251205214433.sql h1:cPyzSgAn5VHElC5yHtK2TCKSnBoTI65S0kcoc2GbIxQ= diff --git a/internal/domain/main-entities/chemo-protocol/entity.go b/internal/domain/main-entities/chemo-protocol/entity.go index 63639f46..7ffc8afd 100644 --- a/internal/domain/main-entities/chemo-protocol/entity.go +++ b/internal/domain/main-entities/chemo-protocol/entity.go @@ -26,4 +26,5 @@ type ChemoProtocol struct { EndDate *time.Time `json:"endDate"` Status_Code erc.DataVerifiedCode `json:"status_code"` ChemoPlans *[]ecp.ChemoPlan `json:"chemoPlans,omitempty" gorm:"foreignKey:Protocol_Id;references:Id"` + Patient_Id *uint `json:"patient_id"` } From c5c4a10e2e8d45a3b22a53049b304605c01704e5 Mon Sep 17 00:00:00 2001 From: vanilia Date: Sat, 6 Dec 2025 05:11:58 +0700 Subject: [PATCH 25/42] adjust protoc --- .../migrations/20251205221124.sql | 2 ++ cmd/main-migration/migrations/atlas.sum | 5 +-- .../main-entities/chemo-protocol/entity.go | 34 +++++++++++-------- 3 files changed, 24 insertions(+), 17 deletions(-) create mode 100644 cmd/main-migration/migrations/20251205221124.sql diff --git a/cmd/main-migration/migrations/20251205221124.sql b/cmd/main-migration/migrations/20251205221124.sql new file mode 100644 index 00000000..3eab115a --- /dev/null +++ b/cmd/main-migration/migrations/20251205221124.sql @@ -0,0 +1,2 @@ +-- Modify "ChemoProtocol" table +ALTER TABLE "public"."ChemoProtocol" ADD COLUMN "VerifiedAt" timestamptz NULL, ADD COLUMN "VerifiedBy_User_Id" bigint NULL, ADD CONSTRAINT "fk_ChemoProtocol_VerifiedBy" FOREIGN KEY ("VerifiedBy_User_Id") REFERENCES "public"."User" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION; diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 176afc27..09459c64 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:8SotxMlqYq7PNXcyAsIzO4075hP1c39CA2efE7Jp1kk= +h1:BsDkwn1AzNdKnOPVb6PkonyiXM7nTdVcjRdw62i/NlQ= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -146,4 +146,5 @@ h1:8SotxMlqYq7PNXcyAsIzO4075hP1c39CA2efE7Jp1kk= 20251202231005.sql h1:lua0KKoeBptSfs/6ehZE6Azo6YUlNkOJwGFyb1HQWkY= 20251205073858.sql h1:Ep03jQ9hJAJILDJfKVcmi3Z6fqmTHSq9gKQtwf070PE= 20251205211957.sql h1:zRHcvLY+nfLdUyMcfpgI8vYQcPzJUWbfjkc4cK0QGHU= -20251205214433.sql h1:cPyzSgAn5VHElC5yHtK2TCKSnBoTI65S0kcoc2GbIxQ= +20251205214433.sql h1:tgHB/fNy9XwAOWIqNI6GCqGXeJgSuZs2aHiCEj3BHZA= +20251205221124.sql h1:VthPlq3XcQOYz5VsFivb4Wof8jCAG36fAaerKmM4/OA= diff --git a/internal/domain/main-entities/chemo-protocol/entity.go b/internal/domain/main-entities/chemo-protocol/entity.go index 7ffc8afd..6377c136 100644 --- a/internal/domain/main-entities/chemo-protocol/entity.go +++ b/internal/domain/main-entities/chemo-protocol/entity.go @@ -8,23 +8,27 @@ import ( ec "simrs-vx/internal/domain/main-entities/chemo" ecp "simrs-vx/internal/domain/main-entities/chemo-plan" + eus "simrs-vx/internal/domain/main-entities/user" ) type ChemoProtocol struct { ecore.Main - Chemo_Id *uint `json:"chemo_id"` - Chemo *ec.Chemo `json:"chemo,omitempty" gorm:"foreignKey:Chemo_Id;references:Id"` - Patient_Weight *float32 `json:"patient_weight"` - Patient_Height *float32 `json:"patient_height"` - Diagnoses *string `json:"diagnoses"` - Duration *uint `json:"duration"` // not used - DurationUnit_Code *erc.TimeUnitCode `json:"durationUnit_code"` // not used - Interval *uint `json:"interval"` - Cycle *uint `json:"cycle"` // total cycle - Series *uint16 `json:"series"` // total series - StartDate *time.Time `json:"startDate"` - EndDate *time.Time `json:"endDate"` - Status_Code erc.DataVerifiedCode `json:"status_code"` - ChemoPlans *[]ecp.ChemoPlan `json:"chemoPlans,omitempty" gorm:"foreignKey:Protocol_Id;references:Id"` - Patient_Id *uint `json:"patient_id"` + Chemo_Id *uint `json:"chemo_id"` + Chemo *ec.Chemo `json:"chemo,omitempty" gorm:"foreignKey:Chemo_Id;references:Id"` + Patient_Weight *float32 `json:"patient_weight"` + Patient_Height *float32 `json:"patient_height"` + Diagnoses *string `json:"diagnoses"` + Duration *uint `json:"duration"` // not used + DurationUnit_Code *erc.TimeUnitCode `json:"durationUnit_code"` // not used + Interval *uint `json:"interval"` + Cycle *uint `json:"cycle"` // total cycle + Series *uint16 `json:"series"` // total series + StartDate *time.Time `json:"startDate"` + EndDate *time.Time `json:"endDate"` + Status_Code erc.DataVerifiedCode `json:"status_code"` + VerifiedAt *time.Time `json:"verifiedAt"` + VerifiedBy_User_Id *uint `json:"verifiedBy_user_id"` + VerifiedBy *eus.User `json:"verifiedBy,omitempty" gorm:"foreignKey:VerifiedBy_User_Id;references:Id"` + ChemoPlans *[]ecp.ChemoPlan `json:"chemoPlans,omitempty" gorm:"foreignKey:Protocol_Id;references:Id"` + Patient_Id *uint `json:"patient_id"` } From faca8dfa14d8a525510b0400c4a32aaa16842721 Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Sun, 7 Dec 2025 09:07:01 +0700 Subject: [PATCH 26/42] feat/order-things: added ap-mcu-order --- .../migrations/20251207020537.sql | 22 ++ cmd/main-migration/migrations/atlas.sum | 5 +- .../domain/main-entities/ap-mcu-order/dto.go | 94 ++++++ .../main-entities/ap-mcu-order/entity.go | 23 ++ internal/interface/migration/main-entities.go | 2 + .../main-use-case/ap-mcu-order/case.go | 276 ++++++++++++++++++ .../main-use-case/ap-mcu-order/helper.go | 30 ++ .../main-use-case/ap-mcu-order/lib.go | 140 +++++++++ .../ap-mcu-order/middleware-runner.go | 103 +++++++ .../main-use-case/ap-mcu-order/middleware.go | 9 + .../main-use-case/ap-mcu-order/tycovar.go | 44 +++ 11 files changed, 746 insertions(+), 2 deletions(-) create mode 100644 cmd/main-migration/migrations/20251207020537.sql create mode 100644 internal/domain/main-entities/ap-mcu-order/dto.go create mode 100644 internal/domain/main-entities/ap-mcu-order/entity.go create mode 100644 internal/use-case/main-use-case/ap-mcu-order/case.go create mode 100644 internal/use-case/main-use-case/ap-mcu-order/helper.go create mode 100644 internal/use-case/main-use-case/ap-mcu-order/lib.go create mode 100644 internal/use-case/main-use-case/ap-mcu-order/middleware-runner.go create mode 100644 internal/use-case/main-use-case/ap-mcu-order/middleware.go create mode 100644 internal/use-case/main-use-case/ap-mcu-order/tycovar.go diff --git a/cmd/main-migration/migrations/20251207020537.sql b/cmd/main-migration/migrations/20251207020537.sql new file mode 100644 index 00000000..14142cb0 --- /dev/null +++ b/cmd/main-migration/migrations/20251207020537.sql @@ -0,0 +1,22 @@ +-- Create "ApMcuOrder" table +CREATE TABLE "public"."ApMcuOrder" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "McuOrder_Id" smallint NULL, + "Substances" text NULL, + "Fictations" text NULL, + "Localization" text NULL, + "ClinicalDiagnoses" text NULL, + "Stadium" text NULL, + "ClinicalNotes" text NULL, + "PastHistory" text NULL, + "CurrentHistory" text NULL, + "PrevApMcu" text NULL, + "PrevApMcuNotes" text NULL, + "SupportingExams" text NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "uni_ApMcuOrder_McuOrder_Id" UNIQUE ("McuOrder_Id"), + CONSTRAINT "fk_ApMcuOrder_McuOrder" FOREIGN KEY ("McuOrder_Id") REFERENCES "public"."McuOrder" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 3ec1b876..632e0ddb 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:qjr3k9/ymXjw1nopw49c6+fWtu0n+H8sQgsioqUC9Fo= +h1:1BOh7w/6hkhDj1PptjXT4tLOgmRtIIofGm3ERJ+EfyM= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -144,4 +144,5 @@ h1:qjr3k9/ymXjw1nopw49c6+fWtu0n+H8sQgsioqUC9Fo= 20251202160848.sql h1:Kd2/TziKSMezrt4XgbjQcYvY/Lo9rX0qw7/Lz0/oyKk= 20251202180207.sql h1:IHmSMIO3ia+YV5GULixbdlV1joaUAWtnjQHPd8+HKiM= 20251202231005.sql h1:lua0KKoeBptSfs/6ehZE6Azo6YUlNkOJwGFyb1HQWkY= -20251203205052.sql h1:az/hGpk7u4YKT7gU+UuEw9guqB9AqdckPF1cYavQ3CA= +20251203205052.sql h1:nk0VK2Uv4bHE3SBfHo/aevVZxtHzr7zAzvmMU8TCCtk= +20251207020537.sql h1:UmtHxX1vZi/BiKxHPOOP7fALRZ3RoRGSGmUma7ttp8w= diff --git a/internal/domain/main-entities/ap-mcu-order/dto.go b/internal/domain/main-entities/ap-mcu-order/dto.go new file mode 100644 index 00000000..7fcaa1d3 --- /dev/null +++ b/internal/domain/main-entities/ap-mcu-order/dto.go @@ -0,0 +1,94 @@ +package apmcuorder + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + emo "simrs-vx/internal/domain/main-entities/mcu-order" +) + +type CreateDto struct { + McuOrder_Id string `json:"mcuOrder_id"` + Substances string `json:"substances"` + Fictations string `json:"fictations"` + Localization string `json:"localization"` + ClinicalDiagnoses string `json:"clinicalDiagnoses"` + Stadium string `json:"stadium"` + ClinicalNotes string `json:"clinicalNotes"` + PastHistory string `json:"pastHistory"` + CurrentHistory string `json:"currentHistory"` + PrevApMcu string `json:"prevApMcu"` + PrevApMcuNotes string `json:"prevApMcuNotes"` + SupportingExams string `json:"supportingExams"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Sort string `json:"sort"` + Pagination ecore.Pagination +} + +type FilterDto struct { + McuOrder_Id string `json:"mcu-order-id"` +} + +type ReadDetailDto struct { + Id uint64 `json:"id"` +} + +type UpdateDto struct { + Id uint64 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint64 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + McuOrder_Id string `json:"mcuOrder_id"` + McuOrder *emo.McuOrder + Substances string `json:"substances"` + Fictations string `json:"fictations"` + Localization string `json:"localization"` + ClinicalDiagnoses string `json:"clinicalDiagnoses"` + Stadium string `json:"stadium"` + ClinicalNotes string `json:"clinicalNotes"` + PastHistory string `json:"pastHistory"` + CurrentHistory string `json:"currentHistory"` + PrevApMcu string `json:"prevApMcu"` + PrevApMcuNotes string `json:"prevApMcuNotes"` + SupportingExams string `json:"supportingExams"` +} + +func (d ApMcuOrder) ToResponse() ResponseDto { + resp := ResponseDto{ + McuOrder_Id: d.McuOrder_Id, + Substances: d.Substances, + Fictations: d.Fictations, + Localization: d.Localization, + ClinicalDiagnoses: d.ClinicalDiagnoses, + Stadium: d.Stadium, + ClinicalNotes: d.ClinicalNotes, + PastHistory: d.PastHistory, + CurrentHistory: d.CurrentHistory, + PrevApMcu: d.PrevApMcu, + PrevApMcuNotes: d.PrevApMcuNotes, + } + resp.McuOrder = d.McuOrder + return resp +} + +func ToResponseList(data []ApMcuOrder) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/ap-mcu-order/entity.go b/internal/domain/main-entities/ap-mcu-order/entity.go new file mode 100644 index 00000000..f57e7497 --- /dev/null +++ b/internal/domain/main-entities/ap-mcu-order/entity.go @@ -0,0 +1,23 @@ +package apmcuorder + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + emo "simrs-vx/internal/domain/main-entities/mcu-order" +) + +type ApMcuOrder struct { + ecore.BigMain + McuOrder_Id string `json:"mcuOrder_id" gorm:"unique;size:10"` + McuOrder *emo.McuOrder `json:"mcuOrder,omitempty" gorm:"foreignKey:McuOrder_Id;references:Id"` + Substances string `json:"substances"` + Fictations string `json:"fictations"` + Localization string `json:"localization"` + ClinicalDiagnoses string `json:"clinicalDiagnoses"` + Stadium string `json:"stadium"` + ClinicalNotes string `json:"clinicalNotes"` + PastHistory string `json:"pastHistory"` + CurrentHistory string `json:"currentHistory"` + PrevApMcu string `json:"prevApMcu"` + PrevApMcuNotes string `json:"prevApMcuNotes"` + SupportingExams string `json:"supportingExams"` +} diff --git a/internal/interface/migration/main-entities.go b/internal/interface/migration/main-entities.go index 34530d78..9767b21b 100644 --- a/internal/interface/migration/main-entities.go +++ b/internal/interface/migration/main-entities.go @@ -8,6 +8,7 @@ import ( ambulatory "simrs-vx/internal/domain/main-entities/ambulatory" antibioticinuse "simrs-vx/internal/domain/main-entities/antibiotic-in-use" antibioticsrccategory "simrs-vx/internal/domain/main-entities/antibiotic-src-category" + apmcuorder "simrs-vx/internal/domain/main-entities/ap-mcu-order" appointment "simrs-vx/internal/domain/main-entities/appointment" authpartner "simrs-vx/internal/domain/main-entities/auth-partner" chemo "simrs-vx/internal/domain/main-entities/chemo" @@ -121,6 +122,7 @@ import ( func getMainEntities() []any { return []any{ &authpartner.AuthPartner{}, + &apmcuorder.ApMcuOrder{}, &user.User{}, &userfes.UserFes{}, &division.Division{}, diff --git a/internal/use-case/main-use-case/ap-mcu-order/case.go b/internal/use-case/main-use-case/ap-mcu-order/case.go new file mode 100644 index 00000000..845b8eeb --- /dev/null +++ b/internal/use-case/main-use-case/ap-mcu-order/case.go @@ -0,0 +1,276 @@ +package apmcuorder + +import ( + e "simrs-vx/internal/domain/main-entities/ap-mcu-order" + "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 = "device" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.ApMcuOrder{} + + 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.ApMcuOrder + var dataList []e.ApMcuOrder + var metaList *e.MetaDto + var err error + + event := pl.Event{ + Feature: "ReadList", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "readList") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, data); err != nil { + return err + } + + if dataList, metaList, err = ReadListData(input, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "list-data", + "status": "fetched", + "page_number": strconv.Itoa(metaList.PageNumber), + "page_size": strconv.Itoa(metaList.PageSize), + "record_totalCount": strconv.Itoa(metaList.Count), + "record_currentCount": strconv.Itoa(len(dataList)), + }, + Data: e.ToResponseList(dataList), + }, nil +} + +func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { + var data *e.ApMcuOrder + 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.ApMcuOrder + 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.ApMcuOrder + 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 + +} diff --git a/internal/use-case/main-use-case/ap-mcu-order/helper.go b/internal/use-case/main-use-case/ap-mcu-order/helper.go new file mode 100644 index 00000000..717e6ce6 --- /dev/null +++ b/internal/use-case/main-use-case/ap-mcu-order/helper.go @@ -0,0 +1,30 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package apmcuorder + +import ( + e "simrs-vx/internal/domain/main-entities/ap-mcu-order" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.ApMcuOrder) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.McuOrder_Id = inputSrc.McuOrder_Id + data.Substances = inputSrc.Substances + data.Fictations = inputSrc.Fictations + data.Localization = inputSrc.Localization + data.ClinicalDiagnoses = inputSrc.ClinicalDiagnoses + data.Stadium = inputSrc.Stadium + data.ClinicalNotes = inputSrc.ClinicalNotes + data.PastHistory = inputSrc.PastHistory + data.CurrentHistory = inputSrc.CurrentHistory + data.PrevApMcu = inputSrc.PrevApMcu +} diff --git a/internal/use-case/main-use-case/ap-mcu-order/lib.go b/internal/use-case/main-use-case/ap-mcu-order/lib.go new file mode 100644 index 00000000..8b6d8a74 --- /dev/null +++ b/internal/use-case/main-use-case/ap-mcu-order/lib.go @@ -0,0 +1,140 @@ +package apmcuorder + +import ( + e "simrs-vx/internal/domain/main-entities/ap-mcu-order" + + plh "simrs-vx/pkg/lib-helper" + 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.ApMcuOrder, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.ApMcuOrder{} + 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 { + return nil, plh.HandleCreateError(input, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.ApMcuOrder, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.ApMcuOrder{} + pagination := gh.Pagination{} + count := int64(0) + meta := e.MetaDto{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + tx = tx. + Model(&e.ApMcuOrder{}). + Scopes(gh.Preload(input.Includes)). + Scopes(gh.Filter(input.FilterDto)). + Count(&count). + Scopes(gh.Paginate(input, &pagination)). + Scopes(gh.Sort(input.Sort)) + + if err := tx.Find(&data).Error; err != nil { + if err == gorm.ErrRecordNotFound { + return nil, &meta, nil + } + return nil, nil, plh.HandleListError(input, event, err) + } + + 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.ApMcuOrder, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.ApMcuOrder{} + + 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.ApMcuOrder, 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.ApMcuOrder, 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 +} diff --git a/internal/use-case/main-use-case/ap-mcu-order/middleware-runner.go b/internal/use-case/main-use-case/ap-mcu-order/middleware-runner.go new file mode 100644 index 00000000..dc7f2495 --- /dev/null +++ b/internal/use-case/main-use-case/ap-mcu-order/middleware-runner.go @@ -0,0 +1,103 @@ +package apmcuorder + +import ( + e "simrs-vx/internal/domain/main-entities/ap-mcu-order" + 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.ApMcuOrder) 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.ApMcuOrder) 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.ApMcuOrder) 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.ApMcuOrder) 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.ApMcuOrder) 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 +} diff --git a/internal/use-case/main-use-case/ap-mcu-order/middleware.go b/internal/use-case/main-use-case/ap-mcu-order/middleware.go new file mode 100644 index 00000000..38161afe --- /dev/null +++ b/internal/use-case/main-use-case/ap-mcu-order/middleware.go @@ -0,0 +1,9 @@ +package apmcuorder + +// example of middleware +// func init() { +// createPreMw = append(createPreMw, +// CreateMw{Name: "modif-input", Func: pm.ModifInput}, +// CreateMw{Name: "check-data", Func: pm.CheckData}, +// ) +// } diff --git a/internal/use-case/main-use-case/ap-mcu-order/tycovar.go b/internal/use-case/main-use-case/ap-mcu-order/tycovar.go new file mode 100644 index 00000000..7f301ff1 --- /dev/null +++ b/internal/use-case/main-use-case/ap-mcu-order/tycovar.go @@ -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 apmcuorder + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/ap-mcu-order" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.ApMcuOrder, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.ApMcuOrder, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.ApMcuOrder, 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 From b9e0d2beb052fd79064055ea48729f965b49c206 Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Sun, 7 Dec 2025 18:35:29 +0700 Subject: [PATCH 27/42] feat/order-things: seperate mcu-order by scope --- .../main-entities/ap-mcu-order/base/dto.go | 23 +++++ .../main-entities/ap-mcu-order/base/entity.go | 23 +++++ .../domain/main-entities/ap-mcu-order/dto.go | 57 +++++++------ .../main-entities/ap-mcu-order/entity.go | 22 ++--- .../main-entities/cp-mcu-order/base/entity.go | 19 +++++ .../domain/main-entities/cp-mcu-order/dto.go | 80 ++++++++++++++++++ .../main-entities/cp-mcu-order/entity.go | 13 +++ .../micro-mcu-order/base/entity.go | 16 ++++ .../main-entities/micro-mcu-order/dto.go | 82 ++++++++++++++++++ .../main-entities/micro-mcu-order/entity.go | 13 +++ .../radiology-mcu-order/base/entity.go | 15 ++++ .../main-entities/radiology-mcu-order/dto.go | 84 +++++++++++++++++++ .../radiology-mcu-order/entity.go | 15 ++++ .../main-use-case/ap-mcu-order/helper.go | 3 - 14 files changed, 417 insertions(+), 48 deletions(-) create mode 100644 internal/domain/main-entities/ap-mcu-order/base/dto.go create mode 100644 internal/domain/main-entities/ap-mcu-order/base/entity.go create mode 100644 internal/domain/main-entities/cp-mcu-order/base/entity.go create mode 100644 internal/domain/main-entities/cp-mcu-order/dto.go create mode 100644 internal/domain/main-entities/cp-mcu-order/entity.go create mode 100644 internal/domain/main-entities/micro-mcu-order/base/entity.go create mode 100644 internal/domain/main-entities/micro-mcu-order/dto.go create mode 100644 internal/domain/main-entities/micro-mcu-order/entity.go create mode 100644 internal/domain/main-entities/radiology-mcu-order/base/entity.go create mode 100644 internal/domain/main-entities/radiology-mcu-order/dto.go create mode 100644 internal/domain/main-entities/radiology-mcu-order/entity.go diff --git a/internal/domain/main-entities/ap-mcu-order/base/dto.go b/internal/domain/main-entities/ap-mcu-order/base/dto.go new file mode 100644 index 00000000..447bc771 --- /dev/null +++ b/internal/domain/main-entities/ap-mcu-order/base/dto.go @@ -0,0 +1,23 @@ +package apmcuorder + +type CreateDto struct { + Encounter_Id uint `json:"encounter_id"` + Number uint64 `json:"number"` + Doctor_Code string `json:"-"` + Substances string `json:"substances"` + Fictations string `json:"fictations"` + Localization string `json:"localization"` + ClinicalDiagnoses string `json:"clinicalDiagnoses"` + Stadium string `json:"stadium"` + ClinicalNotes string `json:"clinicalNotes"` + CurrentHistory string `json:"currentHistory"` + PastHistory string `json:"pastHistory"` + PrevApMcu string `json:"prevApMcu"` + PrevApMcuNotes string `json:"prevApMcuNotes"` + SupportingExams string `json:"supportingExams"` +} + +type UpdateDto struct { + Id uint64 `json:"id"` + CreateDto +} diff --git a/internal/domain/main-entities/ap-mcu-order/base/entity.go b/internal/domain/main-entities/ap-mcu-order/base/entity.go new file mode 100644 index 00000000..5aa99c20 --- /dev/null +++ b/internal/domain/main-entities/ap-mcu-order/base/entity.go @@ -0,0 +1,23 @@ +package apmcuorder + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type ApMcuOrder struct { + ecore.BigMain + Encounter_Id uint `json:"encounter_id"` + Number uint64 `json:"number"` + Doctor_Code string `json:"doctor_code" gorm:"unique;size:20"` + Substances string `json:"substances"` + Fictations string `json:"fictations"` + Localization string `json:"localization"` + ClinicalDiagnoses string `json:"clinicalDiagnoses"` + Stadium string `json:"stadium"` + ClinicalNotes *string `json:"clinicalNotes"` + CurrentHistory string `json:"currentHistory"` + PastHistory string `json:"pastHistory"` + PrevApMcu *string `json:"prevApMcu"` + PrevApMcuNotes *string `json:"prevApMcuNotes"` + SupportingExams *string `json:"supportingExams"` +} diff --git a/internal/domain/main-entities/ap-mcu-order/dto.go b/internal/domain/main-entities/ap-mcu-order/dto.go index 7fcaa1d3..954efad2 100644 --- a/internal/domain/main-entities/ap-mcu-order/dto.go +++ b/internal/domain/main-entities/ap-mcu-order/dto.go @@ -2,22 +2,13 @@ package apmcuorder import ( ecore "simrs-vx/internal/domain/base-entities/core" - emo "simrs-vx/internal/domain/main-entities/mcu-order" + eamob "simrs-vx/internal/domain/main-entities/ap-mcu-order/base" + ed "simrs-vx/internal/domain/main-entities/doctor" + ee "simrs-vx/internal/domain/main-entities/encounter" ) type CreateDto struct { - McuOrder_Id string `json:"mcuOrder_id"` - Substances string `json:"substances"` - Fictations string `json:"fictations"` - Localization string `json:"localization"` - ClinicalDiagnoses string `json:"clinicalDiagnoses"` - Stadium string `json:"stadium"` - ClinicalNotes string `json:"clinicalNotes"` - PastHistory string `json:"pastHistory"` - CurrentHistory string `json:"currentHistory"` - PrevApMcu string `json:"prevApMcu"` - PrevApMcuNotes string `json:"prevApMcuNotes"` - SupportingExams string `json:"supportingExams"` + eamob.CreateDto } type ReadListDto struct { @@ -51,25 +42,32 @@ type MetaDto struct { } type ResponseDto struct { - ecore.Main - McuOrder_Id string `json:"mcuOrder_id"` - McuOrder *emo.McuOrder - Substances string `json:"substances"` - Fictations string `json:"fictations"` - Localization string `json:"localization"` - ClinicalDiagnoses string `json:"clinicalDiagnoses"` - Stadium string `json:"stadium"` - ClinicalNotes string `json:"clinicalNotes"` - PastHistory string `json:"pastHistory"` - CurrentHistory string `json:"currentHistory"` - PrevApMcu string `json:"prevApMcu"` - PrevApMcuNotes string `json:"prevApMcuNotes"` - SupportingExams string `json:"supportingExams"` + ecore.BigMain + Encounter_Id uint `json:"encounter_id"` + Encounter *ee.Encounter + Number uint64 `json:"number"` + Doctor_Code string `json:"doctor_code"` + Doctor *ed.Doctor + Substances string `json:"substances"` + Fictations string `json:"fictations"` + Localization string `json:"localization"` + ClinicalDiagnoses string `json:"clinicalDiagnoses"` + Stadium string `json:"stadium"` + ClinicalNotes *string `json:"clinicalNotes"` + PastHistory string `json:"pastHistory"` + CurrentHistory string `json:"currentHistory"` + PrevApMcu *string `json:"prevApMcu"` + PrevApMcuNotes *string `json:"prevApMcuNotes"` + SupportingExams *string `json:"supportingExams"` } func (d ApMcuOrder) ToResponse() ResponseDto { resp := ResponseDto{ - McuOrder_Id: d.McuOrder_Id, + Encounter_Id: d.Encounter_Id, + Encounter: d.Encounter, + Number: d.Number, + Doctor_Code: d.Doctor_Code, + Doctor: d.Doctor, Substances: d.Substances, Fictations: d.Fictations, Localization: d.Localization, @@ -80,8 +78,9 @@ func (d ApMcuOrder) ToResponse() ResponseDto { CurrentHistory: d.CurrentHistory, PrevApMcu: d.PrevApMcu, PrevApMcuNotes: d.PrevApMcuNotes, + SupportingExams: d.SupportingExams, } - resp.McuOrder = d.McuOrder + resp.BigMain = d.BigMain return resp } diff --git a/internal/domain/main-entities/ap-mcu-order/entity.go b/internal/domain/main-entities/ap-mcu-order/entity.go index f57e7497..703e9ebb 100644 --- a/internal/domain/main-entities/ap-mcu-order/entity.go +++ b/internal/domain/main-entities/ap-mcu-order/entity.go @@ -1,23 +1,13 @@ package apmcuorder import ( - ecore "simrs-vx/internal/domain/base-entities/core" - emo "simrs-vx/internal/domain/main-entities/mcu-order" + eamob "simrs-vx/internal/domain/main-entities/ap-mcu-order/base" + ed "simrs-vx/internal/domain/main-entities/doctor" + ee "simrs-vx/internal/domain/main-entities/encounter" ) type ApMcuOrder struct { - ecore.BigMain - McuOrder_Id string `json:"mcuOrder_id" gorm:"unique;size:10"` - McuOrder *emo.McuOrder `json:"mcuOrder,omitempty" gorm:"foreignKey:McuOrder_Id;references:Id"` - Substances string `json:"substances"` - Fictations string `json:"fictations"` - Localization string `json:"localization"` - ClinicalDiagnoses string `json:"clinicalDiagnoses"` - Stadium string `json:"stadium"` - ClinicalNotes string `json:"clinicalNotes"` - PastHistory string `json:"pastHistory"` - CurrentHistory string `json:"currentHistory"` - PrevApMcu string `json:"prevApMcu"` - PrevApMcuNotes string `json:"prevApMcuNotes"` - SupportingExams string `json:"supportingExams"` + eamob.ApMcuOrder + Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` + Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Code;references:Code"` } diff --git a/internal/domain/main-entities/cp-mcu-order/base/entity.go b/internal/domain/main-entities/cp-mcu-order/base/entity.go new file mode 100644 index 00000000..883ba0b6 --- /dev/null +++ b/internal/domain/main-entities/cp-mcu-order/base/entity.go @@ -0,0 +1,19 @@ +package cpmcuorder + +import ( + "time" + + ecore "simrs-vx/internal/domain/base-entities/core" + ercl "simrs-vx/internal/domain/references/clinical" +) + +type CpMcuOrder struct { + ecore.BigMain + Encounter_Id uint `json:"encounter_id"` + Number uint64 `json:"number"` + Doctor_Code string `json:"doctor_code" gorm:"unique;size:20"` + UrgencyLevel_Code ercl.McuUrgencyLevelCode `json:"urgencyLevel_code" gorm:"not null;size:15"` + OtherNotes *string `json:"otherNotes"` + ExamScheduleDate *time.Time `json:"examinationDate"` + Resume *string `json:"resume"` +} diff --git a/internal/domain/main-entities/cp-mcu-order/dto.go b/internal/domain/main-entities/cp-mcu-order/dto.go new file mode 100644 index 00000000..5cc2e753 --- /dev/null +++ b/internal/domain/main-entities/cp-mcu-order/dto.go @@ -0,0 +1,80 @@ +package cpmcuorder + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ed "simrs-vx/internal/domain/main-entities/doctor" + ee "simrs-vx/internal/domain/main-entities/encounter" +) + +type CreateDto struct { + Encounter_Id uint `json:"encounter_id" validate:"required"` + Number uint64 `json:"number"` // SHOULD BE AUTOMATIC WITHOUT SYNC + UrgencyLevel_Code string `json:"urgencyLevel_code" validate:"required"` + OtherNotes string `json:"otherNotes"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Sort string `json:"sort"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Encounter_Id uint `json:"encounter-id"` + Doctor_Code string `json:"doctor-code"` +} + +type ReadDetailDto struct { + Id uint64 `json:"id"` +} + +type UpdateDto struct { + Id uint64 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint64 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.BigMain + Encounter_Id uint + Encounter *ee.Encounter + Number uint64 `json:"number"` + Doctor_Code string `json:"doctor_code"` + Doctor *ed.Doctor + UrgencyLevel_Code string `json:"urgencyLevel_code" gorm:"not null;size:15"` + OtherNotes *string `json:"otherNotes"` + Resume *string `json:"resume"` +} + +func (d CpMcuOrder) ToResponse() ResponseDto { + resp := ResponseDto{ + Encounter_Id: d.Encounter_Id, + Encounter: d.Encounter, + Number: d.Number, + Doctor_Code: d.Doctor_Code, + Doctor: d.Doctor, + UrgencyLevel_Code: string(d.UrgencyLevel_Code), + OtherNotes: d.OtherNotes, + Resume: d.Resume, + } + resp.BigMain = d.BigMain + return resp +} + +func ToResponseList(data []CpMcuOrder) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/cp-mcu-order/entity.go b/internal/domain/main-entities/cp-mcu-order/entity.go new file mode 100644 index 00000000..92e20ef5 --- /dev/null +++ b/internal/domain/main-entities/cp-mcu-order/entity.go @@ -0,0 +1,13 @@ +package cpmcuorder + +import ( + eamob "simrs-vx/internal/domain/main-entities/cp-mcu-order/base" + ed "simrs-vx/internal/domain/main-entities/doctor" + ee "simrs-vx/internal/domain/main-entities/encounter" +) + +type CpMcuOrder struct { + eamob.CpMcuOrder + Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` + Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Code;references:Code"` +} diff --git a/internal/domain/main-entities/micro-mcu-order/base/entity.go b/internal/domain/main-entities/micro-mcu-order/base/entity.go new file mode 100644 index 00000000..2250ca20 --- /dev/null +++ b/internal/domain/main-entities/micro-mcu-order/base/entity.go @@ -0,0 +1,16 @@ +package micromcuorder + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ercl "simrs-vx/internal/domain/references/clinical" +) + +type MicroMcuOrder struct { + ecore.BigMain + Encounter_Id uint `json:"encounter_id"` + Number uint64 `json:"number"` + Doctor_Code string `json:"doctor_code" gorm:"unique;size:20"` + Stage_Code ercl.McuOrderStageCode `json:"stage_code" gorm:"not null;size:10"` + AxillaryTemp float64 `json:"axillaryTemp"` + OtherNotes *string `json:"otherNotes"` +} diff --git a/internal/domain/main-entities/micro-mcu-order/dto.go b/internal/domain/main-entities/micro-mcu-order/dto.go new file mode 100644 index 00000000..82f926db --- /dev/null +++ b/internal/domain/main-entities/micro-mcu-order/dto.go @@ -0,0 +1,82 @@ +package micromcuorder + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ed "simrs-vx/internal/domain/main-entities/doctor" + ee "simrs-vx/internal/domain/main-entities/encounter" + ercl "simrs-vx/internal/domain/references/clinical" +) + +type CreateDto struct { + Encounter_Id uint `json:"encounter_id" validate:"required"` + Number uint64 `json:"number"` // SHOULD BE AUTOMATIC WITHOUT SYNC + OrderStage_Code string `json:"orderStage_code" gorm:"not null;size:10"` + AxillaryTemp float64 `json:"axillaryTemp"` + OtherNotes string `json:"otherNotes"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Sort string `json:"sort"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Encounter_Id uint `json:"encounter-id"` + Doctor_Code string `json:"doctor-code"` +} + +type ReadDetailDto struct { + Id uint64 `json:"id"` +} + +type UpdateDto struct { + Id uint64 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint64 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.BigMain + Encounter_Id uint + Encounter *ee.Encounter + Number uint64 `json:"number"` + Doctor_Code string `json:"doctor_code"` + Doctor *ed.Doctor + Stage_Code ercl.McuOrderStageCode `json:"stage_code" gorm:"not null;size:10"` + AxillaryTemp float64 `json:"axillaryTemp"` + OtherNotes *string `json:"otherNotes"` +} + +func (d MicroMcuOrder) ToResponse() ResponseDto { + resp := ResponseDto{ + Encounter_Id: d.Encounter_Id, + Encounter: d.Encounter, + Number: d.Number, + Doctor_Code: d.Doctor_Code, + Doctor: d.Doctor, + Stage_Code: d.Stage_Code, + AxillaryTemp: d.AxillaryTemp, + OtherNotes: d.OtherNotes, + } + resp.BigMain = d.BigMain + return resp +} + +func ToResponseList(data []MicroMcuOrder) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/micro-mcu-order/entity.go b/internal/domain/main-entities/micro-mcu-order/entity.go new file mode 100644 index 00000000..1c645040 --- /dev/null +++ b/internal/domain/main-entities/micro-mcu-order/entity.go @@ -0,0 +1,13 @@ +package micromcuorder + +import ( + ed "simrs-vx/internal/domain/main-entities/doctor" + ee "simrs-vx/internal/domain/main-entities/encounter" + eamob "simrs-vx/internal/domain/main-entities/micro-mcu-order/base" +) + +type MicroMcuOrder struct { + eamob.MicroMcuOrder + Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` + Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Code;references:Code"` +} diff --git a/internal/domain/main-entities/radiology-mcu-order/base/entity.go b/internal/domain/main-entities/radiology-mcu-order/base/entity.go new file mode 100644 index 00000000..a771e0a7 --- /dev/null +++ b/internal/domain/main-entities/radiology-mcu-order/base/entity.go @@ -0,0 +1,15 @@ +package radiologymcuorder + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type RadiologyMcuOrder struct { + ecore.BigMain + Encounter_Id uint `json:"encounter_id"` + Number uint64 `json:"number"` + Doctor_Code string `json:"doctor_code" gorm:"unique;size:20"` + ClinicalNotes *string `json:"clinicalNotes"` + OtherNotes *string `json:"otherNotes"` + Resume *string `json:"resume"` +} diff --git a/internal/domain/main-entities/radiology-mcu-order/dto.go b/internal/domain/main-entities/radiology-mcu-order/dto.go new file mode 100644 index 00000000..f24b5668 --- /dev/null +++ b/internal/domain/main-entities/radiology-mcu-order/dto.go @@ -0,0 +1,84 @@ +package radiologymcuorder + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ed "simrs-vx/internal/domain/main-entities/doctor" + ee "simrs-vx/internal/domain/main-entities/encounter" + ermoi "simrs-vx/internal/domain/main-entities/radiology-mcu-order-item/base" +) + +type CreateDto struct { + Encounter_Id uint `json:"encounter_id"` + Number *uint64 `json:"number"` // SHOULD BE AUTOMATIC WITHOUT SYNC + Doctor_Code string `json:"-" validate:"required"` + ClinicalNotes string `json:"clinicalNotes"` + OtherNotes string `json:"otherNotes"` + Items []ermoi.SubCreateDto `json:"items" validate:"required"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Sort string `json:"sort"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Encounter_Id uint `json:"encounter-id"` + Doctor_Code string `json:"doctor-code"` +} + +type ReadDetailDto struct { + Id uint64 `json:"id"` +} + +type UpdateDto struct { + Id uint64 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint64 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.BigMain + Encounter_Id uint `json:"encounter_id"` + Encounter *ee.Encounter + Number uint64 `json:"number"` + Doctor_Code string `json:"doctor_code"` + Doctor *ed.Doctor + ClinicalNotes *string `json:"clinicalNotes"` + OtherNotes *string `json:"otherNotes"` + Resume *string `json:"resume"` + Items []*ermoi.RadiologyMcuOrderItem +} + +func (d RadiologyMcuOrder) ToResponse() ResponseDto { + resp := ResponseDto{ + Encounter_Id: d.Encounter_Id, + Encounter: d.Encounter, + Number: d.Number, + Doctor_Code: d.Doctor_Code, + Doctor: d.Doctor, + ClinicalNotes: d.ClinicalNotes, + OtherNotes: d.OtherNotes, + Resume: d.Resume, + } + resp.BigMain = d.BigMain + return resp +} + +func ToResponseList(data []RadiologyMcuOrder) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/radiology-mcu-order/entity.go b/internal/domain/main-entities/radiology-mcu-order/entity.go new file mode 100644 index 00000000..2ff3ec20 --- /dev/null +++ b/internal/domain/main-entities/radiology-mcu-order/entity.go @@ -0,0 +1,15 @@ +package radiologymcuorder + +import ( + ed "simrs-vx/internal/domain/main-entities/doctor" + ee "simrs-vx/internal/domain/main-entities/encounter" + ermoi "simrs-vx/internal/domain/main-entities/radiology-mcu-order-item/base" + eamob "simrs-vx/internal/domain/main-entities/radiology-mcu-order/base" +) + +type RadiologyMcuOrder struct { + eamob.RadiologyMcuOrder + Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` + Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Code;references:Code"` + Items []*ermoi.RadiologyMcuOrderItem `json:"items" gorm:"foreignKey:RadiologyMcuOrder_Id;references:Id"` +} diff --git a/internal/use-case/main-use-case/ap-mcu-order/helper.go b/internal/use-case/main-use-case/ap-mcu-order/helper.go index 717e6ce6..4b91b7aa 100644 --- a/internal/use-case/main-use-case/ap-mcu-order/helper.go +++ b/internal/use-case/main-use-case/ap-mcu-order/helper.go @@ -17,14 +17,11 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.ApMcuOrder) { inputSrc = &inputTemp.CreateDto } - data.McuOrder_Id = inputSrc.McuOrder_Id data.Substances = inputSrc.Substances data.Fictations = inputSrc.Fictations data.Localization = inputSrc.Localization data.ClinicalDiagnoses = inputSrc.ClinicalDiagnoses data.Stadium = inputSrc.Stadium - data.ClinicalNotes = inputSrc.ClinicalNotes data.PastHistory = inputSrc.PastHistory data.CurrentHistory = inputSrc.CurrentHistory - data.PrevApMcu = inputSrc.PrevApMcu } From 24d216ec5653ca00f2b24c502f73bd2707b67484 Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Mon, 8 Dec 2025 04:08:01 +0700 Subject: [PATCH 28/42] feat/order-things: separated mcu-order-items --- .../cp-mcu-order-item/base/dto.go | 6 ++ .../cp-mcu-order-item/base/entity.go | 16 ++++ .../main-entities/cp-mcu-order-item/dto.go | 80 +++++++++++++++++++ .../main-entities/cp-mcu-order-item/entity.go | 21 +++++ .../micro-mcu-order-item/base/dto.go | 6 ++ .../micro-mcu-order-item/base/entity.go | 17 ++++ .../main-entities/micro-mcu-order-item/dto.go | 80 +++++++++++++++++++ .../micro-mcu-order-item/entity.go | 17 ++++ .../radiology-mcu-order-item/base/dto.go | 6 ++ .../radiology-mcu-order-item/base/entity.go | 17 ++++ .../radiology-mcu-order-item/dto.go | 80 +++++++++++++++++++ .../radiology-mcu-order-item/entity.go | 17 ++++ .../domain/references/clinical/clinical.go | 4 + 13 files changed, 367 insertions(+) create mode 100644 internal/domain/main-entities/cp-mcu-order-item/base/dto.go create mode 100644 internal/domain/main-entities/cp-mcu-order-item/base/entity.go create mode 100644 internal/domain/main-entities/cp-mcu-order-item/dto.go create mode 100644 internal/domain/main-entities/cp-mcu-order-item/entity.go create mode 100644 internal/domain/main-entities/micro-mcu-order-item/base/dto.go create mode 100644 internal/domain/main-entities/micro-mcu-order-item/base/entity.go create mode 100644 internal/domain/main-entities/micro-mcu-order-item/dto.go create mode 100644 internal/domain/main-entities/micro-mcu-order-item/entity.go create mode 100644 internal/domain/main-entities/radiology-mcu-order-item/base/dto.go create mode 100644 internal/domain/main-entities/radiology-mcu-order-item/base/entity.go create mode 100644 internal/domain/main-entities/radiology-mcu-order-item/dto.go create mode 100644 internal/domain/main-entities/radiology-mcu-order-item/entity.go diff --git a/internal/domain/main-entities/cp-mcu-order-item/base/dto.go b/internal/domain/main-entities/cp-mcu-order-item/base/dto.go new file mode 100644 index 00000000..2510f9a0 --- /dev/null +++ b/internal/domain/main-entities/cp-mcu-order-item/base/dto.go @@ -0,0 +1,6 @@ +package cpmcuorderitem + +type SubCreateDto struct { + McuSrc_Code string `json:"mcuSrc_code" validate:"required"` + Note string `json:"note"` +} diff --git a/internal/domain/main-entities/cp-mcu-order-item/base/entity.go b/internal/domain/main-entities/cp-mcu-order-item/base/entity.go new file mode 100644 index 00000000..49cea380 --- /dev/null +++ b/internal/domain/main-entities/cp-mcu-order-item/base/entity.go @@ -0,0 +1,16 @@ +package cpmcuorderitem + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + + erc "simrs-vx/internal/domain/references/common" +) + +type CpMcuOrderItem struct { + ecore.BigMain // adjust this according to the needs + CpMcuOrder_Id uint64 `json:"cpMcuOrder_id" gorm:"uniqueIndex:idx_order_src"` + McuSrc_Code string `json:"mcuSrc_code" gorm:"uniqueIndex:idx_order_src"` + Note *string `json:"note" gorm:"size:1024"` + Result *string `json:"result"` + Status_Code erc.DataStatusCode `json:"status_code"` +} diff --git a/internal/domain/main-entities/cp-mcu-order-item/dto.go b/internal/domain/main-entities/cp-mcu-order-item/dto.go new file mode 100644 index 00000000..a0979186 --- /dev/null +++ b/internal/domain/main-entities/cp-mcu-order-item/dto.go @@ -0,0 +1,80 @@ +package cpmcuorderitem + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + emro "simrs-vx/internal/domain/main-entities/cp-mcu-order" + ems "simrs-vx/internal/domain/main-entities/mcu-src" + erc "simrs-vx/internal/domain/references/common" + "time" +) + +type CreateDto struct { + CpMcuOrder_Id uint64 `json:"cpMcuOrder_id"` + McuSrc_Code string `json:"mcuSrc_code"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + CpMcuOrder_Id *uint64 `json:"cp-mcu-order-id"` + McuSrc_Code *string `json:"mcu-src-code"` + Status_Code erc.DataStatusCode `json:"status-code"` +} +type ReadDetailDto struct { + Id uint `json:"id"` +} + +type UpdateDto struct { + Id uint `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint `json:"id"` +} + +type SetScheduleDto struct { + Id uint `json:"id"` + ExaminationDate *time.Time `json:"examinationDate"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.BigMain + CpMcuOrder_Id uint64 `json:"cpMcuOrder_id"` + CpMcuOrder *emro.CpMcuOrder `json:"cpMcuOrder,omitempty"` + McuSrc_Code string `json:"mcuSrc_code"` + McuSrc *ems.McuSrc `json:"mcuSrc,omitempty"` + Result *string `json:"result"` + Status_Code erc.DataStatusCode `json:"status_code"` +} + +func (d CpMcuOrderItem) ToResponse() ResponseDto { + resp := ResponseDto{ + CpMcuOrder_Id: d.CpMcuOrder_Id, + CpMcuOrder: d.CpMcuOrder, + McuSrc_Code: d.McuSrc_Code, + McuSrc: d.McuSrc, + Result: d.Result, + Status_Code: d.Status_Code, + } + resp.BigMain = d.BigMain + return resp +} + +func ToResponseList(data []CpMcuOrderItem) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/cp-mcu-order-item/entity.go b/internal/domain/main-entities/cp-mcu-order-item/entity.go new file mode 100644 index 00000000..65ec70cd --- /dev/null +++ b/internal/domain/main-entities/cp-mcu-order-item/entity.go @@ -0,0 +1,21 @@ +package cpmcuorderitem + +import ( + emo "simrs-vx/internal/domain/main-entities/cp-mcu-order" + emoib "simrs-vx/internal/domain/main-entities/cp-mcu-order-item/base" + + emosi "simrs-vx/internal/domain/main-entities/mcu-order-sub-item/base" + ems "simrs-vx/internal/domain/main-entities/mcu-src" + erc "simrs-vx/internal/domain/references/common" +) + +type CpMcuOrderItem struct { + emoib.CpMcuOrderItem + CpMcuOrder *emo.CpMcuOrder `json:"cpMcuOrder,omitempty" gorm:"foreignKey:McuOrder_Id;references:Id"` + McuSrc *ems.McuSrc `json:"mcuSrc,omitempty" gorm:"foreignKey:McuSrc_Code;references:Code"` + Items []*emosi.McuOrderSubItem `json:"items" gorm:"foreignKey:McuOrderItem_Id;references:Id"` +} + +func (d CpMcuOrderItem) IsCompleted() bool { + return d.Status_Code == erc.DSCDone +} diff --git a/internal/domain/main-entities/micro-mcu-order-item/base/dto.go b/internal/domain/main-entities/micro-mcu-order-item/base/dto.go new file mode 100644 index 00000000..56827131 --- /dev/null +++ b/internal/domain/main-entities/micro-mcu-order-item/base/dto.go @@ -0,0 +1,6 @@ +package micromcuorderitem + +type SubCreateDto struct { + McuSrc_Code string `json:"mcuSrc_code" validate:"required"` + Note string `json:"note"` +} diff --git a/internal/domain/main-entities/micro-mcu-order-item/base/entity.go b/internal/domain/main-entities/micro-mcu-order-item/base/entity.go new file mode 100644 index 00000000..c9d91561 --- /dev/null +++ b/internal/domain/main-entities/micro-mcu-order-item/base/entity.go @@ -0,0 +1,17 @@ +package micromcuorderitem + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ems "simrs-vx/internal/domain/main-entities/mcu-src" + erc "simrs-vx/internal/domain/references/common" +) + +type MicroMcuOrderItem struct { + ecore.BigMain // adjust this according to the needs + MicroMcuOrder_Id uint64 `json:"microMcuOrder_id" gorm:"uniqueIndex:idx_order_src"` + McuSrc_Code string `json:"mcuSrc_code" gorm:"uniqueIndex:idx_order_src"` + McuSrc *ems.McuSrc `json:"mcuSrc,omitempty" gorm:"foreignKey:McuSrc_Code;references:Code"` + Note *string `json:"note" gorm:"size:1024"` + Result *string `json:"result"` + Status_Code erc.DataStatusCode `json:"status_code"` +} diff --git a/internal/domain/main-entities/micro-mcu-order-item/dto.go b/internal/domain/main-entities/micro-mcu-order-item/dto.go new file mode 100644 index 00000000..1d2ceaeb --- /dev/null +++ b/internal/domain/main-entities/micro-mcu-order-item/dto.go @@ -0,0 +1,80 @@ +package micromcuorderitem + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ems "simrs-vx/internal/domain/main-entities/mcu-src" + emro "simrs-vx/internal/domain/main-entities/micro-mcu-order" + erc "simrs-vx/internal/domain/references/common" + "time" +) + +type CreateDto struct { + MicroMcuOrder_Id uint64 `json:"microMcuOrder_id"` + McuSrc_Code string `json:"mcuSrc_code"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + MicroMcuOrder_Id *uint64 `json:"micro-mcu-order-id"` + McuSrc_Code *string `json:"mcu-src-code"` + Status_Code erc.DataStatusCode `json:"status-code"` +} +type ReadDetailDto struct { + Id uint `json:"id"` +} + +type UpdateDto struct { + Id uint `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint `json:"id"` +} + +type SetScheduleDto struct { + Id uint `json:"id"` + ExaminationDate *time.Time `json:"examinationDate"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.BigMain + MicroMcuOrder_Id uint64 `json:"microMcuOrder_id"` + MicroMcuOrder *emro.MicroMcuOrder `json:"microMcuOrder,omitempty"` + McuSrc_Code string `json:"mcuSrc_code"` + McuSrc *ems.McuSrc `json:"mcuSrc,omitempty"` + Result *string `json:"result"` + Status_Code erc.DataStatusCode `json:"status_code"` +} + +func (d MicroMcuOrderItem) ToResponse() ResponseDto { + resp := ResponseDto{ + MicroMcuOrder_Id: d.MicroMcuOrder_Id, + MicroMcuOrder: d.MicroMcuOrder, + McuSrc_Code: d.McuSrc_Code, + McuSrc: d.McuSrc, + Result: d.Result, + Status_Code: d.Status_Code, + } + resp.BigMain = d.BigMain + return resp +} + +func ToResponseList(data []MicroMcuOrderItem) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/micro-mcu-order-item/entity.go b/internal/domain/main-entities/micro-mcu-order-item/entity.go new file mode 100644 index 00000000..8d818e27 --- /dev/null +++ b/internal/domain/main-entities/micro-mcu-order-item/entity.go @@ -0,0 +1,17 @@ +package micromcuorderitem + +import ( + emo "simrs-vx/internal/domain/main-entities/micro-mcu-order" + emoib "simrs-vx/internal/domain/main-entities/micro-mcu-order-item/base" + + erc "simrs-vx/internal/domain/references/common" +) + +type MicroMcuOrderItem struct { + emoib.MicroMcuOrderItem + MicroMcuOrder *emo.MicroMcuOrder `json:"microMcuOrder,omitempty" gorm:"foreignKey:McuOrder_Id;references:Id"` +} + +func (d MicroMcuOrderItem) IsCompleted() bool { + return d.Status_Code == erc.DSCDone +} diff --git a/internal/domain/main-entities/radiology-mcu-order-item/base/dto.go b/internal/domain/main-entities/radiology-mcu-order-item/base/dto.go new file mode 100644 index 00000000..8ca6d02f --- /dev/null +++ b/internal/domain/main-entities/radiology-mcu-order-item/base/dto.go @@ -0,0 +1,6 @@ +package radiologymcuorderitem + +type SubCreateDto struct { + McuSrc_Code string `json:"mcuSrc_code" validate:"required"` + Note string `json:"note"` +} diff --git a/internal/domain/main-entities/radiology-mcu-order-item/base/entity.go b/internal/domain/main-entities/radiology-mcu-order-item/base/entity.go new file mode 100644 index 00000000..1f3ff5a5 --- /dev/null +++ b/internal/domain/main-entities/radiology-mcu-order-item/base/entity.go @@ -0,0 +1,17 @@ +package radiologymcuorderitem + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ems "simrs-vx/internal/domain/main-entities/mcu-src" + erc "simrs-vx/internal/domain/references/common" +) + +type RadiologyMcuOrderItem struct { + ecore.BigMain // adjust this according to the needs + RadiologyMcuOrder_Id uint64 `json:"radiologyMcuOrder_id" gorm:"uniqueIndex:idx_order_src"` + McuSrc_Code string `json:"mcuSrc_code" gorm:"uniqueIndex:idx_order_src"` + McuSrc *ems.McuSrc `json:"mcuSrc,omitempty" gorm:"foreignKey:McuSrc_Code;references:Code"` + Note *string `json:"note" gorm:"size:1024"` + Result *string `json:"result"` + Status_Code erc.DataStatusCode `json:"status_code"` +} diff --git a/internal/domain/main-entities/radiology-mcu-order-item/dto.go b/internal/domain/main-entities/radiology-mcu-order-item/dto.go new file mode 100644 index 00000000..99c65df3 --- /dev/null +++ b/internal/domain/main-entities/radiology-mcu-order-item/dto.go @@ -0,0 +1,80 @@ +package radiologymcuorderitem + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ems "simrs-vx/internal/domain/main-entities/mcu-src" + emro "simrs-vx/internal/domain/main-entities/radiology-mcu-order" + erc "simrs-vx/internal/domain/references/common" + "time" +) + +type CreateDto struct { + RadiologyMcuOrder_Id uint64 `json:"radiologyMcuOrder_id"` + McuSrc_Code string `json:"mcuSrc_code"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + RadiologyMcuOrder_Id *uint64 `json:"radiology-mcu-order-id"` + McuSrc_Code *string `json:"mcu-src-code"` + Status_Code erc.DataStatusCode `json:"status-code"` +} +type ReadDetailDto struct { + Id uint `json:"id"` +} + +type UpdateDto struct { + Id uint `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint `json:"id"` +} + +type SetScheduleDto struct { + Id uint `json:"id"` + ExaminationDate *time.Time `json:"examinationDate"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.BigMain + RadiologyMcuOrder_Id uint64 `json:"radiologyMcuOrder_id"` + RadiologyMcuOrder *emro.RadiologyMcuOrder `json:"radiologyMcuOrder,omitempty"` + McuSrc_Code string `json:"mcuSrc_code"` + McuSrc *ems.McuSrc `json:"mcuSrc,omitempty"` + Result *string `json:"result"` + Status_Code erc.DataStatusCode `json:"status_code"` +} + +func (d RadiologyMcuOrderItem) ToResponse() ResponseDto { + resp := ResponseDto{ + RadiologyMcuOrder_Id: d.RadiologyMcuOrder_Id, + RadiologyMcuOrder: d.RadiologyMcuOrder, + McuSrc_Code: d.McuSrc_Code, + McuSrc: d.McuSrc, + Result: d.Result, + Status_Code: d.Status_Code, + } + resp.BigMain = d.BigMain + return resp +} + +func ToResponseList(data []RadiologyMcuOrderItem) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/radiology-mcu-order-item/entity.go b/internal/domain/main-entities/radiology-mcu-order-item/entity.go new file mode 100644 index 00000000..2e1734a3 --- /dev/null +++ b/internal/domain/main-entities/radiology-mcu-order-item/entity.go @@ -0,0 +1,17 @@ +package radiologymcuorderitem + +import ( + emo "simrs-vx/internal/domain/main-entities/radiology-mcu-order" + emoib "simrs-vx/internal/domain/main-entities/radiology-mcu-order-item/base" + + erc "simrs-vx/internal/domain/references/common" +) + +type RadiologyMcuOrderItem struct { + emoib.RadiologyMcuOrderItem + RadiologyMcuOrder *emo.RadiologyMcuOrder `json:"radiologyMcuOrder,omitempty" gorm:"foreignKey:McuOrder_Id;references:Id"` +} + +func (d RadiologyMcuOrderItem) IsCompleted() bool { + return d.Status_Code == erc.DSCDone +} diff --git a/internal/domain/references/clinical/clinical.go b/internal/domain/references/clinical/clinical.go index a9d3fc2b..80c451c7 100644 --- a/internal/domain/references/clinical/clinical.go +++ b/internal/domain/references/clinical/clinical.go @@ -9,6 +9,7 @@ type ( InstructionCode string HeadToToeCode string McuUrgencyLevelCode string + McuOrderStageCode string McuScopeCode string SoapiTypeCode string MedicalActionTypeCode string @@ -125,6 +126,9 @@ const ( MULCPF McuUrgencyLevelCode = "priority-form" // Form Prioritas MULCRT McuUrgencyLevelCode = "routine" // Pemeriksaan Rutin + MOSFirst McuOrderStageCode = "first" // Stage 1 + MOSSecond McuOrderStageCode = "repeat" // Stage 2 + STCEarlyNurse SoapiTypeCode = "early-nursery" // Kajian Awal Keperawatan STCEEarlyMedic SoapiTypeCode = "early-medic" // Kajian Awal Rehab Medis STCEarlyRehab SoapiTypeCode = "early-rehab" // Kajian Awal Rehab Medik From 1036cab53ccd8ea8dcd844e6a4411156b80c36d3 Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Mon, 8 Dec 2025 05:13:04 +0700 Subject: [PATCH 29/42] feat/order-things: entity separation finalization --- .../migrations/20251207212015.sql | 99 +++++++++++++++++++ .../migrations/20251207221222.sql | 8 ++ cmd/main-migration/migrations/atlas.sum | 6 +- .../main-entities/ap-mcu-order/base/entity.go | 30 +++--- .../domain/main-entities/ap-mcu-order/dto.go | 3 + .../main-entities/ap-mcu-order/entity.go | 13 +++ .../cp-mcu-order-item/base/entity.go | 3 +- .../main-entities/cp-mcu-order-item/entity.go | 6 +- .../main-entities/cp-mcu-order/base/entity.go | 2 + .../domain/main-entities/cp-mcu-order/dto.go | 6 +- .../main-entities/cp-mcu-order/entity.go | 19 +++- .../micro-mcu-order-item/entity.go | 5 +- .../micro-mcu-order/base/entity.go | 2 + .../main-entities/micro-mcu-order/dto.go | 6 +- .../main-entities/micro-mcu-order/entity.go | 19 +++- .../radiology-mcu-order-item/entity.go | 2 +- .../radiology-mcu-order/base/entity.go | 14 +-- .../main-entities/radiology-mcu-order/dto.go | 10 +- .../radiology-mcu-order/entity.go | 13 +++ internal/interface/migration/main-entities.go | 14 ++- 20 files changed, 239 insertions(+), 41 deletions(-) create mode 100644 cmd/main-migration/migrations/20251207212015.sql create mode 100644 cmd/main-migration/migrations/20251207221222.sql diff --git a/cmd/main-migration/migrations/20251207212015.sql b/cmd/main-migration/migrations/20251207212015.sql new file mode 100644 index 00000000..c551aa8c --- /dev/null +++ b/cmd/main-migration/migrations/20251207212015.sql @@ -0,0 +1,99 @@ +-- Modify "ApMcuOrder" table +ALTER TABLE "public"."ApMcuOrder" DROP COLUMN "McuOrder_Id", ADD COLUMN "Encounter_Id" bigint NULL, ADD COLUMN "Number" bigint NULL, ADD COLUMN "Doctor_Code" character varying(20) NULL, ADD CONSTRAINT "uni_ApMcuOrder_Doctor_Code" UNIQUE ("Doctor_Code"), ADD CONSTRAINT "fk_ApMcuOrder_Doctor" FOREIGN KEY ("Doctor_Code") REFERENCES "public"."Doctor" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_ApMcuOrder_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION; +-- Create "CpMcuOrder" table +CREATE TABLE "public"."CpMcuOrder" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Encounter_Id" bigint NULL, + "Number" bigint NULL, + "Doctor_Code" character varying(20) NULL, + "UrgencyLevel_Code" character varying(15) NOT NULL, + "OtherNotes" text NULL, + "ExamScheduleDate" timestamptz NULL, + "Resume" text NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "uni_CpMcuOrder_Doctor_Code" UNIQUE ("Doctor_Code"), + CONSTRAINT "fk_CpMcuOrder_Doctor" FOREIGN KEY ("Doctor_Code") REFERENCES "public"."Doctor" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_CpMcuOrder_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "CpMcuOrderItem" table +CREATE TABLE "public"."CpMcuOrderItem" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "CpMcuOrder_Id" bigint NULL, + "McuSrc_Code" character varying(20) NULL, + "Note" character varying(1024) NULL, + "Result" text NULL, + "Status_Code" text NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_CpMcuOrderItem_CpMcuOrder" FOREIGN KEY ("CpMcuOrder_Id") REFERENCES "public"."CpMcuOrder" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_CpMcuOrderItem_McuSrc" FOREIGN KEY ("McuSrc_Code") REFERENCES "public"."McuSrc" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "MicroMcuOrder" table +CREATE TABLE "public"."MicroMcuOrder" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Encounter_Id" bigint NULL, + "Number" bigint NULL, + "Doctor_Code" character varying(20) NULL, + "Stage_Code" character varying(10) NOT NULL, + "AxillaryTemp" numeric NULL, + "OtherNotes" text NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "uni_MicroMcuOrder_Doctor_Code" UNIQUE ("Doctor_Code"), + CONSTRAINT "fk_MicroMcuOrder_Doctor" FOREIGN KEY ("Doctor_Code") REFERENCES "public"."Doctor" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_MicroMcuOrder_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "MicroMcuOrderItem" table +CREATE TABLE "public"."MicroMcuOrderItem" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "MicroMcuOrder_Id" bigint NULL, + "McuSrc_Code" character varying(20) NULL, + "Note" character varying(1024) NULL, + "Result" text NULL, + "Status_Code" text NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_MicroMcuOrderItem_McuSrc" FOREIGN KEY ("McuSrc_Code") REFERENCES "public"."McuSrc" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_MicroMcuOrderItem_MicroMcuOrder" FOREIGN KEY ("MicroMcuOrder_Id") REFERENCES "public"."MicroMcuOrder" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "RadiologyMcuOrder" table +CREATE TABLE "public"."RadiologyMcuOrder" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Encounter_Id" bigint NULL, + "Number" bigint NULL, + "Doctor_Code" character varying(20) NULL, + "ClinicalNotes" text NULL, + "OtherNotes" text NULL, + "Resume" text NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "uni_RadiologyMcuOrder_Doctor_Code" UNIQUE ("Doctor_Code"), + CONSTRAINT "fk_RadiologyMcuOrder_Doctor" FOREIGN KEY ("Doctor_Code") REFERENCES "public"."Doctor" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_RadiologyMcuOrder_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "RadiologyMcuOrderItem" table +CREATE TABLE "public"."RadiologyMcuOrderItem" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "RadiologyMcuOrder_Id" bigint NULL, + "McuSrc_Code" character varying(20) NULL, + "Note" character varying(1024) NULL, + "Result" text NULL, + "Status_Code" text NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_RadiologyMcuOrderItem_McuSrc" FOREIGN KEY ("McuSrc_Code") REFERENCES "public"."McuSrc" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_RadiologyMcuOrderItem_RadiologyMcuOrder" FOREIGN KEY ("RadiologyMcuOrder_Id") REFERENCES "public"."RadiologyMcuOrder" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); diff --git a/cmd/main-migration/migrations/20251207221222.sql b/cmd/main-migration/migrations/20251207221222.sql new file mode 100644 index 00000000..3c806128 --- /dev/null +++ b/cmd/main-migration/migrations/20251207221222.sql @@ -0,0 +1,8 @@ +-- Modify "ApMcuOrder" table +ALTER TABLE "public"."ApMcuOrder" ADD COLUMN "Status_Code" character varying(10) NOT NULL; +-- Modify "CpMcuOrder" table +ALTER TABLE "public"."CpMcuOrder" ADD COLUMN "Status_Code" character varying(10) NOT NULL; +-- Modify "MicroMcuOrder" table +ALTER TABLE "public"."MicroMcuOrder" ADD COLUMN "Status_Code" character varying(10) NOT NULL; +-- Modify "RadiologyMcuOrder" table +ALTER TABLE "public"."RadiologyMcuOrder" ADD COLUMN "Status_Code" character varying(10) NOT NULL; diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 632e0ddb..c1ede307 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:1BOh7w/6hkhDj1PptjXT4tLOgmRtIIofGm3ERJ+EfyM= +h1:o4jOACV/QY64oiqrbnZvGei0J65px0JBwAXakl8h+Oc= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -145,4 +145,6 @@ h1:1BOh7w/6hkhDj1PptjXT4tLOgmRtIIofGm3ERJ+EfyM= 20251202180207.sql h1:IHmSMIO3ia+YV5GULixbdlV1joaUAWtnjQHPd8+HKiM= 20251202231005.sql h1:lua0KKoeBptSfs/6ehZE6Azo6YUlNkOJwGFyb1HQWkY= 20251203205052.sql h1:nk0VK2Uv4bHE3SBfHo/aevVZxtHzr7zAzvmMU8TCCtk= -20251207020537.sql h1:UmtHxX1vZi/BiKxHPOOP7fALRZ3RoRGSGmUma7ttp8w= +20251207020537.sql h1:uqqIQaBoZGoOXVQKkalNXwF2awcA+rhjNVevWEzIIok= +20251207212015.sql h1:muRdWqRKfJQFMfezj2B4n0E6bbjIz1GrzHEyhoxy2mk= +20251207221222.sql h1:+mU/25n3hQLRU6MK8B+Uwzl9YBRezX3xWDtIKnweN78= diff --git a/internal/domain/main-entities/ap-mcu-order/base/entity.go b/internal/domain/main-entities/ap-mcu-order/base/entity.go index 5aa99c20..d098fcfd 100644 --- a/internal/domain/main-entities/ap-mcu-order/base/entity.go +++ b/internal/domain/main-entities/ap-mcu-order/base/entity.go @@ -2,22 +2,24 @@ package apmcuorder import ( ecore "simrs-vx/internal/domain/base-entities/core" + erc "simrs-vx/internal/domain/references/common" ) type ApMcuOrder struct { ecore.BigMain - Encounter_Id uint `json:"encounter_id"` - Number uint64 `json:"number"` - Doctor_Code string `json:"doctor_code" gorm:"unique;size:20"` - Substances string `json:"substances"` - Fictations string `json:"fictations"` - Localization string `json:"localization"` - ClinicalDiagnoses string `json:"clinicalDiagnoses"` - Stadium string `json:"stadium"` - ClinicalNotes *string `json:"clinicalNotes"` - CurrentHistory string `json:"currentHistory"` - PastHistory string `json:"pastHistory"` - PrevApMcu *string `json:"prevApMcu"` - PrevApMcuNotes *string `json:"prevApMcuNotes"` - SupportingExams *string `json:"supportingExams"` + Encounter_Id uint `json:"encounter_id"` + Number uint64 `json:"number"` + Doctor_Code string `json:"doctor_code" gorm:"unique;size:20"` + Substances string `json:"substances"` + Fictations string `json:"fictations"` + Localization string `json:"localization"` + ClinicalDiagnoses string `json:"clinicalDiagnoses"` + Stadium string `json:"stadium"` + ClinicalNotes *string `json:"clinicalNotes"` + CurrentHistory string `json:"currentHistory"` + PastHistory string `json:"pastHistory"` + PrevApMcu *string `json:"prevApMcu"` + PrevApMcuNotes *string `json:"prevApMcuNotes"` + SupportingExams *string `json:"supportingExams"` + Status_Code erc.DataStatusCode `json:"status_code" gorm:"not null;size:10"` } diff --git a/internal/domain/main-entities/ap-mcu-order/dto.go b/internal/domain/main-entities/ap-mcu-order/dto.go index 954efad2..80b0b447 100644 --- a/internal/domain/main-entities/ap-mcu-order/dto.go +++ b/internal/domain/main-entities/ap-mcu-order/dto.go @@ -1,6 +1,8 @@ package apmcuorder import ( + la "simrs-vx/internal/lib/auth" + ecore "simrs-vx/internal/domain/base-entities/core" eamob "simrs-vx/internal/domain/main-entities/ap-mcu-order/base" ed "simrs-vx/internal/domain/main-entities/doctor" @@ -9,6 +11,7 @@ import ( type CreateDto struct { eamob.CreateDto + la.AuthInfo } type ReadListDto struct { diff --git a/internal/domain/main-entities/ap-mcu-order/entity.go b/internal/domain/main-entities/ap-mcu-order/entity.go index 703e9ebb..361d0948 100644 --- a/internal/domain/main-entities/ap-mcu-order/entity.go +++ b/internal/domain/main-entities/ap-mcu-order/entity.go @@ -4,6 +4,7 @@ import ( eamob "simrs-vx/internal/domain/main-entities/ap-mcu-order/base" ed "simrs-vx/internal/domain/main-entities/doctor" ee "simrs-vx/internal/domain/main-entities/encounter" + erc "simrs-vx/internal/domain/references/common" ) type ApMcuOrder struct { @@ -11,3 +12,15 @@ type ApMcuOrder struct { Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Code;references:Code"` } + +func (d ApMcuOrder) IsNotNew() bool { + return d.Status_Code != erc.DSCNew +} + +func (d ApMcuOrder) IsCompleted() bool { + return d.Status_Code == erc.DSCDone +} + +func (d ApMcuOrder) IsSameDoctor(doctor_code *string) bool { + return d.Doctor_Code == *doctor_code +} diff --git a/internal/domain/main-entities/cp-mcu-order-item/base/entity.go b/internal/domain/main-entities/cp-mcu-order-item/base/entity.go index 49cea380..5abb8494 100644 --- a/internal/domain/main-entities/cp-mcu-order-item/base/entity.go +++ b/internal/domain/main-entities/cp-mcu-order-item/base/entity.go @@ -2,7 +2,7 @@ package cpmcuorderitem import ( ecore "simrs-vx/internal/domain/base-entities/core" - + ems "simrs-vx/internal/domain/main-entities/mcu-src" erc "simrs-vx/internal/domain/references/common" ) @@ -10,6 +10,7 @@ type CpMcuOrderItem struct { ecore.BigMain // adjust this according to the needs CpMcuOrder_Id uint64 `json:"cpMcuOrder_id" gorm:"uniqueIndex:idx_order_src"` McuSrc_Code string `json:"mcuSrc_code" gorm:"uniqueIndex:idx_order_src"` + McuSrc *ems.McuSrc `json:"mcuSrc,omitempty" gorm:"foreignKey:McuSrc_Code;references:Code"` Note *string `json:"note" gorm:"size:1024"` Result *string `json:"result"` Status_Code erc.DataStatusCode `json:"status_code"` diff --git a/internal/domain/main-entities/cp-mcu-order-item/entity.go b/internal/domain/main-entities/cp-mcu-order-item/entity.go index 65ec70cd..5858ab58 100644 --- a/internal/domain/main-entities/cp-mcu-order-item/entity.go +++ b/internal/domain/main-entities/cp-mcu-order-item/entity.go @@ -4,16 +4,12 @@ import ( emo "simrs-vx/internal/domain/main-entities/cp-mcu-order" emoib "simrs-vx/internal/domain/main-entities/cp-mcu-order-item/base" - emosi "simrs-vx/internal/domain/main-entities/mcu-order-sub-item/base" - ems "simrs-vx/internal/domain/main-entities/mcu-src" erc "simrs-vx/internal/domain/references/common" ) type CpMcuOrderItem struct { emoib.CpMcuOrderItem - CpMcuOrder *emo.CpMcuOrder `json:"cpMcuOrder,omitempty" gorm:"foreignKey:McuOrder_Id;references:Id"` - McuSrc *ems.McuSrc `json:"mcuSrc,omitempty" gorm:"foreignKey:McuSrc_Code;references:Code"` - Items []*emosi.McuOrderSubItem `json:"items" gorm:"foreignKey:McuOrderItem_Id;references:Id"` + CpMcuOrder *emo.CpMcuOrder `json:"cpMcuOrder,omitempty" gorm:"foreignKey:CpMcuOrder_Id;references:Id"` } func (d CpMcuOrderItem) IsCompleted() bool { diff --git a/internal/domain/main-entities/cp-mcu-order/base/entity.go b/internal/domain/main-entities/cp-mcu-order/base/entity.go index 883ba0b6..e9531e22 100644 --- a/internal/domain/main-entities/cp-mcu-order/base/entity.go +++ b/internal/domain/main-entities/cp-mcu-order/base/entity.go @@ -5,6 +5,7 @@ import ( ecore "simrs-vx/internal/domain/base-entities/core" ercl "simrs-vx/internal/domain/references/clinical" + erc "simrs-vx/internal/domain/references/common" ) type CpMcuOrder struct { @@ -16,4 +17,5 @@ type CpMcuOrder struct { OtherNotes *string `json:"otherNotes"` ExamScheduleDate *time.Time `json:"examinationDate"` Resume *string `json:"resume"` + Status_Code erc.DataStatusCode `json:"status_code" gorm:"not null;size:10"` } diff --git a/internal/domain/main-entities/cp-mcu-order/dto.go b/internal/domain/main-entities/cp-mcu-order/dto.go index 5cc2e753..afccfb20 100644 --- a/internal/domain/main-entities/cp-mcu-order/dto.go +++ b/internal/domain/main-entities/cp-mcu-order/dto.go @@ -1,6 +1,8 @@ package cpmcuorder import ( + la "simrs-vx/internal/lib/auth" + ecore "simrs-vx/internal/domain/base-entities/core" ed "simrs-vx/internal/domain/main-entities/doctor" ee "simrs-vx/internal/domain/main-entities/encounter" @@ -11,6 +13,7 @@ type CreateDto struct { Number uint64 `json:"number"` // SHOULD BE AUTOMATIC WITHOUT SYNC UrgencyLevel_Code string `json:"urgencyLevel_code" validate:"required"` OtherNotes string `json:"otherNotes"` + la.AuthInfo } type ReadListDto struct { @@ -26,7 +29,8 @@ type FilterDto struct { } type ReadDetailDto struct { - Id uint64 `json:"id"` + Id uint64 `json:"id"` + Includes string `json:"includes"` } type UpdateDto struct { diff --git a/internal/domain/main-entities/cp-mcu-order/entity.go b/internal/domain/main-entities/cp-mcu-order/entity.go index 92e20ef5..08a3d927 100644 --- a/internal/domain/main-entities/cp-mcu-order/entity.go +++ b/internal/domain/main-entities/cp-mcu-order/entity.go @@ -1,13 +1,28 @@ package cpmcuorder import ( + ecmoi "simrs-vx/internal/domain/main-entities/cp-mcu-order-item/base" eamob "simrs-vx/internal/domain/main-entities/cp-mcu-order/base" ed "simrs-vx/internal/domain/main-entities/doctor" ee "simrs-vx/internal/domain/main-entities/encounter" + erc "simrs-vx/internal/domain/references/common" ) type CpMcuOrder struct { eamob.CpMcuOrder - Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` - Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Code;references:Code"` + Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` + Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Code;references:Code"` + Items []*ecmoi.CpMcuOrderItem `json:"items" gorm:"foreignKey:CpMcuOrder_Id;references:Id"` +} + +func (d CpMcuOrder) IsNotNew() bool { + return d.Status_Code != erc.DSCNew +} + +func (d CpMcuOrder) IsCompleted() bool { + return d.Status_Code == erc.DSCDone +} + +func (d CpMcuOrder) IsSameDoctor(doctor_code *string) bool { + return d.Doctor_Code == *doctor_code } diff --git a/internal/domain/main-entities/micro-mcu-order-item/entity.go b/internal/domain/main-entities/micro-mcu-order-item/entity.go index 8d818e27..64d701f7 100644 --- a/internal/domain/main-entities/micro-mcu-order-item/entity.go +++ b/internal/domain/main-entities/micro-mcu-order-item/entity.go @@ -1,15 +1,16 @@ package micromcuorderitem import ( + ems "simrs-vx/internal/domain/main-entities/mcu-src" emo "simrs-vx/internal/domain/main-entities/micro-mcu-order" emoib "simrs-vx/internal/domain/main-entities/micro-mcu-order-item/base" - erc "simrs-vx/internal/domain/references/common" ) type MicroMcuOrderItem struct { emoib.MicroMcuOrderItem - MicroMcuOrder *emo.MicroMcuOrder `json:"microMcuOrder,omitempty" gorm:"foreignKey:McuOrder_Id;references:Id"` + MicroMcuOrder *emo.MicroMcuOrder `json:"microMcuOrder,omitempty" gorm:"foreignKey:MicroMcuOrder_Id;references:Id"` + McuSrc *ems.McuSrc `json:"mcuSrc,omitempty" gorm:"foreignKey:McuSrc_Code;references:Code"` } func (d MicroMcuOrderItem) IsCompleted() bool { diff --git a/internal/domain/main-entities/micro-mcu-order/base/entity.go b/internal/domain/main-entities/micro-mcu-order/base/entity.go index 2250ca20..3e611d81 100644 --- a/internal/domain/main-entities/micro-mcu-order/base/entity.go +++ b/internal/domain/main-entities/micro-mcu-order/base/entity.go @@ -3,6 +3,7 @@ package micromcuorder import ( ecore "simrs-vx/internal/domain/base-entities/core" ercl "simrs-vx/internal/domain/references/clinical" + erc "simrs-vx/internal/domain/references/common" ) type MicroMcuOrder struct { @@ -13,4 +14,5 @@ type MicroMcuOrder struct { Stage_Code ercl.McuOrderStageCode `json:"stage_code" gorm:"not null;size:10"` AxillaryTemp float64 `json:"axillaryTemp"` OtherNotes *string `json:"otherNotes"` + Status_Code erc.DataStatusCode `json:"status_code" gorm:"not null;size:10"` } diff --git a/internal/domain/main-entities/micro-mcu-order/dto.go b/internal/domain/main-entities/micro-mcu-order/dto.go index 82f926db..008f219f 100644 --- a/internal/domain/main-entities/micro-mcu-order/dto.go +++ b/internal/domain/main-entities/micro-mcu-order/dto.go @@ -1,6 +1,8 @@ package micromcuorder import ( + la "simrs-vx/internal/lib/auth" + ecore "simrs-vx/internal/domain/base-entities/core" ed "simrs-vx/internal/domain/main-entities/doctor" ee "simrs-vx/internal/domain/main-entities/encounter" @@ -13,6 +15,7 @@ type CreateDto struct { OrderStage_Code string `json:"orderStage_code" gorm:"not null;size:10"` AxillaryTemp float64 `json:"axillaryTemp"` OtherNotes string `json:"otherNotes"` + la.AuthInfo } type ReadListDto struct { @@ -28,7 +31,8 @@ type FilterDto struct { } type ReadDetailDto struct { - Id uint64 `json:"id"` + Id uint64 `json:"id"` + Includes string `json:"includes"` } type UpdateDto struct { diff --git a/internal/domain/main-entities/micro-mcu-order/entity.go b/internal/domain/main-entities/micro-mcu-order/entity.go index 1c645040..57550c84 100644 --- a/internal/domain/main-entities/micro-mcu-order/entity.go +++ b/internal/domain/main-entities/micro-mcu-order/entity.go @@ -3,11 +3,26 @@ package micromcuorder import ( ed "simrs-vx/internal/domain/main-entities/doctor" ee "simrs-vx/internal/domain/main-entities/encounter" + emmoi "simrs-vx/internal/domain/main-entities/micro-mcu-order-item/base" eamob "simrs-vx/internal/domain/main-entities/micro-mcu-order/base" + erc "simrs-vx/internal/domain/references/common" ) type MicroMcuOrder struct { eamob.MicroMcuOrder - Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` - Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Code;references:Code"` + Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` + Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Code;references:Code"` + Items []*emmoi.MicroMcuOrderItem `json:"items" gorm:"foreignKey:MicroMcuOrder_Id;references:Id"` +} + +func (d MicroMcuOrder) IsNotNew() bool { + return d.Status_Code != erc.DSCNew +} + +func (d MicroMcuOrder) IsCompleted() bool { + return d.Status_Code == erc.DSCDone +} + +func (d MicroMcuOrder) IsSameDoctor(doctor_code *string) bool { + return d.Doctor_Code == *doctor_code } diff --git a/internal/domain/main-entities/radiology-mcu-order-item/entity.go b/internal/domain/main-entities/radiology-mcu-order-item/entity.go index 2e1734a3..da20a56a 100644 --- a/internal/domain/main-entities/radiology-mcu-order-item/entity.go +++ b/internal/domain/main-entities/radiology-mcu-order-item/entity.go @@ -9,7 +9,7 @@ import ( type RadiologyMcuOrderItem struct { emoib.RadiologyMcuOrderItem - RadiologyMcuOrder *emo.RadiologyMcuOrder `json:"radiologyMcuOrder,omitempty" gorm:"foreignKey:McuOrder_Id;references:Id"` + RadiologyMcuOrder *emo.RadiologyMcuOrder `json:"radiologyMcuOrder,omitempty" gorm:"foreignKey:RadiologyMcuOrder_Id;references:Id"` } func (d RadiologyMcuOrderItem) IsCompleted() bool { diff --git a/internal/domain/main-entities/radiology-mcu-order/base/entity.go b/internal/domain/main-entities/radiology-mcu-order/base/entity.go index a771e0a7..6871e689 100644 --- a/internal/domain/main-entities/radiology-mcu-order/base/entity.go +++ b/internal/domain/main-entities/radiology-mcu-order/base/entity.go @@ -2,14 +2,16 @@ package radiologymcuorder import ( ecore "simrs-vx/internal/domain/base-entities/core" + erc "simrs-vx/internal/domain/references/common" ) type RadiologyMcuOrder struct { ecore.BigMain - Encounter_Id uint `json:"encounter_id"` - Number uint64 `json:"number"` - Doctor_Code string `json:"doctor_code" gorm:"unique;size:20"` - ClinicalNotes *string `json:"clinicalNotes"` - OtherNotes *string `json:"otherNotes"` - Resume *string `json:"resume"` + Encounter_Id uint `json:"encounter_id"` + Number uint64 `json:"number"` + Doctor_Code string `json:"doctor_code" gorm:"unique;size:20"` + ClinicalNotes *string `json:"clinicalNotes"` + OtherNotes *string `json:"otherNotes"` + Resume *string `json:"resume"` + Status_Code erc.DataStatusCode `json:"status_code" gorm:"not null;size:10"` } diff --git a/internal/domain/main-entities/radiology-mcu-order/dto.go b/internal/domain/main-entities/radiology-mcu-order/dto.go index f24b5668..4250b4b0 100644 --- a/internal/domain/main-entities/radiology-mcu-order/dto.go +++ b/internal/domain/main-entities/radiology-mcu-order/dto.go @@ -1,6 +1,8 @@ package radiologymcuorder import ( + la "simrs-vx/internal/lib/auth" + ecore "simrs-vx/internal/domain/base-entities/core" ed "simrs-vx/internal/domain/main-entities/doctor" ee "simrs-vx/internal/domain/main-entities/encounter" @@ -11,9 +13,10 @@ type CreateDto struct { Encounter_Id uint `json:"encounter_id"` Number *uint64 `json:"number"` // SHOULD BE AUTOMATIC WITHOUT SYNC Doctor_Code string `json:"-" validate:"required"` - ClinicalNotes string `json:"clinicalNotes"` - OtherNotes string `json:"otherNotes"` + ClinicalNotes *string `json:"clinicalNotes"` + OtherNotes *string `json:"otherNotes"` Items []ermoi.SubCreateDto `json:"items" validate:"required"` + la.AuthInfo } type ReadListDto struct { @@ -29,7 +32,8 @@ type FilterDto struct { } type ReadDetailDto struct { - Id uint64 `json:"id"` + Id uint64 `json:"id"` + Includes string `json:"includes"` } type UpdateDto struct { diff --git a/internal/domain/main-entities/radiology-mcu-order/entity.go b/internal/domain/main-entities/radiology-mcu-order/entity.go index 2ff3ec20..1ef8882d 100644 --- a/internal/domain/main-entities/radiology-mcu-order/entity.go +++ b/internal/domain/main-entities/radiology-mcu-order/entity.go @@ -5,6 +5,7 @@ import ( ee "simrs-vx/internal/domain/main-entities/encounter" ermoi "simrs-vx/internal/domain/main-entities/radiology-mcu-order-item/base" eamob "simrs-vx/internal/domain/main-entities/radiology-mcu-order/base" + erc "simrs-vx/internal/domain/references/common" ) type RadiologyMcuOrder struct { @@ -13,3 +14,15 @@ type RadiologyMcuOrder struct { Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Code;references:Code"` Items []*ermoi.RadiologyMcuOrderItem `json:"items" gorm:"foreignKey:RadiologyMcuOrder_Id;references:Id"` } + +func (d RadiologyMcuOrder) IsNotNew() bool { + return d.Status_Code != erc.DSCNew +} + +func (d RadiologyMcuOrder) IsCompleted() bool { + return d.Status_Code == erc.DSCDone +} + +func (d RadiologyMcuOrder) IsSameDoctor(doctor_code *string) bool { + return d.Doctor_Code == *doctor_code +} diff --git a/internal/interface/migration/main-entities.go b/internal/interface/migration/main-entities.go index 9767b21b..d4f596b1 100644 --- a/internal/interface/migration/main-entities.go +++ b/internal/interface/migration/main-entities.go @@ -16,6 +16,8 @@ import ( consultation "simrs-vx/internal/domain/main-entities/consultation" controlletter "simrs-vx/internal/domain/main-entities/control-letter" counter "simrs-vx/internal/domain/main-entities/counter" + cpmcuorder "simrs-vx/internal/domain/main-entities/cp-mcu-order" + cpmcuorderitem "simrs-vx/internal/domain/main-entities/cp-mcu-order-item" deathcause "simrs-vx/internal/domain/main-entities/death-cause" device "simrs-vx/internal/domain/main-entities/device" deviceorder "simrs-vx/internal/domain/main-entities/device-order" @@ -68,6 +70,8 @@ import ( medicinemethod "simrs-vx/internal/domain/main-entities/medicine-method" medicinemix "simrs-vx/internal/domain/main-entities/medicine-mix" medicinemixitem "simrs-vx/internal/domain/main-entities/medicine-mix-item" + micromcuorder "simrs-vx/internal/domain/main-entities/micro-mcu-order" + micromcuorderitem "simrs-vx/internal/domain/main-entities/micro-mcu-order-item" midwife "simrs-vx/internal/domain/main-entities/midwife" nurse "simrs-vx/internal/domain/main-entities/nurse" nutritionist "simrs-vx/internal/domain/main-entities/nutritionist" @@ -88,6 +92,8 @@ import ( procedureroomorderitem "simrs-vx/internal/domain/main-entities/procedure-room-order-item" proceduresrc "simrs-vx/internal/domain/main-entities/procedure-src" province "simrs-vx/internal/domain/main-entities/province" + radiologymcuorder "simrs-vx/internal/domain/main-entities/radiology-mcu-order" + radiologymcuorderitem "simrs-vx/internal/domain/main-entities/radiology-mcu-order-item" regency "simrs-vx/internal/domain/main-entities/regency" rehab "simrs-vx/internal/domain/main-entities/rehab" responsibledoctorhist "simrs-vx/internal/domain/main-entities/responsible-doctor-hist" @@ -122,7 +128,6 @@ import ( func getMainEntities() []any { return []any{ &authpartner.AuthPartner{}, - &apmcuorder.ApMcuOrder{}, &user.User{}, &userfes.UserFes{}, &division.Division{}, @@ -202,6 +207,13 @@ func getMainEntities() []any { &mcuorderitem.McuOrderItem{}, &mcusubsrc.McuSubSrc{}, &mcuordersubitem.McuOrderSubItem{}, + &apmcuorder.ApMcuOrder{}, + &radiologymcuorder.RadiologyMcuOrder{}, + &radiologymcuorderitem.RadiologyMcuOrderItem{}, + &cpmcuorder.CpMcuOrder{}, + &cpmcuorderitem.CpMcuOrderItem{}, + µmcuorder.MicroMcuOrder{}, + µmcuorderitem.MicroMcuOrderItem{}, &antibioticsrccategory.AntibioticSrcCategory{}, &antibioticinuse.AntibioticInUse{}, &consultation.Consultation{}, From 5782b86e22f7a3414422d7676b14e41d0d8ed81c Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Mon, 8 Dec 2025 16:04:08 +0700 Subject: [PATCH 30/42] migration from server --- cmd/main-migration/migrations/atlas.sum | 148 ++++++++++++------------ 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index c1ede307..9a5298f1 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:o4jOACV/QY64oiqrbnZvGei0J65px0JBwAXakl8h+Oc= +h1:iGd5sCHeyT0TBFNtV83Ge6PW5BjRp8rpw+tgFigOC4Q= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -75,76 +75,76 @@ h1:o4jOACV/QY64oiqrbnZvGei0J65px0JBwAXakl8h+Oc= 20251106040137.sql h1:ppcqkVoT0o9jZcjI/TN7LuaPxXhJQhnIXEJtloP/46o= 20251106041333.sql h1:2JkxyelQ/EeB+boL5bfpnzefw32ttEGKvKchtQjWmAU= 20251106042006.sql h1:ruppYa1kAJQUU3ufQBbKGMcXrGbGJJiRPclT+dNc/YQ= -20251106050412.sql h1:1002KYtHd8AwrQTMewbs/PPHDylHDghigE/3S7PVdMA= -20251106063418.sql h1:jPW/gBnbFl4RO39lQ0ZMDtYA6xbhyD6CgQupT50HmaY= -20251106071906.sql h1:leYGKxR3EQn794aOehf0sd/ZPmOnvBMZPy5/anGmRB4= -20251106073157.sql h1:KASMzjjjk5UB7Zj8lCRtM1utc4ZnDjlnpZbtTe3vONE= -20251106074218.sql h1:Z5q5deOvLaZDPhiVTN9st3/s56RepBa2YOyrMXBdj4A= -20251106081846.sql h1:P+VsWwhGt60adDIZuE/Aa38JVp/yX1rnsdpXpxASodw= -20251106082844.sql h1:Dmi5A8i9frQZvdXYPwc7f8CisZtBH8liSXq1rI6z1iM= -20251106090021.sql h1:4JwdKgO8T46YhyWVJUxpRIwudBDlG8QN1brSOYmgQ20= -20251106144745.sql h1:nqnQCzGrVJaq8ilOEOGXeRUL1dolj+OPWKuP8A92FRA= -20251107012049.sql h1:Pff4UqltGS3clSlGr0qq8CQM56L29wyxY0FC/N/YAhU= -20251107064812.sql h1:GB9a0ZfMYTIoGNmKUG+XcYUsTnRMFfT4/dAD71uCPc4= -20251107064937.sql h1:IC5pw1Ifj30hiE6dr5NMHXaSHoQI+vRd40N5ABgBHRI= -20251107071420.sql h1:9NO3iyLEXEtWa2kSRjM/8LyzuVIk6pdFL2SuheWjB08= -20251107074318.sql h1:7fHbSRrdjOmHh/xwnjCLwoiB5cW5zeH+uxLV0vZbkIA= -20251107075050.sql h1:np+3uTOnU9QNtK7Knaw8eRMhkyB9AwrtSNHphOBxbHY= -20251107080604.sql h1:cXDBLPJDVWLTG6yEJqkJsOQ7p7VYxLM2SY+mwO8qSHo= -20251107081830.sql h1:/S7OQZo4ZnK80t28g/JyiOTZtmWG/dP5Wg2zXNMQ/iE= -20251107091033.sql h1:/cbkF1nO/IjNSIfDJJx456KJtQ9rWFXOBFAkR/M2xiE= -20251107091209.sql h1:jrLQOUeV8ji2fg0pnEcs1bw4ANUxzTSMXC/rrHLIY+M= -20251107091541.sql h1:6UqbhQQRmzA2+eKu5lIvkwOkk+lH70QLZC8Pjpjcq68= -20251110012217.sql h1:C9HpX0iyHzKjyNv/5DSAn2MCHj6MX4p5UQ/NrY7QD0w= -20251110012306.sql h1:J54yb27d30LBbYp9n1P66gFVRlxPguKu0kxmWIBBG8g= -20251110052049.sql h1:232T2x8xTczJl9nk4jxJpZXhoOGYthhxjJ7nK8Jd8vg= -20251110062042.sql h1:WnfVUXrzYoj8qdkkjO9/JQQ8agGd4GfSHQdMjo7LDAg= -20251110063202.sql h1:hSzGfwVMWa6q3vwIQZUkxKgBNCzHjB+6GKy54zfV+oQ= -20251110063633.sql h1:/VpofIAqNS1CnazEnpW/+evbzn9Kew3xDW48r57M+Xg= -20251110085551.sql h1:bFZwSmfvVbTUr/enWB82WqjG88gpqcZ6s45btUvO0uo= -20251110091516.sql h1:KkJMwPQuaZQhiqnKrNQrgP12gw9rV8T3P2o3mtGTcvY= -20251110091948.sql h1:I4odAYrJdvNf1jPw6ppDC0XdI7v6vKBACg/ABwUgA7I= -20251110092729.sql h1:l1out8soEmVP6dNjaIOtGYo6QDcoJZRI8X1sjZ5ZGmo= -20251110093522.sql h1:nsz8jCxGjEdr/bz9g+4ozfZzIP803xONjVmucad1GMc= -20251110100258.sql h1:IBqt1VZj5WjQ+l9aAFGHOCCBtzb03KlLLihFLut7itg= -20251110100545.sql h1:6/LV7751iyKxE2xI6vO1zly+aHUwxXD/IBwLcVpKxqM= -20251110155448.sql h1:kFPobJB+cpflsXBAWUwy3lohuWvrb/VRlXnhJWl7i3Y= -20251111072601.sql h1:ch8F+yVhsSM5xY+TwMLY3PxdLa4Wuhtj76oyw79R7Js= -20251111073546.sql h1:cCv0NPscADAOBahRVqtDWFs6G2t7n+4a+RwlF8vk/c4= -20251111074148.sql h1:70TsV83u1gQ5TktI13K7NQiyCCa35Td2aR6CNtKUa4U= -20251111074652.sql h1:ddfQ/sRKMezPM75xBFTGytUQX5AwZ3znrJVpg73gKPA= -20251111082257.sql h1:ZsdLY1ROouos0l3oS0lkeSiuKLEUGbVvBhpcM2AVhkw= -20251111111017.sql h1:qrJ93dNtQwcuAvpsP/lAK/H63C4cinXrsVaPmWsTqkU= -20251113101344.sql h1:xaOZvAUP1fFfnO+syEFOzJUIg5lTfBe5AWHPbBWuCLA= -20251113120533.sql h1:f3/U1Ve2yF2zSMhkt+xtwF8wUYfUKYwgbNeGfE37EW4= -20251114062746.sql h1:FInLaEFQByESEwFJKuKnuUSTKmcDpi3ZXaxkKwz2+D8= -20251117005942.sql h1:wD3BWrUSmo1HlW16V3lkaBkJvbAZ0fNk77te7J9NhOc= -20251117075427.sql h1:TqU9VKZa3I8YNXUGQWY3WVBYN+1FvyyaKy0hB1jgAho= -20251118074929.sql h1:p1KsWqCuR1JXA/jVO5BmOhCcaQ8clT7t0YRszAhPFbg= -20251119063438.sql h1:NVGM0X/LHD37EaPl8SNzkNiZDJ7AB1QR+LLwLh6WRdg= -20251119065730.sql h1:U5lzk1WvMB0bw3kwckou7jkEt4bwdYItwHr2Vxqe7w4= -20251119072302.sql h1:qCuI2WMEMF/XNbjV+RXPjBnuCKLu1Fia+mR9HiLWBIs= -20251119072450.sql h1:Xg+bTwqGyKPNFEQhJylvpz1wifdfmDJvcAq6vmNf0Ng= -20251120005512.sql h1:Ek6qpacAI/qVuTYxKno+uJyzn7s5z9pf3t7VA8gTzm4= -20251120074415.sql h1:NNUeJVA03EeBHJhHqPXEZoDv/PnC6yK1/cRhmukyaJo= -20251121033803.sql h1:/vfvFX/3pzSCIHnSbMUT9EMBDykOpVkvyfeTEle9Vas= -20251124071457.sql h1:qg2dhCL9YwD13xnfJ175lW/p6MGfzFKaBqd908FByRc= -20251125125303.sql h1:4JSFv1Pmhbe9tqpLXgO63OwYnGsalStgUXKVWPyc1YE= -20251126064057.sql h1:vAdhz5Nn/gGJy0UKZAEldeXv8HpHtJU/t8ygDVIbTsU= -20251201081333.sql h1:PoC8ADRdwDuohDTB74yW/DaB42igdYa4B6humbrEJBk= -20251201104439.sql h1:tpqdrOf9d2aGwZshqm62nG6SXnfVaO/g6A7z0efPS14= -20251201113804.sql h1:kIEmVoETJXBkab2Q+b3y/pP84eF8W2BdQ47amHCnc+c= -20251201113858.sql h1:KLXKZO5XTQPoEU0YLHE8Fhg9WPKpSN3wNgYPJ+RGFcg= -20251201114751.sql h1:HM17diiPknfSHAmP+kJGP6GzToaPU9/NT+KQBpf3Jq0= -20251201114913.sql h1:gqucFgHFFLA6n/Rdz486cZH5xkaJuwefESLJMJLDue8= -20251202030445.sql h1:QWBVfTepT7DaXP5E0BYoxNM0JwKIQ2qIMXzI4kbz/qE= -20251202044430.sql h1:4QZH9lz0GrQ9rzP1AJ+hJgGalNpp+8FCRckNK7xaTbU= -20251202064000.sql h1:/EN7sT1ol/91qW1aXWrzX+Mc3XOC/7f/LtfA0JRHpbg= -20251202130629.sql h1:9mvalqfhqGCdkcJepJDzHprU2xb0i5sYys1Htf62ioo= -20251202160848.sql h1:Kd2/TziKSMezrt4XgbjQcYvY/Lo9rX0qw7/Lz0/oyKk= -20251202180207.sql h1:IHmSMIO3ia+YV5GULixbdlV1joaUAWtnjQHPd8+HKiM= -20251202231005.sql h1:lua0KKoeBptSfs/6ehZE6Azo6YUlNkOJwGFyb1HQWkY= -20251203205052.sql h1:nk0VK2Uv4bHE3SBfHo/aevVZxtHzr7zAzvmMU8TCCtk= -20251207020537.sql h1:uqqIQaBoZGoOXVQKkalNXwF2awcA+rhjNVevWEzIIok= -20251207212015.sql h1:muRdWqRKfJQFMfezj2B4n0E6bbjIz1GrzHEyhoxy2mk= -20251207221222.sql h1:+mU/25n3hQLRU6MK8B+Uwzl9YBRezX3xWDtIKnweN78= +20251106050412.sql h1:MiEMJ1HCFYnalKuq3Z38xJeogfBAMqsTv2sG4EF8dDw= +20251106063418.sql h1:y3veDJPjKekOWLCZek/LgQwXPRhZtOppTfUXiqoL95s= +20251106071906.sql h1:/TUZA3XpMY23qEJXdkTwlzrNMvSSl6JJniPcgAttBaw= +20251106073157.sql h1:78txeibJ602DMD7huD618ZSMt6phSRzDNPTlo0PGyrc= +20251106074218.sql h1:8Xz7WywrtUnSxOHhlal53gG9rE7r86LFUt5zBFe/mIs= +20251106081846.sql h1:jp91Bf5bxGXMiUB1VIuN6y768vb2iWwow44WfCE5J5k= +20251106082844.sql h1:RHYzRO4G1fSWwf+xc/3QezZ/Iil67cZPIgNpNz3TNhQ= +20251106090021.sql h1:dFDk6mq+zjbYWmfWIrHf9DiKvvoXHjrr0++zssMTWP8= +20251106144745.sql h1:aHcr23iBFqCHer5D/SsPMXBCLjGqUYvWYfRU8jSJgIw= +20251107012049.sql h1:hu/7NHhnAkT4xK0RNtqmMDdH1Bo5EZbl7itDRjiCT+g= +20251107064812.sql h1:sfCXDQYnMf0ddrQ9oYljWJLLSt9NJjJV6o8VS3p7aZE= +20251107064937.sql h1:DlYGJ9LZFwZyR7jBP5zaGB128aIc4HAixBKPYCz9EkY= +20251107071420.sql h1:ynCdZAd2utLl+FhtWZwtahNXgIVOvuk3s/rOq7lfXA4= +20251107074318.sql h1:WE9cPhibWtZ0dbu1VEGirTeY6ijFYGMNhHdBtM32kOc= +20251107075050.sql h1:8tvneruqdynDOaJK1+0z4CH7YXZStZpGdqwIeOMLik4= +20251107080604.sql h1:8c4jd4Tql7tcdhbI9NS0tgvN+ADu9FnCf8wMUbmW7A0= +20251107081830.sql h1:SAAe3lmsm9vGXuSEsDdl7ad0EAxP5CMmFRDEgp9M7yY= +20251107091033.sql h1:JLdX/u7GUdBfjrPrMSNAqc8HtSoj0YA9iW9Vc6FJZdw= +20251107091209.sql h1:CzhYtwAwT+GHrbqcagnJE+v3mbl/rObf1IJaLCKlzrs= +20251107091541.sql h1:+3ZyWJTftDY2JeWThXuIxGWpUBnyMPyOyY4jBjdWYJI= +20251110012217.sql h1:f4Z8TuGc+XMSJ+Ekn4/PeHRE2FlHWkc5gKPJB0hAX7c= +20251110012306.sql h1:ENPyI6Kjdk6qKJQb0yJ6MCTDPAmO1WD/uhKuCSl+jYo= +20251110052049.sql h1:OrQ0acnyoQLKnTitZfnBcVr5jDslF59OFLaqT7SpdVs= +20251110062042.sql h1:9KwldQt0NpVPR86L0T4hlkfHAGau+7CiZYgu5rF+yhg= +20251110063202.sql h1:A117DuZmZ6U0jWHA3DISnr+yvBjKIr1ObrUr047YezQ= +20251110063633.sql h1:qTiC0F19JnhUIXF4LGJQ21jEV6kKGyhTr1x2kimFqPQ= +20251110085551.sql h1:HZcJM0RSC6HBaUSjKBE8MgDG8Vn9f3LmwA/OnT9Cp7I= +20251110091516.sql h1:W3AQhQLgirEWuCObbLl+Prdrbq6k6EEY1xcoWsmbog4= +20251110091948.sql h1:3tsITMrZr/T+L4wqUMz8sHS229jCJl4T0Nu3dMccxH8= +20251110092729.sql h1:uU+k88RH/e0Ns4/SmJl03RVYPscBAPuiLfxR6CJqaf0= +20251110093522.sql h1:O7upSj8VNjzvroL4IU59bfxKATOkAVGBArcUbVNq9aM= +20251110100258.sql h1://JSArUMNI3/gAtYDx2VN94C198SFW0ANjgs+p6eCRM= +20251110100545.sql h1:ENPOqeJYRpMI4e8VCKwaQgaql8se6pIidAhG2cjskBg= +20251110155448.sql h1:VW9KE0jxWy4flZ28sdXmhY6JWd6eKAX/cVL8KWRVii4= +20251111072601.sql h1:99WWzGjcDDFNC2cHRfPu4MBLWNrgPMY5HAYUbmIcVRA= +20251111073546.sql h1:iIGwFNfUgStdczw/PXTH3SD84xAyxrbZICofc3M8TMk= +20251111074148.sql h1:mzkezSKwCV2bTZ/0BHiTCX5qAy4uHpwar1xzwAH15Ko= +20251111074652.sql h1:lYh4/3BHV24pgPC0pP4RUKb+XtL/6AsZGPItRpnzBiQ= +20251111082257.sql h1:+cIZ1lf8HYGSL6t6U88plLKk8nOO1YVdV7h3YOM84ds= +20251111111017.sql h1:xzlhR2xLfOj4ddYlesS+bpEeDrxiAf5ILNOspsbZjBU= +20251113101344.sql h1:vSzThY3p6XYTj0dJ2uFVkHmlytyrFAnGE58CJLx364I= +20251113120533.sql h1:lfjgdqRGo/EohrVw8sWlFbDjh3ASTsfQ6pr3qjafqvc= +20251114062746.sql h1:6DLYjfJ60PkAABZTXvOwSE+xrU25oyoX7gpYlBnA9cw= +20251117005942.sql h1:0XoJKca8IOaB9QKFVF/qPY7jKcIgh6m/LODQuE06SAs= +20251117075427.sql h1:LhY2urosfoSu1/vkHmgsNP4JA4DuWBs9gL59yMqcF8M= +20251118074929.sql h1:3RWBD6BziQVw6WSfthgoVuhTELHER9NrIuZm4hY/F1A= +20251119063438.sql h1:EVTG3ZrHjCmM95YPASZTRPiwHrG6e33A2vO4hLSAaBQ= +20251119065730.sql h1:s98wnZOCW6NbnwDS3H53XIQ60u6B9bDwBLNvy5+Rn64= +20251119072302.sql h1:ZL+VHekLYqgNtOFKlj02WHrAk11dtTxQkmyTKE8IOzY= +20251119072450.sql h1:SiJy2vpSvoPFw4J1SW7HjGSJzrqR62NsjRYAeabV+kc= +20251120005512.sql h1:hJUaWXYJ3HiSquBTw8OKhymjA4O43ehAMGfiOY8W87Q= +20251120074415.sql h1:dNmcqZHqfZwi/wtYvO/pSFgImN2scXL0p/7g0+HLp0s= +20251121033803.sql h1:onlddYGo+tQdGaEdJPqdsx3sncGnwEvqMSCksF6vjjI= +20251124071457.sql h1:ikQLIXFikUbkUd55uJBmEvqLGEC9t0db+Om4TQsWP7M= +20251125125303.sql h1:OLKbNPO36AHtIDursW9AeBvf60sahQKC1iOjHmpx0MA= +20251126064057.sql h1:6al3PTWbw/WGiBcrRrVWppOMLtG+eRaH/qSLbnmh1kQ= +20251201081333.sql h1:dD+jcisoUYnxRYWdtVcnxbDeYjUW12/R/qarYQr+utg= +20251201104439.sql h1:h4tz5uetbCKeOI3agSVmAeh6jUfECYy0LhQ7HooYhzg= +20251201113804.sql h1:DdUzqfLdy4AUpVSRFDrIJXntGmtKgZrtvv8MAT4mMxs= +20251201113858.sql h1:XSpicm4aWjrfeY5EYIiw8Ios9v7BGfzZJxpW/57Qwqs= +20251201114751.sql h1:qx+ShdHLacVFcRwwGrW1zMKFHOjMGdnusk7CEfyV8ig= +20251201114913.sql h1:6l/m2/6fmTIjFmKio0QmB8oTwBDCHTIkbuYTODQ7Gwk= +20251202030445.sql h1:5+6ss5KdN6pll8Qtf0RGGyy/BURNO3dBgIBJOzDb624= +20251202044430.sql h1:nJtlQDGj7ZJtJ07NYcF41JCn9ck50GyDPoitTOe8P/s= +20251202064000.sql h1:yzSMOPZrpvQf+u6CxD6LwNySNH9Ip1u70UEf2vWI5w4= +20251202130629.sql h1:u79EiiYq5irxCcjlOHQcACnCKS05XPDDsL4TzLGrNQA= +20251202160848.sql h1:Aq5rVLbrL4vvNnmfk82V22GTteWVTSq9vk2SYzi3EBo= +20251202180207.sql h1:J0Orufzpi+tNhd5+9eLvonKhYc/WMceVHO1WDVRrHAM= +20251202231005.sql h1:DBunbxmAfPYiO5mHspc4dyTTVFoKrHkZSwk/Ieu5oFA= +20251203205052.sql h1:67NoN6JhDfChBA13dmErBSRDiC1gdVBb2F+8SMzpm4U= +20251207020537.sql h1:SIaioWMbg5W1qJDwoh2r7aGnUTIXs67ZhGEe0XyXVB4= +20251207212015.sql h1:RfXFRdynp6vk5KWFzF2nZc2yFpH9BKP9gqBxuAG/G/Q= +20251207221222.sql h1:6DS9hzcfN3+52WShFeI4f9Gqxd4LCQg1Otn5cRipIWU= From f22968e21782642ca57cd3ef43034aa7d1b6ccc0 Mon Sep 17 00:00:00 2001 From: vanilia Date: Tue, 9 Dec 2025 09:28:15 +0700 Subject: [PATCH 31/42] adjust chemo-plan --- cmd/main-migration/migrations/20251209022744.sql | 2 ++ cmd/main-migration/migrations/atlas.sum | 5 +++-- internal/domain/main-entities/chemo-plan/entity.go | 3 +++ 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 cmd/main-migration/migrations/20251209022744.sql diff --git a/cmd/main-migration/migrations/20251209022744.sql b/cmd/main-migration/migrations/20251209022744.sql new file mode 100644 index 00000000..a8a18481 --- /dev/null +++ b/cmd/main-migration/migrations/20251209022744.sql @@ -0,0 +1,2 @@ +-- Modify "ChemoPlan" table +ALTER TABLE "public"."ChemoPlan" ADD COLUMN "Encounter_Id" bigint NULL, ADD CONSTRAINT "fk_ChemoPlan_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION; diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 09459c64..ccfdf7cb 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:BsDkwn1AzNdKnOPVb6PkonyiXM7nTdVcjRdw62i/NlQ= +h1:k6jcZ+rtVsLhO+oTPZVfHgwAInujs4C4iXNJlSwwkA8= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -147,4 +147,5 @@ h1:BsDkwn1AzNdKnOPVb6PkonyiXM7nTdVcjRdw62i/NlQ= 20251205073858.sql h1:Ep03jQ9hJAJILDJfKVcmi3Z6fqmTHSq9gKQtwf070PE= 20251205211957.sql h1:zRHcvLY+nfLdUyMcfpgI8vYQcPzJUWbfjkc4cK0QGHU= 20251205214433.sql h1:tgHB/fNy9XwAOWIqNI6GCqGXeJgSuZs2aHiCEj3BHZA= -20251205221124.sql h1:VthPlq3XcQOYz5VsFivb4Wof8jCAG36fAaerKmM4/OA= +20251205221124.sql h1:wl56/lrR14r7LrScEKwTQ3cNE45wh/0Ye3UEM7gfVNg= +20251209022744.sql h1:FayWjHhPEZEIq7KWIYaV/2/cmKB7A4PR3aspXXd6Brs= diff --git a/internal/domain/main-entities/chemo-plan/entity.go b/internal/domain/main-entities/chemo-plan/entity.go index 1f3f3ca5..2dc5a363 100644 --- a/internal/domain/main-entities/chemo-plan/entity.go +++ b/internal/domain/main-entities/chemo-plan/entity.go @@ -1,6 +1,7 @@ package chemo_plan import ( + ee "simrs-vx/internal/domain/main-entities/encounter" "time" ecore "simrs-vx/internal/domain/base-entities/core" @@ -18,4 +19,6 @@ type ChemoPlan struct { RealizationDate *time.Time `json:"realizationDate"` Notes *string `json:"notes"` Status ere.StatusProtocolChemo `json:"status"` + Encounter_Id *uint `json:"encounter_id"` + Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` } From 4a22609243dfa7bc5851b4195bf26712fc2aee67 Mon Sep 17 00:00:00 2001 From: vanilia Date: Tue, 9 Dec 2025 09:32:36 +0700 Subject: [PATCH 32/42] update migration --- cmd/main-migration/migrations/atlas.sum | 158 ++++++++++++------------ 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 491fb502..1df5b79f 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:k6jcZ+rtVsLhO+oTPZVfHgwAInujs4C4iXNJlSwwkA8= +h1:bj3Rl8P0sdSmP7kBLfjyB30pIf3iUdthY5EBkfOtk7A= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -75,81 +75,81 @@ h1:k6jcZ+rtVsLhO+oTPZVfHgwAInujs4C4iXNJlSwwkA8= 20251106040137.sql h1:ppcqkVoT0o9jZcjI/TN7LuaPxXhJQhnIXEJtloP/46o= 20251106041333.sql h1:2JkxyelQ/EeB+boL5bfpnzefw32ttEGKvKchtQjWmAU= 20251106042006.sql h1:ruppYa1kAJQUU3ufQBbKGMcXrGbGJJiRPclT+dNc/YQ= -20251106050412.sql h1:MiEMJ1HCFYnalKuq3Z38xJeogfBAMqsTv2sG4EF8dDw= -20251106063418.sql h1:y3veDJPjKekOWLCZek/LgQwXPRhZtOppTfUXiqoL95s= -20251106071906.sql h1:/TUZA3XpMY23qEJXdkTwlzrNMvSSl6JJniPcgAttBaw= -20251106073157.sql h1:78txeibJ602DMD7huD618ZSMt6phSRzDNPTlo0PGyrc= -20251106074218.sql h1:8Xz7WywrtUnSxOHhlal53gG9rE7r86LFUt5zBFe/mIs= -20251106081846.sql h1:jp91Bf5bxGXMiUB1VIuN6y768vb2iWwow44WfCE5J5k= -20251106082844.sql h1:RHYzRO4G1fSWwf+xc/3QezZ/Iil67cZPIgNpNz3TNhQ= -20251106090021.sql h1:dFDk6mq+zjbYWmfWIrHf9DiKvvoXHjrr0++zssMTWP8= -20251106144745.sql h1:aHcr23iBFqCHer5D/SsPMXBCLjGqUYvWYfRU8jSJgIw= -20251107012049.sql h1:hu/7NHhnAkT4xK0RNtqmMDdH1Bo5EZbl7itDRjiCT+g= -20251107064812.sql h1:sfCXDQYnMf0ddrQ9oYljWJLLSt9NJjJV6o8VS3p7aZE= -20251107064937.sql h1:DlYGJ9LZFwZyR7jBP5zaGB128aIc4HAixBKPYCz9EkY= -20251107071420.sql h1:ynCdZAd2utLl+FhtWZwtahNXgIVOvuk3s/rOq7lfXA4= -20251107074318.sql h1:WE9cPhibWtZ0dbu1VEGirTeY6ijFYGMNhHdBtM32kOc= -20251107075050.sql h1:8tvneruqdynDOaJK1+0z4CH7YXZStZpGdqwIeOMLik4= -20251107080604.sql h1:8c4jd4Tql7tcdhbI9NS0tgvN+ADu9FnCf8wMUbmW7A0= -20251107081830.sql h1:SAAe3lmsm9vGXuSEsDdl7ad0EAxP5CMmFRDEgp9M7yY= -20251107091033.sql h1:JLdX/u7GUdBfjrPrMSNAqc8HtSoj0YA9iW9Vc6FJZdw= -20251107091209.sql h1:CzhYtwAwT+GHrbqcagnJE+v3mbl/rObf1IJaLCKlzrs= -20251107091541.sql h1:+3ZyWJTftDY2JeWThXuIxGWpUBnyMPyOyY4jBjdWYJI= -20251110012217.sql h1:f4Z8TuGc+XMSJ+Ekn4/PeHRE2FlHWkc5gKPJB0hAX7c= -20251110012306.sql h1:ENPyI6Kjdk6qKJQb0yJ6MCTDPAmO1WD/uhKuCSl+jYo= -20251110052049.sql h1:OrQ0acnyoQLKnTitZfnBcVr5jDslF59OFLaqT7SpdVs= -20251110062042.sql h1:9KwldQt0NpVPR86L0T4hlkfHAGau+7CiZYgu5rF+yhg= -20251110063202.sql h1:A117DuZmZ6U0jWHA3DISnr+yvBjKIr1ObrUr047YezQ= -20251110063633.sql h1:qTiC0F19JnhUIXF4LGJQ21jEV6kKGyhTr1x2kimFqPQ= -20251110085551.sql h1:HZcJM0RSC6HBaUSjKBE8MgDG8Vn9f3LmwA/OnT9Cp7I= -20251110091516.sql h1:W3AQhQLgirEWuCObbLl+Prdrbq6k6EEY1xcoWsmbog4= -20251110091948.sql h1:3tsITMrZr/T+L4wqUMz8sHS229jCJl4T0Nu3dMccxH8= -20251110092729.sql h1:uU+k88RH/e0Ns4/SmJl03RVYPscBAPuiLfxR6CJqaf0= -20251110093522.sql h1:O7upSj8VNjzvroL4IU59bfxKATOkAVGBArcUbVNq9aM= -20251110100258.sql h1://JSArUMNI3/gAtYDx2VN94C198SFW0ANjgs+p6eCRM= -20251110100545.sql h1:ENPOqeJYRpMI4e8VCKwaQgaql8se6pIidAhG2cjskBg= -20251110155448.sql h1:VW9KE0jxWy4flZ28sdXmhY6JWd6eKAX/cVL8KWRVii4= -20251111072601.sql h1:99WWzGjcDDFNC2cHRfPu4MBLWNrgPMY5HAYUbmIcVRA= -20251111073546.sql h1:iIGwFNfUgStdczw/PXTH3SD84xAyxrbZICofc3M8TMk= -20251111074148.sql h1:mzkezSKwCV2bTZ/0BHiTCX5qAy4uHpwar1xzwAH15Ko= -20251111074652.sql h1:lYh4/3BHV24pgPC0pP4RUKb+XtL/6AsZGPItRpnzBiQ= -20251111082257.sql h1:+cIZ1lf8HYGSL6t6U88plLKk8nOO1YVdV7h3YOM84ds= -20251111111017.sql h1:xzlhR2xLfOj4ddYlesS+bpEeDrxiAf5ILNOspsbZjBU= -20251113101344.sql h1:vSzThY3p6XYTj0dJ2uFVkHmlytyrFAnGE58CJLx364I= -20251113120533.sql h1:lfjgdqRGo/EohrVw8sWlFbDjh3ASTsfQ6pr3qjafqvc= -20251114062746.sql h1:6DLYjfJ60PkAABZTXvOwSE+xrU25oyoX7gpYlBnA9cw= -20251117005942.sql h1:0XoJKca8IOaB9QKFVF/qPY7jKcIgh6m/LODQuE06SAs= -20251117075427.sql h1:LhY2urosfoSu1/vkHmgsNP4JA4DuWBs9gL59yMqcF8M= -20251118074929.sql h1:3RWBD6BziQVw6WSfthgoVuhTELHER9NrIuZm4hY/F1A= -20251119063438.sql h1:EVTG3ZrHjCmM95YPASZTRPiwHrG6e33A2vO4hLSAaBQ= -20251119065730.sql h1:s98wnZOCW6NbnwDS3H53XIQ60u6B9bDwBLNvy5+Rn64= -20251119072302.sql h1:ZL+VHekLYqgNtOFKlj02WHrAk11dtTxQkmyTKE8IOzY= -20251119072450.sql h1:SiJy2vpSvoPFw4J1SW7HjGSJzrqR62NsjRYAeabV+kc= -20251120005512.sql h1:hJUaWXYJ3HiSquBTw8OKhymjA4O43ehAMGfiOY8W87Q= -20251120074415.sql h1:dNmcqZHqfZwi/wtYvO/pSFgImN2scXL0p/7g0+HLp0s= -20251121033803.sql h1:onlddYGo+tQdGaEdJPqdsx3sncGnwEvqMSCksF6vjjI= -20251124071457.sql h1:ikQLIXFikUbkUd55uJBmEvqLGEC9t0db+Om4TQsWP7M= -20251125125303.sql h1:OLKbNPO36AHtIDursW9AeBvf60sahQKC1iOjHmpx0MA= -20251126064057.sql h1:6al3PTWbw/WGiBcrRrVWppOMLtG+eRaH/qSLbnmh1kQ= -20251201081333.sql h1:dD+jcisoUYnxRYWdtVcnxbDeYjUW12/R/qarYQr+utg= -20251201104439.sql h1:h4tz5uetbCKeOI3agSVmAeh6jUfECYy0LhQ7HooYhzg= -20251201113804.sql h1:DdUzqfLdy4AUpVSRFDrIJXntGmtKgZrtvv8MAT4mMxs= -20251201113858.sql h1:XSpicm4aWjrfeY5EYIiw8Ios9v7BGfzZJxpW/57Qwqs= -20251201114751.sql h1:qx+ShdHLacVFcRwwGrW1zMKFHOjMGdnusk7CEfyV8ig= -20251201114913.sql h1:6l/m2/6fmTIjFmKio0QmB8oTwBDCHTIkbuYTODQ7Gwk= -20251202030445.sql h1:5+6ss5KdN6pll8Qtf0RGGyy/BURNO3dBgIBJOzDb624= -20251202044430.sql h1:nJtlQDGj7ZJtJ07NYcF41JCn9ck50GyDPoitTOe8P/s= -20251202064000.sql h1:yzSMOPZrpvQf+u6CxD6LwNySNH9Ip1u70UEf2vWI5w4= -20251202130629.sql h1:u79EiiYq5irxCcjlOHQcACnCKS05XPDDsL4TzLGrNQA= -20251202160848.sql h1:Aq5rVLbrL4vvNnmfk82V22GTteWVTSq9vk2SYzi3EBo= -20251202180207.sql h1:J0Orufzpi+tNhd5+9eLvonKhYc/WMceVHO1WDVRrHAM= -20251202231005.sql h1:DBunbxmAfPYiO5mHspc4dyTTVFoKrHkZSwk/Ieu5oFA= -20251203205052.sql h1:67NoN6JhDfChBA13dmErBSRDiC1gdVBb2F+8SMzpm4U= -20251207020537.sql h1:SIaioWMbg5W1qJDwoh2r7aGnUTIXs67ZhGEe0XyXVB4= -20251207212015.sql h1:RfXFRdynp6vk5KWFzF2nZc2yFpH9BKP9gqBxuAG/G/Q= -20251207221222.sql h1:6DS9hzcfN3+52WShFeI4f9Gqxd4LCQg1Otn5cRipIWU= -20251205073858.sql h1:Ep03jQ9hJAJILDJfKVcmi3Z6fqmTHSq9gKQtwf070PE= -20251205211957.sql h1:zRHcvLY+nfLdUyMcfpgI8vYQcPzJUWbfjkc4cK0QGHU= -20251205214433.sql h1:tgHB/fNy9XwAOWIqNI6GCqGXeJgSuZs2aHiCEj3BHZA= -20251205221124.sql h1:wl56/lrR14r7LrScEKwTQ3cNE45wh/0Ye3UEM7gfVNg= -20251209022744.sql h1:FayWjHhPEZEIq7KWIYaV/2/cmKB7A4PR3aspXXd6Brs= \ No newline at end of file +20251106050412.sql h1:1002KYtHd8AwrQTMewbs/PPHDylHDghigE/3S7PVdMA= +20251106063418.sql h1:jPW/gBnbFl4RO39lQ0ZMDtYA6xbhyD6CgQupT50HmaY= +20251106071906.sql h1:leYGKxR3EQn794aOehf0sd/ZPmOnvBMZPy5/anGmRB4= +20251106073157.sql h1:KASMzjjjk5UB7Zj8lCRtM1utc4ZnDjlnpZbtTe3vONE= +20251106074218.sql h1:Z5q5deOvLaZDPhiVTN9st3/s56RepBa2YOyrMXBdj4A= +20251106081846.sql h1:P+VsWwhGt60adDIZuE/Aa38JVp/yX1rnsdpXpxASodw= +20251106082844.sql h1:Dmi5A8i9frQZvdXYPwc7f8CisZtBH8liSXq1rI6z1iM= +20251106090021.sql h1:4JwdKgO8T46YhyWVJUxpRIwudBDlG8QN1brSOYmgQ20= +20251106144745.sql h1:nqnQCzGrVJaq8ilOEOGXeRUL1dolj+OPWKuP8A92FRA= +20251107012049.sql h1:Pff4UqltGS3clSlGr0qq8CQM56L29wyxY0FC/N/YAhU= +20251107064812.sql h1:GB9a0ZfMYTIoGNmKUG+XcYUsTnRMFfT4/dAD71uCPc4= +20251107064937.sql h1:IC5pw1Ifj30hiE6dr5NMHXaSHoQI+vRd40N5ABgBHRI= +20251107071420.sql h1:9NO3iyLEXEtWa2kSRjM/8LyzuVIk6pdFL2SuheWjB08= +20251107074318.sql h1:7fHbSRrdjOmHh/xwnjCLwoiB5cW5zeH+uxLV0vZbkIA= +20251107075050.sql h1:np+3uTOnU9QNtK7Knaw8eRMhkyB9AwrtSNHphOBxbHY= +20251107080604.sql h1:cXDBLPJDVWLTG6yEJqkJsOQ7p7VYxLM2SY+mwO8qSHo= +20251107081830.sql h1:/S7OQZo4ZnK80t28g/JyiOTZtmWG/dP5Wg2zXNMQ/iE= +20251107091033.sql h1:/cbkF1nO/IjNSIfDJJx456KJtQ9rWFXOBFAkR/M2xiE= +20251107091209.sql h1:jrLQOUeV8ji2fg0pnEcs1bw4ANUxzTSMXC/rrHLIY+M= +20251107091541.sql h1:6UqbhQQRmzA2+eKu5lIvkwOkk+lH70QLZC8Pjpjcq68= +20251110012217.sql h1:C9HpX0iyHzKjyNv/5DSAn2MCHj6MX4p5UQ/NrY7QD0w= +20251110012306.sql h1:J54yb27d30LBbYp9n1P66gFVRlxPguKu0kxmWIBBG8g= +20251110052049.sql h1:232T2x8xTczJl9nk4jxJpZXhoOGYthhxjJ7nK8Jd8vg= +20251110062042.sql h1:WnfVUXrzYoj8qdkkjO9/JQQ8agGd4GfSHQdMjo7LDAg= +20251110063202.sql h1:hSzGfwVMWa6q3vwIQZUkxKgBNCzHjB+6GKy54zfV+oQ= +20251110063633.sql h1:/VpofIAqNS1CnazEnpW/+evbzn9Kew3xDW48r57M+Xg= +20251110085551.sql h1:bFZwSmfvVbTUr/enWB82WqjG88gpqcZ6s45btUvO0uo= +20251110091516.sql h1:KkJMwPQuaZQhiqnKrNQrgP12gw9rV8T3P2o3mtGTcvY= +20251110091948.sql h1:I4odAYrJdvNf1jPw6ppDC0XdI7v6vKBACg/ABwUgA7I= +20251110092729.sql h1:l1out8soEmVP6dNjaIOtGYo6QDcoJZRI8X1sjZ5ZGmo= +20251110093522.sql h1:nsz8jCxGjEdr/bz9g+4ozfZzIP803xONjVmucad1GMc= +20251110100258.sql h1:IBqt1VZj5WjQ+l9aAFGHOCCBtzb03KlLLihFLut7itg= +20251110100545.sql h1:6/LV7751iyKxE2xI6vO1zly+aHUwxXD/IBwLcVpKxqM= +20251110155448.sql h1:kFPobJB+cpflsXBAWUwy3lohuWvrb/VRlXnhJWl7i3Y= +20251111072601.sql h1:ch8F+yVhsSM5xY+TwMLY3PxdLa4Wuhtj76oyw79R7Js= +20251111073546.sql h1:cCv0NPscADAOBahRVqtDWFs6G2t7n+4a+RwlF8vk/c4= +20251111074148.sql h1:70TsV83u1gQ5TktI13K7NQiyCCa35Td2aR6CNtKUa4U= +20251111074652.sql h1:ddfQ/sRKMezPM75xBFTGytUQX5AwZ3znrJVpg73gKPA= +20251111082257.sql h1:ZsdLY1ROouos0l3oS0lkeSiuKLEUGbVvBhpcM2AVhkw= +20251111111017.sql h1:qrJ93dNtQwcuAvpsP/lAK/H63C4cinXrsVaPmWsTqkU= +20251113101344.sql h1:xaOZvAUP1fFfnO+syEFOzJUIg5lTfBe5AWHPbBWuCLA= +20251113120533.sql h1:f3/U1Ve2yF2zSMhkt+xtwF8wUYfUKYwgbNeGfE37EW4= +20251114062746.sql h1:FInLaEFQByESEwFJKuKnuUSTKmcDpi3ZXaxkKwz2+D8= +20251117005942.sql h1:wD3BWrUSmo1HlW16V3lkaBkJvbAZ0fNk77te7J9NhOc= +20251117075427.sql h1:TqU9VKZa3I8YNXUGQWY3WVBYN+1FvyyaKy0hB1jgAho= +20251118074929.sql h1:p1KsWqCuR1JXA/jVO5BmOhCcaQ8clT7t0YRszAhPFbg= +20251119063438.sql h1:NVGM0X/LHD37EaPl8SNzkNiZDJ7AB1QR+LLwLh6WRdg= +20251119065730.sql h1:U5lzk1WvMB0bw3kwckou7jkEt4bwdYItwHr2Vxqe7w4= +20251119072302.sql h1:qCuI2WMEMF/XNbjV+RXPjBnuCKLu1Fia+mR9HiLWBIs= +20251119072450.sql h1:Xg+bTwqGyKPNFEQhJylvpz1wifdfmDJvcAq6vmNf0Ng= +20251120005512.sql h1:Ek6qpacAI/qVuTYxKno+uJyzn7s5z9pf3t7VA8gTzm4= +20251120074415.sql h1:NNUeJVA03EeBHJhHqPXEZoDv/PnC6yK1/cRhmukyaJo= +20251121033803.sql h1:/vfvFX/3pzSCIHnSbMUT9EMBDykOpVkvyfeTEle9Vas= +20251124071457.sql h1:qg2dhCL9YwD13xnfJ175lW/p6MGfzFKaBqd908FByRc= +20251125125303.sql h1:4JSFv1Pmhbe9tqpLXgO63OwYnGsalStgUXKVWPyc1YE= +20251126064057.sql h1:vAdhz5Nn/gGJy0UKZAEldeXv8HpHtJU/t8ygDVIbTsU= +20251201081333.sql h1:PoC8ADRdwDuohDTB74yW/DaB42igdYa4B6humbrEJBk= +20251201104439.sql h1:tpqdrOf9d2aGwZshqm62nG6SXnfVaO/g6A7z0efPS14= +20251201113804.sql h1:kIEmVoETJXBkab2Q+b3y/pP84eF8W2BdQ47amHCnc+c= +20251201113858.sql h1:KLXKZO5XTQPoEU0YLHE8Fhg9WPKpSN3wNgYPJ+RGFcg= +20251201114751.sql h1:HM17diiPknfSHAmP+kJGP6GzToaPU9/NT+KQBpf3Jq0= +20251201114913.sql h1:gqucFgHFFLA6n/Rdz486cZH5xkaJuwefESLJMJLDue8= +20251202030445.sql h1:QWBVfTepT7DaXP5E0BYoxNM0JwKIQ2qIMXzI4kbz/qE= +20251202044430.sql h1:4QZH9lz0GrQ9rzP1AJ+hJgGalNpp+8FCRckNK7xaTbU= +20251202064000.sql h1:/EN7sT1ol/91qW1aXWrzX+Mc3XOC/7f/LtfA0JRHpbg= +20251202130629.sql h1:9mvalqfhqGCdkcJepJDzHprU2xb0i5sYys1Htf62ioo= +20251202160848.sql h1:Kd2/TziKSMezrt4XgbjQcYvY/Lo9rX0qw7/Lz0/oyKk= +20251202180207.sql h1:IHmSMIO3ia+YV5GULixbdlV1joaUAWtnjQHPd8+HKiM= +20251202231005.sql h1:lua0KKoeBptSfs/6ehZE6Azo6YUlNkOJwGFyb1HQWkY= +20251203205052.sql h1:nk0VK2Uv4bHE3SBfHo/aevVZxtHzr7zAzvmMU8TCCtk= +20251205073858.sql h1:46qqXnArgJmzGE/WO7v7Ev8Jh7BudDiGbdANexq/5Dk= +20251205211957.sql h1:3fvtZ/mBWsTIXllXMFOuCLJsp4MivVP56dunehlU0yo= +20251205214433.sql h1:rn3++FEfX7ntcJcOmCEuOMnr27TZqH0KMGRppzFwFTc= +20251205221124.sql h1:CRruUvGZqlVDBmbQSVEl4wFm+uq30AurMMDI6sb8jxg= +20251207020537.sql h1:JspoBMoP1Yk854vtNniepvATINUpODQ9idKiMkNL0OU= +20251207212015.sql h1:pEH0+QnQ5WXNizxcToLk+8XYaAb6q6WJ1/MJViRVtNQ= +20251207221222.sql h1:gpl3V4/3AGqO3WLCpWW2GAtwuhpmNuBqXMiP61wVHX0= +20251209022744.sql h1:0WXCKpMDFAe/aVnosMGmCYp3mw+FIu+foX14sYmq750= From 3e4a49f2169ae8ffe33a40df85901244ff0375b9 Mon Sep 17 00:00:00 2001 From: vanilia Date: Tue, 9 Dec 2025 10:02:01 +0700 Subject: [PATCH 33/42] update migration --- cmd/main-migration/migrations/20251209025908.sql | 2 ++ cmd/main-migration/migrations/atlas.sum | 3 ++- internal/domain/main-entities/chemo/entity.go | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 cmd/main-migration/migrations/20251209025908.sql diff --git a/cmd/main-migration/migrations/20251209025908.sql b/cmd/main-migration/migrations/20251209025908.sql new file mode 100644 index 00000000..5a8522d7 --- /dev/null +++ b/cmd/main-migration/migrations/20251209025908.sql @@ -0,0 +1,2 @@ +-- Modify "Chemo" table +ALTER TABLE "public"."Chemo" ADD COLUMN "Class_Code" text NULL; diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 1df5b79f..ac03c936 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:bj3Rl8P0sdSmP7kBLfjyB30pIf3iUdthY5EBkfOtk7A= +h1:SSn9Za93bvbyBNVuGwpy9R/E/+1hm802NevovuLsplc= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -153,3 +153,4 @@ h1:bj3Rl8P0sdSmP7kBLfjyB30pIf3iUdthY5EBkfOtk7A= 20251207212015.sql h1:pEH0+QnQ5WXNizxcToLk+8XYaAb6q6WJ1/MJViRVtNQ= 20251207221222.sql h1:gpl3V4/3AGqO3WLCpWW2GAtwuhpmNuBqXMiP61wVHX0= 20251209022744.sql h1:0WXCKpMDFAe/aVnosMGmCYp3mw+FIu+foX14sYmq750= +20251209025908.sql h1:MgO50it1hj7Jj8BD5yKjW8OLC9qS3FFEdelqIsLT1v8= diff --git a/internal/domain/main-entities/chemo/entity.go b/internal/domain/main-entities/chemo/entity.go index 682333ed..cc828835 100644 --- a/internal/domain/main-entities/chemo/entity.go +++ b/internal/domain/main-entities/chemo/entity.go @@ -1,6 +1,7 @@ package chemo import ( + ere "simrs-vx/internal/domain/references/encounter" "time" ecore "simrs-vx/internal/domain/base-entities/core" @@ -27,4 +28,5 @@ type Chemo struct { Doctor_Code *string `json:"doctor_code"` Doctor *ed.Doctor `json:"doctor" gorm:"foreignKey:Doctor_Code;references:Code"` NextChemoDate *time.Time `json:"nextChemoDate"` + Class_Code ere.ChemoClassCode `json:"class_code"` } From 9ba0d06ce38bdc2e7edb17e63ad49ce947d15a2e Mon Sep 17 00:00:00 2001 From: vanilia Date: Tue, 9 Dec 2025 10:05:16 +0700 Subject: [PATCH 34/42] update migration --- internal/use-case/main-use-case/chemo-protocol/helper.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/internal/use-case/main-use-case/chemo-protocol/helper.go b/internal/use-case/main-use-case/chemo-protocol/helper.go index 885e6fbb..66a63dcc 100644 --- a/internal/use-case/main-use-case/chemo-protocol/helper.go +++ b/internal/use-case/main-use-case/chemo-protocol/helper.go @@ -17,12 +17,9 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.ChemoProtocol) { inputSrc = &inputTemp.CreateDto } - data.Encounter_Id = inputSrc.Encounter_Id data.Patient_Weight = inputSrc.Patient_Weight data.Patient_Height = inputSrc.Patient_Height data.Diagnoses = inputSrc.Diagnoses - data.Duration = inputSrc.Duration - data.DurationUnit_Code = inputSrc.DurationUnit_Code data.StartDate = inputSrc.StartDate data.EndDate = inputSrc.EndDate } From 7ef090bd17ef2c1cb09f572efcb2e86c07155e21 Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Tue, 9 Dec 2025 12:50:24 +0700 Subject: [PATCH 35/42] update atlas, remove unnecessary code --- cmd/main-migration/migrations/atlas.sum | 14 ++++++++------ internal/interface/main-handler/patient/handler.go | 5 ----- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index ac03c936..d81f6ccb 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:SSn9Za93bvbyBNVuGwpy9R/E/+1hm802NevovuLsplc= +h1:1Uh0B/nQPbiGKWcusDCZ9KUDAIGODzb8qSNiz7+yqrU= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -149,8 +149,10 @@ h1:SSn9Za93bvbyBNVuGwpy9R/E/+1hm802NevovuLsplc= 20251205211957.sql h1:3fvtZ/mBWsTIXllXMFOuCLJsp4MivVP56dunehlU0yo= 20251205214433.sql h1:rn3++FEfX7ntcJcOmCEuOMnr27TZqH0KMGRppzFwFTc= 20251205221124.sql h1:CRruUvGZqlVDBmbQSVEl4wFm+uq30AurMMDI6sb8jxg= -20251207020537.sql h1:JspoBMoP1Yk854vtNniepvATINUpODQ9idKiMkNL0OU= -20251207212015.sql h1:pEH0+QnQ5WXNizxcToLk+8XYaAb6q6WJ1/MJViRVtNQ= -20251207221222.sql h1:gpl3V4/3AGqO3WLCpWW2GAtwuhpmNuBqXMiP61wVHX0= -20251209022744.sql h1:0WXCKpMDFAe/aVnosMGmCYp3mw+FIu+foX14sYmq750= -20251209025908.sql h1:MgO50it1hj7Jj8BD5yKjW8OLC9qS3FFEdelqIsLT1v8= +20251206021053.sql h1:bpuEocu4lOhZ7oLuxd//22dzjfNgU2iaWEqSD1mVwoU= +20251207020537.sql h1:m6uh4NHVF3EKNTVMqOmuBSDFD9oCQk5mAwo05fT46G4= +20251207212015.sql h1:UPelYGTeUR6rm8mU8dfNzgRDEDun0UQ4tkgsaDljn30= +20251207221222.sql h1:bTfUCvCf2UPh+BA2IY2PHQafb9DwY9nhH5FRuMEHy+0= +20251209022744.sql h1:y5/PAiZH/fYCpDJpkQdNRJwWICHH2iNIwM1V+S1P6KA= +20251209025908.sql h1:p3kZA8kyEj+mQZSrdY3k2K1NojQzFJh/MlZJ0Oy6t/k= +20251209030538.sql h1:zltV6/Fu2zJW0/lVBl7MdnWuJcqNTUIRcqYYZ8Fi1wo= diff --git a/internal/interface/main-handler/patient/handler.go b/internal/interface/main-handler/patient/handler.go index ce1c6c52..dc6c3ff5 100644 --- a/internal/interface/main-handler/patient/handler.go +++ b/internal/interface/main-handler/patient/handler.go @@ -69,11 +69,6 @@ func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { return } - authInfo, err := pa.GetAuthInfo(r) - if err != nil { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) - } - dto.Id = uint(id) dto.AuthInfo = *authInfo res, err := u.Update(dto) From e3869ea5e996f6dbe866dff16fc348cd3dec5938 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Tue, 9 Dec 2025 12:52:30 +0700 Subject: [PATCH 36/42] migration from server --- cmd/main-migration/migrations/atlas.sum | 164 ++++++++++++------------ 1 file changed, 82 insertions(+), 82 deletions(-) diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index d81f6ccb..cc3978f3 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:1Uh0B/nQPbiGKWcusDCZ9KUDAIGODzb8qSNiz7+yqrU= +h1:rEaAvMVRfUZCdhjipT3pYEoprBT8VTGN1C6p59FvR3Y= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -75,84 +75,84 @@ h1:1Uh0B/nQPbiGKWcusDCZ9KUDAIGODzb8qSNiz7+yqrU= 20251106040137.sql h1:ppcqkVoT0o9jZcjI/TN7LuaPxXhJQhnIXEJtloP/46o= 20251106041333.sql h1:2JkxyelQ/EeB+boL5bfpnzefw32ttEGKvKchtQjWmAU= 20251106042006.sql h1:ruppYa1kAJQUU3ufQBbKGMcXrGbGJJiRPclT+dNc/YQ= -20251106050412.sql h1:1002KYtHd8AwrQTMewbs/PPHDylHDghigE/3S7PVdMA= -20251106063418.sql h1:jPW/gBnbFl4RO39lQ0ZMDtYA6xbhyD6CgQupT50HmaY= -20251106071906.sql h1:leYGKxR3EQn794aOehf0sd/ZPmOnvBMZPy5/anGmRB4= -20251106073157.sql h1:KASMzjjjk5UB7Zj8lCRtM1utc4ZnDjlnpZbtTe3vONE= -20251106074218.sql h1:Z5q5deOvLaZDPhiVTN9st3/s56RepBa2YOyrMXBdj4A= -20251106081846.sql h1:P+VsWwhGt60adDIZuE/Aa38JVp/yX1rnsdpXpxASodw= -20251106082844.sql h1:Dmi5A8i9frQZvdXYPwc7f8CisZtBH8liSXq1rI6z1iM= -20251106090021.sql h1:4JwdKgO8T46YhyWVJUxpRIwudBDlG8QN1brSOYmgQ20= -20251106144745.sql h1:nqnQCzGrVJaq8ilOEOGXeRUL1dolj+OPWKuP8A92FRA= -20251107012049.sql h1:Pff4UqltGS3clSlGr0qq8CQM56L29wyxY0FC/N/YAhU= -20251107064812.sql h1:GB9a0ZfMYTIoGNmKUG+XcYUsTnRMFfT4/dAD71uCPc4= -20251107064937.sql h1:IC5pw1Ifj30hiE6dr5NMHXaSHoQI+vRd40N5ABgBHRI= -20251107071420.sql h1:9NO3iyLEXEtWa2kSRjM/8LyzuVIk6pdFL2SuheWjB08= -20251107074318.sql h1:7fHbSRrdjOmHh/xwnjCLwoiB5cW5zeH+uxLV0vZbkIA= -20251107075050.sql h1:np+3uTOnU9QNtK7Knaw8eRMhkyB9AwrtSNHphOBxbHY= -20251107080604.sql h1:cXDBLPJDVWLTG6yEJqkJsOQ7p7VYxLM2SY+mwO8qSHo= -20251107081830.sql h1:/S7OQZo4ZnK80t28g/JyiOTZtmWG/dP5Wg2zXNMQ/iE= -20251107091033.sql h1:/cbkF1nO/IjNSIfDJJx456KJtQ9rWFXOBFAkR/M2xiE= -20251107091209.sql h1:jrLQOUeV8ji2fg0pnEcs1bw4ANUxzTSMXC/rrHLIY+M= -20251107091541.sql h1:6UqbhQQRmzA2+eKu5lIvkwOkk+lH70QLZC8Pjpjcq68= -20251110012217.sql h1:C9HpX0iyHzKjyNv/5DSAn2MCHj6MX4p5UQ/NrY7QD0w= -20251110012306.sql h1:J54yb27d30LBbYp9n1P66gFVRlxPguKu0kxmWIBBG8g= -20251110052049.sql h1:232T2x8xTczJl9nk4jxJpZXhoOGYthhxjJ7nK8Jd8vg= -20251110062042.sql h1:WnfVUXrzYoj8qdkkjO9/JQQ8agGd4GfSHQdMjo7LDAg= -20251110063202.sql h1:hSzGfwVMWa6q3vwIQZUkxKgBNCzHjB+6GKy54zfV+oQ= -20251110063633.sql h1:/VpofIAqNS1CnazEnpW/+evbzn9Kew3xDW48r57M+Xg= -20251110085551.sql h1:bFZwSmfvVbTUr/enWB82WqjG88gpqcZ6s45btUvO0uo= -20251110091516.sql h1:KkJMwPQuaZQhiqnKrNQrgP12gw9rV8T3P2o3mtGTcvY= -20251110091948.sql h1:I4odAYrJdvNf1jPw6ppDC0XdI7v6vKBACg/ABwUgA7I= -20251110092729.sql h1:l1out8soEmVP6dNjaIOtGYo6QDcoJZRI8X1sjZ5ZGmo= -20251110093522.sql h1:nsz8jCxGjEdr/bz9g+4ozfZzIP803xONjVmucad1GMc= -20251110100258.sql h1:IBqt1VZj5WjQ+l9aAFGHOCCBtzb03KlLLihFLut7itg= -20251110100545.sql h1:6/LV7751iyKxE2xI6vO1zly+aHUwxXD/IBwLcVpKxqM= -20251110155448.sql h1:kFPobJB+cpflsXBAWUwy3lohuWvrb/VRlXnhJWl7i3Y= -20251111072601.sql h1:ch8F+yVhsSM5xY+TwMLY3PxdLa4Wuhtj76oyw79R7Js= -20251111073546.sql h1:cCv0NPscADAOBahRVqtDWFs6G2t7n+4a+RwlF8vk/c4= -20251111074148.sql h1:70TsV83u1gQ5TktI13K7NQiyCCa35Td2aR6CNtKUa4U= -20251111074652.sql h1:ddfQ/sRKMezPM75xBFTGytUQX5AwZ3znrJVpg73gKPA= -20251111082257.sql h1:ZsdLY1ROouos0l3oS0lkeSiuKLEUGbVvBhpcM2AVhkw= -20251111111017.sql h1:qrJ93dNtQwcuAvpsP/lAK/H63C4cinXrsVaPmWsTqkU= -20251113101344.sql h1:xaOZvAUP1fFfnO+syEFOzJUIg5lTfBe5AWHPbBWuCLA= -20251113120533.sql h1:f3/U1Ve2yF2zSMhkt+xtwF8wUYfUKYwgbNeGfE37EW4= -20251114062746.sql h1:FInLaEFQByESEwFJKuKnuUSTKmcDpi3ZXaxkKwz2+D8= -20251117005942.sql h1:wD3BWrUSmo1HlW16V3lkaBkJvbAZ0fNk77te7J9NhOc= -20251117075427.sql h1:TqU9VKZa3I8YNXUGQWY3WVBYN+1FvyyaKy0hB1jgAho= -20251118074929.sql h1:p1KsWqCuR1JXA/jVO5BmOhCcaQ8clT7t0YRszAhPFbg= -20251119063438.sql h1:NVGM0X/LHD37EaPl8SNzkNiZDJ7AB1QR+LLwLh6WRdg= -20251119065730.sql h1:U5lzk1WvMB0bw3kwckou7jkEt4bwdYItwHr2Vxqe7w4= -20251119072302.sql h1:qCuI2WMEMF/XNbjV+RXPjBnuCKLu1Fia+mR9HiLWBIs= -20251119072450.sql h1:Xg+bTwqGyKPNFEQhJylvpz1wifdfmDJvcAq6vmNf0Ng= -20251120005512.sql h1:Ek6qpacAI/qVuTYxKno+uJyzn7s5z9pf3t7VA8gTzm4= -20251120074415.sql h1:NNUeJVA03EeBHJhHqPXEZoDv/PnC6yK1/cRhmukyaJo= -20251121033803.sql h1:/vfvFX/3pzSCIHnSbMUT9EMBDykOpVkvyfeTEle9Vas= -20251124071457.sql h1:qg2dhCL9YwD13xnfJ175lW/p6MGfzFKaBqd908FByRc= -20251125125303.sql h1:4JSFv1Pmhbe9tqpLXgO63OwYnGsalStgUXKVWPyc1YE= -20251126064057.sql h1:vAdhz5Nn/gGJy0UKZAEldeXv8HpHtJU/t8ygDVIbTsU= -20251201081333.sql h1:PoC8ADRdwDuohDTB74yW/DaB42igdYa4B6humbrEJBk= -20251201104439.sql h1:tpqdrOf9d2aGwZshqm62nG6SXnfVaO/g6A7z0efPS14= -20251201113804.sql h1:kIEmVoETJXBkab2Q+b3y/pP84eF8W2BdQ47amHCnc+c= -20251201113858.sql h1:KLXKZO5XTQPoEU0YLHE8Fhg9WPKpSN3wNgYPJ+RGFcg= -20251201114751.sql h1:HM17diiPknfSHAmP+kJGP6GzToaPU9/NT+KQBpf3Jq0= -20251201114913.sql h1:gqucFgHFFLA6n/Rdz486cZH5xkaJuwefESLJMJLDue8= -20251202030445.sql h1:QWBVfTepT7DaXP5E0BYoxNM0JwKIQ2qIMXzI4kbz/qE= -20251202044430.sql h1:4QZH9lz0GrQ9rzP1AJ+hJgGalNpp+8FCRckNK7xaTbU= -20251202064000.sql h1:/EN7sT1ol/91qW1aXWrzX+Mc3XOC/7f/LtfA0JRHpbg= -20251202130629.sql h1:9mvalqfhqGCdkcJepJDzHprU2xb0i5sYys1Htf62ioo= -20251202160848.sql h1:Kd2/TziKSMezrt4XgbjQcYvY/Lo9rX0qw7/Lz0/oyKk= -20251202180207.sql h1:IHmSMIO3ia+YV5GULixbdlV1joaUAWtnjQHPd8+HKiM= -20251202231005.sql h1:lua0KKoeBptSfs/6ehZE6Azo6YUlNkOJwGFyb1HQWkY= -20251203205052.sql h1:nk0VK2Uv4bHE3SBfHo/aevVZxtHzr7zAzvmMU8TCCtk= -20251205073858.sql h1:46qqXnArgJmzGE/WO7v7Ev8Jh7BudDiGbdANexq/5Dk= -20251205211957.sql h1:3fvtZ/mBWsTIXllXMFOuCLJsp4MivVP56dunehlU0yo= -20251205214433.sql h1:rn3++FEfX7ntcJcOmCEuOMnr27TZqH0KMGRppzFwFTc= -20251205221124.sql h1:CRruUvGZqlVDBmbQSVEl4wFm+uq30AurMMDI6sb8jxg= -20251206021053.sql h1:bpuEocu4lOhZ7oLuxd//22dzjfNgU2iaWEqSD1mVwoU= -20251207020537.sql h1:m6uh4NHVF3EKNTVMqOmuBSDFD9oCQk5mAwo05fT46G4= -20251207212015.sql h1:UPelYGTeUR6rm8mU8dfNzgRDEDun0UQ4tkgsaDljn30= -20251207221222.sql h1:bTfUCvCf2UPh+BA2IY2PHQafb9DwY9nhH5FRuMEHy+0= -20251209022744.sql h1:y5/PAiZH/fYCpDJpkQdNRJwWICHH2iNIwM1V+S1P6KA= -20251209025908.sql h1:p3kZA8kyEj+mQZSrdY3k2K1NojQzFJh/MlZJ0Oy6t/k= -20251209030538.sql h1:zltV6/Fu2zJW0/lVBl7MdnWuJcqNTUIRcqYYZ8Fi1wo= +20251106050412.sql h1:MiEMJ1HCFYnalKuq3Z38xJeogfBAMqsTv2sG4EF8dDw= +20251106063418.sql h1:y3veDJPjKekOWLCZek/LgQwXPRhZtOppTfUXiqoL95s= +20251106071906.sql h1:/TUZA3XpMY23qEJXdkTwlzrNMvSSl6JJniPcgAttBaw= +20251106073157.sql h1:78txeibJ602DMD7huD618ZSMt6phSRzDNPTlo0PGyrc= +20251106074218.sql h1:8Xz7WywrtUnSxOHhlal53gG9rE7r86LFUt5zBFe/mIs= +20251106081846.sql h1:jp91Bf5bxGXMiUB1VIuN6y768vb2iWwow44WfCE5J5k= +20251106082844.sql h1:RHYzRO4G1fSWwf+xc/3QezZ/Iil67cZPIgNpNz3TNhQ= +20251106090021.sql h1:dFDk6mq+zjbYWmfWIrHf9DiKvvoXHjrr0++zssMTWP8= +20251106144745.sql h1:aHcr23iBFqCHer5D/SsPMXBCLjGqUYvWYfRU8jSJgIw= +20251107012049.sql h1:hu/7NHhnAkT4xK0RNtqmMDdH1Bo5EZbl7itDRjiCT+g= +20251107064812.sql h1:sfCXDQYnMf0ddrQ9oYljWJLLSt9NJjJV6o8VS3p7aZE= +20251107064937.sql h1:DlYGJ9LZFwZyR7jBP5zaGB128aIc4HAixBKPYCz9EkY= +20251107071420.sql h1:ynCdZAd2utLl+FhtWZwtahNXgIVOvuk3s/rOq7lfXA4= +20251107074318.sql h1:WE9cPhibWtZ0dbu1VEGirTeY6ijFYGMNhHdBtM32kOc= +20251107075050.sql h1:8tvneruqdynDOaJK1+0z4CH7YXZStZpGdqwIeOMLik4= +20251107080604.sql h1:8c4jd4Tql7tcdhbI9NS0tgvN+ADu9FnCf8wMUbmW7A0= +20251107081830.sql h1:SAAe3lmsm9vGXuSEsDdl7ad0EAxP5CMmFRDEgp9M7yY= +20251107091033.sql h1:JLdX/u7GUdBfjrPrMSNAqc8HtSoj0YA9iW9Vc6FJZdw= +20251107091209.sql h1:CzhYtwAwT+GHrbqcagnJE+v3mbl/rObf1IJaLCKlzrs= +20251107091541.sql h1:+3ZyWJTftDY2JeWThXuIxGWpUBnyMPyOyY4jBjdWYJI= +20251110012217.sql h1:f4Z8TuGc+XMSJ+Ekn4/PeHRE2FlHWkc5gKPJB0hAX7c= +20251110012306.sql h1:ENPyI6Kjdk6qKJQb0yJ6MCTDPAmO1WD/uhKuCSl+jYo= +20251110052049.sql h1:OrQ0acnyoQLKnTitZfnBcVr5jDslF59OFLaqT7SpdVs= +20251110062042.sql h1:9KwldQt0NpVPR86L0T4hlkfHAGau+7CiZYgu5rF+yhg= +20251110063202.sql h1:A117DuZmZ6U0jWHA3DISnr+yvBjKIr1ObrUr047YezQ= +20251110063633.sql h1:qTiC0F19JnhUIXF4LGJQ21jEV6kKGyhTr1x2kimFqPQ= +20251110085551.sql h1:HZcJM0RSC6HBaUSjKBE8MgDG8Vn9f3LmwA/OnT9Cp7I= +20251110091516.sql h1:W3AQhQLgirEWuCObbLl+Prdrbq6k6EEY1xcoWsmbog4= +20251110091948.sql h1:3tsITMrZr/T+L4wqUMz8sHS229jCJl4T0Nu3dMccxH8= +20251110092729.sql h1:uU+k88RH/e0Ns4/SmJl03RVYPscBAPuiLfxR6CJqaf0= +20251110093522.sql h1:O7upSj8VNjzvroL4IU59bfxKATOkAVGBArcUbVNq9aM= +20251110100258.sql h1://JSArUMNI3/gAtYDx2VN94C198SFW0ANjgs+p6eCRM= +20251110100545.sql h1:ENPOqeJYRpMI4e8VCKwaQgaql8se6pIidAhG2cjskBg= +20251110155448.sql h1:VW9KE0jxWy4flZ28sdXmhY6JWd6eKAX/cVL8KWRVii4= +20251111072601.sql h1:99WWzGjcDDFNC2cHRfPu4MBLWNrgPMY5HAYUbmIcVRA= +20251111073546.sql h1:iIGwFNfUgStdczw/PXTH3SD84xAyxrbZICofc3M8TMk= +20251111074148.sql h1:mzkezSKwCV2bTZ/0BHiTCX5qAy4uHpwar1xzwAH15Ko= +20251111074652.sql h1:lYh4/3BHV24pgPC0pP4RUKb+XtL/6AsZGPItRpnzBiQ= +20251111082257.sql h1:+cIZ1lf8HYGSL6t6U88plLKk8nOO1YVdV7h3YOM84ds= +20251111111017.sql h1:xzlhR2xLfOj4ddYlesS+bpEeDrxiAf5ILNOspsbZjBU= +20251113101344.sql h1:vSzThY3p6XYTj0dJ2uFVkHmlytyrFAnGE58CJLx364I= +20251113120533.sql h1:lfjgdqRGo/EohrVw8sWlFbDjh3ASTsfQ6pr3qjafqvc= +20251114062746.sql h1:6DLYjfJ60PkAABZTXvOwSE+xrU25oyoX7gpYlBnA9cw= +20251117005942.sql h1:0XoJKca8IOaB9QKFVF/qPY7jKcIgh6m/LODQuE06SAs= +20251117075427.sql h1:LhY2urosfoSu1/vkHmgsNP4JA4DuWBs9gL59yMqcF8M= +20251118074929.sql h1:3RWBD6BziQVw6WSfthgoVuhTELHER9NrIuZm4hY/F1A= +20251119063438.sql h1:EVTG3ZrHjCmM95YPASZTRPiwHrG6e33A2vO4hLSAaBQ= +20251119065730.sql h1:s98wnZOCW6NbnwDS3H53XIQ60u6B9bDwBLNvy5+Rn64= +20251119072302.sql h1:ZL+VHekLYqgNtOFKlj02WHrAk11dtTxQkmyTKE8IOzY= +20251119072450.sql h1:SiJy2vpSvoPFw4J1SW7HjGSJzrqR62NsjRYAeabV+kc= +20251120005512.sql h1:hJUaWXYJ3HiSquBTw8OKhymjA4O43ehAMGfiOY8W87Q= +20251120074415.sql h1:dNmcqZHqfZwi/wtYvO/pSFgImN2scXL0p/7g0+HLp0s= +20251121033803.sql h1:onlddYGo+tQdGaEdJPqdsx3sncGnwEvqMSCksF6vjjI= +20251124071457.sql h1:ikQLIXFikUbkUd55uJBmEvqLGEC9t0db+Om4TQsWP7M= +20251125125303.sql h1:OLKbNPO36AHtIDursW9AeBvf60sahQKC1iOjHmpx0MA= +20251126064057.sql h1:6al3PTWbw/WGiBcrRrVWppOMLtG+eRaH/qSLbnmh1kQ= +20251201081333.sql h1:dD+jcisoUYnxRYWdtVcnxbDeYjUW12/R/qarYQr+utg= +20251201104439.sql h1:h4tz5uetbCKeOI3agSVmAeh6jUfECYy0LhQ7HooYhzg= +20251201113804.sql h1:DdUzqfLdy4AUpVSRFDrIJXntGmtKgZrtvv8MAT4mMxs= +20251201113858.sql h1:XSpicm4aWjrfeY5EYIiw8Ios9v7BGfzZJxpW/57Qwqs= +20251201114751.sql h1:qx+ShdHLacVFcRwwGrW1zMKFHOjMGdnusk7CEfyV8ig= +20251201114913.sql h1:6l/m2/6fmTIjFmKio0QmB8oTwBDCHTIkbuYTODQ7Gwk= +20251202030445.sql h1:5+6ss5KdN6pll8Qtf0RGGyy/BURNO3dBgIBJOzDb624= +20251202044430.sql h1:nJtlQDGj7ZJtJ07NYcF41JCn9ck50GyDPoitTOe8P/s= +20251202064000.sql h1:yzSMOPZrpvQf+u6CxD6LwNySNH9Ip1u70UEf2vWI5w4= +20251202130629.sql h1:u79EiiYq5irxCcjlOHQcACnCKS05XPDDsL4TzLGrNQA= +20251202160848.sql h1:Aq5rVLbrL4vvNnmfk82V22GTteWVTSq9vk2SYzi3EBo= +20251202180207.sql h1:J0Orufzpi+tNhd5+9eLvonKhYc/WMceVHO1WDVRrHAM= +20251202231005.sql h1:DBunbxmAfPYiO5mHspc4dyTTVFoKrHkZSwk/Ieu5oFA= +20251203205052.sql h1:67NoN6JhDfChBA13dmErBSRDiC1gdVBb2F+8SMzpm4U= +20251205073858.sql h1:q6kLxs713H2BeVmC4cN6OnWz4Vj4k3G1iemqQnddmL8= +20251205211957.sql h1:aYPG5ESbHjhLRf8Dym1IMLBW2eRuafafoL46vpiRbWs= +20251205214433.sql h1:X9NOCU2CenDxnXe3kOyUB11Zikk+yO9yWNYAwFs/Bms= +20251205221124.sql h1:8ZXiMoNKQIMwXoLzrC44EQpXDUyEP16MiDOwUc9FI0s= +20251206021053.sql h1:jntV1lOgr4viO5wfavoTergWBSYDCbqw7L/UkhwuCYM= +20251207020537.sql h1:UIeD0lLOmo80REhicPlYsjj99xYYybPBph8ewZOQa2M= +20251207212015.sql h1:gMDRyRTNMyH9iNG/9cTflLUf60r5qMteaaTcQoDzNAI= +20251207221222.sql h1:FT+HGmIpvm+Y3w7DmENoeJWHBHjucDPQXPl8xyBRn9Y= +20251209022744.sql h1:eRmSp7hnpz5Mded7sBkc2+VZX6xKzU95rIzZOJC9Lhw= +20251209025908.sql h1:ZDtWUIuMIAcjQ/mMdDXbrbk+De9T2TGqprXcVSZOoT4= +20251209030538.sql h1:iTQimic8fGvHU10V7PSpSe9I0YpRFuNjOeOLY0eGMp8= From 792c7cc9d4b883c2003d825da530325897e752f5 Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Tue, 9 Dec 2025 13:43:41 +0700 Subject: [PATCH 37/42] feat/user: added registration entity --- .../migrations/20251209064304.sql | 12 ++++ cmd/main-migration/migrations/atlas.sum | 5 +- .../domain/main-entities/registration/dto.go | 71 +++++++++++++++++++ .../main-entities/registration/entity.go | 15 ++++ internal/interface/migration/main-entities.go | 2 + 5 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 cmd/main-migration/migrations/20251209064304.sql create mode 100644 internal/domain/main-entities/registration/dto.go create mode 100644 internal/domain/main-entities/registration/entity.go diff --git a/cmd/main-migration/migrations/20251209064304.sql b/cmd/main-migration/migrations/20251209064304.sql new file mode 100644 index 00000000..fc289e20 --- /dev/null +++ b/cmd/main-migration/migrations/20251209064304.sql @@ -0,0 +1,12 @@ +-- Create "Registration" table +CREATE TABLE "public"."Registration" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Employee_Id" bigint NULL, + "Installation_Code" character varying(20) NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_Registration_Employee" FOREIGN KEY ("Employee_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_Registration_Installation" FOREIGN KEY ("Installation_Code") REFERENCES "public"."Installation" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION +); diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 3ec1b876..c953a07b 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:qjr3k9/ymXjw1nopw49c6+fWtu0n+H8sQgsioqUC9Fo= +h1:JGe2DnXv3QZTmdne3HWeAGA4rppck8cJaiZ0RgoM+Sg= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -144,4 +144,5 @@ h1:qjr3k9/ymXjw1nopw49c6+fWtu0n+H8sQgsioqUC9Fo= 20251202160848.sql h1:Kd2/TziKSMezrt4XgbjQcYvY/Lo9rX0qw7/Lz0/oyKk= 20251202180207.sql h1:IHmSMIO3ia+YV5GULixbdlV1joaUAWtnjQHPd8+HKiM= 20251202231005.sql h1:lua0KKoeBptSfs/6ehZE6Azo6YUlNkOJwGFyb1HQWkY= -20251203205052.sql h1:az/hGpk7u4YKT7gU+UuEw9guqB9AqdckPF1cYavQ3CA= +20251203205052.sql h1:nk0VK2Uv4bHE3SBfHo/aevVZxtHzr7zAzvmMU8TCCtk= +20251209064304.sql h1:/vp48I71991yaVsOw/g+eFsFydgLGEo+Xfen7Lp8WB4= diff --git a/internal/domain/main-entities/registration/dto.go b/internal/domain/main-entities/registration/dto.go new file mode 100644 index 00000000..b7837aee --- /dev/null +++ b/internal/domain/main-entities/registration/dto.go @@ -0,0 +1,71 @@ +package doctor + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ee "simrs-vx/internal/domain/main-entities/employee" + ei "simrs-vx/internal/domain/main-entities/installation" +) + +type CreateDto struct { + Employee_Id uint `json:"employee_id"` + Installation_Code string `json:"installation_code" validate:"maxLength=20"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Employee_Id *uint `json:"employee-id"` + Installation_Code *string `json:"installation-code"` +} + +type ReadDetailDto struct { + Id *uint16 `json:"id"` + Code *string `json:"code"` + Employee_Id *uint `json:"employee_id"` +} + +type UpdateDto struct { + Id *uint `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + Employee_Id uint `json:"employee_id"` + Employee *ee.Employee `json:"employee,omitempty"` + Installation_Code string `json:"installation_code"` + Installation *ei.Installation `json:"installation,omitempty"` +} + +func (d Registration) ToResponse() ResponseDto { + resp := ResponseDto{ + Employee_Id: d.Employee_Id, + Employee: d.Employee, + Installation_Code: d.Installation_Code, + Installation: d.Installation, + } + resp.Main = d.Main + return resp +} + +func ToResponseList(data []Registration) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/registration/entity.go b/internal/domain/main-entities/registration/entity.go new file mode 100644 index 00000000..52d81f40 --- /dev/null +++ b/internal/domain/main-entities/registration/entity.go @@ -0,0 +1,15 @@ +package doctor + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ee "simrs-vx/internal/domain/main-entities/employee" + ei "simrs-vx/internal/domain/main-entities/installation" +) + +type Registration struct { + ecore.Main // adjust this according to the needs + Employee_Id uint `json:"employee_id"` + Employee *ee.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"` + Installation_Code string `json:"installation_code" gorm:"size:20"` + Installation *ei.Installation `json:"installation,omitempty" gorm:"foreignKey:Installation_Code;references:Code"` +} diff --git a/internal/interface/migration/main-entities.go b/internal/interface/migration/main-entities.go index 34530d78..aa4ed3f6 100644 --- a/internal/interface/migration/main-entities.go +++ b/internal/interface/migration/main-entities.go @@ -88,6 +88,7 @@ import ( proceduresrc "simrs-vx/internal/domain/main-entities/procedure-src" province "simrs-vx/internal/domain/main-entities/province" regency "simrs-vx/internal/domain/main-entities/regency" + registration "simrs-vx/internal/domain/main-entities/registration" rehab "simrs-vx/internal/domain/main-entities/rehab" responsibledoctorhist "simrs-vx/internal/domain/main-entities/responsible-doctor-hist" resume "simrs-vx/internal/domain/main-entities/resume" @@ -140,6 +141,7 @@ func getMainEntities() []any { &proceduresrc.ProcedureSrc{}, &employee.Employee{}, &intern.Intern{}, + ®istration.Registration{}, &doctor.Doctor{}, &nurse.Nurse{}, &nutritionist.Nutritionist{}, From 143b873c1134f7a9d75e948d66db4ccb20222057 Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Tue, 9 Dec 2025 14:02:30 +0700 Subject: [PATCH 38/42] migration: adjust person entity --- .../migrations/20251209070128.sql | 2 ++ cmd/main-migration/migrations/atlas.sum | 16 ++++++++++++++-- internal/domain/main-entities/person/dto.go | 18 ++++++++++-------- internal/domain/main-entities/person/entity.go | 1 + 4 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 cmd/main-migration/migrations/20251209070128.sql diff --git a/cmd/main-migration/migrations/20251209070128.sql b/cmd/main-migration/migrations/20251209070128.sql new file mode 100644 index 00000000..fb0caac3 --- /dev/null +++ b/cmd/main-migration/migrations/20251209070128.sql @@ -0,0 +1,2 @@ +-- Modify "Person" table +ALTER TABLE "public"."Person" ADD COLUMN "BirthPlace" text NULL; diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index c953a07b..b828c76d 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:JGe2DnXv3QZTmdne3HWeAGA4rppck8cJaiZ0RgoM+Sg= +h1:YJzcjq4dKD7GKlV0GJ88TOtZgg0JRDcVMlAe5ZYT9/U= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -145,4 +145,16 @@ h1:JGe2DnXv3QZTmdne3HWeAGA4rppck8cJaiZ0RgoM+Sg= 20251202180207.sql h1:IHmSMIO3ia+YV5GULixbdlV1joaUAWtnjQHPd8+HKiM= 20251202231005.sql h1:lua0KKoeBptSfs/6ehZE6Azo6YUlNkOJwGFyb1HQWkY= 20251203205052.sql h1:nk0VK2Uv4bHE3SBfHo/aevVZxtHzr7zAzvmMU8TCCtk= -20251209064304.sql h1:/vp48I71991yaVsOw/g+eFsFydgLGEo+Xfen7Lp8WB4= +20251205073858.sql h1:46qqXnArgJmzGE/WO7v7Ev8Jh7BudDiGbdANexq/5Dk= +20251205211957.sql h1:3fvtZ/mBWsTIXllXMFOuCLJsp4MivVP56dunehlU0yo= +20251205214433.sql h1:rn3++FEfX7ntcJcOmCEuOMnr27TZqH0KMGRppzFwFTc= +20251205221124.sql h1:CRruUvGZqlVDBmbQSVEl4wFm+uq30AurMMDI6sb8jxg= +20251206021053.sql h1:bpuEocu4lOhZ7oLuxd//22dzjfNgU2iaWEqSD1mVwoU= +20251207020537.sql h1:m6uh4NHVF3EKNTVMqOmuBSDFD9oCQk5mAwo05fT46G4= +20251207212015.sql h1:UPelYGTeUR6rm8mU8dfNzgRDEDun0UQ4tkgsaDljn30= +20251207221222.sql h1:bTfUCvCf2UPh+BA2IY2PHQafb9DwY9nhH5FRuMEHy+0= +20251209022744.sql h1:y5/PAiZH/fYCpDJpkQdNRJwWICHH2iNIwM1V+S1P6KA= +20251209025908.sql h1:p3kZA8kyEj+mQZSrdY3k2K1NojQzFJh/MlZJ0Oy6t/k= +20251209030538.sql h1:zltV6/Fu2zJW0/lVBl7MdnWuJcqNTUIRcqYYZ8Fi1wo= +20251209064304.sql h1:Mj6Zh+2b/4AkM1HjnJGjAs788kVN0UaL34jeaKQIjT0= +20251209070128.sql h1:rdqSlAmJS5XSc1w9dka3C53zwgibQwRIUqBcgmIPoTM= diff --git a/internal/domain/main-entities/person/dto.go b/internal/domain/main-entities/person/dto.go index 588379df..dbab95b0 100644 --- a/internal/domain/main-entities/person/dto.go +++ b/internal/domain/main-entities/person/dto.go @@ -19,6 +19,7 @@ type CreateDto struct { FrontTitle *string `json:"frontTitle" validate:"maxLength=50"` EndTitle *string `json:"endTitle" validate:"maxLength=50"` BirthDate *time.Time `json:"birthDate,omitempty"` + BirthPlace *string `json:"birthPlace" validate:"maxLength=4"` BirthRegency_Code *string `json:"birthRegency_code" validate:"maxLength=4"` Gender_Code *erp.GenderCode `json:"gender_code"` ResidentIdentityNumber *string `json:"residentIdentityNumber" validate:"nik;maxLength=16"` @@ -46,14 +47,13 @@ type ReadListDto struct { type FilterDto struct { Name string `json:"name"` - FrontTitle *string `json:"frontTitle"` - EndTitle *string `json:"endTitle"` - BirthDate *time.Time `json:"birthDate,omitempty"` - BirthRegency_Code *string `json:"birthRegency-code"` + FrontTitle *string `json:"front-title"` + EndTitle *string `json:"end-title"` + BirthDate *time.Time `json:"birth-date,omitempty"` Gender_Code *erp.GenderCode `json:"gender-code"` - ResidentIdentityNumber *string `json:"residentIdentityNumber"` - PassportNumber *string `json:"passportNumber"` - DrivingLicenseNumber *string `json:"drivingLicenseNumber"` + ResidentIdentityNumber *string `json:"resident-identity-number"` + PassportNumber *string `json:"passport-number"` + DrivingLicenseNumber *string `json:"driving-license-number"` Religion_Code *erp.ReligionCode `json:"religion-code"` Education_Code *erp.EducationCode `json:"education-code"` Ocupation_Code *erp.OcupationCode `json:"occupation-code"` @@ -61,7 +61,7 @@ type FilterDto struct { Nationality *string `json:"nationality"` Ethnic_Code *string `json:"ethnic-code"` Language_Code *string `json:"language-code"` - CommunicationIssueStatus bool `json:"communicationIssueStatus"` + CommunicationIssueStatus bool `json:"communication-issue-status"` Disability *string `json:"disability"` } @@ -94,6 +94,7 @@ type ResponseDto struct { FrontTitle *string `json:"frontTitle"` EndTitle *string `json:"endTitle"` BirthDate *time.Time `json:"birthDate,omitempty"` + BirthPlace *string `json:"birthPlace"` BirthRegency_Code *string `json:"birthRegency_code"` BirthRegency *er.Regency `json:"birthRegency,omitempty"` Gender_Code *erp.GenderCode `json:"gender_code"` @@ -128,6 +129,7 @@ func (d *Person) ToResponse() ResponseDto { FrontTitle: d.FrontTitle, EndTitle: d.EndTitle, BirthDate: d.BirthDate, + BirthPlace: d.BirthPlace, BirthRegency_Code: d.BirthRegency_Code, BirthRegency: d.BirthRegency, Gender_Code: d.Gender_Code, diff --git a/internal/domain/main-entities/person/entity.go b/internal/domain/main-entities/person/entity.go index 3c7d8629..10626229 100644 --- a/internal/domain/main-entities/person/entity.go +++ b/internal/domain/main-entities/person/entity.go @@ -23,6 +23,7 @@ type Person struct { FrontTitle *string `json:"frontTitle" gorm:"size:50"` EndTitle *string `json:"endTitle" gorm:"size:50"` BirthDate *time.Time `json:"birthDate,omitempty"` + BirthPlace *string `json:"birthPlace,omitempty"` BirthRegency_Code *string `json:"birthRegency_code" gorm:"size:4"` BirthRegency *er.Regency `json:"birthRegency,omitempty" gorm:"foreignKey:BirthRegency_Code;references:Code"` Gender_Code *erp.GenderCode `json:"gender_code" gorm:"size:10"` From 550b629bcbc6148011d708de663aac9db47529ae Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Tue, 9 Dec 2025 14:24:07 +0700 Subject: [PATCH 39/42] feat/user: adjust some entities --- internal/domain/main-entities/registration/dto.go | 6 +++--- internal/domain/main-entities/user/dto.go | 3 ++- .../use-case/main-use-case/person-address/lib.go | 13 ++++++++++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/internal/domain/main-entities/registration/dto.go b/internal/domain/main-entities/registration/dto.go index b7837aee..ea842e95 100644 --- a/internal/domain/main-entities/registration/dto.go +++ b/internal/domain/main-entities/registration/dto.go @@ -23,9 +23,9 @@ type FilterDto struct { } type ReadDetailDto struct { - Id *uint16 `json:"id"` - Code *string `json:"code"` - Employee_Id *uint `json:"employee_id"` + Id *uint `json:"id"` + Employee_Id *uint `json:"employee_id"` + Includes string `json:"includes"` } type UpdateDto struct { diff --git a/internal/domain/main-entities/user/dto.go b/internal/domain/main-entities/user/dto.go index fd4b3f2c..acd189a0 100644 --- a/internal/domain/main-entities/user/dto.go +++ b/internal/domain/main-entities/user/dto.go @@ -24,8 +24,9 @@ type CreateDto struct { Employee *EmployeUpdateDto `json:"employee"` IHS_Number *string `json:"ihs_number" validate:"maxLength=20"` SIP_Number *string `json:"sip_number" validate:"maxLength=20"` - Unit_Code *string `json:"unit_code"` Infra_Code *string `json:"infra_code"` + Installation_Code *string `json:"installation_code"` + Unit_Code *string `json:"unit_code"` Specialist_Code *string `json:"specialist_code"` Subspecialist_Code *string `json:"subspecialist_code"` ContractPosition_Code erg.ContractPositionCode `json:"contractPosition_code" gorm:"not null;size:20"` diff --git a/internal/use-case/main-use-case/person-address/lib.go b/internal/use-case/main-use-case/person-address/lib.go index 94cbfa69..8a07aba6 100644 --- a/internal/use-case/main-use-case/person-address/lib.go +++ b/internal/use-case/main-use-case/person-address/lib.go @@ -2,6 +2,8 @@ package personaddress import ( e "simrs-vx/internal/domain/main-entities/person-address" + "strconv" + "strings" plh "simrs-vx/pkg/lib-helper" pl "simrs-vx/pkg/logger" @@ -179,10 +181,19 @@ func CreateOrUpdateBatch(input []e.UpdateDto, event *pl.Event, tx ...*gorm.DB) e } setData(&input[idx], &data[idx]) if err := dbx.Create(&data[idx]).Error; err != nil { + errMsg := err.Error() + additionalMessage := "" + // FK error + if strings.Contains(errMsg, "violates foreign key") { + pos := strings.Index(errMsg, "violates foreign key") + additionalMessage = ", " + errMsg[pos:] + } + // Got another errot, put it down below + // .... event.Status = "failed" event.ErrInfo = pl.ErrorInfo{ Code: "data-create-fail", - Detail: "Database insert failed", + Detail: "data insert failed at PersonAddres[" + strconv.Itoa(idx) + "]" + additionalMessage, Raw: err, } return pl.SetLogError(event, input) From 36e65abfac59ba7586208f029ad9e0df2f53d5fd Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Tue, 9 Dec 2025 14:24:28 +0700 Subject: [PATCH 40/42] feat/user: employee regisgtration flow --- .../main-use-case/registration/case.go | 276 ++++++++++++++++++ .../main-use-case/registration/helper.go | 22 ++ .../main-use-case/registration/lib.go | 179 ++++++++++++ .../registration/middleware-runner.go | 103 +++++++ .../main-use-case/registration/middleware.go | 9 + .../main-use-case/registration/tycovar.go | 44 +++ internal/use-case/main-use-case/user/case.go | 10 +- 7 files changed, 642 insertions(+), 1 deletion(-) create mode 100644 internal/use-case/main-use-case/registration/case.go create mode 100644 internal/use-case/main-use-case/registration/helper.go create mode 100644 internal/use-case/main-use-case/registration/lib.go create mode 100644 internal/use-case/main-use-case/registration/middleware-runner.go create mode 100644 internal/use-case/main-use-case/registration/middleware.go create mode 100644 internal/use-case/main-use-case/registration/tycovar.go diff --git a/internal/use-case/main-use-case/registration/case.go b/internal/use-case/main-use-case/registration/case.go new file mode 100644 index 00000000..06d48899 --- /dev/null +++ b/internal/use-case/main-use-case/registration/case.go @@ -0,0 +1,276 @@ +package doctor + +import ( + "strconv" + + dg "github.com/karincake/apem/db-gorm-pg" + d "github.com/karincake/dodol" + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/registration" + + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" +) + +const source = "doctor" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.Registration{} + + 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.Registration + var dataList []e.Registration + var metaList *e.MetaDto + var err error + + event := pl.Event{ + Feature: "ReadList", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "readList") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, data); err != nil { + return err + } + + if dataList, metaList, err = ReadListData(input, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "list-data", + "status": "fetched", + "page_number": strconv.Itoa(metaList.PageNumber), + "page_size": strconv.Itoa(metaList.PageSize), + "record_totalCount": strconv.Itoa(metaList.Count), + "record_currentCount": strconv.Itoa(len(dataList)), + }, + Data: e.ToResponseList(dataList), + }, nil +} + +func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { + var data *e.Registration + 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.Registration + 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.Registration + 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 + +} diff --git a/internal/use-case/main-use-case/registration/helper.go b/internal/use-case/main-use-case/registration/helper.go new file mode 100644 index 00000000..186e7f44 --- /dev/null +++ b/internal/use-case/main-use-case/registration/helper.go @@ -0,0 +1,22 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package doctor + +import ( + e "simrs-vx/internal/domain/main-entities/registration" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Registration) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.Employee_Id = inputSrc.Employee_Id + data.Installation_Code = inputSrc.Installation_Code +} diff --git a/internal/use-case/main-use-case/registration/lib.go b/internal/use-case/main-use-case/registration/lib.go new file mode 100644 index 00000000..7d28bb9a --- /dev/null +++ b/internal/use-case/main-use-case/registration/lib.go @@ -0,0 +1,179 @@ +package doctor + +import ( + "fmt" + e "simrs-vx/internal/domain/main-entities/registration" + + plh "simrs-vx/pkg/lib-helper" + 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.Registration, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.Registration{} + 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 { + return nil, plh.HandleCreateError(input, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Registration, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.Registration{} + pagination := gh.Pagination{} + count := int64(0) + meta := e.MetaDto{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + tx = tx. + Model(&e.Registration{}). + Scopes(gh.Preload(input.Includes)). + 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 + } + return nil, nil, plh.HandleListError(input, event, err) + } + + 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.Registration, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.Registration{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if input.Employee_Id != nil { + tx = tx.Where("\"Employee_Id\" = ?", *input.Employee_Id) + } + if input.Id != nil { + tx = tx.Where("\"Id\" = ?", input.Id) + } + fmt.Println(input.Includes) + if err := tx.Scopes(gh.Preload(input.Includes)).First(&data).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.Registration, 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.Registration, 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 GetIdByUserId(user_id *uint, event *pl.Event, dbx ...*gorm.DB) (*uint, error) { + pl.SetLogInfo(event, nil, "started", "DBGetIdByUserId") + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + var doctor_id uint + + err := tx.Model(&e.Registration{}). + Select("\"Doctor\".\"Id\" as doctor_id"). + Joins("JOIN \"Employee\" as e ON e.\"Id\" = \"Doctor\".\"Employee_Id\""). + Where("e.\"User_Id\" = ?", user_id). + Scan(&doctor_id).Error + + if err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-get-fail", + Detail: "Database get failed", + Raw: err, + } + return nil, pl.SetLogError(event, user_id) + } + + pl.SetLogInfo(event, nil, "complete") + return &doctor_id, nil +} diff --git a/internal/use-case/main-use-case/registration/middleware-runner.go b/internal/use-case/main-use-case/registration/middleware-runner.go new file mode 100644 index 00000000..d68f8de9 --- /dev/null +++ b/internal/use-case/main-use-case/registration/middleware-runner.go @@ -0,0 +1,103 @@ +package doctor + +import ( + e "simrs-vx/internal/domain/main-entities/registration" + 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.Registration) 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.Registration) 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.Registration) 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.Registration) 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.Registration) 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 +} diff --git a/internal/use-case/main-use-case/registration/middleware.go b/internal/use-case/main-use-case/registration/middleware.go new file mode 100644 index 00000000..b6bfc120 --- /dev/null +++ b/internal/use-case/main-use-case/registration/middleware.go @@ -0,0 +1,9 @@ +package doctor + +// example of middleware +// func init() { +// createPreMw = append(createPreMw, +// CreateMw{Name: "modif-input", Func: pm.ModifInput}, +// CreateMw{Name: "check-data", Func: pm.CheckData}, +// ) +// } diff --git a/internal/use-case/main-use-case/registration/tycovar.go b/internal/use-case/main-use-case/registration/tycovar.go new file mode 100644 index 00000000..bda8f4f8 --- /dev/null +++ b/internal/use-case/main-use-case/registration/tycovar.go @@ -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 doctor + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/registration" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.Registration, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.Registration, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.Registration, 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 diff --git a/internal/use-case/main-use-case/user/case.go b/internal/use-case/main-use-case/user/case.go index f6faec22..f360336a 100644 --- a/internal/use-case/main-use-case/user/case.go +++ b/internal/use-case/main-use-case/user/case.go @@ -13,6 +13,7 @@ import ( en "simrs-vx/internal/domain/main-entities/nurse" et "simrs-vx/internal/domain/main-entities/nutritionist" ep "simrs-vx/internal/domain/main-entities/pharmacist" + er "simrs-vx/internal/domain/main-entities/registration" esi "simrs-vx/internal/domain/main-entities/specialist-intern" e "simrs-vx/internal/domain/main-entities/user" @@ -26,6 +27,7 @@ import ( upa "simrs-vx/internal/use-case/main-use-case/person-address" upc "simrs-vx/internal/use-case/main-use-case/person-contact" up "simrs-vx/internal/use-case/main-use-case/pharmacist" + ur "simrs-vx/internal/use-case/main-use-case/registration" usi "simrs-vx/internal/use-case/main-use-case/specialist-intern" erc "simrs-vx/internal/domain/references/common" @@ -167,7 +169,13 @@ func Create(input e.CreateDto) (*d.Data, error) { return err } case ero.EPCReg, ero.EPCScr: - // do nothing + createSub := er.CreateDto{ + Employee_Id: employeeData.Id, + Installation_Code: *input.Installation_Code, + } + if _, err := ur.CreateData(createSub, &event, tx); err != nil { + return err + } default: return errors.New("invalid employee position") } From bd1d5bdde688c890d94d4375bbc2a40b81280aed Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Tue, 9 Dec 2025 15:50:17 +0700 Subject: [PATCH 41/42] feat/user: moved Registration to Registrator --- .../migrations/20251209084929.sql | 14 ++++++ cmd/main-migration/migrations/atlas.sum | 5 ++- .../{registration => registrator}/dto.go | 6 +-- .../{registration => registrator}/entity.go | 4 +- internal/domain/main-entities/user/dto.go | 44 ++++++++++++------- internal/interface/migration/main-entities.go | 4 +- .../main-use-case/authentication/helper.go | 11 +++++ .../{registration => registrator}/case.go | 18 ++++---- .../{registration => registrator}/helper.go | 6 +-- .../{registration => registrator}/lib.go | 32 +++++++------- .../middleware-runner.go | 14 +++--- .../middleware.go | 2 +- .../{registration => registrator}/tycovar.go | 10 ++--- internal/use-case/main-use-case/user/case.go | 4 +- 14 files changed, 105 insertions(+), 69 deletions(-) create mode 100644 cmd/main-migration/migrations/20251209084929.sql rename internal/domain/main-entities/{registration => registrator}/dto.go (92%) rename internal/domain/main-entities/{registration => registrator}/entity.go (93%) rename internal/use-case/main-use-case/{registration => registrator}/case.go (95%) rename internal/use-case/main-use-case/{registration => registrator}/helper.go (83%) rename internal/use-case/main-use-case/{registration => registrator}/lib.go (84%) rename internal/use-case/main-use-case/{registration => registrator}/middleware-runner.go (87%) rename internal/use-case/main-use-case/{registration => registrator}/middleware.go (91%) rename internal/use-case/main-use-case/{registration => registrator}/tycovar.go (75%) diff --git a/cmd/main-migration/migrations/20251209084929.sql b/cmd/main-migration/migrations/20251209084929.sql new file mode 100644 index 00000000..c67550ae --- /dev/null +++ b/cmd/main-migration/migrations/20251209084929.sql @@ -0,0 +1,14 @@ +-- Create "Registrator" table +CREATE TABLE "public"."Registrator" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Employee_Id" bigint NULL, + "Installation_Code" character varying(20) NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_Registrator_Employee" FOREIGN KEY ("Employee_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_Registrator_Installation" FOREIGN KEY ("Installation_Code") REFERENCES "public"."Installation" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Drop "Registration" table +DROP TABLE "public"."Registration"; diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index b828c76d..9c137d56 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:YJzcjq4dKD7GKlV0GJ88TOtZgg0JRDcVMlAe5ZYT9/U= +h1:B/ZKq0d90aqLf0EvQfND4cd8ZRHcmxfzKF2N1lpSeIs= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -157,4 +157,5 @@ h1:YJzcjq4dKD7GKlV0GJ88TOtZgg0JRDcVMlAe5ZYT9/U= 20251209025908.sql h1:p3kZA8kyEj+mQZSrdY3k2K1NojQzFJh/MlZJ0Oy6t/k= 20251209030538.sql h1:zltV6/Fu2zJW0/lVBl7MdnWuJcqNTUIRcqYYZ8Fi1wo= 20251209064304.sql h1:Mj6Zh+2b/4AkM1HjnJGjAs788kVN0UaL34jeaKQIjT0= -20251209070128.sql h1:rdqSlAmJS5XSc1w9dka3C53zwgibQwRIUqBcgmIPoTM= +20251209070128.sql h1:ip4wNCIF/UFQlNo6KpFG87/XA08aG3/Rf5zpxz3xioY= +20251209084929.sql h1:Z5higP1Ecq5UPWhrWZ5UCrxddMNqiJi8PbCNvGBE48A= diff --git a/internal/domain/main-entities/registration/dto.go b/internal/domain/main-entities/registrator/dto.go similarity index 92% rename from internal/domain/main-entities/registration/dto.go rename to internal/domain/main-entities/registrator/dto.go index ea842e95..5f0d4517 100644 --- a/internal/domain/main-entities/registration/dto.go +++ b/internal/domain/main-entities/registrator/dto.go @@ -1,4 +1,4 @@ -package doctor +package registrator import ( ecore "simrs-vx/internal/domain/base-entities/core" @@ -51,7 +51,7 @@ type ResponseDto struct { Installation *ei.Installation `json:"installation,omitempty"` } -func (d Registration) ToResponse() ResponseDto { +func (d Registrator) ToResponse() ResponseDto { resp := ResponseDto{ Employee_Id: d.Employee_Id, Employee: d.Employee, @@ -62,7 +62,7 @@ func (d Registration) ToResponse() ResponseDto { return resp } -func ToResponseList(data []Registration) []ResponseDto { +func ToResponseList(data []Registrator) []ResponseDto { resp := make([]ResponseDto, len(data)) for i, u := range data { resp[i] = u.ToResponse() diff --git a/internal/domain/main-entities/registration/entity.go b/internal/domain/main-entities/registrator/entity.go similarity index 93% rename from internal/domain/main-entities/registration/entity.go rename to internal/domain/main-entities/registrator/entity.go index 52d81f40..31998c1c 100644 --- a/internal/domain/main-entities/registration/entity.go +++ b/internal/domain/main-entities/registrator/entity.go @@ -1,4 +1,4 @@ -package doctor +package registrator import ( ecore "simrs-vx/internal/domain/base-entities/core" @@ -6,7 +6,7 @@ import ( ei "simrs-vx/internal/domain/main-entities/installation" ) -type Registration struct { +type Registrator struct { ecore.Main // adjust this according to the needs Employee_Id uint `json:"employee_id"` Employee *ee.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"` diff --git a/internal/domain/main-entities/user/dto.go b/internal/domain/main-entities/user/dto.go index acd189a0..bb030df3 100644 --- a/internal/domain/main-entities/user/dto.go +++ b/internal/domain/main-entities/user/dto.go @@ -13,23 +13,24 @@ import ( ) type CreateDto struct { - Name string `json:"name" validate:"maxLength=25"` - Password string `json:"password" validate:"maxLength=255"` + Name string `json:"name" validate:"required;maxLength=50"` + Password string `json:"password" validate:"required;maxLength=255"` + ContractPosition_Code erg.ContractPositionCode `json:"contractPosition_code" gorm:"not null;size:20" validate:"required"` Status_Code erc.UserStatusCode `json:"status_code" validate:"maxLength=10"` - Person_Id *uint `json:"-"` - Person *ep.UpdateDto `json:"person"` - PersonAddresses []epa.UpdateDto `json:"personAddresses"` - PersonContacts []epc.UpdateDto `json:"personContacts"` - Code *string `json:"code" validate:"maxLength=20"` - Employee *EmployeUpdateDto `json:"employee"` - IHS_Number *string `json:"ihs_number" validate:"maxLength=20"` - SIP_Number *string `json:"sip_number" validate:"maxLength=20"` - Infra_Code *string `json:"infra_code"` - Installation_Code *string `json:"installation_code"` - Unit_Code *string `json:"unit_code"` - Specialist_Code *string `json:"specialist_code"` - Subspecialist_Code *string `json:"subspecialist_code"` - ContractPosition_Code erg.ContractPositionCode `json:"contractPosition_code" gorm:"not null;size:20"` + + Employee *EmployeUpdateDto `json:"employee"` + Person *ep.UpdateDto `json:"person"` + PersonAddresses []epa.UpdateDto `json:"personAddresses"` + PersonContacts []epc.UpdateDto `json:"personContacts"` + Person_Id *uint `json:"-"` + Code *string `json:"code" validate:"maxLength=20"` + IHS_Number *string `json:"ihs_number" validate:"maxLength=20"` + SIP_Number *string `json:"sip_number" validate:"maxLength=20"` + Installation_Code *string `json:"installation_code"` + Unit_Code *string `json:"unit_code"` + Specialist_Code *string `json:"specialist_code"` + Subspecialist_Code *string `json:"subspecialist_code"` + Infra_Code *string `json:"infra_code"` } type ReadListDto struct { @@ -88,11 +89,20 @@ func (d *User) ToResponse() ResponseDto { type EmployeUpdateDto struct { Id uint `json:"id"` User_Id *uint `json:"-"` - Person_Id *uint `json:"-"` Division_Code *string `json:"division_code"` Number *string `json:"number" validate:"maxLength=20"` Position_Code erg.EmployeePositionCode `json:"position_code" validate:"maxLength=20"` Status_Code erc.ActiveStatusCode `json:"status_code" validate:"maxLength=10"` + Person_Id *uint `json:"-"` + // TODO: Extras + // Code *string `json:"code" validate:"maxLength=20"` + // IHS_Number *string `json:"ihs_number" validate:"maxLength=20"` + // SIP_Number *string `json:"sip_number" validate:"maxLength=20"` + // Installation_Code *string `json:"installation_code"` + // Unit_Code *string `json:"unit_code"` + // Specialist_Code *string `json:"specialist_code"` + // Subspecialist_Code *string `json:"subspecialist_code"` + // Infra_Code *string `json:"infra_code"` } func ToResponseList(data []User) []ResponseDto { diff --git a/internal/interface/migration/main-entities.go b/internal/interface/migration/main-entities.go index 147419e5..af3b35d3 100644 --- a/internal/interface/migration/main-entities.go +++ b/internal/interface/migration/main-entities.go @@ -96,7 +96,7 @@ import ( radiologymcuorder "simrs-vx/internal/domain/main-entities/radiology-mcu-order" radiologymcuorderitem "simrs-vx/internal/domain/main-entities/radiology-mcu-order-item" regency "simrs-vx/internal/domain/main-entities/regency" - registration "simrs-vx/internal/domain/main-entities/registration" + registrator "simrs-vx/internal/domain/main-entities/registrator" rehab "simrs-vx/internal/domain/main-entities/rehab" responsibledoctorhist "simrs-vx/internal/domain/main-entities/responsible-doctor-hist" resume "simrs-vx/internal/domain/main-entities/resume" @@ -149,7 +149,7 @@ func getMainEntities() []any { &proceduresrc.ProcedureSrc{}, &employee.Employee{}, &intern.Intern{}, - ®istration.Registration{}, + ®istrator.Registrator{}, &doctor.Doctor{}, &nurse.Nurse{}, &nutritionist.Nutritionist{}, diff --git a/internal/use-case/main-use-case/authentication/helper.go b/internal/use-case/main-use-case/authentication/helper.go index d8c54751..3a8154b6 100644 --- a/internal/use-case/main-use-case/authentication/helper.go +++ b/internal/use-case/main-use-case/authentication/helper.go @@ -26,6 +26,7 @@ import ( em "simrs-vx/internal/domain/main-entities/midwife" en "simrs-vx/internal/domain/main-entities/nurse" ep "simrs-vx/internal/domain/main-entities/pharmacist" + er "simrs-vx/internal/domain/main-entities/registrator" esp "simrs-vx/internal/domain/main-entities/specialist-position" essp "simrs-vx/internal/domain/main-entities/subspecialist-position" eup "simrs-vx/internal/domain/main-entities/unit-position" @@ -265,6 +266,16 @@ func populateRoles(user *eu.User, input eu.LoginDto, atClaims jwt.MapClaims, out } atClaims["pharmacist_code"] = empData.Code outputData["pharmacist_code"] = empData.Code + case erg.EPCReg: + empData := er.Registrator{} + dg.I.Where("\"Employee_Id\" = ?", employee.Id).First(&empData) + if empData.Id == 0 { + return d.FieldErrors{"authentication": d.FieldError{Code: "auth-noRegistrator", Message: pl.GenMessage("auth-noRegistrator")}} + } + atClaims["registrator_id"] = empData.Id + outputData["registrator_id"] = empData.Id + atClaims["installation_code"] = empData.Installation_Code + outputData["installation_code"] = empData.Installation_Code } errorGetPosition := d.FieldErrors{"authentication": d.FieldError{Code: "auth-getData-failed", Message: pl.GenMessage("auth-getData-failed")}} diff --git a/internal/use-case/main-use-case/registration/case.go b/internal/use-case/main-use-case/registrator/case.go similarity index 95% rename from internal/use-case/main-use-case/registration/case.go rename to internal/use-case/main-use-case/registrator/case.go index 06d48899..64313b97 100644 --- a/internal/use-case/main-use-case/registration/case.go +++ b/internal/use-case/main-use-case/registrator/case.go @@ -1,4 +1,4 @@ -package doctor +package registrator import ( "strconv" @@ -7,16 +7,16 @@ import ( d "github.com/karincake/dodol" "gorm.io/gorm" - e "simrs-vx/internal/domain/main-entities/registration" + e "simrs-vx/internal/domain/main-entities/registrator" pl "simrs-vx/pkg/logger" pu "simrs-vx/pkg/use-case-helper" ) -const source = "doctor" +const source = "registrator" func Create(input e.CreateDto) (*d.Data, error) { - data := e.Registration{} + data := e.Registrator{} event := pl.Event{ Feature: "Create", @@ -66,8 +66,8 @@ func Create(input e.CreateDto) (*d.Data, error) { } func ReadList(input e.ReadListDto) (*d.Data, error) { - var data *e.Registration - var dataList []e.Registration + var data *e.Registrator + var dataList []e.Registrator var metaList *e.MetaDto var err error @@ -119,7 +119,7 @@ func ReadList(input e.ReadListDto) (*d.Data, error) { } func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { - var data *e.Registration + var data *e.Registrator var err error event := pl.Event{ @@ -167,7 +167,7 @@ func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { func Update(input e.UpdateDto) (*d.Data, error) { rdDto := e.ReadDetailDto{Id: input.Id} - var data *e.Registration + var data *e.Registrator var err error event := pl.Event{ @@ -223,7 +223,7 @@ func Update(input e.UpdateDto) (*d.Data, error) { func Delete(input e.DeleteDto) (*d.Data, error) { rdDto := e.ReadDetailDto{Id: &input.Id} - var data *e.Registration + var data *e.Registrator var err error event := pl.Event{ diff --git a/internal/use-case/main-use-case/registration/helper.go b/internal/use-case/main-use-case/registrator/helper.go similarity index 83% rename from internal/use-case/main-use-case/registration/helper.go rename to internal/use-case/main-use-case/registrator/helper.go index 186e7f44..68482b0b 100644 --- a/internal/use-case/main-use-case/registration/helper.go +++ b/internal/use-case/main-use-case/registrator/helper.go @@ -2,13 +2,13 @@ DESCRIPTION: Any functions that are used internally by the use-case */ -package doctor +package registrator import ( - e "simrs-vx/internal/domain/main-entities/registration" + e "simrs-vx/internal/domain/main-entities/registrator" ) -func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Registration) { +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Registrator) { var inputSrc *e.CreateDto if inputT, ok := any(input).(*e.CreateDto); ok { inputSrc = inputT diff --git a/internal/use-case/main-use-case/registration/lib.go b/internal/use-case/main-use-case/registrator/lib.go similarity index 84% rename from internal/use-case/main-use-case/registration/lib.go rename to internal/use-case/main-use-case/registrator/lib.go index 7d28bb9a..694f9441 100644 --- a/internal/use-case/main-use-case/registration/lib.go +++ b/internal/use-case/main-use-case/registrator/lib.go @@ -1,8 +1,8 @@ -package doctor +package registrator import ( "fmt" - e "simrs-vx/internal/domain/main-entities/registration" + e "simrs-vx/internal/domain/main-entities/registrator" plh "simrs-vx/pkg/lib-helper" pl "simrs-vx/pkg/logger" @@ -13,10 +13,10 @@ import ( "gorm.io/gorm" ) -func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Registration, error) { +func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Registrator, error) { pl.SetLogInfo(event, nil, "started", "DBCreate") - data := e.Registration{} + data := e.Registrator{} setData(&input, &data) var tx *gorm.DB @@ -34,9 +34,9 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Registr return &data, nil } -func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Registration, *e.MetaDto, error) { +func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Registrator, *e.MetaDto, error) { pl.SetLogInfo(event, input, "started", "DBReadList") - data := []e.Registration{} + data := []e.Registrator{} pagination := gh.Pagination{} count := int64(0) meta := e.MetaDto{} @@ -49,7 +49,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Re } tx = tx. - Model(&e.Registration{}). + Model(&e.Registrator{}). Scopes(gh.Preload(input.Includes)). Scopes(gh.Filter(input.FilterDto)). Count(&count). @@ -71,9 +71,9 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Re return data, &meta, nil } -func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Registration, error) { +func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Registrator, error) { pl.SetLogInfo(event, input, "started", "DBReadDetail") - data := e.Registration{} + data := e.Registrator{} var tx *gorm.DB if len(dbx) > 0 { @@ -99,7 +99,7 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e return &data, nil } -func UpdateData(input e.UpdateDto, data *e.Registration, event *pl.Event, dbx ...*gorm.DB) error { +func UpdateData(input e.UpdateDto, data *e.Registrator, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, data, "started", "DBUpdate") setData(&input, data) @@ -124,7 +124,7 @@ func UpdateData(input e.UpdateDto, data *e.Registration, event *pl.Event, dbx .. return nil } -func DeleteData(data *e.Registration, event *pl.Event, dbx ...*gorm.DB) error { +func DeleteData(data *e.Registrator, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, data, "started", "DBDelete") var tx *gorm.DB if len(dbx) > 0 { @@ -156,13 +156,13 @@ func GetIdByUserId(user_id *uint, event *pl.Event, dbx ...*gorm.DB) (*uint, erro tx = dg.I } - var doctor_id uint + var registrator_id uint - err := tx.Model(&e.Registration{}). - Select("\"Doctor\".\"Id\" as doctor_id"). + err := tx.Model(&e.Registrator{}). + Select("\"Doctor\".\"Id\" as registrator_id"). Joins("JOIN \"Employee\" as e ON e.\"Id\" = \"Doctor\".\"Employee_Id\""). Where("e.\"User_Id\" = ?", user_id). - Scan(&doctor_id).Error + Scan(®istrator_id).Error if err != nil { event.Status = "failed" @@ -175,5 +175,5 @@ func GetIdByUserId(user_id *uint, event *pl.Event, dbx ...*gorm.DB) (*uint, erro } pl.SetLogInfo(event, nil, "complete") - return &doctor_id, nil + return ®istrator_id, nil } diff --git a/internal/use-case/main-use-case/registration/middleware-runner.go b/internal/use-case/main-use-case/registrator/middleware-runner.go similarity index 87% rename from internal/use-case/main-use-case/registration/middleware-runner.go rename to internal/use-case/main-use-case/registrator/middleware-runner.go index d68f8de9..e0488ca7 100644 --- a/internal/use-case/main-use-case/registration/middleware-runner.go +++ b/internal/use-case/main-use-case/registrator/middleware-runner.go @@ -1,7 +1,7 @@ -package doctor +package registrator import ( - e "simrs-vx/internal/domain/main-entities/registration" + e "simrs-vx/internal/domain/main-entities/registrator" pl "simrs-vx/pkg/logger" pu "simrs-vx/pkg/use-case-helper" @@ -23,7 +23,7 @@ func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner { } // ExecuteCreateMiddleware executes create middleware -func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.Registration) error { +func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.Registrator) error { for _, middleware := range middlewares { logData := pu.GetLogData(input, data) @@ -38,7 +38,7 @@ func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e return nil } -func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.Registration) error { +func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.Registrator) error { for _, middleware := range middlewares { logData := pu.GetLogData(input, data) @@ -53,7 +53,7 @@ func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, inpu return nil } -func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Registration) error { +func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Registrator) error { for _, middleware := range middlewares { logData := pu.GetLogData(input, data) @@ -68,7 +68,7 @@ func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, return nil } -func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Registration) error { +func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Registrator) error { for _, middleware := range middlewares { logData := pu.GetLogData(input, data) @@ -83,7 +83,7 @@ func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, inpu return nil } -func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Registration) error { +func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Registrator) error { for _, middleware := range middlewares { logData := pu.GetLogData(input, data) diff --git a/internal/use-case/main-use-case/registration/middleware.go b/internal/use-case/main-use-case/registrator/middleware.go similarity index 91% rename from internal/use-case/main-use-case/registration/middleware.go rename to internal/use-case/main-use-case/registrator/middleware.go index b6bfc120..c47ed8e0 100644 --- a/internal/use-case/main-use-case/registration/middleware.go +++ b/internal/use-case/main-use-case/registrator/middleware.go @@ -1,4 +1,4 @@ -package doctor +package registrator // example of middleware // func init() { diff --git a/internal/use-case/main-use-case/registration/tycovar.go b/internal/use-case/main-use-case/registrator/tycovar.go similarity index 75% rename from internal/use-case/main-use-case/registration/tycovar.go rename to internal/use-case/main-use-case/registrator/tycovar.go index bda8f4f8..565e186f 100644 --- a/internal/use-case/main-use-case/registration/tycovar.go +++ b/internal/use-case/main-use-case/registrator/tycovar.go @@ -6,27 +6,27 @@ 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 doctor +package registrator import ( "gorm.io/gorm" - e "simrs-vx/internal/domain/main-entities/registration" + e "simrs-vx/internal/domain/main-entities/registrator" ) type createMw struct { Name string - Func func(input *e.CreateDto, data *e.Registration, tx *gorm.DB) error + Func func(input *e.CreateDto, data *e.Registrator, tx *gorm.DB) error } type readListMw struct { Name string - Func func(input *e.ReadListDto, data *e.Registration, tx *gorm.DB) error + Func func(input *e.ReadListDto, data *e.Registrator, tx *gorm.DB) error } type readDetailMw struct { Name string - Func func(input *e.ReadDetailDto, data *e.Registration, tx *gorm.DB) error + Func func(input *e.ReadDetailDto, data *e.Registrator, tx *gorm.DB) error } type UpdateMw = readDetailMw diff --git a/internal/use-case/main-use-case/user/case.go b/internal/use-case/main-use-case/user/case.go index f360336a..1ea8c6ea 100644 --- a/internal/use-case/main-use-case/user/case.go +++ b/internal/use-case/main-use-case/user/case.go @@ -13,7 +13,7 @@ import ( en "simrs-vx/internal/domain/main-entities/nurse" et "simrs-vx/internal/domain/main-entities/nutritionist" ep "simrs-vx/internal/domain/main-entities/pharmacist" - er "simrs-vx/internal/domain/main-entities/registration" + er "simrs-vx/internal/domain/main-entities/registrator" esi "simrs-vx/internal/domain/main-entities/specialist-intern" e "simrs-vx/internal/domain/main-entities/user" @@ -27,7 +27,7 @@ import ( upa "simrs-vx/internal/use-case/main-use-case/person-address" upc "simrs-vx/internal/use-case/main-use-case/person-contact" up "simrs-vx/internal/use-case/main-use-case/pharmacist" - ur "simrs-vx/internal/use-case/main-use-case/registration" + ur "simrs-vx/internal/use-case/main-use-case/registrator" usi "simrs-vx/internal/use-case/main-use-case/specialist-intern" erc "simrs-vx/internal/domain/references/common" From aced63686fe5ef5065d2244700c0c7a30349cd4e Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Wed, 10 Dec 2025 06:29:49 +0700 Subject: [PATCH 42/42] feat/dockerize: finsihed --- Dockerfile-main-api | 1 + Dockerfile-simgos-sync-api | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 Dockerfile-simgos-sync-api diff --git a/Dockerfile-main-api b/Dockerfile-main-api index 821cd4a2..0c75acfa 100644 --- a/Dockerfile-main-api +++ b/Dockerfile-main-api @@ -9,4 +9,5 @@ FROM alpine:latest WORKDIR /app COPY --from=builder /src/cmd/main-api/main-api . COPY --from=builder /src/cmd/main-api/config.yml . +EXPOSE 8000 CMD ["./main-api"] diff --git a/Dockerfile-simgos-sync-api b/Dockerfile-simgos-sync-api new file mode 100644 index 00000000..35660a2f --- /dev/null +++ b/Dockerfile-simgos-sync-api @@ -0,0 +1,13 @@ +FROM golang:1.24.10 AS builder +WORKDIR /src +COPY go.mod go.sum ./ +RUN go mod download +COPY . . +RUN CGO_ENABLED=0 GOOS=linux go build -o ./cmd/simgos-sync-api/simgos-sync-api ./cmd/simgos-sync-api/main.go + +FROM alpine:latest +WORKDIR /app +COPY --from=builder /src/cmd/simgos-sync-api/simgos-sync-api . +COPY --from=builder /src/cmd/simgos-sync-api/config.yml . +EXPOSE 8000 +CMD ["./simgos-sync-api"]