bpjs-bridge 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +262 -12
  2. package/dist/__test__/pcare.service.test.js +14 -11
  3. package/dist/config/enpoints.d.ts +2 -2
  4. package/dist/config/enpoints.js +2 -2
  5. package/dist/core/configHelper.d.ts +3 -0
  6. package/dist/core/configHelper.js +3 -0
  7. package/dist/core/httpClient.js +75 -15
  8. package/dist/index.d.ts +9 -0
  9. package/dist/index.js +10 -0
  10. package/dist/services/antrean/fktpBPJS.service.d.ts +61 -0
  11. package/dist/services/antrean/fktpBPJS.service.js +80 -0
  12. package/dist/services/base.service.d.ts +46 -0
  13. package/dist/services/base.service.js +183 -0
  14. package/dist/services/fktp.service.d.ts +2 -1
  15. package/dist/services/fktp.service.js +5 -4
  16. package/dist/services/i-care/icare.service.d.ts +36 -0
  17. package/dist/services/i-care/icare.service.js +43 -0
  18. package/dist/services/pcare/module/alergi.module.d.ts +15 -0
  19. package/dist/services/pcare/module/alergi.module.js +20 -0
  20. package/dist/services/pcare/module/diagnosa.module.d.ts +8 -0
  21. package/dist/services/pcare/module/diagnosa.module.js +13 -0
  22. package/dist/services/pcare/module/dokter.module.d.ts +12 -0
  23. package/dist/services/pcare/module/dokter.module.js +22 -0
  24. package/dist/services/pcare/module/kesadaran.module.d.ts +14 -0
  25. package/dist/services/pcare/module/kesadaran.module.js +19 -0
  26. package/dist/services/pcare/module/komplok.module.d.ts +82 -0
  27. package/dist/services/pcare/module/komplok.module.js +114 -0
  28. package/dist/services/pcare/module/kunjungan.module.d.ts +58 -0
  29. package/dist/services/pcare/module/kunjungan.module.js +115 -0
  30. package/dist/services/pcare/module/mcu.module.d.ts +40 -0
  31. package/dist/services/pcare/module/mcu.module.js +59 -0
  32. package/dist/services/pcare/module/obat.module.d.ts +39 -0
  33. package/dist/services/pcare/module/obat.module.js +57 -0
  34. package/dist/services/pcare/module/pendafataran.module.d.ts +55 -0
  35. package/dist/services/pcare/module/pendafataran.module.js +77 -0
  36. package/dist/services/pcare/module/peserta.module.d.ts +23 -0
  37. package/dist/services/pcare/module/peserta.module.js +37 -0
  38. package/dist/services/pcare/module/poli.module.d.ts +16 -0
  39. package/dist/services/pcare/module/poli.module.js +24 -0
  40. package/dist/services/pcare/module/prognosa.module.d.ts +14 -0
  41. package/dist/services/pcare/module/prognosa.module.js +19 -0
  42. package/dist/services/pcare/module/provider.module.d.ts +16 -0
  43. package/dist/services/pcare/module/provider.module.js +24 -0
  44. package/dist/services/pcare/module/spesialis.module.d.ts +72 -0
  45. package/dist/services/pcare/module/spesialis.module.js +100 -0
  46. package/dist/services/pcare/module/statusPulang.module.d.ts +15 -0
  47. package/dist/services/pcare/module/statusPulang.module.js +22 -0
  48. package/dist/services/pcare/module/tindakan.module.d.ts +50 -0
  49. package/dist/services/pcare/module/tindakan.module.js +73 -0
  50. package/dist/services/pcare/pcare.service.d.ts +32 -60
  51. package/dist/services/pcare/pcare.service.js +32 -124
  52. package/dist/types/antreanFktp.d.ts +40 -0
  53. package/dist/types/antreanFktp.js +2 -0
  54. package/dist/types/global.d.ts +4 -0
  55. package/dist/types/globalErroModule.d.ts +22 -0
  56. package/dist/types/globalErroModule.js +50 -0
  57. package/dist/types/icare.d.ts +7 -0
  58. package/dist/types/icare.js +2 -0
  59. package/dist/types/kelompok.d.ts +109 -0
  60. package/dist/types/kelompok.js +2 -0
  61. package/dist/types/kunjungan.d.ts +225 -0
  62. package/dist/types/kunjungan.js +2 -0
  63. package/dist/types/pcare.d.ts +130 -0
  64. package/dist/types/pcare.js +1 -0
  65. package/dist/types/pendaftaran.d.ts +108 -0
  66. package/dist/types/pendaftaran.js +2 -0
  67. package/dist/types/peserta.d.ts +45 -0
  68. package/dist/types/peserta.js +2 -0
  69. package/dist/types/spesialis.d.ts +30 -0
  70. package/dist/types/spesialis.js +2 -0
  71. package/package.json +1 -1
package/README.md CHANGED
@@ -1,12 +1,19 @@
1
- # @newustechnology/bpjs-bridging
1
+ <p align="center">
2
+ <img src="https://img.shields.io/badge/Newus%20BPJS%20Bridge-FKTP-blue?style=for-the-badge" />
3
+ </p>
2
4
 
3
- Library resmi untuk bridging BPJS Kesehatan (PCare, VClaim, Antrean, iCare, Rekam Medis)
4
- yang sudah modular, type-safe, dan mudah diintegrasikan.
5
+ <h1 align="center">BPJS Bridge FKTP Service</h1>
6
+
7
+ <p align="center">
8
+ Integrasi BPJS PCare, Antrean FKTP, VClaim, dan iCare dengan dukungan Redis Cache, Logging, dan Modular Service Architecture.
9
+ <br />
10
+ Repository resmi: <a href="https://github.com/NewusTech/bpjs-bridge">NewusTech/bpjs-bridge</a>
11
+ </p>
5
12
 
6
13
  ## Installation
7
14
 
8
15
  ```bash
9
- npm install @newustechnology/bpjs-bridging
16
+ npm i bpjs-bridge
10
17
  ```
11
18
 
12
19
  ## Usage
@@ -20,24 +27,267 @@ secretKey: "...",
20
27
  userKey: "...",
21
28
  username: "...",
22
29
  password: "..."
23
- });
30
+ },redist);
24
31
 
25
- const dokter = await pcare.getDokter(0, 10);
32
+ const dokter = await pcare.dokter.get(0, 10);
26
33
  console.log(dokter);
27
34
  ```
28
35
 
29
36
  ---
30
37
 
31
- Features
38
+ ## 📌 **Fitur Utama**
39
+
40
+ - ⚡ **Redis Caching** untuk mempercepat response BPJS
41
+ - 🔐 Request signing otomatis (X-Signature, Authorization, Timestamp)
42
+ - 🧩 Arsitektur service modular (PcareService, FktpService, AntrolService)
43
+ - 📚 Auto-retry request & error handling kuat
44
+ - 🧵 Prefix Redis per fasilitas kesehatan
45
+ - 🧼 Pattern deletion & flush cache
46
+ - 📦 Endpoints BPJS terstruktur via config JSON
47
+ - 🚀 Support transaksi BPJS GET/POST/PUT/DELETE
48
+
49
+ ---
50
+
51
+ # Dokumentasi Fitur Redis Cache pada `FktpService`
52
+
53
+ Dokumentasi ini menjelaskan cara kerja sistem caching Redis yang diimplementasikan pada class `FktpService`. Tujuannya adalah mempercepat respons API BPJS, mengurangi beban request berulang, serta meningkatkan performa aplikasi.
54
+
55
+ ---
56
+
57
+ ## 🚀 1. Overview Arsitektur
58
+
59
+ Class **`FktpService`** berfungsi sebagai service utama untuk memanggil endpoint BPJS (PCare, Antrean, VClaim, iCare) dengan fitur tambahan berupa:
60
+
61
+ - Redis caching
62
+ - Prefix key dinamis per fasyankes/puskesmas
63
+ - Otomatis menyimpan dan mengambil cache berdasarkan parameter API
64
+ - TTL (kadaluarsa cache) otomatis
65
+ - Penghapusan berdasarkan pola (pattern deletion)
66
+ - Flush semua cache
67
+
68
+ ---
69
+
70
+ ## 🧩 2. Cara Kerja Redis Cache
71
+
72
+ ### **a. Inisialisasi Redis**
73
+
74
+ ```ts
75
+ constructor(config, redisClient, chachePrefix) {
76
+ this.client = createBpjsClient(config);
77
+
78
+ if (redisClient) {
79
+ this.redisClient = redisClient;
80
+
81
+ this.redisClient.on("connect", () => console.info("Redis connected"));
82
+ this.redisClient.on("error", err => console.error("Redis error:", err));
83
+
84
+ if (chachePrefix) {
85
+ this.defaultRedisKeyPrefix =
86
+ this.defaultRedisKeyPrefix + "_" + chachePrefix + ":";
87
+ }
88
+ }
89
+ }
90
+ ```
91
+
92
+ Fitur ini memungkinkan:
93
+
94
+ - Menggunakan Redis secara opsional
95
+ - Menghasilkan prefix unik untuk setiap instansi faskes
96
+ - Mempermudah isolasi cache antar puskesmas
97
+
98
+ ---
99
+
100
+ ## 📦 3. Menyimpan Data ke Redis (`set`)
101
+
102
+ ```ts
103
+ private async set(key, value, expInSecond = 3600)
104
+ ```
105
+
106
+ ### Fungsi ini:
107
+
108
+ - Menerima key dan value
109
+ - Mengubah value menjadi JSON string
110
+ - Menyimpan ke Redis dengan TTL default **3600 detik** (1 jam)
111
+
112
+ Flow:
113
+
114
+ 1. Serialize → JSON.stringify
115
+ 2. Redis SET key with **EXPIRE**
116
+
117
+ ---
118
+
119
+ ## 🔍 4. Mengambil Data dari Redis (`get`)
120
+
121
+ ```ts
122
+ private async get(key)
123
+ ```
124
+
125
+ Fungsi:
126
+
127
+ - Mencari key di Redis
128
+ - Mengembalikan string JSON atau `null` jika tidak ada
129
+ - Logging otomatis jika cache ditemukan
130
+
131
+ Jika data ditemukan:
132
+
133
+ - System **tidak memanggil API BPJS**
134
+ - Mengembalikan data sebagai **fake AxiosResponse**
135
+
136
+ ---
137
+
138
+ ## 🗑️ 5. Menghapus Cache (`del`)
139
+
140
+ ```ts
141
+ private async del(key)
142
+ ```
143
+
144
+ Menghapus satu cache berdasarkan key lengkap.
145
+
146
+ ---
147
+
148
+ ## 🧹 6. Hapus Banyak Key Berdasarkan Pola (`deleteKeysByPattern`)
149
+
150
+ ```ts
151
+ private async deleteKeysByPattern(pattern)
152
+ ```
153
+
154
+ Contoh:
155
+
156
+ - Menghapus semua cache endpoint PCare:
157
+ `deleteKeysByPattern("pcare_*")`
158
+
159
+ Fitur ini sangat berguna ketika:
160
+
161
+ - Fasyankes update mapping
162
+ - Data referensi berubah
163
+ - Harus invalidasi cache massal
164
+
165
+ ---
166
+
167
+ ## 💣 7. Flush Semua Cache
168
+
169
+ ```ts
170
+ private async flushAll()
171
+ ```
172
+
173
+ Membersihkan seluruh isi Redis.
174
+
175
+ ---
176
+
177
+ ## 🔥 8. Mekanisme utama caching di `callEndpoint`
178
+
179
+ ### **Langkah-langkah lengkap:**
180
+
181
+ #### 1️⃣ Generate cacheKey
182
+
183
+ ```ts
184
+ const cacheKey = `${name}:${JSON.stringify(params)}`;
185
+ ```
186
+
187
+ #### 2️⃣ Cek apakah data sudah ada di Redis
32
188
 
33
- 🔐 Auto enkripsi/dekripsi AES BPJS
189
+ ```ts
190
+ const cachedData = await this.get(cacheKey);
191
+ ```
192
+
193
+ Jika ada → langsung return:
194
+
195
+ ```ts
196
+ return {
197
+ data: parsed,
198
+ status: 200,
199
+ statusText: "OK",
200
+ headers: {},
201
+ config: client.defaults,
202
+ };
203
+ ```
204
+
205
+ Tanpa memanggil API BPJS!
206
+
207
+ #### 3️⃣ Jika tidak ada cache → BPJS request dijalankan
208
+
209
+ ```ts
210
+ const res = await this.client({ url: endpoint, method: "GET" });
211
+ ```
212
+
213
+ #### 4️⃣ Data response yang bukan string disimpan ke Redis
34
214
 
35
- 🔄 Auto generate header signature
215
+ ```ts
216
+ await this.set(cacheKey, res.data);
217
+ ```
36
218
 
37
- 📦 Modular service: PCare, VClaim, Antrean, iCare
219
+ ---
38
220
 
39
- 🧪 Fully tested with Jest
221
+ ## 📘 9. Keuntungan Implementasi Cache
40
222
 
41
- Fast, clean, and simple
223
+ | Fitur | Manfaat |
224
+ | -------------------- | ------------------------------------------------- |
225
+ | Redis TTL | Otomatis invalidasi cache usang |
226
+ | Prefix per puskesmas | Cache tidak saling tercampur |
227
+ | Fake AxiosResponse | Kompatibel dengan semua service yang expect Axios |
228
+ | Pattern deletion | Mudah invalidasi cache masal |
229
+ | Response lebih cepat | Hemat request ke BPJS |
42
230
 
43
231
  ---
232
+
233
+ ## 📝 10. Contoh Struktur Key Redis
234
+
235
+ ```
236
+ bpjs_bridge_fktp_puskesmasA:pcare_diagnosa:{"kode":"A00"}
237
+ bpjs_bridge_fktp_puskesmasA:pcare_obat:{"kdObat":"40102"}
238
+ bpjs_bridge_fktp_puskesmasB:vclaim_peserta:{"nokartu":"000123"}
239
+ ```
240
+
241
+ Prefix → per instansi
242
+ Suffix → berdasarkan endpoint + parameter
243
+
244
+ ---
245
+
246
+ ## 🧪 11. Cara Menggunakan dalam Service PCare / Antrean
247
+
248
+ ```ts
249
+ const res = await fktpService.callEndpoint("pcare_diagnosa", { kode: "A00" });
250
+ ```
251
+
252
+ Jika sudah pernah dipanggil → langsung ambil dari Redis.
253
+
254
+ ---
255
+
256
+ ## 📄 12. Catatan Penting
257
+
258
+ - Cache **hanya berjalan untuk request GET**, sesuai pola:
259
+ ```ts
260
+ if (method === "GET") save to Redis
261
+ ```
262
+ - Untuk POST/PUT/DELETE → tidak disimpan agar tidak membuat konflik data.
263
+ - TTL default bisa diganti sesuai kebutuhan.
264
+
265
+ ---
266
+
267
+ #### ✅ Penutup
268
+
269
+ Dokumentasi ini menjelaskan seluruh mekanisme internal caching Redis yang digunakan pada sistem BPJS Bridge.
270
+ Implementasi ini membuat aplikasi lebih cepat, efisien, dan hemat pemanggilan API.
271
+
272
+ ---
273
+
274
+ 🧑‍💻 Kontributor
275
+
276
+ Terima kasih kepada semua kontributor yang telah membantu pengembangan project ini 🙏
277
+
278
+ <br> <!-- Contrib rocks --> <p align="center"> <img src="https://contrib.rocks/image?repo=NewusTech/bpjs-bridge" /> </p>
279
+
280
+ <!-- readme: contributors -start -->
281
+ <!-- readme: contributors -end -->
282
+
283
+ 📄 Lisensi
284
+
285
+ ## MIT License © Newus Teknologi
286
+
287
+ ❤️ Dukungan
288
+
289
+ Jika project ini bermanfaat, jangan lupa:
290
+
291
+ ⭐ Star repository
292
+ 🍴 Fork bila ingin modifikasi
293
+ 🐛 Open issue untuk bug/fitur baru
@@ -4,14 +4,17 @@ const redis_1 = require("../lib/redis");
4
4
  const pcare_service_1 = require("../services/pcare/pcare.service");
5
5
  const config_1 = require("./config");
6
6
  // Setup PcareService
7
- const pcareService = new pcare_service_1.PcareService(config_1.PcareConfig, redis_1.redis);
7
+ const pcareService = new pcare_service_1.PcareService(config_1.PcareConfig, redis_1.redis, "redis_prefix_test");
8
8
  describe("PcareService", () => {
9
+ afterAll(() => {
10
+ redis_1.redis.disconnect();
11
+ });
9
12
  it("should load environment variables", () => {
10
13
  console.log(config_1.PcareConfig);
11
14
  expect(config_1.PcareConfig).toBeDefined();
12
15
  });
13
16
  it("should fetch diagnosa data", async () => {
14
- const response = await pcareService.getDiagnosa("r51", 0, 10);
17
+ const response = await pcareService.diagnosa.get("r51", 0, 10);
15
18
  expect(response).toEqual(expect.objectContaining({
16
19
  count: expect.any(Number), // count harus berupa number
17
20
  list: expect.arrayContaining([
@@ -25,7 +28,7 @@ describe("PcareService", () => {
25
28
  }));
26
29
  });
27
30
  it("should fetch getAlergiJenis 01", async () => {
28
- const response = await pcareService.getAlergiJenis("01");
31
+ const response = await pcareService.alergi.get("01");
29
32
  expect(response).toEqual(expect.objectContaining({
30
33
  list: expect.arrayContaining([
31
34
  // list harus berupa array
@@ -37,7 +40,7 @@ describe("PcareService", () => {
37
40
  }));
38
41
  });
39
42
  it("should fetch getDokter", async () => {
40
- const response = await pcareService.getDokter(0, 1);
43
+ const response = await pcareService.dokter.get(0, 1);
41
44
  expect(response).toEqual(expect.objectContaining({
42
45
  count: expect.any(Number),
43
46
  list: expect.arrayContaining([
@@ -49,7 +52,7 @@ describe("PcareService", () => {
49
52
  }));
50
53
  });
51
54
  it("should fetch getKesadaran", async () => {
52
- const response = await pcareService.getKesadaran();
55
+ const response = await pcareService.kesadaran.get();
53
56
  expect(response).toEqual(expect.objectContaining({
54
57
  count: expect.any(Number),
55
58
  list: expect.arrayContaining([
@@ -61,7 +64,7 @@ describe("PcareService", () => {
61
64
  }));
62
65
  });
63
66
  it("should fetch getDPHO", async () => {
64
- const response = await pcareService.getDPHO("a", 0, 1);
67
+ const response = await pcareService.obat.getDPHO("a", 0, 1);
65
68
  expect(response).toEqual(expect.objectContaining({
66
69
  count: expect.any(Number),
67
70
  list: expect.arrayContaining([
@@ -74,7 +77,7 @@ describe("PcareService", () => {
74
77
  }));
75
78
  });
76
79
  it("should fetch Poli FKTP", async () => {
77
- const response = await pcareService.getPiliFKTP(0, 1);
80
+ const response = await pcareService.poli.get(0, 1);
78
81
  expect(response).toEqual(expect.objectContaining({
79
82
  count: expect.any(Number),
80
83
  list: expect.arrayContaining([
@@ -87,7 +90,7 @@ describe("PcareService", () => {
87
90
  }));
88
91
  });
89
92
  it("should fetch Provider Rayonisasi", async () => {
90
- const response = await pcareService.getProviderRayonisasi(0, 1);
93
+ const response = await pcareService.provider.get(0, 1);
91
94
  expect(response).toEqual(expect.objectContaining({
92
95
  count: expect.any(Number),
93
96
  list: expect.arrayContaining([
@@ -99,7 +102,7 @@ describe("PcareService", () => {
99
102
  }));
100
103
  });
101
104
  it("should fetch Status Pulang", async () => {
102
- const response = await pcareService.getStatusPulang(false);
105
+ const response = await pcareService.statusPulang.get(false);
103
106
  expect(response).toEqual(expect.objectContaining({
104
107
  count: expect.any(Number),
105
108
  list: expect.arrayContaining([
@@ -111,7 +114,7 @@ describe("PcareService", () => {
111
114
  }));
112
115
  });
113
116
  it("should fetch Referensi Tindakan", async () => {
114
- const response = await pcareService.getReferensiTindakan("10", 0, 1);
117
+ const response = await pcareService.tindakan.getReferensi("10", 0, 1);
115
118
  expect(response).toEqual(expect.objectContaining({
116
119
  count: expect.any(Number),
117
120
  list: expect.arrayContaining([
@@ -125,7 +128,7 @@ describe("PcareService", () => {
125
128
  }));
126
129
  });
127
130
  it("should fetch Prognosa", async () => {
128
- const response = await pcareService.getPrognosa();
131
+ const response = await pcareService.prognosa.get();
129
132
  expect(response).toEqual(expect.objectContaining({
130
133
  list: expect.arrayContaining([
131
134
  expect.objectContaining({
@@ -274,13 +274,13 @@ export declare const BaseUrl: {
274
274
  url_pcare: string;
275
275
  url_icare: string;
276
276
  url_vclaim: string;
277
- url_antrol: string;
277
+ url_antrean_fktp: string;
278
278
  };
279
279
  prod: {
280
280
  url_icare: string;
281
281
  url_pcare: string;
282
282
  url_vclaim: string;
283
- url_antrol: string;
283
+ url_antrean_fktp: string;
284
284
  };
285
285
  };
286
286
  export type EndpointName = (typeof enpoints)[number]["name"];
@@ -332,12 +332,12 @@ exports.BaseUrl = {
332
332
  url_pcare: "https://apijkn-dev.bpjs-kesehatan.go.id/pcare-rest-dev",
333
333
  url_icare: "https://apijkn-dev.bpjs-kesehatan.go.id/ihs_dev",
334
334
  url_vclaim: "https://apijkn-dev.bpjs-kesehatan.go.id/vclaim-rest-dev",
335
- url_antrol: "https://apijkn-dev.bpjs-kesehatan.go.id/antreanfktp_dev",
335
+ url_antrean_fktp: "https://apijkn-dev.bpjs-kesehatan.go.id/antreanfktp_dev",
336
336
  },
337
337
  prod: {
338
338
  url_icare: "https://apijkn.bpjs-kesehatan.go.id/ihs",
339
339
  url_pcare: "https://apijkn.bpjs-kesehatan.go.id/pcare-rest",
340
340
  url_vclaim: "https://apijkn.bpjs-kesehatan.go.id/vclaim-rest",
341
- url_antrol: "https://apijkn.bpjs-kesehatan.go.id/antreanfktp",
341
+ url_antrean_fktp: "https://apijkn.bpjs-kesehatan.go.id/antreanfktp",
342
342
  },
343
343
  };
@@ -6,6 +6,9 @@ export type configType = {
6
6
  userKey: string;
7
7
  mode: "dev" | "prod";
8
8
  };
9
+ /**
10
+ * @deprecated
11
+ */
9
12
  export declare function resolveConfig(globalCfg: configType, serviceCfg: configType): {
10
13
  consId: string;
11
14
  secretKey: string;
@@ -2,6 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resolveConfig = resolveConfig;
4
4
  // src/core/configHelper.ts
5
+ /**
6
+ * @deprecated
7
+ */
5
8
  function resolveConfig(globalCfg, serviceCfg) {
6
9
  return {
7
10
  consId: serviceCfg?.consId ?? globalCfg?.consId,
@@ -7,6 +7,7 @@ exports.createBpjsClient = void 0;
7
7
  const axios_1 = __importDefault(require("axios"));
8
8
  const decrypt_1 = require("./decrypt");
9
9
  const security_1 = require("./security");
10
+ const globalErroModule_1 = require("../types/globalErroModule");
10
11
  const createBpjsClient = (config) => {
11
12
  const client = axios_1.default.create({
12
13
  baseURL: config.baseUrl,
@@ -25,27 +26,86 @@ const createBpjsClient = (config) => {
25
26
  return req;
26
27
  });
27
28
  client.interceptors.response.use(async (res) => {
29
+ const url = `${res.config.method?.toUpperCase()} ${res.config.baseURL}/${res.config.url}`;
28
30
  const { response: encryptedData } = res.data;
29
- // Ensure encryptedData is a string before trying to decrypt
30
- if (typeof encryptedData === "string") {
31
- const timestamp = String(headers["X-timestamp"]);
32
- const decrypted = (0, decrypt_1.decryptBpjsResponse)(encryptedData, config.consId, config.secretKey, timestamp);
33
- return { ...res, data: decrypted };
31
+ if (encryptedData) {
32
+ if (typeof encryptedData !== "string") {
33
+ throw new globalErroModule_1.BpjsDecryptionError(`[DECRYPTION ERROR] ${url} Format encrypted data tidak valid, expected string`, { type: typeof encryptedData, data: encryptedData });
34
+ }
35
+ try {
36
+ const timestamp = String(headers["X-timestamp"]);
37
+ if (!timestamp) {
38
+ throw new Error("Timestamp tidak tersedia untuk decryption");
39
+ }
40
+ const decrypted = (0, decrypt_1.decryptBpjsResponse)(encryptedData, config.consId, config.secretKey, timestamp);
41
+ return {
42
+ ...res,
43
+ data: decrypted,
44
+ headers: {
45
+ ...res.headers,
46
+ "x-decrypted": "true",
47
+ },
48
+ };
49
+ }
50
+ catch (decryptError) {
51
+ throw new globalErroModule_1.BpjsDecryptionError(`[DECRYPTION ERROR] ${url} : ${decryptError.message}`, {
52
+ originalError: decryptError,
53
+ encryptedLength: encryptedData.length,
54
+ consId: config.consId,
55
+ });
56
+ }
34
57
  }
35
- res.data = `[HTTP CLIENT ERROR => URL : ${res.config.baseURL}/${res.config.url} ] => ${res.data.metaData?.message || "unknown error"}`;
36
- return res;
58
+ res.data = `[HTTP CLIENT ERROR => URL : ${res.config.baseURL}/${res.config.url} ] => ${"NO_CONTENT_IN_RESPONSE"}`;
59
+ res.status = 204;
60
+ res.statusText = "No Content";
61
+ const AxiosError = {
62
+ name: "BpjsResponseError",
63
+ code: "NO_CONTENT_IN_RESPONSE",
64
+ message: res.data,
65
+ status: res.status,
66
+ config: res.config,
67
+ isAxiosError: true,
68
+ response: {
69
+ data: res.data,
70
+ status: res.status,
71
+ statusText: res.statusText,
72
+ headers: res.headers,
73
+ config: res.config,
74
+ },
75
+ toJSON: () => ({}),
76
+ };
77
+ return Promise.reject(AxiosError);
37
78
  }, (err) => {
38
- console.error("[HTTP CLIENT ERROR]", err.message + " || " + JSON.stringify(err.response?.data) || "");
39
- const fallback = {
40
- data: `[HTTP CLIENT ERROR => URL : ${err.config.baseURL}/${err.config.url} ] => ${err.response?.data?.metaData?.message ??
41
- err.message ??
42
- "unknown error"}`,
43
- status: err.status || 500,
44
- statusText: err.message || "Internal Server Error",
79
+ const url = `${err.config.method?.toUpperCase()} ${err.config.baseURL}/${err.config.url}`;
80
+ const fallBackResponse = {
81
+ data: {
82
+ message: `[HTTP CLIENT ERROR => URL : ${url} ] => ${err.response?.data?.metaData?.message ??
83
+ err.message ??
84
+ "unknown error"}`,
85
+ originalResponse: err.response?.data,
86
+ },
87
+ status: err.response?.data?.metaData?.code || err.status || 500,
88
+ statusText: err.response?.data?.metaData?.message ??
89
+ (err.message || "Internal Server Error"),
45
90
  headers: {},
46
91
  config: err.config || {},
47
92
  };
48
- return fallback;
93
+ const AxiosError = {
94
+ name: "BpjsResponseError",
95
+ message: fallBackResponse.data.message,
96
+ status: fallBackResponse.status,
97
+ config: fallBackResponse.config,
98
+ isAxiosError: true,
99
+ response: {
100
+ data: fallBackResponse.data,
101
+ status: fallBackResponse.status,
102
+ statusText: fallBackResponse.statusText,
103
+ headers: err.headers,
104
+ config: fallBackResponse.config,
105
+ },
106
+ toJSON: () => ({}),
107
+ };
108
+ return Promise.reject(AxiosError);
49
109
  });
50
110
  return client;
51
111
  };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,15 @@
1
1
  export * from "./core/httpClient";
2
2
  export * from "./core/configHelper";
3
3
  export * from "./services/pcare/pcare.service";
4
+ export * from "./services/antrean/fktpBPJS.service";
5
+ export * from "./services/i-care/icare.service";
4
6
  export * from "./lib/redis";
5
7
  export * from "./types/global";
6
8
  export * from "./types/pcare";
9
+ export * from "./types/kunjungan";
10
+ export * from "./types/peserta";
11
+ export * from "./types/kunjungan";
12
+ export * from "./types/pendaftaran";
13
+ export * from "./types/spesialis";
14
+ export * from "./types/antreanFktp";
15
+ export * from "./types/icare";
package/dist/index.js CHANGED
@@ -17,6 +17,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./core/httpClient"), exports);
18
18
  __exportStar(require("./core/configHelper"), exports);
19
19
  __exportStar(require("./services/pcare/pcare.service"), exports);
20
+ __exportStar(require("./services/antrean/fktpBPJS.service"), exports);
21
+ __exportStar(require("./services/i-care/icare.service"), exports);
20
22
  __exportStar(require("./lib/redis"), exports);
23
+ //
21
24
  __exportStar(require("./types/global"), exports);
22
25
  __exportStar(require("./types/pcare"), exports);
26
+ __exportStar(require("./types/kunjungan"), exports);
27
+ __exportStar(require("./types/peserta"), exports);
28
+ __exportStar(require("./types/kunjungan"), exports);
29
+ __exportStar(require("./types/pendaftaran"), exports);
30
+ __exportStar(require("./types/spesialis"), exports);
31
+ __exportStar(require("./types/antreanFktp"), exports);
32
+ __exportStar(require("./types/icare"), exports);
@@ -0,0 +1,61 @@
1
+ import Redis from "ioredis";
2
+ import { configType } from "../../core/configHelper";
3
+ import { DataArray } from "../../types/global";
4
+ import { AntreanFktpBatalPayload, AntreanFktpPayload, AntreanFktpReferensiDokterType, AntreanFktpReferensiPoliType, AntreanFktpStatusPayload } from "../../types/antreanFktp";
5
+ import { BaseService } from "../base.service";
6
+ /**
7
+ * Service untuk mengakses endpoint Antrean BPJS FKTP
8
+ */
9
+ export declare class AntreanFktpService extends BaseService {
10
+ /**
11
+ * Constructor AntreanFktpService
12
+ * @param config konfigurasi BPJS
13
+ * @param redisClient instance Redis (opsional)
14
+ * @param chachePrefix prefix untuk cache Redis (opsional)
15
+ */
16
+ constructor(config: configType, redisClient?: Redis, chachePrefix?: string);
17
+ /**
18
+ *
19
+ * @param tanggal
20
+ * @returns
21
+ * @description
22
+ * Melihat referensi poli pada layanan antrean (WS Antrol)
23
+ */
24
+ getReferensiPoli(tanggal: string): Promise<DataArray<AntreanFktpReferensiPoliType>>;
25
+ /**
26
+ *
27
+ * @param kodepoli
28
+ * @param tanggal
29
+ * @returns
30
+ * @description
31
+ * Melihat daftar dokter berdasarkan poli dan tanggal
32
+ */
33
+ getReferensiDokter(kodepoli: string, tanggal: string): Promise<DataArray<AntreanFktpReferensiDokterType>>;
34
+ /**
35
+ *
36
+ * @param body
37
+ * @returns
38
+ * @description
39
+ * Menambah data antrean pasien
40
+ */
41
+ add(body: AntreanFktpPayload): Promise<null>;
42
+ /**
43
+ *
44
+ * @param body
45
+ * ### notes :
46
+ * - Status 1 = Hadir; Status 2 = Tidak Hadir
47
+ * - Waktu dalam bentuk timestamp milisecond
48
+ * @returns
49
+ * @description
50
+ * Update status antrean hadir/tidak hadir
51
+ */
52
+ updateStatus(body: AntreanFktpStatusPayload): Promise<null>;
53
+ /**
54
+ *
55
+ * @param body
56
+ * @returns
57
+ * @description
58
+ * Membatalkan antrean pasien
59
+ */
60
+ batal(body: AntreanFktpBatalPayload): Promise<null>;
61
+ }