# Agent Skill: toldo-offline-export-import ## Metadata ```yaml name: toldo-offline-export-import description: Exportar/importar JSON versionado, migraciones de esquema, validación e integridad para uso offline/APK. Funciona sin red. ``` ## When to use Use this skill when: - Implementing export functionality - Implementing import functionality - Handling schema migrations - Versioning data formats - Ensuring data portability between devices ## Export Format (Versioned JSON) ```typescript interface ExportData { schemaVersion: number; // Database/schema version appVersion: string; // App version exportedAt: string; // ISO 8601 timestamp data: { productores: Productor[]; productos: Producto[]; movimientosInventario: MovimientoInventario[]; ventas: Venta[]; ventaLineas: VentaLinea[]; gastos: Gasto[]; ajustes: Ajuste[]; cuadres: CuadreCaja[]; }; } ``` ## Export Requirements - [ ] Include all entities - [ ] Use current schemaVersion - [ ] Include appVersion - [ ] Include exportedAt timestamp - [ ] Pretty print or compact JSON (both fine) - [ ] Filename suggestion: `toldo-export-YYYY-MM-DD-HHMMSS.json` - [ ] Works offline (no network calls) ## Import Requirements - [ ] Validate JSON structure - [ ] Check schemaVersion compatibility - [ ] Migrate data if schemaVersion is older (supported migration path) - [ ] Reject if schemaVersion is newer and no migration path (with clear message) - [ ] Validate required fields - [ ] Handle errors gracefully with user-friendly messages - [ ] Option to backup current data before import? (recommended) - [ ] Works offline ## Migration Strategy ```typescript function migrateExport(exportData: ExportData): ExportData { let data = { ...exportData }; // Migrate from older versions while (data.schemaVersion < CURRENT_SCHEMA_VERSION) { data = migrateToNextVersion(data); } if (data.schemaVersion > CURRENT_SCHEMA_VERSION) { throw new Error( `Incompatible schema version: ${data.schemaVersion}. ` + `Current app supports up to ${CURRENT_SCHEMA_VERSION}. ` + `Please update the app.` ); } return data; } function migrateToNextVersion(data: ExportData): ExportData { // Implement version-specific migrations // Example: add new fields with defaults switch (data.schemaVersion) { case 1: // migrate v1 -> v2 return { ...data, schemaVersion: 2, data: migratedData }; default: throw new Error('Unknown schema version'); } } ``` ## Validation ```typescript function validateExport(data: unknown): data is ExportData { // Check structure if (!isObject(data)) throw new Error('Invalid export format'); if (typeof data.schemaVersion !== 'number') throw new Error('Missing schemaVersion'); if (typeof data.appVersion !== 'string') throw new Error('Missing appVersion'); if (!data.exportedAt) throw new Error('Missing exportedAt'); if (!isObject(data.data)) throw new Error('Missing data'); // Validate data arrays exist const required = ['productores', 'productos', 'ventas', 'gastos', ...]; for (const key of required) { if (!Array.isArray(data.data[key])) throw new Error(`Missing or invalid ${key}`); } return true; } ``` ## Usage in Capacitor For APK/native, can use: - `@capacitor/filesystem` to save/load files - Web File API as fallback - Share API if available Always mock in tests. ```typescript // In tests vi.mock('@capacitor/filesystem', () => ({ Filesystem: { writeFile: vi.fn().mockResolvedValue({ uri: 'file://' }), readFile: vi.fn().mockResolvedValue({ data: '...' }), }, })); ``` ## Distribution Between Devices - Export on device A (tablet at market or home) - Transfer via USB/OTG to device B - Import on device B - All offline, no network needed - Works with any file manager ## Best Practices - [ ] Always version exports - [ ] Validate before importing - [ ] Provide clear error messages - [ ] Don't silently corrupt data - [ ] Test migrations with real export files - [ ] Keep backward compatibility when possible - [ ] Log migration steps for debugging - [ ] Consider backing up before destructive import ## Error Messages Be user-friendly in Spanish (app is for CESTA in Colombia): - "Formato de archivo inválido" - "Versión de esquema incompatible. Actualice la aplicación." - "Error al leer el archivo" - "Datos importados correctamente" ## Resources - See `openspec/changes/add-toldo-poc-capacitor/specs/toldo-poc/spec.md` for scenarios - JSON versioned format is critical for long-term maintainability - Test import/export round-trip