Abridge CI Integration
Overview
CI/CD pipeline for Abridge clinical documentation integrations. Healthcare CI pipelines require FHIR resource validation, PHI leak scanning, HIPAA compliance checks, and sandbox integration testing.
Instructions
Step 1: GitHub Actions Workflow
# .github/workflows/abridge-ci.yml
name: Abridge Integration CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
env:
NODE_VERSION: '20'
jobs:
lint-and-type-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '${{ env.NODE_VERSION }}' }
- run: npm ci
- run: npm run lint
- run: npm run typecheck
phi-leak-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Scan for PHI patterns in source code
run: |
echo "Scanning for PHI patterns..."
# SSN patterns
if grep -rn '\b[0-9]\{3\}-[0-9]\{2\}-[0-9]\{4\}\b' src/ --include='*.ts' --include='*.js'; then
echo "FAIL: Possible SSN found in source code"
exit 1
fi
# Hardcoded patient names (common test names)
if grep -rn '"John Doe\|Jane Doe\|Test Patient"' src/ --include='*.ts'; then
echo "WARN: Hardcoded patient names — use synthetic data"
fi
echo "PHI scan passed"
fhir-validation:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '${{ env.NODE_VERSION }}' }
- run: npm ci
- name: Validate FHIR resources
run: |
npm run test:fhir-schemas
echo "FHIR R4 validation passed"
sandbox-integration:
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
needs: [lint-and-type-check, phi-leak-scan, fhir-validation]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '${{ env.NODE_VERSION }}' }
- run: npm ci
- name: Run sandbox integration tests
env:
ABRIDGE_SANDBOX_URL: ${{ secrets.ABRIDGE_SANDBOX_URL }}
ABRIDGE_CLIENT_SECRET: ${{ secrets.ABRIDGE_CLIENT_SECRET }}
ABRIDGE_ORG_ID: ${{ secrets.ABRIDGE_ORG_ID }}
run: npm run test:integration
Step 2: FHIR Schema Validation Tests
// tests/fhir-validation.test.ts
import { describe, it, expect } from 'vitest';
describe('FHIR R4 Resource Validation', () => {
it('should generate valid DocumentReference', () => {
const docRef = {
resourceType: 'DocumentReference',
status: 'current',
type: { coding: [{ system: 'http://loinc.org', code: '11506-3', display: 'Progress note' }] },
subject: { reference: 'Patient/test-001' },
content: [{ attachment: { contentType: 'text/plain', data: btoa('test note') } }],
};
expect(docRef.resourceType).toBe('DocumentReference');
expect(docRef.status).toBe('current');
expect(docRef.type.coding[0].system).toBe('http://loinc.org');
expect(docRef.content[0].attachment.contentType).toBe('text/plain');
});
it('should generate valid Communication resource for patient summary', () => {
const comm = {
resourceType: 'Communication',
status: 'completed',
category: [{ coding: [{ system: 'http://terminology.hl7.org/CodeSystem/communication-category', code: 'notification' }] }],
subject: { reference: 'Patient/test-001' },
payload: [{ contentString: 'Your visit summary...' }],
};
expect(comm.resourceType).toBe('Communication');
expect(comm.payload[0].contentString).toBeTruthy();
});
});
Step 3: Integration Test with Sandbox
// tests/integration/sandbox.test.ts
import { describe, it, expect } from 'vitest';
import axios from 'axios';
describe('Abridge Sandbox Integration', () => {
const api = axios.create({
baseURL: process.env.ABRIDGE_SANDBOX_URL,
headers: {
'Authorization': `Bearer ${process.env.ABRIDGE_CLIENT_SECRET}`,
'X-Org-Id': process.env.ABRIDGE_ORG_ID!,
},
});
it('should create and finalize an encounter session', async () => {
const { data: session } = await api.post('/encounters/sessions', {
patient_id: 'ci-test-patient',
provider_id: 'ci-test-provider',
encounter_type: 'outpatient',
specialty: 'internal_medicine',
sandbox: true,
});
expect(session.session_id).toBeTruthy();
expect(session.status).toBe('initialized');
// Submit transcript
await api.post(`/encounters/sessions/${session.session_id}/transcript`, {
speaker: 'provider', text: 'CI test — patient presents with headache.',
});
// Finalize
await api.post(`/encounters/sessions/${session.session_id}/finalize`);
}, 30000);
});
Output
- GitHub Actions workflow with 4 jobs: lint, PHI scan, FHIR validation, sandbox integration
- PHI leak detection scanning source code for SSN/MRN patterns
- FHIR R4 resource validation tests
- Sandbox integration tests (main branch only)
Error Handling
| Issue |
Cause |
Solution |
| PHI scan false positive |
Regex too broad |
Add pattern to allowlist in scan script |
| Sandbox test timeout |
API slow |
Increase vitest timeout to 30s |
| Secrets not available |
Missing GitHub Secrets |
Add to repo Settings > Secrets |
Resources
Next Steps
For deployment procedures, see abridge-deploy-integration.
1---2name: abridge-ci-integration3description: |4 Configure CI/CD pipeline for Abridge clinical AI integrations with GitHub Actions.5 Use when setting up automated testing, FHIR validation, HIPAA compliance checks,6 or deployment pipelines for healthcare AI applications.7 Trigger: "abridge CI", "abridge GitHub Actions", "abridge pipeline",8 "abridge automated testing", "abridge CI/CD".9allowed-tools: Read, Write, Edit, Bash(npm:*), Grep10version: 1.0.011license: MIT12author: Jeremy Longshore <jeremy@intentsolutions.io>13tags: [saas, healthcare, ai, abridge, ci-cd]14compatible-with: claude-code15---1617# Abridge CI Integration1819## Overview2021CI/CD pipeline for Abridge clinical documentation integrations. Healthcare CI pipelines require FHIR resource validation, PHI leak scanning, HIPAA compliance checks, and sandbox integration testing.2223## Instructions2425### Step 1: GitHub Actions Workflow2627```yaml28# .github/workflows/abridge-ci.yml29name: Abridge Integration CI3031on:32 push:33 branches: [main, develop]34 pull_request:35 branches: [main]3637env:38 NODE_VERSION: '20'3940jobs:41 lint-and-type-check:42 runs-on: ubuntu-latest43 steps:44 - uses: actions/checkout@v445 - uses: actions/setup-node@v446 with: { node-version: '${{ env.NODE_VERSION }}' }47 - run: npm ci48 - run: npm run lint49 - run: npm run typecheck5051 phi-leak-scan:52 runs-on: ubuntu-latest53 steps:54 - uses: actions/checkout@v455 - name: Scan for PHI patterns in source code56 run: |57 echo "Scanning for PHI patterns..."58 # SSN patterns59 if grep -rn '\b[0-9]\{3\}-[0-9]\{2\}-[0-9]\{4\}\b' src/ --include='*.ts' --include='*.js'; then60 echo "FAIL: Possible SSN found in source code"61 exit 162 fi63 # Hardcoded patient names (common test names)64 if grep -rn '"John Doe\|Jane Doe\|Test Patient"' src/ --include='*.ts'; then65 echo "WARN: Hardcoded patient names — use synthetic data"66 fi67 echo "PHI scan passed"6869 fhir-validation:70 runs-on: ubuntu-latest71 steps:72 - uses: actions/checkout@v473 - uses: actions/setup-node@v474 with: { node-version: '${{ env.NODE_VERSION }}' }75 - run: npm ci76 - name: Validate FHIR resources77 run: |78 npm run test:fhir-schemas79 echo "FHIR R4 validation passed"8081 sandbox-integration:82 runs-on: ubuntu-latest83 if: github.event_name == 'push' && github.ref == 'refs/heads/main'84 needs: [lint-and-type-check, phi-leak-scan, fhir-validation]85 steps:86 - uses: actions/checkout@v487 - uses: actions/setup-node@v488 with: { node-version: '${{ env.NODE_VERSION }}' }89 - run: npm ci90 - name: Run sandbox integration tests91 env:92 ABRIDGE_SANDBOX_URL: ${{ secrets.ABRIDGE_SANDBOX_URL }}93 ABRIDGE_CLIENT_SECRET: ${{ secrets.ABRIDGE_CLIENT_SECRET }}94 ABRIDGE_ORG_ID: ${{ secrets.ABRIDGE_ORG_ID }}95 run: npm run test:integration96```9798### Step 2: FHIR Schema Validation Tests99100```typescript101// tests/fhir-validation.test.ts102import { describe, it, expect } from 'vitest';103104describe('FHIR R4 Resource Validation', () => {105 it('should generate valid DocumentReference', () => {106 const docRef = {107 resourceType: 'DocumentReference',108 status: 'current',109 type: { coding: [{ system: 'http://loinc.org', code: '11506-3', display: 'Progress note' }] },110 subject: { reference: 'Patient/test-001' },111 content: [{ attachment: { contentType: 'text/plain', data: btoa('test note') } }],112 };113114 expect(docRef.resourceType).toBe('DocumentReference');115 expect(docRef.status).toBe('current');116 expect(docRef.type.coding[0].system).toBe('http://loinc.org');117 expect(docRef.content[0].attachment.contentType).toBe('text/plain');118 });119120 it('should generate valid Communication resource for patient summary', () => {121 const comm = {122 resourceType: 'Communication',123 status: 'completed',124 category: [{ coding: [{ system: 'http://terminology.hl7.org/CodeSystem/communication-category', code: 'notification' }] }],125 subject: { reference: 'Patient/test-001' },126 payload: [{ contentString: 'Your visit summary...' }],127 };128129 expect(comm.resourceType).toBe('Communication');130 expect(comm.payload[0].contentString).toBeTruthy();131 });132});133```134135### Step 3: Integration Test with Sandbox136137```typescript138// tests/integration/sandbox.test.ts139import { describe, it, expect } from 'vitest';140import axios from 'axios';141142describe('Abridge Sandbox Integration', () => {143 const api = axios.create({144 baseURL: process.env.ABRIDGE_SANDBOX_URL,145 headers: {146 'Authorization': `Bearer ${process.env.ABRIDGE_CLIENT_SECRET}`,147 'X-Org-Id': process.env.ABRIDGE_ORG_ID!,148 },149 });150151 it('should create and finalize an encounter session', async () => {152 const { data: session } = await api.post('/encounters/sessions', {153 patient_id: 'ci-test-patient',154 provider_id: 'ci-test-provider',155 encounter_type: 'outpatient',156 specialty: 'internal_medicine',157 sandbox: true,158 });159160 expect(session.session_id).toBeTruthy();161 expect(session.status).toBe('initialized');162163 // Submit transcript164 await api.post(`/encounters/sessions/${session.session_id}/transcript`, {165 speaker: 'provider', text: 'CI test — patient presents with headache.',166 });167168 // Finalize169 await api.post(`/encounters/sessions/${session.session_id}/finalize`);170 }, 30000);171});172```173174## Output175176- GitHub Actions workflow with 4 jobs: lint, PHI scan, FHIR validation, sandbox integration177- PHI leak detection scanning source code for SSN/MRN patterns178- FHIR R4 resource validation tests179- Sandbox integration tests (main branch only)180181## Error Handling182183| Issue | Cause | Solution |184|-------|-------|----------|185| PHI scan false positive | Regex too broad | Add pattern to allowlist in scan script |186| Sandbox test timeout | API slow | Increase vitest timeout to 30s |187| Secrets not available | Missing GitHub Secrets | Add to repo Settings > Secrets |188189## Resources190191- [Abridge Platform](https://www.abridge.com/product)192- [GitHub Actions Secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets)193- [FHIR Validator](https://hl7.org/fhir/R4/validation.html)194195## Next Steps196197For deployment procedures, see `abridge-deploy-integration`.198