Files
shopdb-flask/scripts/site_imports/wjf/README.md
Cam Proudlock 8666e0271c Reciprocal controls links, dead chip links, and a resumable legacy import
The machine page now shows the PC that controls it. The endpoint was correct all
along and returned both directions; AssetTriageBand discarded every peer whose
type was not 'machine' and was mounted only on the PC page. The counterpart type,
label and relationship types are now props.

Fixed while adopting it more widely: every band chip linked to /assets/<id>, and
there is no such route. The resolver that AssetRelationships.vue kept privately
is now frontend/src/utils/assetRoute.js, used by both - and its type lookup is
case-insensitive, because seed data capitalises the type names while this site's
database does not.

The legacy import is now safe to resume. The 409-resolve asked for
per_page=10000 against a server that clamps to 100, so it silently searched the
first 100 rows and dropped links past that on every re-run. The crosswalk is now
bound to the database it describes, so one carried across a rebuild is refused
rather than attaching rows to the wrong assets. Source database names are
resolved from the environment, so the loader can be aimed without editing it.

Full suite 2178 passed, frontend 280 passed.
2026-08-29 19:09:06 -04:00

3.3 KiB

WJ classic-ASP import loader (reference implementation)

This is site-specific reference glue, not product code. It maps West Jefferson's classic-ASP shopdb / cmmc_usb / wjf_employees schema onto the maintained, schema-agnostic import contract in the IMPORT-API wiki page.

Every adopting site has its own source database. Nobody else runs this loader. Instead, copy the pattern:

  1. Point the harness at your source DB(s) (edit harness.Source).
  2. Write per-entity stages that read your tables and POST to the same the IMPORT-API wiki page endpoints with Authorization: Bearer <admin PAT> and X-Import-Mode: true.
  3. Persist legacy-id -> new-id crosswalks (see harness.IdMap) so later stages resolve foreign keys and a crashed run resumes.

The import API is the stable contract; loaders are per-site. The mapping itself is the bulk of the work: enumerate the source tables against this contract and write one stage per entity (this loader is the worked example).

Running (against a THROWAWAY import database)

DATABASE_URL='mysql+pymysql://root:PW@127.0.0.1:3306/shopdb_flask_import?charset=utf8mb4' \
  venv/bin/python -m scripts.site_imports.wjf.run --stages reference,employees

Prereqs: a fresh target DB built with flask db upgrade + flask plugin upgrade-all + flask seed permissions/settings/reference-data, and the three source dumps loaded into scratch DBs (shopdb_src, cmmc_usb_src, wjf_employees_src). See scratchpad/IMPORT-PLAN.md for the full mapping, resolved decisions, and remaining stages.

Status

All 17 stages built: reference, employees, catalog, assets (the hub + machineid->assetid crosswalk), locations, printers, metrology, communications, applications (+ installs), warranties, notifications, knowledgebase, relationships, defaultprinters, subnets, usb, verify.

The counts below are from the 2026-07-13 run and are STALE. Two routing changes landed after them - the isactive=1 filter and the metrology routing rework - so the asset mix has moved substantially. They are kept only as a shape, not as a checklist: re-measure from the next full run before quoting them anywhere, and do not verify a fresh import against them.

Last full run (2026-07-13, superseded): 983 assets (computer 663, machine 76, network 58, measuring-tool 136, printer 50), 24 locations, 415 employees, 850 installs, 461 primary IPs, 464 warranties, 261 notifications, 341 KB, 93 relationships, 37 subnets, 18 USB devices + 232 events.

Known gaps, none of them blocking a scratch run:

  • warranties, notifications and knowledgebase POST without a duplicate check on the API side, so resuming ACROSS one of those stages doubles its rows. Resuming at or after them is safe. Re-run into a clean target when in doubt.
  • There is no --dry-run and no guard on the target: the harness mints an admin PAT and sets setup_complete in whatever DATABASE_URL points at. Check the target before running.
  • The verify stage counts target assets against source machines, which is apples to oranges - the target also holds printers and synthesized metrology tools.

Known follow-ups: general asset locationid is null (no source column outside printers); the ~146 duplicate machinenumbers are first-wins-skipped by decision.