Add audit routing fields to patient and SQL logs - #3267
Queued
jerome-ng wants to merge 4 commits into
Queued
Conversation
5 tasks
jerome-ng
marked this pull request as ready for review
September 7, 2026 02:21
jerome-ng
requested review from
SantanM,
csafreen,
khairul-syazwan,
maggie-li-yd,
p-hoffmann and
suwarnoong
as code owners
September 7, 2026 02:21
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
The focused implementation is consistent across both audit paths and adequately covered by regression tests.
Pull request overview
Adds standardized routing metadata to analytics audit events while preserving existing payloads and output behavior.
Changes:
- Adds routing fields to patient-access and CDM SQL events.
- Adds console/file format regression tests.
- Documents audit configuration and output format.
File summaries
| File | Description |
|---|---|
README.md |
Links to audit documentation. |
plugins/functions/analytics-svc/README.md |
Documents audit fields, configuration, and tests. |
plugins/functions/analytics-svc/src/utils/AuditEventWriter.ts |
Adds patient-event routing fields. |
plugins/functions/analytics-svc/src/utils/CdmSqlAuditLogger.ts |
Adds SQL-event routing fields. |
plugins/functions/analytics-svc/src/utils/AuditLogFormat_test.ts |
Verifies payload and NDJSON preservation. |
Review details
- Files reviewed: 5/5 changed files
- Comments generated: 0
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
maggie-li-yd
approved these changes
Sep 7, 2026
jerome-ng
enabled auto-merge
September 10, 2026 06:29
jerome-ng
added this pull request to the merge queue
Sep 10, 2026
Any commits made after this event will not be merged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Patient-access and CDM SQL audit events now include three top-level fields used to identify audit records and their source:
{"log-type":"audit","audit-log-type":"access","service-name":"analytics-svc"}Both logger types use
access, including failed SQL executions. All existing payload field names, values, and nesting are preserved. Audit enablement flags, NDJSON file output, and theAUDIT_LOG_TO_CONSOLEdestination switch behave as before.Example JSON
These events were captured from authenticated requests to this PR branch on the local demo database. Only
personIdandactor.idhave been replaced with example values. JSON is formatted here for readability; the console emitted each event as a single JSON line.The
raw-audit-...values are correlation labels explicitly supplied in the test requests'x-req-correlation-idheaders. They are not generated UUIDs; the logger preserves the incoming correlation ID.Patient access
{ "action": "read", "occurredAt": "2026-09-07T03:04:05.795Z", "personId": "example-patient", "accessChannel": "D2E Pt Ls", "successful": true, "attributes": [ "patient.attributes.Gender_concept_name" ], "configs": { "cohortBuilder": { "id": "4fce3cb7-32bf-4b46-8cba-32e4f77a14dd", "version": "A" }, "cdm": { "id": "e10f83a0-ade9-4a33-90ae-cf760813943c", "version": "3" } }, "log-type": "audit", "audit-log-type": "access", "service-name": "analytics-svc", "schemaVersion": 1, "eventType": "patient.access", "actor": { "type": "user", "id": "example-user" } }SQL query for patient access
{ "log-type": "audit", "audit-log-type": "access", "service-name": "analytics-svc", "schemaVersion": 1, "eventType": "cdm.sql", "occurredAt": "2026-09-07T03:04:05.792Z", "actor": { "type": "user", "id": "example-user" }, "request": { "method": "GET", "path": "/analytics-svc/api/services/patient", "correlationId": "raw-audit-develop-patient-access", "query": { "mriquery": "eJyNkU1LAzEQhv+KzDkr3W60bW5qUbyoiHiRIrPJpAZ2kzWZLUrZ/y5ZP4oW0Vs+3nnyzGQLBhkT8aUBBZU+OjqeLmxhJ1gVktAW81JSMZGLekE4NdKUIECHpxB5SdZ5xy54UFvQwVu3XiLjbjcypdVU6XpWVNPaFrKWx8Vc11hUU5J2NsNSGjMyc8U9xTQC4QQGARqjSR88Js+gHvbW1q1vkJ9AQYfs8oUA5xOj13TVtzVFUJPd0eXyW9JjS6DgFJPTB6N9jqJmtyFQFptEAvi1y6Fz1zDFM4zZF5mjq3umH36rr/hpCA2hPwue0XmKICB0ubOrZe4NzSb73LmW3sGgfN80w9+A61v4R+rzmZdsmLXWPUZDBhTHngQ0rnUMqhQQrE3E45R0aPrWp19ne7hr+7BzeQ4hmqwOICDRM6jJIP4uvSBvKD7q4DV1/Dh+wj6qHFbD8AYkrd8/", "datasetId": "3c55629f-f0a3-4eaf-814e-049b9ea2d4d1" }, "params": {}, "body": {} }, "database": { "engine": "duckdb", "dialect": "postgresql", "code": "demo_database", "schema": "demo_cdm" }, "operation": "executeQuery", "sql": "WITH patientDEF AS (SELECT P0.\"GENDER_CONCEPT_ID\" AS \"06242c43\", P0.\"person_id\" AS \"fff367b7\" FROM memory.main.\"MRI_PLUGIN_3050ba0523eac439f1e99f612a8e5bfb79f952de6c186295\" P0 GROUP BY P0.\"GENDER_CONCEPT_ID\", P0.\"person_id\") SELECT * FROM patientDEF", "parameterCount": 0, "successful": true, "durationMs": 5.908, "datasetId": "3c55629f-f0a3-4eaf-814e-049b9ea2d4d1", "configs": { "cohortBuilder": { "id": "4fce3cb7-32bf-4b46-8cba-32e4f77a14dd", "version": "A" }, "cdm": { "id": "e10f83a0-ade9-4a33-90ae-cf760813943c", "version": "3" } } }SQL query for ID-only access
{ "log-type": "audit", "audit-log-type": "access", "service-name": "analytics-svc", "schemaVersion": 1, "eventType": "cdm.sql", "occurredAt": "2026-09-07T03:04:06.429Z", "actor": { "type": "user", "id": "example-user" }, "request": { "method": "GET", "path": "/analytics-svc/api/services/patient", "correlationId": "raw-audit-develop-patient-id-only", "query": { "mriquery": "eJyNkMtOwzAQRX8FzTqp0sZ9eUdbIXVTEEJsEIuJPW4tJXawJxWoyr8jh0cFCMHOj+vjc+cEGhkj8VaDhFJNp7PJ0uSmwDIXhCZfjAXlhVhWS8KJFnoMGSh/8IE3ZKyzbL0DeQLlnbH7DTKedwNTGEWlquZ5OalMLioxyxeqwryckDDzOY6F1gMzvbinEAcgXEKfgcKg4zuPyTHIhx9rY/c3yAeQ0CLbdJGBdZHRKdp1TUUBZHE+2m6+JB02BBJWGK26GOxTFBXbI4E0WEfKgF/aFLqyNVNYY0i+yBxs1TF983v8jK+8rwnd2jtG6yhABr5NzXab1A31Mfnc2YbewCBdV9f934DrW/hH6uOb52SYtPYdBk0aJIeOMqhtYxnkOANvTCQepqR83TUu/jrb0bn2qLVpDj7opA6QQaQnkEX/2PevdvXE8A==", "datasetId": "3c55629f-f0a3-4eaf-814e-049b9ea2d4d1" }, "params": {}, "body": {} }, "database": { "engine": "duckdb", "dialect": "postgresql", "code": "demo_database", "schema": "demo_cdm" }, "operation": "executeQuery", "sql": "WITH patientDEF AS (SELECT P0.\"person_id\" AS \"057de8c4\" FROM memory.main.\"MRI_PLUGIN_999e970e53fa09fce0b8b290f95ecaa378c04a75b6eb6d83\" P0 GROUP BY P0.\"person_id\") SELECT * FROM patientDEF", "parameterCount": 0, "successful": true, "durationMs": 2.854, "datasetId": "3c55629f-f0a3-4eaf-814e-049b9ea2d4d1", "configs": { "cohortBuilder": { "id": "4fce3cb7-32bf-4b46-8cba-32e4f77a14dd", "version": "A" }, "cdm": { "id": "e10f83a0-ade9-4a33-90ae-cf760813943c", "version": "3" } } }SQL query for an empty patient list
{ "log-type": "audit", "audit-log-type": "access", "service-name": "analytics-svc", "schemaVersion": 1, "eventType": "cdm.sql", "occurredAt": "2026-09-07T03:04:06.788Z", "actor": { "type": "user", "id": "example-user" }, "request": { "method": "GET", "path": "/analytics-svc/api/services/patient", "correlationId": "raw-audit-develop-empty-patient-list", "query": { "mriquery": "eJyNkU9LxDAQxb+KzDmVdhtdNzfdRfGiIuJFRKbJZDfQJjWZiiL97pL6Z9FFNKdJ8vLLezOvYJAxEZ8bUFDrg4PD2cIWtsS6kIS2OKokFaVcNAvCmZGmAgE6bELkFVnnHbvgQb2CDt669QoZt7uJKa2mWjfzop41tpCNPCyOdINFPSNp53OspDETM7+4pZgmIBzDKEBjNOmDx+QZ1N1Obd36CnkDCnpkly8EOJ8YvaaLoWsogiq3R+erb0qPHYGCE0xO703usxQ1uycCZbFNJIBf+iw6dS1TXGLMfpE5umZg+uHv/kt+EkJL6JfBMzpPEQSEPie7WOVsaJ6ynxvX0TsYlB/advwbcHkN/1B9fvOcHWZb6wGjIQOK40ACWtc5BlUJCNYmymX5sfI02qHz6dce72/j7/cu9yNEkyMACEj0CKocxd9Pz8gbig86eE09P0zD2EVV4/04vgFpBODA", "datasetId": "3c55629f-f0a3-4eaf-814e-049b9ea2d4d1" }, "params": {}, "body": {} }, "database": { "engine": "duckdb", "dialect": "postgresql", "code": "demo_database", "schema": "demo_cdm" }, "operation": "executeQuery", "sql": "WITH patientDEF AS (SELECT P0.\"GENDER_CONCEPT_ID\" AS \"f420b384\", P0.\"person_id\" AS \"4ff8237e\" FROM memory.main.\"MRI_PLUGIN_b766b9b83a45588a847f73b8c8d35c32d1529d4f24cdfcf3\" P0 GROUP BY P0.\"GENDER_CONCEPT_ID\", P0.\"person_id\") SELECT * FROM patientDEF", "parameterCount": 0, "successful": true, "durationMs": 1.435, "datasetId": "3c55629f-f0a3-4eaf-814e-049b9ea2d4d1", "configs": { "cohortBuilder": { "id": "4fce3cb7-32bf-4b46-8cba-32e4f77a14dd", "version": "A" }, "cdm": { "id": "e10f83a0-ade9-4a33-90ae-cf760813943c", "version": "3" } } }Failed SQL execution (invalid negative limit)
{ "log-type": "audit", "audit-log-type": "access", "service-name": "analytics-svc", "schemaVersion": 1, "eventType": "cdm.sql", "occurredAt": "2026-09-07T03:04:07.148Z", "actor": { "type": "user", "id": "example-user" }, "request": { "method": "GET", "path": "/analytics-svc/api/services/patient", "correlationId": "raw-audit-develop-invalid-negative-limit", "query": { "mriquery": "eJyNkU1LxDAQhv+KzDmR7Ta6bm7qonhREfEiItNksgbapCZTUaT/XVI/Fl1Eb/l458kzk1ewyJiJzyxoqM3e3v586aSbYS0VoZMHlSI5U8tmSTi3ylYgwMSHmHhFzgfPPgbQr2BicH69QsbNbmIqZ6g2zULW88ZJ1ah9eWAalPWclFsssFLWTsxScUMpT0A4hFGAwWTzB48pMOjbrbXz60vkB9DQI/tyIcCHzBgMnQ9dQwn0bHN0tvqWDNgRaDjC7M3OZF+iaNg/EWiHbSYB/NKX0IlvmdIxpuKLzMk3A9MPv7uv+FGMLWE4joHRB0ogIPals/NV6Q3tU/G59h29g0GHoW3HvwEXV/CP1Oczz8WwaK0HTJYsaE4DCWh95xm0rARE5zLxNCYT26EL+dfh7m763u19GURMtrgDCMj0CHo2ir9LTylYSvcmBkM930+/sI2qxrtxfAPpPN9s", "datasetId": "3c55629f-f0a3-4eaf-814e-049b9ea2d4d1" }, "params": {}, "body": {} }, "database": { "engine": "duckdb", "dialect": "postgresql", "code": "demo_database", "schema": "demo_cdm" }, "operation": "executeUpdate", "sql": "INSERT INTO memory.main.\"MRI_PLUGIN_80f1d59662a1207515107ac20fd6daf89575dd598bb52fb9\"\n \n SELECT \"pTable\".*\n FROM (\n SELECT \"62118ca8\" FROM (SELECT P0.\"person_id\" AS \"62118ca8\" FROM $$SCHEMA$$.\"person\" P0 GROUP BY P0.\"person_id\" LIMIT -1 OFFSET 0) AS alias2\n ) AS alias1\n JOIN $$SCHEMA$$.\"person\" \"pTable\"\n ON \"62118ca8\" = \"pTable\".\"person_id\"", "parameterCount": 2, "successful": false, "durationMs": 23.417, "datasetId": "3c55629f-f0a3-4eaf-814e-049b9ea2d4d1", "configs": { "cohortBuilder": { "id": "4fce3cb7-32bf-4b46-8cba-32e4f77a14dd", "version": "A" }, "cdm": { "id": "e10f83a0-ade9-4a33-90ae-cf760813943c", "version": "3" } }, "error": { "name": "Error" } }SQL query for CDM version
{ "log-type": "audit", "audit-log-type": "access", "service-name": "analytics-svc", "schemaVersion": 1, "eventType": "cdm.sql", "occurredAt": "2026-09-07T03:04:07.408Z", "actor": { "type": "user", "id": "example-user" }, "request": { "method": "GET", "path": "/analytics-svc/api/services/alpdb/cdmversion", "correlationId": "raw-audit-develop-cdm-version", "query": { "datasetId": "3c55629f-f0a3-4eaf-814e-049b9ea2d4d1" }, "params": {}, "body": {} }, "database": { "engine": "duckdb", "dialect": "postgresql", "code": "demo_database", "schema": "demo_cdm" }, "operation": "executeQuery", "sql": "SELECT CDM_VERSION FROM _3c55629f_f0a3_4eaf_814e_049b9ea2d4d1.demo_cdm.CDM_SOURCE", "parameterCount": 0, "successful": true, "durationMs": 1.963, "datasetId": "3c55629f-f0a3-4eaf-814e-049b9ea2d4d1", "configs": { "cohortBuilder": { "id": "4fce3cb7-32bf-4b46-8cba-32e4f77a14dd", "version": "A" }, "cdm": { "id": "e10f83a0-ade9-4a33-90ae-cf760813943c", "version": "3" } } }Validation
--no-checkconvention.git diff --checkpassed. The original local runtime and audit settings were restored after validation.Merge Checklist
Companion PR: #3268.