--- name: flexport-local-dev-loop description: 'Configure Flexport local development with mock API responses and testing. Use when setting up a development environment, creating mock shipment data, or establishing a fast iteration cycle for Flexport logistics integration. Trigger: "flexport dev setup", "flexport local development", "flexport mock API". ' allowed-tools: Read, Write, Edit, Bash(npm:*), Bash(pnpm:*), Grep version: 1.0.0 license: MIT author: Jeremy Longshore tags: - saas - logistics - flexport compatibility: Designed for Claude Code --- # Flexport Local Dev Loop ## Overview Set up a fast, reproducible local development workflow for Flexport integrations. Since Flexport has no official SDK, the dev loop centers on a typed HTTP client wrapper with mock responses for testing. ## Instructions ### Step 1: Project Structure ``` flexport-integration/ ├── src/ │ ├── flexport/ │ │ ├── client.ts # Typed Flexport API client │ │ ├── types.ts # API response types │ │ └── mock-data.ts # Test fixtures │ └── index.ts ├── tests/ │ ├── flexport.test.ts # Unit tests with mocks │ └── integration.test.ts # Live API tests (CI only) ├── .env.local # Local secrets (git-ignored) ├── .env.example └── package.json ``` ### Step 2: Typed Client Wrapper ```typescript // src/flexport/types.ts interface FlexportShipment { id: string; status: 'booked' | 'in_transit' | 'arrived' | 'delivered'; freight_type: 'ocean' | 'air' | 'trucking'; origin_port: { code: string; name: string }; destination_port: { code: string; name: string }; cargo_ready_date: string; estimated_arrival_date: string; } interface FlexportResponse { data: { records: T[]; total_count: number }; } // src/flexport/client.ts export class FlexportClient { private base = 'https://api.flexport.com'; private headers: Record; constructor(apiKey: string) { this.headers = { 'Authorization': `Bearer ${apiKey}`, 'Flexport-Version': '2', 'Content-Type': 'application/json', }; } async listShipments(page = 1, per = 25): Promise> { const res = await fetch(`${this.base}/shipments?page=${page}&per=${per}`, { headers: this.headers, }); if (!res.ok) throw new Error(`Flexport ${res.status}: ${await res.text()}`); return res.json(); } } ``` ### Step 3: Mock Data for Testing ```typescript // src/flexport/mock-data.ts export const mockShipment: FlexportShipment = { id: 'shp_test_001', status: 'in_transit', freight_type: 'ocean', origin_port: { code: 'CNSHA', name: 'Shanghai' }, destination_port: { code: 'USLAX', name: 'Los Angeles' }, cargo_ready_date: '2025-04-01', estimated_arrival_date: '2025-05-15', }; export function mockFlexportFetch(path: string) { if (path.includes('/shipments')) { return { data: { records: [mockShipment], total_count: 1 } }; } throw new Error(`No mock for ${path}`); } ``` ### Step 4: Vitest Unit Tests ```typescript // tests/flexport.test.ts import { describe, it, expect, vi, beforeEach } from 'vitest'; import { FlexportClient } from '../src/flexport/client'; import { mockShipment } from '../src/flexport/mock-data'; describe('FlexportClient', () => { beforeEach(() => { vi.stubGlobal('fetch', vi.fn().mockResolvedValue({ ok: true, json: () => Promise.resolve({ data: { records: [mockShipment], total_count: 1 } }), })); }); it('lists shipments', async () => { const client = new FlexportClient('test-key'); const result = await client.listShipments(); expect(result.data.records).toHaveLength(1); expect(result.data.records[0].freight_type).toBe('ocean'); }); it('sends correct auth header', async () => { const client = new FlexportClient('test-key'); await client.listShipments(); expect(fetch).toHaveBeenCalledWith( expect.stringContaining('/shipments'), expect.objectContaining({ headers: expect.objectContaining({ 'Flexport-Version': '2' }) }), ); }); }); ``` ### Step 5: Dev Scripts ```json { "scripts": { "dev": "tsx watch src/index.ts", "test": "vitest", "test:watch": "vitest --watch", "test:integration": "FLEXPORT_LIVE=1 vitest tests/integration.test.ts" } } ``` ## Resources - [Flexport Developer Portal](https://developers.flexport.com/) - [Vitest Documentation](https://vitest.dev/) ## Next Steps See `flexport-sdk-patterns` for production-ready code patterns.