Skip to main content

Guest QR access (unpispas-qra)

Diner-facing SPA: scan a table QR, order, pay, call a waiter, download a courtesy receipt. This page is the product map for developers. Binding rules live in the feature contract; Playwright narratives live in the testing repo.

LayerWhere
App shellapps/unpispas-qra/ — Access = 'GUEST'; baseHref /unpispas-qra/ (nx/pw development) or / (production / LAB edge)
Screenslibs/feature/guest/upp-feature-guest.mdc (do not copy RN/RF here)
RESTSlim paths below; published OpenAPI in docs/swagger/ on doc.* (About this guide)
E2ERepo uppv4-testing: apps/upp-guide/docs/guides/guest-e2e-tests.md — not duplicated in this guide

Canonical URL (D-ENV-01)​

Stickers generated from POS (QrCode.QrCodeUrl) use AppConstants.qraURL plus query params, never v3 qr-access as the live path and never POS thisURL:

{qraURL}?qr=true&lang=&validQR=&table=
SurfaceHostqraRoute / public URL
Nx docker (docker/README.md)qra.nx.{domain} (QRA_DOMAIN)/unpispas-qra/
DEV/LAB edgeqra.{DOMAIN} (QRA_DOMAIN)Host / (subdomain selects the SPA). Legacy /unpispas-qra/* and v3 /qr-access 301 to that Host.

public/config.js must set qraPath / qraRoute (Nx: qra.nx. + /unpispas-qra/; deploy materialize: qra. + /). Angular baseHref follows the same split: development build keeps the path prefix for docker/nx+pw; production build uses / for LAB/DEV Host root. The guest app’s own appPath/appRoute match that public URL. Do not mix POS chrome (LOGIN / USER / staff PLACE) into this app.

User flow​

StepWhat the diner doesFeature surface
AccessOpens sticker URL; device fingerprint + POST /guest/access; later visits may use stored token + POST /guest/checkUppGuestAccessComponent
HomePlace photo, social, extras notice, PDF menu, gated actionsUppGuestHomeComponent
OrderContinuous catalog list grouped by top-level group (chips bar follows scroll; search is a flat list of the same rows), configure product, cart (extras VIEW-only), send (proximity unless the place turns guest geolocation off)UppGuestOrderComponent → UppGuestCatalogComponent / UppGuestRowComponent
PaySelect payable tickets; cash/card (proximity when table service and guest geolocation on) or Stripe CheckoutUppGuestPaymentComponent → return page public/on-payment/
Waiter / actionFollow-up AskWaiter, or “go to the counter” when there is no table serviceUppGuestWaiterComponent / UppGuestActionComponent
ReadyOverlay when kitchen marks tickets ready (FCM / poll)UppGuestReadyComponent
ReceiptList paid tickets of the session; preview; courtesy PDFUppGuestReceiptComponent

Slim API (guest)​

MethodPathRole
POST/guest/accessOpen a GUEST session (table + auth)
POST/guest/checkVerify / refresh an existing guest session
POST/guest/payment/checkoutStripe Checkout for selected tickets (DoPayment('PAYLINE') → PP + commercial snapshot first)
POST/stripe/webhookStripe notify (metadata.action=TICKET): X→S/T, TICKETCHANGE F, optional TBAI/VFTU; not under /guest/
POST/guest/ticketpdfCourtesy PDF (device + session)

Source of truth: server/openapi/openapi.yaml. If a path is missing there, fix the OpenAPI (and the service), not this page.

Out of v1​

  • Paytef, PayPal, MyPOS
  • Hosted Stripe Checkout as an E2E scenario
  • Real FCM credentials in git — remediación F-SECREM-04 in the secrets plan (plan-secretos-hardcodeados)
  • Staff QR assignment (feature/qrcode) — already POS
  • App contract (RN-QRA-*, PWA): apps/unpispas-qra/unpispas-qra.mdc
  • Feature contract: libs/feature/guest/upp-feature-guest.mdc
  • Numbering / Stripe close: server/.../spec/ticket-numbering.mdc, server/.../stripe/stripe.mdc §B
  • Shell: apps/unpispas-qra/src/app/app.component.mdc
  • Serve: docker/README.md, unpispas.deploy deploy-DEV.mdc / deploy-LAB.mdc (operator checklist)
  • Adding a library: Adding a Feature Library