Commit Graph

6 Commits

Author SHA1 Message Date
ac58d150ea feat(sysadmin): Part 3 — Remote Managers section in SiteDetailPage
Backend (manager_auth.py):
- register: upsert instead of 409 — if email exists, just add site access
- GET /api/manager/by-site/{site_id}: list managers linked to a site (admin auth)
- DELETE /api/manager/site-access: remove a manager's access to a site (admin auth)

Sysadmin API client:
- getManagersBySite, addManagerToSite, removeManagerSiteAccess

SiteDetailPage.jsx:
- Remote Managers section: lists all linked managers with email, name, active badge
- Add Manager modal: email + full name + password form (password ignored if account exists)
- Remove access button with optimistic removal from list

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 10:04:28 +03:00
f291234c14 fix: switch manager auth from OAuth2PasswordBearer to HTTPBearer
OAuth2PasswordBearer caused Swagger UI to show a username/password/
client_id form instead of a simple token input, making the docs
unusable for testing. HTTPBearer shows a plain 'Bearer token' field,
consistent with how the local_backend handles auth.

No runtime behaviour change — token extraction is identical.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 00:49:09 +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