Commit Graph

7 Commits

Author SHA1 Message Date
a73f081ca1 fix: QR menu branding fields — display name, header image, empty-to-hide
- menu_display_name is now separate from the site's internal name (was
  incorrectly showing the sysadmin-only site name on the public menu).
- Header image now resolves against the cloud API origin instead of
  the menu-app's own origin, fixing the broken-image icon.
- Tagline/blurb/hours now genuinely hide when cleared: the sysadmin
  save handler was converting empty fields to null, which the PUT
  endpoint's exclude_none silently drops instead of clearing.
- Added a settable blurb (EN/GR) below the tagline, previously
  hardcoded ("Fresh seasonal plates, served with care.").
- Collapsed hours from two fields (EN/GR) to one — opening hours don't
  vary by language.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-19 10:44:28 +03:00
d87540e08f feat: per-site QR menu mode (order vs view-only) + editable branding
Adds a sysadmin-configurable toggle so sites can disable online ordering
on the public QR menu until it's fully supported, plus editable
tagline/hours and a header image (replacing the hardcoded "Our Menu"
placeholder) — all previously hardcoded frontend strings.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-19 09:59:35 +03:00
17fb3a2589 fix(sysadmin): use site_id UUID string instead of integer PK throughout manager endpoints
The sysadmin panel URL uses site.site_id (UUID string) not site.id (int PK).
All manager account endpoints were querying/expecting the integer PK — none matched.

- GET /by-site/{site_id}: param type str, filter by Site.site_id
- POST /register: site_ids type list[str], query Site.site_id.in_()
- DELETE /site-access: site_id type str, query Site.site_id
- schemas/manager.py: ManagerRegisterRequest.site_ids list[int] → list[str]
- SiteDetailPage.jsx: remove Number() casts on siteId in add/remove calls

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 10:45:10 +03:00
abe7f4ff0d feat(connect): return site_numeric_id in heartbeat response
Local backend needs the cloud DB integer PK to call Connect API
endpoints (menu sync, order pending poll). Heartbeat is the only
authenticated channel available at startup, so we piggyback the id
there rather than adding a new endpoint.

Changes:
  - schemas/site.py: site_numeric_id: int | None added to HeartbeatResponse
  - routers/heartbeat.py: site_numeric_id=site.id included in response

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 00:11:48 +03:00
cd8a6c53cf feat(connect): Phase 3 — cloud API routes for Xenia Connect
Adds four new routers, three schema files, and one new model.
All new endpoints use new URL prefixes — no existing routes touched.

routers/menu.py
  GET  /api/menu/{site_slug}     — public menu snapshot (no auth)
  POST /api/menu/sync            — upsert snapshot (site API key)

routers/orders.py
  POST /api/orders/{site_slug}         — customer places order (public)
  GET  /api/orders/status/{public_ref} — customer tracks order (public)
  GET  /api/orders/pending/{site_id}   — local backend polls (site key)
  POST /api/orders/{id}/synced         — mark synced (site key)
  PATCH /api/orders/{id}/status        — update status with transition
                                         validation (site key)

routers/manager_auth.py
  POST /api/manager/register  — create manager account (admin JWT)
  POST /api/manager/login     — returns manager JWT
  POST /api/manager/refresh   — refreshes manager JWT
  Shared _get_current_manager dependency used by remote_dashboard

routers/remote_dashboard.py
  GET  /api/remote/sites                           — manager JWT
  GET  /api/remote/sites/{id}/snapshot             — manager JWT
  GET  /api/remote/sites/{id}/orders               — manager JWT
  GET  /api/remote/sites/{id}/orders/pending       — manager JWT
  PATCH /api/remote/sites/{id}/orders/{oid}/status — manager JWT
  POST /api/remote/snapshot                        — site API key
                                                     (stats push)

models/stats_snapshot.py (NEW)
  stats_snapshots table — one row per site, holds serialized
  operational stats; created by create_all on startup

config.py / .env.example
  MANAGER_JWT_SECRET and MANAGER_JWT_EXPIRE_HOURS (default 72h)
  added as separate settings from the admin SECRET_KEY

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 00:05:48 +03:00
06b01533d4 feat: waiter domain + local IP tracking
- Site model: add waiter_domain and last_seen_local_ip columns
- HeartbeatRequest: accept optional local_ip field from local backend
- HeartbeatResponse: return waiter_domain to local backend
- heartbeat router: persist local_ip on each check-in
- SiteDetailPage: show Public IP / Local IP separately, add Waiter Domain
  card with inline edit modal

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 14:06:36 +03:00
4cbf8986df Initial Commit. Split cloud service from the combined project 2026-05-08 13:20:23 +03:00