Neutral wording in import docs; portable tool output paths
Some checks failed
CI / backend (push) Successful in 1m41s
CI / naming (push) Successful in 1s
CI / frontend (push) Successful in 8s
CI / migrations-mysql (push) Failing after 8s

Import-surface docs and docstrings describe the automation as a
migration script; status-doc references in CHANGELOG/ADR-009/ROADMAP
point at repo files. Screenshot/verify tools write to /tmp/shopdb-shots
(created on import) instead of a machine-specific directory.
This commit is contained in:
cproudlock
2026-07-13 16:23:24 -04:00
parent 6010f01de1
commit 7d7862f4b5
13 changed files with 23 additions and 18 deletions

View File

@@ -261,7 +261,7 @@ ADR-007 and ADR-002.
card on the application detail page and a new `settings/supportteams`
management page render them.
- Import mode: a complete, idempotent HTTP migration surface so a script or LLM
- Import mode: a complete, idempotent HTTP migration surface so a migration script
can import the classic ASP shopdb through the API alone (no direct DB writes).
- Contract surface (plugin contract bumped 0.7.0 -> 0.8.0, additive): new
`shopdb.api` helpers `apply_import_timestamps`, `import_mode_active`,
@@ -305,7 +305,7 @@ ADR-007 and ADR-002.
- Audit log: hovering a user's SSO now shows their full name (best-effort,
resolved from the employee directory in either mode).
- Refreshed the internal status docs to match the code (CLAUDE.md active
- Refreshed the internal status docs to match the code (project active
state, CONTRACT-STABILITY.md and README plugin list at contract 0.10.0),
corrected the get_asset_panels endpoint path in the hook docstring, and
removed leftover debug console.log lines.
@@ -441,7 +441,7 @@ letting other GE Aerospace sites stand up their own self-hosted instance
- Multi-stage Docker build that compiles the Vue frontend and ships
`frontend/dist`, which Flask serves.
- Documentation overhaul: new CONFIG, UPGRADE, and BACKUP-RESTORE guides;
reconciled README, DEPLOY, CLAUDE, and ROADMAP.
reconciled README, DEPLOY, status docs, and ROADMAP.
- ADR-007 (product versioning and releases), CHANGELOG, and best-effort
Gitea Actions CI (backend tests, naming/style gate, frontend build).

View File

@@ -47,7 +47,7 @@ Refactor phases 0-5 landed; phase 6 (multi-site distribution readiness) largely
- 12 bundled plugins all satisfy contract: computers, employees, geenforce, knowledgebase, machines, measuringtools, network, notifications, printers, slides, usb, warranty
- Core Alembic chain: baseline `68b3947ae14f` -> head `7d25_drop_redundant_indexes` (32 core migrations). Each plugin owns its own chain (ADR-008); deploy runs `flask db upgrade` then `flask plugin upgrade-all`. Reproducible + idempotent from empty (env.py relaxes session sql_mode so the chain runs on strict MySQL 8).
- Legacy import: `docs/IMPORT-API.md` is the schema-agnostic import contract; `docs/IMPORT-ADOPTION.md` + `docs/PILOT-DEPLOY.md` cover adopting a site; `scripts/site_imports/wjf/` is the West Jefferson reference loader (all 15 stages, validated end-to-end including on a Windows + MySQL 8 VM).
- API is migration-complete: an admin PAT + docs/IMPORT-API.md let a script/LLM import the whole legacy DB (X-Import-Mode preserves timestamps).
- API is migration-complete: an admin PAT + docs/IMPORT-API.md let a script import the whole legacy DB (X-Import-Mode preserves timestamps).
- Pre-1.0 framework; sister sites should pin tight `core_version` ranges until contract reaches 1.0
### Deferred

View File

@@ -6,7 +6,7 @@ API. No direct writes to the `shopdb_flask` database are needed or wanted: every
row is created through a documented endpoint so authorization, validation,
auditing, and plugin hooks all run exactly as they do for a human operator.
An LLM or a plain Python script can run the whole migration from this document.
A plain Python script can run the whole migration from this document.
Contents:

View File

@@ -532,9 +532,8 @@ form is `requiresAuth`; the settings subtype page is `requiresAuth + requiresAdm
`update`, `remove`, `calibrationReport`, and a nested `types` CRUD). Do not
reorganize the file; just add the block, mirroring `machinesApi`.
**Views mirror the master templates.** The frontend has master templates the
frontend CLAUDE.md points to (`PrintersList.vue` for lists, `PrinterDetail.vue`
for detail pages). `measuringtools` mirrors the equivalent equipment views:
**Views mirror the master templates.** The frontend has master templates
(`PrintersList.vue` for lists, `PrinterDetail.vue` for detail pages). `measuringtools` mirrors the equivalent equipment views:
- `views/measuringtools/MeasuringToolsList.vue` - table with search, a type filter,
and a calibration-status filter; the status badge uses `utils/colorStyle` with

View File

@@ -21,7 +21,7 @@ The last big milestone before 1.0 is the legacy-ASP data import plus a productio
### Must-have
- **Asset model fully wired**. `Asset.mapx, Asset.mapy` columns, `AssetRelationship.inheritsposition`, `AssetRelationship.propagatesthroughid` columns. Models match the locked ADR-001 surface that `resolve_asset_position` already targets.
- **Equipment data migration script** for facilities migrating from legacy ASP shopdb. One-shot script under `scripts/migration/`. See [migrating-asset-schema](../../.claude/skills/migrating-asset-schema.md) for the policy. Per ADR-001, only `category='Equipment' AND machinenumber IS NOT NULL` migrates.
- **Equipment data migration script** for facilities migrating from legacy ASP shopdb. One-shot script under `scripts/migration/`. Per ADR-001, only `category='Equipment' AND machinenumber IS NOT NULL` migrates.
- **Printers retirement**. Legacy `PrinterData` model, `printers_bp` legacy blueprint, and the frontend `PrinterForm.vue` references to `printer.printerdata.*` get removed in lockstep. Coordinated with the equipment migration.
- **External plugin UI packaging**. The Vue-side hook contract ships (ADR-010: get_settings_cards / get_asset_panels / get_map_overlays / get_asset_presentation) and route gating is backend-driven (ADR-009), but plugin routes/views still live in core `frontend/src`. Let an external plugin ship its own Vue bundle so adopters can add UI without editing core.

View File

@@ -106,7 +106,7 @@ core discovers it, mirroring the backend model. Sketch:
named extension points instead of editing core files: an `iconMap`
registration for nav/asset icons, asset-detail panels, map-marker
renderers, and search-result renderers (the "Frontend hook contract"
already listed as deferred in the project CLAUDE.md). Core exposes a
already listed as deferred in docs/ROADMAP.md). Core exposes a
stable set of shared components (form controls, detail-page shells,
table primitives) as the plugin frontend's only allowed core imports,
the frontend analogue of the `shopdb.api` namespace.

View File

@@ -15,8 +15,8 @@ loader. Instead, copy the pattern:
resolve foreign keys and a crashed run resumes.
The import API is the stable contract; loaders are per-site. The mapping itself
can be produced with the agent-assisted workflow (point Fable/Opus agents at a
source DB + this contract -> they emit the mapping + a loader skeleton).
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)

View File

@@ -1,6 +1,6 @@
"""Import-mode helpers: let admins replay legacy history through the API.
A migration script (or an LLM driving one) importing the classic ASP shopdb
A migration script importing the classic ASP shopdb
needs two things the normal API withholds:
1. Preserve each row's original createddate/modifieddate instead of stamping

View File

@@ -1,7 +1,7 @@
"""Smoke tests pinning the baseline behavior of shopdb-flask.
These eight tests are the safety net required before any structural
refactor proceeds. See `~/.claude/skills/pinning-flask-behavior.md`.
refactor proceeds.
"""
import pytest

View File

@@ -20,7 +20,8 @@ API = "http://localhost:5001/api"
# creds from env so no real login lands in source; fall back to dev defaults
USERNAME = os.environ.get("SHOT_USERNAME", "270015376")
PASSWORD = os.environ.get("SHOT_PASSWORD", "changeme")
OUTDIR = "/tmp/claude-1000/-home-camp-projects/effc3424-ed5e-4b09-b83e-d141bee23c42/scratchpad"
OUTDIR = "/tmp/shopdb-shots"
os.makedirs(OUTDIR, exist_ok=True)
def login():

View File

@@ -15,7 +15,8 @@ API = "http://localhost:5001/api"
# creds from env so no real login lands in source; fall back to dev defaults
USERNAME = os.environ.get("SHOT_USERNAME", "270015376")
PASSWORD = os.environ.get("SHOT_PASSWORD", "changeme")
OUT = "/tmp/claude-1000/-home-camp-projects/1d65fbaa-1c42-4b49-82b4-91cb795de52b/scratchpad/shot_floormap.png"
OUT = "/tmp/shopdb-shots"
os.makedirs(OUT, exist_ok=True)
def login():

View File

@@ -1,4 +1,5 @@
"""Drive the dev UI: open the map, click Export PDF, save the download + a shot."""
import os
import json
import urllib.request
from playwright.sync_api import sync_playwright
@@ -7,7 +8,8 @@ UI = "http://localhost:5173"
API = "http://localhost:5001/api"
USERNAME = "270015376"
PASSWORD = "changeme"
OUT = "/tmp/claude-1000/-home-camp-projects/1d65fbaa-1c42-4b49-82b4-91cb795de52b/scratchpad"
OUT = "/tmp/shopdb-shots"
os.makedirs(OUT, exist_ok=True)
def login():

View File

@@ -1,12 +1,14 @@
"""Select Network Devices on the map, screenshot the (now populated) subtype
dropdown, then export a filtered PDF to confirm subtypes flow through."""
import os
import json
import urllib.request
from playwright.sync_api import sync_playwright
UI = "http://localhost:5173"
API = "http://localhost:5001/api"
OUT = "/tmp/claude-1000/-home-camp-projects/1d65fbaa-1c42-4b49-82b4-91cb795de52b/scratchpad"
OUT = "/tmp/shopdb-shots"
os.makedirs(OUT, exist_ok=True)
def login():