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.
| Layer | Where |
|---|---|
| App shell | apps/unpispas-qra/ — Access = 'GUEST'; baseHref /unpispas-qra/ (nx/pw development) or / (production / LAB edge) |
| Screens | libs/feature/guest/upp-feature-guest.mdc (do not copy RN/RF here) |
| REST | Slim paths below; published OpenAPI in docs/swagger/ on doc.* (About this guide) |
| E2E | Repo 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=
| Surface | Host | qraRoute / public URL |
|---|---|---|
Nx docker (docker/README.md) | qra.nx.{domain} (QRA_DOMAIN) | /unpispas-qra/ |
| DEV/LAB edge | qra.{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
| Step | What the diner does | Feature surface |
|---|---|---|
| Access | Opens sticker URL; device fingerprint + POST /guest/access; later visits may use stored token + POST /guest/check | UppGuestAccessComponent |
| Home | Place photo, social, extras notice, PDF menu, gated actions | UppGuestHomeComponent |
| Order | Continuous 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 |
| Pay | Select payable tickets; cash/card (proximity when table service and guest geolocation on) or Stripe Checkout | UppGuestPaymentComponent → return page public/on-payment/ |
| Waiter / action | Follow-up AskWaiter, or “go to the counter” when there is no table service | UppGuestWaiterComponent / UppGuestActionComponent |
| Ready | Overlay when kitchen marks tickets ready (FCM / poll) | UppGuestReadyComponent |
| Receipt | List paid tickets of the session; preview; courtesy PDF | UppGuestReceiptComponent |
Slim API (guest)
| Method | Path | Role |
|---|---|---|
POST | /guest/access | Open a GUEST session (table + auth) |
POST | /guest/check | Verify / refresh an existing guest session |
POST | /guest/payment/checkout | Stripe Checkout for selected tickets (DoPayment('PAYLINE') → PP + commercial snapshot first) |
POST | /stripe/webhook | Stripe notify (metadata.action=TICKET): X→S/T, TICKETCHANGE F, optional TBAI/VFTU; not under /guest/ |
POST | /guest/ticketpdf | Courtesy 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-04in the secrets plan (plan-secretos-hardcodeados) - Staff QR assignment (
feature/qrcode) — already POS
Related
- 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.deploydeploy-DEV.mdc/deploy-LAB.mdc(operator checklist) - Adding a library: Adding a Feature Library