| name | flexport-migration-deep-dive |
| description | Execute major migration strategies for Flexport including migrating from
legacy freight forwarders, ERP system integration, and strangler fig patterns.
Trigger: "flexport migration", "migrate to flexport", "flexport ERP integration".
|
| allowed-tools | Read, Write, Edit, Bash(npm:*), Grep |
| version | 1.6.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
| tags | ["saas","logistics","flexport"] |
| compatibility | Designed for Claude Code |
Flexport Migration Deep Dive
Overview
Guide for migrating to Flexport from legacy freight forwarders, manual spreadsheet workflows, or other logistics platforms. Uses a strangler fig pattern to gradually move operations to the Flexport API while maintaining existing systems.
Migration Scenarios
| From | To | Complexity | Timeline |
|---|
| Spreadsheet/email | Flexport API | Low | 2-4 weeks |
| Legacy freight forwarder API | Flexport API | Medium | 4-8 weeks |
| ERP (SAP, Oracle) | ERP + Flexport | High | 8-16 weeks |
| Multiple forwarders | Flexport consolidated | High | 6-12 weeks |
Instructions
Phase 1: Data Migration — Product Catalog
async function migrateProducts(legacyProducts: LegacyProduct[]) {
const results = { success: 0, failed: 0, errors: [] as string[] };
for (const legacy of legacyProducts) {
try {
await fetch('https://api.flexport.com/products', {
method: 'POST',
headers,
body: JSON.stringify({
name: legacy.description,
sku: legacy.partNumber,
hs_code: legacy.tariffCode,
country_of_origin: legacy.originCountry,
unit_cost: { amount: legacy.unitCost, currency: legacy.currency },
weight: { value: legacy.weightKg, unit: 'kg' },
}),
});
results.success++;
} catch (err) {
results.failed++;
results.errors.push();
}
}
.();
results;
}
Phase 2: Strangler Fig — Dual-Write
class DualWriteShipmentService {
constructor(
private legacy: LegacyForwarderClient,
private flexport: FlexportClient,
private featureFlags: FeatureFlags,
) {}
async createBooking(params: BookingParams) {
const legacyResult = await this.legacy.createBooking(params);
if (this.featureFlags.isEnabled('flexport_booking', { route: params.route })) {
try {
const fpResult = await this.flexport.createBooking(params);
this.compareResults(legacyResult, fpResult);
} catch (err) {
logger.warn({ err, route: params.route }, );
}
}
legacyResult;
}
}
Phase 3: Cutover — Route by Route
const MIGRATION_PHASES = [
{ routes: ['CNSHA-USLAX'], startDate: '2025-04-01', description: 'Shanghai-LA (highest volume)' },
{ routes: ['CNSHA-DEHAM', 'CNSHA-NLRTM'], startDate: '2025-05-01', description: 'Asia-Europe' },
{ routes: ['*'], startDate: '2025-06-01', description: 'All remaining routes' },
];
async function validateRoute(route: string): Promise<{
productsCovered: boolean;
webhooksWorking: boolean;
dataParity: boolean;
}> {
const products = await db.products.findMany({ where: { routes: { has: route } } });
const fpProducts = await flexport('/products?per=100');
const fpSkus = new (fpProducts...( p.));
productsCovered = products.( fpSkus.(p.));
{ productsCovered, : , : };
}
Phase 4: Decommission Legacy
async function decommissionLegacy() {
const allShipments = await legacy.exportAllShipments();
await archiveToS3(allShipments, 'legacy-forwarder-archive');
logger.info('Legacy forwarder decommissioned');
}
Migration Checklist
Resources
Next Steps
This completes the Flexport skill pack. Start with flexport-install-auth for new integrations.