Skip to content

feat: console view — inventory grid with CRUD, price/sold/listing dialogs, CSV import/export (0.2.0) - #1

Merged
mabry1985 merged 4 commits into
mainfrom
feat/console-view
Sep 12, 2026
Merged

mabry1985 merged 4 commits into
mainfrom
feat/console-view

Conversation

@mabry1985

Copy link
Copy Markdown
Member

Slice 2 of the inventory plugin: manual CRUD

The rail view. Everything the tools can do, an operator can do by hand here: lots, items, targets with a basis, sales with fees netted out, listings, CSV in and out, and the audit log.

Draft until the local smoke test (real DS kit, headless browser) passes — screenshots will be attached.

Rules honoured

  • Page on the public /plugins/inventory prefix, data on the gated /api/plugins/inventory prefix (two routers).
  • BASE derived from the page URL; kit CSS/JS off BASE; kit.apiFetch for all data; the kit owns the handshake.
  • The status select refuses a bare "sold" and opens the sale dialog, matching the tools and the API.

Tests

60 host-free (was 57): declared view path served with text/html and 404 under /api; four-rules assertions on the page source; a grep-level guard that data is only interpolated through esc()/fmt().

🤖 Generated with Claude Code

https://claude.ai/code/session_011UQ33xXfygwEkzbbJx3YwZ

@mabry1985
mabry1985 marked this pull request as ready for review September 12, 2026 10:23
@protoreview

protoreview Bot commented Sep 12, 2026

Copy link
Copy Markdown

⚠️ QA panel exhausted — this PR has not been reviewed.
The review panel failed after 2 attempt(s) on head e718a22a7617. No verdict was posted.
A new push will re-trigger the review.

@protoreview

protoreview Bot commented Sep 12, 2026

Copy link
Copy Markdown

⚠️ QA panel exhausted — this PR has not been reviewed.
The review panel failed after 2 attempt(s) on head cf3fc1aa2c94. No verdict was posted.
A new push will re-trigger the review.

@mabry1985

Copy link
Copy Markdown
Member Author

@vera review

mabry1985 and others added 4 commits September 12, 2026 03:48
…import/export

A rail view (manifest `views[]`, icon Boxes) served on the PUBLIC /plugins/inventory
prefix; every byte of data comes through the gated /api/plugins/inventory router via the
DS kit's authed, slug-aware fetch. Vanilla JS + the design-system kit; no build step.

- Items grid: double-click to edit name / category / condition / qty inline; status
  select (choosing "sold" opens the sale dialog instead of a bare status write); click a
  price for the Price dialog (basis REQUIRED, optional comps recorded as an observation);
  per-row Price / Sold / List / Edit / Delete.
- Stat tiles from /summary (lot cost, remaining at target with the low–high band,
  realized net, projected net at target, items + unpriced), scoped to the selected lot.
- Lots tab with the per-lot roll-up + edit/delete; Sales tab; Activity (audit) tab.
- CSV import (file or paste; kind auto/items/lots; default lot) with the mapping report
  left open in the dialog; CSV export of the current filter.
- Four-rules tests: the manifest path is served publicly and not under /api; kit links off
  BASE; apiFetch only; no hand-rolled theme map or message listener; escaped rendering.
- 60 host-free tests (was 57). 0.2.0.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011UQ33xXfygwEkzbbJx3YwZ
…e; node syntax check in the suite

The lots table template ended a single-quoted string with a double quote, a SyntaxError
that stopped the whole module before any handler was wired — the chrome rendered, no
data, no error banner. Found by the local smoke run; the Python tests cannot see it, so
the suite now runs node --check on both scripts (skipped where node is absent).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011UQ33xXfygwEkzbbJx3YwZ
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011UQ33xXfygwEkzbbJx3YwZ
…y signs, guards

- Edit dialog sends `status` only when it changed, so a sold item's name can be fixed
  (an unchanged "sold" was refused by the API and the dialog could never save).
- Deleting the filtered lot clears the filter; render() drops a filter whose lot is gone.
- fmt(-12.5) is "-$12.50" (was "$-12.50"); a `signed()` helper for the projected-net
  tiles, "—" for null instead of "+—".
- Inline edit refuses a blank name; the listing dialog reads the full item so its "Live:"
  hint is real; un-selling through the status select asks first (the sale stays on the
  books); an in-flight guard stops a slow load painting over a newer one; render on error
  so the chrome matches state; Escape closes dialogs; the dialog takes focus when it has
  no inputs; the view route is out of the schema; dead code removed.
- Tests: the four-rules check now fails a page with a hand-rolled theme map, a message
  sniffer, a hardcoded host or an un-kitted fetch, and asserts the public router serves
  exactly the manifest path; a node harness runs the real module with a stub DOM and
  checks money formatting, the escaper and the field builder against hostile values.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011UQ33xXfygwEkzbbJx3YwZ
@mabry1985

Copy link
Copy Markdown
Member Author

Rebased onto main after #2 (only the two version lines conflicted). 113 tests. Vera's panel is exhausting on this repo from upstream rate limiting; the view had an in-session adversarial review (XSS executed clean; D1–D9 fixed in 9ddeae1). Merging on CI green.

@mabry1985
mabry1985 merged commit 849fa01 into main Sep 12, 2026
1 check passed
@mabry1985
mabry1985 deleted the feat/console-view branch September 12, 2026 10:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant