Commit graph

55 commits

Author SHA1 Message Date
b750004714 Show Newbook fetch timestamp with staleness warning on Daily Cash Up
Staff were seeing false 'out of balance' readings when the Newbook
totals shown were fetched at page load (or last manual click) and
had gone stale during the count, then balanced once re-checked
later against fresh Newbook data. Surfacing when the data was last
fetched, with a warning past 3 minutes, lets staff catch this before
submitting instead of assuming a real shortfall.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 17:31:20 +00:00
b4810aa2c1 Add iOS install hint + Apple PWA meta tags
iOS Safari has no beforeinstallprompt API, so the portal's Install
button (?install=1) silently did nothing there. IosInstallHint now
shows Share -> Add to Home Screen steps on Safari, or a prompt to
switch to Safari first if opened in another iOS browser/in-app
webview (those can't install PWAs on iOS at all).

Also added apple-mobile-web-app-title + apple-touch-icon so the
home screen icon isn't a page screenshot.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-06 14:12:12 +00:00
742960e5a1 Add Excel-style selection/sum to Safe Count's New Total column
Extract the click/shift-click cell selection + sum/avg status bar
from the weekly report into a shared useExcelSelection hook, and wire
it up to the New Total column (and its footer total) on Safe Count.
2026-08-03 09:08:11 +00:00
5c5d051c35 Fix history links opening today's cash up instead of the target date
Daily Cash Up initialised its date state from today() only, ignoring
the ?date= query param History links navigate with. Read it from the
URL on mount instead.
2026-08-03 08:56:35 +00:00
2e9b4a2ca3 Let admins unfinalise a cash up from history
Adds POST /api/cashup/:id/unfinalise (admin-only) to revert a
finalised cash up back to draft so it can be corrected, plus an
Unfinalise button in the history table for admin users.
2026-08-03 08:53:00 +00:00
cbabda81d5 Scope PWA manifest to app's own path instead of origin root
Every installed PWA claimed scope "/", so Android link-capturing routed
navigation for any app on the shared origin into whichever PWA had it.
2026-07-29 13:47:05 +00:00
1309ab5719 Fix PWA manifest scope to / per install-architecture doc
Scope was set to the app's own base path, which breaks the installed
PWA out of standalone mode into a regular browser tab on any
same-origin navigation outside that path (e.g. the auth redirect).
scope: "/" keeps navigation inside the installed app's window.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-24 17:06:42 +00:00
349fbb335c Fix logout (add missing nginx auth proxy) + show name/email in sidebar footer
The /cashup/api/auth/ → central auth nginx block was missing, so the logout
POST was hitting the app backend and returning 404 — cookie never cleared,
user stayed logged in. Also removes the stale navigate('/login') call and
shows name + email in the sidebar footer instead of name in the header.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-22 11:09:59 +00:00
5aafc0e99f Start cash up creates DB record immediately so photo uploads are available
Clicking 'Start Cash Up' now POSTs an empty draft to the backend straight
away, then reloads the record to populate cashUp.id — so PDQ Z-report and
receipt evidence uploaders are available without having to save a draft first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-20 22:43:11 +00:00
e9cf648f8c Add daily audit summary cross-checks to multiday report
Fetch reports_daily_audit_summary per day. Use cash_income total as the
reconciliation audit column (independent payment cross-check vs transaction
flow). Add a second Audit (DAS) column on the sales breakdown using
accrual_income totals alongside the earned revenue Audit (ER) column —
both highlight in amber if they diverge from the configured columns gross.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-20 09:23:30 +00:00
fa62c7c44a Fix sales breakdown Audit column — show all-groups total vs configured columns
Gross Total now sums only configured GL column gross amounts. Audit column
shows the all-groups earned revenue total (daily_gross_sales), with amber
variance highlight when they diverge — flags unconfigured GL groups the same
way the original WP plugin did.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-20 08:58:30 +00:00
dbef4b9f7a Fix sales breakdown GL matching — exact group ID instead of fuzzy names
Switch sales breakdown column matching from fuzzy name matching to exact
gl_group_id comparison. Add gl_account_groups_list endpoint for settings
sync so columns store real Newbook group IDs. Removes the name-based
fallback that was causing sundries VAT to bleed into sundries no-VAT.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-20 08:23:54 +00:00
2b04d99fd6 Fix mobile overflow on reconciliation, safe count, and settings tables
Tables with multiple columns now scroll horizontally within their cards
instead of overflowing off-screen on mobile.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-14 11:59:15 +00:00
82348bc834 Mobile-responsive layout and camera upload improvements
- Hamburger menu with slide-in nav for viewports < 700px; auto-closes on route change
- PhotoUploader: separate camera trigger on mobile (capture="environment"), file input hidden on mobile; useCallback to fix stale-closure reset
- Add .gitignore to exclude compiled JS artefacts and package-lock

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-14 08:57:54 +00:00
ad7d43f720 Configurable inactivity timeout — disabled automatically in PWA/standalone mode 2026-07-13 12:28:58 +00:00
f8847c0726 Redirect to login on mid-session 401 instead of silently failing
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-12 20:09:15 +00:00
a39b131e6a Replace letter icons with Lucide PWA icons 2026-07-11 20:30:05 +00:00
4a46bcf45f Make cashup installable as a PWA
vite-plugin-pwa with manifest scoped to /cashup/, purple £ icons matching
portal style, auto install prompt when opened with ?install=1 from the
portal dashboard, nginx no-cache rules for sw.js and manifest.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-11 10:54:50 +00:00
dec7ac2f3e Add shared device session timeout, sidebar scrollbar styling
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-10 12:24:40 +00:00
37453ddfda Return 200+null instead of 404 when no cash up found for date — eliminates browser console error 2026-07-07 20:56:34 +00:00
ed9cce1d76 Cashup: safe count adjust flow, cash summary cross-tab, table denomination view
Safe Count (new flow):
- Replaces simple re-use of FloatCountForm with a dedicated 3-column table:
  Current in Safe | Adjustment | New Total
- Loads the most recent safe_cash float count on mount to pre-populate Current
- Adjustment inputs accept positive (deposit) or negative (uplift/exchange) values
- New Total = Current + Adjustment per denomination; minimum clamped to 0
- Saves a new safe_cash float_count record via existing /floats/save endpoint

Cash Summary (redesign):
- Backend adds a per-date denomination query (by_date_denom) to the
  cash-summary endpoint in addition to the existing aggregate query
- Frontend rewritten as a cross-tab: denominations down rows, dates across
  columns, row totals on the right, per-day cash totals in the footer
- Status badges (draft/final) shown per column in a header row
- "+ Add to Safe" button navigates to /safe passing the period's denomination
  totals as React Router state, pre-filling the adjustment column

Float Management:
- Denomination entry form switched from CSS grid divs to a proper <table>
  matching the style of the print view (header row, qty input right-aligned,
  amount column, total in tfoot)
- DetailRecord type and FloatRecordPrint component exported so SafeCount can
  reuse the existing print/view component for safe cash records

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 11:56:45 +00:00
8b2dc4ad78 Cashup: preserve orphaned card machine data when settings name is removed
applyLoaded now appends any DB machines whose name is no longer in the
current settings list, rather than silently dropping them. This prevents
their amounts being deleted from the database the next time the record
is saved (backend does DELETE + re-insert on every save).

Orphaned machines render with a red 'Removed from settings' badge, a
pink border, and read-only inputs so the data is visible but can't be
accidentally edited. They are still included in totalPdq and the save
payload, so nothing is lost.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 11:38:12 +00:00
dcb450bd99 Cashup: configurable card machines — settings + inline Z-report layout
Settings: add Card Machines section to configure number of PDQ terminals
and their names (1–6 machines, defaults to Front Desk + Restaurant / Bar).
Names are stored under the 'card_machines' settings key.

DailyCashUp: machine names now load from settings instead of hardcoded
const. Card Machines section changed from a 2-column grid to a vertical
list; each machine row shows the amount inputs on the left and its PDQ
Z-report photo uploader on the right. Separate PDQ Z-Reports card removed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 11:32:37 +00:00
13f1b524b0 Cashup: show Newbook reported cash target + variance in Cash Takings section
Mirrors the float count variance pattern — once Newbook data is loaded,
shows the reported cash amount and the counted vs reported variance
directly beneath the Cash Takings header.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 11:26:19 +00:00
2f9b876d0d Fix cashup bugs: PDQ totals, WET placeholder, print styles, cash summary
Issue #1: Parse card machine amounts as floats in applyLoaded — pg returns
DECIMAL as strings which caused JS string concatenation in totalPdq and
reconciliation banked amounts. After draft save, reload cashUp to get the
persisted ID so PDQ Z-report uploads work on first save.

Issue #2: Guard empty gl_code in sales breakdown name-matching — an empty
column code caused gName.includes('') to always be true, making placeholder
columns (like WET 5%) match the first available GL group (dry dept).

Issue #3: Move Cash Summary above Safe Count in sidebar nav. Extend
cash-summary endpoint with per-day breakdown. Rewrite CashSummary.tsx
with a daily cash takings table above the denomination summary.

Issue #4: Add @media print CSS — hide sidebar nav, force colour printing,
style disabled inputs as plain text, and keep tables/cards intact on paper.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-07 11:25:27 +00:00
c2ab162870 Cashup: add 'Load last count' receipts button on petty cash form
Fetches receipts from the most recent petty cash count and populates the
current form — for when the tin hasn't been replenished and slips carry over.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 21:06:13 +00:00
5fe8fe2814 Cashup: fix exchange table — show all over-par denominations
Was filtering out any denomination with target=0 before checking if it
was counted, so notes (default target £0) never appeared even when surplus.
Now: skip only shortfalls where no target is set; surpluses always show.
Also use denom.target from the saved record (backend already populates this)
instead of current-settings lookup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 20:47:01 +00:00
4b0b73c520 Cashup: fix change tin count — use bag values not coin face values
Qty entered for coins = number of bags, so total = BAG_VALUES[denom] × qty
not denom × qty. Fixes totalCounted, row totals, change order counted column,
and save payload. Also shows £X/bag hint under coin denomination labels.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 20:25:27 +00:00
8193b05acc Float management: save→view/print, history columns, uploads path fix
- Change tin count: remove bags/loose split — single qty per denomination
- After save: show saved record inline with Print button (clean new-window
  printout with denomination table, receipts, totals/variance, signature lines)
- Change tin print: bank exchange order table (surplus=to bank, shortfall=in exchange)
- Petty cash history: Cash | Receipts | Total | Variance columns
- Fix uploads path: /app/src/../../uploads resolved to /uploads (container root,
  outside Docker volume). Changed to /app/src/../uploads = /app/uploads so files
  persist across rebuilds on the named volume.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 20:15:50 +00:00
6c805ce5a7 Settings: change tin notes/notes, label fix, placeholder GL columns
Change tin targets:
- Add £5/£10/£20/£50 note rows (qty in individual notes, not bags)
- Fix label: (= £40.00 @ £20.00 each) instead of (= £40.00 each)
- Add per-denomination Notes text field (stored as change_tin_notes setting)
- Table layout replaces 2-col grid for all 10 denominations

Float count form:
- Notes denominations show a single Qty input; coins keep Bags + Loose
- Change order correctly shows "notes" vs "bags" needed per denomination

Sales breakdown columns:
- Add placeholder column button (gl_code='', labelled PLACEHOLDER)
- Add delete (×) button on every column row
- Fix key={i} to support multiple placeholders with same empty gl_code

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 15:58:46 +00:00
618992206e Fix upload response: ins.rows[0] → ins[0] (rows already destructured)
INSERT RETURNING * was succeeding but response threw TypeError trying to
access .rows[0] on the already-unwrapped rows array. File was saved, DB
record created, but 500 returned. Frontend now gets the record immediately
without needing a refresh.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 15:47:50 +00:00
5623f64732 Float management: bagged coins, history nav fix, change order sheet, upload 500 fix
- Fix history nav: type underscore → hyphen for route match
- Change tin: Bags + Loose inputs per denomination with UK bag values
- Change tin target: per-denomination bag count in Settings
- Change order sheet: inline table showing bags to order vs counted
- db: bag_quantity column on float_denominations
- api.ts: put text fields before file in FormData so busboy doesn't drain file stream early
- db.js: additive migration for uploaded_by column on cash_count_attachments

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 15:29:38 +00:00
d03371dca1 Auto-save drafts, reorder float/takings, 5-col reconciliation table
- Auto-save: every 60s while editing, silently saves draft if form has data.
  Status "Auto-saved at HH:MM" appears next to the Save Draft button briefly.
- Float Count moved above Cash Takings and defaults to open so staff count
  the float first before counting takings.
- Reconciliation table gains a fifth "Card Total" column: PDQ Visa/MC and
  PDQ Amex rows share a rowspan=2 cell showing the combined PDQ variance.
  If the per-category rows are red but the combined is green it means only
  the Visa/Amex split was mis-allocated, not an actual cash discrepancy
  (labelled "split only"). Gateway rows similarly grouped (always auto 0).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 14:55:05 +00:00
fb66dcd6bf Save transaction checks, till float variance, fix image upload
- Persist transaction breakdown checked state in cash_ups.checked_transactions
  (JSONB column); saved on each draft/final save and restored on page load.
  Re-fetching Newbook no longer resets the checked items.
- Add till_float_target setting; Float Count card shows target and variance
  so staff can see at a glance whether the till balances.
- Compress images client-side (max 1600px, 85% JPEG) before upload to avoid
  504 gateway timeouts from NPM when uploading large mobile photos.
- File input accepts image/* only (was image/*+PDF which confuses mobile pickers).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 14:46:52 +00:00
4754231f6f Split floats→safe_count, reports→cash_summary, add history cap
Adds three new granular capabilities:
- history: gates /history page and GET /api/cashup/history
- cash_summary: gates /summary page and GET /api/reports/cash-summary
- safe_count: gates /safe page and safe_cash float routes

Updates legacy-token fallback to include all seven non-settings caps.
Route guards and nav items updated to use the split caps.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 14:35:56 +00:00
be670f724d Enforce granular capabilities across cashup
Backend (server-side enforcement, not just UI):
- auth.js: read caps from JWT; hasCap() + requireCap() helpers;
  legacy-token fallback (full access minus settings) so existing
  sessions keep working until re-login
- finalise: submit final, delete draft, bulk-finalise, attachments
- reports: multiday report, cash summary, debtors
- floats: float management + safe count
- settings: settings mutations (was is_admin)
- count: draft save, newbook fetch

Frontend:
- can(user, cap) helper; User.caps from /verify
- Nav items, routes and actions (Submit Final, delete, bulk-finalise)
  gated on capabilities; non-finalisers see a draft-only hint

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 14:19:30 +00:00
43c332be9b Add photo upload for PDQ Z-reports and receipt evidence
DB:
- Add attachment_type ('pdq_z_report' | 'receipt_error' | 'other') and
  label columns to cash_count_attachments; migrate existing rows via
  ALTER TABLE IF NOT EXISTS (no data loss)

Backend:
- Upload route now reads attachment_type and label from multipart form
  fields alongside the file, stores them in the DB

Frontend:
- PhotoUploader component: thumbnail grid, upload button (images + PDF),
  spinner during upload, ✕ delete button on each photo, click opens in
  new tab
- DailyCashUp: PDQ Z-Reports card (one section per machine — Front Desk /
  Restaurant Bar) appears after Card Machines when a cash up exists
- DailyCashUp: Receipt Evidence card at bottom for any discrepancy photos;
  stays editable even on final cash ups so receipts can be added later

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 09:22:22 +00:00
1f5f1639c7 Weekly report status bar: show variance instead of cash total
Variance = banked total - reported total across all payment categories.
Green badge = balanced, red = short (▼), amber = over (▲).
Days with no cash up show no variance (nothing was counted).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 09:13:26 +00:00
460e0c3d77 Weekly report: proper Excel drag-select (no text highlight)
- Switch from onClick to onMouseDown + e.preventDefault() so the
  browser never starts its own text-selection on click or drag
- Add document-level mousemove/mouseup listeners for drag-to-select:
  hold mouse button and sweep across cells to highlight a range
- Shift+click still extends the rectangle from the anchor cell
- userSelect: none on tables prevents any residual text highlighting
- Stats bar (Count/Sum/Avg) now appears after mouseup so it reads the
  final selection, not mid-drag state

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 00:21:25 +00:00
f62aa6f347 Fix gross sales zero bug; add Excel stats bar
- Backend: sales_breakdown column matching was always failing because
  Newbook returns numeric gl_group_id but column settings use string codes
  like 'ACCOMMODATION'. Added normalised name-fuzzy fallback matching and
  a daily_gross_sales field that sums ALL earned revenue for the date,
  bypassing column config entirely.
- Frontend: dayGrossSales() now uses daily_gross_sales from backend first
- Add floating Excel-style status bar (bottom-right): when cells are
  selected it shows Count, Sum, and Average of the selected values;
  disappears when ✕ clicked or selection cleared

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 00:14:40 +00:00
e7af072851 Weekly report: rewrite to match original layout
- Reconciliation now has two side-by-side tables (BANKED left, REPORTED right)
  with dates on rows and payment categories on columns — matching original orientation
- BANKED table: green bg for manual cells (cash/PDQ), orange for auto (gateway/BACS),
  red/amber bg + ▼/▲ indicator when variance vs reported
- REPORTED table: orange background, Audit column showing daily gross sales
- Gross Sales sub-table below reconciliation
- Sales Breakdown: dates now on rows, GL categories on columns (was transposed)
  with Total Net / VAT / Gross Total / Audit columns
- Occupancy: dates on rows, metric columns, hover tooltips with category breakdown
- Copy/Paste Format section: spreadsheet-ready 2-row-per-date tables
- Excel-like cell selection: click to select, Shift+click for range,
  Ctrl+C copies selected cells as TSV to clipboard

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 00:06:23 +00:00
74d238576d Fix unused 'vs' parameter in occupancy total fn
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 23:52:10 +00:00
b53df5b6a5 Weekly report: full occupancy stats + VAT column in sales
Occupancy table now calculates from raw Newbook data:
- Rooms occupied (from per-category occupancy API)
- Occ % (rooms occupied / total rooms from sites_data)
- Guests (adults + children + infants from bookings_data)
- Net accommodation revenue (from earned_revenue, ACC GL group)
- Avg net per room, REVPAR
- GGR (average guest rate from tariffs_quoted)
- Avg lead time (arriving bookings only)

Sales breakdown now shows Net, VAT, Gross as separate total columns.
Debtors/Creditors adds Period Close row.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 22:40:12 +00:00
e4ab137025 Fix invalid date in history; expand weekly report
- History: slice session_date to YYYY-MM-DD before Date parse (postgres
  returns date columns as ISO timestamps in JSON)
- History: fix Edit/View navigate link passing full ISO string as date param
- Weekly report: add daily status row, reconciliation variance (banked vs
  Newbook reported), sales with gross+net, debtors/creditors lazy-loaded

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 22:29:50 +00:00
4caf307fd1 Auto-fetch Newbook on date load; add transaction breakdown checklist
- Newbook payments now fetched automatically when a date loads (in
  parallel with the cash up fetch), not just on button click
- Refresh button still available for manual re-fetch
- Transaction breakdown section below reconciliation table: three
  collapsible groups (Reception Manual, Reception Gateway, Restaurant/Bar)
  each showing individual transactions with click-to-tick checkboxes
  for tracking down discrepancies — local state, clears on refresh

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 22:15:42 +00:00
53c8938c2f Fix denomination total wrong when loaded from DB
PostgreSQL NUMERIC columns return as strings in node-postgres. denomTotal
was doing 0 + "40.00" + "30.00" → "040.0030.00", and parseFloat in
fmtGBP read only the first portion, giving a wrong total (£40.00 instead
of £78.80 etc).

Fix: coerce total_amount and value_entered to numbers in applyLoaded;
make denomTotal's reducer defensively use Number() so strings can't
silently break the sum again.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 22:06:03 +00:00
4ea5238e62 Fix cash summary quantity bug; add Safe Count as own nav item
- Cash summary: derive total_quantity from total_amount/denomination_value
  so value_entered rows are counted (previously SUM(quantity) returned
  NULL for those rows)
- Safe Count: moved safe_cash out of Float Management tabs into its own
  /safe/* route with a dedicated sidebar entry (Vault icon)
- FloatManagement now only shows Petty Cash and Change Tin tabs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 21:36:19 +00:00
e6188fb337 Add proper state machine flow to DailyCashUp
- On mount/date change: auto-fetch existing cash up
  - Draft found → auto-load into editing state
  - Finalised → auto-load into locked state (read-only + banner)
  - Not found → show 'Start Cash Up' prompt
- Removed manual 'Load Existing' / 'New' buttons
- Submitting final transitions immediately to locked state

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 21:30:22 +00:00
4cbe68ebf7 Vertical tab order in denomination grids
Tab now moves down the Qty column first (£50→£20→...→1p), then down
the Value Override column, for both takings and float grids.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 21:24:41 +00:00
b9fb7b1dc7 Pass SETTINGS_URL and SETTINGS_SECRET to backend container
These were in the .env file but missing from docker-compose environment,
so process.env.SETTINGS_URL was undefined and newbook.js crashed on
URL construction.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-01 21:22:37 +00:00