Skip to content

Commit dffc59c

Browse files
skylightis666claude
andcommitted
Add required OAuth env vars to frontend configuration docs
Document AIDBOX_CLIENT_ID and AIDBOX_CLIENT_SECRET as required frontend environment variables. Without them users get "Client is not configured for authorization code" error on login. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 69ba703 commit dffc59c

6 files changed

Lines changed: 478 additions & 1 deletion

SUMMARY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
* [Configure MDM module](configure-mdm-module.md)
66
* [Find duplicates: $match](find-duplicates-match.md)
77
* [Merging and Unmerging Records: $merge and $unmerge](merging-and-unmerging-records-usdmerge-and-usdunmerge.md)
8+
* [Configure Merge View](configure-merge-view.md)
9+
* [Custom SQL Operations](custom-sql-operations.md)
810
* [RBAC configuration](rbac.md)
911
* [Matching Model Explanation](matching-model-explanation.md)
1012
* [Mathematical Details](mathematical-details.md)

docs/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ Configure the MDM module to use a matching model stored in the MDM server (backe
6464

6565
Use `$match` operation to find duplicates
6666

67+
{% content-ref url="find-duplicates-match.md" %}
68+
[find-duplicates-match.md](find-duplicates-match.md)
69+
{% endcontent-ref %}
6770

6871
## Merge and Unmerge Records
6972

docs/configure-mdm-module.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ grant_types:
3434
- code
3535
```
3636
37+
Then configure the frontend service with the matching client credentials:
38+
39+
```bash
40+
AIDBOX_CLIENT_ID=mpi-dev
41+
AIDBOX_CLIENT_SECRET=pass
42+
```
43+
44+
{% hint style="warning" %}
45+
These two environment variables are **required** for the MDM frontend to authenticate via OAuth. Without them, users will see a "Client is not configured for authorization code" error when trying to log in.
46+
{% endhint %}
47+
3748
## Add admin privileges to your user
3849

3950
Navigate to: **Aidbox → IAM → Users → Your Admin**

docs/configure-merge-view.md

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
# Configure Merge View
2+
3+
By default, the merge UI displays a fixed set of patient fields (ID, name, gender, birth date). The **MergeViewModel** feature lets you customize which fields appear in the merge view — and in what order — without changing any code.
4+
5+
A MergeViewModel is a database record containing an ordered list of field descriptors. Each field has a human-readable **label** and a **JSONPath expression** that tells the system how to read and write values from FHIR Patient resources.
6+
7+
## How it works
8+
9+
1. You create a `MergeViewModel` record in the database with the desired field configuration.
10+
2. You set the `MERGE_VIEW_MODEL_ID` environment variable to the record's ID.
11+
3. When a clinician opens the merge UI, the system loads the configured fields and renders them instead of the defaults.
12+
13+
If the environment variable is not set or the record is not found, the system falls back to the default field list automatically.
14+
15+
## Environment variable
16+
17+
| Variable | Required | Default | Description |
18+
|----------|----------|---------|-------------|
19+
| `MERGE_VIEW_MODEL_ID` | No || ID of the MergeViewModel record to use. If unset, the default fields are shown. |
20+
21+
## Create a MergeViewModel
22+
23+
Insert a record directly into the database:
24+
25+
```sql
26+
INSERT INTO mpi.mergeviewmodel (id, version, resource)
27+
VALUES (
28+
'my-merge-view',
29+
1,
30+
'{
31+
"id": "my-merge-view",
32+
"name": "Custom Merge View",
33+
"fields": [
34+
{ "label": "ID", "path": "$.id" },
35+
{ "label": "First Name", "path": "$.name[0].given[0]" },
36+
{ "label": "Last Name", "path": "$.name[0].family" },
37+
{ "label": "Gender", "path": "$.gender" },
38+
{ "label": "Birth Date", "path": "$.birthDate" },
39+
{ "label": "Phone", "path": "$.telecom[?(@.system==\"phone\")].value" },
40+
{ "label": "Email", "path": "$.telecom[?(@.system==\"email\")].value" }
41+
]
42+
}'::jsonb
43+
);
44+
```
45+
46+
Then set the environment variable for the MDM **frontend** service:
47+
48+
```bash
49+
MERGE_VIEW_MODEL_ID=my-merge-view
50+
```
51+
52+
After restarting the service, the merge UI will display the configured fields.
53+
54+
## Field descriptor format
55+
56+
Each entry in the `fields` array has two properties:
57+
58+
| Property | Type | Description |
59+
|----------|------|-------------|
60+
| `label` | string | Display name shown in the merge UI |
61+
| `path` | string | JSONPath expression for reading and writing the value |
62+
63+
The same JSONPath expression is used for both **reading** the value from each patient and **writing** the selected value into the merge result. The order of fields in the array determines the display order in the UI.
64+
65+
## Supported JSONPath expressions
66+
67+
Field paths use [JSONPath](https://goessner.net/articles/JsonPath/) syntax compatible with the `jsonpath-plus` library. Examples:
68+
69+
| Path | Description |
70+
|------|-------------|
71+
| `$.id` | Patient ID |
72+
| `$.name[0].given[0]` | First given name |
73+
| `$.name[0].given[1]` | Second given name (middle name) |
74+
| `$.name[0].family` | Family name |
75+
| `$.gender` | Gender |
76+
| `$.birthDate` | Date of birth |
77+
| `$.address[0].line[0]` | First address line |
78+
| `$.address[0].line[1]` | Second address line |
79+
| `$.address[0].city` | City |
80+
| `$.address[0].state` | State |
81+
| `$.address[0].postalCode` | ZIP / postal code |
82+
| `$.telecom[?(@.system=="phone")].value` | Phone number (filter expression) |
83+
| `$.telecom[?(@.system=="email")].value` | Email address (filter expression) |
84+
85+
{% hint style="info" %}
86+
Filter expressions like `[?(@.system=="phone")]` let you target specific entries in arrays based on a condition, rather than relying on a fixed array index.
87+
{% endhint %}
88+
89+
## Default fields
90+
91+
When no MergeViewModel is configured, the system uses the following default fields:
92+
93+
| Label | Path |
94+
|-------|------|
95+
| ID | `$.id` |
96+
| First Name | `$.name[0].given[0]` |
97+
| Second Name | `$.name[0].given[1]` |
98+
| Last Name | `$.name[0].family` |
99+
| Gender | `$.gender` |
100+
| Birth Date | `$.birthDate` |
101+
102+
## Merge UI behavior
103+
104+
The merge view displays each configured field as a row with values from both patient records:
105+
106+
- If both patients have the **same value** for a field, it is displayed without a selection control.
107+
- If the values **differ**, radio buttons allow the clinician to pick which value to keep in the merged result.
108+
- If a JSONPath expression resolves to **no value** in one or both patients, an empty string is shown.
109+
110+
The clinician can also select an entire patient column at once using the header radio buttons, which copies all field values from that patient into the merge result.
111+
112+
## Update a MergeViewModel
113+
114+
To change the field configuration, update the record in the database:
115+
116+
```sql
117+
UPDATE mpi.mergeviewmodel
118+
SET resource = '{
119+
"id": "my-merge-view",
120+
"name": "Updated Merge View",
121+
"fields": [
122+
{ "label": "ID", "path": "$.id" },
123+
{ "label": "First Name", "path": "$.name[0].given[0]" },
124+
{ "label": "Last Name", "path": "$.name[0].family" },
125+
{ "label": "Birth Date", "path": "$.birthDate" }
126+
]
127+
}'::jsonb,
128+
version = version + 1
129+
WHERE id = 'my-merge-view';
130+
```
131+
132+
Changes take effect on the next merge page load — no redeployment is required.
133+
134+
## Database schema
135+
136+
The MergeViewModel is stored in two tables:
137+
138+
**`mpi.mergeviewmodel`** — active configuration:
139+
140+
| Column | Type | Description |
141+
|--------|------|-------------|
142+
| `id` | `text` (PK) | Unique identifier |
143+
| `version` | `integer` | Incremented on each update |
144+
| `cts` | `timestamptz` | Created / last updated timestamp |
145+
| `resource` | `jsonb` | Configuration including the `fields` array |
146+
147+
**`mpi.mergeviewmodel_history`** — audit trail of previous versions:
148+
149+
| Column | Type | Description |
150+
|--------|------|-------------|
151+
| `id` | `text` | Record identifier |
152+
| `version` | `integer` | Version number |
153+
| `cts` | `timestamptz` | Timestamp of this version |
154+
| `resource` | `jsonb` | Configuration snapshot |
155+
| | | UNIQUE (`id`, `version`) |

0 commit comments

Comments
 (0)