{"id":13401662,"url":"https://github.com/metriport/metriport","last_synced_at":"2025-05-14T08:08:39.791Z","repository":{"id":65039191,"uuid":"580652318","full_name":"metriport/metriport","owner":"metriport","description":"Metriport is an open-source universal API for healthcare data.","archived":false,"fork":false,"pushed_at":"2025-04-04T22:52:07.000Z","size":519793,"stargazers_count":568,"open_issues_count":145,"forks_count":62,"subscribers_count":6,"default_branch":"develop","last_synced_at":"2025-04-04T23:19:35.696Z","etag":null,"topics":["api","fhir","healthcare","hipaa","open-source","self-hostable","soc2","typescript"],"latest_commit_sha":null,"homepage":"https://metriport.com/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/metriport.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":"SUPPORT.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-21T05:07:17.000Z","updated_at":"2025-04-04T19:09:32.000Z","dependencies_parsed_at":"2023-09-21T23:25:21.669Z","dependency_job_id":"fa95e503-8e56-4088-ba31-cc6d94c743b7","html_url":"https://github.com/metriport/metriport","commit_stats":{"total_commits":7270,"total_committers":28,"mean_commits":"259.64285714285717","dds":0.7731774415405777,"last_synced_commit":"6b6f5b10ec108209862ad705ba2257f36c85c36b"},"previous_names":[],"tags_count":3702,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metriport%2Fmetriport","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metriport%2Fmetriport/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metriport%2Fmetriport/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metriport%2Fmetriport/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/metriport","download_url":"https://codeload.github.com/metriport/metriport/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247723430,"owners_count":20985361,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","fhir","healthcare","hipaa","open-source","self-hostable","soc2","typescript"],"created_at":"2024-07-30T19:01:05.463Z","updated_at":"2025-04-09T06:01:53.963Z","avatar_url":"https://github.com/metriport.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","EHR \u0026 Hospital Integrations"],"sub_categories":["Universal Health APIs"],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/metriport/metriport\"\u003e\n    \u003cimg src=\"./assets/logo.png\" alt=\"Logo\"\u003e\n  \u003c/a\u003e\n\n  \u003cp align=\"center\"\u003e\n    Metriport helps healthcare organizations access comprehensive patient medical data, through an\n    open-source universal API.\n    \u003cbr /\u003e\n    \u003ca href=\"https://metriport.com\" target=\"_blank\"\u003e\u003cstrong\u003eLearn more »\u003c/strong\u003e\u003c/a\u003e\n    \u003cbr /\u003e\n    \u003cbr /\u003e\n    \u003ca href=\"https://docs.metriport.com/\" target=\"_blank\"\u003eDocs\u003c/a\u003e\n    ·\n    \u003ca href=\"https://www.npmjs.com/package/@metriport/api-sdk\" target=\"_blank\"\u003eNPM\u003c/a\u003e\n    ·\n    \u003ca href=\"https://dash.metriport.com\" target=\"_blank\"\u003eDeveloper Dashboard\u003c/a\u003e\n    ·\n    \u003ca href=\"https://metriport.com\" target=\"_blank\"\u003eWebsite\u003c/a\u003e\n\n  \u003c/p\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n   \u003ca href=\"https://status.metriport.com/\"\u003e\u003cimg src=\"https://api.checklyhq.com/v1/badges/checks/6aee48de-8699-4746-8843-80e28366ccb0?style=flat\u0026theme=default\" alt=\"API Status Check\"\u003e\u003c/a\u003e\n   \u003ca href=\"https://github.com/metriport/metriport/stargazers\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/metriport/metriport\" alt=\"Github Stars\"\u003e\u003c/a\u003e\n   \u003ca href=\"https://github.com/metriport/metriport/blob/master/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-AGPLv3-purple\" alt=\"License\"\u003e\u003c/a\u003e\n   \u003ca href=\"https://github.com/metriport/metriport/pulse\"\u003e\u003cimg src=\"https://img.shields.io/github/commit-activity/m/metriport/metriport\" alt=\"Commits-per-month\"\u003e\u003c/a\u003e\n   \u003ca href=\"https://twitter.com/metriport\"\u003e\u003cimg src=\"https://img.shields.io/twitter/follow/metriport?style=social\"\u003e\u003c/a\u003e\n   \u003ca href=\"https://www.linkedin.com/company/metriport\"\u003e\u003cimg src=\"https://img.shields.io/static/v1?label=LinkedIn\u0026message=Metriport (YC S22)\u0026color=blue\" alt=\"LinkedIn\"\u003e\u003c/a\u003e\n   \u003ca href=\"https://www.ycombinator.com/companies/metriport\"\u003e\u003cimg src=\"https://img.shields.io/static/v1?label=Y Combinator\u0026message=Metriport\u0026color=orange\" alt=\"YC\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n### **[Join us on our Slack Community](https://join.slack.com/t/metriport-oss/shared_invite/zt-2jezazysw-~AuXop_rFmWQXKmjYRr~cA) 💬**\n\n## **Overview**\n\n\u003cdiv\u003e\n    \u003ca href=\"https://www.loom.com/share/c5c049d2f0444e1ea8e075640077a77f\"\u003e\n      \u003cp\u003eCheck out our platform demo:\u003c/p\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://www.loom.com/share/c5c049d2f0444e1ea8e075640077a77f\"\u003e\n      \u003cimg style=\"max-width:300px;\" src=\"https://cdn.loom.com/sessions/thumbnails/c5c049d2f0444e1ea8e075640077a77f-with-play.gif\"\u003e\n    \u003c/a\u003e\n  \u003c/div\u003e\n\n## **Security and Privacy**\n\nMetriport is SOC 2 and HIPAA compliant. [Click here](https://security.metriport.com/) to learn more about our security practices.\n\n\u003cp style=\"text-align: center;\"\u003e\n  \u003cimg src=\"./assets/soc2.png\" width=\"20%\" /\u003e\n  \u003cimg src=\"./assets/hipaa.png\" width=\"30%\" /\u003e\n\u003c/p\u003e\n\n### **Medical API**\n\n\u003cdiv align=\"center\"\u003e\n   \u003cimg width=\"90%\" alt=\"open source healthcare data api\" src=\"./assets/medical-api.png\"\u003e\n\u003c/div\u003e\n\nOur [Medical API](https://www.metriport.com/medical) brings you data from the largest clinical data networks in the country - one open-source API, 300+ million patients.\n\nMetriport ensures clinical accuracy and completeness of medical information, with HL7 FHIR, C-CDA, and PDF formats supported. Through standardizing, de-duplicating, consolidating, and hydrating data with medical code crosswalking, Metriport delivers rich and comprehensive patient data at the point-of-care.\n\n### **Medical Dashboard**\n\n\u003cdiv align=\"center\"\u003e\n   \u003cimg width=\"90%\" alt=\"open source healthcare data dashboard\" src=\"./assets/medical-dashboard.png\"\u003e\n\u003c/div\u003e\n\nOur [Medical Dashboard](https://www.metriport.com/dashboard) enables providers to streamline their patient record retrieval process. Get up and running within minutes, accessing the largest health information networks in the country through a user-friendly interface.\n\nTools like our FHIR explorer and PDF converter help you make sense of the data you need to make relevant care decisions and improve patient outcomes.\n\n### **Converter API**\n\n\u003cdiv align=\"center\"\u003e\n   \u003cimg width=\"90%\" alt=\"convert c-cda to fhir\" src=\"./assets/fhir-converter.png\"\u003e\n\u003c/div\u003e\n\nA key piece to achieving true interoperability is compatibility between different data formats. Using advanced processing techniques, Metriport's [FHIR Converter](https://www.metriport.com/fhir-converter) takes common healthcare data formats such as C-CDA, and converts them into FHIR R4 to streamline data exchange.\n\nGet started converting using our [Quickstart Guide](https://docs.metriport.com/converter-api/getting-started/quickstart).\n\n## **Getting Started**\n\nCheck out the links below to get started with Metriport in minutes!\n\n### **[Slack Community](https://join.slack.com/t/metriport-oss/shared_invite/zt-2jezazysw-~AuXop_rFmWQXKmjYRr~cA) 💬**\n\n### **[Quickstart Guide](https://docs.metriport.com/medical-api/getting-started/quickstart) 🚀**\n\n### **[Developer Dashboard](https://dash.metriport.com/) 💻**\n\n### **[npm package](https://www.npmjs.com/package/@metriport/api-sdk)**\n\n## **Repo Rundown**\n\n### **API Server**\n\nBackend for the Metriport API.\n\n- Dir: [`/packages/api`](/packages/api)\n- URL: [https://api.metriport.com/](https://api.metriport.com/)\n- Sandbox URL: [https://api.sandbox.metriport.com/](https://api.sandbox.metriport.com/)\n\n### **FHIR Converter**\n\nEngine to convert various healthcara data formats to FHIR, and back.\n\n- Dir: [`/packages/fhir-converter`](/packages/fhir-converter)\n\n### **Infrastructure as Code**\n\nWe use AWS CDK as IaC.\n\n- Dir: [`/packages/infra`](/packages/infra)\n\n### **Docs**\n\nOur beautiful developer documentation, powered by [mintlify](https://mintlify.com/) ❤️.\n\n- Dir: [`/docs`](/docs)\n- URL: [https://docs.metriport.com/](https://docs.metriport.com/getting-started/introduction)\n\n### **Packages**\n\n#### **npm**\n\nOur npm packages are available in [`/packages`](/packages):\n\n- [Metriport API](/packages/api-sdk/): contains the Metriport data models, and a convenient API client wrapper.\n- [CommonWell JWT Maker](/packages/commonwell-jwt-maker/): CLI to create a JWT for use in [CommonWell](https://www.commonwellalliance.org/) queries.\n- [CommonWell SDK](/packages/commonwell-sdk/): SDK to simplify CommonWell API integration.\n\n---\n\n## Contributing\n\nGot ideas for how you can make Metriport better? We welcome community contributions!\n\n#### Contribution guidelines\n\nBy making a contribution to this project, you are deemed to have accepted the [Developer Certificate of Origin](https://developercertificate.org/) (DCO), agree to GitHub's [Community Guidelines](https://help.github.com/en/github/site-policy/github-community-guidelines), and agree to the [Acceptable Use Policies](https://help.github.com/en/github/site-policy/github-acceptable-use-policies).\n\n#### Requesting a feature, or reporting a bug\n\n[Click here to open a new issue](https://github.com/metriport/metriport/issues/new/choose) - follow the chosen template and you're good to go.\n\n## **Local Development**\n\n### Monorepo\n\nThis monorepo uses [npm workspaces](https://docs.npmjs.com/cli/v9/using-npm/workspaces) to manage the packages and execute commands globally.\n\nBut not all folders under `/packages` are part of the workspace. To see the ones that are, check the\nroot folder's `package.json` under the `workspaces` section.\n\nTo setup this repository for local development, issue this command on the root folder:\n\n```shell\n$ npm run init # only needs to be run once\n$ npm run build # packages depend on each other, so its best to build/compile them all\n```\n\nUseful commands:\n\n- `npm run test`: it executes the `test` script on all workspaces;\n- `npm run typecheck`: it will run `typecheck` on all workspaces, which checks for typescript compilation/syntax issues;\n- `npm run lint-fix`: it will run `lint-fix` on all workspaces, which checks for linting issues and automatically fixes the issues it can;\n- `npm run prettier-fix`: it will run `prettier-fix` on all workspaces, which checks for formatting issues and automatically fixes the issues it can;\n\n### Semantic version\n\nThis repo uses [Semantic Version](https://semver.org/), and we automate the versioning by using [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).\n\nThis means all commit messages must be created following a certain standard:\n\n```\n\u003ctype\u003e[optional scope]: \u003cdescription\u003e\n[optional body]\n[optional footer(s)]\n```\n\nTo enforce commits follow this pattern, we have a Git hook (using [Husky](https://github.com/typicode/husky)) that verifies commit messages according to the Conventional Commits -\nit uses [commitlint](https://github.com/conventional-changelog/commitlint) under the hood ([config](https://github.com/conventional-changelog/commitlint/tree/master/@commitlint/config-conventional)).\n\nAccepted types:\n\n- build\n- chore\n- ci\n- docs\n- feat\n- fix\n- perf\n- refactor\n- revert\n- style\n- test\n\nScope is optional, and we can use one of these, or empty (no scope):\n\n- api\n- sdk\n- infra\n- core\n- shared\n- utils\n- scripts\n- docs\n- ... (usually subdirectories of `./packages`)\n\nThe footer should have the ticket number supporting the commit:\n\n```\n...\nRef: #\u003cticket-number\u003e\n```\n\n#### Commitizen\n\nOne can enter the commit message manually and have `commitlint` check its content, or use [Commitizen](https://github.com/commitizen/cz-cli)'s\nCLI to guide through building the commit message:\n\n```shell\n$ npm run commit\n```\n\nIn case something goes wrong after you prepare the commit message and you want to retry it after fixing the issue, you can issue this command:\n\n```shell\n$ npm run commit -- --retry\n```\n\nCommitizen will retry the last commit message you prepared previously. More about this [here](https://github.com/commitizen/cz-cli#retrying-failed-commits).\n\n### Security\n\nTo avoid pushing secrets to the remote git repository we use [Gitleaks](https://github.com/gitleaks/gitleaks) - triggered by [Husky](https://github.com/typicode/husky).\n\nFrom their repository:\n\n\u003e Gitleaks is a SAST tool for detecting and preventing hardcoded secrets like passwords, api keys, and tokens in git repos.\n\nIt automaticaly scans new commits and interrupts the execution if it finds content that match the configured rules.\n\nExample of report while trying to commit changes:\n\n```shell\n\u003e metriport@1.0.0 check-secrets\n\u003e docker run --rm -v $(pwd):/path zricethezav/gitleaks:v8.17.0 protect --source='/path' --staged --no-banner -v\n\nFinding:     ...XXXXXXXXX\u001b[1;3;mAIXXXXXXXX\u001b[0mXXXXXXX/aXXXXXXX...\nSecret:      \u001b[1;3;mXXXXXXXXXXXXXX\u001b[0m\nRuleID:      aws-access-token\nEntropy:     1.021928\nFile:        packages/core/src/external/cda/__tests__/examples.ts\nLine:        69\nFingerprint: packages/core/src/external/cda/__tests__/examples.ts:aws-access-token:69\n\n\u001b[90m2:31AM\u001b[0m \u001b[32mINF\u001b[0m 1 commits scanned.\n\u001b[90m2:31AM\u001b[0m \u001b[32mINF\u001b[0m scan completed in 141ms\n\u001b[90m2:31AM\u001b[0m \u001b[31mWRN\u001b[0m leaks found: 1\nhusky - pre-commit hook exited with code 1 (error)\n```\n\nIf you're absolutely sure there's no secret on the reported file/line, add the fingerprint to `.gitleaksignore` file - that will be ignored and you'll be able to commit.\n\n### **API Server**\n\nFirst, create a local environment file to define your developer keys, and local dev URLs:\n\n```shell\n$ touch packages/api/.env\n$ echo \"LOCAL_ACCOUNT_CXID=\u003cYOUR-TESTING-ACCOUNT-ID\u003e\" \u003e\u003e packages/api/.env\n$ echo \"API_URL=http://localhost:8080\" \u003e\u003e packages/api/.env\n$ echo \"FHIR_SERVER_URL=\u003cFHIR-SERVER-URL\u003e\" \u003e\u003e packages/api/.env # optional\n```\n\nAdditionally, define your System Root [OID](https://en.wikipedia.org/wiki/Object_identifier). This will be the base identifier to represent your system in any medical data you create - such as organizations, facilities, patients, and etc.\n\nYour OID must be registered and assigned by HL7. You can do this [here](http://www.hl7.org/oid/index.cfm).\n\nBy default, OIDs in Metriport are managed according to the [recommended standards outlined by HL7](http://www.hl7.org/documentcenter/private/standards/v3/V3_OIDS_R1_INFORM_2011NOV.pdf).\n\n```shell\n$ echo \"SYSTEM_ROOT_OID=\u003cYOUR-OID\u003e\" \u003e\u003e packages/api/.env\n```\n\nThese envs are specific to CommonWell and are necessary in sending requests to their platform.\n\n```shell\n$ echo \"CW_TECHNICAL_CONTACT_NAME=\u003cYOUR-SECRET\u003e\" \u003e\u003e packages/api/.env\n$ echo \"CW_TECHNICAL_CONTACT_TITLE=\u003cYOUR-SECRET\u003e\" \u003e\u003e packages/api/.env\n$ echo \"CW_TECHNICAL_CONTACT_EMAIL=\u003cYOUR-SECRET\u003e\" \u003e\u003e packages/api/.env\n$ echo \"CW_TECHNICAL_CONTACT_PHONE=\u003cYOUR-SECRET\u003e\" \u003e\u003e packages/api/.env\n$ echo \"CW_GATEWAY_ENDPOINT=\u003cYOUR-SECRET\u003e\" \u003e\u003e packages/api/.env\n$ echo \"CW_GATEWAY_AUTHORIZATION_SERVER_ENDPOINT=\u003cYOUR-SECRET\u003e\" \u003e\u003e packages/api/.env\n$ echo \"CW_GATEWAY_AUTHORIZATION_CLIENT_ID=\u003cYOUR-SECRET\u003e\" \u003e\u003e packages/api/.env\n$ echo \"CW_GATEWAY_AUTHORIZATION_CLIENT_SECRET=\u003cYOUR-SECRET\u003e\" \u003e\u003e packages/api/.env\n$ echo \"CW_MEMBER_NAME=\u003cYOUR-SECRET\u003e\" \u003e\u003e packages/api/.env\n$ echo \"CW_MEMBER_OID=\u003cYOUR-SECRET\u003e\" \u003e\u003e packages/api/.env\n$ echo \"CW_ORG_MANAGEMENT_PRIVATE_KEY=\u003cYOUR-SECRET\u003e\" \u003e\u003e packages/api/.env\n$ echo \"CW_ORG_MANAGEMENT_CERTIFICATE=\u003cYOUR-SECRET\u003e\" \u003e\u003e packages/api/.env\n$ echo \"CW_MEMBER_PRIVATE_KEY=\u003cYOUR-SECRET\u003e\" \u003e\u003e packages/api/.env\n$ echo \"CW_MEMBER_CERTIFICATE=\u003cYOUR-SECRET\u003e\" \u003e\u003e packages/api/.env\n```\n\n#### **Optional analytics reporting**\n\nThe API server reports analytics to [PostHog](https://posthog.com/). This is optional.\n\nIf you want to set it up, add this to the `.env` file:\n\n```shell\n$ echo \"POST_HOG_API_KEY_SECRET=\u003cYOUR-API-KEY\u003e\" \u003e\u003e packages/api/.env\n```\n\n#### **Optional usage report**\n\nThe API server reports endpoint usage to an external service. This is optional.\n\nA reachable service that accepts a `POST` request to the informed URL with the payload below is required:\n\n```json\n{\n  \"cxId\": \"\u003cthe account ID\u003e\",\n  \"cxUserId\": \"\u003cthe ID of the user who's data is being requested\u003e\"\n}\n```\n\nIf you want to set it up, add this to the `.env` file:\n\n```shell\n$ echo \"USAGE_URL=\u003cYOUR-URL\u003e\" \u003e packages/api/.env\n```\n\n#### **Finalizing setting up the API Server**\n\nThen to run the full back-end stack, use docker-compose to lauch a Postgres container, local instance of DynamoDB, and the Node server itself:\n\n```shell\n$ cd packages/api\n$ npm run start-docker-compose\n```\n\n...or, from the root folder...\n\n```shell\n$ npm run start-docker-compose -w api\n```\n\nNow, the backend services will be available at:\n\n- API Server: `0.0.0/0:8080`\n- Postgres: `localhost:5432`\n- DynamoDB: `localhost:8000`\n\nAnother option is to have the dependency services running with docker compose and the back-end API running as regular NodeJS process (faster\nto run and restart); this has the benefit of Docker Desktop managing the services and you likely only need to start the dependencies once.\n\n```shell\n$ cd packages/api\n$ npm run start-dependencies # might be able run it once\n$ npm run dev\n```\n\n#### **Database Migrations**\n\nThe API Server uses Sequelize as an ORM, and its migration component to update the DB with changes as the application\nevolves. It also uses Umzug for programatic migration execution and typing.\n\nWhen the application runs it automatically executes all migrations located under `src/sequelize/migrations` (in ascending order)\nbefore the code is atually executed.\n\nIf you need to undo/revert a migration manually, you can use the CLI, which is a wrapper to Umzug's CLI (still under heavy\ndevelopment at the time of this writing).\n\nIt requires DB credentials on the environment variable `DB_CREDS` (values from `docker-compose.dev.yml`, update as needed):\n\n```shell\n$ export DB_CREDS='{\"username\":\"admin\",\"password\":\"admin\",\"dbname\":\"db\",\"engine\":\"postgres\",\"host\":\"localhost\",\"port\":5432}'\n```\n\nRun the CLI with:\n\n```shell\n$ npm i -g ts-node # only needs to be run once\n$ cd packages/api\n$ ts-node src/sequelize/cli\n```\n\nAlternatively, you can use a shortcut for migrations on local environment:\n\n```shell\n$ npm run db-local -- \u003ccmd\u003e\n```\n\n\u003e Note: the double dash `--` is required so parameters after it go to sequelize cli; without it, parameters go to `npm`\n\nUmzug's CLI is still in development at the time of this writing, so that's how one uses it:\n\n- it will print the commands being sent to the DB\n- followed by the result of the command\n- it won't exit by default, you need to `ctrl+c`\n- the command `up` executes all outstanding migrations\n- the command `down` reverts one migration at a time\n\nTo create new migrations:\n\n1. Duplicate a migration file on `./packages/api/src/sequelize/migrations`\n2. Rename the new file so the timestamp is close to the current time - it must be unique, migrations are executed in sorting order\n3. Edit the migration file to perform the changes you want\n   - `up` add changes to the DB (takes it to the new version)\n   - `down` rolls back changes from the DB (goes back to the previous version)\n\n#### **Additional stuff**\n\nTo do basic UI admin operations on the DynamoDB instance, you can do the following:\n\n```shell\n$ npm install -g dynamodb-admin # only needs to be run once\n$ npm run ddb-admin # admin console will be available at http://localhost:8001/\n```\n\nTo kill and clean-up the back-end, hit `CTRL + C` a few times, and run the following from the `packages/api` directory:\n\n```shell\n$ docker-compose -f docker-compose.dev.yml down\n```\n\nTo debug the backend, you can attach a debugger to the running Docker container by launching the `Docker: Attach to Node` configuration in VS Code. Note that this will support hot reloads 🔥🔥!\n\n### Utils\n\nThe `./packages/utils` folder contains utilities that help with the development of this and other opensource Metriport projects:\n\n- [mock-webhook](https://github.com/metriport/metriport/blob/develop/packages/utils/src/mock-webhook.ts): implements the Metriport webhook protocol, can be used by applications integrating with Metriport API as a reference to the behavior expected from these applications when using the webhook feature.\n- [fhir-uploader](https://github.com/metriport/metriport/blob/develop/packages/utils/src/fhir-uploader.ts): useful to insert synthetic/mock data from [Synthea](https://github.com/synthetichealth/synthea) into [FHIR](https://www.hl7.org/fhir) servers (see https://github.com/metriport/hapi-fhir-jpaserver).\n\nCheck the scripts on the folder's [package.json](https://github.com/metriport/metriport/blob/develop/packages/utils/package.json) to see how to run these.\n\n---\n\n### Tests\n\nUnit tests can be executed with:\n\n```shell\n$ npm run test\n```\n\nTo run integration tests, make sure to check each package/folder README for requirements, but in general they can be\nexecuted with:\n\n```shell\n$ npm run test:e2e\n```\n\n## **Self-Hosted Deployments**\n\n### **API Key Setup**\n\nMost endpoints require an API Gateway [API Key](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-api-usage-plans.html).\nYou can do it manually on AWS console or programaticaly through AWS CLI or SDK.\n\nTo do it manually:\n\n1. Login to the AWS console;\n1. Go to API Gateway;\n1. Create a Usage Plan if you don't already have one;\n1. Create an API Key;\n   - the `value` field must follow this pattern: base 64 of \"`\u003cKEY\u003e:\u003cUUID\u003e`\", where:\n   - `KEY` is a random key (e.g., generated with `nanoid`); and\n   - `UUID` is the customer ID (more about this on [Initialization](#initialization))\n1. Add the newly created API Key to a Usage Plan.\n\nNow you can make requests to endpoints that require the an API Key by setting the `x-api-key` header.\n\n### **Environment Setup**\n\n1. Install [AWS CLI](https://aws.amazon.com/cli/) and authenticate with it.\n\n2. You'll need to create and configure a deployment config file: `/infra/config/production.ts`. You can see `example.ts` in the same directory\n   for a sample of what the end result should look like. Optionally, you can setup config files for `staging` and `sandbox` deployments, based on\n   your environment needs. Then, proceed with the deployment steps below.\n\n3. Install [GNU Parallel](https://www.gnu.org/software/parallel/) to run tests (w/ `npm run test`).\n\n### **Deployment Steps**\n\n1. First, deploy the secrets stack. This will setup the secret keys required to run the server using AWS Secrets Manager and create other infra\n   pre-requisites. To deploy it, run the following commands (with `\u003cconfig.stackName\u003e` replaced with what you've set in your config file):\n\n```shell\n$ ./packages/scripts/deploy-infra.sh -e \"production\" -s \"\u003cconfig.secretsStackName\u003e\"\n```\n\n2. After the previous steps are done, define all of the required keys in the AWS console by navigating to the Secrets Manager.\n\n3. Then, to provision the infrastructure needed by the API/back-end execute the following command:\n\n```shell\n$ ./packages/scripts/deploy-infra.sh -e \"production\" -s \"\u003cconfig.stackName\u003e\"\n```\n\nThis will create the infrastructure to run the API, including the ECR repository where the API will be deployed at. Take note of that to populate\nthe environment variable `ECR_REPO_URI`.\n\n4. To provision the IHE Gateway:\n\nUpdate the `packages/infra/config/production.ts` configuration file, populating the properties under\n`iheGateway` with the information from the respective resources created on the previous step\n(API Stack).\n\nExecute:\n\n```shell\n$ ./packages/scripts/deploy-infra.sh -e \"production\" -s \"IHEStack\"\n```\n\nThis will create the infrastructure to run the IHE Gateway.\n\n5. To deploy the API on ECR and restart the ECS service to make use of it:\n\n```shell\n$ AWS_REGION=xxx ECR_REPO_URI=xxx ECS_CLUSTER=xxx ECS_SERVICE=xxx ./packages/scripts/deploy-api.sh\"\n```\n\nwhere:\n\n- ECR_REPO_URI: The URI of the ECR repository to push the Docker image to (created on the previous step)\n- AWS_REGION: The AWS region where the API should be deployed at\n- ECS_CLUSTER: The ARN of the ECS cluster containing the service to be restarted upon deployment\n- ECS_SERVICE: The ARN of the ECS service to be restarted upon deployment\n\nAfter deployment, the API will be available at the configured subdomain + domain.\n\nNote: if you need help with the `deploy-infra.sh` script at any time, you can run:\n\n```shell\n$ ./packages/scripts/deploy-infra.sh -h\n```\n\n## License\n\nDistributed under the AGPLv3 License. See `LICENSE` for more information.\n\nCopyright © Metriport 2022-present\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetriport%2Fmetriport","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmetriport%2Fmetriport","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetriport%2Fmetriport/lists"}