From 3e9850101732bb3d1bdca06fb1b6978cf8ff0067 Mon Sep 17 00:00:00 2001 From: ahdan15 Date: Fri, 25 Apr 2025 08:48:15 +0700 Subject: [PATCH] servicemongo --- internal/database/database.go | 27 ++++- internal/server/routes.go | 8 ++ pkg/database/mongo/database.go | 13 +++ pkg/database/mongo/patient.go | 41 +++++++ pkg/database/satu_data/database.go | 4 +- pkg/handlers/Patient/patient.go | 72 +++++++++++++ pkg/models/patient/patient.go | 167 +++++++++++++++++++++++++++++ 7 files changed, 326 insertions(+), 6 deletions(-) create mode 100644 pkg/database/mongo/database.go create mode 100644 pkg/database/mongo/patient.go create mode 100644 pkg/handlers/Patient/patient.go create mode 100644 pkg/models/patient/patient.go diff --git a/internal/database/database.go b/internal/database/database.go index 2ba5113..0afe5e1 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -52,8 +52,29 @@ var ( ) func New(database ...string) Service { - // Reuse Connection + mongoDBName := os.Getenv("MONGODB_DEV_MASTER") + if len(database) > 0 { + mongoDBName = database[0] + } if dbInstance != nil { + if database != nil { + mongoURI := fmt.Sprintf("mongodb://%s:%s@%s:%s/%s?authSource=admin", + userMongo, passMongo, hostMongo, portMongo, mongoDBName) + log.Println("Connecting to MongoDB...") + log.Println(mongoURI) + clientOptions := options.Client().ApplyURI(mongoURI) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + client, err := mongo.Connect(ctx, clientOptions) + if err == nil { + log.Println("Connected to MongoDB") + } + if err = client.Ping(ctx, readpref.Primary()); err != nil { + log.Println("Failed to connect to MongoDB!!!") + log.Fatalf("Failed to connect to database: %v", err) + } + dbInstance.mongoDB = client.Database(mongoDBName) + } return dbInstance } simrs := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable TimeZone=Asia/Jakarta", hostSimrs, userNameSimrs, passwordSimrs, dbNameSimrs, portSimrs) @@ -72,10 +93,6 @@ func New(database ...string) Service { } else { log.Println("Successfully connected to the database") } - mongoDBName := os.Getenv("MONGODB_DEV_MASTER") - if len(database) > 0 { - mongoDBName = database[0] - } mongoURI := fmt.Sprintf("mongodb://%s:%s@%s:%s/%s?authSource=admin", userMongo, passMongo, hostMongo, portMongo, database) var client *mongo.Client diff --git a/internal/server/routes.go b/internal/server/routes.go index 2782a32..2ca1909 100644 --- a/internal/server/routes.go +++ b/internal/server/routes.go @@ -1,6 +1,7 @@ package server import ( + patientHandler "api-poliklinik/pkg/handlers/Patient" datapoliklinikHandler "api-poliklinik/pkg/handlers/Poliklinik" datapractitionerHandler "api-poliklinik/pkg/handlers/Practitioner" "github.com/gin-contrib/cors" @@ -25,6 +26,13 @@ func (s *Server) RegisterRoutes() http.Handler { { Practitioner.GET("/getdata", datapractitionerHandler.GetDataPractitioner) } + + patient := v1.Group("/patient") + { + patient.POST("/insertpatient", patientHandler.InsertPatient) + patient.GET("/getallpatient", patientHandler.GetAllPatient) + } + r.Use(cors.New(cors.Config{ AllowOrigins: []string{"*"}, // or specific domains like "http://example.com" AllowMethods: []string{"GET", "POST", "PUT", "DELETE"}, diff --git a/pkg/database/mongo/database.go b/pkg/database/mongo/database.go new file mode 100644 index 0000000..4cebe32 --- /dev/null +++ b/pkg/database/mongo/database.go @@ -0,0 +1,13 @@ +package mongo + +import ( + "go.mongodb.org/mongo-driver/mongo" +) + +type DatabaseService struct { + DBMongo *mongo.Database +} + +func NewDatabaseServiceMongo(db *mongo.Database) *DatabaseService { + return &DatabaseService{DBMongo: db} +} diff --git a/pkg/database/mongo/patient.go b/pkg/database/mongo/patient.go new file mode 100644 index 0000000..eedd4dc --- /dev/null +++ b/pkg/database/mongo/patient.go @@ -0,0 +1,41 @@ +package mongo + +import ( + "api-poliklinik/pkg/models/patient" + "context" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo/options" + "log" + "time" +) + +func (s *DatabaseService) InsertPatient(req *patient.Patient) error { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + _, err := s.DBMongo.Collection("patient").InsertOne(ctx, req) + if err != nil { + log.Println(err) + return err + } + return nil +} + +func (s *DatabaseService) GetAllDataPatient(limit int64, skip int64) ([]*patient.Patient, error) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + findOptions := options.Find() + findOptions.SetLimit(limit) + findOptions.SetSkip(skip) + + dataUser, err := s.DBMongo.Collection("patient").Find(ctx, bson.D{}, findOptions) + if err != nil { + log.Println(err) + } + var users []*patient.Patient + err = dataUser.All(ctx, &users) + if err != nil { + log.Println(err) + return nil, err + } + return users, nil +} diff --git a/pkg/database/satu_data/database.go b/pkg/database/satu_data/database.go index de5f3cf..09773b0 100644 --- a/pkg/database/satu_data/database.go +++ b/pkg/database/satu_data/database.go @@ -1,6 +1,8 @@ package satu_data -import "gorm.io/gorm" +import ( + "gorm.io/gorm" +) type DatabaseService struct { DB *gorm.DB diff --git a/pkg/handlers/Patient/patient.go b/pkg/handlers/Patient/patient.go new file mode 100644 index 0000000..4014d73 --- /dev/null +++ b/pkg/handlers/Patient/patient.go @@ -0,0 +1,72 @@ +package Patient + +import ( + "api-poliklinik/internal/database" + "api-poliklinik/pkg/database/mongo" + "api-poliklinik/pkg/models/patient" + "github.com/gin-gonic/gin" + "net/http" + "os" + "strconv" + "time" +) + +func InsertPatient(c *gin.Context) { + local := os.Getenv("MONGODB_DEV_LOCAL") + db := database.New(local).GetMongoDB() + if db == nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": "Database connection failed"}) + return + } + mongoDB := mongo.NewDatabaseServiceMongo(db) + var req *patient.Patient + err := c.Bind(&req) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": err.Error()}) + return + } + + dateCreated := time.Now().Format("2006-01-02 15:04:05") + req.ResourceType = "Patient" + req.CreatedAt = dateCreated + + errInsert := mongoDB.InsertPatient(req) + if errInsert != nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": errInsert.Error()}) + return + } + c.JSON(http.StatusOK, gin.H{"message": "Patient successfully inserted"}) +} + +func GetAllPatient(c *gin.Context) { + local := os.Getenv("MONGODB_DEV_LOCAL") + db := database.New(local).GetMongoDB() + if db == nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": "Database connection failed"}) + return + } + + // Default values + limit := int64(10) + skip := int64(0) + + // Ambil dari query jika tersedia + if l := c.Query("limit"); l != "" { + if parsed, err := strconv.ParseInt(l, 10, 64); err == nil { + limit = parsed + } + } + if s := c.Query("skip"); s != "" { + if parsed, err := strconv.ParseInt(s, 10, 64); err == nil { + skip = parsed + } + } + + mongoDB := mongo.NewDatabaseServiceMongo(db) + dataPatient, errSelect := mongoDB.GetAllDataPatient(limit, skip) + if errSelect != nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": errSelect.Error()}) + return + } + c.JSON(http.StatusOK, dataPatient) +} diff --git a/pkg/models/patient/patient.go b/pkg/models/patient/patient.go new file mode 100644 index 0000000..fe81d03 --- /dev/null +++ b/pkg/models/patient/patient.go @@ -0,0 +1,167 @@ +package patient + +type Coding struct { + System string `bson:"system,omitempty"` + Version string `bson:"version,omitempty"` + Code string `bson:"code,omitempty"` + Display string `bson:"display,omitempty"` + UserSelected bool `bson:"userSelected,omitempty"` +} + +type Identifier struct { + Use string `bson:"use,omitempty"` + Type CodeableConcept `bson:"type,omitempty"` + System string `bson:"system,omitempty"` + Value string `bson:"value,omitempty"` + Period Period `bson:"period,omitempty"` + Assigner struct{} `bson:"assigner,omitempty"` +} + +type CodeableConcept struct { + Coding []Coding `bson:"coding,omitempty"` + Text string `bson:"text,omitempty"` +} + +type Period struct { + Start string `bson:"start,omitempty"` + End string `bson:"end,omitempty"` +} + +type ContactPoint struct { + System string `bson:"system,omitempty"` + Value string `bson:"value,omitempty"` + Use string `bson:"use,omitempty"` + Rank int `bson:"rank,omitempty"` + Period Period `bson:"period,omitempty"` +} + +type HumanName struct { + Use string `bson:"use,omitempty"` + Text string `bson:"text,omitempty"` + Family string `bson:"family,omitempty"` + Given []string `bson:"given,omitempty"` + Prefix []string `bson:"prefix,omitempty"` + Suffix []string `bson:"suffix,omitempty"` + Period Period `bson:"period,omitempty"` +} + +type Address struct { + Use string `bson:"use,omitempty"` + Type string `bson:"type,omitempty"` + Text string `bson:"text,omitempty"` + Line []string `bson:"line,omitempty"` + City string `bson:"city,omitempty"` + District string `bson:"district,omitempty"` + State string `bson:"state,omitempty"` + PostalCode string `bson:"postalCode,omitempty"` + Country string `bson:"country,omitempty"` + Period Period `bson:"period,omitempty"` +} + +type Organization struct { + Reference string `bson:"reference,omitempty"` +} + +type Contact struct { + Relationship []CodeableConcept `bson:"relationship,omitempty"` + Name []HumanName `bson:"name,omitempty"` + Telecom []ContactPoint `bson:"telecom,omitempty"` + Address Address `bson:"address,omitempty"` + Organization Organization `bson:"organization,omitempty"` + Gender string `bson:"gender,omitempty"` + Period Period `bson:"period,omitempty"` +} + +type Communication struct { + Language CodeableConcept `bson:"language,omitempty"` + Preferred bool `bson:"preferred,omitempty"` +} + +type ReqInsertCommunication struct { + Language Coding `bson:"language,omitempty"` + Preferred bool `bson:"preferred,omitempty"` +} + +type Link struct { + RelatePerson []RelatePerson `bson:"relatePerson,omitempty"` +} + +type RelatePerson struct { + Identifier []Identifier `bson:"identifier,omitempty"` + Active bool `bson:"active"` + Patient string `bson:"patient"` + Relationship CodeableConcept `bson:"relationship"` + Name []HumanName `bson:"name,omitempty"` + Telecom []ContactPoint `bson:"telecom,omitempty"` + Gender string `bson:"gender,omitempty"` + BirthDate string `bson:"birthDate,omitempty"` + Address []Address `bson:"address,omitempty"` + Photo string `bson:"photo,omitempty"` + Period Period `bson:"period,omitempty"` + Communication []Communication `bson:"communication,omitempty"` + Preferred bool `bson:"preferred"` +} + +type Deceased struct { + DeceasedBoolean bool `bson:"deceasedBoolean,omitempty"` + DeceasedDateTime string `bson:"deceasedDateTime,omitempty"` +} + +type MultipleBirth struct { + MultipleBirthBoolean bool `bson:"multipleBirthBoolean,omitempty"` + MultipleBirthInteger int `bson:"multipleBirthInteger,omitempty"` +} + +type Patient struct { + ResourceType string `bson:"resourceType"` + ID string `bson:"_id"` + Identifier []Identifier `bson:"identifier,omitempty"` + Active bool `bson:"active"` + Name []HumanName `bson:"name,omitempty"` + Telecom []ContactPoint `bson:"telecom,omitempty"` + Gender string `bson:"gender,omitempty"` + BirthPlace string `bson:"birthPlace,omitempty"` + BirthDate string `bson:"birthDate,omitempty"` + Address []Address `bson:"address,omitempty"` + MaritalStatus CodeableConcept `bson:"maritalStatus,omitempty"` + Job CodeableConcept `bson:"job,omitempty"` + Religion CodeableConcept `bson:"religion,omitempty"` + Tribe CodeableConcept `bson:"tribe,omitempty"` + Link Link `bson:"link,omitempty"` + Communication []Communication `bson:"communication,omitempty"` + Disability bool `bson:"disability,omitempty"` + National string `bson:"national,omitempty"` + Deceased Deceased `bson:"deceased,omitempty"` + MultipleBirth MultipleBirth `bson:"multipleBirth,omitempty"` + CreatedAt string `bson:"createdAt"` + UpdatedAt string `bson:"updatedAt"` +} + +type ReqInsertIdentifier struct { + Use string `bson:"use,omitempty"` + Type Coding `bson:"type,omitempty"` + System string `bson:"system,omitempty"` + Value string `bson:"value,omitempty"` + Period Period `bson:"period,omitempty"` +} + +type ReqInsertPatient struct { + Identifier []ReqInsertIdentifier `bson:"identifier,omitempty"` + Active bool `bson:"active"` + Name []HumanName `bson:"name,omitempty"` + Telecom []ContactPoint `bson:"telecom,omitempty"` + Gender string `bson:"gender,omitempty"` + BirthPlace string `bson:"birthPlace,omitempty"` + BirthDate string `bson:"birthDate,omitempty"` + Address []Address `bson:"address,omitempty"` + MaritalStatus []CodeableConcept `bson:"maritalStatus,omitempty"` + Job []CodeableConcept `bson:"job,omitempty"` + Religion []CodeableConcept `bson:"religion,omitempty"` + Tribe []CodeableConcept `bson:"tribe,omitempty"` + Link Link `bson:"link,omitempty"` + Communication []Communication `bson:"communication,omitempty"` + Disability bool `bson:"disability,omitempty"` + National string `bson:"national,omitempty"` + Deceased Deceased `bson:"deceased,omitempty"` + MultipleBirth MultipleBirth `bson:"multipleBirth,omitempty"` +}