clear general tool

This commit is contained in:
2025-08-28 18:03:38 +07:00
parent f060a01b98
commit af9d04de07
22 changed files with 5349 additions and 2154 deletions

View File

@@ -215,67 +215,6 @@ const docTemplate = `{
}
}
},
"/api/v1/bpjs/Peserta/nik/{nik}/tglSEP/{tglSEP}": {
"get": {
"description": "Search participant data based on Population NIK and service date",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"BPJS"
],
"summary": "Get participant data by NIK",
"parameters": [
{
"type": "string",
"description": "NIK KTP",
"name": "nik",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Service date/SEP date (format: yyyy-MM-dd)",
"name": "tglSEP",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Participant data",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"400": {
"description": "Bad request",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"404": {
"description": "Participant not found",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "Internal server error",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/api/v1/retribusi/{id}": {
"get": {
"description": "Returns a single retribusi by ID",
@@ -761,9 +700,14 @@ const docTemplate = `{
}
}
},
"/sep": {
"put": {
"description": "Update Surat Eligibilitas Peserta",
"/peserta/:nokartu": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Get participant eligibility information",
"consumes": [
"application/json"
],
@@ -771,89 +715,49 @@ const docTemplate = `{
"application/json"
],
"tags": [
"SEP"
"vclaim",
"peserta"
],
"summary": "Update SEP",
"summary": "Get Peserta data",
"parameters": [
{
"description": "SEP update request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api-service_internal_models_vclaim.SepPutRequest"
}
"type": "string",
"description": "Nokartu",
"name": "nokartu",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "SEP updated successfully",
"description": "OK",
"schema": {
"$ref": "#/definitions/api-service_internal_models_vclaim.SepResponse"
"$ref": "#/definitions/reference.PesertaResponse"
}
},
"400": {
"description": "Invalid request",
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/gin.H"
"$ref": "#/definitions/reference.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/gin.H"
}
}
}
},
"post": {
"description": "Create a new Surat Eligibilitas Peserta",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"SEP"
],
"summary": "Create a new SEP",
"parameters": [
{
"description": "SEP creation request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api-service_internal_models_vclaim.SepPostRequest"
}
}
],
"responses": {
"200": {
"description": "SEP created successfully",
"schema": {
"$ref": "#/definitions/api-service_internal_models_vclaim.SepResponse"
}
},
"400": {
"description": "Invalid request",
"schema": {
"$ref": "#/definitions/gin.H"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/gin.H"
"$ref": "#/definitions/reference.ErrorResponse"
}
}
}
}
},
"/sep/{noSep}": {
"/rujukan/:norujukan": {
"get": {
"description": "Retrieve a Surat Eligibilitas Peserta by noSep",
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Get referral information",
"consumes": [
"application/json"
],
@@ -861,41 +765,206 @@ const docTemplate = `{
"application/json"
],
"tags": [
"SEP"
"vclaim",
"rujukan"
],
"summary": "Get SEP",
"summary": "Get Rujukan data",
"parameters": [
{
"type": "string",
"description": "No SEP",
"name": "noSep",
"description": "Norujukan",
"name": "norujukan",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Data SEP retrieved successfully",
"description": "OK",
"schema": {
"$ref": "#/definitions/api-service_internal_models_vclaim.SepResponse"
"$ref": "#/definitions/reference.RujukanResponse"
}
},
"400": {
"description": "Invalid request",
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/gin.H"
"$ref": "#/definitions/reference.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/gin.H"
"$ref": "#/definitions/reference.ErrorResponse"
}
}
}
}
},
"/sep": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Manage SEP (Surat Eligibilitas Peserta)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"vclaim",
"sep"
],
"summary": "Create Sep",
"parameters": [
{
"description": "Sep data",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/reference.SEPRequest"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/reference.SEPResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/reference.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/reference.ErrorResponse"
}
}
}
}
},
"/sep/:nosep": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Manage SEP (Surat Eligibilitas Peserta)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"vclaim",
"sep"
],
"summary": "Get Sep data",
"parameters": [
{
"type": "string",
"description": "Nosep",
"name": "nosep",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/reference.SEPResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/reference.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/reference.ErrorResponse"
}
}
}
},
"put": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Manage SEP (Surat Eligibilitas Peserta)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"vclaim",
"sep"
],
"summary": "Update Sep",
"parameters": [
{
"type": "string",
"description": "Nosep",
"name": "nosep",
"in": "path",
"required": true
},
{
"description": "Sep data",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/reference.SEPRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/reference.SEPResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/reference.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/reference.ErrorResponse"
}
}
}
},
"delete": {
"description": "Delete a Surat Eligibilitas Peserta by noSep",
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Manage SEP (Surat Eligibilitas Peserta)",
"consumes": [
"application/json"
],
@@ -903,42 +972,36 @@ const docTemplate = `{
"application/json"
],
"tags": [
"SEP"
"vclaim",
"sep"
],
"summary": "Delete SEP",
"summary": "Delete Sep",
"parameters": [
{
"type": "string",
"description": "No SEP",
"name": "noSep",
"description": "Nosep",
"name": "nosep",
"in": "path",
"required": true
},
{
"type": "string",
"description": "User",
"name": "user",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "SEP deleted successfully",
"description": "OK",
"schema": {
"$ref": "#/definitions/api-service_internal_models_vclaim.SepResponse"
"$ref": "#/definitions/reference.BaseResponse"
}
},
"400": {
"description": "Invalid request",
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/gin.H"
"$ref": "#/definitions/reference.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/gin.H"
"$ref": "#/definitions/reference.ErrorResponse"
}
}
}
@@ -1371,27 +1434,403 @@ const docTemplate = `{
}
}
},
"api-service_internal_models_vclaim.SepPostRequest": {
"type": "object"
},
"api-service_internal_models_vclaim.SepPutRequest": {
"type": "object"
},
"api-service_internal_models_vclaim.SepResponse": {
"reference.BaseResponse": {
"type": "object",
"properties": {
"data": {
"message": {
"type": "string"
},
"request_id": {
"type": "string"
},
"status": {
"type": "string"
},
"timestamp": {
"type": "string"
}
}
},
"reference.ErrorResponse": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"errors": {
"type": "object",
"additionalProperties": true
},
"message": {
"type": "string"
},
"request_id": {
"type": "string"
},
"status": {
"type": "string"
}
}
},
"gin.H": {
"reference.PesertaData": {
"type": "object",
"additionalProperties": {}
"properties": {
"aktif": {
"type": "string"
},
"asuransi": {
"type": "string"
},
"cob": {
"type": "string"
},
"kdCabang": {
"type": "string"
},
"kdJnsPst": {
"type": "string"
},
"ketAktif": {
"type": "string"
},
"klsRawat": {
"type": "string"
},
"mr": {
"type": "object",
"properties": {
"nmMR": {
"type": "string"
},
"noMR": {
"type": "string"
},
"sex": {
"type": "string"
},
"tglLahir": {
"type": "string"
},
"tglMeninggal": {
"type": "string"
}
}
},
"nama": {
"type": "string"
},
"nik": {
"type": "string"
},
"nmCabang": {
"type": "string"
},
"nmJnsPst": {
"type": "string"
},
"noKartu": {
"type": "string"
},
"noKtp": {
"type": "string"
},
"noSKTM": {
"type": "string"
},
"pisa": {
"type": "string"
},
"sex": {
"type": "string"
},
"statusPeserta": {
"type": "string"
},
"tglLahir": {
"type": "string"
},
"tglTAT": {
"type": "string"
},
"tglTMT": {
"type": "string"
},
"tglTunggak": {
"type": "string"
}
}
},
"reference.PesertaResponse": {
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/reference.PesertaData"
},
"message": {
"type": "string"
},
"metaData": {},
"request_id": {
"type": "string"
},
"status": {
"type": "string"
},
"timestamp": {
"type": "string"
}
}
},
"reference.RujukanData": {
"type": "object",
"properties": {
"diagnosa": {
"type": "object",
"properties": {
"kdDiagnosa": {
"type": "string"
},
"nmDiagnosa": {
"type": "string"
}
}
},
"kelasRawat": {
"type": "string"
},
"nama": {
"type": "string"
},
"noKartu": {
"type": "string"
},
"noRujukan": {
"type": "string"
},
"pelayanan": {
"type": "string"
},
"poliRujukan": {
"type": "object",
"properties": {
"kdPoli": {
"type": "string"
},
"nmPoli": {
"type": "string"
}
}
},
"provPerujuk": {
"type": "object",
"properties": {
"kdProvider": {
"type": "string"
},
"nmProvider": {
"type": "string"
}
}
},
"statusRujukan": {
"type": "string"
},
"tglRujukan": {
"type": "string"
}
}
},
"reference.RujukanResponse": {
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/reference.RujukanData"
},
"list": {
"type": "array",
"items": {
"$ref": "#/definitions/reference.RujukanData"
}
},
"message": {
"type": "string"
},
"request_id": {
"type": "string"
},
"status": {
"type": "string"
},
"timestamp": {
"type": "string"
}
}
},
"reference.SEPData": {
"type": "object",
"properties": {
"catatan": {
"type": "string"
},
"diagnosa": {
"type": "string"
},
"informasi": {
"type": "object",
"properties": {
"dpjpLayan": {
"type": "string"
},
"noSKDP": {
"type": "string"
},
"noTelp": {
"type": "string"
},
"subSpesialis": {
"type": "string"
}
}
},
"jnsPelayanan": {
"type": "string"
},
"klsRawat": {
"type": "string"
},
"noMR": {
"type": "string"
},
"noSep": {
"type": "string"
},
"peserta": {
"$ref": "#/definitions/reference.PesertaData"
},
"poli": {
"type": "string"
},
"rujukan": {
"$ref": "#/definitions/reference.SEPRujukan"
},
"tglSep": {
"type": "string"
}
}
},
"reference.SEPRequest": {
"type": "object",
"required": [
"diagnosa",
"jnsPelayanan",
"klsRawat",
"noKartu",
"noMR",
"poli",
"ppkPelayanan",
"tglSep",
"user"
],
"properties": {
"catatan": {
"type": "string"
},
"diagnosa": {
"type": "string"
},
"jnsPelayanan": {
"type": "string",
"enum": [
"1",
"2"
]
},
"klsRawat": {
"type": "string",
"enum": [
"1",
"2",
"3"
]
},
"noKartu": {
"type": "string"
},
"noMR": {
"type": "string"
},
"noTelp": {
"type": "string"
},
"poli": {
"type": "string"
},
"ppkPelayanan": {
"type": "string"
},
"request_id": {
"type": "string"
},
"rujukan": {
"$ref": "#/definitions/reference.SEPRujukan"
},
"tglSep": {
"type": "string"
},
"timestamp": {
"type": "string"
},
"user": {
"type": "string"
}
}
},
"reference.SEPResponse": {
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/reference.SEPData"
},
"message": {
"type": "string"
},
"request_id": {
"type": "string"
},
"status": {
"type": "string"
},
"timestamp": {
"type": "string"
}
}
},
"reference.SEPRujukan": {
"type": "object",
"required": [
"asalRujukan",
"noRujukan",
"ppkRujukan",
"tglRujukan"
],
"properties": {
"asalRujukan": {
"type": "string",
"enum": [
"1",
"2"
]
},
"noRujukan": {
"type": "string"
},
"ppkRujukan": {
"type": "string"
},
"tglRujukan": {
"type": "string"
}
}
},
"sql.NullString": {
"type": "object",

View File

@@ -212,67 +212,6 @@
}
}
},
"/api/v1/bpjs/Peserta/nik/{nik}/tglSEP/{tglSEP}": {
"get": {
"description": "Search participant data based on Population NIK and service date",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"BPJS"
],
"summary": "Get participant data by NIK",
"parameters": [
{
"type": "string",
"description": "NIK KTP",
"name": "nik",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Service date/SEP date (format: yyyy-MM-dd)",
"name": "tglSEP",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Participant data",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"400": {
"description": "Bad request",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"404": {
"description": "Participant not found",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "Internal server error",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/api/v1/retribusi/{id}": {
"get": {
"description": "Returns a single retribusi by ID",
@@ -758,9 +697,14 @@
}
}
},
"/sep": {
"put": {
"description": "Update Surat Eligibilitas Peserta",
"/peserta/:nokartu": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Get participant eligibility information",
"consumes": [
"application/json"
],
@@ -768,89 +712,49 @@
"application/json"
],
"tags": [
"SEP"
"vclaim",
"peserta"
],
"summary": "Update SEP",
"summary": "Get Peserta data",
"parameters": [
{
"description": "SEP update request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api-service_internal_models_vclaim.SepPutRequest"
}
"type": "string",
"description": "Nokartu",
"name": "nokartu",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "SEP updated successfully",
"description": "OK",
"schema": {
"$ref": "#/definitions/api-service_internal_models_vclaim.SepResponse"
"$ref": "#/definitions/reference.PesertaResponse"
}
},
"400": {
"description": "Invalid request",
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/gin.H"
"$ref": "#/definitions/reference.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/gin.H"
}
}
}
},
"post": {
"description": "Create a new Surat Eligibilitas Peserta",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"SEP"
],
"summary": "Create a new SEP",
"parameters": [
{
"description": "SEP creation request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/api-service_internal_models_vclaim.SepPostRequest"
}
}
],
"responses": {
"200": {
"description": "SEP created successfully",
"schema": {
"$ref": "#/definitions/api-service_internal_models_vclaim.SepResponse"
}
},
"400": {
"description": "Invalid request",
"schema": {
"$ref": "#/definitions/gin.H"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/gin.H"
"$ref": "#/definitions/reference.ErrorResponse"
}
}
}
}
},
"/sep/{noSep}": {
"/rujukan/:norujukan": {
"get": {
"description": "Retrieve a Surat Eligibilitas Peserta by noSep",
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Get referral information",
"consumes": [
"application/json"
],
@@ -858,41 +762,206 @@
"application/json"
],
"tags": [
"SEP"
"vclaim",
"rujukan"
],
"summary": "Get SEP",
"summary": "Get Rujukan data",
"parameters": [
{
"type": "string",
"description": "No SEP",
"name": "noSep",
"description": "Norujukan",
"name": "norujukan",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Data SEP retrieved successfully",
"description": "OK",
"schema": {
"$ref": "#/definitions/api-service_internal_models_vclaim.SepResponse"
"$ref": "#/definitions/reference.RujukanResponse"
}
},
"400": {
"description": "Invalid request",
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/gin.H"
"$ref": "#/definitions/reference.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/gin.H"
"$ref": "#/definitions/reference.ErrorResponse"
}
}
}
}
},
"/sep": {
"post": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Manage SEP (Surat Eligibilitas Peserta)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"vclaim",
"sep"
],
"summary": "Create Sep",
"parameters": [
{
"description": "Sep data",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/reference.SEPRequest"
}
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/reference.SEPResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/reference.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/reference.ErrorResponse"
}
}
}
}
},
"/sep/:nosep": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Manage SEP (Surat Eligibilitas Peserta)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"vclaim",
"sep"
],
"summary": "Get Sep data",
"parameters": [
{
"type": "string",
"description": "Nosep",
"name": "nosep",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/reference.SEPResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/reference.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/reference.ErrorResponse"
}
}
}
},
"put": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Manage SEP (Surat Eligibilitas Peserta)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"vclaim",
"sep"
],
"summary": "Update Sep",
"parameters": [
{
"type": "string",
"description": "Nosep",
"name": "nosep",
"in": "path",
"required": true
},
{
"description": "Sep data",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/reference.SEPRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/reference.SEPResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/reference.ErrorResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/reference.ErrorResponse"
}
}
}
},
"delete": {
"description": "Delete a Surat Eligibilitas Peserta by noSep",
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Manage SEP (Surat Eligibilitas Peserta)",
"consumes": [
"application/json"
],
@@ -900,42 +969,36 @@
"application/json"
],
"tags": [
"SEP"
"vclaim",
"sep"
],
"summary": "Delete SEP",
"summary": "Delete Sep",
"parameters": [
{
"type": "string",
"description": "No SEP",
"name": "noSep",
"description": "Nosep",
"name": "nosep",
"in": "path",
"required": true
},
{
"type": "string",
"description": "User",
"name": "user",
"in": "query",
"required": true
}
],
"responses": {
"200": {
"description": "SEP deleted successfully",
"description": "OK",
"schema": {
"$ref": "#/definitions/api-service_internal_models_vclaim.SepResponse"
"$ref": "#/definitions/reference.BaseResponse"
}
},
"400": {
"description": "Invalid request",
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/gin.H"
"$ref": "#/definitions/reference.ErrorResponse"
}
},
"500": {
"description": "Internal server error",
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/gin.H"
"$ref": "#/definitions/reference.ErrorResponse"
}
}
}
@@ -1368,27 +1431,403 @@
}
}
},
"api-service_internal_models_vclaim.SepPostRequest": {
"type": "object"
},
"api-service_internal_models_vclaim.SepPutRequest": {
"type": "object"
},
"api-service_internal_models_vclaim.SepResponse": {
"reference.BaseResponse": {
"type": "object",
"properties": {
"data": {
"message": {
"type": "string"
},
"request_id": {
"type": "string"
},
"status": {
"type": "string"
},
"timestamp": {
"type": "string"
}
}
},
"reference.ErrorResponse": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"errors": {
"type": "object",
"additionalProperties": true
},
"message": {
"type": "string"
},
"request_id": {
"type": "string"
},
"status": {
"type": "string"
}
}
},
"gin.H": {
"reference.PesertaData": {
"type": "object",
"additionalProperties": {}
"properties": {
"aktif": {
"type": "string"
},
"asuransi": {
"type": "string"
},
"cob": {
"type": "string"
},
"kdCabang": {
"type": "string"
},
"kdJnsPst": {
"type": "string"
},
"ketAktif": {
"type": "string"
},
"klsRawat": {
"type": "string"
},
"mr": {
"type": "object",
"properties": {
"nmMR": {
"type": "string"
},
"noMR": {
"type": "string"
},
"sex": {
"type": "string"
},
"tglLahir": {
"type": "string"
},
"tglMeninggal": {
"type": "string"
}
}
},
"nama": {
"type": "string"
},
"nik": {
"type": "string"
},
"nmCabang": {
"type": "string"
},
"nmJnsPst": {
"type": "string"
},
"noKartu": {
"type": "string"
},
"noKtp": {
"type": "string"
},
"noSKTM": {
"type": "string"
},
"pisa": {
"type": "string"
},
"sex": {
"type": "string"
},
"statusPeserta": {
"type": "string"
},
"tglLahir": {
"type": "string"
},
"tglTAT": {
"type": "string"
},
"tglTMT": {
"type": "string"
},
"tglTunggak": {
"type": "string"
}
}
},
"reference.PesertaResponse": {
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/reference.PesertaData"
},
"message": {
"type": "string"
},
"metaData": {},
"request_id": {
"type": "string"
},
"status": {
"type": "string"
},
"timestamp": {
"type": "string"
}
}
},
"reference.RujukanData": {
"type": "object",
"properties": {
"diagnosa": {
"type": "object",
"properties": {
"kdDiagnosa": {
"type": "string"
},
"nmDiagnosa": {
"type": "string"
}
}
},
"kelasRawat": {
"type": "string"
},
"nama": {
"type": "string"
},
"noKartu": {
"type": "string"
},
"noRujukan": {
"type": "string"
},
"pelayanan": {
"type": "string"
},
"poliRujukan": {
"type": "object",
"properties": {
"kdPoli": {
"type": "string"
},
"nmPoli": {
"type": "string"
}
}
},
"provPerujuk": {
"type": "object",
"properties": {
"kdProvider": {
"type": "string"
},
"nmProvider": {
"type": "string"
}
}
},
"statusRujukan": {
"type": "string"
},
"tglRujukan": {
"type": "string"
}
}
},
"reference.RujukanResponse": {
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/reference.RujukanData"
},
"list": {
"type": "array",
"items": {
"$ref": "#/definitions/reference.RujukanData"
}
},
"message": {
"type": "string"
},
"request_id": {
"type": "string"
},
"status": {
"type": "string"
},
"timestamp": {
"type": "string"
}
}
},
"reference.SEPData": {
"type": "object",
"properties": {
"catatan": {
"type": "string"
},
"diagnosa": {
"type": "string"
},
"informasi": {
"type": "object",
"properties": {
"dpjpLayan": {
"type": "string"
},
"noSKDP": {
"type": "string"
},
"noTelp": {
"type": "string"
},
"subSpesialis": {
"type": "string"
}
}
},
"jnsPelayanan": {
"type": "string"
},
"klsRawat": {
"type": "string"
},
"noMR": {
"type": "string"
},
"noSep": {
"type": "string"
},
"peserta": {
"$ref": "#/definitions/reference.PesertaData"
},
"poli": {
"type": "string"
},
"rujukan": {
"$ref": "#/definitions/reference.SEPRujukan"
},
"tglSep": {
"type": "string"
}
}
},
"reference.SEPRequest": {
"type": "object",
"required": [
"diagnosa",
"jnsPelayanan",
"klsRawat",
"noKartu",
"noMR",
"poli",
"ppkPelayanan",
"tglSep",
"user"
],
"properties": {
"catatan": {
"type": "string"
},
"diagnosa": {
"type": "string"
},
"jnsPelayanan": {
"type": "string",
"enum": [
"1",
"2"
]
},
"klsRawat": {
"type": "string",
"enum": [
"1",
"2",
"3"
]
},
"noKartu": {
"type": "string"
},
"noMR": {
"type": "string"
},
"noTelp": {
"type": "string"
},
"poli": {
"type": "string"
},
"ppkPelayanan": {
"type": "string"
},
"request_id": {
"type": "string"
},
"rujukan": {
"$ref": "#/definitions/reference.SEPRujukan"
},
"tglSep": {
"type": "string"
},
"timestamp": {
"type": "string"
},
"user": {
"type": "string"
}
}
},
"reference.SEPResponse": {
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/reference.SEPData"
},
"message": {
"type": "string"
},
"request_id": {
"type": "string"
},
"status": {
"type": "string"
},
"timestamp": {
"type": "string"
}
}
},
"reference.SEPRujukan": {
"type": "object",
"required": [
"asalRujukan",
"noRujukan",
"ppkRujukan",
"tglRujukan"
],
"properties": {
"asalRujukan": {
"type": "string",
"enum": [
"1",
"2"
]
},
"noRujukan": {
"type": "string"
},
"ppkRujukan": {
"type": "string"
},
"tglRujukan": {
"type": "string"
}
}
},
"sql.NullString": {
"type": "object",

View File

@@ -292,20 +292,271 @@ definitions:
message:
type: string
type: object
api-service_internal_models_vclaim.SepPostRequest:
type: object
api-service_internal_models_vclaim.SepPutRequest:
type: object
api-service_internal_models_vclaim.SepResponse:
reference.BaseResponse:
properties:
data:
message:
type: string
request_id:
type: string
status:
type: string
timestamp:
type: string
type: object
reference.ErrorResponse:
properties:
code:
type: string
errors:
additionalProperties: true
type: object
message:
type: string
request_id:
type: string
status:
type: string
type: object
gin.H:
additionalProperties: {}
reference.PesertaData:
properties:
aktif:
type: string
asuransi:
type: string
cob:
type: string
kdCabang:
type: string
kdJnsPst:
type: string
ketAktif:
type: string
klsRawat:
type: string
mr:
properties:
nmMR:
type: string
noMR:
type: string
sex:
type: string
tglLahir:
type: string
tglMeninggal:
type: string
type: object
nama:
type: string
nik:
type: string
nmCabang:
type: string
nmJnsPst:
type: string
noKartu:
type: string
noKtp:
type: string
noSKTM:
type: string
pisa:
type: string
sex:
type: string
statusPeserta:
type: string
tglLahir:
type: string
tglTAT:
type: string
tglTMT:
type: string
tglTunggak:
type: string
type: object
reference.PesertaResponse:
properties:
data:
$ref: '#/definitions/reference.PesertaData'
message:
type: string
metaData: {}
request_id:
type: string
status:
type: string
timestamp:
type: string
type: object
reference.RujukanData:
properties:
diagnosa:
properties:
kdDiagnosa:
type: string
nmDiagnosa:
type: string
type: object
kelasRawat:
type: string
nama:
type: string
noKartu:
type: string
noRujukan:
type: string
pelayanan:
type: string
poliRujukan:
properties:
kdPoli:
type: string
nmPoli:
type: string
type: object
provPerujuk:
properties:
kdProvider:
type: string
nmProvider:
type: string
type: object
statusRujukan:
type: string
tglRujukan:
type: string
type: object
reference.RujukanResponse:
properties:
data:
$ref: '#/definitions/reference.RujukanData'
list:
items:
$ref: '#/definitions/reference.RujukanData'
type: array
message:
type: string
request_id:
type: string
status:
type: string
timestamp:
type: string
type: object
reference.SEPData:
properties:
catatan:
type: string
diagnosa:
type: string
informasi:
properties:
dpjpLayan:
type: string
noSKDP:
type: string
noTelp:
type: string
subSpesialis:
type: string
type: object
jnsPelayanan:
type: string
klsRawat:
type: string
noMR:
type: string
noSep:
type: string
peserta:
$ref: '#/definitions/reference.PesertaData'
poli:
type: string
rujukan:
$ref: '#/definitions/reference.SEPRujukan'
tglSep:
type: string
type: object
reference.SEPRequest:
properties:
catatan:
type: string
diagnosa:
type: string
jnsPelayanan:
enum:
- "1"
- "2"
type: string
klsRawat:
enum:
- "1"
- "2"
- "3"
type: string
noKartu:
type: string
noMR:
type: string
noTelp:
type: string
poli:
type: string
ppkPelayanan:
type: string
request_id:
type: string
rujukan:
$ref: '#/definitions/reference.SEPRujukan'
tglSep:
type: string
timestamp:
type: string
user:
type: string
required:
- diagnosa
- jnsPelayanan
- klsRawat
- noKartu
- noMR
- poli
- ppkPelayanan
- tglSep
- user
type: object
reference.SEPResponse:
properties:
data:
$ref: '#/definitions/reference.SEPData'
message:
type: string
request_id:
type: string
status:
type: string
timestamp:
type: string
type: object
reference.SEPRujukan:
properties:
asalRujukan:
enum:
- "1"
- "2"
type: string
noRujukan:
type: string
ppkRujukan:
type: string
tglRujukan:
type: string
required:
- asalRujukan
- noRujukan
- ppkRujukan
- tglRujukan
type: object
sql.NullString:
properties:
@@ -460,48 +711,6 @@ paths:
summary: Register new user
tags:
- Authentication
/api/v1/bpjs/Peserta/nik/{nik}/tglSEP/{tglSEP}:
get:
consumes:
- application/json
description: Search participant data based on Population NIK and service date
parameters:
- description: NIK KTP
in: path
name: nik
required: true
type: string
- description: 'Service date/SEP date (format: yyyy-MM-dd)'
in: path
name: tglSEP
required: true
type: string
produces:
- application/json
responses:
"200":
description: Participant data
schema:
additionalProperties: true
type: object
"400":
description: Bad request
schema:
additionalProperties: true
type: object
"404":
description: Participant not found
schema:
additionalProperties: true
type: object
"500":
description: Internal server error
schema:
additionalProperties: true
type: object
summary: Get participant data by NIK
tags:
- BPJS
/api/v1/retribusi/{id}:
delete:
consumes:
@@ -824,127 +1033,203 @@ paths:
summary: Generate token directly
tags:
- Token
/peserta/:nokartu:
get:
consumes:
- application/json
description: Get participant eligibility information
parameters:
- description: Nokartu
in: path
name: nokartu
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/reference.PesertaResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/reference.ErrorResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/reference.ErrorResponse'
security:
- ApiKeyAuth: []
summary: Get Peserta data
tags:
- vclaim
- peserta
/rujukan/:norujukan:
get:
consumes:
- application/json
description: Get referral information
parameters:
- description: Norujukan
in: path
name: norujukan
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/reference.RujukanResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/reference.ErrorResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/reference.ErrorResponse'
security:
- ApiKeyAuth: []
summary: Get Rujukan data
tags:
- vclaim
- rujukan
/sep:
post:
consumes:
- application/json
description: Create a new Surat Eligibilitas Peserta
description: Manage SEP (Surat Eligibilitas Peserta)
parameters:
- description: SEP creation request
- description: Sep data
in: body
name: request
required: true
schema:
$ref: '#/definitions/api-service_internal_models_vclaim.SepPostRequest'
$ref: '#/definitions/reference.SEPRequest'
produces:
- application/json
responses:
"200":
description: SEP created successfully
"201":
description: Created
schema:
$ref: '#/definitions/api-service_internal_models_vclaim.SepResponse'
$ref: '#/definitions/reference.SEPResponse'
"400":
description: Invalid request
description: Bad Request
schema:
$ref: '#/definitions/gin.H'
$ref: '#/definitions/reference.ErrorResponse'
"500":
description: Internal server error
description: Internal Server Error
schema:
$ref: '#/definitions/gin.H'
summary: Create a new SEP
$ref: '#/definitions/reference.ErrorResponse'
security:
- ApiKeyAuth: []
summary: Create Sep
tags:
- SEP
put:
consumes:
- application/json
description: Update Surat Eligibilitas Peserta
parameters:
- description: SEP update request
in: body
name: request
required: true
schema:
$ref: '#/definitions/api-service_internal_models_vclaim.SepPutRequest'
produces:
- application/json
responses:
"200":
description: SEP updated successfully
schema:
$ref: '#/definitions/api-service_internal_models_vclaim.SepResponse'
"400":
description: Invalid request
schema:
$ref: '#/definitions/gin.H'
"500":
description: Internal server error
schema:
$ref: '#/definitions/gin.H'
summary: Update SEP
tags:
- SEP
/sep/{noSep}:
- vclaim
- sep
/sep/:nosep:
delete:
consumes:
- application/json
description: Delete a Surat Eligibilitas Peserta by noSep
description: Manage SEP (Surat Eligibilitas Peserta)
parameters:
- description: No SEP
- description: Nosep
in: path
name: noSep
required: true
type: string
- description: User
in: query
name: user
name: nosep
required: true
type: string
produces:
- application/json
responses:
"200":
description: SEP deleted successfully
description: OK
schema:
$ref: '#/definitions/api-service_internal_models_vclaim.SepResponse'
$ref: '#/definitions/reference.BaseResponse'
"400":
description: Invalid request
description: Bad Request
schema:
$ref: '#/definitions/gin.H'
$ref: '#/definitions/reference.ErrorResponse'
"500":
description: Internal server error
description: Internal Server Error
schema:
$ref: '#/definitions/gin.H'
summary: Delete SEP
$ref: '#/definitions/reference.ErrorResponse'
security:
- ApiKeyAuth: []
summary: Delete Sep
tags:
- SEP
- vclaim
- sep
get:
consumes:
- application/json
description: Retrieve a Surat Eligibilitas Peserta by noSep
description: Manage SEP (Surat Eligibilitas Peserta)
parameters:
- description: No SEP
- description: Nosep
in: path
name: noSep
name: nosep
required: true
type: string
produces:
- application/json
responses:
"200":
description: Data SEP retrieved successfully
description: OK
schema:
$ref: '#/definitions/api-service_internal_models_vclaim.SepResponse'
$ref: '#/definitions/reference.SEPResponse'
"400":
description: Invalid request
description: Bad Request
schema:
$ref: '#/definitions/gin.H'
$ref: '#/definitions/reference.ErrorResponse'
"500":
description: Internal server error
description: Internal Server Error
schema:
$ref: '#/definitions/gin.H'
summary: Get SEP
$ref: '#/definitions/reference.ErrorResponse'
security:
- ApiKeyAuth: []
summary: Get Sep data
tags:
- SEP
- vclaim
- sep
put:
consumes:
- application/json
description: Manage SEP (Surat Eligibilitas Peserta)
parameters:
- description: Nosep
in: path
name: nosep
required: true
type: string
- description: Sep data
in: body
name: request
required: true
schema:
$ref: '#/definitions/reference.SEPRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/reference.SEPResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/reference.ErrorResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/reference.ErrorResponse'
security:
- ApiKeyAuth: []
summary: Update Sep
tags:
- vclaim
- sep
schemes:
- http
- https

View File

@@ -1,92 +0,0 @@
package handlers
import (
"context"
"fmt"
"net/http"
"time"
"api-service/internal/config"
services "api-service/internal/services/bpjs"
"github.com/gin-gonic/gin"
)
// PesertaHandler handles BPJS participant operations
type PesertaHandler struct {
bpjsService services.VClaimService
}
// NewPesertaHandler creates a new PesertaHandler instance
func NewPesertaHandler(cfg config.BpjsConfig) *PesertaHandler {
return &PesertaHandler{
bpjsService: services.NewService(cfg),
}
}
// GetPesertaByNIK godoc
// @Summary Get participant data by NIK
// @Description Search participant data based on Population NIK and service date
// @Tags BPJS
// @Accept json
// @Produce json
// @Param nik path string true "NIK KTP"
// @Param tglSEP path string true "Service date/SEP date (format: yyyy-MM-dd)"
// @Success 200 {object} map[string]interface{} "Participant data"
// @Failure 400 {object} map[string]interface{} "Bad request"
// @Failure 404 {object} map[string]interface{} "Participant not found"
// @Failure 500 {object} map[string]interface{} "Internal server error"
// @Router /api/v1/bpjs/Peserta/nik/{nik}/tglSEP/{tglSEP} [get]
func (h *PesertaHandler) GetPesertaByNIK(c *gin.Context) {
nik := c.Param("nik")
tglSEP := c.Param("tglSEP")
// Validate parameters
if nik == "" {
c.JSON(http.StatusBadRequest, gin.H{
"error": "NIK parameter is required",
"message": "NIK KTP tidak boleh kosong",
})
return
}
if tglSEP == "" {
c.JSON(http.StatusBadRequest, gin.H{
"error": "tglSEP parameter is required",
"message": "Tanggal SEP tidak boleh kosong",
})
return
}
// Validate date format
if _, err := time.Parse("2006-01-02", tglSEP); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "Invalid date format",
"message": "Format tanggal harus yyyy-MM-dd",
})
return
}
// Create context with timeout
ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second)
defer cancel()
// Build endpoint URL
endpoint := fmt.Sprintf("/Peserta/nik/%s/tglSEP/%s", nik, tglSEP)
// Call BPJS service
var result map[string]interface{}
if err := h.bpjsService.Get(ctx, endpoint, &result); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Failed to fetch participant data",
"message": err.Error(),
})
return
}
// Return successful response
c.JSON(http.StatusOK, gin.H{
"message": "Data peserta berhasil diambil",
"data": result,
})
}

View File

@@ -1,100 +0,0 @@
package swagger
import (
"net/http"
"strings"
"github.com/gin-gonic/gin"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
"api-service/internal/config"
)
// Handler handles Swagger documentation
type Handler struct {
config *config.Config
}
// NewHandler creates a new Swagger handler
func NewHandler(cfg *config.Config) *Handler {
return &Handler{
config: cfg,
}
}
// RegisterRoutes registers Swagger routes
func (h *Handler) RegisterRoutes(router *gin.Engine) {
// Serve Swagger UI
router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
// Serve OpenAPI spec
router.GET("/openapi.json", h.serveOpenAPISpec)
router.GET("/openapi.yaml", h.serveOpenAPISpecYAML)
}
// serveOpenAPISpec serves the OpenAPI JSON specification
func (h *Handler) serveOpenAPISpec(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"openapi": "3.0.0",
"info": map[string]interface{}{
"title": h.config.Swagger.Title,
"description": h.config.Swagger.Description,
"version": h.config.Swagger.Version,
"termsOfService": h.config.Swagger.TermsOfService,
"contact": map[string]interface{}{
"name": h.config.Swagger.ContactName,
"url": h.config.Swagger.ContactURL,
"email": h.config.Swagger.ContactEmail,
},
"license": map[string]interface{}{
"name": h.config.Swagger.LicenseName,
"url": h.config.Swagger.LicenseURL,
},
},
"servers": []map[string]interface{}{
{
"url": strings.Join([]string{strings.ToLower(h.config.Swagger.Schemes[0]), "://", h.config.Swagger.Host, h.config.Swagger.BasePath}, ""),
"description": "API Server",
},
},
"paths": map[string]interface{}{},
"components": map[string]interface{}{
"schemas": map[string]interface{}{},
"securitySchemes": map[string]interface{}{},
},
})
}
// serveOpenAPISpecYAML serves the OpenAPI YAML specification
func (h *Handler) serveOpenAPISpecYAML(c *gin.Context) {
c.YAML(http.StatusOK, map[string]interface{}{
"openapi": "3.0.0",
"info": map[string]interface{}{
"title": h.config.Swagger.Title,
"description": h.config.Swagger.Description,
"version": h.config.Swagger.Version,
"termsOfService": h.config.Swagger.TermsOfService,
"contact": map[string]interface{}{
"name": h.config.Swagger.ContactName,
"url": h.config.Swagger.ContactURL,
"email": h.config.Swagger.ContactEmail,
},
"license": map[string]interface{}{
"name": h.config.Swagger.LicenseName,
"url": h.config.Swagger.LicenseURL,
},
},
"servers": []map[string]interface{}{
{
"url": strings.Join([]string{strings.ToLower(h.config.Swagger.Schemes[0]), "://", h.config.Swagger.Host, h.config.Swagger.BasePath}, ""),
"description": "API Server",
},
},
"paths": map[string]interface{}{},
"components": map[string]interface{}{
"schemas": map[string]interface{}{},
"securitySchemes": map[string]interface{}{},
},
})
}

View File

@@ -1,190 +0,0 @@
package handlers
import (
"context"
"fmt"
"net/http"
"time"
"api-service/internal/config"
vclaimModels "api-service/internal/models/vclaim"
services "api-service/internal/services/bpjs"
"github.com/gin-gonic/gin"
)
type SepHandler struct {
service services.VClaimService
}
func NewSepHandler(cfg config.BpjsConfig) *SepHandler {
return &SepHandler{
service: services.NewService(cfg),
}
}
// CreateSEP godoc
// @Summary Create a new SEP
// @Description Create a new Surat Eligibilitas Peserta
// @Tags SEP
// @Accept json
// @Produce json
// @Param request body vclaimModels.SepPostRequest true "SEP creation request"
// @Success 200 {object} vclaimModels.SepResponse "SEP created successfully"
// @Failure 400 {object} gin.H "Invalid request"
// @Failure 500 {object} gin.H "Internal server error"
// @Router /sep [post]
func (h *SepHandler) CreateSEP(c *gin.Context) {
var req vclaimModels.SepPostRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "invalid body",
"message": err.Error(),
})
return
}
ctx, cancel := context.WithTimeout(c, 30*time.Second)
defer cancel()
var result map[string]interface{}
if err := h.service.Post(ctx, "SEP/2.0/insert", req, &result); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "create failed",
"message": err.Error(),
})
return
}
c.JSON(http.StatusOK, vclaimModels.SepResponse{
Message: "SEP berhasil dibuat",
Data: result,
})
}
// UpdateSEP godoc
// @Summary Update SEP
// @Description Update Surat Eligibilitas Peserta
// @Tags SEP
// @Accept json
// @Produce json
// @Param request body vclaimModels.SepPutRequest true "SEP update request"
// @Success 200 {object} vclaimModels.SepResponse "SEP updated successfully"
// @Failure 400 {object} gin.H "Invalid request"
// @Failure 500 {object} gin.H "Internal server error"
// @Router /sep [put]
func (h *SepHandler) UpdateSEP(c *gin.Context) {
var req vclaimModels.SepPutRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "invalid body",
"message": err.Error(),
})
return
}
ctx, cancel := context.WithTimeout(c, 30*time.Second)
defer cancel()
var result map[string]interface{}
if err := h.service.Put(ctx, "SEP/2.0/update", req, &result); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "update failed",
"message": err.Error(),
})
return
}
c.JSON(http.StatusOK, vclaimModels.SepResponse{
Message: "SEP berhasil diperbarui",
Data: result,
})
}
// DeleteSEP godoc
// @Summary Delete SEP
// @Description Delete a Surat Eligibilitas Peserta by noSep
// @Tags SEP
// @Accept json
// @Produce json
// @Param noSep path string true "No SEP"
// @Param user query string true "User"
// @Success 200 {object} vclaimModels.SepResponse "SEP deleted successfully"
// @Failure 400 {object} gin.H "Invalid request"
// @Failure 500 {object} gin.H "Internal server error"
// @Router /sep/{noSep} [delete]
func (h *SepHandler) DeleteSEP(c *gin.Context) {
noSep := c.Param("noSep")
user := c.Query("user")
if noSep == "" || user == "" {
c.JSON(http.StatusBadRequest, gin.H{
"error": "noSep and user required",
})
return
}
body := vclaimModels.SepDeleteRequest{}
body.TSep.NoSep = noSep
body.TSep.User = user
ctx, cancel := context.WithTimeout(c, 30*time.Second)
defer cancel()
if err := h.service.Delete(ctx, "SEP/2.0/delete", body); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "delete failed",
"message": err.Error(),
})
return
}
var result map[string]interface{}
c.JSON(http.StatusOK, vclaimModels.SepResponse{
Message: "SEP berhasil dihapus",
Data: result,
})
}
// GetSEP godoc
// @Summary Get SEP
// @Description Retrieve a Surat Eligibilitas Peserta by noSep
// @Tags SEP
// @Accept json
// @Produce json
// @Param noSep path string true "No SEP"
// @Success 200 {object} vclaimModels.SepResponse "Data SEP retrieved successfully"
// @Failure 400 {object} gin.H "Invalid request"
// @Failure 500 {object} gin.H "Internal server error"
// @Router /sep/{noSep} [get]
func (h *SepHandler) GetSEP(c *gin.Context) {
noSep := c.Param("noSep")
if noSep == "" {
c.JSON(http.StatusBadRequest, gin.H{
"error": "noSep required",
})
return
}
ctx, cancel := context.WithTimeout(c, 30*time.Second)
defer cancel()
endpoint := fmt.Sprintf("SEP/%s", noSep)
var result map[string]interface{}
if err := h.service.Get(ctx, endpoint, &result); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "fetch failed",
"message": err.Error(),
})
return
}
c.JSON(http.StatusOK, vclaimModels.SepResponse{
Message: "Data SEP berhasil diambil",
Data: result,
})
}

View File

@@ -0,0 +1,401 @@
// Code generated by generate-dynamic-handler.go; DO NOT EDIT.
// Generated at: 2025-08-28 17:47:19
// Service: VClaim (vclaim)
// Description: BPJS VClaim service for eligibility and SEP management
package handlers
import (
"context"
"fmt"
"net/http"
"strconv"
"strings"
"time"
"api-service/internal/config"
"api-service/internal/models/reference"
"api-service/internal/services/bpjs"
"api-service/pkg/logger"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"github.com/google/uuid"
)
// VClaimHandler handles VClaim BPJS services
type VClaimHandler struct {
service services.VClaimService
validator *validator.Validate
logger logger.Logger
config config.BpjsConfig
}
// VClaimHandlerConfig contains configuration for VClaimHandler
type VClaimHandlerConfig struct {
BpjsConfig config.BpjsConfig
Logger logger.Logger
Validator *validator.Validate
}
// NewVClaimHandler creates a new VClaimHandler
func NewVClaimHandler(cfg VClaimHandlerConfig) *VClaimHandler {
return &VClaimHandler{
service: services.NewService(cfg.BpjsConfig),
validator: cfg.Validator,
logger: cfg.Logger,
config: cfg.BpjsConfig,
}
}
// GetPESERTA retrieves Peserta data
// @Summary Get Peserta data
// @Description Get participant eligibility information
// @Tags vclaim,peserta
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param nokartu path string true "nokartu"
// @Success 200 {object} reference.PesertaResponse
// @Failure 400 {object} reference.ErrorResponse
// @Failure 500 {object} reference.ErrorResponse
// @Router /Peserta/:nokartu [get]
func (h *VClaimHandler) GetPESERTA(c *gin.Context) {
ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second)
defer cancel()
// Generate request ID if not present
requestID := c.GetHeader("X-Request-ID")
if requestID == "" {
requestID = uuid.New().String()
c.Header("X-Request-ID", requestID)
}
h.logger.Info("Processing GetPeserta request", map[string]interface{}{
"request_id": requestID,
"endpoint": "/Peserta/:nokartu",
"nokartu": c.Param("nokartu"),
})
// Extract path parameters
nokartu := c.Param("nokartu")
if nokartu == "" {
h.logger.Error("Missing required parameter nokartu", map[string]interface{}{
"request_id": requestID,
})
c.JSON(http.StatusBadRequest, reference.ErrorResponse{
Status: "error",
Message: "Missing required parameter nokartu",
RequestID: requestID,
})
return
}
// Call service method
var response reference.PesertaResponse
result, err := h.service.GetPESERTA(ctx, nokartu)
if err != nil {
h.logger.Error("Failed to get Peserta", map[string]interface{}{
"error": err.Error(),
"request_id": requestID,
})
c.JSON(http.StatusInternalServerError, reference.ErrorResponse{
Status: "error",
Message: "Internal server error",
RequestID: requestID,
})
return
}
// Ensure response has proper fields
response.Status = "success"
response.RequestID = requestID
c.JSON(http.StatusOK, response)
}
// GetSEP retrieves Sep data
// @Summary Get Sep data
// @Description Manage SEP (Surat Eligibilitas Peserta)
// @Tags vclaim,sep
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param nosep path string true "nosep"
// @Success 200 {object} reference.SEPResponse
// @Failure 400 {object} reference.ErrorResponse
// @Failure 500 {object} reference.ErrorResponse
// @Router /SEP/:nosep [get]
func (h *VClaimHandler) GetSEP(c *gin.Context) {
ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second)
defer cancel()
// Generate request ID if not present
requestID := c.GetHeader("X-Request-ID")
if requestID == "" {
requestID = uuid.New().String()
c.Header("X-Request-ID", requestID)
}
h.logger.Info("Processing GetSep request", map[string]interface{}{
"request_id": requestID,
"endpoint": "/SEP/:nosep",
"nosep": c.Param("nosep"),
})
// Extract path parameters
nosep := c.Param("nosep")
if nosep == "" {
h.logger.Error("Missing required parameter nosep", map[string]interface{}{
"request_id": requestID,
})
c.JSON(http.StatusBadRequest, reference.ErrorResponse{
Status: "error",
Message: "Missing required parameter nosep",
RequestID: requestID,
})
return
}
// Call service method
var response reference.SEPResponse
result, err := h.service.GetSEP(ctx, nosep)
if err != nil {
h.logger.Error("Failed to get Sep", map[string]interface{}{
"error": err.Error(),
"request_id": requestID,
})
c.JSON(http.StatusInternalServerError, reference.ErrorResponse{
Status: "error",
Message: "Internal server error",
RequestID: requestID,
})
return
}
// Ensure response has proper fields
response.Status = "success"
response.RequestID = requestID
c.JSON(http.StatusOK, response)
}
// CreateSEP creates new Sep
// @Summary Create Sep
// @Description Manage SEP (Surat Eligibilitas Peserta)
// @Tags vclaim,sep
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param request body reference.SEPRequest true "Sep data"
// @Success 201 {object} reference.SEPResponse
// @Failure 400 {object} reference.ErrorResponse
// @Failure 500 {object} reference.ErrorResponse
// @Router /sep [post]
func (h *VClaimHandler) CreateSEP(c *gin.Context) {
ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second)
defer cancel()
requestID := c.GetHeader("X-Request-ID")
if requestID == "" {
requestID = uuid.New().String()
c.Header("X-Request-ID", requestID)
}
h.logger.Info("Processing CreateSep request", map[string]interface{}{
"request_id": requestID,
})
var req reference.SEPRequest
if err := c.ShouldBindJSON(&req); err != nil {
h.logger.Error("Invalid request body", map[string]interface{}{
"error": err.Error(),
"request_id": requestID,
})
c.JSON(http.StatusBadRequest, reference.ErrorResponse{
Status: "error",
Message: "Invalid request body: " + err.Error(),
RequestID: requestID,
})
return
}
// Validate request
if err := h.validator.Struct(&req); err != nil {
h.logger.Error("Validation failed", map[string]interface{}{
"error": err.Error(),
"request_id": requestID,
})
c.JSON(http.StatusBadRequest, reference.ErrorResponse{
Status: "error",
Message: "Validation failed: " + err.Error(),
RequestID: requestID,
})
return
}
// Call service method
var response reference.SEPResponse
result, err := h.service.CreateSEP(ctx, &req)
if err != nil {
h.logger.Error("Failed to create Sep", map[string]interface{}{
"error": err.Error(),
"request_id": requestID,
})
c.JSON(http.StatusInternalServerError, reference.ErrorResponse{
Status: "error",
Message: "Internal server error",
RequestID: requestID,
})
return
}
// Ensure response has proper fields
response.Status = "success"
response.RequestID = requestID
c.JSON(http.StatusCreated, response)
}
// GetRUJUKAN retrieves Rujukan data
// @Summary Get Rujukan data
// @Description Get referral information
// @Tags vclaim,rujukan
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param norujukan path string true "norujukan"
// @Success 200 {object} reference.RujukanResponse
// @Failure 400 {object} reference.ErrorResponse
// @Failure 500 {object} reference.ErrorResponse
// @Router /rujukan/:norujukan [get]
func (h *VClaimHandler) GetRUJUKAN(c *gin.Context) {
ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second)
defer cancel()
// Generate request ID if not present
requestID := c.GetHeader("X-Request-ID")
if requestID == "" {
requestID = uuid.New().String()
c.Header("X-Request-ID", requestID)
}
h.logger.Info("Processing GetRujukan request", map[string]interface{}{
"request_id": requestID,
"endpoint": "/rujukan/:norujukan",
"norujukan": c.Param("norujukan"),
})
// Extract path parameters
norujukan := c.Param("norujukan")
if norujukan == "" {
h.logger.Error("Missing required parameter norujukan", map[string]interface{}{
"request_id": requestID,
})
c.JSON(http.StatusBadRequest, reference.ErrorResponse{
Status: "error",
Message: "Missing required parameter norujukan",
RequestID: requestID,
})
return
}
// Call service method
var response reference.RujukanResponse
result, err := h.service.GetRUJUKAN(ctx, norujukan)
if err != nil {
h.logger.Error("Failed to get Rujukan", map[string]interface{}{
"error": err.Error(),
"request_id": requestID,
})
c.JSON(http.StatusInternalServerError, reference.ErrorResponse{
Status: "error",
Message: "Internal server error",
RequestID: requestID,
})
return
}
// Ensure response has proper fields
response.Status = "success"
response.RequestID = requestID
c.JSON(http.StatusOK, response)
}

View File

@@ -0,0 +1,70 @@
package reference
// === REFERENSI MODELS ===
// ReferensiRequest represents referensi lookup request
type ReferensiRequest struct {
BaseRequest
JenisReferensi string `json:"jenis_referensi" validate:"required,oneof=diagnosa procedure obat alkes faskes dokter poli"`
Keyword string `json:"keyword,omitempty"`
KodeReferensi string `json:"kode_referensi,omitempty"`
PaginationRequest
}
// ReferensiData represents referensi information
type ReferensiData struct {
Kode string `json:"kode"`
Nama string `json:"nama"`
Kategori string `json:"kategori,omitempty"`
Status string `json:"status"`
TglBerlaku string `json:"tgl_berlaku,omitempty"`
TglBerakhir string `json:"tgl_berakhir,omitempty"`
Keterangan string `json:"keterangan,omitempty"`
}
// ReferensiResponse represents referensi API response
type ReferensiResponse struct {
BaseResponse
Data []ReferensiData `json:"data,omitempty"`
Pagination *PaginationResponse `json:"pagination,omitempty"`
}
// === MONITORING MODELS ===
// MonitoringRequest represents monitoring data request
type MonitoringRequest struct {
BaseRequest
TanggalAwal string `json:"tanggal_awal" validate:"required"`
TanggalAkhir string `json:"tanggal_akhir" validate:"required"`
JenisLaporan string `json:"jenis_laporan" validate:"required,oneof=kunjungan klaim rujukan sep"`
PPK string `json:"ppk,omitempty"`
StatusData string `json:"status_data,omitempty"`
PaginationRequest
}
// MonitoringData represents monitoring information
type MonitoringData struct {
Tanggal string `json:"tanggal"`
PPK string `json:"ppk"`
NamaPPK string `json:"nama_ppk"`
JumlahKasus int `json:"jumlah_kasus"`
TotalTarif float64 `json:"total_tarif"`
StatusData string `json:"status_data"`
Keterangan string `json:"keterangan,omitempty"`
}
// MonitoringResponse represents monitoring API response
type MonitoringResponse struct {
BaseResponse
Data []MonitoringData `json:"data,omitempty"`
Summary *MonitoringSummary `json:"summary,omitempty"`
Pagination *PaginationResponse `json:"pagination,omitempty"`
}
// MonitoringSummary represents monitoring summary
type MonitoringSummary struct {
TotalKasus int `json:"total_kasus"`
TotalTarif float64 `json:"total_tarif"`
RataRataTarif float64 `json:"rata_rata_tarif"`
PeriodeLaporan string `json:"periode_laporan"`
}

View File

@@ -0,0 +1,53 @@
package reference
import (
"time"
)
// BaseRequest contains common fields for all BPJS requests
type BaseRequest struct {
RequestID string `json:"request_id,omitempty"`
Timestamp time.Time `json:"timestamp,omitempty"`
}
// BaseResponse contains common response fields
type BaseResponse struct {
Status string `json:"status"`
Message string `json:"message,omitempty"`
RequestID string `json:"request_id,omitempty"`
Timestamp string `json:"timestamp,omitempty"`
}
// ErrorResponse represents error response structure
type ErrorResponse struct {
Status string `json:"status"`
Message string `json:"message"`
RequestID string `json:"request_id,omitempty"`
Errors map[string]interface{} `json:"errors,omitempty"`
Code string `json:"code,omitempty"`
}
// PaginationRequest contains pagination parameters
type PaginationRequest struct {
Page int `json:"page" validate:"min=1"`
Limit int `json:"limit" validate:"min=1,max=100"`
SortBy string `json:"sort_by,omitempty"`
SortDir string `json:"sort_dir,omitempty" validate:"omitempty,oneof=asc desc"`
}
// PaginationResponse contains pagination metadata
type PaginationResponse struct {
CurrentPage int `json:"current_page"`
TotalPages int `json:"total_pages"`
TotalItems int64 `json:"total_items"`
ItemsPerPage int `json:"items_per_page"`
HasNext bool `json:"has_next"`
HasPrev bool `json:"has_previous"`
}
// MetaInfo contains additional metadata
type MetaInfo struct {
Version string `json:"version"`
Environment string `json:"environment"`
ServerTime string `json:"server_time"`
}

View File

@@ -0,0 +1,148 @@
package reference
// === KLAIM MODELS ===
// KlaimRequest represents klaim submission request
type KlaimRequest struct {
BaseRequest
NoSep string `json:"nomor_sep" validate:"required"`
NoKartu string `json:"nomor_kartu" validate:"required"`
NoMR string `json:"nomor_mr" validate:"required"`
TglPulang string `json:"tgl_pulang" validate:"required"`
TglMasuk string `json:"tgl_masuk" validate:"required"`
JnsPelayanan string `json:"jenis_pelayanan" validate:"required,oneof=1 2"`
CaraPulang string `json:"cara_pulang" validate:"required"`
Data KlaimData `json:"data" validate:"required"`
}
// KlaimData represents detailed klaim information
type KlaimData struct {
Diagnosa []DiagnosaKlaim `json:"diagnosa" validate:"required,dive"`
Procedure []ProcedureKlaim `json:"procedure,omitempty"`
Investigasi []InvestigasiKlaim `json:"investigasi,omitempty"`
ObatAlkes []ObatKlaim `json:"obat_alkes,omitempty"`
TarifRS []TarifKlaim `json:"tarif_rs,omitempty"`
DRG *DRGInfo `json:"drg,omitempty"`
SpecialCMG *SpecialCMGInfo `json:"special_cmg,omitempty"`
}
// DiagnosaKlaim represents diagnosis in klaim
type DiagnosaKlaim struct {
KodeDiagnosa string `json:"kode_diagnosa" validate:"required"`
NamaDiagnosa string `json:"nama_diagnosa"`
TipeDiagnosa string `json:"tipe_diagnosa" validate:"required,oneof=1 2"`
}
// ProcedureKlaim represents procedure in klaim
type ProcedureKlaim struct {
KodeTindakan string `json:"kode_tindakan" validate:"required"`
NamaTindakan string `json:"nama_tindakan"`
TanggalTindakan string `json:"tanggal_tindakan" validate:"required"`
Keterangan string `json:"keterangan,omitempty"`
}
// InvestigasiKlaim represents investigation/lab results
type InvestigasiKlaim struct {
KodeInvestigasi string `json:"kode_investigasi" validate:"required"`
NamaInvestigasi string `json:"nama_investigasi"`
Hasil string `json:"hasil,omitempty"`
Satuan string `json:"satuan,omitempty"`
NilaiNormal string `json:"nilai_normal,omitempty"`
}
// ObatKlaim represents medication in klaim
type ObatKlaim struct {
KodeObat string `json:"kode_obat" validate:"required"`
NamaObat string `json:"nama_obat"`
Dosis string `json:"dosis,omitempty"`
Frekuensi string `json:"frekuensi,omitempty"`
Jumlah float64 `json:"jumlah" validate:"min=0"`
Harga float64 `json:"harga" validate:"min=0"`
}
// TarifKlaim represents hospital tariff
type TarifKlaim struct {
KodeTarif string `json:"kode_tarif" validate:"required"`
NamaTarif string `json:"nama_tarif"`
Jumlah int `json:"jumlah" validate:"min=0"`
Tarif float64 `json:"tarif" validate:"min=0"`
Total float64 `json:"total"`
}
// DRGInfo represents DRG information
type DRGInfo struct {
KodeDRG string `json:"kode_drg"`
NamaDRG string `json:"nama_drg"`
TarifDRG float64 `json:"tarif_drg"`
Severity string `json:"severity,omitempty"`
}
// SpecialCMGInfo represents Special CMG information
type SpecialCMGInfo struct {
KodeCMG string `json:"kode_cmg"`
NamaCMG string `json:"nama_cmg"`
TarifCMG float64 `json:"tarif_cmg"`
SubAcute string `json:"sub_acute,omitempty"`
}
// KlaimResponse represents klaim API response
type KlaimResponse struct {
BaseResponse
Data *KlaimResponseData `json:"data,omitempty"`
}
// KlaimResponseData represents processed klaim data
type KlaimResponseData struct {
NoKlaim string `json:"nomor_klaim"`
NoSep string `json:"nomor_sep"`
StatusKlaim string `json:"status_klaim"`
TarifAktual float64 `json:"tarif_aktual"`
TarifRS float64 `json:"tarif_rs"`
TarifApproved float64 `json:"tarif_approved"`
Grouper *GrouperResult `json:"grouper,omitempty"`
}
// === GROUPER MODELS ===
// GrouperRequest represents grouper processing request
type GrouperRequest struct {
BaseRequest
NoSep string `json:"nomor_sep" validate:"required"`
NoKartu string `json:"nomor_kartu" validate:"required"`
TglMasuk string `json:"tgl_masuk" validate:"required"`
TglPulang string `json:"tgl_pulang" validate:"required"`
JnsPelayanan string `json:"jenis_pelayanan" validate:"required,oneof=1 2"`
CaraPulang string `json:"cara_pulang" validate:"required"`
DiagnosaPrimer string `json:"diagnosa_primer" validate:"required"`
DiagnosaSkunder []string `json:"diagnosa_skunder,omitempty"`
Procedure []string `json:"procedure,omitempty"`
AdlScore int `json:"adl_score,omitempty"`
AgeAtAdmission int `json:"age_at_admission" validate:"min=0"`
}
// GrouperResult represents grouper processing result
type GrouperResult struct {
KodeDRG string `json:"kode_drg"`
NamaDRG string `json:"nama_drg"`
TarifDRG float64 `json:"tarif_drg"`
KodeCMG string `json:"kode_cmg,omitempty"`
NamaCMG string `json:"nama_cmg,omitempty"`
TarifCMG float64 `json:"tarif_cmg,omitempty"`
Severity string `json:"severity"`
SubAcute bool `json:"sub_acute"`
Chronic bool `json:"chronic"`
TopUp *TopUpInfo `json:"top_up,omitempty"`
}
// TopUpInfo represents top-up information
type TopUpInfo struct {
Eligible bool `json:"eligible"`
Percentage float64 `json:"percentage"`
Amount float64 `json:"amount"`
}
// GrouperResponse represents grouper API response
type GrouperResponse struct {
BaseResponse
Data *GrouperResult `json:"data,omitempty"`
}

View File

@@ -1,84 +0,0 @@
package models
// PesertaResponse represents the response structure for BPJS participant data
type PesertaResponse struct {
Message string `json:"message"`
Data map[string]interface{} `json:"data"`
}
// PesertaRawResponse represents the raw response structure from BPJS API
type PesertaRawResponse struct {
MetaData struct {
Code string `json:"code"`
Message string `json:"message"`
} `json:"metaData"`
Response interface{} `json:"response"`
}
// PesertaRequest represents the request structure for BPJS participant search
type PesertaRequest struct {
NIK string `json:"nik" binding:"required"`
TglSEP string `json:"tglSEP" binding:"required"`
}
// PesertaData represents the participant data structure
type PesertaData struct {
NoKartu string `json:"noKartu"`
NIK string `json:"nik"`
Nama string `json:"nama"`
Pisa string `json:"pisa"`
Sex string `json:"sex"`
TglLahir string `json:"tglLahir"`
Pob string `json:"pob"`
KdProvider string `json:"kdProvider"`
NmProvider string `json:"nmProvider"`
KelasRawat string `json:"kelasRawat"`
Keterangan string `json:"keterangan"`
NoTelepon string `json:"noTelepon"`
Alamat string `json:"alamat"`
KdPos string `json:"kdPos"`
Pekerjaan string `json:"pekerjaan"`
StatusKawin string `json:"statusKawin"`
TglCetakKartu string `json:"tglCetakKartu"`
TglTAT string `json:"tglTAT"`
TglTMT string `json:"tglTMT"`
ProvUmum struct {
KdProvider string `json:"kdProvider"`
NmProvider string `json:"nmProvider"`
} `json:"provUmum"`
JenisPeserta struct {
KdJenisPeserta string `json:"kdJenisPeserta"`
NmJenisPeserta string `json:"nmJenisPeserta"`
} `json:"jenisPeserta"`
KelasTanggungan struct {
KdKelas string `json:"kdKelas"`
NmKelas string `json:"nmKelas"`
} `json:"kelasTanggungan"`
Informasi struct {
Dinsos string `json:"dinsos"`
NoSKTM string `json:"noSKTM"`
ProlanisPRB string `json:"prolanisPRB"`
} `json:"informasi"`
Cob struct {
NoAsuransi string `json:"noAsuransi"`
NmAsuransi string `json:"nmAsuransi"`
TglTAT string `json:"tglTAT"`
TglTMT string `json:"tglTMT"`
} `json:"cob"`
HakKelas struct {
Kode string `json:"kode"`
Nama string `json:"nama"`
} `json:"hakKelas"`
Mr struct {
NoMR string `json:"noMR"`
NoTelepon string `json:"noTelepon"`
} `json:"mr"`
ProvRujuk struct {
KdProvider string `json:"kdProvider"`
NmProvider string `json:"nmProvider"`
} `json:"provRujuk"`
StatusPeserta struct {
Kode string `json:"kode"`
Nama string `json:"nama"`
} `json:"statusPeserta"`
}

View File

@@ -0,0 +1,29 @@
// internal/models/reference/services.go
package reference
import "context"
// VClaimService defines VClaim service interface
type VClaimService interface {
GetPeserta(ctx context.Context, noKartu string) (*PesertaData, error)
CreateSEP(ctx context.Context, req *SEPRequest) (*SEPData, error)
GetSEP(ctx context.Context, noSep string) (*SEPData, error)
UpdateSEP(ctx context.Context, noSep string, req *SEPRequest) (*SEPData, error)
DeleteSEP(ctx context.Context, noSep string) error
GetRujukan(ctx context.Context, noRujukan string) (*RujukanData, error)
}
// EClaimService defines EClaim service interface
type EClaimService interface {
CreateKlaim(ctx context.Context, req *KlaimRequest) (*KlaimResponseData, error)
GetKlaim(ctx context.Context, noKlaim string) (*KlaimResponseData, error)
UpdateKlaim(ctx context.Context, noKlaim string, req *KlaimRequest) (*KlaimResponseData, error)
ProcessGrouper(ctx context.Context, req *GrouperRequest) (*GrouperResult, error)
}
// AplicareService defines Aplicare service interface
type AplicareService interface {
GetReferensi(ctx context.Context, req *ReferensiRequest) ([]ReferensiData, *PaginationResponse, error)
GetMonitoring(ctx context.Context, req *MonitoringRequest) ([]MonitoringData, *MonitoringSummary, *PaginationResponse, error)
CreateMonitoring(ctx context.Context, req *MonitoringRequest) error
}

View File

@@ -0,0 +1,106 @@
package reference
import (
"regexp"
"strings"
"time"
"github.com/go-playground/validator/v10"
)
// CustomValidator wraps the validator
type CustomValidator struct {
Validator *validator.Validate
}
// Validate validates struct
func (cv *CustomValidator) Validate(i interface{}) error {
return cv.Validator.Struct(i)
}
// RegisterCustomValidations registers custom validation rules
func RegisterCustomValidations(v *validator.Validate) {
// Validate Indonesian phone number
v.RegisterValidation("indonesian_phone", validateIndonesianPhone)
// Validate BPJS card number format
v.RegisterValidation("bpjs_card", validateBPJSCard)
// Validate Indonesian NIK
v.RegisterValidation("indonesian_nik", validateIndonesianNIK)
// Validate date format YYYY-MM-DD
v.RegisterValidation("date_format", validateDateFormat)
// Validate ICD-10 code format
v.RegisterValidation("icd10", validateICD10)
// Validate ICD-9-CM procedure code
v.RegisterValidation("icd9cm", validateICD9CM)
}
func validateIndonesianPhone(fl validator.FieldLevel) bool {
phone := fl.Field().String()
if phone == "" {
return true // Optional field
}
// Indonesian phone number pattern: +62, 62, 08, or 8
pattern := `^(\+?62|0?8)[1-9][0-9]{7,11}$`
matched, _ := regexp.MatchString(pattern, phone)
return matched
}
func validateBPJSCard(fl validator.FieldLevel) bool {
card := fl.Field().String()
if len(card) != 13 {
return false
}
// BPJS card should be numeric
pattern := `^\d{13}$`
matched, _ := regexp.MatchString(pattern, card)
return matched
}
func validateIndonesianNIK(fl validator.FieldLevel) bool {
nik := fl.Field().String()
if len(nik) != 16 {
return false
}
// NIK should be numeric
pattern := `^\d{16}$`
matched, _ := regexp.MatchString(pattern, nik)
return matched
}
func validateDateFormat(fl validator.FieldLevel) bool {
dateStr := fl.Field().String()
_, err := time.Parse("2006-01-02", dateStr)
return err == nil
}
func validateICD10(fl validator.FieldLevel) bool {
code := fl.Field().String()
if code == "" {
return true
}
// Basic ICD-10 pattern: Letter followed by 2 digits, optional dot and more digits
pattern := `^[A-Z]\d{2}(\.\d+)?$`
matched, _ := regexp.MatchString(pattern, strings.ToUpper(code))
return matched
}
func validateICD9CM(fl validator.FieldLevel) bool {
code := fl.Field().String()
if code == "" {
return true
}
// Basic ICD-9-CM procedure pattern: 2-4 digits with optional decimal
pattern := `^\d{2,4}(\.\d+)?$`
matched, _ := regexp.MatchString(pattern, code)
return matched
}

View File

@@ -0,0 +1,144 @@
// internal/models/reference/vclaim.go
package reference
// === PESERTA MODELS ===
// PesertaRequest represents peserta lookup request
type PesertaRequest struct {
BaseRequest
NoKartu string `json:"nokartu" validate:"required,min=13,max=13"`
NIK string `json:"nik,omitempty" validate:"omitempty,min=16,max=16"`
TanggalSEP string `json:"tglsep" validate:"required" example:"2024-01-15"`
NoTelepon string `json:"notelp,omitempty" validate:"omitempty,max=15"`
}
// PesertaData represents peserta information from BPJS
type PesertaData struct {
NoKartu string `json:"noKartu"`
NIK string `json:"nik"`
Nama string `json:"nama"`
Pisa string `json:"pisa"`
Sex string `json:"sex"`
TanggalLahir string `json:"tglLahir"`
TelephoneMsisdn string `json:"tglTAT"`
TelephoneAsat string `json:"tglTMT"`
KodeCabang string `json:"kdCabang"`
NamaCabang string `json:"nmCabang"`
KodeJenisPeserta string `json:"kdJnsPst"`
NamaJenisPeserta string `json:"nmJnsPst"`
KelasRawat string `json:"klsRawat"`
Status string `json:"statusPeserta"`
Aktif string `json:"aktif"`
KeteranganAktif string `json:"ketAktif"`
NoSKTM string `json:"noSKTM,omitempty"`
NoKTP string `json:"noKtp"`
Asuransi string `json:"asuransi,omitempty"`
CoB string `json:"cob,omitempty"`
TunggakanIuran string `json:"tglTunggak,omitempty"`
MR struct {
NoMR string `json:"noMR"`
NamaMR string `json:"nmMR"`
Sex string `json:"sex"`
TglLahir string `json:"tglLahir"`
TglMeninggal string `json:"tglMeninggal,omitempty"`
} `json:"mr,omitempty"`
}
// PesertaResponse represents peserta API response
type PesertaResponse struct {
BaseResponse
Data *PesertaData `json:"data,omitempty"`
MetaData interface{} `json:"metaData,omitempty"`
}
// === SEP (Surat Eligibilitas Peserta) MODELS ===
// SEPRequest represents SEP creation/update request
type SEPRequest struct {
BaseRequest
NoKartu string `json:"noKartu" validate:"required"`
TglSep string `json:"tglSep" validate:"required"`
PPKPelayanan string `json:"ppkPelayanan" validate:"required"`
JnsPelayanan string `json:"jnsPelayanan" validate:"required,oneof=1 2"`
KlsRawat string `json:"klsRawat" validate:"required,oneof=1 2 3"`
NoMR string `json:"noMR" validate:"required"`
Rujukan *SEPRujukan `json:"rujukan"`
Catatan string `json:"catatan,omitempty"`
Diagnosa string `json:"diagnosa" validate:"required"`
PoliTujuan string `json:"poli" validate:"required"`
ExternalUser string `json:"user" validate:"required"`
NoTelp string `json:"noTelp,omitempty"`
}
// SEPRujukan represents rujukan information in SEP
type SEPRujukan struct {
AsalRujukan string `json:"asalRujukan" validate:"required,oneof=1 2"`
TglRujukan string `json:"tglRujukan" validate:"required"`
NoRujukan string `json:"noRujukan" validate:"required"`
PPKRujukan string `json:"ppkRujukan" validate:"required"`
}
// SEPData represents SEP response data
type SEPData struct {
NoSep string `json:"noSep"`
TglSep string `json:"tglSep"`
JnsPelayanan string `json:"jnsPelayanan"`
PoliTujuan string `json:"poli"`
KlsRawat string `json:"klsRawat"`
NoMR string `json:"noMR"`
Rujukan SEPRujukan `json:"rujukan"`
Catatan string `json:"catatan"`
Diagnosa string `json:"diagnosa"`
Peserta PesertaData `json:"peserta"`
Informasi struct {
NoSKDP string `json:"noSKDP,omitempty"`
DPJPLayan string `json:"dpjpLayan"`
NoTelepon string `json:"noTelp"`
SubSpesialis string `json:"subSpesialis,omitempty"`
} `json:"informasi"`
}
// SEPResponse represents SEP API response
type SEPResponse struct {
BaseResponse
Data *SEPData `json:"data,omitempty"`
}
// === RUJUKAN MODELS ===
// RujukanRequest represents rujukan lookup request
type RujukanRequest struct {
BaseRequest
NoRujukan string `json:"noRujukan" validate:"required"`
NoKartu string `json:"noKartu,omitempty"`
}
// RujukanData represents rujukan information
type RujukanData struct {
NoRujukan string `json:"noRujukan"`
TglRujukan string `json:"tglRujukan"`
NoKartu string `json:"noKartu"`
Nama string `json:"nama"`
KelasRawat string `json:"kelasRawat"`
Diagnosa struct {
KodeDiagnosa string `json:"kdDiagnosa"`
NamaDiagnosa string `json:"nmDiagnosa"`
} `json:"diagnosa"`
PoliRujukan struct {
KodePoli string `json:"kdPoli"`
NamaPoli string `json:"nmPoli"`
} `json:"poliRujukan"`
ProvPerujuk struct {
KodeProvider string `json:"kdProvider"`
NamaProvider string `json:"nmProvider"`
} `json:"provPerujuk"`
PelayananInfo string `json:"pelayanan"`
StatusRujukan string `json:"statusRujukan"`
}
// RujukanResponse represents rujukan API response
type RujukanResponse struct {
BaseResponse
Data *RujukanData `json:"data,omitempty"`
List []RujukanData `json:"list,omitempty"`
}

View File

@@ -1,144 +0,0 @@
package models
// SepPostRequest represents the request payload for creating a SEP
type SepPostRequest struct {
TSep TSepPost `json:"tsep" binding:"required"`
}
// TSepPost contains the main SEP data for creation
type TSepPost struct {
NoKartu string `json:"noKartu" binding:"required"`
TglSep string `json:"tglSep" binding:"required"` // yyyy-MM-dd
PpkPelayanan string `json:"ppkPelayanan" binding:"required"`
JnsPelayanan string `json:"jnsPelayanan" binding:"required"`
KlsRawat KlsRawatPost `json:"klsRawat" binding:"required"`
NoMR string `json:"noMR" binding:"required"`
Rujukan Rujukan `json:"rujukan" binding:"required"`
Catatan string `json:"catatan"`
DiagAwal string `json:"diagAwal" binding:"required"`
Poli Poli `json:"poli" binding:"required"`
Cob Flag `json:"cob" binding:"required"`
Katarak Flag `json:"katarak" binding:"required"`
Jaminan Jaminan `json:"jaminan" binding:"required"`
TujuanKunj string `json:"tujuanKunj"`
FlagProcedure string `json:"flagProcedure"`
KdPenunjang string `json:"kdPenunjang"`
AssesmentPel string `json:"assesmentPel"`
Skdp Skdp `json:"skdp" binding:"required"`
DpjpLayan string `json:"dpjpLayan"`
NoTelp string `json:"noTelp"`
User string `json:"user" binding:"required"`
}
// KlsRawatPost represents class of care data for POST requests
type KlsRawatPost struct {
KlsRawatHak string `json:"klsRawatHak" binding:"required"`
KlsRawatNaik string `json:"klsRawatNaik"`
Pembiayaan string `json:"pembiayaan"`
PenanggungJawab string `json:"penanggungJawab"`
}
// Rujukan represents referral data
type Rujukan struct {
AsalRujukan string `json:"asalRujukan" binding:"required"`
TglRujukan string `json:"tglRujukan" binding:"required"`
NoRujukan string `json:"noRujukan" binding:"required"`
PpkRujukan string `json:"ppkRujukan" binding:"required"`
}
// Poli represents poly/department data
type Poli struct {
Tujuan string `json:"tujuan" binding:"required"`
Eksekutif string `json:"eksekutif" binding:"required"`
}
// Flag represents a generic flag structure
type Flag struct {
Flag string `json:"flag" binding:"required"`
}
// Jaminan represents insurance guarantee data
type Jaminan struct {
LakaLantas string `json:"lakaLantas" binding:"required"`
NoLP string `json:"noLP"`
Penjamin Penjamin `json:"penjamin"`
}
// Penjamin represents guarantor data
type Penjamin struct {
TglKejadian string `json:"tglKejadian"`
Keterangan string `json:"keterangan"`
Suplesi Suplesi `json:"suplesi"`
}
// Suplesi represents supplementary data
type Suplesi struct {
Suplesi string `json:"suplesi"`
NoSepSuplesi string `json:"noSepSuplesi"`
LokasiLaka LokasiLaka `json:"lokasiLaka"`
}
// LokasiLaka represents accident location data
type LokasiLaka struct {
KdPropinsi string `json:"kdPropinsi"`
KdKabupaten string `json:"kdKabupaten"`
KdKecamatan string `json:"kdKecamatan"`
}
// Skdp represents SKDP data
type Skdp struct {
NoSurat string `json:"noSurat" binding:"required"`
KodeDPJP string `json:"kodeDPJP" binding:"required"`
}
// SepPutRequest represents the request payload for updating a SEP
type SepPutRequest struct {
TSep TSepPut `json:"tsep" binding:"required"`
}
// TSepPut contains the main SEP data for updates
type TSepPut struct {
NoSep string `json:"noSep" binding:"required"`
KlsRawat KlsRawatPut `json:"klsRawat"`
NoMR string `json:"noMR"`
Catatan string `json:"catatan"`
DiagAwal string `json:"diagAwal"`
Poli Poli `json:"poli"`
Cob Flag `json:"cob"`
Katarak Flag `json:"katarak"`
Jaminan Jaminan `json:"jaminan"`
DpjpLayan string `json:"dpjpLayan"`
NoTelp string `json:"noTelp"`
User string `json:"user" binding:"required"`
}
// KlsRawatPut represents class of care data for PUT requests
type KlsRawatPut struct {
KlsRawatHak string `json:"klsRawatHak"`
KlsRawatNaik string `json:"klsRawatNaik"`
Pembiayaan string `json:"pembiayaan"`
PenanggungJawab string `json:"penanggungJawab"`
}
// SepDeleteRequest represents the request payload for deleting a SEP
type SepDeleteRequest struct {
TSep struct {
NoSep string `json:"noSep" binding:"required"`
User string `json:"user" binding:"required"`
} `json:"tsep" binding:"required"`
}
// SepResponse represents the standard response for SEP operations
type SepResponse struct {
Message string `json:"message"`
Data map[string]interface{} `json:"data,omitempty"`
}
// SepRawResponse represents the raw response from BPJS API
type SepRawResponse struct {
MetaData struct {
Code string `json:"code"`
Message string `json:"message"`
} `json:"metaData"`
Response interface{} `json:"response"`
}

View File

@@ -5,7 +5,6 @@ import (
"api-service/internal/database"
authHandlers "api-service/internal/handlers/auth"
healthcheckHandlers "api-service/internal/handlers/healthcheck"
bpjsPesertaHandlers "api-service/internal/handlers/reference"
retribusiHandlers "api-service/internal/handlers/retribusi"
"api-service/internal/middleware"
services "api-service/internal/services/auth"
@@ -65,10 +64,6 @@ func RegisterRoutes(cfg *config.Config) *gin.Engine {
v1.POST("/token/generate", tokenHandler.GenerateToken)
v1.POST("/token/generate-direct", tokenHandler.GenerateTokenDirect)
// BPJS endpoints
bpjsPesertaHandler := bpjsPesertaHandlers.NewPesertaHandler(cfg.Bpjs)
v1.GET("/bpjs/peserta/nik/:nik/tglSEP/:tglSEP", bpjsPesertaHandler.GetPesertaByNIK)
// ============= PUBLISHED ROUTES ===============================================
// // Retribusi endpoints

View File

@@ -22,8 +22,8 @@ type VClaimService interface {
Post(ctx context.Context, endpoint string, payload interface{}, result interface{}) error
Put(ctx context.Context, endpoint string, payload interface{}, result interface{}) error
Delete(ctx context.Context, endpoint string, result interface{}) error
GetRawResponse(ctx context.Context, endpoint string) (*ResponDTO, error)
PostRawResponse(ctx context.Context, endpoint string, payload interface{}) (*ResponDTO, error)
GetRawResponse(ctx context.Context, endpoint string) (*ResponDTOVclaim, error)
PostRawResponse(ctx context.Context, endpoint string, payload interface{}) (*ResponDTOVclaim, error)
}
// Service struct for VClaim service
@@ -33,7 +33,7 @@ type Service struct {
}
// Response structures
type ResponMentahDTO struct {
type ResponMentahDTOVclaim struct {
MetaData struct {
Code string `json:"code"`
Message string `json:"message"`
@@ -41,7 +41,7 @@ type ResponMentahDTO struct {
Response string `json:"response"`
}
type ResponDTO struct {
type ResponDTOVclaim struct {
MetaData struct {
Code string `json:"code"`
Message string `json:"message"`
@@ -133,7 +133,7 @@ func (s *Service) prepareRequest(ctx context.Context, method, endpoint string, b
}
// processResponse processes response from VClaim API
func (s *Service) processResponse(res *http.Response) (*ResponDTO, error) {
func (s *Service) processResponse(res *http.Response) (*ResponDTOVclaim, error) {
defer res.Body.Close()
log.Info().
@@ -170,7 +170,7 @@ func (s *Service) processResponse(res *http.Response) (*ResponDTO, error) {
}
// Parse raw response
var respMentah ResponMentahDTO
var respMentah ResponMentahDTOVclaim
if err := json.Unmarshal(body, &respMentah); err != nil {
log.Error().
Err(err).
@@ -186,7 +186,7 @@ func (s *Service) processResponse(res *http.Response) (*ResponDTO, error) {
Msg("Response metadata")
// Create final response
finalResp := &ResponDTO{
finalResp := &ResponDTOVclaim{
MetaData: respMentah.MetaData,
}
@@ -312,7 +312,7 @@ func (s *Service) Delete(ctx context.Context, endpoint string, result interface{
}
// GetRawResponse returns raw response without mapping
func (s *Service) GetRawResponse(ctx context.Context, endpoint string) (*ResponDTO, error) {
func (s *Service) GetRawResponse(ctx context.Context, endpoint string) (*ResponDTOVclaim, error) {
req, err := s.prepareRequest(ctx, http.MethodGet, endpoint, nil)
if err != nil {
return nil, err
@@ -327,7 +327,7 @@ func (s *Service) GetRawResponse(ctx context.Context, endpoint string) (*ResponD
}
// PostRawResponse returns raw response without mapping
func (s *Service) PostRawResponse(ctx context.Context, endpoint string, payload interface{}) (*ResponDTO, error) {
func (s *Service) PostRawResponse(ctx context.Context, endpoint string, payload interface{}) (*ResponDTOVclaim, error) {
var buf bytes.Buffer
if payload != nil {
if err := json.NewEncoder(&buf).Encode(payload); err != nil {
@@ -349,7 +349,7 @@ func (s *Service) PostRawResponse(ctx context.Context, endpoint string, payload
}
// mapToResult maps the final response to the result interface
func mapToResult(resp *ResponDTO, result interface{}) error {
func mapToResult(resp *ResponDTOVclaim, result interface{}) error {
respBytes, err := json.Marshal(resp)
if err != nil {
return fmt.Errorf("failed to marshal final response: %w", err)

149
services-config-bpjs.yaml Normal file
View File

@@ -0,0 +1,149 @@
# services-config-complete.yaml
global:
module_name: "api-service"
output_dir: "internal/handlers"
package_prefix: "api-service"
enable_swagger: true
enable_logging: true
enable_metrics: true
services:
vclaim:
name: "VClaim"
category: "vclaim"
package: "vclaim"
description: "BPJS VClaim service for eligibility and SEP management"
base_url: "https://apijkn.bpjs-kesehatan.go.id/vclaim-rest"
timeout: 30
retry_count: 3
middleware:
- "RequestLogger"
- "ResponseLogger"
- "RateLimiter"
dependencies:
- "database"
- "redis"
endpoints:
peserta:
methods: ["GET"]
get_path: "/Peserta/:nokartu"
model: "PesertaRequest"
response_model: "PesertaResponse"
description: "Get participant eligibility information"
summary: "Get Participant Info"
tags: ["vclaim", "peserta"]
require_auth: true
rate_limit: 100
cache_enabled: true
cache_ttl: 300
sep:
methods: ["GET", "POST", "PUT", "DELETE"]
get_path: "/SEP/:nosep"
post_path: "/sep"
put_path: "/sep/:nosep"
delete_path: "/sep/:nosep"
model: "SEPRequest"
response_model: "SEPResponse"
description: "Manage SEP (Surat Eligibilitas Peserta)"
summary: "SEP Management"
tags: ["vclaim", "sep"]
require_auth: true
rate_limit: 50
cache_enabled: true
cache_ttl: 180
custom_headers:
X-Service: "VClaim"
X-Version: "2.0"
rujukan:
methods: ["GET"]
get_path: "/rujukan/:norujukan"
model: "RujukanRequest"
response_model: "RujukanResponse"
description: "Get referral information"
summary: "Get Referral Info"
tags: ["vclaim", "rujukan"]
require_auth: true
rate_limit: 100
cache_enabled: true
cache_ttl: 600
eclaim:
name: "EClaim"
category: "eclaim"
package: "eclaim"
description: "BPJS EClaim service for claim processing and grouper"
base_url: "https://apijkn.bpjs-kesehatan.go.id/new-eclaim-rest"
timeout: 60
retry_count: 2
middleware:
- "RequestLogger"
- "ResponseLogger"
- "ClaimValidator"
dependencies:
- "database"
- "grouper_service"
endpoints:
klaim:
methods: ["GET", "POST", "PUT"]
get_path: "/klaim/:noklaim"
post_path: "/klaim"
put_path: "/klaim/:noklaim"
model: "KlaimRequest"
response_model: "KlaimResponse"
description: "Manage insurance claims"
summary: "Claim Management"
tags: ["eclaim", "klaim"]
require_auth: true
rate_limit: 30
cache_enabled: false
grouper:
methods: ["POST"]
post_path: "/grouper"
model: "GrouperRequest"
response_model: "GrouperResponse"
description: "Process claim grouping and pricing"
summary: "Claim Grouper"
tags: ["eclaim", "grouper"]
require_auth: true
rate_limit: 20
cache_enabled: true
cache_ttl: 120
aplicare:
name: "Aplicare"
category: "aplicare"
package: "aplicare"
description: "BPJS Aplicare service for reference data and monitoring"
base_url: "https://apijkn.bpjs-kesehatan.go.id/aplicaresws"
timeout: 45
retry_count: 3
middleware:
- "RequestLogger"
- "ResponseLogger"
dependencies:
- "database"
endpoints:
referensi:
methods: ["GET"]
get_path: "/referensi/:jenis"
model: "ReferensiRequest"
response_model: "ReferensiResponse"
description: "Get reference data (diagnoses, procedures, etc.)"
summary: "Get Reference Data"
tags: ["aplicare", "referensi"]
require_auth: true
rate_limit: 200
cache_enabled: true
cache_ttl: 3600
monitoring:
methods: ["GET", "POST"]
get_path: "/monitoring/:tanggal"
post_path: "/monitoring"
model: "MonitoringRequest"
response_model: "MonitoringResponse"
description: "Healthcare monitoring and reporting"
summary: "Monitoring Data"
tags: ["aplicare", "monitoring"]
require_auth: true
rate_limit: 50
cache_enabled: false

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

573
vclaim_handler.go Normal file
View File

@@ -0,0 +1,573 @@
// Code generated by generate-dynamic-handler.go; DO NOT EDIT.
// Generated at: 2025-08-28 14:59:09
// Service: VClaim (vclaim)
// Description: BPJS VClaim service for eligibility and SEP management
package handlers
import (
"context"
"fmt"
"net/http"
"strings"
"time"
"api-service/internal/config"
"api-service/internal/models/reference"
services "api-service/internal/services/bpjs"
"api-service/pkg/logger"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"github.com/google/uuid"
)
// VClaimHandler handles VClaim BPJS services
type VClaimHandler struct {
service services.VClaimService
validator *validator.Validate
logger logger.Logger
config *config.BpjsConfig
}
// VClaimHandlerConfig contains configuration for VClaimHandler
type VClaimHandlerConfig struct {
BpjsConfig *config.BpjsConfig
Logger logger.Logger
Validator *validator.Validate
}
// NewVClaimHandler creates a new VClaimHandler
func NewVClaimHandler(cfg VClaimHandlerConfig) *VClaimHandler {
return &VClaimHandler{
service: services.NewService(*cfg.BpjsConfig),
validator: cfg.Validator,
logger: cfg.Logger,
config: cfg.BpjsConfig,
}
}
// GetPESERTA retrieves Peserta data
// @Summary Get Peserta data
// @Description Get participant eligibility information
// @Tags vclaim,peserta
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param nokartu path string true "Nokartu"
// @Success 200 {object} reference.PesertaResponse
// @Failure 400 {object} reference.ErrorResponse
// @Failure 500 {object} reference.ErrorResponse
// @Router /Peserta/:nokartu [get]
func (h *VClaimHandler) GetPESERTA(c *gin.Context) {
ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second)
defer cancel()
// Generate request ID if not present
requestID := c.GetHeader("X-Request-ID")
if requestID == "" {
requestID = uuid.New().String()
c.Header("X-Request-ID", requestID)
}
// Authentication check
if err := h.authenticateRequest(c); err != nil {
h.logger.Error("Authentication failed", "error", err.Error(), "request_id", requestID)
c.JSON(http.StatusUnauthorized, reference.ErrorResponse{
Status: "error",
Message: "Authentication failed",
RequestID: requestID,
})
return
}
// Extract path parameters
nokartu := c.Param("nokartu")
if nokartu == "" {
h.logger.Error("Missing required parameter: nokartu", "request_id", requestID)
c.JSON(http.StatusBadRequest, reference.ErrorResponse{
Status: "error",
Message: "Missing required parameter: nokartu",
RequestID: requestID,
})
return
}
// Check cache first
cacheKey := fmt.Sprintf("vclaim:peserta:%s", nokartu)
if cached, found := h.getCachedResponse(cacheKey); found {
h.logger.Info("Cache hit for GetPESERTA", "request_id", requestID, "cache_key", cacheKey)
c.Header("X-Cache", "HIT")
c.JSON(http.StatusOK, cached)
return
}
h.logger.Info("Processing GetPESERTA request",
"request_id", requestID,
"endpoint", "/Peserta/:nokartu",
"nokartu", nokartu)
// Call service method
result, err := h.service.GetPESERTA(ctx, nokartu)
if err != nil {
h.logger.Error("Failed to get Peserta",
"error", err.Error(),
"request_id", requestID)
c.JSON(http.StatusInternalServerError, reference.ErrorResponse{
Status: "error",
Message: "Internal server error",
RequestID: requestID,
})
return
}
// Prepare response
response := reference.PesertaResponse{
Status: "success",
Data: result,
RequestID: requestID,
}
// Cache successful response
h.setCachedResponse(cacheKey, response, 300)
c.Header("X-Cache", "MISS")
c.JSON(http.StatusOK, response)
}
// GetSEP retrieves Sep data
// @Summary Get Sep data
// @Description Manage SEP (Surat Eligibilitas Peserta)
// @Tags vclaim,sep
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param nosep path string true "Nosep"
// @Success 200 {object} reference.SEPResponse
// @Failure 400 {object} reference.ErrorResponse
// @Failure 500 {object} reference.ErrorResponse
// @Router /SEP/:nosep [get]
func (h *VClaimHandler) GetSEP(c *gin.Context) {
ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second)
defer cancel()
// Generate request ID if not present
requestID := c.GetHeader("X-Request-ID")
if requestID == "" {
requestID = uuid.New().String()
c.Header("X-Request-ID", requestID)
}
// Authentication check
if err := h.authenticateRequest(c); err != nil {
h.logger.Error("Authentication failed", "error", err.Error(), "request_id", requestID)
c.JSON(http.StatusUnauthorized, reference.ErrorResponse{
Status: "error",
Message: "Authentication failed",
RequestID: requestID,
})
return
}
// Extract path parameters
nosep := c.Param("nosep")
if nosep == "" {
h.logger.Error("Missing required parameter: nosep", "request_id", requestID)
c.JSON(http.StatusBadRequest, reference.ErrorResponse{
Status: "error",
Message: "Missing required parameter: nosep",
RequestID: requestID,
})
return
}
// Check cache first
cacheKey := fmt.Sprintf("vclaim:sep:%s", nosep)
if cached, found := h.getCachedResponse(cacheKey); found {
h.logger.Info("Cache hit for GetSEP", "request_id", requestID, "cache_key", cacheKey)
c.Header("X-Cache", "HIT")
c.JSON(http.StatusOK, cached)
return
}
h.logger.Info("Processing GetSEP request",
"request_id", requestID,
"endpoint", "/SEP/:nosep",
"nosep", nosep)
// Call service method
result, err := h.service.GetSEP(ctx, nosep)
if err != nil {
h.logger.Error("Failed to get Sep",
"error", err.Error(),
"request_id", requestID)
c.JSON(http.StatusInternalServerError, reference.ErrorResponse{
Status: "error",
Message: "Internal server error",
RequestID: requestID,
})
return
}
// Prepare response
response := reference.SEPResponse{
Status: "success",
Data: result,
RequestID: requestID,
}
// Cache successful response
h.setCachedResponse(cacheKey, response, 180)
c.Header("X-Cache", "MISS")
c.JSON(http.StatusOK, response)
}
// CreateSEP creates new Sep
// @Summary Create Sep
// @Description Manage SEP (Surat Eligibilitas Peserta)
// @Tags vclaim,sep
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param request body reference.SEPRequest true "Sep data"
// @Success 201 {object} reference.SEPResponse
// @Failure 400 {object} reference.ErrorResponse
// @Failure 500 {object} reference.ErrorResponse
// @Router /sep [post]
func (h *VClaimHandler) CreateSEP(c *gin.Context) {
ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second)
defer cancel()
requestID := c.GetHeader("X-Request-ID")
if requestID == "" {
requestID = uuid.New().String()
c.Header("X-Request-ID", requestID)
}
// Authentication check
if err := h.authenticateRequest(c); err != nil {
h.logger.Error("Authentication failed", "error", err.Error(), "request_id", requestID)
c.JSON(http.StatusUnauthorized, reference.ErrorResponse{
Status: "error",
Message: "Authentication failed",
RequestID: requestID,
})
return
}
var req reference.SEPRequest
if err := c.ShouldBindJSON(&req); err != nil {
h.logger.Error("Invalid request body",
"error", err.Error(),
"request_id", requestID)
c.JSON(http.StatusBadRequest, reference.ErrorResponse{
Status: "error",
Message: "Invalid request body: " + err.Error(),
RequestID: requestID,
})
return
}
// Validate request
if err := h.validator.Struct(&req); err != nil {
h.logger.Error("Validation failed",
"error", err.Error(),
"request_id", requestID)
c.JSON(http.StatusBadRequest, reference.ErrorResponse{
Status: "error",
Message: "Validation failed: " + err.Error(),
RequestID: requestID,
})
return
}
h.logger.Info("Processing CreateSEP request", "request_id", requestID)
// Call service method
result, err := h.service.CreateSEP(ctx, &req)
if err != nil {
h.logger.Error("Failed to create Sep",
"error", err.Error(),
"request_id", requestID)
c.JSON(http.StatusInternalServerError, reference.ErrorResponse{
Status: "error",
Message: "Internal server error",
RequestID: requestID,
})
return
}
response := reference.SEPResponse{
Status: "success",
Data: result,
RequestID: requestID,
}
c.JSON(http.StatusCreated, response)
}
// UpdateSEP updates existing Sep
// @Summary Update Sep
// @Description Manage SEP (Surat Eligibilitas Peserta)
// @Tags vclaim,sep
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param nosep path string true "Nosep"
// @Param request body reference.SEPRequest true "Sep data"
// @Success 200 {object} reference.SEPResponse
// @Failure 400 {object} reference.ErrorResponse
// @Failure 500 {object} reference.ErrorResponse
// @Router /sep/:nosep [put]
func (h *VClaimHandler) UpdateSEP(c *gin.Context) {
ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second)
defer cancel()
requestID := c.GetHeader("X-Request-ID")
if requestID == "" {
requestID = uuid.New().String()
c.Header("X-Request-ID", requestID)
}
// Extract path parameters
nosep := c.Param("nosep")
if nosep == "" {
c.JSON(http.StatusBadRequest, reference.ErrorResponse{
Status: "error",
Message: "Missing required parameter: nosep",
RequestID: requestID,
})
return
}
var req reference.SEPRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, reference.ErrorResponse{
Status: "error",
Message: "Invalid request body: " + err.Error(),
RequestID: requestID,
})
return
}
if err := h.validator.Struct(&req); err != nil {
c.JSON(http.StatusBadRequest, reference.ErrorResponse{
Status: "error",
Message: "Validation failed: " + err.Error(),
RequestID: requestID,
})
return
}
// Invalidate cache
cacheKey := fmt.Sprintf("vclaim:sep:%s", nosep)
h.invalidateCache(cacheKey)
// Call service method
result, err := h.service.UpdateSEP(ctx, nosep, &req)
if err != nil {
h.logger.Error("Failed to update Sep", "error", err.Error(), "request_id", requestID)
c.JSON(http.StatusInternalServerError, reference.ErrorResponse{
Status: "error",
Message: "Internal server error",
RequestID: requestID,
})
return
}
response := reference.SEPResponse{
Status: "success",
Data: result,
RequestID: requestID,
}
c.JSON(http.StatusOK, response)
}
// DeleteSEP deletes existing Sep
// @Summary Delete Sep
// @Description Manage SEP (Surat Eligibilitas Peserta)
// @Tags vclaim,sep
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param nosep path string true "Nosep"
// @Success 200 {object} reference.BaseResponse
// @Failure 400 {object} reference.ErrorResponse
// @Failure 500 {object} reference.ErrorResponse
// @Router /sep/:nosep [delete]
func (h *VClaimHandler) DeleteSEP(c *gin.Context) {
ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second)
defer cancel()
requestID := c.GetHeader("X-Request-ID")
if requestID == "" {
requestID = uuid.New().String()
c.Header("X-Request-ID", requestID)
}
// Extract path parameters
nosep := c.Param("nosep")
if nosep == "" {
c.JSON(http.StatusBadRequest, reference.ErrorResponse{
Status: "error",
Message: "Missing required parameter: nosep",
RequestID: requestID,
})
return
}
// Invalidate cache
cacheKey := fmt.Sprintf("vclaim:sep:%s", nosep)
h.invalidateCache(cacheKey)
// Call service method
err := h.service.DeleteSEP(ctx, nosep)
if err != nil {
h.logger.Error("Failed to delete Sep", "error", err.Error(), "request_id", requestID)
c.JSON(http.StatusInternalServerError, reference.ErrorResponse{
Status: "error",
Message: "Internal server error",
RequestID: requestID,
})
return
}
response := reference.BaseResponse{
Status: "success",
Message: "Sep deleted successfully",
RequestID: requestID,
}
c.JSON(http.StatusOK, response)
}
// GetRUJUKAN retrieves Rujukan data
// @Summary Get Rujukan data
// @Description Get referral information
// @Tags vclaim,rujukan
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param norujukan path string true "Norujukan"
// @Success 200 {object} reference.RujukanResponse
// @Failure 400 {object} reference.ErrorResponse
// @Failure 500 {object} reference.ErrorResponse
// @Router /rujukan/:norujukan [get]
func (h *VClaimHandler) GetRUJUKAN(c *gin.Context) {
ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second)
defer cancel()
// Generate request ID if not present
requestID := c.GetHeader("X-Request-ID")
if requestID == "" {
requestID = uuid.New().String()
c.Header("X-Request-ID", requestID)
}
// Authentication check
if err := h.authenticateRequest(c); err != nil {
h.logger.Error("Authentication failed", "error", err.Error(), "request_id", requestID)
c.JSON(http.StatusUnauthorized, reference.ErrorResponse{
Status: "error",
Message: "Authentication failed",
RequestID: requestID,
})
return
}
// Extract path parameters
norujukan := c.Param("norujukan")
if norujukan == "" {
h.logger.Error("Missing required parameter: norujukan", "request_id", requestID)
c.JSON(http.StatusBadRequest, reference.ErrorResponse{
Status: "error",
Message: "Missing required parameter: norujukan",
RequestID: requestID,
})
return
}
// Check cache first
cacheKey := fmt.Sprintf("vclaim:rujukan:%s", norujukan)
if cached, found := h.getCachedResponse(cacheKey); found {
h.logger.Info("Cache hit for GetRUJUKAN", "request_id", requestID, "cache_key", cacheKey)
c.Header("X-Cache", "HIT")
c.JSON(http.StatusOK, cached)
return
}
h.logger.Info("Processing GetRUJUKAN request",
"request_id", requestID,
"endpoint", "/rujukan/:norujukan",
"norujukan", norujukan)
// Call service method
result, err := h.service.GetRUJUKAN(ctx, norujukan)
if err != nil {
h.logger.Error("Failed to get Rujukan",
"error", err.Error(),
"request_id", requestID)
c.JSON(http.StatusInternalServerError, reference.ErrorResponse{
Status: "error",
Message: "Internal server error",
RequestID: requestID,
})
return
}
// Prepare response
response := reference.RujukanResponse{
Status: "success",
Data: result,
RequestID: requestID,
}
// Cache successful response
h.setCachedResponse(cacheKey, response, 600)
c.Header("X-Cache", "MISS")
c.JSON(http.StatusOK, response)
}
// RegisterRoutes registers all VClaim routes
func (h *VClaimHandler) RegisterRoutes(router *gin.RouterGroup) {
router.GET("/Peserta/:nokartu", h.GetPESERTA)
router.GET("/SEP/:nosep", h.GetSEP)
router.POST("/sep", h.CreateSEP)
router.PUT("/sep/:nosep", h.UpdateSEP)
router.DELETE("/sep/:nosep", h.DeleteSEP)
router.GET("/rujukan/:norujukan", h.GetRUJUKAN)
}
// Helper methods
func (h *VClaimHandler) authenticateRequest(c *gin.Context) error {
token := c.GetHeader("Authorization")
if token == "" {
return fmt.Errorf("missing authorization header")
}
if strings.HasPrefix(token, "Bearer ") {
token = strings.TrimPrefix(token, "Bearer ")
}
return h.auth.ValidateToken(token)
}
func (h *VClaimHandler) getCachedResponse(key string) (interface{}, bool) {
if h.cache == nil {
return nil, false
}
return h.cache.Get(key)
}
func (h *VClaimHandler) setCachedResponse(key string, data interface{}, ttl int) {
if h.cache == nil {
return
}
h.cache.Set(key, data, time.Duration(ttl)*time.Second)
}
func (h *VClaimHandler) invalidateCache(key string) {
if h.cache == nil {
return
}
h.cache.Delete(key)
}

365
vclaim_handler2.go Normal file
View File

@@ -0,0 +1,365 @@
// Code generated by generate-dynamic-handler.go; DO NOT EDIT.
// Generated at: 2025-08-28 14:47:36
// Service: VClaim (vclaim)
// Description: BPJS VClaim service for eligibility and SEP management
package handlers
import (
"api-service/internal/config"
"api-service/internal/models/reference"
services "api-service/internal/services/bpjs"
"api-service/pkg/logger"
"context"
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"github.com/google/uuid"
)
// VClaimHandler handles VClaim BPJS services
type VClaimHandler struct {
service services.VClaimService
validator *validator.Validate
logger logger.Logger
config config.BpjsConfig
}
// VClaimHandlerConfig contains configuration for VClaimHandler
type VClaimHandlerConfig struct {
BpjsConfig config.BpjsConfig
Logger logger.Logger
Validator *validator.Validate
}
// NewVClaimHandler creates a new VClaimHandler
func NewVClaimHandler(cfg VClaimHandlerConfig) *VClaimHandler {
return &VClaimHandler{
service: services.NewService(cfg.BpjsConfig),
validator: cfg.Validator,
logger: cfg.Logger,
config: cfg.BpjsConfig,
}
}
// GetPESERTA retrieves Peserta data
// @Summary Get Peserta data
// @Description Get participant eligibility information
// @Tags vclaim,peserta
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param nokartu path string true "nokartu"
// @Success 200 {object} reference.PesertaResponse
// @Failure 400 {object} reference.ErrorResponse
// @Failure 500 {object} reference.ErrorResponse
// @Router /Peserta/:nokartu [get]
func (h *VClaimHandler) GetPeserta(c *gin.Context) {
ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second)
defer cancel()
// Generate request ID if not present
requestID := c.GetHeader("X-Request-ID")
if requestID == "" {
requestID = uuid.New().String()
c.Header("X-Request-ID", requestID)
}
h.logger.Info("Processing GetPeserta request", map[string]interface{}{
"request_id": requestID,
"endpoint": "/Peserta/:nokartu",
"nokartu": c.Param("nokartu"),
})
// Extract path parameters
nokartu := c.Param("nokartu")
if nokartu == "" {
h.logger.Error("Missing required parameter nokartu", map[string]interface{}{
"request_id": requestID,
})
c.JSON(http.StatusBadRequest, reference.ErrorResponse{
Status: "error",
Message: "Missing required parameter nokartu",
RequestID: requestID,
})
return
}
// Call service method
var response reference.PesertaResponse
response, err := h.service.GetPeserta(ctx, nokartu)
if err != nil {
h.logger.Error("Failed to get Peserta", map[string]interface{}{
"error": err.Error(),
"request_id": requestID,
})
c.JSON(http.StatusInternalServerError, reference.ErrorResponse{
Status: "error",
Message: "Internal server error",
RequestID: requestID,
})
return
}
// Ensure response has proper fields
response.Status = "success"
response.RequestID = requestID
c.JSON(http.StatusOK, response)
}
// GetSEP retrieves Sep data
// @Summary Get Sep data
// @Description Manage SEP (Surat Eligibilitas Peserta)
// @Tags vclaim,sep
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param nosep path string true "nosep"
// @Success 200 {object} reference.SEPResponse
// @Failure 400 {object} reference.ErrorResponse
// @Failure 500 {object} reference.ErrorResponse
// @Router /SEP/:nosep [get]
func (h *VClaimHandler) GetSEP(c *gin.Context) {
ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second)
defer cancel()
// Generate request ID if not present
requestID := c.GetHeader("X-Request-ID")
if requestID == "" {
requestID = uuid.New().String()
c.Header("X-Request-ID", requestID)
}
h.logger.Info("Processing GetSep request", map[string]interface{}{
"request_id": requestID,
"endpoint": "/SEP/:nosep",
"nosep": c.Param("nosep"),
})
// Extract path parameters
nosep := c.Param("nosep")
if nosep == "" {
h.logger.Error("Missing required parameter nosep", map[string]interface{}{
"request_id": requestID,
})
c.JSON(http.StatusBadRequest, reference.ErrorResponse{
Status: "error",
Message: "Missing required parameter nosep",
RequestID: requestID,
})
return
}
// Call service method
var response reference.SEPResponse
result, err := h.service.GetSEP(ctx, nosep)
if err != nil {
h.logger.Error("Failed to get Sep", map[string]interface{}{
"error": err.Error(),
"request_id": requestID,
})
c.JSON(http.StatusInternalServerError, reference.ErrorResponse{
Status: "error",
Message: "Internal server error",
RequestID: requestID,
})
return
}
// Ensure response has proper fields
response.Status = "success"
response.RequestID = requestID
c.JSON(http.StatusOK, response)
}
// CreateSEP creates new Sep
// @Summary Create Sep
// @Description Manage SEP (Surat Eligibilitas Peserta)
// @Tags vclaim,sep
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param request body reference.SEPRequest true "Sep data"
// @Success 201 {object} reference.SEPResponse
// @Failure 400 {object} reference.ErrorResponse
// @Failure 500 {object} reference.ErrorResponse
// @Router /sep [post]
func (h *VClaimHandler) CreateSEP(c *gin.Context) {
ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second)
defer cancel()
requestID := c.GetHeader("X-Request-ID")
if requestID == "" {
requestID = uuid.New().String()
c.Header("X-Request-ID", requestID)
}
h.logger.Info("Processing CreateSep request", map[string]interface{}{
"request_id": requestID,
})
var req reference.SEPRequest
if err := c.ShouldBindJSON(&req); err != nil {
h.logger.Error("Invalid request body", map[string]interface{}{
"error": err.Error(),
"request_id": requestID,
})
c.JSON(http.StatusBadRequest, reference.ErrorResponse{
Status: "error",
Message: "Invalid request body: " + err.Error(),
RequestID: requestID,
})
return
}
// Validate request
if err := h.validator.Struct(&req); err != nil {
h.logger.Error("Validation failed", map[string]interface{}{
"error": err.Error(),
"request_id": requestID,
})
c.JSON(http.StatusBadRequest, reference.ErrorResponse{
Status: "error",
Message: "Validation failed: " + err.Error(),
RequestID: requestID,
})
return
}
// Call service method
var response reference.SEPResponse
response, err := h.service.CreateSEP(ctx, &req)
if err != nil {
h.logger.Error("Failed to create Sep", map[string]interface{}{
"error": err.Error(),
"request_id": requestID,
})
c.JSON(http.StatusInternalServerError, reference.ErrorResponse{
Status: "error",
Message: "Internal server error",
RequestID: requestID,
})
return
}
// Ensure response has proper fields
response.Status = "success"
response.RequestID = requestID
c.JSON(http.StatusCreated, response)
}
// GetRUJUKAN retrieves Rujukan data
// @Summary Get Rujukan data
// @Description Get referral information
// @Tags vclaim,rujukan
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param norujukan path string true "norujukan"
// @Success 200 {object} reference.RujukanResponse
// @Failure 400 {object} reference.ErrorResponse
// @Failure 500 {object} reference.ErrorResponse
// @Router /rujukan/:norujukan [get]
func (h *VClaimHandler) GetRUJUKAN(c *gin.Context) {
ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second)
defer cancel()
// Generate request ID if not present
requestID := c.GetHeader("X-Request-ID")
if requestID == "" {
requestID = uuid.New().String()
c.Header("X-Request-ID", requestID)
}
h.logger.Info("Processing GetRujukan request", map[string]interface{}{
"request_id": requestID,
"endpoint": "/rujukan/:norujukan",
"norujukan": c.Param("norujukan"),
})
// Extract path parameters
norujukan := c.Param("norujukan")
if norujukan == "" {
h.logger.Error("Missing required parameter norujukan", map[string]interface{}{
"request_id": requestID,
})
c.JSON(http.StatusBadRequest, reference.ErrorResponse{
Status: "error",
Message: "Missing required parameter norujukan",
RequestID: requestID,
})
return
}
// Call service method
var response reference.RujukanResponse
response, err := h.service.GetRUJUKAN(ctx, norujukan)
if err != nil {
h.logger.Error("Failed to get Rujukan", map[string]interface{}{
"error": err.Error(),
"request_id": requestID,
})
c.JSON(http.StatusInternalServerError, reference.ErrorResponse{
Status: "error",
Message: "Internal server error",
RequestID: requestID,
})
return
}
// Ensure response has proper fields
response.Status = "success"
response.RequestID = requestID
c.JSON(http.StatusOK, response)
}