fhirsmith 0.18.1 → 1.0.0
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.
- package/ACCESSIBILITY.md +119 -0
- package/CHANGELOG.md +190 -9
- package/CONFIGURATION.md +305 -0
- package/LICENSE +29 -0
- package/README.md +29 -122
- package/cluster.js +1220 -0
- package/cluster.md +707 -0
- package/config-template.json +77 -8
- package/extension-tracker/extension-tracker-template.html +5 -8
- package/extension-tracker/extension-tracker.js +0 -2
- package/folder/folder.js +7 -6
- package/ips/analysis.js +560 -0
- package/ips/ips-template.html +5 -8
- package/ips/ips.js +331 -33
- package/ips/jurisdictions.js +65 -0
- package/ips/nationality.js +120 -0
- package/ips/pipeline.js +131 -17
- package/ips/presenter.js +1 -1
- package/ips/profile-editor.js +283 -4
- package/ips/readme.md +170 -20
- package/ips/render.js +769 -109
- package/ips/scripts.js +46 -0
- package/ips/store.js +123 -11
- package/ips/structure.js +247 -0
- package/ips/terminology.js +1 -1
- package/library/body-limit.js +22 -0
- package/library/cache-generation.js +15 -0
- package/library/cgroup-memory.js +133 -1
- package/library/cluster-counts.js +121 -0
- package/library/cluster-events.js +153 -0
- package/library/cluster-metrics.js +193 -0
- package/library/cluster-status.js +468 -0
- package/library/config-reader.js +96 -0
- package/library/daily-report.js +100 -2
- package/library/html-server.js +27 -1
- package/library/i18nsupport.js +23 -1
- package/library/keep-alive.js +18 -0
- package/library/languages.js +17 -3
- package/library/logger.js +31 -0
- package/library/memory-guard.js +428 -0
- package/library/native-memory.js +52 -0
- package/library/npm-audit.js +51 -25
- package/library/openapi-doc.js +7 -5
- package/library/package-manager.js +8 -0
- package/library/role.js +197 -0
- package/library/server-credentials.js +169 -0
- package/library/sqlite-utilities.js +59 -0
- package/library/ssrf-guard.js +100 -0
- package/library/static-response-stats.js +16 -0
- package/library/version-utilities.js +50 -0
- package/library/worker-count.js +192 -0
- package/nginx.md +30 -11
- package/npmprojector/indexer.js +18 -10
- package/package.json +11 -8
- package/packages/feed-check-page.js +117 -0
- package/packages/feed-check.js +279 -0
- package/packages/npm-check.js +57 -3
- package/packages/npm-signing.js +219 -0
- package/packages/openapi.yaml +207 -1
- package/packages/package-crawler.js +322 -41
- package/packages/packages-template.html +6 -8
- package/packages/packages.js +604 -57
- package/packages/readme.md +113 -1
- package/publisher/publisher-template.html +2 -5
- package/publisher/publisher.js +121 -110
- package/publisher/readme.md +75 -0
- package/registry/api.js +179 -1
- package/registry/crawler.js +86 -108
- package/registry/documentation/api.md +68 -2
- package/registry/documentation/configuration.md +34 -0
- package/registry/documentation/internals.md +4 -1
- package/registry/documentation/readme.md +3 -2
- package/registry/model.js +8 -0
- package/registry/openapi.yaml +84 -0
- package/registry/registry-template.html +5 -8
- package/registry/registry.js +58 -6
- package/root-bare-template.html +7 -4
- package/root-template.html +5 -8
- package/server.js +398 -198
- package/shl/shl.js +38 -37
- package/static/a11y/a11y-check.js +832 -0
- package/static/a11y/axe.min.js +12 -0
- package/static/assets/css/bootstrap-fhir.css +15 -15
- package/static/assets/images/flags/au.svg +18 -0
- package/static/assets/images/flags/unknown.svg +11 -0
- package/static/assets/images/flags/us.svg +63 -0
- package/static/assets/images/icon_audit.png +0 -0
- package/static/assets/images/icon_clinical.png +0 -0
- package/static/assets/images/icon_document.png +0 -0
- package/static/assets/images/icon_external.png +0 -0
- package/static/assets/images/icon_medication.png +0 -0
- package/static/assets/images/icon_organization.png +0 -0
- package/static/assets/images/icon_other.png +0 -0
- package/static/assets/images/icon_person.png +0 -0
- package/static/assets/images/icon_section.png +0 -0
- package/stats-db.js +45 -0
- package/stats.js +197 -10
- package/testing/testing-template.html +5 -8
- package/token/nginx_passport_setup.md +1 -1
- package/token/security_guide.md +1 -1
- package/token/token-template.html +2 -5
- package/token/token.js +40 -36
- package/translations/Messages.properties +19 -0
- package/tx/README.md +158 -4
- package/tx/closure/closure-store.js +126 -3
- package/tx/cm/cm-database.js +69 -57
- package/tx/cm/cm-package.js +50 -16
- package/tx/cs/cs-api.js +284 -19
- package/tx/cs/cs-api.md +41 -4
- package/tx/cs/cs-areacode.js +1 -1
- package/tx/cs/cs-country.js +17 -5
- package/tx/cs/cs-cpt.js +33 -16
- package/tx/cs/cs-cs.js +199 -24
- package/tx/cs/cs-currency.js +1 -1
- package/tx/cs/cs-icd11.js +21 -13
- package/tx/cs/cs-icf.js +22 -3
- package/tx/cs/cs-lang.js +2 -2
- package/tx/cs/cs-loinc.js +193 -67
- package/tx/cs/cs-mimetypes.js +12 -2
- package/tx/cs/cs-ndc.js +40 -25
- package/tx/cs/cs-omop.js +54 -29
- package/tx/cs/cs-rxnorm.js +300 -196
- package/tx/cs/cs-snomed.js +861 -95
- package/tx/cs/cs-ucum.js +14 -4
- package/tx/cs/cs-unii.js +18 -14
- package/tx/cs/cs-virtual.js +210 -0
- package/tx/ecosystem-resolver.js +413 -0
- package/tx/html/cluster-dash-metrics.liquid +26 -0
- package/tx/html/cluster-home-metrics.liquid +31 -0
- package/tx/html/cluster-metrics-script.liquid +251 -0
- package/tx/html/codesystem-operations.liquid +3 -3
- package/tx/html/ecl-panel.liquid +1 -1
- package/tx/html/external-metrics.liquid +17 -0
- package/tx/html/operations-form.liquid +17 -17
- package/tx/html/search-form.liquid +11 -11
- package/tx/html/status-line.liquid +58 -0
- package/tx/html/status-panel.liquid +140 -0
- package/tx/html/status-tasks.liquid +25 -0
- package/tx/html/tx-template.html +2 -5
- package/tx/importers/atc-to-fhir.js +17 -16
- package/tx/importers/export-icd11-codesystem.js +3 -2
- package/tx/importers/import-icd11.js +4 -3
- package/tx/importers/import-loinc.module.js +118 -56
- package/tx/importers/import-ndc.module.js +56 -44
- package/tx/importers/import-rxnorm.module.js +118 -79
- package/tx/importers/import-sct.module.js +125 -61
- package/tx/importers/import-unii.module.js +37 -36
- package/tx/importers/subset-loinc.module.js +49 -48
- package/tx/importers/subset-rxnorm.module.js +29 -28
- package/tx/importers/terminal.js +18 -0
- package/tx/importers/tx-import-base.js +13 -12
- package/tx/importers/tx-import-settings.js +5 -4
- package/tx/importers/tx-import.js +53 -52
- package/tx/library/canonical-resource.js +49 -0
- package/tx/library/codesystem.js +94 -5
- package/tx/library/designations.js +45 -2
- package/tx/library/extensions.js +13 -7
- package/tx/library/implicit-valuesets.js +66 -0
- package/tx/library/renderer.js +77 -21
- package/tx/library/sqlite-utilities.js +2 -0
- package/tx/library/tho-precedence.js +40 -0
- package/tx/library/ucum-parsers.js +11 -1
- package/tx/library/wait-for-cache.js +43 -0
- package/tx/library.js +321 -22
- package/tx/openapi-operations.js +6 -4
- package/tx/operation-context.js +460 -99
- package/tx/params.js +25 -0
- package/tx/problems.js +3 -5
- package/tx/provider.js +314 -67
- package/tx/resource-cache-sqlite.js +1050 -0
- package/tx/sct/documentation.md +45 -21
- package/tx/sct/ecl.js +81 -17
- package/tx/sct/editions.js +39 -0
- package/tx/sct/expressions.js +10 -1
- package/tx/sct/load-config.js +107 -0
- package/tx/sct/mmap.js +109 -0
- package/tx/sct/structures.js +175 -15
- package/tx/sct/text-index.js +5 -1
- package/tx/syndication/syndication-feed.js +2 -2
- package/tx/tx-html.js +44 -8
- package/tx/tx.fhir.org.yml +8 -8
- package/tx/tx.js +282 -80
- package/tx/usage-tracker.js +39 -11
- package/tx/vs/vs-api.js +19 -0
- package/tx/vs/vs-database.js +386 -62
- package/tx/vs/vs-package.js +44 -17
- package/tx/vs/vs-vsac.js +649 -101
- package/tx/workers/batch-validate.js +37 -10
- package/tx/workers/batch.js +6 -1
- package/tx/workers/cache-control.js +15 -4
- package/tx/workers/closure.js +156 -13
- package/tx/workers/compare.js +8 -5
- package/tx/workers/expand.js +1173 -289
- package/tx/workers/metadata.js +35 -0
- package/tx/workers/search.js +53 -1
- package/tx/workers/supplement-filters.js +145 -0
- package/tx/workers/translate.js +169 -4
- package/tx/workers/validate.js +223 -119
- package/tx/workers/worker.js +123 -31
- package/tx/xversion/xv-valueset.js +7 -4
- package/utilities/submit-test-report.js +3 -1
- package/utilities/tx-stress-test.js +482 -0
- package/vcl/readme.md +37 -0
- package/vcl/vcl-parser.js +15 -0
- package/xig/readme.md +52 -0
- package/xig/xig-template.html +5 -8
- package/xig/xig.js +238 -422
- package/changelog-template.md +0 -22
- package/registry/test-runner.js +0 -237
- package/release.sh +0 -80
- package/test-scripts/repro-re2-wasm-leak.js +0 -34
- package/tsconfig.eslint.json +0 -9
- package/tx/html/dash-metrics.liquid +0 -147
- package/tx/html/home-metrics.liquid +0 -225
package/CONFIGURATION.md
ADDED
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
# FHIRsmith Configuration
|
|
2
|
+
|
|
3
|
+
The server is configured by `config.json` in the data directory (see
|
|
4
|
+
[Data Directory](README.md#data-directory)), plus a few environment variables.
|
|
5
|
+
`config-template.json` is a starting point: it has every section, with comments, and every
|
|
6
|
+
module turned off - set `"enabled": true` on the ones you run. `config.json` is JSON, except that
|
|
7
|
+
it may have comments: `//` to the end of the line, and `/* ... */`.
|
|
8
|
+
|
|
9
|
+
Upgrading? See [Upgrading to 1.0.0](#upgrading-to-100).
|
|
10
|
+
|
|
11
|
+
The top level of `config.json` has the server-wide settings described here, and a
|
|
12
|
+
`modules` section with an entry for each module (see [Modules](#modules)).
|
|
13
|
+
|
|
14
|
+
## Server
|
|
15
|
+
|
|
16
|
+
Create a `config.json` file in your data directory (use `config-template.json` as a starting point):
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"hostName" : "[descriptive name for the server]",
|
|
21
|
+
"server": {
|
|
22
|
+
"port": 3000,
|
|
23
|
+
"cors": {
|
|
24
|
+
"origin": "*",
|
|
25
|
+
"credentials": true
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"modules": {
|
|
29
|
+
// per modules...
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
| Option | Default | Description |
|
|
35
|
+
|---|---|---|
|
|
36
|
+
| `server.maxBodyMB` | `50` | Largest request body accepted, in MB. A body is read whole into memory before it is parsed, so this bounds what one request can take. A bigger body gets a 413: an OperationOutcome (too-costly) on a tx endpoint, and the module's own handling elsewhere. The largest IG Publisher request seen on build.fhir.org was 1.39 MB, so 50 leaves plenty of room. The ips module reads its own bodies, with its own limit |
|
|
37
|
+
|
|
38
|
+
Behind nginx, nginx's `client_max_body_size` is checked first. If it is lower than `maxBodyMB`, nginx refuses a bigger body with its own 413 HTML page before FHIRsmith sees it, so set it at or above `maxBodyMB` to get FHIRsmith's OperationOutcome; if it is higher, `maxBodyMB` applies. Requests of over 100 MB have been seen, caused by client-side issues: choose `maxBodyMB` (default 50) and the nginx limit with that in mind. See [nginx.md](nginx.md).
|
|
39
|
+
|
|
40
|
+
### Memory
|
|
41
|
+
|
|
42
|
+
`server.memory` sets the memory guard: fractions of the memory limit (the cgroup limit, such
|
|
43
|
+
as `MemoryMax` on the systemd unit, or else the machine's RAM), measured against process RSS;
|
|
44
|
+
with a role, against the whole cgroup's private memory (see [cluster.md](cluster.md#memory)).
|
|
45
|
+
|
|
46
|
+
| Option | Default | Description |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| `server.memory.rejectFraction` | `0.85` | Above this, new requests get 503 + `Retry-After` |
|
|
49
|
+
| `server.memory.abortFraction` | `0.92` | Above this, running operations are aborted with 422 too-costly |
|
|
50
|
+
| `server.memory.trimAllocator` | `false`; `true` with a role | Whether the server returns the C allocator's free memory (`malloc_trim`, Linux) while refusing, and, with a role, once after loading. Without a role it is off unless set `true`; with one, `false` is for diagnosis. See [cluster.md](cluster.md#memory) |
|
|
51
|
+
|
|
52
|
+
### Cluster
|
|
53
|
+
|
|
54
|
+
To use more than one CPU core for terminology on one machine, a master and several tx
|
|
55
|
+
workers share the data directory and `config.json` (started by `node cluster.js`, or by hand
|
|
56
|
+
with `--role`). Their settings are in `server.cluster`, documented with the arrangement in
|
|
57
|
+
[cluster.md](cluster.md): the launcher's (`workers`, `maxOutstanding`, `queueSeconds`,
|
|
58
|
+
`recycleSeconds`, the fast lane, ...) under
|
|
59
|
+
[The launcher](cluster.md#the-launcher-clusterjs), and what the processes share
|
|
60
|
+
(`sharedCache`, `cacheAffinity`, `sharedCacheMaxMB`, `sharedClosure`) under
|
|
61
|
+
[Options](cluster.md#options). With no role, `server.cluster` is ignored.
|
|
62
|
+
The status panel's snapshot of every process (`statusSeconds`) is under
|
|
63
|
+
[Status](cluster.md#status).
|
|
64
|
+
|
|
65
|
+
### Statistics
|
|
66
|
+
|
|
67
|
+
`stats` sets the request counters and the graphs on `/` and `/dashboard`.
|
|
68
|
+
|
|
69
|
+
| Option | Default | Description |
|
|
70
|
+
|---|---|---|
|
|
71
|
+
| `stats.enabled` | `true` | `false`: the counters are kept in memory only |
|
|
72
|
+
| `stats.database` | `stats.db` | The counters' SQLite file, under the data folder's `databases` directory |
|
|
73
|
+
| `stats.intervalMinutes` | `10` | How often the counters are written to the database; also the graphs' sample interval, unless `sampleSeconds` is set (a server with no role, as before) |
|
|
74
|
+
| `stats.sampleSeconds` | `intervalMinutes`; with a role, 60 at most | How often the graphs take a sample. With a role (cluster.md), at most a minute unless set, so the graphs of a short session can be read. The graphs show 24 hours; under the launcher at most 1,440 samples a process, so with less than a minute they show less. The counters are still written every `intervalMinutes` |
|
|
75
|
+
|
|
76
|
+
## Logging
|
|
77
|
+
|
|
78
|
+
Add a `logging` section to `config.json` to control log behaviour. All fields are optional and have sensible defaults:
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"logging": {
|
|
83
|
+
"level": "info",
|
|
84
|
+
"console": true,
|
|
85
|
+
"consoleErrors": false,
|
|
86
|
+
"maxFiles": 14,
|
|
87
|
+
"maxSize": "50m",
|
|
88
|
+
"flushInterval": 2000,
|
|
89
|
+
"flushSize": 200
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
| Option | Default | Description |
|
|
95
|
+
|---|---|---|
|
|
96
|
+
| `level` | `"info"` | Minimum level to log: `error`, `warn`, `info`, `debug`, or `verbose` |
|
|
97
|
+
| `console` | `true` | Write log lines to stdout/stderr. Disable when running as a systemd service where console output goes to the journal and is redundant |
|
|
98
|
+
| `consoleErrors` | `false` | Whether `error` and `warn` levels appear on the console. When `false`, errors and warnings are written to the log file only |
|
|
99
|
+
| `maxFiles` | `14` | Number of daily log files to retain before old ones are deleted |
|
|
100
|
+
| `maxSize` | `0` (unlimited) | Maximum size per log file before rotation. Accepts human-readable strings: `"20m"`, `"1g"`, or a raw byte count |
|
|
101
|
+
| `flushInterval` | `2000` | Milliseconds between buffered writes to disk. Increase to reduce I/O under heavy load |
|
|
102
|
+
| `flushSize` | `200` | Number of buffered log lines that trigger an immediate flush regardless of the timer |
|
|
103
|
+
|
|
104
|
+
Log files are written to the `logs/` subdirectory of the data directory as `server-YYYY-MM-DD.log`. A `server.log` symlink always points to the current day's file, so `tail -f data/logs/server.log` tracks the active log without needing to know the date.
|
|
105
|
+
|
|
106
|
+
## Email and the Daily Report
|
|
107
|
+
|
|
108
|
+
The server can email a short markdown report on itself once a day. It needs two things in
|
|
109
|
+
`config.json`: an SMTP server to send through, and someone to send to:
|
|
110
|
+
|
|
111
|
+
```json
|
|
112
|
+
{
|
|
113
|
+
"email": {
|
|
114
|
+
"host": "smtp.example.org",
|
|
115
|
+
"port": 587,
|
|
116
|
+
"user": "fhirsmith",
|
|
117
|
+
"password": "...",
|
|
118
|
+
"from": "FHIRsmith <fhirsmith@example.org>"
|
|
119
|
+
},
|
|
120
|
+
"dailyReport": {
|
|
121
|
+
"to": ["ops@example.org"]
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
`user`/`password` are optional (an open relay); `secure` defaults to true for port 465 and
|
|
127
|
+
to STARTTLS otherwise. Without an `email` block nothing is emailed, and without
|
|
128
|
+
`dailyReport.to` there's no report (`dailyReport.enabled: false` turns it off explicitly).
|
|
129
|
+
|
|
130
|
+
The report, titled "`{hostName}` daily report", goes out at midnight (the server's local
|
|
131
|
+
time), or as soon as the server is up again if it was down at midnight. It has a paragraph
|
|
132
|
+
on the server's stability since the last report - how much of the time it was up, restarts,
|
|
133
|
+
the longest outage, and any upgrade (from the run history in the statistics database, so
|
|
134
|
+
`stats.enabled: false` leaves the uptime unknown); under the launcher (`cluster.js`), a
|
|
135
|
+
paragraph on the cluster - processes that exited or were recycled, how long they were
|
|
136
|
+
unavailable, and the requests the launcher refused or abandoned itself (see
|
|
137
|
+
[cluster.md](cluster.md#the-daily-report)); a paragraph from each running module that
|
|
138
|
+
has something to report (by default, none do); and a paragraph on the system - version,
|
|
139
|
+
Node.js and OS, how long this run has been up, the log files and the free disk space they're
|
|
140
|
+
drawing on, plus anything the npm audit check has found (packages with known vulnerabilities and
|
|
141
|
+
what to do about them, or a newer FHIRsmith release). If any background task's last run failed, a
|
|
142
|
+
final section lists them. When the last report was sent is kept in `daily-report.json` in the data
|
|
143
|
+
directory.
|
|
144
|
+
|
|
145
|
+
A module takes part by implementing `dailyReport({since, now})`, returning its paragraph as
|
|
146
|
+
markdown (or a promise of it); an empty return means it has nothing to say that day. The
|
|
147
|
+
request counts a module quotes come from `stats.countsSince(since, now)`, the per-operation
|
|
148
|
+
counts in the statistics database for the period. The modules that report:
|
|
149
|
+
|
|
150
|
+
| Module | Reports |
|
|
151
|
+
|---|---|
|
|
152
|
+
| Terminology server | how many of each operation were performed, over all its endpoints |
|
|
153
|
+
| Terminology server registry | client requests answered by the API, servers registered, and any server that answered none of the registry's scans in the period |
|
|
154
|
+
| Packages | packages served (tarball downloads) and new package versions found by the crawler |
|
|
155
|
+
| XIG | pages served, and whether the database could be accessed (and whether the last download failed) |
|
|
156
|
+
| Testing | pages served, test reports received, and the number held |
|
|
157
|
+
| SMART Health Links | QR codes created (SMART Health Links and Verifiable Health Links), link accesses, and the documents stored to serve them |
|
|
158
|
+
| IPS | pages served, IPS documents received, and the number stored |
|
|
159
|
+
| Publisher | publication runs started, and how many finished successfully |
|
|
160
|
+
|
|
161
|
+
## Environment Variables
|
|
162
|
+
|
|
163
|
+
| Variable | Description | Default |
|
|
164
|
+
|---|---|---|
|
|
165
|
+
| `FHIRSMITH_DATA_DIR` | Path to the data directory | `./data` |
|
|
166
|
+
| `PORT` | Server port (overrides config) | from config.json |
|
|
167
|
+
| `FHIRSMITH_ROLE` | `master` or `tx-worker`, as `--role` (see [cluster.md](cluster.md#roles)). Not set: an ordinary single server | none |
|
|
168
|
+
| `FHIRSMITH_INSTANCE_CODE` | This process's cache-id prefix, as `--instance-code` (see [cluster.md](cluster.md#roles)) | a master: `modules.tx.instanceCode`, and with none it stops with an error; a worker: none, and it stops with an error. The launcher gives `m0`, `tx1`, ... |
|
|
169
|
+
| `FHIRSMITH_WORKERS` | How many tx-workers `node cluster.js` starts, as `--workers` (`server.cluster.workers`) | from the CPUs and memory |
|
|
170
|
+
| `FHIRSMITH_CACHE_WAIT_MS` | How long a tx-worker waits for the master to build a cache it reads (see [cluster.md](cluster.md#what-runs-where)) | `300000` (5 minutes) |
|
|
171
|
+
| `NODE_ENV` | Node environment. Express and other libraries check it (in development mode, Express's error pages include stack traces). If it isn't set the server sets it to `production`, or to `development` when run with `npm run dev` | `production` |
|
|
172
|
+
|
|
173
|
+
## Modules
|
|
174
|
+
|
|
175
|
+
Each module has its own entry under `modules`, documented with the module:
|
|
176
|
+
|
|
177
|
+
| Module | Configuration |
|
|
178
|
+
|---|---|
|
|
179
|
+
| `tx` - terminology server | [tx/README.md](tx/README.md#configuration) |
|
|
180
|
+
| `registry` - terminology server registry | [registry/documentation/configuration.md](registry/documentation/configuration.md) |
|
|
181
|
+
| `packages` - package server | [packages/readme.md](packages/readme.md) |
|
|
182
|
+
| `shl` - SMART Health Links | [shl/readme.md](shl/readme.md) |
|
|
183
|
+
| `ips` - IPS documents | [ips/readme.md](ips/readme.md) |
|
|
184
|
+
| `testing` - test reports | [testing/readme.md](testing/readme.md) |
|
|
185
|
+
| `folder` | [folder/readme.md](folder/readme.md) |
|
|
186
|
+
| `npmprojector` | [npmprojector/readme.md](npmprojector/readme.md) |
|
|
187
|
+
| `token` | [token/security_guide.md](token/security_guide.md) |
|
|
188
|
+
| `xig` | [xig/readme.md](xig/readme.md) |
|
|
189
|
+
| `vcl` | [vcl/readme.md](vcl/readme.md) |
|
|
190
|
+
| `publisher` | [publisher/readme.md](publisher/readme.md) |
|
|
191
|
+
|
|
192
|
+
## Upgrading to 1.0.0
|
|
193
|
+
|
|
194
|
+
1.0.0 is a big upgrade from 0.17 and 0.18. Most servers won't need to change any settings, but
|
|
195
|
+
every operator should check these. Each item says who it affects; the [CHANGELOG](CHANGELOG.md)
|
|
196
|
+
has the detail.
|
|
197
|
+
|
|
198
|
+
### Every server
|
|
199
|
+
|
|
200
|
+
- **Node.js 24** or later (`engines` in package.json). After upgrading Node, `npm ci` (there
|
|
201
|
+
are new dependencies) - or `npm rebuild` for the native ones.
|
|
202
|
+
- **Start command**: `npm start` is now `node --expose-gc server.js`. A service that runs
|
|
203
|
+
`node server.js` still works (the memory guard sets the flag itself), but add `--expose-gc`.
|
|
204
|
+
`--port` or `--instance-code` without `--role` now stops the server with an error (they used
|
|
205
|
+
to be ignored): drop them from a single server's command line.
|
|
206
|
+
- **`NODE_ENV`** is `production` when it isn't set (`npm run dev`: `development`). Set it
|
|
207
|
+
yourself if you relied on development mode (Express's error pages with stack traces).
|
|
208
|
+
- **Keep-alive**: idle connections are kept for 65 s (was Node's 5 s), longer than nginx's
|
|
209
|
+
upstream `keepalive_timeout` (60 s by default). If you set nginx's higher, keep it under 65 s.
|
|
210
|
+
- **Memory guard** (new, on by default): above 85% of the memory limit (the cgroup's - systemd
|
|
211
|
+
`MemoryMax` - or else the machine's RAM) new requests get 503, and above 92% running
|
|
212
|
+
operations are aborted (422). If your memory limit is tight, check `server.memory` ([Memory](#memory)).
|
|
213
|
+
- **Request size**: `server.maxBodyMB` (default 50) is now a setting. nginx's
|
|
214
|
+
`client_max_body_size` must be at least as big, or clients get nginx's HTML 413 rather than an
|
|
215
|
+
OperationOutcome.
|
|
216
|
+
- **`config.json` may have comments** (`//` and `/* */`), and `config-template.json` now has
|
|
217
|
+
every module turned off.
|
|
218
|
+
- **New, optional**: `email` and `dailyReport.to` ([the daily report](#email-and-the-daily-report) -
|
|
219
|
+
nothing is sent without both), `npmAudit` (a periodic `npm audit` of the server; set
|
|
220
|
+
`"enabled": false` on a server with no internet access), `accessibility.checkPanel`,
|
|
221
|
+
`stats.sampleSeconds`.
|
|
222
|
+
- **Cluster mode** (`node cluster.js`, [cluster.md](cluster.md)) is new and opt-in: `server.js`
|
|
223
|
+
runs as before.
|
|
224
|
+
|
|
225
|
+
### tx (terminology server)
|
|
226
|
+
|
|
227
|
+
- **Expansion limits**: the defaults are now `externalLimit` 10000 (was 3000) and `internalLimit`
|
|
228
|
+
100000 (was 10000), and there's a new `walkLimit` (default 10 x `internalLimit`) for paging.
|
|
229
|
+
The three are checked at startup: one that isn't a whole number above 0, or
|
|
230
|
+
external <= internal <= walk not holding, **stops the server**. If you set any of them, check
|
|
231
|
+
them. Bigger expansions now succeed, so a busy server may use more memory.
|
|
232
|
+
- **Value sets with an exclude or an import are limited** like any other (they used to come
|
|
233
|
+
back whole, whatever their size): a client that expands a big one unpaged now gets a 422
|
|
234
|
+
too-costly, and should page it.
|
|
235
|
+
- **`Tools/Java` is no longer special**: the IG Publisher and the tx-ecosystem test runner get
|
|
236
|
+
the configured limits like any client (they used to be held to 3000/10000).
|
|
237
|
+
- **`x-too-costly-threshold`** can only lower the limit: a value above `internalLimit` is cut
|
|
238
|
+
down to it, and `0` (or anything that isn't a positive whole number) is ignored - it no
|
|
239
|
+
longer means "no limit".
|
|
240
|
+
- **Memory caps** with defaults (see the `Limits:` line in the startup log): `cacheMaxConcepts`,
|
|
241
|
+
`cacheMaxTotalConcepts`, `expansionCacheMaxCodes`, `usageTrackerMaxCodes`,
|
|
242
|
+
`usageTrackerMaxCodeLength`, `languageTagCacheSize`. A client may now get `cache-id-unknown`
|
|
243
|
+
(or 422) for a `$cache-control` cache that grew too big.
|
|
244
|
+
- **New, optional**: `snomed` (load SNOMED CT editions memory-mapped, or prewarmed - see
|
|
245
|
+
tx/README.md), and `ecosystem` (`$validate-code` for code systems held by other servers in
|
|
246
|
+
the terminology ecosystem; off by default).
|
|
247
|
+
- **`pruneTerminologyCache`** (new, default false): delete the databases, caches and packages
|
|
248
|
+
in `terminology-cache` that the library no longer uses. Turn it on for a server that has the
|
|
249
|
+
data directory to itself.
|
|
250
|
+
- **`instanceCode`** is checked at startup, and a cluster master needs one.
|
|
251
|
+
- **VSAC** (`vsacCfg`): the default `baseUrl` is https (an http one is logged as a warning);
|
|
252
|
+
value sets are read from the database when asked for, with a cache sized by `valueSetCacheMB`
|
|
253
|
+
(default 64); a value set version VSAC doesn't have is now not found.
|
|
254
|
+
- **Language packs**: a `lang-pack` or `extension-codes` supplement is used without being
|
|
255
|
+
referenced only when it is marked `codesystem-supplement-global` = `true`. The
|
|
256
|
+
`global-lang-pack` code is gone. If you load language packs, check they are marked.
|
|
257
|
+
- **Behaviour, with no setting**: `regex` filters match the whole value (LOINC regex value sets
|
|
258
|
+
may select fewer codes); ICD-11 codes are entity ids; a resource that both THO and a core
|
|
259
|
+
package provide is available in both versions; for LOINC answer lists, `answers-for` is the
|
|
260
|
+
filter (`LIST` still works, for backwards compatibility only); `$cache-control` caches are
|
|
261
|
+
never carried over a restart.
|
|
262
|
+
- **Rebuilds** (optional, for the new features): SNOMED CT caches for alternate identifiers and
|
|
263
|
+
concrete values, and any built in a time zone ahead of UTC (their effectiveTimes are a day
|
|
264
|
+
early); the LOINC database for its mappings, its Part translations (`PartName` designations,
|
|
265
|
+
from every linguistic variant) and without the blank answer code that externally defined
|
|
266
|
+
answer lists added. RxNorm's new index is added to an existing database at load. Coming from
|
|
267
|
+
0.16 or earlier, the package value set and concept map caches rebuild themselves once, so
|
|
268
|
+
the first start is slower.
|
|
269
|
+
|
|
270
|
+
### Other modules
|
|
271
|
+
|
|
272
|
+
- **registry**: `maxResponseMB` (default 100) limits what the crawler reads from a server. New,
|
|
273
|
+
optional: `oauth`, client credentials for servers that need a token to be scanned.
|
|
274
|
+
- **packages**: the crawler refuses packages over its new limits (`maxDownloadMB` 250,
|
|
275
|
+
`maxUnpackedMB` 4096, `maxFileMB` 50, `maxFiles` 250000); raise them only if a real package
|
|
276
|
+
is refused.
|
|
277
|
+
- **packages, signing** (on by default, `npmSigning`): the registry signs every version, so
|
|
278
|
+
`npm audit signatures` works against it. At the first start it makes its key,
|
|
279
|
+
`npm-signing-key.pem` next to the database (`npmSigning.keyFile`) - **back it up**: clients
|
|
280
|
+
check signatures against the published key - and signs the versions it already holds in the
|
|
281
|
+
background (`/packages/-/npm/v1/keys` is a 404 until it's done; progress in `/packages/status`).
|
|
282
|
+
Set `"enabled": false` to opt out.
|
|
283
|
+
- **packages, publishers' signatures**: `crawler.signatures` defaults to `check` (a signature
|
|
284
|
+
that fails is logged and the package stored anyway); `require` refuses unsigned packages and
|
|
285
|
+
doesn't read feeds that list no keys. Feeds' keys are in `package-feeds.json`.
|
|
286
|
+
- **packages, `/packages/feed-check`** (on by default, `feedCheck`): anyone can have the server
|
|
287
|
+
download and check a feed's packages (one run at a time, at most `maxItems` 50 and
|
|
288
|
+
`maxTotalMB` 500). Set `"enabled": false` if you don't want that on your server.
|
|
289
|
+
- **xig**: `POST /xig/update` only works when `updateToken` is set.
|
|
290
|
+
- **ext-tracker**: set `token` (the IG Publisher's) so only the publisher can submit.
|
|
291
|
+
- **token**: the JSON API takes the API key in a header (`Authorization: Bearer` or
|
|
292
|
+
`X-API-Key`), not the URL - clients must change. The session cookie is now `Secure` when the
|
|
293
|
+
request came over https, which behind nginx needs `X-Forwarded-Proto` (`cookieSecure`
|
|
294
|
+
overrides).
|
|
295
|
+
- **publisher**: the administrator's password is now `adminPassword` in the config (set at
|
|
296
|
+
every start). Without it, an administrator that still has the old fixed default password
|
|
297
|
+
(`admin123`) gets a random one at startup, which is logged - set `adminPassword`, or look in
|
|
298
|
+
the log.
|
|
299
|
+
- **ips**: to use a validator jar of your own, set `validator.jar`, rather than replacing
|
|
300
|
+
`bin/validator_cli.jar`. `validator.checkIpsCodes` is gone (validator 7.0.4 refuses it);
|
|
301
|
+
`validator.autoLoadPackages` (default true) lets the validator load the packages that define
|
|
302
|
+
extensions it doesn't know.
|
|
303
|
+
|
|
304
|
+
There are no manual data migrations: the databases that changed migrate themselves at startup.
|
|
305
|
+
|
package/LICENSE
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-2026, Health Intersections Pty Ltd and the FHIRsmith contributors
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
17
|
+
contributors may be used to endorse or promote products derived from
|
|
18
|
+
this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
CHANGED
|
@@ -32,12 +32,19 @@ These are not being actively developed at present.
|
|
|
32
32
|
## Planned
|
|
33
33
|
|
|
34
34
|
* R4/R6 interconverter
|
|
35
|
+
* Full RESTful server implementation
|
|
36
|
+
|
|
37
|
+
## Open Areas of Work
|
|
38
|
+
|
|
39
|
+
* How to handle expansions and validations of some kinds of invalid value sets
|
|
40
|
+
* more efficient CodeSystem implementations
|
|
41
|
+
* more work on internationalization of IPS documents and the IPS repository generally
|
|
35
42
|
|
|
36
43
|
## Summary Statement
|
|
37
44
|
|
|
38
45
|
* Maintainers: Grahame Grieve, Italo Macêdo, Josh Mandel, Jose Costa Teixeira
|
|
39
46
|
* Issues / Discussion: Use github issues
|
|
40
|
-
* License: BSD-3
|
|
47
|
+
* License: BSD-3-Clause (see [LICENSE](LICENSE))
|
|
41
48
|
* Contribution Policy: Make PRs. PRs have to pass all the tests
|
|
42
49
|
* Security Information: See [security.md](security.md)
|
|
43
50
|
|
|
@@ -51,23 +58,25 @@ in-build support for SSL, rate limiting etc. See [nginx.md](nginx.md) for how to
|
|
|
51
58
|
|
|
52
59
|
## Quick Start
|
|
53
60
|
|
|
54
|
-
There are
|
|
61
|
+
There are 5 executable programs:
|
|
55
62
|
* the server (`node server`)
|
|
63
|
+
* the cluster server (`node cluster`) - for high performance uses (see [cluster.md](cluster.md))
|
|
56
64
|
* the terminology importer (`node --max-old-space-size=8192 tx/importers/tx-import XXX`) - see [Doco](tx/importers/readme.md)
|
|
57
65
|
* the test cases (`npm test`)
|
|
58
66
|
* the test cases generater (`node tx/tests/testcases-generator.js`)
|
|
59
67
|
|
|
60
|
-
Unless you're developing, you only need the first
|
|
68
|
+
Unless you're developing, you only need the first three
|
|
61
69
|
|
|
62
70
|
FHIRsmith is open source - see below, and you're welcome to use it for any kind of use. Note,
|
|
63
|
-
though, that if you support FHIRsmith commercially as part of a managed service or product,
|
|
64
|
-
|
|
71
|
+
though, that if you support FHIRsmith commercially as part of a managed service or product,
|
|
72
|
+
and you seek support for your implementation from the project team, you are required to be a
|
|
73
|
+
Commercial Partner of HL7 - consult [The FHIR Product Director](mailto:fhir-director@hl7.org).
|
|
65
74
|
|
|
66
75
|
### Quick Start
|
|
67
76
|
|
|
68
77
|
* Install FHIRSmith (using docker, or an NPM release, or just get the code by git)
|
|
69
78
|
* Figure out the data directory
|
|
70
|
-
* Provide a configuration to tell the server what to run (see
|
|
79
|
+
* Provide a configuration to tell the server what to run (see [CONFIGURATION.md](CONFIGURATION.md), or use a [prebuilt configuration](configurations/readme.md))
|
|
71
80
|
* Run the server
|
|
72
81
|
|
|
73
82
|
For further details of these steps, read on
|
|
@@ -116,115 +125,17 @@ npm install
|
|
|
116
125
|
mkdir -p data data/logs
|
|
117
126
|
|
|
118
127
|
# Copy example configuration
|
|
119
|
-
cp config.
|
|
128
|
+
cp config-template.json data/config.json
|
|
120
129
|
|
|
121
|
-
# Edit configuration
|
|
130
|
+
# Edit configuration: every module is off until you set "enabled": true (comments are allowed)
|
|
122
131
|
nano data/config.json
|
|
123
132
|
```
|
|
124
133
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
### Basic Configuration
|
|
128
|
-
|
|
129
|
-
Create a `config.json` file in your data directory (use `config-template.json` as a starting point):
|
|
130
|
-
|
|
131
|
-
```json
|
|
132
|
-
{
|
|
133
|
-
"hostName" : "[descriptive name for the server]",
|
|
134
|
-
"server": {
|
|
135
|
-
"port": 3000,
|
|
136
|
-
"cors": {
|
|
137
|
-
"origin": "*",
|
|
138
|
-
"credentials": true
|
|
139
|
-
}
|
|
140
|
-
},
|
|
141
|
-
"modules": {
|
|
142
|
-
// per modules...
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### Logging Configuration
|
|
148
|
-
|
|
149
|
-
Add a `logging` section to `config.json` to control log behaviour. All fields are optional and have sensible defaults:
|
|
150
|
-
|
|
151
|
-
```json
|
|
152
|
-
{
|
|
153
|
-
"logging": {
|
|
154
|
-
"level": "info",
|
|
155
|
-
"console": true,
|
|
156
|
-
"consoleErrors": false,
|
|
157
|
-
"maxFiles": 14,
|
|
158
|
-
"maxSize": "50m",
|
|
159
|
-
"flushInterval": 2000,
|
|
160
|
-
"flushSize": 200
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
| Option | Default | Description |
|
|
166
|
-
|---|---|---|
|
|
167
|
-
| `level` | `"info"` | Minimum level to log: `error`, `warn`, `info`, `debug`, or `verbose` |
|
|
168
|
-
| `console` | `true` | Write log lines to stdout/stderr. Disable when running as a systemd service where console output goes to the journal and is redundant |
|
|
169
|
-
| `consoleErrors` | `false` | Whether `error` and `warn` levels appear on the console. When `false`, errors and warnings are written to the log file only |
|
|
170
|
-
| `maxFiles` | `14` | Number of daily log files to retain before old ones are deleted |
|
|
171
|
-
| `maxSize` | `0` (unlimited) | Maximum size per log file before rotation. Accepts human-readable strings: `"20m"`, `"1g"`, or a raw byte count |
|
|
172
|
-
| `flushInterval` | `2000` | Milliseconds between buffered writes to disk. Increase to reduce I/O under heavy load |
|
|
173
|
-
| `flushSize` | `200` | Number of buffered log lines that trigger an immediate flush regardless of the timer |
|
|
174
|
-
|
|
175
|
-
Log files are written to the `logs/` subdirectory of the data directory as `server-YYYY-MM-DD.log`. A `server.log` symlink always points to the current day's file, so `tail -f data/logs/server.log` tracks the active log without needing to know the date.
|
|
176
|
-
|
|
177
|
-
### Email and the Daily Report
|
|
178
|
-
|
|
179
|
-
The server can email a short markdown report on itself once a day. It needs two things in
|
|
180
|
-
`config.json`: an SMTP server to send through, and someone to send to:
|
|
181
|
-
|
|
182
|
-
```json
|
|
183
|
-
{
|
|
184
|
-
"email": {
|
|
185
|
-
"host": "smtp.example.org",
|
|
186
|
-
"port": 587,
|
|
187
|
-
"user": "fhirsmith",
|
|
188
|
-
"password": "...",
|
|
189
|
-
"from": "FHIRsmith <fhirsmith@example.org>"
|
|
190
|
-
},
|
|
191
|
-
"dailyReport": {
|
|
192
|
-
"to": ["ops@example.org"]
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
```
|
|
134
|
+
### Configuration
|
|
196
135
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
The report, titled "`{hostName}` daily report", goes out at midnight (the server's local
|
|
202
|
-
time), or as soon as the server is up again if it was down at midnight. It has a paragraph
|
|
203
|
-
on the server's stability since the last report - how much of the time it was up, restarts,
|
|
204
|
-
the longest outage, and any upgrade (from the run history in the statistics database, so
|
|
205
|
-
`stats.enabled: false` leaves the uptime unknown); a paragraph from each running module that
|
|
206
|
-
has something to report (by default, none do); and a paragraph on the system - version,
|
|
207
|
-
Node.js and OS, how long this run has been up, the log files and the free disk space they're
|
|
208
|
-
drawing on, plus anything the npm audit check has found (packages with known vulnerabilities and
|
|
209
|
-
what to do about them, or a newer FHIRsmith release). If any background task's last run failed, a
|
|
210
|
-
final section lists them. When the last report was sent is kept in `daily-report.json` in the data
|
|
211
|
-
directory.
|
|
212
|
-
|
|
213
|
-
A module takes part by implementing `dailyReport({since, now})`, returning its paragraph as
|
|
214
|
-
markdown (or a promise of it); an empty return means it has nothing to say that day. The
|
|
215
|
-
request counts a module quotes come from `stats.countsSince(since, now)`, the per-operation
|
|
216
|
-
counts in the statistics database for the period. The modules that report:
|
|
217
|
-
|
|
218
|
-
| Module | Reports |
|
|
219
|
-
|---|---|
|
|
220
|
-
| Terminology server | how many of each operation were performed, over all its endpoints |
|
|
221
|
-
| Terminology server registry | client requests answered by the API, servers registered, and any server that answered none of the registry's scans in the period |
|
|
222
|
-
| Packages | packages served (tarball downloads) and new package versions found by the crawler |
|
|
223
|
-
| XIG | pages served, and whether the database could be accessed (and whether the last download failed) |
|
|
224
|
-
| Testing | pages served, test reports received, and the number held |
|
|
225
|
-
| SMART Health Links | QR codes created (SMART Health Links and Verifiable Health Links), link accesses, and the documents stored to serve them |
|
|
226
|
-
| IPS | pages served, IPS documents received, and the number stored |
|
|
227
|
-
| Publisher | publication runs started, and how many finished successfully |
|
|
136
|
+
The server reads `config.json` from the data directory. See [CONFIGURATION.md](CONFIGURATION.md)
|
|
137
|
+
for the server settings (port, body size, logging, email and the daily report), the environment
|
|
138
|
+
variables, and where each module's own settings are documented.
|
|
228
139
|
|
|
229
140
|
### Start the Server
|
|
230
141
|
|
|
@@ -237,9 +148,10 @@ npm start
|
|
|
237
148
|
```
|
|
238
149
|
|
|
239
150
|
The server will be available at `http://localhost:{port}` using the port specified in the config.
|
|
240
|
-
In the production servers listed above, the server always
|
|
151
|
+
In the production servers listed above, the server should always sit behind an NGINX server which manages
|
|
241
152
|
SSL, security, rate limiting etc. See [nginx.md](nginx.md) for configuration advice, including
|
|
242
|
-
running several servers behind one front door.
|
|
153
|
+
running several servers behind one front door. To use more than one CPU core for terminology on
|
|
154
|
+
one machine, see [cluster.md](cluster.md): a master and several tx workers, behind nginx.
|
|
243
155
|
|
|
244
156
|
## Testing
|
|
245
157
|
|
|
@@ -274,6 +186,9 @@ Or run it inline:
|
|
|
274
186
|
FHIRSMITH_DATA_DIR=/var/lib/fhirsmith fhirsmith
|
|
275
187
|
```
|
|
276
188
|
|
|
189
|
+
For cluster mode (a master and tx-workers - see [cluster.md](cluster.md)), run `fhirsmith-cluster`
|
|
190
|
+
instead of `fhirsmith`.
|
|
191
|
+
|
|
277
192
|
### Changing the Node.js version
|
|
278
193
|
|
|
279
194
|
Some of FHIRsmith's dependencies (the SQLite drivers) are native modules, built for the
|
|
@@ -309,14 +224,6 @@ Available tags:
|
|
|
309
224
|
- `vX.Y.Z`: Specific version (e.g., `v1.0.0`)
|
|
310
225
|
- `cibuild`: Latest build from the main branch
|
|
311
226
|
|
|
312
|
-
### Environment Variables
|
|
313
|
-
|
|
314
|
-
| Variable | Description | Default |
|
|
315
|
-
|---|---|---|
|
|
316
|
-
| `FHIRSMITH_DATA_DIR` | Path to the data directory | `./data` |
|
|
317
|
-
| `PORT` | Server port (overrides config) | from config.json |
|
|
318
|
-
| `NODE_ENV` | Node environment | `production` |
|
|
319
|
-
|
|
320
227
|
### Windows Installation
|
|
321
228
|
|
|
322
229
|
You can install as a windows service using [windows-install.js](utilities/windows-install.js). You might need to
|
|
@@ -420,7 +327,7 @@ or do it via a PR
|
|
|
420
327
|
./release.sh X.Y.Z
|
|
421
328
|
```
|
|
422
329
|
|
|
423
|
-
`
|
|
330
|
+
`release.sh` checks that the release is ready - on `main` and pushed, the three versions in
|
|
424
331
|
`package.json` and `package-lock.json` match, `CHANGELOG.md` has a dated section with the
|
|
425
332
|
conformance statement, and `test-cases-report.json` passed, is from this version and is
|
|
426
333
|
newer than the last code change - then submits the report to
|
|
@@ -448,7 +355,7 @@ or do it via a PR
|
|
|
448
355
|
|
|
449
356
|
## License
|
|
450
357
|
|
|
451
|
-
[BSD-3](https://opensource.org/license/bsd-3-clause)
|
|
358
|
+
[BSD-3-Clause](LICENSE) - see also [opensource.org](https://opensource.org/license/bsd-3-clause)
|
|
452
359
|
|
|
453
360
|
## Contributing
|
|
454
361
|
|