Files
shopdb-flask/scripts/site_imports/wjf
Cam Proudlock d267813999 Printer assignment end to end, and a container that keeps a site's files
Assign printers to a MACHINE and let whichever PC controls it install them, with
the observed half kept strictly apart from the assigned half: a collector report
can never write an assignment row. Adoption is explicit. Adds a singular
relationship type so defaultprinter can mean exactly one, client scripts that
converge a bay's queues and correct a drifted one in place, and a wave gate so a
fleet-wide driver rollout cannot stampede its own share.

On the container side: the compose stack never persisted the instance directory,
so a rebuild discarded plugins.json and every upload. It is a volume now, the
image ships instance/ owned by the app user so the mountpoint is writable, and
the database moves to MySQL 8.4 LTS, which the Windows runbook has recommended
since 8.0 went end of life. The image also could not build at all: the frontend
stage never copied the plugin staging script it runs.

Adds a topology migration guide covering IIS to Docker and back.
2026-08-20 07:46:35 -04:00
..

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

Complete - all 15 stages built and verified end-to-end against a fresh scratch target (zero endpoint errors): reference, employees, catalog, assets (the hub + machineid->assetid crosswalk), locations, printers, communications, applications (+ installs), warranties, notifications, knowledgebase, relationships, subnets, usb, verify.

Last full run: 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. UI spot-check passed (computer list + shop-floor map).

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