Skip to content

Commit

Permalink
feat: i-Care implementation (#41)
Browse files Browse the repository at this point in the history
* init

* update doc

* define individual icare user key

* add note about icare user key

* explicitly set content-type

* fix i care response type

* clarify test

* fix type

* clarify icare user key doc

* add changeset
  • Loading branch information
mustofa-id authored Aug 25, 2023
1 parent 66f9f9a commit 5e48a47
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/fifty-lemons-vanish.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@ssecd/jkn': minor
---

implement i-care service
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ JKN_CONS_SECRET=
JKN_VCLAIM_USER_KEY=
JKN_ANTREAN_USER_KEY=
JKN_APOTEK_USER_KEY=
JKN_PCARE_USER_KEY=
JKN_PCARE_USER_KEY=
JKN_ICARE_USER_KEY=
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,16 @@ interface Config {
*/
pcareUserKey: string;

/**
* User key i-Care dari BPJS
*
* Umumnya user key i-Care ini nilai sama dengan user key VClaim
* untuk FKRTL dan PCare untuk FKTP
*
* @default process.env.JKN_ICARE_USER_KEY
*/
icareUserKey: string;

/**
* Berupa mode "development" dan "production". Secara default akan
* membaca nilai environment variable NODE_ENV atau "development"
Expand Down Expand Up @@ -196,10 +206,11 @@ interface Config {
- ✅ Antrean
- ✅ Apotek _(experimental)_
- 🧩 PCare _([partial](https://github.com/ssecd/jkn/pull/26))_
- ✅ i-Care

## Kontribusi

Kontribusi sangat dipersilakan dan dapat dilakukan dengan berbagai cara seperti melaporkan masalah, membuat permintaan atau menambahkan fitur melalui PR, atau sekedar memperbaiki kesalahan ketikan.
Kontribusi sangat dipersilakan dan dapat dilakukan dengan berbagai cara seperti melaporkan masalah, membuat permintaan atau menambahkan fitur melalui PR, atau sekedar memperbaiki kesalahan ketikan.

## Lisensi

Expand All @@ -209,5 +220,4 @@ Kontribusi sangat dipersilakan dan dapat dilakukan dengan berbagai cara seperti

- [Consent](https://github.com/ssecd/jkn/issues/6)
- [Pemecahan Masalah](https://github.com/ssecd/jkn/issues?q=is%3Aissue)
- [Laporkan Bug](https://github.com/ssecd/jkn/issues)

- [Laporkan Bug](https://github.com/ssecd/jkn/issues/new)
31 changes: 25 additions & 6 deletions src/fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ type MaybePromise<T> = T | Promise<T>;

export type Mode = 'development' | 'production';

export type Type = 'vclaim' | 'antrean' | 'apotek' | 'pcare';
export type Type = 'vclaim' | 'antrean' | 'apotek' | 'pcare' | 'icare';

export interface Config {
/**
Expand Down Expand Up @@ -50,6 +50,16 @@ export interface Config {
*/
pcareUserKey: string;

/**
* User key i-Care dari BPJS
*
* Umumnya user key i-Care ini nilai sama dengan user key VClaim
* untuk FKRTL dan PCare untuk FKTP
*
* @default process.env.JKN_ICARE_USER_KEY
*/
icareUserKey: string;

/**
* Berupa mode "development" dan "production". Secara default akan
* membaca nilai environment variable NODE_ENV atau "development"
Expand Down Expand Up @@ -98,10 +108,10 @@ export interface LowerResponse<T> {
};
}

export interface CamelResponse<T> {
export interface CamelResponse<T, C = string> {
response: T;
metaData: {
code: string;
code: C;
message: string;
};
}
Expand All @@ -111,6 +121,7 @@ export type SendResponse<T> = {
vclaim: CamelResponse<T>;
apotek: CamelResponse<T>;
pcare: CamelResponse<T>;
icare: CamelResponse<T, number>;
};

const api_base_urls: Record<Type, Record<Mode, string>> = {
Expand All @@ -129,6 +140,10 @@ const api_base_urls: Record<Type, Record<Mode, string>> = {
pcare: {
development: 'https://apijkn-dev.bpjs-kesehatan.go.id/pcare-rest-dev',
production: 'https://apijkn.bpjs-kesehatan.go.id/pcare-rest'
},
icare: {
development: 'https://apijkn-dev.bpjs-kesehatan.go.id/ihs_dev',
production: 'https://apijkn.bpjs-kesehatan.go.id/ihs'
}
};

Expand All @@ -143,6 +158,7 @@ export class Fetcher {
antreanUserKey: process.env.JKN_ANTREAN_USER_KEY ?? '',
apotekUserKey: process.env.JKN_APOTEK_USER_KEY ?? '',
pcareUserKey: process.env.JKN_PCARE_USER_KEY ?? '',
icareUserKey: process.env.JKN_ICARE_USER_KEY ?? '',
throw: false
};

Expand Down Expand Up @@ -176,7 +192,8 @@ export class Fetcher {
vclaim: this.config.vclaimUserKey,
antrean: this.config.antreanUserKey,
apotek: this.config.apotekUserKey,
pcare: this.config.pcareUserKey
pcare: this.config.pcareUserKey,
icare: this.config.icareUserKey
};
}

Expand Down Expand Up @@ -264,13 +281,15 @@ export class Fetcher {
: 'An error occurred while requesting information from the JKN API';
if (error instanceof Error) message += `. ` + error.message;
message += '. ' + response;
const code = '500';
console.error(error);

// TODO: find better way to infer generic response type
const code = type === 'icare' ? 500 : '500';
return {
metadata: { code: +code, message },
metaData: { code, message },
response: undefined
};
} as unknown as SendResponse<R>[T];
}
}

Expand Down
34 changes: 34 additions & 0 deletions src/icare.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { BaseApi } from './base.js';

export class ICare extends BaseApi<'icare'> {
protected type = 'icare' as const;

async fkrtl(data: {
/** Nomor kartu peserta */
param: string;

/** Kode dokter */
kodedokter: number;
}) {
return this.send<{ url: string }>({
path: `/api/rs/validate`,
method: 'POST',
skipContentTypeHack: true,
headers: { 'Content-Type': 'Application/json' },
data
});
}

async fktp(data: {
/** Nomor kartu peserta */
param: string;
}) {
return this.send<{ url: string }>({
path: `/api/pcare/validate`,
method: 'POST',
skipContentTypeHack: true,
headers: { 'Content-Type': 'Application/json' },
data
});
}
}
5 changes: 5 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Antrean } from './antrean.js';
import { Apotek } from './apotek/index.js';
import { CachedApi } from './base.js';
import { Fetcher } from './fetcher.js';
import { ICare } from './icare.js';
import { PCare } from './pcare/index.js';
import { VClaim } from './vclaim/index.js';

Expand Down Expand Up @@ -32,6 +33,10 @@ export default class JKN extends Fetcher {
get pcare(): PCare {
return this.cache.get('pcare', PCare);
}

get icare(): ICare {
return this.cache.get('icare', ICare);
}
}

export type AntreanResponse<K extends keyof Antrean> = JKNResponseType<Antrean, K>;
Expand Down
26 changes: 26 additions & 0 deletions test/icare.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { describe, expect, it } from 'vitest';
import jkn from './jkn';

describe(
'ICare',
() => {
it.concurrent('fkrtl()', async () => {
const result = await jkn.icare.fkrtl({
param: '0002084717968',
kodedokter: 292667
});
expect(result.metaData.code).toBe(200);
expect(result.response?.url).not.toBeFalsy();
expect(result.response?.url).contains('?token=');
});

it.concurrent('fktp()', async () => {
const result = await jkn.icare.fktp({
param: '0002084717968'
});
expect(result.metaData.code).toBe(200);
expect(result.response?.url).not.toBeFalsy();
});
},
{ timeout: 25_000 }
);
1 change: 1 addition & 0 deletions words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ hapusresep
HEMODIALISA
HFIS
Histori
icare
ICCU
IDUSERSJP
Inacbg
Expand Down

0 comments on commit 5e48a47

Please sign in to comment.