Five findings from the review of the WINC import, plus the rendering each fix needed to be usable. An undo that hit a conflict wrote status 'undone' anyway, and undo_batch returns immediately for an undone batch. So the one entry that needed a retry was the only one that could never get it: the human resolves the conflict, clicks Undo, and gets a no-op. A conflicted undo is now 'partially-undone', undoneat is stamped only when the batch is genuinely finished, and the batches table offers "Retry undo" for that status. The column was String(16) and the new value is exactly 16 characters, so migration 7d38 widens it to 32 rather than rely on an exact fit. _UNDO_REFERENCES listed only assets, so a business unit this batch created was hard-deleted even when something else still pointed at it. Two of the three missing referrers are real FKs (dashboarddefaults.businessunitid, businessunits.parentid): MySQL raises and the whole undo rolls back, so the batch cannot be undone at all. The third, notifications.businessunitid, has no FK, so the delete succeeded and left a notification pointing at an id that no longer exists - silently, on both engines. All four are listed and the guard is tested through the route. The reference guard also queried tables that need not exist. A lean site drops the tables of plugins it does not install (ADR-014), and notifications is plugin-owned, so on such a site the query raised 1146, rolled the undo back and left the batch permanently un-undoable. Absent tables are skipped; a table that does not exist cannot hold a reference. _PACKET_GROUPS reports on location, but apply_plan only ever creates business units - it sets locationid only when the location already resolved. A plan needing a new location asked the admin to acknowledge it, got the tick, wrote nothing, and reported nothing. build_packet now takes the groups the writer can actually create; anything else needed is 'uncreatable' and blocks at plan time, where the admin can act on it, rather than dying at commit on a message about acknowledging something the screen had no control for. The writer refuses the same case independently. Both the console packet and the import page name the blocking groups: setting blocking without printing the reason would leave the banner pointing at nothing. The web undo route caught ValueError only, so refusing a batch belonging to another importer surfaced as a 500. That refusal is new too: the journal is a general primitive and undo_batch does not filter on kind, so any other importer's batches were reversible through this endpoint, carrying WINC's references map - which lists none of that importer's tables, making every reference check pass and every delete unconditional. Nine tests. The two guards were verified by planting violations: dropping dashboarddefaults from the references map, and passing creatable=None, each fail the test written for them. Scope: product
WINC machine-adoption import (CLI)
Adopts machines from a Maximo asset export (validated against the WINC / West Manufacturing site). It only updates machines that already exist; it never creates canonical per-table rows. Every commit is journaled so it can be undone as one batch.
Run all commands from the repo root. Each reads .env and connects to the
configured database.
1. Preview (read-only)
python -m scripts.site_imports.winc.dry_run --export EXPORT.csv
| switch | what it does |
|---|---|
--export PATH |
the Maximo ASSET export CSV to analyze (required) |
--rows |
print the per-row plan, not just the summary |
--csv PATH |
write the full plan to a CSV so runs can be diffed |
Nothing is written. Use this to see what would change and which values are unresolved before committing.
2. Commit (writes, reversibly)
python -m scripts.site_imports.winc.writer --export EXPORT.csv --commit --acknowledge businessunit
| switch | what it does |
|---|---|
--export PATH |
the same export CSV (required) |
--commit |
actually write; without it this is a dry run |
--acknowledge GROUP |
approve a needs-create group (repeatable), e.g. businessunit |
--createdby NAME |
who approved the import; stamped on the batch |
On success it prints the new batchid and the exact undo command.
3. List batches
python -m scripts.site_imports.winc.batches
| switch | what it does |
|---|---|
--limit N |
show at most N batches, newest first (default 50) |
--json |
emit JSON instead of a table |
Read-only. Use it to find the batchid to undo.
4. Undo a batch
python -m scripts.site_imports.winc.undo --batch BATCHID --commit
| switch | what it does |
|---|---|
--batch BATCHID |
the batch to reverse (required) |
--commit |
actually reverse; without it this is a no-op |
Reversal is conservative: a cell a human changed since the import is left as-is and reported, and a created business unit is deleted only when nothing outside the batch still references it.