Agent Skills: Abridge Upgrade & Migration

|

UncategorizedID: jeremylongshore/claude-code-plugins-plus-skills/abridge-upgrade-migration

Install this agent skill to your local

pnpm dlx add-skill https://github.com/jeremylongshore/claude-code-plugins-plus-skills/tree/HEAD/plugins/saas-packs/abridge-pack/skills/abridge-upgrade-migration

Skill Files

Browse the full folder contents for abridge-upgrade-migration.

Download Skill

Loading file tree…

plugins/saas-packs/abridge-pack/skills/abridge-upgrade-migration/SKILL.md

Skill Metadata

Name
abridge-upgrade-migration
Description
|

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.