- change DOLLARS_PER_HOUR from 5 to 4 across backend and frontend
- merge soft-delete/restore/permanent-delete into single DELETE endpoint
- refund scraps, restore inventory, reverse penalties, and delete order row in one step
- add console.log for admin order reverts with full context
- simplify admin orders UI to single revert button with confirmation modal
- New nullable roll_cost_override column on shop_items (migration 0011)
- calculateRollCost uses override if set, otherwise auto-calculates
- Admin UI: new 'roll cost override' input with auto placeholder + reset button
- EV simulation and item cards respect the override
- Frontend shop page + ShopItemModal use override for display and affordability
- Backend try-luck endpoint uses override from locked row
- calculatePricing now accepts optional priceOverride parameter
- When price is overridden, optimal pricing uses actual price for EV checks
- hasCustomPricing now also checks price mismatch
- calculateShopItemPricing now simulates all upgrade levels and bumps
baseUpgradeCost until expectedTotalCost >= price at every level
- Synced to shop-pricing.ts (computeItemPricing) and frontend calculatePricing
- All price points from $5-$800 verified safe (house edge 0.2-18%)
- Show detailed required/available scraps in insufficient funds errors
- ShopItemModal: check data.error/data.success instead of response.ok
(backend returns 200 for all responses including errors, so response.ok
was always true and errors were silently swallowed, closing the modal)
- Shop page + ShopItemModal: use baseProbability for roll cost display
(matching backend calculateRollCost which uses fixed base probability)
- Auth: anchor session cookie regex to prevent matching wrong cookies
- Auth: keep dev-mode reduced OAuth scopes
- Fix upgradeBudget: was 3×price−rollCost, now 1.5×price to match backend
- Add direct scraps price override input (yellow border when overridden)
- Auto-detect overrides when editing existing items
- Update pricing model reference panel to match actual backend semantics
- Fix win condition display: show eff% × 17/20 threshold
- Use effectiveProbability (not baseProbability) for roll cost
- Add computeRollThreshold (17/20) for actual win chance calculation
- Rename EVSummary fields to bestPlayer* (remove old optimal*/base*/maxUpgrade*)
- Update modal form EV display to use new property names
- Add actualWinChance column to detailed EV table
- Simplify item card EV display to show house edge + best strategy
The regex /session=([^;]+)/ was matching _theseus_session (from
HackClub auth) instead of the actual session cookie, since it matched
the first occurrence of 'session=' anywhere in the cookie string.
Changed to /(?:^|;\s*)session=([^;]+)/ which only matches 'session'
at the start of the string or after a semicolon separator.
Also returns a 200 HTML page with meta-refresh instead of a 302, to
ensure Set-Cookie is reliably stored by the browser before redirecting
to the frontend.
In dev, only requests: openid, profile, email, name, slack_id,
verification_status. Skips birthdate, address, and basic_info
which require additional verification.
- Changed refinery spent query from refinery_orders to refinery_spending_history
(refinery_orders rows are deleted on item win, inflating displayed balance)
- Removed extra status != 'permanently_rejected' filter from earned subqueries
to match getUserScrapsBalance which only checks scraps_paid_at IS NOT NULL
- Removed unused shopOrdersTable import
- Fix calculatePricing: use 'price * 3.0 - rollCost' matching backend
(was incorrectly using 'price * 1.5')
- Fix simulateEV: use baseProbability for rollCost (backend uses base,
not effective probability for roll cost)
- Fix simulateEV: use effectiveProbability directly as win chance
(backend has no threshold scaling, remove bogus computeRollThreshold)
- Fix house edge reference panel to reflect actual pricing model
- Add optimal pricing hint in add/edit modal showing server-calculated
values with yellow highlights when fields diverge from optimal
- Add 'use optimal' button to reset pricing fields to calculated values
- Update shop-pricing.ts return type to Promise<number>
- Add POST /admin/recalculate-shop-pricing endpoint (admin only)
that calls updateShopItemPricing() and returns updated item count
- Add recalculate button to admin dashboard under the admin-only
tools section with loading/error/success states
- Pricing already recalculates on server startup; this gives admins
a manual trigger after changing the calc formula or item data
- Roll cost now scales with effective probability (base + boosts - penalties)
instead of being fixed at base probability. At any probability level p,
expected roll spend = item price. Upgrades reduce variance, not expected
value. The house edge is exactly the total spent on refinery upgrades.
- Block refinery upgrades on out-of-stock items (both frontend and backend)
- Frontend refinery page shows sold out badge instead of upgrade button
- Update pricing calculator upgrade budget to reflect new model
- Fix lint: remove debug forEach, != to !==, unused variable