.cursor/skills/data-migrate/SKILL.md
Move records from an external source (CSV, JSON, SQL dump, or API response) into a live FileMaker solution via OData. Reads the source data, maps source columns to FM fields with type coercion, gets developer approval on the mapping, then executes the migration with error tracking. Use when the developer asks to "migrate data", "import records", "move data into FileMaker", "load CSV", or "import JSON".
npx skillsauth add petrowsky/agentic-fm data-migrateInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Move records from an external data source into a live FileMaker solution via OData POST requests. Handles field mapping, type coercion, referential integrity, and error reporting.
Read agent/config/automation.json and identify the target solution:
agent/CONTEXT.json exists, read CONTEXT.json["solution"] to get the solution name.automation.json["solutions"][solution_name]["odata"] for the OData credentials and base URL.odata block exists for the solution, stop and inform the developer:OData is not configured for this solution. Add an
odatablock toagent/config/automation.jsonundersolutions.{solution name}withbase_url,database,username,password, andscript_bridge. SeeCLAUDE.mdfor the structure.
The developer provides a file path or describes the data source. Auto-detect the format:
[ { "field": "value" }, ... ] -- each object is a record.{ "data": [ ... ] } or { "records": [ ... ] } -- unwrap the array.INSERT INTO statements to extract table name, column names, and values.If the format is not recognized, ask the developer to describe the structure or convert to CSV/JSON.
Use the same schema discovery as data-seed (Step 2), in order of preference:
agent/context/{solution}/fields.index$metadata -- fetch and parse EntityType elementsIdentify the target table. If the developer has not specified which FM table to import into:
For each source column, propose a mapping to an FM field:
| Source type | FM field type | Coercion | |------------|---------------|----------| | String number ("42.5") | Number | Parse as float | | ISO date ("2025-01-15") | Date | Reformat to MM/DD/YYYY | | European date ("15/01/2025") | Date | Detect DD/MM/YYYY and reformat to MM/DD/YYYY | | ISO timestamp ("2025-01-15T10:30:00") | Timestamp | Reformat to MM/DD/YYYY HH:MM:SS | | Unix timestamp (1705334400) | Timestamp | Convert to MM/DD/YYYY HH:MM:SS | | Boolean (true/false, yes/no, 1/0) | Number | Convert to 1 or 0 | | NULL / empty | Any | Omit the field from the POST body (let FM use default) | | String | Number | Attempt parse; if not numeric, log warning and skip field for that record |
Display a mapping table for developer review:
Field mapping: source -> {Table Name}
| # | Source Column | FM Field | Type Coercion | Notes | |---|-------------|----------|---------------|-------| | 1 | first_name | FirstName | none | exact match | | 2 | last_name | LastName | none | normalized match | | 3 | email | Email | none | exact match | | 4 | phone_number | Phone | none | normalized match | | 5 | signup_date | DateCreated | ISO -> MM/DD/YYYY | date format conversion | | 6 | is_active | Active | true/false -> 1/0 | boolean conversion | | 7 | legacy_id | -- | UNMAPPED | no matching FM field | | 8 | -- | PrimaryKey | SKIPPED | auto-enter serial | | 9 | -- | CreationTimestamp | SKIPPED | auto-enter |
Source records: 247 Unmapped source columns: legacy_id Duplicate handling: (not yet specified)
Please review and confirm, or specify changes (e.g., "map legacy_id to ExternalID", "skip phone_number").
Wait for the developer to confirm or adjust the mapping. Key decisions to resolve:
Do not proceed until the developer has confirmed the mapping.
If migrating multiple related tables:
For each source record:
GET {base_url}/{database}/{table}?$filter={lookupField} eq '{value}'&$top=1
If found, handle according to the developer's duplicate policy.POST {base_url}/{database}/{TableOccurrenceName}
Authorization: Basic <base64(username:password)>
Content-Type: application/json
{
"FieldName1": "coerced_value1",
"FieldName2": 42
}
Present a migration summary:
Migration complete: {source file} -> {Table Name}
| Metric | Count | |--------|-------| | Source records | 247 | | Created | 241 | | Skipped (duplicate) | 3 | | Failed | 3 |
Field mapping used: | Source | FM Field | Coercions applied | |--------|----------|-------------------| | first_name | FirstName | 0 | | signup_date | DateCreated | 241 (ISO -> MM/DD/YYYY) | | is_active | Active | 241 (bool -> number) |
Errors (3):
- Row 42: 400 Bad Request -- field "Amount" value "N/A" is not a valid number
- Row 118: 500 Server Error -- "Field validation failed for Status"
- Row 203: 400 Bad Request -- field "Amount" value "TBD" is not a valid number
Recommendation: Rows 42 and 203 have non-numeric values in the Amount column. Clean the source data and re-run for those rows, or manually enter them in FileMaker.
If any failed records share a common pattern (e.g., all failures are due to the same field), highlight that pattern and suggest a fix.
User: "Import clients.csv into the Clients table"
clients.csv -- 50 rows, columns: name, email, phone, city, stateUser: "Migrate orders.json -- it has orders and line items"
orders.json -- contains { "orders": [...], "line_items": [...] }User: "Import updated client list, skip existing clients"
User: "Import this CSV into FileMaker"
odata blockodata block to automation.json for this solution to enable data migration."development
Generate a complete web application inside a FileMaker Web Viewer — self-contained HTML/CSS/JS styled with the FM theme, plus companion FM bridge scripts for bidirectional data flow. Use when the developer says "web viewer", "webviewer app", "HTML in FileMaker", "build web viewer", or when the layout-design skill delegates to the web-first output path. Recommended for modern, responsive UI, complex interactions (drag-and-drop, charts, rich text), or solutions considering future migration off FileMaker.
development
Trace references to a FileMaker object across the entire solution. Supports usage reports ("where is this field used?"), impact analysis ("what breaks if I rename this?"), and dead object scans ("show unused fields/scripts"). Use when the developer says "trace", "find references", "where is X used", "impact of renaming", "unused fields/scripts", "dead code", "what references X", or "is X used anywhere".
development
Analyze a FileMaker solution and produce a structured profile covering data model, business logic, UI layer, integrations, and health metrics. Uses on-disk pre-processing to handle solutions of any size without sending raw XML through the agent. Use when the developer says "analyze solution", "solution overview", "solution analysis", "solution profile", "solution spec", "what does this solution do", "solution summary", or wants a high-level understanding of an entire FileMaker solution.
development
Interactive setup wizard for agentic-fm. Detects what's already configured, walks the user through each remaining step, and verifies completion before proceeding. Use when the developer says "help me set up", "setup", "get started", "onboard", "first time setup", "install agentic-fm", "configure agentic-fm", or is clearly new to the project and needs guidance.