Skip to content

Add budget-driven Restocking tab and Claude Code workflowNew features - #256

Open
tsharish wants to merge 2 commits into
beck-source:mainfrom
tsharish:new_features
Open

Add budget-driven Restocking tab and Claude Code workflowNew features#256
tsharish wants to merge 2 commits into
beck-source:mainfrom
tsharish:new_features

Conversation

@tsharish

Copy link
Copy Markdown

Summary

Two independent changes, one commit each:

  1. 8b9a11a — Restocking tab. A new view that recommends what to reorder from the demand forecast for a given budget, plus a "Submitted Orders" section in the Orders tab showing delivery lead time.
  2. 04ca729 — Claude Code GitHub Actions workflow. Responds to @claude mentions. Inert until two manual steps are done — see below.

Restocking tab

Frontend

  • New client/src/views/Restocking.vue: budget slider ($0–$10,000 in $250 steps) driving a greedy-by-shortfall allocation, with a partial fill on the last affordable line. Full-coverage cost is computed from the loaded forecasts rather than hardcoded, so it tracks fixture changes.
  • Orders.vue gains a "Submitted Orders" card above All Orders, loading independently of the FilterBar.
  • en/ja locales at parity (266 keys, no gaps).

Backend

  • demand_forecasts.json gains unit_cost and lead_time_days on all 9 records. PSU-501 reuses its real inventory cost ($18.99); the other 8 SKUs have no inventory row, so costs are set per part type.
  • POST /api/restock-orders re-validates budget, SKUs and quantities server-side, so the client cannot overspend even if its arithmetic drifts. GET /api/restock-orders lists newest first.

Two bugs caught during review

  • Float drift dropped a line item. At exactly the advertised full-coverage budget ($6,832.48), accumulated float subtraction left the remaining budget at 95.99999999999957 instead of 96.00. VLV-506 costs exactly $96.00, so it failed the affordability check, and Math.floor(95.99999999999957 / 96.0) then returned 0 — delivering 7 of 8 items with $96 unspent. Fixed by rounding to cents at each step. Deliberately not fixed with an epsilon (>= fullCost - 0.01), which would permit a one-cent overspend.
  • Cents dropped in display. The shared formatCurrency uses maximumFractionDigits: 0, so unit costs rendered as $25 against a line total of $3,675 — 150 × $25 = $3,750, and nothing on screen reconciled. Restocking now uses the pre-existing formatCurrencyWithDecimals(..., 2). The shared currency.js is unchanged, since Dashboard, Spending, Reports and Orders all depend on its 0-decimal default.

Testing

59 backend tests pass (40 pre-existing + 19 new in tests/backend/test_restocking.py). New tests are written relative to a baseline count, since the order list accumulates within a session.

Verified live end-to-end: at a $7,000 budget all 8 shortfall items are recommended, every line total equals quantity × unit cost exactly, summing to $6,832.48 with $167.52 remaining. A submitted order appeared in Orders with a 28-day lead time and the correct delivery date.

Known limitations

  • Submitted orders are process-scoped and lost on restart. This app has no database by design.
  • The slider's $250 step makes $6,832.48 unreachable — the neighbouring stops are $6,750 and $7,000. Full coverage is therefore only achievable by overshooting.
  • JPY line items don't reconcile to the cent. currency.js rounds each converted value independently and yen has no subunit, so a unit price of ¥1,838 shows against a ¥198,450 line total (¥54 across 108 units, ~0.03%). Inherent to the shared util, which this PR leaves alone.
  • The Orders tables show raw amounts with a currency symbol and no JPY conversion. Pre-existing behaviour in All Orders; Submitted Orders deliberately mirrors it rather than introducing an inconsistency.

The workflow file needs two manual steps

.github/workflows/claude.yml does nothing until someone with repo admin also:

  1. Installs the Claude GitHub App on this repository.
  2. Adds an ANTHROPIC_API_KEY repository secret.

/install-github-app could not be used to automate this: it needs an interactive terminal for the OAuth grant, and the gh CLI is not installed on the dev machine.

Security notes for a public repo: no credential is committed — only the secrets.ANTHROPIC_API_KEY reference. The action only runs for commenters with write access, and GitHub withholds secrets from fork-PR runs. client/.npmrc and the client/package-lock.json gitignore rule are untouched.

Not included

docs/architecture.html (written earlier in the same session) is intentionally left out. It predates this feature — it says 14 endpoints when there are now 16, and doesn't mention the Restocking tab. It'll come in a separate PR once refreshed.

🤖 Generated with Claude Code

tsharish and others added 2 commits August 27, 2026 14:06
Adds a Restocking view that recommends what to reorder from the demand
forecast for a given budget, and surfaces submitted orders in the Orders tab.

Frontend:
- New Restocking.vue: budget slider ($0-$10,000, $250 steps) driving a
  greedy-by-shortfall allocation with partial fills on the last affordable
  line. Full-coverage cost is computed from the loaded forecasts rather
  than hardcoded, so it tracks fixture changes.
- Money math is rounded to cents at each step. Accumulated float
  subtraction otherwise left the remaining budget at 95.99999999999957
  instead of 96.00, which silently dropped a $96.00 line item and left
  the budget unspent at exactly the full-coverage figure.
- Restocking uses formatCurrencyWithDecimals(..., 2) for unit costs and
  line totals so they reconcile against quantity. The shared
  currency.js default of 0 decimals is unchanged, since Dashboard,
  Spending, Reports and Orders all depend on it.
- Orders.vue gains a "Submitted Orders" card above All Orders showing
  lead time and expected delivery; loads independently of the FilterBar.
- en/ja locales at parity (266 keys, no gaps).

Backend:
- demand_forecasts.json gains unit_cost and lead_time_days on all 9
  records. PSU-501 reuses its real inventory cost ($18.99); the other 8
  SKUs have no inventory row, so costs are set per part type.
- POST /api/restock-orders re-validates the budget, SKUs and quantities
  server-side, so the client cannot overspend even if its arithmetic
  drifts. GET /api/restock-orders lists newest first.
- Orders are stored in a process-scoped list and are lost on restart;
  this app has no database by design.

Tests: 19 new backend tests (59 total, all passing), written relative to
a baseline count since the order list accumulates within a session.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Responds to @claude mentions on issues and PR review comments, pinned to
anthropics/claude-code-action@v1.

This is step 3 of the manual setup only. The workflow does nothing until
someone with repo admin also:
  1. installs the Claude GitHub App (github.com/apps/claude)
  2. adds an ANTHROPIC_API_KEY repository secret

/install-github-app could not be used here: it needs an interactive
terminal for the OAuth grant and the gh CLI, which is not installed.

On this public repo the action only runs for commenters with write
access, and GitHub withholds secrets from fork-PR runs. No credential is
committed here, only the secrets.ANTHROPIC_API_KEY reference.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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