Skip to content

Commit f2249b2

Browse files
author
JAMES FUQIAN
committed
1st cut cleanup.
1 parent 0097fcc commit f2249b2

29 files changed

Lines changed: 174 additions & 984 deletions

README.md

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,11 @@ Download and install node. Go to https://nodejs.org/en/download/ and follow the
2424

2525
Once you have Docker and Node installed and setup then do the following:
2626

27-
copy server/src/configs/sample.config.ts -> server/src/configs/config.ts
27+
cp server/sample-bluebutton-config.json -> server/.bluebutton-config.json
2828

2929
Make sure to replace the clientId and clientSecret variables within the config file with
3030
the ones you were provided, for your application, when you created your Blue Button Sandbox account.
3131

32-
copy server/src/pre-start/env/sandbox.sample.env -> server/src/pre-start/env/development.env
33-
3432
docker-compose up -d
3533

3634
This single command will create the docker container with all the necessary packages, configuration, and code to
@@ -66,7 +64,7 @@ To start the sample in native OS (e.g. Linux) with server and client components
6664
1. go to the base directory of the repo
6765
2. run below to start the server:
6866
1. yarn --cwd server install
69-
2. yarn --cwd server start:dev
67+
2. yarn --cwd server start
7068
3. run below to start the client:
7169
1. yarn --cwd client install
7270
2. yarn --cwd client start-native
@@ -77,15 +75,6 @@ Both ways of starting the sample are running the sample in foreground, logging a
7775

7876
For client and server started separately in their command window, type Ctrl C respectively
7977

80-
## Run tests
81-
82-
Go to local repo base directory:
83-
84-
copy server/src/configs/sample.config.ts -> server/src/configs/config.ts
85-
86-
yarn --cwd server install
87-
yarn --cwd server test
88-
8978
## Run selenium tests in docker
9079

9180
Configure the remote target BB2 instance where the tested app is registered (as described above "Running the Back-end & Front-end")

server/Dockerfile

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@ LABEL description="Demo of a Medicare claims data sample app"
55

66
WORKDIR /server
77

8-
COPY ["./src/configs/sample.config.ts", "./src/configs/config.ts"]
9-
COPY ["./src/pre-start/env/sandbox.sample.env","./src/pre-start/env/development.env"]
10-
118
COPY . .
129

1310
RUN yarn install

server/index.ts

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import express, { Request, Response } from "express";
2+
import { AuthorizationToken, BlueButton } from "cms-bluebutton-sdk";
3+
4+
interface User {
5+
authToken?: AuthorizationToken,
6+
eobData?: any,
7+
errors?: string[]
8+
}
9+
10+
const app = express();
11+
12+
const bb = new BlueButton();
13+
const authData = bb.generateAuthData();
14+
15+
// This is where medicare.gov beneficiary associated
16+
// with the current logged in app user,
17+
// in real app, this could be the app specific
18+
// account management system
19+
20+
const loggedInUser: User = {
21+
};
22+
23+
// AuthorizationToken holds access grant info:
24+
// access token, expire in, expire at, token type, scope, refreh token, etc.
25+
// it is associated with current logged in user in real app,
26+
// check SDK js docs for more details.
27+
28+
let authToken: AuthorizationToken;
29+
30+
// auth flow: response with URL to redirect to Medicare.gov beneficiary login
31+
app.get("/api/authorize/authurl", (req: Request, res: Response) => {
32+
res.send(bb.generateAuthorizeUrl(authData));
33+
});
34+
35+
// auth flow: oauth2 call back
36+
app.get("/api/bluebutton/callback", async (req: Request, res: Response) => {
37+
if (typeof req.query.error === "string") {
38+
res.json({ message: req.query.error });
39+
} else {
40+
if (
41+
typeof req.query.code === "string" &&
42+
typeof req.query.state === "string"
43+
) {
44+
// let results;
45+
try {
46+
authToken = await bb.getAuthorizationToken(
47+
authData,
48+
req.query.code,
49+
req.query.state
50+
);
51+
// data flow: after access granted
52+
// the app logic can fetch the beneficiary's data in app specific ways:
53+
// e.g. download EOB periodically etc.
54+
// access token can expire, SDK automatically refresh access token when that happens.
55+
const eobResults = await bb.getExplanationOfBenefitData(authToken);
56+
authToken = eobResults.token; // in case authToken got refreshed during fhir call
57+
// const patientResults = await bb.getPatientData(authToken);
58+
// authToken = patientResults.token;
59+
// const coverageResults = await bb.getCoverageData(authToken);
60+
// authToken = coverageResults.token;
61+
// const profileResults = await bb.getProfileData(authToken);
62+
// authToken = profileResults.token;
63+
64+
// nav pages if needed for eob, patient, coverage
65+
// client code can preemptively refresh tokens by calling refreshAuthToken(authToken)
66+
// console.log(
67+
// "============= preemptively do oauth token refresh before fetch EOB ================="
68+
// );
69+
70+
// console.log("============= authToken =================");
71+
72+
// authToken = await bb.refreshAuthToken(authToken);
73+
74+
// console.log(authToken);
75+
76+
loggedInUser.authToken = authToken;
77+
// console.log("============= EOB PAGES =================");
78+
79+
loggedInUser.eobData = eobResults.response?.data;
80+
// const eobs = await bb.getPages(eobbundle, authToken);
81+
// for (let i = 0; i < eobs.pages.length; i++) {
82+
// fs.writeFileSync(`eob_p${i}.json`, JSON.stringify(eobs.pages[i]));
83+
// }
84+
85+
// authToken = eobs.token;
86+
87+
// console.log("=============PATIENT=================");
88+
// const ptbundle = patientResults.response?.data;
89+
// const pts = await bb.getPages(ptbundle, authToken);
90+
// authToken = pts.token;
91+
92+
// console.log("=============COVERAGE=================");
93+
// const coveragebundle = coverageResults.response?.data;
94+
// const coverages = await bb.getPages(coveragebundle, authToken);
95+
// authToken = coverages.token;
96+
97+
// console.log("=============PROFILE=================");
98+
// const pfbundle = profileResults.response?.data;
99+
// const pfs = await bb.getPages(pfbundle, authToken);
100+
// authToken = pfs.token;
101+
102+
// results = {
103+
// eob: eobs.pages,
104+
// patient: pts.pages,
105+
// coverage: coverages.pages,
106+
// profile: pfs.pages,
107+
// };
108+
} catch (e) {
109+
console.log(e);
110+
}
111+
// res.json(results);
112+
} else {
113+
//res.json({ message: "Missing AC in callback." });
114+
console.log("Missing AC in callback.");
115+
}
116+
}
117+
const fe_redirect_url =
118+
process.env.SELENIUM_TESTS ? 'http://client:3000' : 'http://localhost:3000';
119+
res.redirect(fe_redirect_url);
120+
});
121+
122+
// data flow: front end fetch eob
123+
app.get("/api/data/benefit", async (req: Request, res: Response) => {
124+
if (loggedInUser.eobData) {
125+
res.json(loggedInUser.eobData);
126+
}
127+
});
128+
129+
const port = 3001;
130+
app.listen(port, () => {
131+
console.log(`[server]: Server is running at https://localhost:${port}`);
132+
});

server/package.json

Lines changed: 13 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,13 @@
11
{
22
"name": "server",
3-
"version": "0.0.0",
3+
"version": "1.0.0",
4+
"description": "CMS Blue Button API Sample App",
5+
"author": "CMS Blue Button API team",
6+
"license": "MIT",
47
"scripts": {
5-
"build": "./node_modules/.bin/ts-node build.ts",
68
"lint": "eslint --fix --ext .ts --ext .tsx .",
7-
"start": "node -r module-alias/register ./dist --env=production",
8-
"start:debug": "node --inspect=0.0.0.0:9229 ./node_modules/.bin/ts-node -r tsconfig-paths/register ./src",
9-
"start:dev": "nodemon",
10-
"test": "jest --coverage"
11-
},
12-
"nodemonConfig": {
13-
"watch": [
14-
"src"
15-
],
16-
"ext": "ts, html",
17-
"ignore": [
18-
"src/public"
19-
],
20-
"exec": "./node_modules/.bin/ts-node -r tsconfig-paths/register ./src"
21-
},
22-
"_moduleAliases": {
23-
"@daos": "dist/daos",
24-
"@entities": "dist/entities",
25-
"@shared": "dist/shared",
26-
"@configs": "dist/configs",
27-
"@server": "dist/Server"
9+
"start": "node ./node_modules/.bin/ts-node -r tsconfig-paths/register .",
10+
"start:debug": "node --inspect=0.0.0.0:9229 ./node_modules/.bin/ts-node -r tsconfig-paths/register ."
2811
},
2912
"eslintConfig": {
3013
"parser": "@typescript-eslint/parser",
@@ -58,51 +41,23 @@
5841
}
5942
},
6043
"eslintIgnore": [
61-
"src/public/",
6244
"build.ts"
6345
],
6446
"dependencies": {
65-
"axios": "^0.21.2",
66-
"command-line-args": "^5.1.1",
67-
"cookie-parser": "^1.4.5",
68-
"dotenv": "^8.2.0",
69-
"express": "^4.17.1",
70-
"express-async-errors": "^3.1.1",
71-
"form-data": "^3.0.0",
72-
"helmet": "^4.5.0",
73-
"http-status-codes": "^2.1.4",
74-
"jet-logger": "^1.0.4",
75-
"jsonfile": "^6.1.0",
76-
"module-alias": "^2.2.2",
77-
"moment": "^2.29.1",
78-
"morgan": "^1.10.0"
47+
"@types/express": "^4.17.14",
48+
"cms-bluebutton-sdk": "file:../../cms-bb2-node-sdk/",
49+
"express": "^4.18.2",
50+
"ts-node": "^10.9.1",
51+
"typescript": "^4.9.3"
7952
},
8053
"devDependencies": {
81-
"@babel/preset-env": "^7.16.11",
82-
"@babel/preset-typescript": "^7.16.7",
83-
"@types/command-line-args": "^5.0.0",
84-
"@types/cookie-parser": "^1.4.2",
85-
"@types/express": "^4.17.11",
86-
"@types/find": "^0.2.1",
87-
"@types/fs-extra": "^9.0.11",
88-
"@types/jest": "^27.4.1",
89-
"@types/jsonfile": "^6.0.0",
90-
"@types/morgan": "^1.9.2",
91-
"@types/node": "^15.0.1",
92-
"@types/supertest": "^2.0.11",
9354
"@typescript-eslint/eslint-plugin": "^4.22.0",
9455
"@typescript-eslint/parser": "^4.22.0",
9556
"eslint": "^7.25.0",
9657
"eslint-config-airbnb": "^19.0.4",
9758
"eslint-config-airbnb-typescript": "^16.1.0",
9859
"eslint-plugin-import": "^2.25.4",
99-
"find": "^0.3.0",
100-
"fs-extra": "^9.1.0",
101-
"jest": "^27.5.1",
102-
"nodemon": "^2.0.7",
103-
"supertest": "^6.1.3",
104-
"ts-node": "^10.8.1",
105-
"tsconfig-paths": "^3.9.0",
106-
"typescript": "^4.2.4"
60+
"jest": "^29.3.1",
61+
"tsconfig-paths": "^4.1.0"
10762
}
10863
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"clientId": "<client_id>",
3+
"clientSecret": "<client_secret>",
4+
"callbackUrl": "http://localhost:3001/api/bluebutton/callback/",
5+
"version": "2",
6+
"environment": "SANDBOX"
7+
}
8+

server/spec/index.ts

Whitespace-only changes.

server/spec/loadEnv.ts

Lines changed: 0 additions & 10 deletions
This file was deleted.

server/spec/nodemon.json

Lines changed: 0 additions & 6 deletions
This file was deleted.

server/src/@types/express/index.d.ts

Lines changed: 0 additions & 9 deletions
This file was deleted.

server/src/Server.ts

Lines changed: 0 additions & 46 deletions
This file was deleted.

0 commit comments

Comments
 (0)