Commit Graph
6 Commits
Author SHA1 Message Date
bonaminandClaude Opus 5.5 96a014ecbe feat(cloud): heartbeat returns a signed license token (Ed25519)
Sites now enforce their license offline (client-services KI-006): the
cloud is needed to renew a license, not to run it. Each heartbeat carries
license_token = base64url(payload).base64url(signature), payload
{v:1, site_id, active, locked, lock_reason, expires_at, issued_at}, signed
with LICENSE_SIGNING_KEY (base64 raw Ed25519 private key, cloud .env). The
matching public key is built into the site code, so a stored token can't be
edited and a clock can't be set before issued_at unnoticed.

Additive field only (old sites ignore it). Without the key the field is
null and a warning is logged. Pins cryptography==46.0.4 (was transitive).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 22:16:32 +03:00
bonaminandClaude Sonnet 5 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
bonaminandClaude Sonnet 5 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
bonaminandClaude Sonnet 4.6 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
bonaminandClaude Sonnet 4.6 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
bonamin 4cbf8986df Initial Commit. Split cloud service from the combined project 2026-05-08 13:20:23 +03:00