clear tool generete bpjs
This commit is contained in:
212
docs/docs.go
212
docs/docs.go
@@ -702,11 +702,43 @@ const docTemplate = `{
|
||||
},
|
||||
"/peserta/:nokartu": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Get participant eligibility information by card number",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Peserta"
|
||||
],
|
||||
"summary": "Get PesertaBynokartu data",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Request ID for tracking",
|
||||
"name": "X-Request-ID",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"example": "\"example_value\"",
|
||||
"description": "nokartu",
|
||||
"name": "nokartu",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successfully retrieved PesertaBynokartu data",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/peserta.PesertaResponse"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_peserta.PesertaResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
@@ -738,11 +770,43 @@ const docTemplate = `{
|
||||
},
|
||||
"/peserta/nik/:nik": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Get participant eligibility information by NIK",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Peserta"
|
||||
],
|
||||
"summary": "Get PesertaBynik data",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Request ID for tracking",
|
||||
"name": "X-Request-ID",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"example": "\"example_value\"",
|
||||
"description": "nik",
|
||||
"name": "nik",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successfully retrieved PesertaBynik data",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/peserta.PesertaResponse"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_peserta.PesertaResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
@@ -774,6 +838,22 @@ const docTemplate = `{
|
||||
},
|
||||
"/sep": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Manage SEP (Surat Eligibilitas Peserta)",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Sep"
|
||||
],
|
||||
"summary": "Create new SepSep",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@@ -787,7 +867,7 @@ const docTemplate = `{
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/sep.SepRequest"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_sep.SepRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -795,7 +875,7 @@ const docTemplate = `{
|
||||
"201": {
|
||||
"description": "Successfully created SepSep",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/sep.SepResponse"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_sep.SepResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
@@ -827,11 +907,43 @@ const docTemplate = `{
|
||||
},
|
||||
"/sep/:nosep": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Manage SEP (Surat Eligibilitas Peserta)",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Sep"
|
||||
],
|
||||
"summary": "Get SepSep data",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Request ID for tracking",
|
||||
"name": "X-Request-ID",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"example": "\"example_value\"",
|
||||
"description": "nosep",
|
||||
"name": "nosep",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successfully retrieved SepSep data",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/sep.SepResponse"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_sep.SepResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
@@ -861,14 +973,44 @@ const docTemplate = `{
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Manage SEP (Surat Eligibilitas Peserta)",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Sep"
|
||||
],
|
||||
"summary": "Update existing SepSep",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Request ID for tracking",
|
||||
"name": "X-Request-ID",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"example": "\"example_value\"",
|
||||
"description": "nosep",
|
||||
"name": "nosep",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "SepSep data",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/sep.SepRequest"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_sep.SepRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -876,7 +1018,7 @@ const docTemplate = `{
|
||||
"200": {
|
||||
"description": "Successfully updated SepSep",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/sep.SepResponse"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_sep.SepResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
@@ -906,11 +1048,43 @@ const docTemplate = `{
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Manage SEP (Surat Eligibilitas Peserta)",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Sep"
|
||||
],
|
||||
"summary": "Delete existing SepSep",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Request ID for tracking",
|
||||
"name": "X-Request-ID",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"example": "\"example_value\"",
|
||||
"description": "nosep",
|
||||
"name": "nosep",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successfully deleted SepSep",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/sep.SepResponse"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_sep.SepResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
@@ -1388,7 +1562,7 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"peserta.PesertaData": {
|
||||
"api-service_internal_models_vclaim_peserta.PesertaData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"aktif": {
|
||||
@@ -1476,11 +1650,11 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"peserta.PesertaResponse": {
|
||||
"api-service_internal_models_vclaim_peserta.PesertaResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/peserta.PesertaData"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_peserta.PesertaData"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
@@ -1497,7 +1671,7 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"sep.SepData": {
|
||||
"api-service_internal_models_vclaim_sep.SepData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"catatan": {
|
||||
@@ -1536,20 +1710,20 @@ const docTemplate = `{
|
||||
"type": "string"
|
||||
},
|
||||
"peserta": {
|
||||
"$ref": "#/definitions/peserta.PesertaData"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_peserta.PesertaData"
|
||||
},
|
||||
"poli": {
|
||||
"type": "string"
|
||||
},
|
||||
"rujukan": {
|
||||
"$ref": "#/definitions/sep.SepRujukan"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_sep.SepRujukan"
|
||||
},
|
||||
"tglSep": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sep.SepRequest": {
|
||||
"api-service_internal_models_vclaim_sep.SepRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"diagnosa",
|
||||
@@ -1603,7 +1777,7 @@ const docTemplate = `{
|
||||
"type": "string"
|
||||
},
|
||||
"rujukan": {
|
||||
"$ref": "#/definitions/sep.SepRujukan"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_sep.SepRujukan"
|
||||
},
|
||||
"tglSep": {
|
||||
"type": "string"
|
||||
@@ -1616,11 +1790,11 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"sep.SepResponse": {
|
||||
"api-service_internal_models_vclaim_sep.SepResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/sep.SepData"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_sep.SepData"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
@@ -1636,7 +1810,7 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"sep.SepRujukan": {
|
||||
"api-service_internal_models_vclaim_sep.SepRujukan": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"asalRujukan",
|
||||
|
||||
@@ -699,11 +699,43 @@
|
||||
},
|
||||
"/peserta/:nokartu": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Get participant eligibility information by card number",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Peserta"
|
||||
],
|
||||
"summary": "Get PesertaBynokartu data",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Request ID for tracking",
|
||||
"name": "X-Request-ID",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"example": "\"example_value\"",
|
||||
"description": "nokartu",
|
||||
"name": "nokartu",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successfully retrieved PesertaBynokartu data",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/peserta.PesertaResponse"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_peserta.PesertaResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
@@ -735,11 +767,43 @@
|
||||
},
|
||||
"/peserta/nik/:nik": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Get participant eligibility information by NIK",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Peserta"
|
||||
],
|
||||
"summary": "Get PesertaBynik data",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Request ID for tracking",
|
||||
"name": "X-Request-ID",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"example": "\"example_value\"",
|
||||
"description": "nik",
|
||||
"name": "nik",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successfully retrieved PesertaBynik data",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/peserta.PesertaResponse"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_peserta.PesertaResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
@@ -771,6 +835,22 @@
|
||||
},
|
||||
"/sep": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Manage SEP (Surat Eligibilitas Peserta)",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Sep"
|
||||
],
|
||||
"summary": "Create new SepSep",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@@ -784,7 +864,7 @@
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/sep.SepRequest"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_sep.SepRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -792,7 +872,7 @@
|
||||
"201": {
|
||||
"description": "Successfully created SepSep",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/sep.SepResponse"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_sep.SepResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
@@ -824,11 +904,43 @@
|
||||
},
|
||||
"/sep/:nosep": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Manage SEP (Surat Eligibilitas Peserta)",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Sep"
|
||||
],
|
||||
"summary": "Get SepSep data",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Request ID for tracking",
|
||||
"name": "X-Request-ID",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"example": "\"example_value\"",
|
||||
"description": "nosep",
|
||||
"name": "nosep",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successfully retrieved SepSep data",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/sep.SepResponse"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_sep.SepResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
@@ -858,14 +970,44 @@
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Manage SEP (Surat Eligibilitas Peserta)",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Sep"
|
||||
],
|
||||
"summary": "Update existing SepSep",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Request ID for tracking",
|
||||
"name": "X-Request-ID",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"example": "\"example_value\"",
|
||||
"description": "nosep",
|
||||
"name": "nosep",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"description": "SepSep data",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/sep.SepRequest"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_sep.SepRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -873,7 +1015,7 @@
|
||||
"200": {
|
||||
"description": "Successfully updated SepSep",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/sep.SepResponse"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_sep.SepResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
@@ -903,11 +1045,43 @@
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Manage SEP (Surat Eligibilitas Peserta)",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Sep"
|
||||
],
|
||||
"summary": "Delete existing SepSep",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Request ID for tracking",
|
||||
"name": "X-Request-ID",
|
||||
"in": "header"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"example": "\"example_value\"",
|
||||
"description": "nosep",
|
||||
"name": "nosep",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successfully deleted SepSep",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/sep.SepResponse"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_sep.SepResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
@@ -1385,7 +1559,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"peserta.PesertaData": {
|
||||
"api-service_internal_models_vclaim_peserta.PesertaData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"aktif": {
|
||||
@@ -1473,11 +1647,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"peserta.PesertaResponse": {
|
||||
"api-service_internal_models_vclaim_peserta.PesertaResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/peserta.PesertaData"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_peserta.PesertaData"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
@@ -1494,7 +1668,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"sep.SepData": {
|
||||
"api-service_internal_models_vclaim_sep.SepData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"catatan": {
|
||||
@@ -1533,20 +1707,20 @@
|
||||
"type": "string"
|
||||
},
|
||||
"peserta": {
|
||||
"$ref": "#/definitions/peserta.PesertaData"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_peserta.PesertaData"
|
||||
},
|
||||
"poli": {
|
||||
"type": "string"
|
||||
},
|
||||
"rujukan": {
|
||||
"$ref": "#/definitions/sep.SepRujukan"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_sep.SepRujukan"
|
||||
},
|
||||
"tglSep": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sep.SepRequest": {
|
||||
"api-service_internal_models_vclaim_sep.SepRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"diagnosa",
|
||||
@@ -1600,7 +1774,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"rujukan": {
|
||||
"$ref": "#/definitions/sep.SepRujukan"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_sep.SepRujukan"
|
||||
},
|
||||
"tglSep": {
|
||||
"type": "string"
|
||||
@@ -1613,11 +1787,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"sep.SepResponse": {
|
||||
"api-service_internal_models_vclaim_sep.SepResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/sep.SepData"
|
||||
"$ref": "#/definitions/api-service_internal_models_vclaim_sep.SepData"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
@@ -1633,7 +1807,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"sep.SepRujukan": {
|
||||
"api-service_internal_models_vclaim_sep.SepRujukan": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"asalRujukan",
|
||||
|
||||
@@ -306,7 +306,7 @@ definitions:
|
||||
message:
|
||||
type: string
|
||||
type: object
|
||||
peserta.PesertaData:
|
||||
api-service_internal_models_vclaim_peserta.PesertaData:
|
||||
properties:
|
||||
aktif:
|
||||
type: string
|
||||
@@ -364,10 +364,10 @@ definitions:
|
||||
tglTunggak:
|
||||
type: string
|
||||
type: object
|
||||
peserta.PesertaResponse:
|
||||
api-service_internal_models_vclaim_peserta.PesertaResponse:
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/definitions/peserta.PesertaData'
|
||||
$ref: '#/definitions/api-service_internal_models_vclaim_peserta.PesertaData'
|
||||
message:
|
||||
type: string
|
||||
metaData: {}
|
||||
@@ -378,7 +378,7 @@ definitions:
|
||||
timestamp:
|
||||
type: string
|
||||
type: object
|
||||
sep.SepData:
|
||||
api-service_internal_models_vclaim_sep.SepData:
|
||||
properties:
|
||||
catatan:
|
||||
type: string
|
||||
@@ -404,15 +404,15 @@ definitions:
|
||||
noSep:
|
||||
type: string
|
||||
peserta:
|
||||
$ref: '#/definitions/peserta.PesertaData'
|
||||
$ref: '#/definitions/api-service_internal_models_vclaim_peserta.PesertaData'
|
||||
poli:
|
||||
type: string
|
||||
rujukan:
|
||||
$ref: '#/definitions/sep.SepRujukan'
|
||||
$ref: '#/definitions/api-service_internal_models_vclaim_sep.SepRujukan'
|
||||
tglSep:
|
||||
type: string
|
||||
type: object
|
||||
sep.SepRequest:
|
||||
api-service_internal_models_vclaim_sep.SepRequest:
|
||||
properties:
|
||||
catatan:
|
||||
type: string
|
||||
@@ -442,7 +442,7 @@ definitions:
|
||||
request_id:
|
||||
type: string
|
||||
rujukan:
|
||||
$ref: '#/definitions/sep.SepRujukan'
|
||||
$ref: '#/definitions/api-service_internal_models_vclaim_sep.SepRujukan'
|
||||
tglSep:
|
||||
type: string
|
||||
timestamp:
|
||||
@@ -460,10 +460,10 @@ definitions:
|
||||
- tglSep
|
||||
- user
|
||||
type: object
|
||||
sep.SepResponse:
|
||||
api-service_internal_models_vclaim_sep.SepResponse:
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/definitions/sep.SepData'
|
||||
$ref: '#/definitions/api-service_internal_models_vclaim_sep.SepData'
|
||||
message:
|
||||
type: string
|
||||
request_id:
|
||||
@@ -473,7 +473,7 @@ definitions:
|
||||
timestamp:
|
||||
type: string
|
||||
type: object
|
||||
sep.SepRujukan:
|
||||
api-service_internal_models_vclaim_sep.SepRujukan:
|
||||
properties:
|
||||
asalRujukan:
|
||||
enum:
|
||||
@@ -969,11 +969,27 @@ paths:
|
||||
- Token
|
||||
/peserta/:nokartu:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: Get participant eligibility information by card number
|
||||
parameters:
|
||||
- description: Request ID for tracking
|
||||
in: header
|
||||
name: X-Request-ID
|
||||
type: string
|
||||
- description: nokartu
|
||||
example: '"example_value"'
|
||||
in: path
|
||||
name: nokartu
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: Successfully retrieved PesertaBynokartu data
|
||||
schema:
|
||||
$ref: '#/definitions/peserta.PesertaResponse'
|
||||
$ref: '#/definitions/api-service_internal_models_vclaim_peserta.PesertaResponse'
|
||||
"400":
|
||||
description: Bad request - invalid parameters
|
||||
schema:
|
||||
@@ -990,13 +1006,34 @@ paths:
|
||||
description: Internal server error
|
||||
schema:
|
||||
$ref: '#/definitions/api-service_internal_models.ErrorResponseBpjs'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Get PesertaBynokartu data
|
||||
tags:
|
||||
- Peserta
|
||||
/peserta/nik/:nik:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: Get participant eligibility information by NIK
|
||||
parameters:
|
||||
- description: Request ID for tracking
|
||||
in: header
|
||||
name: X-Request-ID
|
||||
type: string
|
||||
- description: nik
|
||||
example: '"example_value"'
|
||||
in: path
|
||||
name: nik
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: Successfully retrieved PesertaBynik data
|
||||
schema:
|
||||
$ref: '#/definitions/peserta.PesertaResponse'
|
||||
$ref: '#/definitions/api-service_internal_models_vclaim_peserta.PesertaResponse'
|
||||
"400":
|
||||
description: Bad request - invalid parameters
|
||||
schema:
|
||||
@@ -1013,8 +1050,16 @@ paths:
|
||||
description: Internal server error
|
||||
schema:
|
||||
$ref: '#/definitions/api-service_internal_models.ErrorResponseBpjs'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Get PesertaBynik data
|
||||
tags:
|
||||
- Peserta
|
||||
/sep:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: Manage SEP (Surat Eligibilitas Peserta)
|
||||
parameters:
|
||||
- description: Request ID for tracking
|
||||
in: header
|
||||
@@ -1025,12 +1070,14 @@ paths:
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/sep.SepRequest'
|
||||
$ref: '#/definitions/api-service_internal_models_vclaim_sep.SepRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"201":
|
||||
description: Successfully created SepSep
|
||||
schema:
|
||||
$ref: '#/definitions/sep.SepResponse'
|
||||
$ref: '#/definitions/api-service_internal_models_vclaim_sep.SepResponse'
|
||||
"400":
|
||||
description: Bad request - invalid request body or validation error
|
||||
schema:
|
||||
@@ -1047,13 +1094,34 @@ paths:
|
||||
description: Internal server error
|
||||
schema:
|
||||
$ref: '#/definitions/api-service_internal_models.ErrorResponseBpjs'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Create new SepSep
|
||||
tags:
|
||||
- Sep
|
||||
/sep/:nosep:
|
||||
delete:
|
||||
consumes:
|
||||
- application/json
|
||||
description: Manage SEP (Surat Eligibilitas Peserta)
|
||||
parameters:
|
||||
- description: Request ID for tracking
|
||||
in: header
|
||||
name: X-Request-ID
|
||||
type: string
|
||||
- description: nosep
|
||||
example: '"example_value"'
|
||||
in: path
|
||||
name: nosep
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: Successfully deleted SepSep
|
||||
schema:
|
||||
$ref: '#/definitions/sep.SepResponse'
|
||||
$ref: '#/definitions/api-service_internal_models_vclaim_sep.SepResponse'
|
||||
"400":
|
||||
description: Bad request - invalid parameters
|
||||
schema:
|
||||
@@ -1070,12 +1138,33 @@ paths:
|
||||
description: Internal server error
|
||||
schema:
|
||||
$ref: '#/definitions/api-service_internal_models.ErrorResponseBpjs'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Delete existing SepSep
|
||||
tags:
|
||||
- Sep
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: Manage SEP (Surat Eligibilitas Peserta)
|
||||
parameters:
|
||||
- description: Request ID for tracking
|
||||
in: header
|
||||
name: X-Request-ID
|
||||
type: string
|
||||
- description: nosep
|
||||
example: '"example_value"'
|
||||
in: path
|
||||
name: nosep
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: Successfully retrieved SepSep data
|
||||
schema:
|
||||
$ref: '#/definitions/sep.SepResponse'
|
||||
$ref: '#/definitions/api-service_internal_models_vclaim_sep.SepResponse'
|
||||
"400":
|
||||
description: Bad request - invalid parameters
|
||||
schema:
|
||||
@@ -1092,19 +1181,39 @@ paths:
|
||||
description: Internal server error
|
||||
schema:
|
||||
$ref: '#/definitions/api-service_internal_models.ErrorResponseBpjs'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Get SepSep data
|
||||
tags:
|
||||
- Sep
|
||||
put:
|
||||
consumes:
|
||||
- application/json
|
||||
description: Manage SEP (Surat Eligibilitas Peserta)
|
||||
parameters:
|
||||
- description: Request ID for tracking
|
||||
in: header
|
||||
name: X-Request-ID
|
||||
type: string
|
||||
- description: nosep
|
||||
example: '"example_value"'
|
||||
in: path
|
||||
name: nosep
|
||||
required: true
|
||||
type: string
|
||||
- description: SepSep data
|
||||
in: body
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/sep.SepRequest'
|
||||
$ref: '#/definitions/api-service_internal_models_vclaim_sep.SepRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: Successfully updated SepSep
|
||||
schema:
|
||||
$ref: '#/definitions/sep.SepResponse'
|
||||
$ref: '#/definitions/api-service_internal_models_vclaim_sep.SepResponse'
|
||||
"400":
|
||||
description: Bad request - invalid parameters or request body
|
||||
schema:
|
||||
@@ -1121,6 +1230,11 @@ paths:
|
||||
description: Internal server error
|
||||
schema:
|
||||
$ref: '#/definitions/api-service_internal_models.ErrorResponseBpjs'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Update existing SepSep
|
||||
tags:
|
||||
- Sep
|
||||
schemes:
|
||||
- http
|
||||
- https
|
||||
|
||||
847
generetebpjs
847
generetebpjs
@@ -1,847 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// runSwagInit runs the swag init command to generate swagger docs
|
||||
func runSwagInit() error {
|
||||
cmd := exec.Command("swag", "init", "-g", "../../cmd/api/main.go", "--parseDependency", "--parseInternal")
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// ServiceConfig represents the main configuration structure
|
||||
type ServiceConfig struct {
|
||||
Services map[string]Service `yaml:"services"`
|
||||
Global GlobalConfig `yaml:"global,omitempty"`
|
||||
}
|
||||
|
||||
// GlobalConfig contains global configuration
|
||||
type GlobalConfig struct {
|
||||
ModuleName string `yaml:"module_name"`
|
||||
OutputDir string `yaml:"output_dir"`
|
||||
PackagePrefix string `yaml:"package_prefix"`
|
||||
EnableSwagger bool `yaml:"enable_swagger"`
|
||||
EnableLogging bool `yaml:"enable_logging"`
|
||||
EnableMetrics bool `yaml:"enable_metrics"`
|
||||
}
|
||||
|
||||
// Service represents individual service configuration
|
||||
type Service struct {
|
||||
Name string `yaml:"name"`
|
||||
Category string `yaml:"category"`
|
||||
Package string `yaml:"package"`
|
||||
Description string `yaml:"description"`
|
||||
BaseURL string `yaml:"base_url"`
|
||||
Timeout int `yaml:"timeout"`
|
||||
RetryCount int `yaml:"retry_count"`
|
||||
Endpoints map[string]SubEndpoints `yaml:"endpoints"`
|
||||
Middleware []string `yaml:"middleware,omitempty"` // FIXED: Changed to []string
|
||||
Dependencies []string `yaml:"dependencies,omitempty"` // FIXED: Changed to []string
|
||||
}
|
||||
|
||||
// Endpoint represents endpoint configuration
|
||||
type Endpoint struct {
|
||||
Methods []string `yaml:"methods"`
|
||||
GetPath string `yaml:"get_path,omitempty"`
|
||||
PostPath string `yaml:"post_path,omitempty"`
|
||||
PutPath string `yaml:"put_path,omitempty"`
|
||||
DeletePath string `yaml:"delete_path,omitempty"`
|
||||
PatchPath string `yaml:"patch_path,omitempty"`
|
||||
Model string `yaml:"model"`
|
||||
ResponseModel string `yaml:"response_model"`
|
||||
Description string `yaml:"description"`
|
||||
Summary string `yaml:"summary"`
|
||||
Tags []string `yaml:"tags"`
|
||||
RequireAuth bool `yaml:"require_auth"`
|
||||
RateLimit int `yaml:"rate_limit,omitempty"`
|
||||
CacheEnabled bool `yaml:"cache_enabled"`
|
||||
CacheTTL int `yaml:"cache_ttl,omitempty"`
|
||||
CustomHeaders map[string]string `yaml:"custom_headers,omitempty"`
|
||||
}
|
||||
|
||||
// SubEndpoints represents nested endpoint configuration for tree structure
|
||||
type SubEndpoints map[string]Endpoint
|
||||
|
||||
// TemplateData holds data for generating handlers
|
||||
type TemplateData struct {
|
||||
ServiceName string
|
||||
ServiceLower string
|
||||
ServiceUpper string
|
||||
Category string
|
||||
Package string
|
||||
Description string
|
||||
BaseURL string
|
||||
Timeout int
|
||||
RetryCount int
|
||||
Endpoints []EndpointData
|
||||
Timestamp string
|
||||
ModuleName string
|
||||
HasValidator bool
|
||||
HasLogger bool
|
||||
HasMetrics bool
|
||||
HasSwagger bool
|
||||
HasAuth bool
|
||||
HasCache bool
|
||||
Dependencies []string // FIXED: Changed to []string
|
||||
Middleware []string // FIXED: Changed to []string
|
||||
GlobalConfig GlobalConfig
|
||||
}
|
||||
|
||||
// EndpointData represents processed endpoint data
|
||||
type EndpointData struct {
|
||||
Name string
|
||||
NameLower string
|
||||
NameUpper string
|
||||
NameCamel string
|
||||
Methods []string
|
||||
GetPath string
|
||||
PostPath string
|
||||
PutPath string
|
||||
DeletePath string
|
||||
PatchPath string
|
||||
Model string
|
||||
ResponseModel string
|
||||
Description string
|
||||
Summary string
|
||||
Tags []string
|
||||
HasGet bool
|
||||
HasPost bool
|
||||
HasPut bool
|
||||
HasDelete bool
|
||||
HasPatch bool
|
||||
RequireAuth bool
|
||||
RateLimit int
|
||||
CacheEnabled bool
|
||||
CacheTTL int
|
||||
PathParams []string
|
||||
QueryParams []string
|
||||
RequiredFields []string
|
||||
OptionalFields []string
|
||||
CustomHeaders map[string]string
|
||||
ModelPackage string // Package name for the model (peserta, sep, etc.)
|
||||
}
|
||||
|
||||
// Updated template for merged handler structure
|
||||
const handlerTemplate = `
|
||||
// Service: {{.ServiceName}} ({{.Category}})
|
||||
// Description: {{.Description}}
|
||||
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"{{.ModuleName}}/internal/config"
|
||||
"{{.ModuleName}}/internal/models"
|
||||
"{{.ModuleName}}/internal/models/vclaim/peserta"
|
||||
"{{.ModuleName}}/internal/models/vclaim/sep"
|
||||
"{{.ModuleName}}/internal/services/bpjs"
|
||||
"{{.ModuleName}}/pkg/logger"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// {{.ServiceName}}Handler handles {{.ServiceName}} BPJS services
|
||||
type {{.ServiceName}}Handler struct {
|
||||
service services.{{.ServiceName}}Service
|
||||
validator *validator.Validate
|
||||
logger logger.Logger
|
||||
config config.BpjsConfig
|
||||
}
|
||||
|
||||
// {{.ServiceName}}HandlerConfig contains configuration for {{.ServiceName}}Handler
|
||||
type {{.ServiceName}}HandlerConfig struct {
|
||||
BpjsConfig config.BpjsConfig
|
||||
Logger logger.Logger
|
||||
Validator *validator.Validate
|
||||
}
|
||||
|
||||
// New{{.ServiceName}}Handler creates a new {{.ServiceName}}Handler
|
||||
func New{{.ServiceName}}Handler(cfg {{.ServiceName}}HandlerConfig) *{{.ServiceName}}Handler {
|
||||
return &{{.ServiceName}}Handler{
|
||||
service: services.NewService(cfg.BpjsConfig),
|
||||
validator: cfg.Validator,
|
||||
logger: cfg.Logger,
|
||||
config: cfg.BpjsConfig,
|
||||
}
|
||||
}
|
||||
|
||||
{{range .Endpoints}}
|
||||
{{if .HasGet}}
|
||||
// Get{{.NameUpper}} retrieves {{.Name}} data
|
||||
{{if $.HasSwagger}}
|
||||
// @Summary Get {{.Name}} data
|
||||
// @Description {{.Description}}
|
||||
// @Tags {{join .Tags ","}}
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
{{if .RequireAuth}}
|
||||
// @Security ApiKeyAuth
|
||||
{{end}}
|
||||
{{range .PathParams}}
|
||||
// @Param {{.}} path string true "{{.}}"
|
||||
{{end}}
|
||||
// @Success 200 {object} {{.ModelPackage}}.{{.ResponseModel}}
|
||||
// @Failure 400 {object} models.ErrorResponseBpjs
|
||||
// @Failure 500 {object} models.ErrorResponseBpjs
|
||||
// @Router {{.GetPath}} [get]
|
||||
{{end}}
|
||||
func (h *{{$.ServiceName}}Handler) Get{{.Name}}(c *gin.Context) {
|
||||
ctx, cancel := context.WithTimeout(c.Request.Context(), {{$.Timeout}}*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)
|
||||
}
|
||||
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Info("Processing Get{{.Name}} request", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
"endpoint": "{{.GetPath}}",
|
||||
{{range .PathParams}}
|
||||
"{{.}}": c.Param("{{.}}"),
|
||||
{{end}}
|
||||
})
|
||||
{{end}}
|
||||
|
||||
// Extract path parameters
|
||||
{{range .PathParams}}
|
||||
{{.}} := c.Param("{{.}}")
|
||||
if {{.}} == "" {
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Error("Missing required parameter {{.}}", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
{{end}}
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Missing required parameter {{.}}",
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
{{end}}
|
||||
|
||||
// Call service method
|
||||
var response {{.ModelPackage}}.{{.ResponseModel}}
|
||||
{{if .PathParams}}
|
||||
endpoint := "{{.GetPath}}"
|
||||
{{range .PathParams}}
|
||||
endpoint = strings.Replace(endpoint, ":{{.}}", {{.}}, 1)
|
||||
{{end}}
|
||||
err := h.service.Get(ctx, endpoint, &response)
|
||||
{{else}}
|
||||
err := h.service.Get(ctx, "{{.GetPath}}", &response)
|
||||
{{end}}
|
||||
if err != nil {
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Error("Failed to get {{.Name}}", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
{{end}}
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{
|
||||
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)
|
||||
}
|
||||
{{end}}
|
||||
|
||||
{{if .HasPost}}
|
||||
// Create{{.NameUpper}} creates new {{.Name}}
|
||||
{{if $.HasSwagger}}
|
||||
// @Summary Create {{.Name}}
|
||||
// @Description {{.Description}}
|
||||
// @Tags {{join .Tags ","}}
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
{{if .RequireAuth}}
|
||||
// @Security ApiKeyAuth
|
||||
{{end}}
|
||||
// @Param request body {{.ModelPackage}}.{{.Model}} true "{{.Name}} data"
|
||||
// @Success 201 {object} {{.ModelPackage}}.{{.ResponseModel}}
|
||||
// @Failure 400 {object} models.ErrorResponseBpjs
|
||||
// @Failure 500 {object} models.ErrorResponseBpjs
|
||||
// @Router {{.PostPath}} [post]
|
||||
{{end}}
|
||||
func (h *{{$.ServiceName}}Handler) Create{{.Name}}(c *gin.Context) {
|
||||
ctx, cancel := context.WithTimeout(c.Request.Context(), {{$.Timeout}}*time.Second)
|
||||
defer cancel()
|
||||
|
||||
requestID := c.GetHeader("X-Request-ID")
|
||||
if requestID == "" {
|
||||
requestID = uuid.New().String()
|
||||
c.Header("X-Request-ID", requestID)
|
||||
}
|
||||
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Info("Processing Create{{.Name}} request", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
{{end}}
|
||||
|
||||
var req {{.ModelPackage}}.{{.Model}}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Error("Invalid request body", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
{{end}}
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Invalid request body: " + err.Error(),
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Validate request
|
||||
if err := h.validator.Struct(&req); err != nil {
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Error("Validation failed", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
{{end}}
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Validation failed: " + err.Error(),
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Call service method
|
||||
var response {{.ModelPackage}}.{{.ResponseModel}}
|
||||
err := h.service.Post(ctx, "{{.PostPath}}", &req, &response)
|
||||
if err != nil {
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Error("Failed to create {{.Name}}", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
{{end}}
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{
|
||||
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)
|
||||
}
|
||||
{{end}}
|
||||
|
||||
{{if .HasPut}}
|
||||
// Update{{.NameUpper}} updates existing {{.Name}}
|
||||
{{if $.HasSwagger}}
|
||||
// @Summary Update {{.Name}}
|
||||
// @Description {{.Description}}
|
||||
// @Tags {{join .Tags ","}}
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
{{if .RequireAuth}}
|
||||
// @Security ApiKeyAuth
|
||||
{{end}}
|
||||
{{range .PathParams}}
|
||||
// @Param {{.}} path string true "{{.}}"
|
||||
{{end}}
|
||||
// @Param request body {{.ModelPackage}}.{{.Model}} true "{{.Name}} data"
|
||||
// @Success 200 {object} {{.ModelPackage}}.{{.ResponseModel}}
|
||||
// @Failure 400 {object} models.ErrorResponseBpjs
|
||||
// @Failure 500 {object} models.ErrorResponseBpjs
|
||||
// @Router {{.PutPath}} [put]
|
||||
{{end}}
|
||||
func (h *{{$.ServiceName}}Handler) Update{{.Name}}(c *gin.Context) {
|
||||
ctx, cancel := context.WithTimeout(c.Request.Context(), {{$.Timeout}}*time.Second)
|
||||
defer cancel()
|
||||
|
||||
requestID := c.GetHeader("X-Request-ID")
|
||||
if requestID == "" {
|
||||
requestID = uuid.New().String()
|
||||
c.Header("X-Request-ID", requestID)
|
||||
}
|
||||
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Info("Processing Update{{.Name}} request", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
{{end}}
|
||||
|
||||
{{range .PathParams}}
|
||||
{{.}} := c.Param("{{.}}")
|
||||
if {{.}} == "" {
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Error("Missing required parameter {{.}}", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
{{end}}
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Missing required parameter {{.}}",
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
{{end}}
|
||||
|
||||
var req {{.ModelPackage}}.{{.Model}}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Error("Invalid request body", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
{{end}}
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Invalid request body: " + err.Error(),
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Validate request
|
||||
if err := h.validator.Struct(&req); err != nil {
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Error("Validation failed", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
{{end}}
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Validation failed: " + err.Error(),
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Call service method
|
||||
var response {{.ModelPackage}}.{{.ResponseModel}}
|
||||
{{if .PathParams}}
|
||||
endpoint := "{{.PutPath}}"
|
||||
{{range .PathParams}}
|
||||
endpoint = strings.Replace(endpoint, ":{{.}}", {{.}}, 1)
|
||||
{{end}}
|
||||
err := h.service.Put(ctx, endpoint, &req, &response)
|
||||
{{else}}
|
||||
err := h.service.Put(ctx, "{{.PutPath}}", &req, &response)
|
||||
{{end}}
|
||||
if err != nil {
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Error("Failed to update {{.Name}}", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
{{end}}
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{
|
||||
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)
|
||||
}
|
||||
{{end}}
|
||||
|
||||
{{if .HasDelete}}
|
||||
// Delete{{.NameUpper}} deletes existing {{.Name}}
|
||||
{{if $.HasSwagger}}
|
||||
// @Summary Delete {{.Name}}
|
||||
// @Description {{.Description}}
|
||||
// @Tags {{join .Tags ","}}
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
{{if .RequireAuth}}
|
||||
// @Security ApiKeyAuth
|
||||
{{end}}
|
||||
{{range .PathParams}}
|
||||
// @Param {{.}} path string true "{{.}}"
|
||||
{{end}}
|
||||
// @Success 200 {object} {{.ModelPackage}}.{{.ResponseModel}}
|
||||
// @Failure 400 {object} models.ErrorResponseBpjs
|
||||
// @Failure 500 {object} models.ErrorResponseBpjs
|
||||
// @Router {{.DeletePath}} [delete]
|
||||
{{end}}
|
||||
func (h *{{$.ServiceName}}Handler) Delete{{.Name}}(c *gin.Context) {
|
||||
ctx, cancel := context.WithTimeout(c.Request.Context(), {{$.Timeout}}*time.Second)
|
||||
defer cancel()
|
||||
|
||||
requestID := c.GetHeader("X-Request-ID")
|
||||
if requestID == "" {
|
||||
requestID = uuid.New().String()
|
||||
c.Header("X-Request-ID", requestID)
|
||||
}
|
||||
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Info("Processing Delete{{.Name}} request", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
{{end}}
|
||||
|
||||
{{range .PathParams}}
|
||||
{{.}} := c.Param("{{.}}")
|
||||
if {{.}} == "" {
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Error("Missing required parameter {{.}}", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
{{end}}
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Missing required parameter {{.}}",
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
{{end}}
|
||||
|
||||
// Call service method
|
||||
var response {{.ModelPackage}}.{{.ResponseModel}}
|
||||
{{if .PathParams}}
|
||||
endpoint := "{{.DeletePath}}"
|
||||
{{range .PathParams}}
|
||||
endpoint = strings.Replace(endpoint, ":{{.}}", {{.}}, 1)
|
||||
{{end}}
|
||||
err := h.service.Delete(ctx, endpoint, &response)
|
||||
{{else}}
|
||||
err := h.service.Delete(ctx, "{{.DeletePath}}", &response)
|
||||
{{end}}
|
||||
if err != nil {
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Error("Failed to delete {{.Name}}", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
{{end}}
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{
|
||||
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)
|
||||
}
|
||||
{{end}}
|
||||
{{end}}
|
||||
`
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
printUsage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
configFile := os.Args[1]
|
||||
var targetService string
|
||||
if len(os.Args) > 2 {
|
||||
targetService = os.Args[2]
|
||||
}
|
||||
|
||||
// Load configuration
|
||||
config, err := loadConfig(configFile)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error loading config: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Println("🚀 Starting BPJS Dynamic Handler Generation...")
|
||||
fmt.Printf("📁 Config file: %s\n", configFile)
|
||||
if targetService != "" {
|
||||
fmt.Printf("🎯 Target service: %s\n", targetService)
|
||||
}
|
||||
|
||||
generated := 0
|
||||
errors := 0
|
||||
|
||||
// Generate handlers
|
||||
for serviceName, service := range config.Services {
|
||||
if targetService != "" && serviceName != targetService {
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("🔧 Generating handler for service: %s (%s)\n", service.Name, service.Category)
|
||||
err := generateHandler(serviceName, service, config.Global)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error generating handler for %s: %v\n", serviceName, err)
|
||||
errors++
|
||||
continue
|
||||
}
|
||||
fmt.Printf("✅ Generated handler: %s_handler.go\n", strings.ToLower(serviceName))
|
||||
generated++
|
||||
}
|
||||
|
||||
// Summary
|
||||
fmt.Println("\n📊 Generation Summary:")
|
||||
fmt.Printf(" ✅ Successfully generated: %d handlers\n", generated)
|
||||
if errors > 0 {
|
||||
fmt.Printf(" ❌ Failed: %d handlers\n", errors)
|
||||
}
|
||||
|
||||
if generated > 0 {
|
||||
fmt.Println("🎉 Generation completed successfully!")
|
||||
|
||||
// Generate Swagger documentation if enabled
|
||||
if config.Global.EnableSwagger {
|
||||
fmt.Println("📚 Generating Swagger documentation...")
|
||||
if err := runSwagInit(); err != nil {
|
||||
fmt.Printf("⚠️ Warning: Failed to generate Swagger docs: %v\n", err)
|
||||
} else {
|
||||
fmt.Println("✅ Swagger documentation generated successfully!")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func printUsage() {
|
||||
fmt.Println("BPJS Dynamic Handler Generator")
|
||||
fmt.Println()
|
||||
fmt.Println("Usage:")
|
||||
fmt.Println(" go run generate-dynamic-handler.go <config-file> [service-name]")
|
||||
fmt.Println()
|
||||
fmt.Println("Examples:")
|
||||
fmt.Println(" go run generate-dynamic-handler.go services-config.yaml")
|
||||
fmt.Println(" go run generate-dynamic-handler.go services-config.yaml vclaim")
|
||||
}
|
||||
|
||||
func loadConfig(filename string) (*ServiceConfig, error) {
|
||||
data, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read config file: %w", err)
|
||||
}
|
||||
|
||||
var config ServiceConfig
|
||||
err = yaml.Unmarshal(data, &config)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse YAML config: %w", err)
|
||||
}
|
||||
|
||||
// Set default values
|
||||
if config.Global.ModuleName == "" {
|
||||
config.Global.ModuleName = "api-service"
|
||||
}
|
||||
if config.Global.OutputDir == "" {
|
||||
config.Global.OutputDir = "internal/handlers"
|
||||
}
|
||||
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
func generateHandler(serviceName string, service Service, globalConfig GlobalConfig) error {
|
||||
// Prepare template data
|
||||
templateData := TemplateData{
|
||||
ServiceName: service.Name,
|
||||
ServiceLower: strings.ToLower(service.Name),
|
||||
ServiceUpper: strings.ToUpper(service.Name),
|
||||
Category: service.Category,
|
||||
Package: service.Package,
|
||||
Description: service.Description,
|
||||
BaseURL: service.BaseURL,
|
||||
Timeout: getOrDefault(service.Timeout, 30),
|
||||
RetryCount: getOrDefault(service.RetryCount, 3),
|
||||
Timestamp: time.Now().Format("2006-01-02 15:04:05"),
|
||||
ModuleName: globalConfig.ModuleName,
|
||||
HasValidator: true,
|
||||
HasLogger: globalConfig.EnableLogging,
|
||||
HasMetrics: globalConfig.EnableMetrics,
|
||||
HasSwagger: globalConfig.EnableSwagger,
|
||||
Dependencies: service.Dependencies, // Now []string
|
||||
Middleware: service.Middleware, // Now []string
|
||||
GlobalConfig: globalConfig,
|
||||
}
|
||||
|
||||
// Check for advanced features
|
||||
for _, subEndpoints := range service.Endpoints {
|
||||
for _, endpoint := range subEndpoints {
|
||||
if endpoint.RequireAuth {
|
||||
templateData.HasAuth = true
|
||||
}
|
||||
if endpoint.CacheEnabled {
|
||||
templateData.HasCache = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process endpoints
|
||||
for endpointName, subEndpoints := range service.Endpoints {
|
||||
for subEndpointName, endpoint := range subEndpoints {
|
||||
// Compose full endpoint name with sub-endpoint name
|
||||
fullEndpointName := endpointName
|
||||
if subEndpointName != "" {
|
||||
fullEndpointName = fullEndpointName + strings.Title(subEndpointName)
|
||||
}
|
||||
endpointData := processEndpoint(fullEndpointName, endpoint, endpointName)
|
||||
templateData.Endpoints = append(templateData.Endpoints, endpointData)
|
||||
}
|
||||
}
|
||||
|
||||
// Create output directory
|
||||
outputDir := globalConfig.OutputDir
|
||||
if outputDir == "" {
|
||||
outputDir = "internal/handlers"
|
||||
}
|
||||
if err := os.MkdirAll(outputDir, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create output directory: %w", err)
|
||||
}
|
||||
|
||||
// Generate handler file
|
||||
filename := filepath.Join(outputDir, fmt.Sprintf("%s_handler.go", strings.ToLower(serviceName)))
|
||||
|
||||
// Create template with custom functions
|
||||
tmpl := template.New("handler").Funcs(template.FuncMap{
|
||||
"contains": strings.Contains,
|
||||
"join": strings.Join,
|
||||
"title": strings.Title,
|
||||
"trimPrefix": strings.TrimPrefix,
|
||||
})
|
||||
|
||||
tmpl, err := tmpl.Parse(handlerTemplate)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse template: %w", err)
|
||||
}
|
||||
|
||||
file, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create file: %w", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
err = tmpl.Execute(file, templateData)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute template: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func processEndpoint(name string, endpoint Endpoint, endpointGroup string) EndpointData {
|
||||
data := EndpointData{
|
||||
Name: strings.Title(name),
|
||||
NameLower: strings.ToLower(name),
|
||||
NameUpper: strings.ToUpper(name),
|
||||
NameCamel: toCamelCase(name),
|
||||
Methods: endpoint.Methods,
|
||||
GetPath: endpoint.GetPath,
|
||||
PostPath: endpoint.PostPath,
|
||||
PutPath: endpoint.PutPath,
|
||||
DeletePath: endpoint.DeletePath,
|
||||
PatchPath: endpoint.PatchPath,
|
||||
Model: endpoint.Model,
|
||||
ResponseModel: endpoint.ResponseModel,
|
||||
Description: endpoint.Description,
|
||||
Summary: endpoint.Summary,
|
||||
Tags: endpoint.Tags,
|
||||
RequireAuth: endpoint.RequireAuth,
|
||||
RateLimit: endpoint.RateLimit,
|
||||
CacheEnabled: endpoint.CacheEnabled,
|
||||
CacheTTL: getOrDefault(endpoint.CacheTTL, 300),
|
||||
CustomHeaders: endpoint.CustomHeaders,
|
||||
ModelPackage: endpointGroup, // Set the model package based on endpoint group
|
||||
}
|
||||
|
||||
// Set method flags and extract path parameters
|
||||
for _, method := range endpoint.Methods {
|
||||
switch strings.ToUpper(method) {
|
||||
case "GET":
|
||||
data.HasGet = true
|
||||
data.PathParams = extractPathParams(endpoint.GetPath)
|
||||
case "POST":
|
||||
data.HasPost = true
|
||||
case "PUT":
|
||||
data.HasPut = true
|
||||
data.PathParams = extractPathParams(endpoint.PutPath)
|
||||
case "DELETE":
|
||||
data.HasDelete = true
|
||||
data.PathParams = extractPathParams(endpoint.DeletePath)
|
||||
case "PATCH":
|
||||
data.HasPatch = true
|
||||
data.PathParams = extractPathParams(endpoint.PatchPath)
|
||||
}
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
func extractPathParams(path string) []string {
|
||||
if path == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var params []string
|
||||
parts := strings.Split(path, "/")
|
||||
for _, part := range parts {
|
||||
if strings.HasPrefix(part, ":") {
|
||||
params = append(params, strings.TrimPrefix(part, ":"))
|
||||
}
|
||||
}
|
||||
|
||||
return params
|
||||
}
|
||||
|
||||
func toCamelCase(str string) string {
|
||||
words := strings.FieldsFunc(str, func(c rune) bool {
|
||||
return c == '_' || c == '-' || c == ' '
|
||||
})
|
||||
|
||||
if len(words) == 0 {
|
||||
return str
|
||||
}
|
||||
|
||||
result := strings.ToLower(words[0])
|
||||
for _, word := range words[1:] {
|
||||
result += strings.Title(strings.ToLower(word))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func getOrDefault(value, defaultValue int) int {
|
||||
if value == 0 {
|
||||
return defaultValue
|
||||
}
|
||||
return value
|
||||
}
|
||||
625
genet
625
genet
@@ -1,625 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// ServiceConfig represents the main configuration structure
|
||||
type ServiceConfig struct {
|
||||
Services map[string]Service `yaml:"services"`
|
||||
Global GlobalConfig `yaml:"global,omitempty"`
|
||||
}
|
||||
|
||||
// GlobalConfig contains global configuration
|
||||
type GlobalConfig struct {
|
||||
ModuleName string `yaml:"module_name"`
|
||||
OutputDir string `yaml:"output_dir"`
|
||||
PackagePrefix string `yaml:"package_prefix"`
|
||||
EnableSwagger bool `yaml:"enable_swagger"`
|
||||
EnableLogging bool `yaml:"enable_logging"`
|
||||
EnableMetrics bool `yaml:"enable_metrics"`
|
||||
}
|
||||
|
||||
// Service represents individual service configuration
|
||||
type Service struct {
|
||||
Name string `yaml:"name"`
|
||||
Category string `yaml:"category"`
|
||||
Package string `yaml:"package"`
|
||||
Description string `yaml:"description"`
|
||||
BaseURL string `yaml:"base_url"`
|
||||
Timeout int `yaml:"timeout"`
|
||||
RetryCount int `yaml:"retry_count"`
|
||||
Endpoints map[string]Endpoint `yaml:"endpoints"`
|
||||
Middleware []string `yaml:"middleware,omitempty"` // FIXED: Changed to []string
|
||||
Dependencies []string `yaml:"dependencies,omitempty"` // FIXED: Changed to []string
|
||||
}
|
||||
|
||||
// Endpoint represents endpoint configuration
|
||||
type Endpoint struct {
|
||||
Methods []string `yaml:"methods"`
|
||||
GetPath string `yaml:"get_path,omitempty"`
|
||||
PostPath string `yaml:"post_path,omitempty"`
|
||||
PutPath string `yaml:"put_path,omitempty"`
|
||||
DeletePath string `yaml:"delete_path,omitempty"`
|
||||
PatchPath string `yaml:"patch_path,omitempty"`
|
||||
Model string `yaml:"model"`
|
||||
ResponseModel string `yaml:"response_model"`
|
||||
Description string `yaml:"description"`
|
||||
Summary string `yaml:"summary"`
|
||||
Tags []string `yaml:"tags"`
|
||||
RequireAuth bool `yaml:"require_auth"`
|
||||
RateLimit int `yaml:"rate_limit,omitempty"`
|
||||
CacheEnabled bool `yaml:"cache_enabled"`
|
||||
CacheTTL int `yaml:"cache_ttl,omitempty"`
|
||||
CustomHeaders map[string]string `yaml:"custom_headers,omitempty"` // ADDED: Missing field
|
||||
}
|
||||
|
||||
// TemplateData holds data for generating handlers
|
||||
type TemplateData struct {
|
||||
ServiceName string
|
||||
ServiceLower string
|
||||
ServiceUpper string
|
||||
Category string
|
||||
Package string
|
||||
Description string
|
||||
BaseURL string
|
||||
Timeout int
|
||||
RetryCount int
|
||||
Endpoints []EndpointData
|
||||
Timestamp string
|
||||
ModuleName string
|
||||
HasValidator bool
|
||||
HasLogger bool
|
||||
HasMetrics bool
|
||||
HasSwagger bool
|
||||
HasAuth bool
|
||||
HasCache bool
|
||||
Dependencies []string // FIXED: Changed to []string
|
||||
Middleware []string // FIXED: Changed to []string
|
||||
GlobalConfig GlobalConfig
|
||||
}
|
||||
|
||||
// EndpointData represents processed endpoint data
|
||||
type EndpointData struct {
|
||||
Name string
|
||||
NameLower string
|
||||
NameUpper string
|
||||
NameCamel string
|
||||
Methods []string
|
||||
GetPath string
|
||||
PostPath string
|
||||
PutPath string
|
||||
DeletePath string
|
||||
PatchPath string
|
||||
Model string
|
||||
ResponseModel string
|
||||
Description string
|
||||
Summary string
|
||||
Tags []string
|
||||
HasGet bool
|
||||
HasPost bool
|
||||
HasPut bool
|
||||
HasDelete bool
|
||||
HasPatch bool
|
||||
RequireAuth bool
|
||||
RateLimit int
|
||||
CacheEnabled bool
|
||||
CacheTTL int
|
||||
PathParams []string
|
||||
QueryParams []string
|
||||
RequiredFields []string
|
||||
OptionalFields []string
|
||||
CustomHeaders map[string]string
|
||||
}
|
||||
|
||||
// Template remains the same as before...
|
||||
const handlerTemplate = `
|
||||
// Code generated by generate-dynamic-handler.go; DO NOT EDIT.
|
||||
// Generated at: {{.Timestamp}}
|
||||
// Service: {{.ServiceName}} ({{.Category}})
|
||||
// Description: {{.Description}}
|
||||
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"{{.ModuleName}}/internal/config"
|
||||
"{{.ModuleName}}/internal/models/reference"
|
||||
"{{.ModuleName}}/pkg/logger"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// {{.ServiceName}}Service defines {{.ServiceName}} service interface
|
||||
type {{.ServiceName}}Service interface {
|
||||
{{range .Endpoints}}
|
||||
{{if .HasGet}}
|
||||
Get{{.Name}}(ctx context.Context{{range .PathParams}}, {{.}} string{{end}}) (*reference.{{.Name}}Data, error)
|
||||
{{end}}
|
||||
{{if .HasPost}}
|
||||
Create{{.Name}}(ctx context.Context, req *reference.{{.Model}}) (*reference.{{.Name}}Data, error)
|
||||
{{end}}
|
||||
{{if .HasPut}}
|
||||
Update{{.Name}}(ctx context.Context{{range .PathParams}}, {{.}} string{{end}}, req *reference.{{.Model}}) (*reference.{{.Name}}Data, error)
|
||||
{{end}}
|
||||
{{if .HasDelete}}
|
||||
Delete{{.Name}}(ctx context.Context{{range .PathParams}}, {{.}} string{{end}}) error
|
||||
{{end}}
|
||||
{{end}}
|
||||
}
|
||||
|
||||
// {{.ServiceName}}Handler handles {{.ServiceName}} BPJS services
|
||||
type {{.ServiceName}}Handler struct {
|
||||
service {{.ServiceName}}Service
|
||||
validator *validator.Validate
|
||||
logger logger.Logger
|
||||
config config.BpjsConfig
|
||||
}
|
||||
|
||||
// {{.ServiceName}}HandlerConfig contains configuration for {{.ServiceName}}Handler
|
||||
type {{.ServiceName}}HandlerConfig struct {
|
||||
BpjsConfig config.BpjsConfig
|
||||
Logger logger.Logger
|
||||
Validator *validator.Validate
|
||||
}
|
||||
|
||||
// New{{.ServiceName}}Handler creates a new {{.ServiceName}}Handler
|
||||
func New{{.ServiceName}}Handler(cfg {{.ServiceName}}HandlerConfig, service {{.ServiceName}}Service) *{{.ServiceName}}Handler {
|
||||
return &{{.ServiceName}}Handler{
|
||||
service: service,
|
||||
validator: cfg.Validator,
|
||||
logger: cfg.Logger,
|
||||
config: cfg.BpjsConfig,
|
||||
}
|
||||
}
|
||||
|
||||
{{range .Endpoints}}
|
||||
{{if .HasGet}}
|
||||
// Get{{.NameUpper}} retrieves {{.Name}} data
|
||||
{{if $.HasSwagger}}
|
||||
// @Summary Get {{.Name}} data
|
||||
// @Description {{.Description}}
|
||||
// @Tags {{join .Tags ","}}
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
{{if .RequireAuth}}
|
||||
// @Security ApiKeyAuth
|
||||
{{end}}
|
||||
{{range .PathParams}}
|
||||
// @Param {{.}} path string true "{{.}}"
|
||||
{{end}}
|
||||
// @Success 200 {object} reference.{{.ResponseModel}}
|
||||
// @Failure 400 {object} reference.ErrorResponse
|
||||
// @Failure 500 {object} reference.ErrorResponse
|
||||
// @Router {{.GetPath}} [get]
|
||||
{{end}}
|
||||
func (h *{{$.ServiceName}}Handler) Get{{.Name}}(c *gin.Context) {
|
||||
ctx, cancel := context.WithTimeout(c.Request.Context(), {{$.Timeout}}*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)
|
||||
}
|
||||
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Info("Processing Get{{.Name}} request", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
"endpoint": "{{.GetPath}}",
|
||||
{{range .PathParams}}
|
||||
"{{.}}": c.Param("{{.}}"),
|
||||
{{end}}
|
||||
})
|
||||
{{end}}
|
||||
|
||||
// Extract path parameters
|
||||
{{range .PathParams}}
|
||||
{{.}} := c.Param("{{.}}")
|
||||
if {{.}} == "" {
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Error("Missing required parameter {{.}}", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
{{end}}
|
||||
c.JSON(http.StatusBadRequest, reference.ErrorResponse{
|
||||
Status: "error",
|
||||
Message: "Missing required parameter {{.}}",
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
{{end}}
|
||||
|
||||
// Call service method
|
||||
var response reference.{{.ResponseModel}}
|
||||
{{if .PathParams}}
|
||||
result, err := h.service.Get{{.Name}}(ctx{{range .PathParams}}, {{.}}{{end}})
|
||||
{{else}}
|
||||
result, err := h.service.Get{{.Name}}(ctx)
|
||||
{{end}}
|
||||
if err != nil {
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Error("Failed to get {{.Name}}", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
{{end}}
|
||||
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
|
||||
response.Data = result
|
||||
c.JSON(http.StatusOK, response)
|
||||
}
|
||||
{{end}}
|
||||
|
||||
{{if .HasPost}}
|
||||
// Create{{.NameUpper}} creates new {{.Name}}
|
||||
{{if $.HasSwagger}}
|
||||
// @Summary Create {{.Name}}
|
||||
// @Description {{.Description}}
|
||||
// @Tags {{join .Tags ","}}
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
{{if .RequireAuth}}
|
||||
// @Security ApiKeyAuth
|
||||
{{end}}
|
||||
// @Param request body reference.{{.Model}} true "{{.Name}} data"
|
||||
// @Success 201 {object} reference.{{.ResponseModel}}
|
||||
// @Failure 400 {object} reference.ErrorResponse
|
||||
// @Failure 500 {object} reference.ErrorResponse
|
||||
// @Router {{.PostPath}} [post]
|
||||
{{end}}
|
||||
func (h *{{$.ServiceName}}Handler) Create{{.Name}}(c *gin.Context) {
|
||||
ctx, cancel := context.WithTimeout(c.Request.Context(), {{$.Timeout}}*time.Second)
|
||||
defer cancel()
|
||||
|
||||
requestID := c.GetHeader("X-Request-ID")
|
||||
if requestID == "" {
|
||||
requestID = uuid.New().String()
|
||||
c.Header("X-Request-ID", requestID)
|
||||
}
|
||||
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Info("Processing Create{{.Name}} request", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
{{end}}
|
||||
|
||||
var req reference.{{.Model}}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Error("Invalid request body", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
{{end}}
|
||||
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 {
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Error("Validation failed", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
{{end}}
|
||||
c.JSON(http.StatusBadRequest, reference.ErrorResponse{
|
||||
Status: "error",
|
||||
Message: "Validation failed: " + err.Error(),
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Call service method
|
||||
var response reference.{{.ResponseModel}}
|
||||
result, err := h.service.Create{{.Name}}(ctx, &req)
|
||||
if err != nil {
|
||||
{{if $.HasLogger}}
|
||||
h.logger.Error("Failed to create {{.Name}}", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
{{end}}
|
||||
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
|
||||
response.Data = result
|
||||
c.JSON(http.StatusCreated, response)
|
||||
}
|
||||
{{end}}
|
||||
{{end}}
|
||||
`
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
printUsage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
configFile := os.Args[1]
|
||||
var targetService string
|
||||
if len(os.Args) > 2 {
|
||||
targetService = os.Args[2]
|
||||
}
|
||||
|
||||
// Load configuration
|
||||
config, err := loadConfig(configFile)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error loading config: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Println("🚀 Starting BPJS Dynamic Handler Generation...")
|
||||
fmt.Printf("📁 Config file: %s\n", configFile)
|
||||
if targetService != "" {
|
||||
fmt.Printf("🎯 Target service: %s\n", targetService)
|
||||
}
|
||||
|
||||
generated := 0
|
||||
errors := 0
|
||||
|
||||
// Generate handlers
|
||||
for serviceName, service := range config.Services {
|
||||
if targetService != "" && serviceName != targetService {
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("🔧 Generating handler for service: %s (%s)\n", service.Name, service.Category)
|
||||
err := generateHandler(serviceName, service, config.Global)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error generating handler for %s: %v\n", serviceName, err)
|
||||
errors++
|
||||
continue
|
||||
}
|
||||
fmt.Printf("✅ Generated handler: %s_handler.go\n", strings.ToLower(serviceName))
|
||||
generated++
|
||||
}
|
||||
|
||||
// Summary
|
||||
fmt.Println("\n📊 Generation Summary:")
|
||||
fmt.Printf(" ✅ Successfully generated: %d handlers\n", generated)
|
||||
if errors > 0 {
|
||||
fmt.Printf(" ❌ Failed: %d handlers\n", errors)
|
||||
}
|
||||
|
||||
if generated > 0 {
|
||||
fmt.Println("🎉 Generation completed successfully!")
|
||||
}
|
||||
}
|
||||
|
||||
func printUsage() {
|
||||
fmt.Println("BPJS Dynamic Handler Generator")
|
||||
fmt.Println()
|
||||
fmt.Println("Usage:")
|
||||
fmt.Println(" go run generate-dynamic-handler.go <config-file> [service-name]")
|
||||
fmt.Println()
|
||||
fmt.Println("Examples:")
|
||||
fmt.Println(" go run generate-dynamic-handler.go services-config.yaml")
|
||||
fmt.Println(" go run generate-dynamic-handler.go services-config.yaml vclaim")
|
||||
}
|
||||
|
||||
func loadConfig(filename string) (*ServiceConfig, error) {
|
||||
data, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read config file: %w", err)
|
||||
}
|
||||
|
||||
var config ServiceConfig
|
||||
err = yaml.Unmarshal(data, &config)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse YAML config: %w", err)
|
||||
}
|
||||
|
||||
// Set default values
|
||||
if config.Global.ModuleName == "" {
|
||||
config.Global.ModuleName = "api-service"
|
||||
}
|
||||
if config.Global.OutputDir == "" {
|
||||
config.Global.OutputDir = "internal/handlers"
|
||||
}
|
||||
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
func generateHandler(serviceName string, service Service, globalConfig GlobalConfig) error {
|
||||
// Prepare template data
|
||||
templateData := TemplateData{
|
||||
ServiceName: service.Name,
|
||||
ServiceLower: strings.ToLower(service.Name),
|
||||
ServiceUpper: strings.ToUpper(service.Name),
|
||||
Category: service.Category,
|
||||
Package: service.Package,
|
||||
Description: service.Description,
|
||||
BaseURL: service.BaseURL,
|
||||
Timeout: getOrDefault(service.Timeout, 30),
|
||||
RetryCount: getOrDefault(service.RetryCount, 3),
|
||||
Timestamp: time.Now().Format("2006-01-02 15:04:05"),
|
||||
ModuleName: globalConfig.ModuleName,
|
||||
HasValidator: true,
|
||||
HasLogger: globalConfig.EnableLogging,
|
||||
HasMetrics: globalConfig.EnableMetrics,
|
||||
HasSwagger: globalConfig.EnableSwagger,
|
||||
Dependencies: service.Dependencies, // Now []string
|
||||
Middleware: service.Middleware, // Now []string
|
||||
GlobalConfig: globalConfig,
|
||||
}
|
||||
|
||||
// Check for advanced features
|
||||
for _, endpoint := range service.Endpoints {
|
||||
if endpoint.RequireAuth {
|
||||
templateData.HasAuth = true
|
||||
}
|
||||
if endpoint.CacheEnabled {
|
||||
templateData.HasCache = true
|
||||
}
|
||||
}
|
||||
|
||||
// Process endpoints
|
||||
for endpointName, endpoint := range service.Endpoints {
|
||||
endpointData := processEndpoint(endpointName, endpoint)
|
||||
templateData.Endpoints = append(templateData.Endpoints, endpointData)
|
||||
}
|
||||
|
||||
// Create output directory
|
||||
outputDir := globalConfig.OutputDir
|
||||
if outputDir == "" {
|
||||
outputDir = "internal/handlers"
|
||||
}
|
||||
if err := os.MkdirAll(outputDir, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create output directory: %w", err)
|
||||
}
|
||||
|
||||
// Generate handler file
|
||||
filename := filepath.Join(outputDir, fmt.Sprintf("%s_handler.go", strings.ToLower(serviceName)))
|
||||
|
||||
// Create template with custom functions
|
||||
tmpl := template.New("handler").Funcs(template.FuncMap{
|
||||
"contains": strings.Contains,
|
||||
"join": strings.Join,
|
||||
"title": strings.Title,
|
||||
"trimPrefix": strings.TrimPrefix,
|
||||
})
|
||||
|
||||
tmpl, err := tmpl.Parse(handlerTemplate)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse template: %w", err)
|
||||
}
|
||||
|
||||
file, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create file: %w", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
err = tmpl.Execute(file, templateData)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute template: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func processEndpoint(name string, endpoint Endpoint) EndpointData {
|
||||
data := EndpointData{
|
||||
Name: strings.Title(name),
|
||||
NameLower: strings.ToLower(name),
|
||||
NameUpper: strings.ToUpper(name),
|
||||
NameCamel: toCamelCase(name),
|
||||
Methods: endpoint.Methods,
|
||||
GetPath: endpoint.GetPath,
|
||||
PostPath: endpoint.PostPath,
|
||||
PutPath: endpoint.PutPath,
|
||||
DeletePath: endpoint.DeletePath,
|
||||
PatchPath: endpoint.PatchPath,
|
||||
Model: endpoint.Model,
|
||||
ResponseModel: endpoint.ResponseModel,
|
||||
Description: endpoint.Description,
|
||||
Summary: endpoint.Summary,
|
||||
Tags: endpoint.Tags,
|
||||
RequireAuth: endpoint.RequireAuth,
|
||||
RateLimit: endpoint.RateLimit,
|
||||
CacheEnabled: endpoint.CacheEnabled,
|
||||
CacheTTL: getOrDefault(endpoint.CacheTTL, 300),
|
||||
CustomHeaders: endpoint.CustomHeaders,
|
||||
}
|
||||
|
||||
// Set method flags and extract path parameters
|
||||
for _, method := range endpoint.Methods {
|
||||
switch strings.ToUpper(method) {
|
||||
case "GET":
|
||||
data.HasGet = true
|
||||
data.PathParams = extractPathParams(endpoint.GetPath)
|
||||
case "POST":
|
||||
data.HasPost = true
|
||||
case "PUT":
|
||||
data.HasPut = true
|
||||
data.PathParams = extractPathParams(endpoint.PutPath)
|
||||
case "DELETE":
|
||||
data.HasDelete = true
|
||||
data.PathParams = extractPathParams(endpoint.DeletePath)
|
||||
case "PATCH":
|
||||
data.HasPatch = true
|
||||
data.PathParams = extractPathParams(endpoint.PatchPath)
|
||||
}
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
func extractPathParams(path string) []string {
|
||||
if path == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var params []string
|
||||
parts := strings.Split(path, "/")
|
||||
for _, part := range parts {
|
||||
if strings.HasPrefix(part, ":") {
|
||||
params = append(params, strings.TrimPrefix(part, ":"))
|
||||
}
|
||||
}
|
||||
|
||||
return params
|
||||
}
|
||||
|
||||
func toCamelCase(str string) string {
|
||||
words := strings.FieldsFunc(str, func(c rune) bool {
|
||||
return c == '_' || c == '-' || c == ' '
|
||||
})
|
||||
|
||||
if len(words) == 0 {
|
||||
return str
|
||||
}
|
||||
|
||||
result := strings.ToLower(words[0])
|
||||
for _, word := range words[1:] {
|
||||
result += strings.Title(strings.ToLower(word))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func getOrDefault(value, defaultValue int) int {
|
||||
if value == 0 {
|
||||
return defaultValue
|
||||
}
|
||||
return value
|
||||
}
|
||||
2
go.mod
2
go.mod
@@ -26,6 +26,7 @@ require (
|
||||
github.com/swaggo/gin-swagger v1.6.0
|
||||
github.com/swaggo/swag v1.16.6
|
||||
github.com/tidwall/gjson v1.18.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -82,7 +83,6 @@ require (
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
golang.org/x/tools v0.35.0 // indirect
|
||||
google.golang.org/protobuf v1.36.7 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gorm.io/gorm v1.30.0 // indirect
|
||||
)
|
||||
|
||||
@@ -1,510 +0,0 @@
|
||||
// Code generated by generate-dynamic-handler.go DO NOT EDIT.
|
||||
// Generated at 2025-09-01 13:38:57
|
||||
// Service: VClaim (vclaim)
|
||||
// Description: BPJS VClaim service for eligibility and SEP management
|
||||
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"api-service/internal/config"
|
||||
"api-service/internal/models"
|
||||
"api-service/internal/models/vclaim/peserta"
|
||||
"api-service/internal/models/vclaim/sep"
|
||||
"api-service/internal/services"
|
||||
"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,
|
||||
}
|
||||
}
|
||||
|
||||
// GetPesertaBynokartu godoc
|
||||
// @Summary Get participant data by card number
|
||||
// @Description Get participant eligibility information from BPJS by card number
|
||||
// @Tags vclaim,peserta
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param X-Request-ID header string false "Request ID for tracking"
|
||||
// @Param nokartu path string true "BPJS card number" example("0000054321654")
|
||||
// @Success 200 {object} peserta.PesertaResponse "Successfully retrieved participant data"
|
||||
// @Failure 400 {object} models.ErrorResponseBpjs "Bad request - invalid card number format"
|
||||
// @Failure 401 {object} models.ErrorResponseBpjs "Unauthorized - invalid API credentials"
|
||||
// @Failure 404 {object} models.ErrorResponseBpjs "Not found - participant not found"
|
||||
// @Failure 500 {object} models.ErrorResponseBpjs "Internal server error"
|
||||
// @Router /peserta/{nokartu} [get]
|
||||
func (h *VClaimHandler) GetPesertaBynokartu(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 GetPesertaBynokartu 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, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Missing required parameter: nokartu",
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Call service method
|
||||
var response peserta.PesertaResponse
|
||||
endpoint := "peserta/{nokartu}"
|
||||
endpoint = strings.Replace(endpoint, "{nokartu}", nokartu, 1)
|
||||
|
||||
err := h.service.Get(ctx, endpoint, &response)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to get PesertaBynokartu", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{
|
||||
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)
|
||||
}
|
||||
|
||||
// GetPesertaBynik godoc
|
||||
// @Summary Get participant data by NIK
|
||||
// @Description Get participant eligibility information from BPJS by National ID Number (NIK)
|
||||
// @Tags vclaim,peserta
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param X-Request-ID header string false "Request ID for tracking"
|
||||
// @Param nik path string true "National ID Number (NIK)" example("3201234567890123")
|
||||
// @Success 200 {object} peserta.PesertaResponse "Successfully retrieved participant data"
|
||||
// @Failure 400 {object} models.ErrorResponseBpjs "Bad request - invalid NIK format"
|
||||
// @Failure 401 {object} models.ErrorResponseBpjs "Unauthorized - invalid API credentials"
|
||||
// @Failure 404 {object} models.ErrorResponseBpjs "Not found - participant not found"
|
||||
// @Failure 500 {object} models.ErrorResponseBpjs "Internal server error"
|
||||
// @Router /peserta/nik/{nik} [get]
|
||||
func (h *VClaimHandler) GetPesertaBynik(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 GetPesertaBynik request", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
"endpoint": "peserta/nik/{nik}",
|
||||
"nik": c.Param("nik"),
|
||||
})
|
||||
|
||||
// Extract path parameters
|
||||
nik := c.Param("nik")
|
||||
if nik == "" {
|
||||
h.logger.Error("Missing required parameter: nik", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Missing required parameter: nik",
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Call service method
|
||||
var response peserta.PesertaResponse
|
||||
endpoint := "peserta/nik/{nik}"
|
||||
endpoint = strings.Replace(endpoint, "{nik}", nik, 1)
|
||||
|
||||
err := h.service.Get(ctx, endpoint, &response)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to get PesertaBynik", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{
|
||||
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)
|
||||
}
|
||||
|
||||
// GetSepSep godoc
|
||||
// @Summary Get SEP data by number
|
||||
// @Description Get SEP (Surat Eligibilitas Peserta) information by SEP number
|
||||
// @Tags vclaim,sep
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param X-Request-ID header string false "Request ID for tracking"
|
||||
// @Param nosep path string true "SEP Number" example("0301R0010717V000001")
|
||||
// @Success 200 {object} sep.SepResponse "Successfully retrieved SEP data"
|
||||
// @Failure 400 {object} models.ErrorResponseBpjs "Bad request - invalid SEP number format"
|
||||
// @Failure 401 {object} models.ErrorResponseBpjs "Unauthorized - invalid API credentials"
|
||||
// @Failure 404 {object} models.ErrorResponseBpjs "Not found - SEP not found"
|
||||
// @Failure 500 {object} models.ErrorResponseBpjs "Internal server error"
|
||||
// @Router /sep/{nosep} [get]
|
||||
func (h *VClaimHandler) GetSepSep(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 GetSepSep 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, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Missing required parameter: nosep",
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Call service method
|
||||
var response sep.SepResponse
|
||||
endpoint := "sep/{nosep}"
|
||||
endpoint = strings.Replace(endpoint, "{nosep}", nosep, 1)
|
||||
|
||||
err := h.service.Get(ctx, endpoint, &response)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to get SepSep", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{
|
||||
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)
|
||||
}
|
||||
|
||||
// CreateSepSep godoc
|
||||
// @Summary Create new SEP
|
||||
// @Description Create a new SEP (Surat Eligibilitas Peserta) for participant
|
||||
// @Tags vclaim,sep
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param X-Request-ID header string false "Request ID for tracking"
|
||||
// @Param request body sep.SepRequest true "SEP creation data"
|
||||
// @Success 201 {object} sep.SepResponse "Successfully created SEP"
|
||||
// @Failure 400 {object} models.ErrorResponseBpjs "Bad request - invalid request body or validation error"
|
||||
// @Failure 401 {object} models.ErrorResponseBpjs "Unauthorized - invalid API credentials"
|
||||
// @Failure 409 {object} models.ErrorResponseBpjs "Conflict - SEP already exists"
|
||||
// @Failure 500 {object} models.ErrorResponseBpjs "Internal server error"
|
||||
// @Router /sep [post]
|
||||
func (h *VClaimHandler) CreateSepSep(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 CreateSepSep request", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
|
||||
var req sep.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, models.ErrorResponseBpjs{
|
||||
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, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Validation failed: " + err.Error(),
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Call service method
|
||||
var response sep.SepResponse
|
||||
err := h.service.Post(ctx, "sep", &req, &response)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to create SepSep", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{
|
||||
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)
|
||||
}
|
||||
|
||||
// UpdateSepSep godoc
|
||||
// @Summary Update existing SEP
|
||||
// @Description Update an existing SEP (Surat Eligibilitas Peserta) by SEP number
|
||||
// @Tags vclaim,sep
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param X-Request-ID header string false "Request ID for tracking"
|
||||
// @Param nosep path string true "SEP Number to update" example("0301R0010717V000001")
|
||||
// @Param request body sep.SepRequest true "SEP update data"
|
||||
// @Success 200 {object} sep.SepResponse "Successfully updated SEP"
|
||||
// @Failure 400 {object} models.ErrorResponseBpjs "Bad request - invalid request body or validation error"
|
||||
// @Failure 401 {object} models.ErrorResponseBpjs "Unauthorized - invalid API credentials"
|
||||
// @Failure 404 {object} models.ErrorResponseBpjs "Not found - SEP not found"
|
||||
// @Failure 500 {object} models.ErrorResponseBpjs "Internal server error"
|
||||
// @Router /sep/{nosep} [put]
|
||||
func (h *VClaimHandler) UpdateSepSep(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 UpdateSepSep request", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
|
||||
nosep := c.Param("nosep")
|
||||
if nosep == "" {
|
||||
h.logger.Error("Missing required parameter: nosep", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Missing required parameter: nosep",
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
var req sep.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, models.ErrorResponseBpjs{
|
||||
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, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Validation failed: " + err.Error(),
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Call service method
|
||||
var response sep.SepResponse
|
||||
endpoint := "sep/{nosep}"
|
||||
endpoint = strings.Replace(endpoint, "{nosep}", nosep, 1)
|
||||
|
||||
err := h.service.Put(ctx, endpoint, &req, &response)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to update SepSep", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{
|
||||
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)
|
||||
}
|
||||
|
||||
// DeleteSepSep godoc
|
||||
// @Summary Delete SEP
|
||||
// @Description Delete an existing SEP (Surat Eligibilitas Peserta) by SEP number
|
||||
// @Tags vclaim,sep
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param X-Request-ID header string false "Request ID for tracking"
|
||||
// @Param nosep path string true "SEP Number to delete" example("0301R0010717V000001")
|
||||
// @Success 200 {object} sep.SepResponse "Successfully deleted SEP"
|
||||
// @Failure 400 {object} models.ErrorResponseBpjs "Bad request - invalid SEP number format"
|
||||
// @Failure 401 {object} models.ErrorResponseBpjs "Unauthorized - invalid API credentials"
|
||||
// @Failure 404 {object} models.ErrorResponseBpjs "Not found - SEP not found"
|
||||
// @Failure 500 {object} models.ErrorResponseBpjs "Internal server error"
|
||||
// @Router /sep/{nosep} [delete]
|
||||
func (h *VClaimHandler) DeleteSepSep(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 DeleteSepSep request", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
|
||||
nosep := c.Param("nosep")
|
||||
if nosep == "" {
|
||||
h.logger.Error("Missing required parameter: nosep", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Missing required parameter: nosep",
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Call service method
|
||||
var response sep.SepResponse
|
||||
endpoint := "sep/{nosep}"
|
||||
endpoint = strings.Replace(endpoint, "{nosep}", nosep, 1)
|
||||
|
||||
err := h.service.Delete(ctx, endpoint, &response)
|
||||
if err != nil {
|
||||
h.logger.Error("Failed to delete SepSep", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{
|
||||
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)
|
||||
}
|
||||
@@ -1,543 +0,0 @@
|
||||
// Code generated by generate-dynamic-handler.go; DO NOT EDIT.
|
||||
// Generated at: 2025-09-01 13:38:57
|
||||
// Service: VClaim (vclaim)
|
||||
// Description: BPJS VClaim service for eligibility and SEP management
|
||||
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"api-service/internal/config"
|
||||
"api-service/internal/models"
|
||||
"api-service/internal/models/vclaim/peserta"
|
||||
"api-service/internal/models/vclaim/sep"
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
GetPesertaBynokartu godoc
|
||||
@Summary Get PesertaBynokartu data
|
||||
@Description Get participant eligibility information by card number
|
||||
@Tags vclaim,peserta,nokartu
|
||||
@Accept json
|
||||
@Produce json
|
||||
@Param nokartu path string true "nokartu"
|
||||
@Success 200 {object} peserta.PesertaResponse
|
||||
@Failure 400 {object} models.ErrorResponseBpjs
|
||||
@Failure 500 {object} models.ErrorResponseBpjs
|
||||
@Router /peserta/:nokartu [get]
|
||||
*/
|
||||
func (h *VClaimHandler) GetPesertaBynokartu(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 GetPesertaBynokartu 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, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Missing required parameter nokartu",
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Call service method
|
||||
var response peserta.PesertaResponse
|
||||
|
||||
endpoint := "/peserta/:nokartu"
|
||||
|
||||
endpoint = strings.Replace(endpoint, ":nokartu", nokartu, 1)
|
||||
|
||||
err := h.service.Get(ctx, endpoint, &response)
|
||||
|
||||
if err != nil {
|
||||
|
||||
h.logger.Error("Failed to get PesertaBynokartu", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{
|
||||
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)
|
||||
}
|
||||
|
||||
/*
|
||||
GetPesertaBynik godoc
|
||||
@Summary Get PesertaBynik data
|
||||
@Description Get participant eligibility information by NIK
|
||||
@Tags vclaim,peserta,nik
|
||||
@Accept json
|
||||
@Produce json
|
||||
@Param nik path string true "nik"
|
||||
@Success 200 {object} peserta.PesertaResponse
|
||||
@Failure 400 {object} models.ErrorResponseBpjs
|
||||
@Failure 500 {object} models.ErrorResponseBpjs
|
||||
@Router /peserta/nik/:nik [get]
|
||||
*/
|
||||
func (h *VClaimHandler) GetPesertaBynik(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 GetPesertaBynik request", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
"endpoint": "/peserta/nik/:nik",
|
||||
|
||||
"nik": c.Param("nik"),
|
||||
})
|
||||
|
||||
// Extract path parameters
|
||||
|
||||
nik := c.Param("nik")
|
||||
if nik == "" {
|
||||
|
||||
h.logger.Error("Missing required parameter nik", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Missing required parameter nik",
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Call service method
|
||||
var response peserta.PesertaResponse
|
||||
|
||||
endpoint := "/peserta/nik/:nik"
|
||||
|
||||
endpoint = strings.Replace(endpoint, ":nik", nik, 1)
|
||||
|
||||
err := h.service.Get(ctx, endpoint, &response)
|
||||
|
||||
if err != nil {
|
||||
|
||||
h.logger.Error("Failed to get PesertaBynik", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{
|
||||
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)
|
||||
}
|
||||
|
||||
/*
|
||||
GetSepSep godoc
|
||||
@Summary Get SepSep data
|
||||
@Description Manage SEP (Surat Eligibilitas Peserta)
|
||||
@Tags vclaim,sep
|
||||
@Accept json
|
||||
@Produce json
|
||||
@Param nosep path string true "nosep"
|
||||
@Success 200 {object} sep.SepResponse
|
||||
@Failure 400 {object} models.ErrorResponseBpjs
|
||||
@Failure 500 {object} models.ErrorResponseBpjs
|
||||
@Router /sep/:nosep [get]
|
||||
*/
|
||||
func (h *VClaimHandler) GetSepSep(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 GetSepSep 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, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Missing required parameter nosep",
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Call service method
|
||||
var response sep.SepResponse
|
||||
|
||||
endpoint := "/sep/:nosep"
|
||||
|
||||
endpoint = strings.Replace(endpoint, ":nosep", nosep, 1)
|
||||
|
||||
err := h.service.Get(ctx, endpoint, &response)
|
||||
|
||||
if err != nil {
|
||||
|
||||
h.logger.Error("Failed to get SepSep", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{
|
||||
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)
|
||||
}
|
||||
|
||||
/*
|
||||
CreateSepSep godoc
|
||||
@Summary Create SepSep
|
||||
@Description Manage SEP (Surat Eligibilitas Peserta)
|
||||
@Tags vclaim,sep
|
||||
@Accept json
|
||||
@Produce json
|
||||
@Param request body sep.SepRequest true "SepSep data"
|
||||
@Success 201 {object} sep.SepResponse
|
||||
@Failure 400 {object} models.ErrorResponseBpjs
|
||||
@Failure 500 {object} models.ErrorResponseBpjs
|
||||
@Router /sep [post]
|
||||
*/
|
||||
func (h *VClaimHandler) CreateSepSep(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 CreateSepSep request", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
|
||||
var req sep.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, models.ErrorResponseBpjs{
|
||||
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, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Validation failed: " + err.Error(),
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Call service method
|
||||
var response sep.SepResponse
|
||||
err := h.service.Post(ctx, "/sep", &req, &response)
|
||||
if err != nil {
|
||||
|
||||
h.logger.Error("Failed to create SepSep", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{
|
||||
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)
|
||||
}
|
||||
|
||||
/*
|
||||
UpdateSepSep godoc
|
||||
@Summary Update SepSep
|
||||
@Description Manage SEP (Surat Eligibilitas Peserta)
|
||||
@Tags vclaim,sep
|
||||
@Accept json
|
||||
@Produce json
|
||||
@Param nosep path string true "nosep"
|
||||
@Param request body sep.SepRequest true "SepSep data"
|
||||
@Success 200 {object} sep.SepResponse
|
||||
@Failure 400 {object} models.ErrorResponseBpjs
|
||||
@Failure 500 {object} models.ErrorResponseBpjs
|
||||
@Router /sep/:nosep [put]
|
||||
*/
|
||||
func (h *VClaimHandler) UpdateSepSep(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 UpdateSepSep request", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
|
||||
nosep := c.Param("nosep")
|
||||
if nosep == "" {
|
||||
|
||||
h.logger.Error("Missing required parameter nosep", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Missing required parameter nosep",
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
var req sep.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, models.ErrorResponseBpjs{
|
||||
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, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Validation failed: " + err.Error(),
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Call service method
|
||||
var response sep.SepResponse
|
||||
|
||||
endpoint := "/sep/:nosep"
|
||||
|
||||
endpoint = strings.Replace(endpoint, ":nosep", nosep, 1)
|
||||
|
||||
err := h.service.Put(ctx, endpoint, &req, &response)
|
||||
|
||||
if err != nil {
|
||||
|
||||
h.logger.Error("Failed to update SepSep", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{
|
||||
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)
|
||||
}
|
||||
|
||||
/*
|
||||
DeleteSepSep godoc
|
||||
@Summary Delete SepSep
|
||||
@Description Manage SEP (Surat Eligibilitas Peserta)
|
||||
@Tags vclaim,sep
|
||||
@Accept json
|
||||
@Produce json
|
||||
@Param nosep path string true "nosep"
|
||||
@Success 200 {object} sep.SepResponse
|
||||
@Failure 400 {object} models.ErrorResponseBpjs
|
||||
@Failure 500 {object} models.ErrorResponseBpjs
|
||||
@Router /sep/:nosep [delete]
|
||||
*/
|
||||
func (h *VClaimHandler) DeleteSepSep(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 DeleteSepSep request", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
|
||||
nosep := c.Param("nosep")
|
||||
if nosep == "" {
|
||||
|
||||
h.logger.Error("Missing required parameter nosep", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Missing required parameter nosep",
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Call service method
|
||||
var response sep.SepResponse
|
||||
|
||||
endpoint := "/sep/:nosep"
|
||||
|
||||
endpoint = strings.Replace(endpoint, ":nosep", nosep, 1)
|
||||
|
||||
err := h.service.Delete(ctx, endpoint, &response)
|
||||
|
||||
if err != nil {
|
||||
|
||||
h.logger.Error("Failed to delete SepSep", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{
|
||||
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)
|
||||
}
|
||||
232
internal/handlers/vclaim/peserta/peserta.go
Normal file
232
internal/handlers/vclaim/peserta/peserta.go
Normal file
@@ -0,0 +1,232 @@
|
||||
|
||||
// Service: VClaim (vclaim)
|
||||
// Description: BPJS VClaim service for eligibility and SEP management
|
||||
|
||||
package peserta
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"api-service/internal/config"
|
||||
"api-service/internal/models"
|
||||
"api-service/internal/models/vclaim/peserta"
|
||||
"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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// GetPesertaBynokartu godoc
|
||||
// @Summary Get PesertaBynokartu data
|
||||
// @Description Get participant eligibility information by card number
|
||||
// @Tags Peserta
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param X-Request-ID header string false "Request ID for tracking"
|
||||
// @Param nokartu path string true "nokartu" example("example_value")
|
||||
// @Success 200 {object} peserta.PesertaResponse "Successfully retrieved PesertaBynokartu data"
|
||||
// @Failure 400 {object} models.ErrorResponseBpjs "Bad request - invalid parameters"
|
||||
// @Failure 401 {object} models.ErrorResponseBpjs "Unauthorized - invalid API credentials"
|
||||
// @Failure 404 {object} models.ErrorResponseBpjs "Not found - PesertaBynokartu not found"
|
||||
// @Failure 500 {object} models.ErrorResponseBpjs "Internal server error"
|
||||
// @Router /peserta/:nokartu [get]
|
||||
func (h *VClaimHandler) GetPesertaBynokartu(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 GetPesertaBynokartu 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, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Missing required parameter nokartu",
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Call service method
|
||||
var response peserta.PesertaResponse
|
||||
|
||||
endpoint := "/peserta/:nokartu"
|
||||
|
||||
endpoint = strings.Replace(endpoint, ":nokartu", nokartu, 1)
|
||||
|
||||
err := h.service.Get(ctx, endpoint, &response)
|
||||
|
||||
if err != nil {
|
||||
|
||||
h.logger.Error("Failed to get PesertaBynokartu", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// GetPesertaBynik godoc
|
||||
// @Summary Get PesertaBynik data
|
||||
// @Description Get participant eligibility information by NIK
|
||||
// @Tags Peserta
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param X-Request-ID header string false "Request ID for tracking"
|
||||
// @Param nik path string true "nik" example("example_value")
|
||||
// @Success 200 {object} peserta.PesertaResponse "Successfully retrieved PesertaBynik data"
|
||||
// @Failure 400 {object} models.ErrorResponseBpjs "Bad request - invalid parameters"
|
||||
// @Failure 401 {object} models.ErrorResponseBpjs "Unauthorized - invalid API credentials"
|
||||
// @Failure 404 {object} models.ErrorResponseBpjs "Not found - PesertaBynik not found"
|
||||
// @Failure 500 {object} models.ErrorResponseBpjs "Internal server error"
|
||||
// @Router /peserta/nik/:nik [get]
|
||||
func (h *VClaimHandler) GetPesertaBynik(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 GetPesertaBynik request", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
"endpoint": "/peserta/nik/:nik",
|
||||
|
||||
"nik": c.Param("nik"),
|
||||
|
||||
})
|
||||
|
||||
|
||||
// Extract path parameters
|
||||
|
||||
nik := c.Param("nik")
|
||||
if nik == "" {
|
||||
|
||||
h.logger.Error("Missing required parameter nik", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Missing required parameter nik",
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Call service method
|
||||
var response peserta.PesertaResponse
|
||||
|
||||
endpoint := "/peserta/nik/:nik"
|
||||
|
||||
endpoint = strings.Replace(endpoint, ":nik", nik, 1)
|
||||
|
||||
err := h.service.Get(ctx, endpoint, &response)
|
||||
|
||||
if err != nil {
|
||||
|
||||
h.logger.Error("Failed to get PesertaBynik", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Service: VClaim (vclaim)
|
||||
// Description: BPJS VClaim service for eligibility and SEP management
|
||||
|
||||
package handlers
|
||||
package sep
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
|
||||
"api-service/internal/config"
|
||||
"api-service/internal/models"
|
||||
"api-service/internal/models/vclaim/peserta"
|
||||
"api-service/internal/models/vclaim/sep"
|
||||
"api-service/internal/services/bpjs"
|
||||
"api-service/pkg/logger"
|
||||
@@ -48,205 +47,15 @@ func NewVClaimHandler(cfg VClaimHandlerConfig) *VClaimHandler {
|
||||
}
|
||||
|
||||
|
||||
// GetPESERTABYNIK godoc
|
||||
// @Summary Get PesertaBynik data
|
||||
// @Description Get participant eligibility information by NIK
|
||||
// @Tags vclaim,peserta,nik
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
|
||||
// @Param X-Request-ID header string false "Request ID for tracking"
|
||||
|
||||
// @Param nik path string true "nik" example("example_value")
|
||||
|
||||
// @Success 200 {object} peserta.PesertaResponse "Successfully retrieved PesertaBynik data"
|
||||
// @Failure 400 {object} models.ErrorResponseBpjs "Bad request - invalid parameters"
|
||||
// @Failure 401 {object} models.ErrorResponseBpjs "Unauthorized - invalid API credentials"
|
||||
// @Failure 404 {object} models.ErrorResponseBpjs "Not found - PesertaBynik not found"
|
||||
// @Failure 500 {object} models.ErrorResponseBpjs "Internal server error"
|
||||
// @Router /peserta/nik/:nik [get]
|
||||
func (h *VClaimHandler) GetPesertaBynik(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 GetPesertaBynik request", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
"endpoint": "/peserta/nik/:nik",
|
||||
|
||||
"nik": c.Param("nik"),
|
||||
|
||||
})
|
||||
|
||||
|
||||
// Extract path parameters
|
||||
|
||||
nik := c.Param("nik")
|
||||
if nik == "" {
|
||||
|
||||
h.logger.Error("Missing required parameter nik", map[string]interface{}{
|
||||
"request_id": requestID,
|
||||
})
|
||||
|
||||
c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Missing required parameter nik",
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Call service method
|
||||
var response peserta.PesertaResponse
|
||||
|
||||
endpoint := "/peserta/nik/:nik"
|
||||
|
||||
endpoint = strings.Replace(endpoint, ":nik", nik, 1)
|
||||
|
||||
err := h.service.Get(ctx, endpoint, &response)
|
||||
|
||||
if err != nil {
|
||||
|
||||
h.logger.Error("Failed to get PesertaBynik", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// GetPESERTABYNOKARTU godoc
|
||||
// @Summary Get PesertaBynokartu data
|
||||
// @Description Get participant eligibility information by card number
|
||||
// @Tags vclaim,peserta,nokartu
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
|
||||
// @Param X-Request-ID header string false "Request ID for tracking"
|
||||
|
||||
// @Param nokartu path string true "nokartu" example("example_value")
|
||||
|
||||
// @Success 200 {object} peserta.PesertaResponse "Successfully retrieved PesertaBynokartu data"
|
||||
// @Failure 400 {object} models.ErrorResponseBpjs "Bad request - invalid parameters"
|
||||
// @Failure 401 {object} models.ErrorResponseBpjs "Unauthorized - invalid API credentials"
|
||||
// @Failure 404 {object} models.ErrorResponseBpjs "Not found - PesertaBynokartu not found"
|
||||
// @Failure 500 {object} models.ErrorResponseBpjs "Internal server error"
|
||||
// @Router /peserta/:nokartu [get]
|
||||
func (h *VClaimHandler) GetPesertaBynokartu(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 GetPesertaBynokartu 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, models.ErrorResponseBpjs{
|
||||
Status: "error",
|
||||
Message: "Missing required parameter nokartu",
|
||||
RequestID: requestID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Call service method
|
||||
var response peserta.PesertaResponse
|
||||
|
||||
endpoint := "/peserta/:nokartu"
|
||||
|
||||
endpoint = strings.Replace(endpoint, ":nokartu", nokartu, 1)
|
||||
|
||||
err := h.service.Get(ctx, endpoint, &response)
|
||||
|
||||
if err != nil {
|
||||
|
||||
h.logger.Error("Failed to get PesertaBynokartu", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"request_id": requestID,
|
||||
})
|
||||
|
||||
c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// GetSEPSEP godoc
|
||||
// GetSepSep godoc
|
||||
// @Summary Get SepSep data
|
||||
// @Description Manage SEP (Surat Eligibilitas Peserta)
|
||||
// @Tags vclaim,sep
|
||||
// @Tags Sep
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
|
||||
// @Security ApiKeyAuth
|
||||
// @Param X-Request-ID header string false "Request ID for tracking"
|
||||
|
||||
// @Param nosep path string true "nosep" example("example_value")
|
||||
|
||||
// @Success 200 {object} sep.SepResponse "Successfully retrieved SepSep data"
|
||||
// @Failure 400 {object} models.ErrorResponseBpjs "Bad request - invalid parameters"
|
||||
// @Failure 401 {object} models.ErrorResponseBpjs "Unauthorized - invalid API credentials"
|
||||
@@ -324,13 +133,13 @@ func (h *VClaimHandler) GetSepSep(c *gin.Context) {
|
||||
|
||||
|
||||
|
||||
// CreateSEPSEP godoc
|
||||
// CreateSepSep godoc
|
||||
// @Summary Create new SepSep
|
||||
// @Description Manage SEP (Surat Eligibilitas Peserta)
|
||||
// @Tags vclaim,sep
|
||||
// @Tags Sep
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
|
||||
// @Security ApiKeyAuth
|
||||
// @Param X-Request-ID header string false "Request ID for tracking"
|
||||
// @Param request body sep.SepRequest true "SepSep data"
|
||||
// @Success 201 {object} sep.SepResponse "Successfully created SepSep"
|
||||
@@ -413,17 +222,15 @@ func (h *VClaimHandler) CreateSepSep(c *gin.Context) {
|
||||
|
||||
|
||||
|
||||
// UpdateSEPSEP godoc
|
||||
// UpdateSepSep godoc
|
||||
// @Summary Update existing SepSep
|
||||
// @Description Manage SEP (Surat Eligibilitas Peserta)
|
||||
// @Tags vclaim,sep
|
||||
// @Tags Sep
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
|
||||
// @Security ApiKeyAuth
|
||||
// @Param X-Request-ID header string false "Request ID for tracking"
|
||||
|
||||
// @Param nosep path string true "nosep" example("example_value")
|
||||
|
||||
// @Param request body sep.SepRequest true "SepSep data"
|
||||
// @Success 200 {object} sep.SepResponse "Successfully updated SepSep"
|
||||
// @Failure 400 {object} models.ErrorResponseBpjs "Bad request - invalid parameters or request body"
|
||||
@@ -528,17 +335,15 @@ func (h *VClaimHandler) UpdateSepSep(c *gin.Context) {
|
||||
|
||||
|
||||
|
||||
// DeleteSEPSEP godoc
|
||||
// DeleteSepSep godoc
|
||||
// @Summary Delete existing SepSep
|
||||
// @Description Manage SEP (Surat Eligibilitas Peserta)
|
||||
// @Tags vclaim,sep
|
||||
// @Tags Sep
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
|
||||
// @Security ApiKeyAuth
|
||||
// @Param X-Request-ID header string false "Request ID for tracking"
|
||||
|
||||
// @Param nosep path string true "nosep" example("example_value")
|
||||
|
||||
// @Success 200 {object} sep.SepResponse "Successfully deleted SepSep"
|
||||
// @Failure 400 {object} models.ErrorResponseBpjs "Bad request - invalid parameters"
|
||||
// @Failure 401 {object} models.ErrorResponseBpjs "Unauthorized - invalid API credentials"
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
authHandlers "api-service/internal/handlers/auth"
|
||||
healthcheckHandlers "api-service/internal/handlers/healthcheck"
|
||||
retribusiHandlers "api-service/internal/handlers/retribusi"
|
||||
"api-service/internal/handlers/vclaim/peserta"
|
||||
"api-service/internal/handlers/vclaim/sep"
|
||||
"api-service/internal/middleware"
|
||||
services "api-service/internal/services/auth"
|
||||
"api-service/pkg/logger"
|
||||
@@ -66,6 +68,28 @@ func RegisterRoutes(cfg *config.Config) *gin.Engine {
|
||||
|
||||
// ============= PUBLISHED ROUTES ===============================================
|
||||
|
||||
// Peserta routes
|
||||
pesertaHandler := peserta.NewVClaimHandler(peserta.VClaimHandlerConfig{
|
||||
BpjsConfig: cfg.Bpjs,
|
||||
Logger: *logger.Default(),
|
||||
Validator: nil,
|
||||
})
|
||||
pesertaGroup := v1.Group("/peserta")
|
||||
pesertaGroup.GET("/peserta/:nokartu", pesertaHandler.GetPesertaBynokartu)
|
||||
pesertaGroup.GET("/peserta/nik/:nik", pesertaHandler.GetPesertaBynik)
|
||||
|
||||
// Sep routes
|
||||
sepHandler := sep.NewVClaimHandler(sep.VClaimHandlerConfig{
|
||||
BpjsConfig: cfg.Bpjs,
|
||||
Logger: *logger.Default(),
|
||||
Validator: nil,
|
||||
})
|
||||
sepGroup := v1.Group("/sep")
|
||||
sepGroup.GET("/sep/:nosep", sepHandler.GetSepSep)
|
||||
sepGroup.POST("/sep", sepHandler.CreateSepSep)
|
||||
sepGroup.PUT("/sep/:nosep", sepHandler.UpdateSepSep)
|
||||
sepGroup.DELETE("/sep/:nosep", sepHandler.DeleteSepSep)
|
||||
|
||||
// // Retribusi endpoints
|
||||
// retribusiHandler := retribusiHandlers.NewRetribusiHandler()
|
||||
// retribusiGroup := v1.Group("/retribusi")
|
||||
@@ -100,5 +124,28 @@ func RegisterRoutes(cfg *config.Config) *gin.Engine {
|
||||
protectedRetribusi.DELETE("/:id", retribusiHandler.DeleteRetribusi) // DELETE /api/v1/retribusi/:id
|
||||
}
|
||||
|
||||
// // BPJS VClaim endpoints (require authentication)
|
||||
// // Peserta routes
|
||||
// pesertaHandler := peserta.NewVClaimHandler(peserta.VClaimHandlerConfig{
|
||||
// BpjsConfig: cfg.Bpjs,
|
||||
// Logger: *logger.Default(),
|
||||
// Validator: nil,
|
||||
// })
|
||||
// protectedPeserta := protected.Group("/peserta")
|
||||
// protectedPeserta.GET("/peserta/:nokartu", pesertaHandler.GetPesertaBynokartu)
|
||||
// protectedPeserta.GET("/peserta/nik/:nik", pesertaHandler.GetPesertaBynik)
|
||||
|
||||
// // Sep routes
|
||||
// sepHandler := sep.NewVClaimHandler(sep.VClaimHandlerConfig{
|
||||
// BpjsConfig: cfg.Bpjs,
|
||||
// Logger: *logger.Default(),
|
||||
// Validator: nil,
|
||||
// })
|
||||
// protectedSep := protected.Group("/sep")
|
||||
// protectedSep.GET("/sep/:nosep", sepHandler.GetSepSep)
|
||||
// protectedSep.POST("/sep", sepHandler.CreateSepSep)
|
||||
// protectedSep.PUT("/sep/:nosep", sepHandler.UpdateSepSep)
|
||||
// protectedSep.DELETE("/sep/:nosep", sepHandler.DeleteSepSep)
|
||||
|
||||
return router
|
||||
}
|
||||
|
||||
@@ -23,7 +23,8 @@ services:
|
||||
response_model: "PesertaResponse"
|
||||
description: "Get participant eligibility information by card number"
|
||||
summary: "Get Participant Info by No Kartu"
|
||||
tags: ["vclaim", "peserta", "nokartu"]
|
||||
tags: ["Peserta"]
|
||||
require_auth: true
|
||||
cache_enabled: true
|
||||
cache_ttl: 300
|
||||
bynik:
|
||||
@@ -33,7 +34,8 @@ services:
|
||||
response_model: "PesertaResponse"
|
||||
description: "Get participant eligibility information by NIK"
|
||||
summary: "Get Participant Info by NIK"
|
||||
tags: ["vclaim", "peserta", "nik"]
|
||||
tags: ["Peserta"]
|
||||
require_auth: true
|
||||
cache_enabled: true
|
||||
cache_ttl: 300
|
||||
sep:
|
||||
@@ -47,6 +49,7 @@ services:
|
||||
response_model: "SepResponse"
|
||||
description: "Manage SEP (Surat Eligibilitas Peserta)"
|
||||
summary: "SEP Management"
|
||||
tags: ["vclaim", "sep"]
|
||||
tags: ["Sep"]
|
||||
require_auth: true
|
||||
cache_enabled: true
|
||||
cache_ttl: 180
|
||||
|
||||
@@ -138,7 +138,7 @@ const handlerTemplate = `
|
||||
// Service: {{.ServiceName}} ({{.Category}})
|
||||
// Description: {{.Description}}
|
||||
|
||||
package handlers
|
||||
package {{.Package}}
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -148,8 +148,7 @@ import (
|
||||
|
||||
"{{.ModuleName}}/internal/config"
|
||||
"{{.ModuleName}}/internal/models"
|
||||
"{{.ModuleName}}/internal/models/vclaim/peserta"
|
||||
"{{.ModuleName}}/internal/models/vclaim/sep"
|
||||
"{{.ModuleName}}/internal/models/vclaim/{{.Package}}"
|
||||
"{{.ModuleName}}/internal/services/bpjs"
|
||||
"{{.ModuleName}}/pkg/logger"
|
||||
|
||||
@@ -184,19 +183,15 @@ func New{{.ServiceName}}Handler(cfg {{.ServiceName}}HandlerConfig) *{{.ServiceNa
|
||||
}
|
||||
{{range .Endpoints}}
|
||||
{{if .HasGet}}
|
||||
// Get{{.NameUpper}} godoc
|
||||
// Get{{.Name}} godoc
|
||||
// @Summary Get {{.Name}} data
|
||||
// @Description {{.Description}}
|
||||
// @Tags {{join .Tags ","}}
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
{{if .RequireAuth}}
|
||||
// @Security ApiKeyAuth
|
||||
{{end}}
|
||||
// @Param X-Request-ID header string false "Request ID for tracking"
|
||||
{{range .PathParams}}
|
||||
// @Param {{.}} path string true "{{.}}" example("example_value")
|
||||
{{end}}
|
||||
// @Produce json {{if .RequireAuth}}
|
||||
// @Security ApiKeyAuth {{end}}
|
||||
// @Param X-Request-ID header string false "Request ID for tracking" {{range .PathParams}}
|
||||
// @Param {{.}} path string true "{{.}}" example("example_value") {{end}}
|
||||
// @Success 200 {object} {{.ModelPackage}}.{{.ResponseModel}} "Successfully retrieved {{.Name}} data"
|
||||
// @Failure 400 {object} models.ErrorResponseBpjs "Bad request - invalid parameters"
|
||||
// @Failure 401 {object} models.ErrorResponseBpjs "Unauthorized - invalid API credentials"
|
||||
@@ -276,15 +271,13 @@ func (h *{{$.ServiceName}}Handler) Get{{.Name}}(c *gin.Context) {
|
||||
{{end}}
|
||||
|
||||
{{if .HasPost}}
|
||||
// Create{{.NameUpper}} godoc
|
||||
// Create{{.Name}} godoc
|
||||
// @Summary Create new {{.Name}}
|
||||
// @Description {{.Description}}
|
||||
// @Tags {{join .Tags ","}}
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
{{if .RequireAuth}}
|
||||
// @Security ApiKeyAuth
|
||||
{{end}}
|
||||
// @Produce json {{if .RequireAuth}}
|
||||
// @Security ApiKeyAuth {{end}}
|
||||
// @Param X-Request-ID header string false "Request ID for tracking"
|
||||
// @Param request body {{.ModelPackage}}.{{.Model}} true "{{.Name}} data"
|
||||
// @Success 201 {object} {{.ModelPackage}}.{{.ResponseModel}} "Successfully created {{.Name}}"
|
||||
@@ -367,19 +360,15 @@ func (h *{{$.ServiceName}}Handler) Create{{.Name}}(c *gin.Context) {
|
||||
{{end}}
|
||||
|
||||
{{if .HasPut}}
|
||||
// Update{{.NameUpper}} godoc
|
||||
// Update{{.Name}} godoc
|
||||
// @Summary Update existing {{.Name}}
|
||||
// @Description {{.Description}}
|
||||
// @Tags {{join .Tags ","}}
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
{{if .RequireAuth}}
|
||||
// @Security ApiKeyAuth
|
||||
{{end}}
|
||||
// @Param X-Request-ID header string false "Request ID for tracking"
|
||||
{{range .PathParams}}
|
||||
// @Param {{.}} path string true "{{.}}" example("example_value")
|
||||
{{end}}
|
||||
// @Produce json {{if .RequireAuth}}
|
||||
// @Security ApiKeyAuth {{end}}
|
||||
// @Param X-Request-ID header string false "Request ID for tracking" {{range .PathParams}}
|
||||
// @Param {{.}} path string true "{{.}}" example("example_value") {{end}}
|
||||
// @Param request body {{.ModelPackage}}.{{.Model}} true "{{.Name}} data"
|
||||
// @Success 200 {object} {{.ModelPackage}}.{{.ResponseModel}} "Successfully updated {{.Name}}"
|
||||
// @Failure 400 {object} models.ErrorResponseBpjs "Bad request - invalid parameters or request body"
|
||||
@@ -486,19 +475,15 @@ func (h *{{$.ServiceName}}Handler) Update{{.Name}}(c *gin.Context) {
|
||||
{{end}}
|
||||
|
||||
{{if .HasDelete}}
|
||||
// Delete{{.NameUpper}} godoc
|
||||
// Delete{{.Name}} godoc
|
||||
// @Summary Delete existing {{.Name}}
|
||||
// @Description {{.Description}}
|
||||
// @Tags {{join .Tags ","}}
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
{{if .RequireAuth}}
|
||||
// @Security ApiKeyAuth
|
||||
{{end}}
|
||||
// @Param X-Request-ID header string false "Request ID for tracking"
|
||||
{{range .PathParams}}
|
||||
// @Param {{.}} path string true "{{.}}" example("example_value")
|
||||
{{end}}
|
||||
// @Produce json {{if .RequireAuth}}
|
||||
// @Security ApiKeyAuth {{end}}
|
||||
// @Param X-Request-ID header string false "Request ID for tracking" {{range .PathParams}}
|
||||
// @Param {{.}} path string true "{{.}}" example("example_value") {{end}}
|
||||
// @Success 200 {object} {{.ModelPackage}}.{{.ResponseModel}} "Successfully deleted {{.Name}}"
|
||||
// @Failure 400 {object} models.ErrorResponseBpjs "Bad request - invalid parameters"
|
||||
// @Failure 401 {object} models.ErrorResponseBpjs "Unauthorized - invalid API credentials"
|
||||
@@ -573,6 +558,46 @@ func (h *{{$.ServiceName}}Handler) Delete{{.Name}}(c *gin.Context) {
|
||||
{{end}}
|
||||
`
|
||||
|
||||
// Template for generating routes
|
||||
const routesTemplate = `
|
||||
package v1
|
||||
|
||||
import (
|
||||
"{{.ModuleName}}/internal/config"
|
||||
"{{.ModuleName}}/internal/middleware"
|
||||
"{{.ModuleName}}/internal/handlers/{{.Category}}/{{.Package}}"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func Register{{.ServiceName}}Routes(router *gin.RouterGroup, cfg *config.Config) {
|
||||
handler := {{.Package}}.New{{.ServiceName}}Handler({{.Package}}.{{.ServiceName}}HandlerConfig{
|
||||
BpjsConfig: cfg.Bpjs,
|
||||
Logger: *logger.Default(),
|
||||
Validator: nil,
|
||||
})
|
||||
|
||||
group := router.Group("/{{.ServiceLower}}")
|
||||
|
||||
{{range .Endpoints}}
|
||||
{{if .HasGet}}
|
||||
group.GET("{{.GetPath}}", handler.Get{{.Name}})
|
||||
{{end}}
|
||||
{{if .HasPost}}
|
||||
group.POST("{{.PostPath}}", handler.Create{{.Name}})
|
||||
{{end}}
|
||||
{{if .HasPut}}
|
||||
group.PUT("{{.PutPath}}", handler.Update{{.Name}})
|
||||
{{end}}
|
||||
{{if .HasDelete}}
|
||||
group.DELETE("{{.DeletePath}}", handler.Delete{{.Name}})
|
||||
{{end}}
|
||||
{{if .HasPatch}}
|
||||
group.PATCH("{{.PatchPath}}", handler.Patch{{.Name}})
|
||||
{{end}}
|
||||
{{end}}
|
||||
}
|
||||
`
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
printUsage()
|
||||
@@ -614,15 +639,24 @@ func main() {
|
||||
errors++
|
||||
continue
|
||||
}
|
||||
fmt.Printf("✅ Generated handler: %s_handler.go\n", strings.ToLower(serviceName))
|
||||
fmt.Printf("✅ Generated handler: %s.go\n", strings.ToLower(serviceName))
|
||||
|
||||
// Generate routes for this service
|
||||
err = generateRoutes(serviceName, service, config.Global)
|
||||
if err != nil {
|
||||
fmt.Printf("❌ Error generating routes for %s: %v\n", serviceName, err)
|
||||
errors++
|
||||
continue
|
||||
}
|
||||
fmt.Printf("✅ Generated routes: %s_routes.go\n", strings.ToLower(serviceName))
|
||||
generated++
|
||||
}
|
||||
|
||||
// Summary
|
||||
fmt.Println("\n📊 Generation Summary:")
|
||||
fmt.Printf(" ✅ Successfully generated: %d handlers\n", generated)
|
||||
fmt.Printf(" ✅ Successfully generated: %d handlers and routes\n", generated)
|
||||
if errors > 0 {
|
||||
fmt.Printf(" ❌ Failed: %d handlers\n", errors)
|
||||
fmt.Printf(" ❌ Failed: %d handlers/routes\n", errors)
|
||||
}
|
||||
|
||||
if generated > 0 {
|
||||
@@ -675,65 +709,6 @@ func loadConfig(filename string) (*ServiceConfig, error) {
|
||||
}
|
||||
|
||||
func generateHandler(serviceName string, service Service, globalConfig GlobalConfig) error {
|
||||
// Prepare template data
|
||||
templateData := TemplateData{
|
||||
ServiceName: service.Name,
|
||||
ServiceLower: strings.ToLower(service.Name),
|
||||
ServiceUpper: strings.ToUpper(service.Name),
|
||||
Category: service.Category,
|
||||
Package: service.Package,
|
||||
Description: service.Description,
|
||||
BaseURL: service.BaseURL,
|
||||
Timeout: getOrDefault(service.Timeout, 30),
|
||||
RetryCount: getOrDefault(service.RetryCount, 3),
|
||||
Timestamp: time.Now().Format("2006-01-02 15:04:05"),
|
||||
ModuleName: globalConfig.ModuleName,
|
||||
HasValidator: true,
|
||||
HasLogger: globalConfig.EnableLogging,
|
||||
HasMetrics: globalConfig.EnableMetrics,
|
||||
HasSwagger: globalConfig.EnableSwagger,
|
||||
Dependencies: service.Dependencies, // Now []string
|
||||
Middleware: service.Middleware, // Now []string
|
||||
GlobalConfig: globalConfig,
|
||||
}
|
||||
|
||||
// Check for advanced features
|
||||
for _, subEndpoints := range service.Endpoints {
|
||||
for _, endpoint := range subEndpoints {
|
||||
if endpoint.RequireAuth {
|
||||
templateData.HasAuth = true
|
||||
}
|
||||
if endpoint.CacheEnabled {
|
||||
templateData.HasCache = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process endpoints
|
||||
for endpointName, subEndpoints := range service.Endpoints {
|
||||
for subEndpointName, endpoint := range subEndpoints {
|
||||
// Compose full endpoint name with sub-endpoint name
|
||||
fullEndpointName := endpointName
|
||||
if subEndpointName != "" {
|
||||
fullEndpointName = fullEndpointName + strings.Title(subEndpointName)
|
||||
}
|
||||
endpointData := processEndpoint(fullEndpointName, endpoint, endpointName)
|
||||
templateData.Endpoints = append(templateData.Endpoints, endpointData)
|
||||
}
|
||||
}
|
||||
|
||||
// Create output directory
|
||||
outputDir := globalConfig.OutputDir
|
||||
if outputDir == "" {
|
||||
outputDir = "internal/handlers"
|
||||
}
|
||||
if err := os.MkdirAll(outputDir, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create output directory: %w", err)
|
||||
}
|
||||
|
||||
// Generate handler file
|
||||
filename := filepath.Join(outputDir, fmt.Sprintf("%s_handler.go", strings.ToLower(serviceName)))
|
||||
|
||||
// Create template with custom functions
|
||||
tmpl := template.New("handler").Funcs(template.FuncMap{
|
||||
"contains": strings.Contains,
|
||||
@@ -747,17 +722,207 @@ func generateHandler(serviceName string, service Service, globalConfig GlobalCon
|
||||
return fmt.Errorf("failed to parse template: %w", err)
|
||||
}
|
||||
|
||||
outputDir := globalConfig.OutputDir
|
||||
if outputDir == "" {
|
||||
outputDir = "internal/handlers"
|
||||
}
|
||||
|
||||
generatedFiles := 0
|
||||
errorsCount := 0
|
||||
|
||||
// Loop over each module group in service.Endpoints
|
||||
for groupName, subEndpoints := range service.Endpoints {
|
||||
// Prepare template data for this group
|
||||
templateData := TemplateData{
|
||||
ServiceName: service.Name,
|
||||
ServiceLower: strings.ToLower(service.Name),
|
||||
ServiceUpper: strings.ToUpper(service.Name),
|
||||
Category: service.Category,
|
||||
Package: groupName, // package name is group name
|
||||
Description: service.Description,
|
||||
BaseURL: service.BaseURL,
|
||||
Timeout: getOrDefault(service.Timeout, 30),
|
||||
RetryCount: getOrDefault(service.RetryCount, 3),
|
||||
Timestamp: time.Now().Format("2006-01-02 15:04:05"),
|
||||
ModuleName: globalConfig.ModuleName,
|
||||
HasValidator: true,
|
||||
HasLogger: globalConfig.EnableLogging,
|
||||
HasMetrics: globalConfig.EnableMetrics,
|
||||
HasSwagger: globalConfig.EnableSwagger,
|
||||
Dependencies: service.Dependencies,
|
||||
Middleware: service.Middleware,
|
||||
GlobalConfig: globalConfig,
|
||||
}
|
||||
|
||||
// Check for advanced features in this group
|
||||
for _, endpoint := range subEndpoints {
|
||||
if endpoint.RequireAuth {
|
||||
templateData.HasAuth = true
|
||||
}
|
||||
if endpoint.CacheEnabled {
|
||||
templateData.HasCache = true
|
||||
}
|
||||
}
|
||||
|
||||
// Process endpoints for this group
|
||||
for subEndpointName, endpoint := range subEndpoints {
|
||||
fullEndpointName := groupName
|
||||
if subEndpointName != "" {
|
||||
fullEndpointName = fullEndpointName + strings.Title(subEndpointName)
|
||||
}
|
||||
endpointData := processEndpoint(fullEndpointName, endpoint, groupName)
|
||||
templateData.Endpoints = append(templateData.Endpoints, endpointData)
|
||||
}
|
||||
|
||||
// Create output directory for this group: outputDir/service.Package/groupName
|
||||
groupOutputDir := filepath.Join(outputDir, service.Package, groupName)
|
||||
if err := os.MkdirAll(groupOutputDir, 0755); err != nil {
|
||||
errorsCount++
|
||||
fmt.Printf("❌ Failed to create directory %s: %v\n", groupOutputDir, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Generate handler file for this group
|
||||
filename := filepath.Join(groupOutputDir, fmt.Sprintf("%s.go", groupName))
|
||||
|
||||
// Check if file already exists, skip generation if so
|
||||
if _, err := os.Stat(filename); err == nil {
|
||||
fmt.Printf("⚠️ Skipping generation for existing file: %s\n", filename)
|
||||
continue
|
||||
}
|
||||
|
||||
file, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create file: %w", err)
|
||||
errorsCount++
|
||||
fmt.Printf("❌ Failed to create file %s: %v\n", filename, err)
|
||||
continue
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
err = tmpl.Execute(file, templateData)
|
||||
file.Close()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute template: %w", err)
|
||||
errorsCount++
|
||||
fmt.Printf("❌ Failed to execute template for %s: %v\n", filename, err)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("✅ Generated handler: %s\n", filename)
|
||||
generatedFiles++
|
||||
}
|
||||
|
||||
if errorsCount > 0 {
|
||||
return fmt.Errorf("generation completed with %d errors", errorsCount)
|
||||
}
|
||||
|
||||
if generatedFiles == 0 {
|
||||
return fmt.Errorf("no handlers generated")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func generateRoutes(serviceName string, service Service, globalConfig GlobalConfig) error {
|
||||
// Read the main routes.go file
|
||||
routesFilePath := "internal/routes/v1/routes.go"
|
||||
routesContent, err := ioutil.ReadFile(routesFilePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read routes file: %w", err)
|
||||
}
|
||||
|
||||
routesContentStr := string(routesContent)
|
||||
|
||||
// Check if routes are already registered
|
||||
if strings.Contains(routesContentStr, fmt.Sprintf("Register%sRoutes", service.Name)) {
|
||||
fmt.Printf("⚠️ Routes for %s already registered in main routes file\n", service.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Prepare template data for all groups
|
||||
var allRoutes []string
|
||||
|
||||
// Loop over each module group in service.Endpoints
|
||||
for groupName, subEndpoints := range service.Endpoints {
|
||||
// Prepare template data for this group
|
||||
templateData := TemplateData{
|
||||
ServiceName: service.Name,
|
||||
ServiceLower: strings.ToLower(service.Name),
|
||||
ServiceUpper: strings.ToUpper(service.Name),
|
||||
Category: service.Category,
|
||||
Package: groupName, // package name is group name
|
||||
Description: service.Description,
|
||||
BaseURL: service.BaseURL,
|
||||
Timeout: getOrDefault(service.Timeout, 30),
|
||||
RetryCount: getOrDefault(service.RetryCount, 3),
|
||||
Timestamp: time.Now().Format("2006-01-02 15:04:05"),
|
||||
ModuleName: globalConfig.ModuleName,
|
||||
HasValidator: true,
|
||||
HasLogger: globalConfig.EnableLogging,
|
||||
HasMetrics: globalConfig.EnableMetrics,
|
||||
HasSwagger: globalConfig.EnableSwagger,
|
||||
Dependencies: service.Dependencies,
|
||||
Middleware: service.Middleware,
|
||||
GlobalConfig: globalConfig,
|
||||
}
|
||||
|
||||
// Process endpoints for this group
|
||||
for subEndpointName, endpoint := range subEndpoints {
|
||||
fullEndpointName := groupName
|
||||
if subEndpointName != "" {
|
||||
fullEndpointName = fullEndpointName + strings.Title(subEndpointName)
|
||||
}
|
||||
endpointData := processEndpoint(fullEndpointName, endpoint, groupName)
|
||||
templateData.Endpoints = append(templateData.Endpoints, endpointData)
|
||||
}
|
||||
|
||||
// Generate routes code for this group
|
||||
var routesCode strings.Builder
|
||||
|
||||
routesCode.WriteString(fmt.Sprintf("\n\t// %s routes\n", strings.Title(groupName)))
|
||||
routesCode.WriteString(fmt.Sprintf("\t%sHandler := %s.New%sHandler(%s.%sHandlerConfig{\n", groupName, groupName, service.Name, groupName, service.Name))
|
||||
routesCode.WriteString("\t\tBpjsConfig: cfg.Bpjs,\n")
|
||||
routesCode.WriteString("\t\tLogger: *logger.Default(),\n")
|
||||
routesCode.WriteString("\t\tValidator: nil,\n")
|
||||
routesCode.WriteString("\t})\n")
|
||||
routesCode.WriteString(fmt.Sprintf("\t%sGroup := v1.Group(\"/%s\")\n", groupName, groupName))
|
||||
|
||||
for _, endpoint := range templateData.Endpoints {
|
||||
if endpoint.HasGet {
|
||||
routesCode.WriteString(fmt.Sprintf("\t%sGroup.GET(\"%s\", %sHandler.Get%s)\n", groupName, endpoint.GetPath, groupName, endpoint.Name))
|
||||
}
|
||||
if endpoint.HasPost {
|
||||
routesCode.WriteString(fmt.Sprintf("\t%sGroup.POST(\"%s\", %sHandler.Create%s)\n", groupName, endpoint.PostPath, groupName, endpoint.Name))
|
||||
}
|
||||
if endpoint.HasPut {
|
||||
routesCode.WriteString(fmt.Sprintf("\t%sGroup.PUT(\"%s\", %sHandler.Update%s)\n", groupName, endpoint.PutPath, groupName, endpoint.Name))
|
||||
}
|
||||
if endpoint.HasDelete {
|
||||
routesCode.WriteString(fmt.Sprintf("\t%sGroup.DELETE(\"%s\", %sHandler.Delete%s)\n", groupName, endpoint.DeletePath, groupName, endpoint.Name))
|
||||
}
|
||||
if endpoint.HasPatch {
|
||||
routesCode.WriteString(fmt.Sprintf("\t%sGroup.PATCH(\"%s\", %sHandler.Patch%s)\n", groupName, endpoint.PatchPath, groupName, endpoint.Name))
|
||||
}
|
||||
}
|
||||
|
||||
allRoutes = append(allRoutes, routesCode.String())
|
||||
}
|
||||
|
||||
// Find the PUBLISHED ROUTES section and insert the routes
|
||||
publishedRoutesMarker := "// ============= PUBLISHED ROUTES ==============================================="
|
||||
if !strings.Contains(routesContentStr, publishedRoutesMarker) {
|
||||
return fmt.Errorf("PUBLISHED ROUTES marker not found in routes.go")
|
||||
}
|
||||
|
||||
// Insert the routes after the marker
|
||||
insertionPoint := strings.Index(routesContentStr, publishedRoutesMarker) + len(publishedRoutesMarker)
|
||||
newRoutesContent := routesContentStr[:insertionPoint] + "\n" + strings.Join(allRoutes, "\n") + "\n" + routesContentStr[insertionPoint:]
|
||||
|
||||
// Write back the modified routes file
|
||||
err = ioutil.WriteFile(routesFilePath, []byte(newRoutesContent), 0644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write updated routes file: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("✅ Updated main routes file with %s routes\n", service.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
1029
tools/bpjs/generete
1029
tools/bpjs/generete
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,644 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// BpjsHandlerData contains template data for BPJS handler generation
|
||||
type BpjsHandlerData struct {
|
||||
Name string
|
||||
NameLower string
|
||||
NameUpper string
|
||||
Category string
|
||||
CategoryPath string
|
||||
ModuleName string
|
||||
HasGet bool
|
||||
HasPost bool
|
||||
HasPut bool
|
||||
HasDelete bool
|
||||
GetEndpoint string
|
||||
PostEndpoint string
|
||||
PutEndpoint string
|
||||
DeleteEndpoint string
|
||||
Timestamp string
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
fmt.Println("Usage: go run generate-bpjs-handler.go [category/]entity [methods]")
|
||||
fmt.Println("Examples:")
|
||||
fmt.Println(" go run generate-bpjs-handler.go vclaim/peserta get post put delete")
|
||||
fmt.Println(" go run generate-bpjs-handler.go eclaim/sep get post")
|
||||
fmt.Println(" go run generate-bpjs-handler.go peserta get")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Parse entity path (could be "entity" or "category/entity")
|
||||
entityPath := os.Args[1]
|
||||
methods := []string{}
|
||||
if len(os.Args) > 2 {
|
||||
methods = os.Args[2:]
|
||||
} else {
|
||||
// Default methods if none specified
|
||||
methods = []string{"get", "post", "put", "delete"}
|
||||
}
|
||||
|
||||
// Parse category and entity
|
||||
var category, entityName string
|
||||
if strings.Contains(entityPath, "/") {
|
||||
parts := strings.Split(entityPath, "/")
|
||||
if len(parts) != 2 {
|
||||
fmt.Println("❌ Error: Invalid path format. Use 'category/entity' or just 'entity'")
|
||||
os.Exit(1)
|
||||
}
|
||||
category = parts[0]
|
||||
entityName = parts[1]
|
||||
} else {
|
||||
category = ""
|
||||
entityName = entityPath
|
||||
}
|
||||
|
||||
// Format names
|
||||
entityName = strings.Title(entityName) // PascalCase entity name
|
||||
entityLower := strings.ToLower(entityName)
|
||||
entityUpper := strings.ToUpper(entityName)
|
||||
|
||||
data := BpjsHandlerData{
|
||||
Name: entityName,
|
||||
NameLower: entityLower,
|
||||
NameUpper: entityUpper,
|
||||
Category: category,
|
||||
CategoryPath: category,
|
||||
ModuleName: "api-service",
|
||||
Timestamp: time.Now().Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
|
||||
// Set methods and endpoints based on arguments
|
||||
for _, m := range methods {
|
||||
switch strings.ToLower(m) {
|
||||
case "get":
|
||||
data.HasGet = true
|
||||
data.GetEndpoint = fmt.Sprintf("/%s/{id}", entityUpper)
|
||||
case "post":
|
||||
data.HasPost = true
|
||||
data.PostEndpoint = fmt.Sprintf("/%s/2.0/insert", entityUpper)
|
||||
case "put":
|
||||
data.HasPut = true
|
||||
data.PutEndpoint = fmt.Sprintf("/%s/2.0/update", entityUpper)
|
||||
case "delete":
|
||||
data.HasDelete = true
|
||||
data.DeleteEndpoint = fmt.Sprintf("/%s/2.0/delete", entityUpper)
|
||||
}
|
||||
}
|
||||
|
||||
// Create directories with dynamic logic (sama seperti generate-handler.go)
|
||||
var handlerDir, modelDir string
|
||||
if category != "" {
|
||||
// Dengan kategori: internal/handlers/category/
|
||||
handlerDir = filepath.Join("internal", "handlers", category)
|
||||
modelDir = filepath.Join("internal", "models", category)
|
||||
} else {
|
||||
// Tanpa kategori: langsung internal/handlers/
|
||||
handlerDir = filepath.Join("internal", "handlers")
|
||||
modelDir = filepath.Join("internal", "models")
|
||||
}
|
||||
|
||||
// Create directories
|
||||
for _, d := range []string{handlerDir, modelDir} {
|
||||
if err := os.MkdirAll(d, 0755); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Generate files
|
||||
generateBpjsHandlerFile(data, handlerDir)
|
||||
generateBpjsModelFile(data, modelDir)
|
||||
updateBpjsRoutesFile(data)
|
||||
|
||||
fmt.Printf("✅ Successfully generated BPJS handler: %s\n", entityName)
|
||||
if category != "" {
|
||||
fmt.Printf("📁 Category: %s\n", category)
|
||||
}
|
||||
fmt.Printf("📁 Handler: %s\n", filepath.Join(handlerDir, entityLower+".go"))
|
||||
fmt.Printf("📁 Model: %s\n", filepath.Join(modelDir, entityLower+".go"))
|
||||
}
|
||||
|
||||
// ================= HANDLER GENERATION =====================
|
||||
|
||||
func generateBpjsHandlerFile(data BpjsHandlerData, handlerDir string) {
|
||||
// Build import path based on category (sama seperti generate-handler.go)
|
||||
var modelsImportPath string
|
||||
if data.Category != "" {
|
||||
modelsImportPath = data.ModuleName + "/internal/models/" + data.Category
|
||||
} else {
|
||||
modelsImportPath = data.ModuleName + "/internal/models"
|
||||
}
|
||||
|
||||
handlerContent := `package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"` + data.ModuleName + `/internal/config"
|
||||
models "` + modelsImportPath + `"
|
||||
services "` + data.ModuleName + `/internal/services/bpjs"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// ` + data.Name + `Handler handles ` + data.NameLower + ` BPJS services
|
||||
type ` + data.Name + `Handler struct {
|
||||
service services.VClaimService
|
||||
}
|
||||
|
||||
// New` + data.Name + `Handler creates a new ` + data.Name + `Handler
|
||||
func New` + data.Name + `Handler(cfg config.BpjsConfig) *` + data.Name + `Handler {
|
||||
return &` + data.Name + `Handler{
|
||||
service: services.NewService(cfg),
|
||||
}
|
||||
}`
|
||||
|
||||
// Add methods based on flags
|
||||
if data.HasPost {
|
||||
handlerContent += generateBpjsCreateMethod(data)
|
||||
}
|
||||
|
||||
if data.HasPut {
|
||||
handlerContent += generateBpjsUpdateMethod(data)
|
||||
}
|
||||
|
||||
if data.HasDelete {
|
||||
handlerContent += generateBpjsDeleteMethod(data)
|
||||
}
|
||||
|
||||
if data.HasGet {
|
||||
handlerContent += generateBpjsGetMethod(data)
|
||||
}
|
||||
|
||||
writeFileBpjs(filepath.Join(handlerDir, data.NameLower+".go"), handlerContent)
|
||||
}
|
||||
|
||||
func generateBpjsCreateMethod(data BpjsHandlerData) string {
|
||||
// Build route path based on category (dynamic, tidak hardcode bpjs/)
|
||||
var routePath string
|
||||
if data.Category != "" {
|
||||
routePath = data.Category + "/" + data.NameLower
|
||||
} else {
|
||||
routePath = data.NameLower
|
||||
}
|
||||
|
||||
// Tag untuk swagger
|
||||
var tagName string
|
||||
if data.Category != "" {
|
||||
tagName = data.Category + "-" + data.NameLower
|
||||
} else {
|
||||
tagName = data.NameLower
|
||||
}
|
||||
|
||||
return `
|
||||
|
||||
// Create` + data.Name + ` godoc
|
||||
// @Summary Create a new ` + data.NameUpper + `
|
||||
// @Description Create a new ` + data.Name + ` in BPJS system
|
||||
// @Tags ` + tagName + `
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body models.` + data.Name + `PostRequest true "` + data.Name + ` creation request"
|
||||
// @Success 200 {object} models.` + data.Name + `Response "` + data.Name + ` created successfully"
|
||||
// @Failure 400 {object} gin.H "Invalid request"
|
||||
// @Failure 500 {object} gin.H "Internal server error"
|
||||
// @Router /api/v1/` + routePath + ` [post]
|
||||
func (h *` + data.Name + `Handler) Create` + data.Name + `(c *gin.Context) {
|
||||
var req models.` + data.Name + `PostRequest
|
||||
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, "` + data.PostEndpoint + `", req, &result); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "create failed", "message": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, models.` + data.Name + `Response{
|
||||
Message: "` + data.Name + ` berhasil dibuat",
|
||||
Data: result,
|
||||
})
|
||||
}`
|
||||
}
|
||||
|
||||
func generateBpjsUpdateMethod(data BpjsHandlerData) string {
|
||||
var routePath string
|
||||
if data.Category != "" {
|
||||
routePath = data.Category + "/" + data.NameLower
|
||||
} else {
|
||||
routePath = data.NameLower
|
||||
}
|
||||
|
||||
var tagName string
|
||||
if data.Category != "" {
|
||||
tagName = data.Category + "-" + data.NameLower
|
||||
} else {
|
||||
tagName = data.NameLower
|
||||
}
|
||||
|
||||
return `
|
||||
|
||||
// Update` + data.Name + ` godoc
|
||||
// @Summary Update an existing ` + data.NameUpper + `
|
||||
// @Description Update an existing ` + data.Name + ` in BPJS system
|
||||
// @Tags ` + tagName + `
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param request body models.` + data.Name + `PutRequest true "` + data.Name + ` update request"
|
||||
// @Success 200 {object} models.` + data.Name + `Response "` + data.Name + ` updated successfully"
|
||||
// @Failure 400 {object} gin.H "Invalid request"
|
||||
// @Failure 500 {object} gin.H "Internal server error"
|
||||
// @Router /api/v1/` + routePath + ` [put]
|
||||
func (h *` + data.Name + `Handler) Update` + data.Name + `(c *gin.Context) {
|
||||
var req models.` + data.Name + `PutRequest
|
||||
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, "` + data.PutEndpoint + `", req, &result); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "update failed", "message": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, models.` + data.Name + `Response{
|
||||
Message: "` + data.Name + ` berhasil diperbarui",
|
||||
Data: result,
|
||||
})
|
||||
}`
|
||||
}
|
||||
|
||||
func generateBpjsDeleteMethod(data BpjsHandlerData) string {
|
||||
var routePath string
|
||||
if data.Category != "" {
|
||||
routePath = data.Category + "/" + data.NameLower
|
||||
} else {
|
||||
routePath = data.NameLower
|
||||
}
|
||||
|
||||
var tagName string
|
||||
if data.Category != "" {
|
||||
tagName = data.Category + "-" + data.NameLower
|
||||
} else {
|
||||
tagName = data.NameLower
|
||||
}
|
||||
|
||||
return `
|
||||
|
||||
// Delete` + data.Name + ` godoc
|
||||
// @Summary Delete an existing ` + data.NameUpper + `
|
||||
// @Description Delete a ` + data.Name + ` by ID
|
||||
// @Tags ` + tagName + `
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "` + data.Name + ` ID"
|
||||
// @Param user query string true "User"
|
||||
// @Success 200 {object} models.` + data.Name + `Response "` + data.Name + ` deleted successfully"
|
||||
// @Failure 400 {object} gin.H "Invalid request"
|
||||
// @Failure 500 {object} gin.H "Internal server error"
|
||||
// @Router /api/v1/` + routePath + `/{id} [delete]
|
||||
func (h *` + data.Name + `Handler) Delete` + data.Name + `(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
user := c.Query("user")
|
||||
if id == "" || user == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "id & user required"})
|
||||
return
|
||||
}
|
||||
|
||||
body := models.` + data.Name + `DeleteRequest{}
|
||||
body.T` + data.Name + `.ID = id
|
||||
body.T` + data.Name + `.User = user
|
||||
|
||||
ctx, cancel := context.WithTimeout(c, 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := h.service.Delete(ctx, "` + data.DeleteEndpoint + `", body); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "delete failed", "message": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, models.` + data.Name + `Response{
|
||||
Message: "` + data.Name + ` berhasil dihapus",
|
||||
Data: nil,
|
||||
})
|
||||
}`
|
||||
}
|
||||
|
||||
func generateBpjsGetMethod(data BpjsHandlerData) string {
|
||||
var routePath string
|
||||
if data.Category != "" {
|
||||
routePath = data.Category + "/" + data.NameLower
|
||||
} else {
|
||||
routePath = data.NameLower
|
||||
}
|
||||
|
||||
var tagName string
|
||||
if data.Category != "" {
|
||||
tagName = data.Category + "-" + data.NameLower
|
||||
} else {
|
||||
tagName = data.NameLower
|
||||
}
|
||||
|
||||
return `
|
||||
|
||||
// Get` + data.Name + ` godoc
|
||||
// @Summary Get an existing ` + data.NameUpper + `
|
||||
// @Description Retrieve a ` + data.Name + ` by ID
|
||||
// @Tags ` + tagName + `
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param id path string true "` + data.Name + ` ID"
|
||||
// @Success 200 {object} models.` + data.Name + `Response "Data ` + data.Name + ` retrieved successfully"
|
||||
// @Failure 400 {object} gin.H "Invalid request"
|
||||
// @Failure 500 {object} gin.H "Internal server error"
|
||||
// @Router /api/v1/` + routePath + `/{id} [get]
|
||||
func (h *` + data.Name + `Handler) Get` + data.Name + `(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
if id == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "id required"})
|
||||
return
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(c, 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
endpoint := fmt.Sprintf("` + strings.Replace(data.GetEndpoint, "{id}", "%s", 1) + `", id)
|
||||
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, models.` + data.Name + `Response{
|
||||
Message: "Data ` + data.Name + ` berhasil diambil",
|
||||
Data: result,
|
||||
})
|
||||
}`
|
||||
}
|
||||
|
||||
// ================= MODEL GENERATION =====================
|
||||
|
||||
func generateBpjsModelFile(data BpjsHandlerData, modelDir string) {
|
||||
modelContent := `package models
|
||||
|
||||
// ` + data.Name + ` BPJS Models
|
||||
// Generated at: ` + data.Timestamp + `
|
||||
// Category: ` + data.Category + `
|
||||
|
||||
// Common Response Structure
|
||||
type ` + data.Name + `Response struct {
|
||||
Message string ` + "`json:\"message\"`" + `
|
||||
Data map[string]interface{} ` + "`json:\"data,omitempty\"`" + `
|
||||
}
|
||||
|
||||
type ` + data.Name + `RawResponse struct {
|
||||
MetaData struct {
|
||||
Code string ` + "`json:\"code\"`" + `
|
||||
Message string ` + "`json:\"message\"`" + `
|
||||
} ` + "`json:\"metaData\"`" + `
|
||||
Response interface{} ` + "`json:\"response\"`" + `
|
||||
}`
|
||||
|
||||
if data.HasPost {
|
||||
modelContent += `
|
||||
|
||||
// ` + data.Name + ` POST Request Structure
|
||||
type ` + data.Name + `PostRequest struct {
|
||||
T` + data.Name + ` ` + data.Name + `Post ` + "`json:\"t_" + data.NameLower + "\" binding:\"required\"`" + `
|
||||
}
|
||||
|
||||
type ` + data.Name + `Post struct {
|
||||
// Add your specific fields here based on BPJS API requirements
|
||||
NoKartu string ` + "`json:\"noKartu\" binding:\"required\"`" + `
|
||||
TglLayanan string ` + "`json:\"tglLayanan\" binding:\"required\"`" + `
|
||||
JnsPelayanan string ` + "`json:\"jnsPelayanan\" binding:\"required\"`" + `
|
||||
User string ` + "`json:\"user\" binding:\"required\"`" + `
|
||||
}`
|
||||
}
|
||||
|
||||
if data.HasPut {
|
||||
modelContent += `
|
||||
|
||||
// ` + data.Name + ` PUT Request Structure
|
||||
type ` + data.Name + `PutRequest struct {
|
||||
T` + data.Name + ` ` + data.Name + `Put ` + "`json:\"t_" + data.NameLower + "\" binding:\"required\"`" + `
|
||||
}
|
||||
|
||||
type ` + data.Name + `Put struct {
|
||||
ID string ` + "`json:\"id\" binding:\"required\"`" + `
|
||||
NoKartu string ` + "`json:\"noKartu\"`" + `
|
||||
TglLayanan string ` + "`json:\"tglLayanan\"`" + `
|
||||
JnsPelayanan string ` + "`json:\"jnsPelayanan\"`" + `
|
||||
User string ` + "`json:\"user\" binding:\"required\"`" + `
|
||||
}`
|
||||
}
|
||||
|
||||
if data.HasDelete {
|
||||
modelContent += `
|
||||
|
||||
// ` + data.Name + ` DELETE Request Structure
|
||||
type ` + data.Name + `DeleteRequest struct {
|
||||
T` + data.Name + ` struct {
|
||||
ID string ` + "`json:\"id\" binding:\"required\"`" + `
|
||||
User string ` + "`json:\"user\" binding:\"required\"`" + `
|
||||
} ` + "`json:\"t_" + data.NameLower + "\" binding:\"required\"`" + `
|
||||
}`
|
||||
}
|
||||
|
||||
// Add helper structures
|
||||
modelContent += `
|
||||
|
||||
// Common Helper Structures
|
||||
type Flag struct {
|
||||
Flag string ` + "`json:\"flag\" binding:\"required\"`" + `
|
||||
}
|
||||
|
||||
type Poli struct {
|
||||
Tujuan string ` + "`json:\"tujuan\"`" + `
|
||||
Eksekutif string ` + "`json:\"eksekutif\" binding:\"required\"`" + `
|
||||
}
|
||||
|
||||
// Validation helpers
|
||||
func IsValidStatus(status string) bool {
|
||||
validStatuses := []string{"active", "inactive", "pending", "processed"}
|
||||
for _, v := range validStatuses {
|
||||
if v == status {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}`
|
||||
|
||||
writeFileBpjs(filepath.Join(modelDir, data.NameLower+".go"), modelContent)
|
||||
}
|
||||
|
||||
// ================= ROUTES GENERATION =====================
|
||||
|
||||
func updateBpjsRoutesFile(data BpjsHandlerData) {
|
||||
routesFile := "internal/routes/v1/routes.go"
|
||||
content, err := os.ReadFile(routesFile)
|
||||
if err != nil {
|
||||
fmt.Printf("⚠️ Could not read routes.go: %v\n", err)
|
||||
fmt.Printf("📝 Please manually add these routes to your routes.go file:\n")
|
||||
printBpjsRoutesSample(data)
|
||||
return
|
||||
}
|
||||
|
||||
routesContent := string(content)
|
||||
|
||||
// Build import path berdasarkan category (sama seperti generate-handler.go)
|
||||
var importPath, importAlias string
|
||||
if data.Category != "" {
|
||||
importPath = fmt.Sprintf("%s/internal/handlers/%s", data.ModuleName, data.Category)
|
||||
importAlias = data.NameLower + "Handlers"
|
||||
} else {
|
||||
importPath = fmt.Sprintf("%s/internal/handlers", data.ModuleName)
|
||||
importAlias = data.NameLower + "Handlers"
|
||||
}
|
||||
|
||||
// Check and add import
|
||||
importPattern := fmt.Sprintf("%s \"%s\"", importAlias, importPath)
|
||||
if !strings.Contains(routesContent, importPattern) {
|
||||
importToAdd := fmt.Sprintf("\t%s \"%s\"", importAlias, importPath)
|
||||
if strings.Contains(routesContent, "import (") {
|
||||
routesContent = strings.Replace(routesContent, "import (",
|
||||
"import (\n"+importToAdd, 1)
|
||||
}
|
||||
}
|
||||
|
||||
// Build routes
|
||||
newRoutes := fmt.Sprintf("\t\t// %s endpoints\n", data.Name)
|
||||
if data.Category != "" {
|
||||
newRoutes = fmt.Sprintf("\t\t// %s %s endpoints\n", data.Category, data.Name)
|
||||
}
|
||||
newRoutes += fmt.Sprintf("\t\t%sHandler := %s.New%sHandler(config.LoadConfig().Bpjs)\n",
|
||||
data.NameLower, importAlias, data.Name)
|
||||
|
||||
// Build route paths berdasarkan category (dynamic, tidak hardcode)
|
||||
var routePath string
|
||||
if data.Category != "" {
|
||||
routePath = data.Category + "/" + data.NameLower
|
||||
} else {
|
||||
routePath = data.NameLower
|
||||
}
|
||||
|
||||
if data.HasGet {
|
||||
newRoutes += fmt.Sprintf("\t\tv1.GET(\"/%s/:id\", %sHandler.Get%s)\n",
|
||||
routePath, data.NameLower, data.Name)
|
||||
}
|
||||
|
||||
if data.HasPost {
|
||||
newRoutes += fmt.Sprintf("\t\tv1.POST(\"/%s\", %sHandler.Create%s)\n",
|
||||
routePath, data.NameLower, data.Name)
|
||||
}
|
||||
|
||||
if data.HasPut {
|
||||
newRoutes += fmt.Sprintf("\t\tv1.PUT(\"/%s\", %sHandler.Update%s)\n",
|
||||
routePath, data.NameLower, data.Name)
|
||||
}
|
||||
|
||||
if data.HasDelete {
|
||||
newRoutes += fmt.Sprintf("\t\tv1.DELETE(\"/%s/:id\", %sHandler.Delete%s)\n",
|
||||
routePath, data.NameLower, data.Name)
|
||||
}
|
||||
|
||||
newRoutes += "\n"
|
||||
|
||||
// Insert routes
|
||||
insertMarker := "\t\tprotected := v1.Group(\"/\")"
|
||||
if strings.Contains(routesContent, insertMarker) {
|
||||
if !strings.Contains(routesContent, fmt.Sprintf("New%sHandler", data.Name)) {
|
||||
routesContent = strings.Replace(routesContent, insertMarker,
|
||||
newRoutes+insertMarker, 1)
|
||||
} else {
|
||||
fmt.Printf("✅ Routes for %s already exist, skipping...\n", data.Name)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err := os.WriteFile(routesFile, []byte(routesContent), 0644); err != nil {
|
||||
fmt.Printf("Error writing routes.go: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
if data.Category != "" {
|
||||
fmt.Printf("✅ Updated routes.go with %s %s endpoints\n", data.Category, data.Name)
|
||||
} else {
|
||||
fmt.Printf("✅ Updated routes.go with %s endpoints\n", data.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func printBpjsRoutesSample(data BpjsHandlerData) {
|
||||
var importAlias string
|
||||
if data.Category != "" {
|
||||
importAlias = data.NameLower + "Handlers"
|
||||
} else {
|
||||
importAlias = data.NameLower + "Handlers"
|
||||
}
|
||||
|
||||
var routePath string
|
||||
if data.Category != "" {
|
||||
routePath = data.Category + "/" + data.NameLower
|
||||
} else {
|
||||
routePath = data.NameLower
|
||||
}
|
||||
|
||||
if data.Category != "" {
|
||||
fmt.Printf(`
|
||||
// %s %s endpoints
|
||||
%sHandler := %s.New%sHandler(config.LoadConfig().Bpjs)
|
||||
`, data.Category, data.Name, data.NameLower, importAlias, data.Name)
|
||||
} else {
|
||||
fmt.Printf(`
|
||||
// %s endpoints
|
||||
%sHandler := %s.New%sHandler(config.LoadConfig().Bpjs)
|
||||
`, data.Name, data.NameLower, importAlias, data.Name)
|
||||
}
|
||||
|
||||
if data.HasGet {
|
||||
fmt.Printf("\tv1.GET(\"/%s/:id\", %sHandler.Get%s)\n", routePath, data.NameLower, data.Name)
|
||||
}
|
||||
if data.HasPost {
|
||||
fmt.Printf("\tv1.POST(\"/%s\", %sHandler.Create%s)\n", routePath, data.NameLower, data.Name)
|
||||
}
|
||||
if data.HasPut {
|
||||
fmt.Printf("\tv1.PUT(\"/%s\", %sHandler.Update%s)\n", routePath, data.NameLower, data.Name)
|
||||
}
|
||||
if data.HasDelete {
|
||||
fmt.Printf("\tv1.DELETE(\"/%s/:id\", %sHandler.Delete%s)\n", routePath, data.NameLower, data.Name)
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
// ================= UTILITY FUNCTIONS =====================
|
||||
|
||||
func writeFileBpjs(filename, content string) {
|
||||
if err := os.WriteFile(filename, []byte(content), 0644); err != nil {
|
||||
fmt.Printf("❌ Error creating file %s: %v\n", filename, err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("✅ Generated: %s\n", filename)
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,414 +0,0 @@
|
||||
// Code generated by generate-dynamic-handler.go; DO NOT EDIT.
|
||||
// Generated at: 2025-08-29 13:02:57
|
||||
// Service: VClaim (vclaim)
|
||||
// Description: BPJS VClaim service for eligibility and SEP management
|
||||
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"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
|
||||
// @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.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
|
||||
}
|
||||
|
||||
// Assign result to response
|
||||
response.Status = "success"
|
||||
response.RequestID = requestID
|
||||
response.Data = result
|
||||
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
|
||||
// @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) GetSEPHandler(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.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
|
||||
}
|
||||
|
||||
// Assign result to response
|
||||
response.Status = "success"
|
||||
response.RequestID = requestID
|
||||
response.Data = result
|
||||
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
|
||||
// @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) CreateSEPHandler(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.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
|
||||
}
|
||||
|
||||
// Assign result to response
|
||||
response.Status = "success"
|
||||
response.RequestID = requestID
|
||||
response.Data = result
|
||||
c.JSON(http.StatusCreated, response)
|
||||
}
|
||||
|
||||
// Handler for Helpers
|
||||
|
||||
// GetPeserta implements reference.VClaimService.GetPeserta
|
||||
func (h *VClaimHandler) GetPeserta(ctx context.Context, noKartu string) (*reference.PesertaData, error) {
|
||||
var response struct {
|
||||
MetaData struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
} `json:"metaData"`
|
||||
Response reference.PesertaData `json:"response"`
|
||||
}
|
||||
|
||||
endpoint := fmt.Sprintf("/Peserta/%s", noKartu)
|
||||
err := h.service.Get(ctx, endpoint, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if response.MetaData.Code != "200" {
|
||||
return nil, fmt.Errorf("BPJS API error: %s - %s", response.MetaData.Code, response.MetaData.Message)
|
||||
}
|
||||
|
||||
return &response.Response, nil
|
||||
}
|
||||
|
||||
// GetSEP implements reference.VClaimService.GetSEP
|
||||
func (h *VClaimHandler) GetSEP(ctx context.Context, noSep string) (*reference.SEPData, error) {
|
||||
var response struct {
|
||||
MetaData struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
} `json:"metaData"`
|
||||
Response reference.SEPData `json:"response"`
|
||||
}
|
||||
|
||||
endpoint := fmt.Sprintf("/SEP/%s", noSep)
|
||||
err := h.service.Get(ctx, endpoint, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if response.MetaData.Code != "200" {
|
||||
return nil, fmt.Errorf("BPJS API error: %s - %s", response.MetaData.Code, response.MetaData.Message)
|
||||
}
|
||||
|
||||
return &response.Response, nil
|
||||
}
|
||||
|
||||
// CreateSEP implements reference.VClaimService.CreateSEP
|
||||
func (h *VClaimHandler) CreateSEP(ctx context.Context, req *reference.SEPRequest) (*reference.SEPData, error) {
|
||||
var response struct {
|
||||
MetaData struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
} `json:"metaData"`
|
||||
Response reference.SEPData `json:"response"`
|
||||
}
|
||||
|
||||
endpoint := "/SEP/2.0/insert"
|
||||
err := h.service.Post(ctx, endpoint, req, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if response.MetaData.Code != "200" {
|
||||
return nil, fmt.Errorf("BPJS API error: %s - %s", response.MetaData.Code, response.MetaData.Message)
|
||||
}
|
||||
|
||||
return &response.Response, nil
|
||||
}
|
||||
|
||||
// UpdateSEP implements reference.VClaimService.UpdateSEP
|
||||
func (h *VClaimHandler) UpdateSEP(ctx context.Context, noSep string, req *reference.SEPRequest) (*reference.SEPData, error) {
|
||||
var response struct {
|
||||
MetaData struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
} `json:"metaData"`
|
||||
Response reference.SEPData `json:"response"`
|
||||
}
|
||||
|
||||
endpoint := fmt.Sprintf("/SEP/%s", noSep)
|
||||
err := h.service.Put(ctx, endpoint, req, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if response.MetaData.Code != "200" {
|
||||
return nil, fmt.Errorf("BPJS API error: %s - %s", response.MetaData.Code, response.MetaData.Message)
|
||||
}
|
||||
|
||||
return &response.Response, nil
|
||||
}
|
||||
|
||||
// DeleteSEP implements reference.VClaimService.DeleteSEP
|
||||
func (h *VClaimHandler) DeleteSEP(ctx context.Context, noSep string) error {
|
||||
var response struct {
|
||||
MetaData struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
} `json:"metaData"`
|
||||
}
|
||||
|
||||
endpoint := fmt.Sprintf("/SEP/%s", noSep)
|
||||
err := h.service.Delete(ctx, endpoint, &response)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if response.MetaData.Code != "200" {
|
||||
return fmt.Errorf("BPJS API error: %s - %s", response.MetaData.Code, response.MetaData.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRujukan implements reference.VClaimService.GetRujukan
|
||||
func (h *VClaimHandler) GetRujukan(ctx context.Context, noRujukan string) (*reference.RujukanData, error) {
|
||||
var response struct {
|
||||
MetaData struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
} `json:"metaData"`
|
||||
Response reference.RujukanData `json:"response"`
|
||||
}
|
||||
|
||||
endpoint := fmt.Sprintf("/Rujukan/%s", noRujukan)
|
||||
err := h.service.Get(ctx, endpoint, &response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if response.MetaData.Code != "200" {
|
||||
return nil, fmt.Errorf("BPJS API error: %s - %s", response.MetaData.Code, response.MetaData.Message)
|
||||
}
|
||||
|
||||
return &response.Response, nil
|
||||
}
|
||||
Reference in New Issue
Block a user