Skillshub abridge-upgrade-migration
install
source · Clone the upstream repo
git clone https://github.com/ComeOnOliver/skillshub
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/ComeOnOliver/skillshub "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/jeremylongshore/claude-code-plugins-plus-skills/abridge-upgrade-migration" ~/.claude/skills/comeonoliver-skillshub-abridge-upgrade-migration && rm -rf "$T"
manifest:
skills/jeremylongshore/claude-code-plugins-plus-skills/abridge-upgrade-migration/SKILL.mdsource content
Abridge Upgrade & Migration
Overview
Procedures for upgrading Abridge API integrations and migrating between EHR systems. Healthcare migrations are high-risk — clinical documentation cannot have gaps.
Common Migration Scenarios
| Scenario | Complexity | Downtime | Risk |
|---|---|---|---|
| API version bump (v1 → v2) | Medium | Zero (dual-version) | Low |
| EHR migration (Epic → Athena) | High | Planned window | High |
| New specialty onboarding | Low | Zero | Low |
| Note template changes | Medium | Zero | Medium |
| Multi-site rollout | High | Per-site windows | Medium |
Instructions
Step 1: API Version Migration
// src/migration/api-version-adapter.ts // Dual-version adapter for zero-downtime API upgrades interface ApiVersionConfig { v1BaseUrl: string; // Current production v2BaseUrl: string; // New version (canary) canaryPercent: number; // Percentage of traffic to v2 } class AbridgeVersionAdapter { constructor(private config: ApiVersionConfig) {} getBaseUrl(): string { // Gradual canary rollout const useV2 = Math.random() * 100 < this.config.canaryPercent; return useV2 ? this.config.v2BaseUrl : this.config.v1BaseUrl; } // Map v1 response to v2 format (or vice versa) normalizeNoteResponse(response: any, version: 'v1' | 'v2'): any { if (version === 'v1') { return { ...response, // v2 adds quality_metrics — provide defaults for v1 quality_metrics: response.quality_metrics || { confidence_score: response.confidence || 0, completeness_score: 0, coding_accuracy: 0, }, }; } return response; } }
Step 2: EHR Migration Procedure
// src/migration/ehr-migration.ts interface EhrMigrationPlan { sourceEhr: 'epic' | 'athena' | 'cerner' | 'eclinicalworks'; targetEhr: 'epic' | 'athena' | 'cerner' | 'eclinicalworks'; migrationDate: Date; providerCount: number; steps: MigrationStep[]; } interface MigrationStep { order: number; name: string; description: string; rollbackable: boolean; estimatedMinutes: number; } function generateMigrationPlan(source: string, target: string): EhrMigrationPlan { return { sourceEhr: source as any, targetEhr: target as any, migrationDate: new Date(), providerCount: 0, // Set per org steps: [ { order: 1, name: 'Freeze new enrollments', description: 'Stop new provider enrollments on source EHR', rollbackable: true, estimatedMinutes: 5 }, { order: 2, name: 'Export note templates', description: 'Export all custom note templates and SmartPhrases', rollbackable: true, estimatedMinutes: 30 }, { order: 3, name: 'Configure target EHR', description: 'Set up FHIR endpoints and OAuth for target EHR', rollbackable: true, estimatedMinutes: 60 }, { order: 4, name: 'Parallel run', description: 'Run both EHRs for 1 week — compare note output', rollbackable: true, estimatedMinutes: 10080 }, { order: 5, name: 'Provider re-enrollment', description: 'Re-enroll providers on target EHR', rollbackable: true, estimatedMinutes: 120 }, { order: 6, name: 'Cutover', description: 'Switch primary EHR integration to target', rollbackable: true, estimatedMinutes: 15 }, { order: 7, name: 'Decommission source', description: 'Disable source EHR integration after 30-day soak', rollbackable: false, estimatedMinutes: 30 }, ], }; }
Step 3: Note Template Migration
// src/migration/template-migration.ts interface NoteTemplate { id: string; name: string; specialty: string; sections: string[]; smartPhrases: Record<string, string>; // Epic-specific } async function migrateTemplates( sourceApi: any, targetApi: any, ): Promise<{ migrated: number; failed: string[] }> { const { data: templates } = await sourceApi.get('/note-templates'); const failed: string[] = []; let migrated = 0; for (const template of templates) { try { // Remove EHR-specific fields const { smartPhrases, ...portable } = template; await targetApi.post('/note-templates', { ...portable, // Map SmartPhrases to target EHR equivalent if applicable }); migrated++; } catch (err) { failed.push(template.id); } } return { migrated, failed }; }
Rollback Procedures
#!/bin/bash # scripts/abridge-migration-rollback.sh echo "=== Migration Rollback ===" echo "Step 1: Revert FHIR endpoint to source EHR" echo "Step 2: Re-enable source EHR Abridge module" echo "Step 3: Notify providers of rollback" echo "Step 4: Verify note generation on source EHR" echo "=== Rollback Complete ==="
Output
- Dual-version API adapter for zero-downtime upgrades
- EHR migration plan with parallel run validation
- Note template migration with rollback
- Provider re-enrollment procedure
Error Handling
| Error | Cause | Solution |
|---|---|---|
| Template incompatible | EHR-specific fields | Strip EHR-specific data before migration |
| Provider enrollment fails | Credentials not migrated | Re-issue provider credentials on target |
| Note format mismatch | Different FHIR profiles | Map FHIR profiles between EHR systems |
Resources
Next Steps
For CI/CD pipeline setup, see
abridge-ci-integration.