Same bug as backend — perRollMultiplier (0.05) was applied as a direct
multiplier on base roll cost in the admin shop EV simulation, making
everything appear exploitable (red).
- i18n: widen Translations type to accept any string values
- home: fix async onMount returning cleanup function
- CreateProjectModal: import Project from stores instead of local interface
- user profile: non-null assert githubUrl inside existence check
- Add fetchServerConfig to config.ts (fetches /admin/config endpoint)
- Call fetchServerConfig in +layout.svelte onMount for early client init
- Format long lines in admin dashboard page
- Add displayRollCost to ShopItem interface in stores
- ShopItemModal and shop page prefer server-provided displayRollCost
- Clean up as-any casts in ShopItemModal roll cost computation
- Admin shop: add perRollMultiplier to item type and EV simulation
- Remove unused modalEV derived (dead code, formEV used in template)
- Delete modal requires reason (min 3 chars) before sending DELETE
- Undo toast allows 30-second window to restore deleted order
- Admin user detail page: replace soft-delete + DELETE with single DELETE
call including reason payload
- Add lightweight DOM toast helper for status messages
- 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
- 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