Fix bit(1) import coercion and subpath login redirect; add GitHub export script
Loader: bool() on pymysql bit(1) bytes is always true - isinstallable and isshopfloor imported as 1 for every row; route through _truthy_bit. The employee source DB is now optional (shopdb-only imports). Frontend: under a subpath mount the 401 interceptor stored the browser path (mount base included) as the login redirect and the router applied its base again (/ops/ops). New stripBase() keeps redirects base-free. tools/export-github.sh automates the publication flow: prune + scrub + commit into ~/projects/shopdb-flask-pub and emit a transfer bundle.
This commit is contained in:
@@ -16,6 +16,8 @@ the machineid->assetid crosswalk this harness persists.
|
||||
|
||||
import argparse
|
||||
|
||||
import pymysql
|
||||
|
||||
from .harness import Harness
|
||||
|
||||
|
||||
@@ -451,7 +453,7 @@ def stage_applications(h):
|
||||
continue
|
||||
payload = {'appname': name, 'appdescription': a['appdescription'],
|
||||
'supportteamid': h.ids.get('supportteam', a['supportteamid']),
|
||||
'isinstallable': bool(a['isinstallable']),
|
||||
'isinstallable': _truthy_bit(a['isinstallable']),
|
||||
'applicationnotes': a['applicationnotes'], 'installpath': a['installpath'],
|
||||
'applicationlink': a['applicationlink'],
|
||||
'documentationpath': a['documentationpath']}
|
||||
@@ -534,13 +536,17 @@ def stage_notifications(h):
|
||||
|
||||
# SSO -> "First Last" from the employee source, so recognition/training
|
||||
# notifications display a name, not a bare SSO (the model shows employeename
|
||||
# or falls back to employeesso).
|
||||
# or falls back to employeesso). Employee source is optional: without it
|
||||
# (shopdb-only import) notifications keep the bare SSO.
|
||||
ssoname = {}
|
||||
for e in h.source.rows('wjf_employees_src',
|
||||
'SELECT SSO, First_Name, Last_Name FROM employees'):
|
||||
full = f"{(e['First_Name'] or '').strip()} {(e['Last_Name'] or '').strip()}".strip()
|
||||
if full:
|
||||
ssoname[str(e['SSO']).strip()] = full
|
||||
try:
|
||||
for e in h.source.rows('wjf_employees_src',
|
||||
'SELECT SSO, First_Name, Last_Name FROM employees'):
|
||||
full = f"{(e['First_Name'] or '').strip()} {(e['Last_Name'] or '').strip()}".strip()
|
||||
if full:
|
||||
ssoname[str(e['SSO']).strip()] = full
|
||||
except pymysql.err.OperationalError:
|
||||
print(' (no wjf_employees_src - notifications keep bare SSOs)')
|
||||
|
||||
def _names(employeesso):
|
||||
if not employeesso:
|
||||
@@ -566,7 +572,7 @@ def stage_notifications(h):
|
||||
'appid': h.ids.get('app', n['appid']),
|
||||
'starttime': str(n['starttime']) if n['starttime'] else None,
|
||||
'endtime': endtime, 'ticketnumber': n['ticketnumber'], 'link': n['link'],
|
||||
'isshopfloor': bool(n['isshopfloor']), 'employeesso': n['employeesso'],
|
||||
'isshopfloor': _truthy_bit(n['isshopfloor']), 'employeesso': n['employeesso'],
|
||||
'employeename': _names(n['employeesso'])}
|
||||
status, _ = h.post('/api/notifications', payload)
|
||||
if status in (200, 201):
|
||||
@@ -759,7 +765,11 @@ def stage_verify(h):
|
||||
from sqlalchemy import text
|
||||
report = {}
|
||||
for label, sdb, sql, target_table in checks:
|
||||
src = h.source.rows(sdb, sql)[0]['c']
|
||||
try:
|
||||
src = h.source.rows(sdb, sql)[0]['c']
|
||||
except pymysql.err.OperationalError:
|
||||
report[label] = 'source db absent - skipped'
|
||||
continue
|
||||
tgt = db.session.execute(text(f'SELECT COUNT(*) FROM {target_table}')).scalar()
|
||||
report[label] = f'source~{src} target={tgt}'
|
||||
return report
|
||||
|
||||
Reference in New Issue
Block a user