--- name: importer-scaffolder description: "Use when asked to build an importer from a competitor's export, migrate users' data from another tool, map a CSV or JSON export onto my data model, or make switching to my project easy. Given a sample export (CSV or JSON), produces a field mapping table, an importer code skeleton, a rule that unmatched records are kept rather than dropped, and test fixtures including the awkward cases. For a database migration inside one system, use database-migration-plan." version: 1.0.0 --- # Importer Scaffolder People switch tools when leaving costs them nothing, and an importer is how a small project removes that cost. Importers fail quietly: a column is renamed, a date is in another format, a record has no match, and data disappears without anyone noticing. This skill builds an importer from a real sample export, with a mapping that is explicit and a rule that nothing is silently dropped. ## Required Inputs Ask for these if not provided: - **A sample export**: a few rows of CSV or a JSON excerpt, with any personal data replaced - **The source tool** and how users produce the export - **Your data model**: the target fields, types and required fields - **Your language and stack** for the importer - **Where unmatched data should go**: a notes field, an extras column, or a separate file ## Output Structure ### 1. Source profile What the sample shows: format, encoding, delimiter, header names, date and number formats, nested fields, and anything ambiguous. List assumptions explicitly. ### 2. Field mapping table | Source field | Example value | Target field | Transform | Required? | If missing or invalid | |---|---|---|---|---|---| Every source field appears in the table, mapped or not. Unmapped fields go to the extras destination named in the inputs. ### 3. The keep-everything rule State it in the code and the docs: **no source record is dropped.** A record that fails validation is imported with what could be parsed, flagged, and listed in an import report; its raw source is preserved in the extras destination. ### 4. Importer skeleton Code in the requested language with these parts, each a small function: - `read(source)`: streams rows; detects encoding and delimiter; never loads a huge file whole - `mapRow(row)`: applies the mapping table; returns `{ record, warnings, extras }` - `validate(record)`: required fields and types; returns problems without throwing - `write(record)`: idempotent upsert keyed on a stable source ID, so re-running an import does not duplicate data - `report()`: counts of imported, imported with warnings, and per-warning examples Include a dry-run mode that prints the report without writing. ### 5. Test fixtures Fixture files plus the expected result for each: - the happy path (three normal rows) - a renamed or reordered header - an empty required field - a malformed date and a number with a thousands separator - non-ASCII text (accents, Chinese characters, emoji) - a duplicate row (checks idempotency) - a row with extra unknown columns (checks they land in extras) ### 6. User-facing instructions Five to eight steps telling users how to export from the source tool and import, including what the import report means. ## Quality Checks - [ ] Every source field in the sample appears in the mapping table - [ ] The code imports invalid records with a flag instead of dropping them - [ ] Unmapped fields are preserved in the named extras destination - [ ] Re-running the import on the same file creates no duplicates - [ ] A dry-run mode exists and writes nothing - [ ] Fixtures cover non-ASCII text, a malformed date and a duplicate row - [ ] The sample data contains no real personal data ## Anti-Patterns - **Silent drops.** A skipped row is lost data the user may never notice. - **Mapping by column position.** Exports reorder columns; map by header name. - **Loading the whole file into memory.** Real exports are bigger than samples. - **Guessing ambiguous dates.** If 03/04 could be either order, ask or detect from the whole file, and record the choice. ## Example Trigger Phrases - "Build an importer for Trello JSON exports into my app." - "Here's a CSV export from Notion, map it onto my data model." - "Make it easy for users to switch from [competitor] to my project." - "Write a CSV importer that never drops rows."