Docs audit fixes: kiosk code drift, PowerShell chains, broken links, leaks
Some checks failed
CI / backend (push) Successful in 1m45s
CI / naming (push) Successful in 1s
CI / frontend (push) Successful in 8s
CI / migrations-mysql (push) Failing after 8s

From the Fable/Opus documentation audit (8 confirmed + verified
lab-drift the run's session limit had cut short):
- HIGH: the lab's kiosk _kiosk_find_item block showed the pre-stage-17
  row-id resolver as current; replace with the shipped gagelabtag /
  numeric-tail resolver, fix the stale 'resolved by row id' prose and
  the 'stage-7 code is corrected' note.
- MED: the badge _external_lookup block used dict-only row access that
  breaks on a tuple cursor; use the tuple-or-dict form shipped. Split
  '&&' command chains (fail in PowerShell 5.1) in the lab.
- LOW/link: the Windows note's [DEVELOPMENT-SETUP] link dropped the .md
  and 404'd in four docs; fix. Correct the stage-6a->16a comment and
  the lab-stage tag range (..16 -> ..17).
- Leaks: drop /home/camp path from ADR-006, the internal gitea host
  from PLUGINS.md.
- Windows: add an mklink junction note for the external-plugin symlink
  dev loop.
- CI: prime root to mysql_native_password so pymysql connects to the
  MySQL 8 service without the cryptography package (and its kit wheel).
This commit is contained in:
cproudlock
2026-07-17 18:05:47 -04:00
parent aba588cc07
commit efb879d44a
7 changed files with 53 additions and 31 deletions

View File

@@ -17,7 +17,7 @@ decision records: `docs/proposals/printedparts-plugin.md`.
> **Windows / VS Code:** command examples below use the Linux venv path
> `venv/bin/python`; on Windows use `venv\Scripts\python` and
> `$env:FLASK_APP="shopdb"` (not `export`). Full Windows onboarding:
> [DEVELOPMENT-SETUP](DEVELOPMENT-SETUP).
> [DEVELOPMENT-SETUP](DEVELOPMENT-SETUP.md).
Know before you start
@@ -262,7 +262,7 @@ def downgrade():
See it work:
```
flask plugin install printedparts && flask plugin enable printedparts
flask plugin install printedparts; flask plugin enable printedparts
mysql> SHOW TABLES LIKE 'printed%'; -- both tables
mysql> SELECT * FROM alembic_version_printedparts; -- printedparts0001baseline
flask plugin upgrade-all -- printedparts: ok
@@ -299,7 +299,7 @@ printedparts_bp = Blueprint('printedparts', __name__)
@printedparts_bp.route('/items', methods=['GET'])
@jwt_required(optional=True) # stage 6a tightens this to view-gated
@jwt_required(optional=True) # stage 16a tightens this to view-gated
def list_items():
"""List printed items, paginated; search + low-stock filter."""
page, per_page = get_pagination_params(request)
@@ -629,10 +629,11 @@ def _external_lookup(kind, digits):
f'WHERE {column} = %s', (digits,))
row = cursor.fetchone()
if row:
sso = str(row['SSO'])
name = f"{(row['First_Name'] or '').strip()} " \
f"{(row['Last_Name'] or '').strip()}".strip()
return sso, name
# pymysql may return a tuple or a dict cursor - handle both.
sso = str(row[0] if not isinstance(row, dict) else row['SSO'])
first = row[1] if not isinstance(row, dict) else row['First_Name']
last = row[2] if not isinstance(row, dict) else row['Last_Name']
return sso, f"{(first or '').strip()} {(last or '').strip()}".strip()
except Exception:
logger.exception('HR directory lookup failed for %s %s', kind, digits)
finally:
@@ -798,17 +799,25 @@ catch you (below).
def _kiosk_find_item(itemcode):
"""Resolve a scanned or typed code to an active item.
Accepts the full code (WJRP0042) or bare digits from the touch keypad -
the digits in a minted code ARE the row id, so id lookup keeps working
even for labels printed under an older prefix."""
itemcode = (itemcode or '').strip()
Matches the internal code OR the gage-lab tag exactly; bare keypad
digits match the numeric tail of EITHER identifier, and only when
exactly one active item matches (see stage 17)."""
scanned = (itemcode or '').strip().upper()
item = PrintedItem.query.filter(
PrintedItem.itemcode == itemcode,
or_(PrintedItem.itemcode == scanned,
PrintedItem.gagelabtag == scanned),
PrintedItem.isactive == True).first()
if not item and itemcode.isdigit():
candidate = db.session.get(PrintedItem, int(itemcode))
if candidate and candidate.isactive:
item = candidate
if not item and scanned.isdigit():
wanted = int(scanned)
matches = []
for candidate in PrintedItem.query.filter_by(isactive=True).all():
for value in (candidate.itemcode, candidate.gagelabtag):
tail = ''.join(ch for ch in (value or '') if ch.isdigit())
if tail and int(tail) == wanted:
matches.append(candidate)
break
if len(matches) == 1:
item = matches[0]
return item
@@ -920,7 +929,8 @@ function onWedgeEnter() {
```
Manual fallbacks use the TouchKeypad: badge entry is digits (an SSO), and
item entry is bare digits resolved by row id server-side - no alphanumeric
item entry is bare digits matched server-side against the numeric tail of
either the internal code or the gage-lab tag (unique match only) - no alphanumeric
on-screen keyboard needed. Success screen auto-resets after a few seconds.
Full component (~250 lines) at the tag.
@@ -1093,7 +1103,7 @@ failure. Summaries here; complete diffs at the tags.
hit the deny policy. Lesson: anything resolving PEOPLE must honor the
site's directory mode (the stage-5 code above is the corrected version).
- **16 - touchscreen findings** (`lab-stage-16`): the focus-steal guard and
keypad-driven manual entry (the stage-7 code above is the corrected
keypad-driven manual entry (the kiosk resolver above is the stage-17
version).
- **17 - the gage-lab asset tag** (`lab-stage-17`): the field team assigns
@@ -1134,11 +1144,12 @@ for a contributor:
2. **Build in stage-sized commits** exactly as this lab does - each commit a
working checkpoint with its tests. Subject line: short, plain English,
present tense ("printedparts stage 5: the ledger"); body says WHY.
3. **Before every push**, the same three gates CI runs:
```bash
bash scripts/check-naming-and-style.sh
venv/bin/python -m pytest tests/ -q
cd frontend && npx vitest run && npm run build
3. **Before every push**, run the three gates CI runs (in VS Code: the
**Check: naming + tests + build** task). By hand in PowerShell:
```powershell
venv\Scripts\python -m pytest tests/ -q
cd frontend; npx vitest run; npm run build; cd ..
bash scripts/check-naming-and-style.sh # naming - runs via Git Bash
```
4. **Push your branch and open a Pull Request** against `main`:
```bash
@@ -1179,4 +1190,4 @@ for a contributor:
| List/Detail master templates | `PrintersList.vue`, `PrinterDetail.vue` |
| Reports hook + CSV | `plugins/warranty/` + `shopdb/core/api/reports.py` |
| Permissions declaration | `plugins/usb/plugin.py::get_permissions` |
| The finished plugin itself | branch `feat/printedparts-plugin`, tags `lab-stage-01..16` |
| The finished plugin itself | branch `feat/printedparts-plugin`, tags `lab-stage-01..17` |