T8.6 - D6: the material list uploads the way the location list does
CR-013 accepted free text because the master workbook never arrived; the
Aug 18 call was the CR-005 call again - build the upload path now.
THE component, extracted: T5.4's paste-or-file machinery (file read in the
browser, ONE parser on the server; dry-run check; a report naming every
rejected row with its source line; an editable list that deactivates rather
than deletes) moved from the location-specific functions into
html/wp-list-import.js. The location list and the new material list are both
instances of it - the done-when's "against the same component, not beside it"
made literally true. The loc* names survive as thin delegates because row
handlers, step entry and the probes call them; locations_check re-pointed its
fetch-count assertion to where the fetches now live and still demands every
read and write reach the server.
The material list itself: description, unit, optional code - one new table
(Alembic a1b8c6d4e2f9, additive), GET/import/POST/PATCH routes on the CR-005
pattern, deactivate-never-delete, reactivation reuses the same row so nothing
referencing it orphans. The sample rows are obviously fake (SAMPLE-EMT-075).
NO inventory, price, stock or warehouse field anywhere - the probe walks the
model's columns by regex. The wizard hosts it on step 11 beside the location
list, optional by design: a project with no list still raises free-text
requests (T8.5 wires that).
Parser bug caught by the probe's first run: strip(',;') ate a LEADING comma,
so ',FT' - an empty description - was accepted as a material named FT.
rstrip only, now; the empty first column is rejected with its line number.
Verification (each probe run alone): NEW tests/materials_check.py 17/17.
Regression: locations_check 58/58 through the shared component.
Items: D6
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -344,8 +344,18 @@ def run(page, base, tok):
|
||||
if not ln.strip().startswith(("//", "*", "/*")))
|
||||
chk("...and never touches localStorage", "localStorage" not in code_only,
|
||||
[ln for ln in code_only.splitlines() if "localStorage" in ln][:3])
|
||||
# Re-pointed at T8.6, not relaxed: the fetches moved into the shared list
|
||||
# component (wp-list-import.js) when the material list was built "against
|
||||
# the same component" (D6). The proposition is unchanged - every read and
|
||||
# write reaches the server - so it is asserted where the fetches now live,
|
||||
# plus the wiring that sends THIS list's traffic there.
|
||||
comp = open(os.path.join(ROOT, "html", "wp-list-import.js"), encoding="utf-8").read()
|
||||
comp_code = chr(10).join(ln for ln in comp.splitlines()
|
||||
if not ln.strip().startswith(("//", "*", "/*")))
|
||||
chk("...reaching the server for every read and write",
|
||||
block.count("fetch(locApi") >= 4, block.count("fetch(locApi"))
|
||||
"api: locApi" in block and comp_code.count("fetch(cfg.api") >= 4
|
||||
and "localStorage" not in comp_code,
|
||||
(block.count("api: locApi"), comp_code.count("fetch(cfg.api")))
|
||||
|
||||
# The B100 floor/area list has not been supplied (IMPLEMENTATION.md section 8),
|
||||
# so any of these appearing as a location value would be a guess presented as
|
||||
|
||||
Reference in New Issue
Block a user