From b3e19b5e575900177c51342ccab2d0fd41a706c1 Mon Sep 17 00:00:00 2001 From: renaldybrada Date: Thu, 5 Feb 2026 09:14:47 +0700 Subject: [PATCH] api reference diagnosa --- docs/docs.go | 82 ++++++++++++++++++- docs/swagger.json | 82 ++++++++++++++++++- docs/swagger.yaml | 57 ++++++++++++- internal/domain/reference/diagnosa/handler.go | 41 ++++++++++ internal/domain/reference/diagnosa/model.go | 30 +++++++ .../domain/reference/diagnosa/repository.go | 71 ++++++++++++++++ internal/domain/reference/diagnosa/routes.go | 17 ++++ internal/routes/routes.go | 2 + 8 files changed, 371 insertions(+), 11 deletions(-) create mode 100644 internal/domain/reference/diagnosa/handler.go create mode 100644 internal/domain/reference/diagnosa/model.go create mode 100644 internal/domain/reference/diagnosa/repository.go create mode 100644 internal/domain/reference/diagnosa/routes.go diff --git a/docs/docs.go b/docs/docs.go index cccd48c..03b04c6 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -136,6 +136,39 @@ const docTemplate = `{ } } }, + "/reference/diagnosa/": { + "get": { + "tags": [ + "Reference" + ], + "summary": "Get List Diagnosa", + "parameters": [ + { + "type": "string", + "description": "Search keyword", + "name": "search", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/diagnosa.DiagnosaModel" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/shared.BaseErrorResponse" + } + } + } + } + }, "/reference/dokter/": { "get": { "tags": [ @@ -325,9 +358,14 @@ const docTemplate = `{ "definitions": { "antrianoperasi.CreatePasienOperasiRequest": { "type": "object", + "required": [ + "diagnosisItems", + "tindakanItems" + ], "properties": { "diagnosisItems": { "type": "array", + "minItems": 1, "items": { "$ref": "#/definitions/antrianoperasi.DiagnosisItemRequest" } @@ -349,6 +387,7 @@ const docTemplate = `{ }, "tindakanItems": { "type": "array", + "minItems": 1, "items": { "$ref": "#/definitions/antrianoperasi.TindakanItemRequest" } @@ -357,6 +396,11 @@ const docTemplate = `{ }, "antrianoperasi.DiagnosisItemRequest": { "type": "object", + "required": [ + "diagnosa", + "jenisDiagnosa", + "kodeDiagnosa" + ], "properties": { "diagnosa": { "type": "string" @@ -388,6 +432,9 @@ const docTemplate = `{ }, "antrianoperasi.FormDataRequest": { "type": "object", + "required": [ + "nomorTelepon" + ], "properties": { "alamat": { "type": "string" @@ -406,6 +453,7 @@ const docTemplate = `{ }, "nomorTelepon": { "type": "array", + "minItems": 1, "items": { "type": "string" } @@ -422,7 +470,10 @@ const docTemplate = `{ "type": "object", "properties": { "diagnosa": { - "type": "string" + "type": "array", + "items": { + "type": "string" + } }, "id": { "type": "string" @@ -433,9 +484,6 @@ const docTemplate = `{ "kategori": { "type": "string" }, - "kodeDiagnosa": { - "type": "string" - }, "namaPasien": { "type": "string" }, @@ -465,11 +513,18 @@ const docTemplate = `{ }, "tglDaftar": { "type": "string" + }, + "tindakan": { + "type": "string" } } }, "antrianoperasi.RencanaOperasiRequest": { "type": "object", + "required": [ + "spesialis", + "subSpesialis" + ], "properties": { "kategoriOperasi": { "type": "integer" @@ -507,6 +562,11 @@ const docTemplate = `{ }, "antrianoperasi.TindakanItemRequest": { "type": "object", + "required": [ + "kodeTindakan", + "tindakan", + "tindakanTambahan" + ], "properties": { "kodeTindakan": { "type": "string" @@ -533,6 +593,20 @@ const docTemplate = `{ } } }, + "diagnosa.DiagnosaModel": { + "type": "object", + "properties": { + "jenisPenyakit": { + "type": "string" + }, + "kodeDiagnosa": { + "type": "string" + }, + "sebabPenyakit": { + "type": "string" + } + } + }, "dokter.DokterResponse": { "type": "object", "properties": { diff --git a/docs/swagger.json b/docs/swagger.json index 6021ab8..e42752f 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -130,6 +130,39 @@ } } }, + "/reference/diagnosa/": { + "get": { + "tags": [ + "Reference" + ], + "summary": "Get List Diagnosa", + "parameters": [ + { + "type": "string", + "description": "Search keyword", + "name": "search", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/diagnosa.DiagnosaModel" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/shared.BaseErrorResponse" + } + } + } + } + }, "/reference/dokter/": { "get": { "tags": [ @@ -319,9 +352,14 @@ "definitions": { "antrianoperasi.CreatePasienOperasiRequest": { "type": "object", + "required": [ + "diagnosisItems", + "tindakanItems" + ], "properties": { "diagnosisItems": { "type": "array", + "minItems": 1, "items": { "$ref": "#/definitions/antrianoperasi.DiagnosisItemRequest" } @@ -343,6 +381,7 @@ }, "tindakanItems": { "type": "array", + "minItems": 1, "items": { "$ref": "#/definitions/antrianoperasi.TindakanItemRequest" } @@ -351,6 +390,11 @@ }, "antrianoperasi.DiagnosisItemRequest": { "type": "object", + "required": [ + "diagnosa", + "jenisDiagnosa", + "kodeDiagnosa" + ], "properties": { "diagnosa": { "type": "string" @@ -382,6 +426,9 @@ }, "antrianoperasi.FormDataRequest": { "type": "object", + "required": [ + "nomorTelepon" + ], "properties": { "alamat": { "type": "string" @@ -400,6 +447,7 @@ }, "nomorTelepon": { "type": "array", + "minItems": 1, "items": { "type": "string" } @@ -416,7 +464,10 @@ "type": "object", "properties": { "diagnosa": { - "type": "string" + "type": "array", + "items": { + "type": "string" + } }, "id": { "type": "string" @@ -427,9 +478,6 @@ "kategori": { "type": "string" }, - "kodeDiagnosa": { - "type": "string" - }, "namaPasien": { "type": "string" }, @@ -459,11 +507,18 @@ }, "tglDaftar": { "type": "string" + }, + "tindakan": { + "type": "string" } } }, "antrianoperasi.RencanaOperasiRequest": { "type": "object", + "required": [ + "spesialis", + "subSpesialis" + ], "properties": { "kategoriOperasi": { "type": "integer" @@ -501,6 +556,11 @@ }, "antrianoperasi.TindakanItemRequest": { "type": "object", + "required": [ + "kodeTindakan", + "tindakan", + "tindakanTambahan" + ], "properties": { "kodeTindakan": { "type": "string" @@ -527,6 +587,20 @@ } } }, + "diagnosa.DiagnosaModel": { + "type": "object", + "properties": { + "jenisPenyakit": { + "type": "string" + }, + "kodeDiagnosa": { + "type": "string" + }, + "sebabPenyakit": { + "type": "string" + } + } + }, "dokter.DokterResponse": { "type": "object", "properties": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index ebd26db..26cddd8 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -5,6 +5,7 @@ definitions: diagnosisItems: items: $ref: '#/definitions/antrianoperasi.DiagnosisItemRequest' + minItems: 1 type: array dokterPelaksanaItems: items: @@ -19,7 +20,11 @@ definitions: tindakanItems: items: $ref: '#/definitions/antrianoperasi.TindakanItemRequest' + minItems: 1 type: array + required: + - diagnosisItems + - tindakanItems type: object antrianoperasi.DiagnosisItemRequest: properties: @@ -29,6 +34,10 @@ definitions: type: string kodeDiagnosa: type: string + required: + - diagnosa + - jenisDiagnosa + - kodeDiagnosa type: object antrianoperasi.DokterPelaksanaItemRequest: properties: @@ -56,24 +65,27 @@ definitions: nomorTelepon: items: type: string + minItems: 1 type: array tanggalLahir: type: string umur: type: string + required: + - nomorTelepon type: object antrianoperasi.PasienOperasi: properties: diagnosa: - type: string + items: + type: string + type: array id: type: string jenisKelamin: type: string kategori: type: string - kodeDiagnosa: - type: string namaPasien: type: string noKtp: @@ -94,6 +106,8 @@ definitions: type: string tglDaftar: type: string + tindakan: + type: string type: object antrianoperasi.RencanaOperasiRequest: properties: @@ -109,6 +123,9 @@ definitions: type: integer tanggalDaftar: type: string + required: + - spesialis + - subSpesialis type: object antrianoperasi.StatusPasienRequest: properties: @@ -127,6 +144,10 @@ definitions: type: string tindakanTambahan: type: string + required: + - kodeTindakan + - tindakan + - tindakanTambahan type: object dashboard.AntrianPerKategori: properties: @@ -137,6 +158,15 @@ definitions: kategori: type: string type: object + diagnosa.DiagnosaModel: + properties: + jenisPenyakit: + type: string + kodeDiagnosa: + type: string + sebabPenyakit: + type: string + type: object dokter.DokterResponse: properties: hfis_code: @@ -319,6 +349,27 @@ paths: summary: Get Antrian Per Kategori tags: - Dashboard + /reference/diagnosa/: + get: + parameters: + - description: Search keyword + in: query + name: search + type: string + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/diagnosa.DiagnosaModel' + type: array + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/shared.BaseErrorResponse' + summary: Get List Diagnosa + tags: + - Reference /reference/dokter/: get: parameters: diff --git a/internal/domain/reference/diagnosa/handler.go b/internal/domain/reference/diagnosa/handler.go new file mode 100644 index 0000000..eac431d --- /dev/null +++ b/internal/domain/reference/diagnosa/handler.go @@ -0,0 +1,41 @@ +package diagnosa + +import ( + "net/http" + + baseResponse "antrian-operasi/internal/shared" + + "github.com/gin-gonic/gin" +) + +type DiagnosaHandler struct { + repo IDiagnosaRepository +} + +func NewDiagnosaHandler(repo IDiagnosaRepository) DiagnosaHandler { + return DiagnosaHandler{repo} +} + +// List Diagnosa godoc +// @Summary Get List Diagnosa +// @Tags Reference +// @Param search query string false "Search keyword" +// @Success 200 {object} []DiagnosaModel +// @Failure 500 {object} shared.BaseErrorResponse +// @Router /reference/diagnosa/ [get] +func (h DiagnosaHandler) ListDiagnosa(c *gin.Context) { + list, err := h.repo.SearchableListDiagnosa(c) + if err != nil { + errorResponse := baseResponse.BaseErrorResponse{ + Success: false, + Code: 500, + Message: err.Error(), + } + c.JSON(http.StatusInternalServerError, errorResponse) + return + } + + response := baseResponse.ToBaseResponse(list.ToResponseList(), true, 200, "success get diagnosa") + + c.JSON(http.StatusOK, response) +} diff --git a/internal/domain/reference/diagnosa/model.go b/internal/domain/reference/diagnosa/model.go new file mode 100644 index 0000000..854bbe7 --- /dev/null +++ b/internal/domain/reference/diagnosa/model.go @@ -0,0 +1,30 @@ +package diagnosa + +type DiagnosaModel struct { + KodeDiagnosa string `db:"icd_code"` + JenisPenyakit string `db:"jenis_penyakit"` + SebabPenyakit *string `db:"sebabpenyakit"` +} + +type DiagnosaResponse struct { + KodeDiagnosa string `db:"kode_diagnosa"` + Diagnosa string `db:"diagnosa"` +} + +func (m DiagnosaModel) ToResponse() DiagnosaResponse { + return DiagnosaResponse{ + KodeDiagnosa: m.KodeDiagnosa, + Diagnosa: m.JenisPenyakit, + } +} + +type ListDiagnosaModel []DiagnosaModel + +func (rows ListDiagnosaModel) ToResponseList() []DiagnosaResponse { + result := make([]DiagnosaResponse, 0, len(rows)) + for _, item := range rows { + result = append(result, item.ToResponse()) + } + + return result +} diff --git a/internal/domain/reference/diagnosa/repository.go b/internal/domain/reference/diagnosa/repository.go new file mode 100644 index 0000000..75ba706 --- /dev/null +++ b/internal/domain/reference/diagnosa/repository.go @@ -0,0 +1,71 @@ +package diagnosa + +import ( + "antrian-operasi/internal/database" + + queryUtils "antrian-operasi/internal/utils/query" + + "github.com/gin-gonic/gin" +) + +const DB_NAME = "db_simrs" +const TBL_NAME = "icd" + +type IDiagnosaRepository interface { + SearchableListDiagnosa(c *gin.Context) (ListDiagnosaModel, error) +} + +type diagnosaRepo struct { + queryBuilder *queryUtils.QueryBuilder + db database.Service +} + +func NewRepository(dbService database.Service) IDiagnosaRepository { + queryBuilder := queryUtils.NewQueryBuilder(queryUtils.DBTypePostgreSQL). + SetAllowedColumns([]string{ + "icd_code", "jenis_penyakit", "sebabpenyakit", + }). + SetSecurityOptions(false, 100) + + return diagnosaRepo{ + queryBuilder: queryBuilder, + db: dbService, + } +} + +func (r diagnosaRepo) SearchableListDiagnosa(c *gin.Context) (ListDiagnosaModel, error) { + var result ListDiagnosaModel + search := c.Query("search") + + query := queryUtils.DynamicQuery{ + From: TBL_NAME, + Fields: []queryUtils.SelectField{ + {Expression: "icd_code"}, + {Expression: "jenis_penyakit"}, + {Expression: "sebabpenyakit"}, + }, + Limit: 10, + } + + if search != "" { + searchFilters := []queryUtils.DynamicFilter{ + {Column: "icd_code", Operator: queryUtils.OpILike, Value: "%" + search + "%"}, + {Column: "jenis_penyakit", Operator: queryUtils.OpILike, Value: "%" + search + "%"}, + {Column: "sebabpenyakit", Operator: queryUtils.OpILike, Value: "%" + search + "%"}, + } + query.Filters = append(query.Filters, queryUtils.FilterGroup{Filters: searchFilters, LogicOp: "OR"}) + } + + dbconn, err := r.db.GetSQLXDB(DB_NAME) + if err != nil { + return result, err + } + + err = r.queryBuilder.ExecuteQuery( + c, dbconn, query, &result) + if err != nil { + return result, err + } + + return result, nil +} diff --git a/internal/domain/reference/diagnosa/routes.go b/internal/domain/reference/diagnosa/routes.go new file mode 100644 index 0000000..a3d426e --- /dev/null +++ b/internal/domain/reference/diagnosa/routes.go @@ -0,0 +1,17 @@ +package diagnosa + +import ( + "antrian-operasi/internal/database" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(r *gin.RouterGroup, dbService database.Service) { + diagnosaRepo := NewRepository(dbService) + DiagnosaHandler := NewDiagnosaHandler(diagnosaRepo) + + kategori := r.Group("/diagnosa") + { + kategori.GET("", DiagnosaHandler.ListDiagnosa) + } +} diff --git a/internal/routes/routes.go b/internal/routes/routes.go index 03b67af..1dc754b 100644 --- a/internal/routes/routes.go +++ b/internal/routes/routes.go @@ -5,6 +5,7 @@ import ( "antrian-operasi/internal/database" antrianoperasi "antrian-operasi/internal/domain/antrian_operasi" "antrian-operasi/internal/domain/dashboard" + "antrian-operasi/internal/domain/reference/diagnosa" "antrian-operasi/internal/domain/reference/dokter" "antrian-operasi/internal/domain/reference/kategori" "antrian-operasi/internal/domain/reference/pasien" @@ -42,6 +43,7 @@ func RegisterRoutes(cfg *config.Config, dbService database.Service) *gin.Engine spesialis.RegisterRoutes(reference, dbService) dokter.RegisterRoutes(reference, dbService) pasien.RegisterRoutes(reference, dbService) + diagnosa.RegisterRoutes(reference, dbService) } dboard := api.Group("dashboard") {