Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Parity Checklist

Screen-by-screen mapping of legacy hh-pegasus → hh-pegasus-monorepo. The single source of truth for “are we done porting?”.

This is the real inventory — extracted 2026-06-16 by 12 opencode parity-mapper agents

  • 1 integrations-surveyor + 1 parity-critic over the legacy repo (see 10-parity-extraction-runbook.md). 77 screens across 12 clusters; 92% route coverage (138/150 user-facing routes). Migration status is cross-mapped to the 127 GitHub issues + ClickUp subtasks in 08-issue-index.md.

Owner: Tompi (parity sign-off). Detta verifies.

Status legend: ✅ done by dev · 🟦 implementing · 🟡 in progress · 🔴 not started (tracked) · ❓ untracked (no GitHub issue or ClickUp subtask found — the real gaps) Surfaces: D = desktop · M = mobile · H = native-hybrid


⚠️ Headline: ~30 screens have ZERO tracked migration work

Mapping the legacy app against the live backlog exposes large untracked surfaces — including two payment-bearing screens. These are the parity risk, not the in-flight work:

Untracked surfaceScreensWhy it matters
Vouchers & Gift cards (whole cluster)6 (incl. Gift Card Buy — Omise + GBPrimePay)A payment flow with no migration task
Profile — orders & wallet (whole cluster)6 (incl. Payment Methods — Stripe Elements + card-brand routing)Saved-card management, untracked
Settings (whole cluster)5 (Hub, Language/Currency, Password, Notifications, Delete Account)Account-critical, untracked
Profile — account core (most)Benefits, Tier, Point History, Edit Profile, Cuisine Prefs, Referral, History stubLoyalty + account, untracked
OpenRice partner flow2 (vendor HMAC + partner config)Revenue partner integration
MiscEdit Booking, Self Check-In, Promotions, Careers, Survey, Tags, Near Me, City aliasesAssorted

→ Decision for Tompi: each of these needs a GitHub issue + ClickUp subtask, or an explicit “won’t port / kill” decision, before cutover scope can be called complete.

Coverage summary

Count
Screens mapped77
Route coverage92% (138/150 user-facing)
Uncovered routes (critic)11 — all [lang]/[slug]/* legacy dynamic-slug family (see Critic findings)
Screens ✅ done by dev~3 (Checkout, BiteList, country-by-IP)
Screens 🟦/🟡 in flight~24
Screens 🔴 tracked-not-started~14 (booking-confirmation, payment, QR pay-now, group landing)
Screens ❓ untracked~30

Critical-path ranking (drives E2E priority)

RankFlowWhy
1Discovery / search / filtersTop of funnel, highest traffic
2Booking flowDirect revenue
3Package / view-menuDirect revenue
4Payment / checkout / confirmation / QR payRevenue + trust; highest blast radius
5Account / authRetention
6ReviewsEngagement / SEO

Screen tracker (by cluster)

ScreenCritSurfStatusTracked inHardest bit
Top-level Locale Index (redirect entry)⭐DMH🟦home tier 86d35j1en, country-by-IP 86d2xm0xtserver redirect + cookies
Search Results Page⭐DMH🟦 implementing#944–946, 86d2tn5jgurql + hybrid bridge
Search Suggestion (zero-state)⭐DMH🟦 implementing86d2tn5jgvalibot + hybrid
Top Restaurants (→ group landing)DMH🟡worker chainredirect
Top BrandsDMH🟡#885–893, 86d2wnn*getAllGroupLanding side-effect
Near Me (geo search)DMH❓—geolocation
Tags BrowserMH❓—group/deal/package_type classify
City Aliases (web-/mobile-[city])DMH❓—dead-URL redirect pattern
Restaurants Index Alias (→ search)DMH❓—redirect

2 — Restaurant Detail

ScreenCritSurfStatusTracked inHardest bit
Restaurant Storepage⭐DMH🟡 in progress#328–343, #761–763, 86d2tk2xb, 86d38d5knMaps/Mapbox + Firebase analytics + hybrid
Branch City Homepage⭐DMH🟡(under restaurant)identity cookies + hybrid personalization
Group Landing⭐DMH🔴 not startedworker chain #737, #885–893Mapbox + CF cache invalidation
Bitelist LandingDMH🟡86d33dw4hshare-earn-points referral

3 — Package & View Menu

ScreenCritSurfStatusTracked inHardest bit
Restaurant Package Detail⭐DMH🟡 in progress#653–663, add-on race fix 86d3bq1jrDTP v2 + partner config + hybrid
Package View Menu (QR detail)⭐DM🟡#653–663DIY booking widgets + hybrid setup
Add-on Detail⭐DMH🟡add-on tab fixpartner config + DTP
Add-on View MenuDMH🟡—hybrid back-event
Package Menu IframeDM❓—iframe height bridge
QR Menu Entry (bookingId)DM🔴Guest QR Pay-Now #849–867—
QR Menu (per reservation)DM🔴#849–867in-island vue-router
OpenRice Select/View Menu⭐DM❓ untracked—vendor HMAC + partner config + Notyf CDN

4 — Booking flow

ScreenCritSurfStatusTracked inHardest bit
Package Booking Flow⭐DMH🟡createBooking parity 86d3bnz82, checkout v2/v37+ payment/vendor integrations, GrowthBook, KV cart
Restaurant Booking Entry (redirects)DMH🟡—redirect
Booking Payment ExpiredDMH🟡timeout fixes 86d3bp5u1hybrid deeplinks
Booking Reservation InvalidDMH🟡—callback redirect safety (isSafeRedirectUrl)
Edit Booking⭐DMH❓ untracked—token-in-body auth, hybrid setup

5 — Checkout / Payment / Confirmation

ScreenCritSurfStatusTracked inHardest bit
Checkout⭐DMH✅ done by devv2 86d33vnpw, v3 86d36x7xx, #636–6514 payment SDKs + KV booking-lock
Booking Confirmation⭐DMH🔴 not started#925–933—
Generic Confirmation / Landing Hub⭐DMH🔴#925–933server redirection
Payment Success⭐DMH🔴#925–933 (+ critic gap: [slug]/payment-success/* unmapped)Firebase realtime watcher
Payment Failed (restaurant flow)⭐DMH🔴(critic gap: [slug]/payment-failed/*)Firebase watcher + serverRedirection
Payment Failed (top-level)⭐DM🔴—Firebase watcher
QR Payment Landing⭐DMH🔴Guest QR Pay-Now #849–8673 payment SDKs (Stripe/Xendit/Omise)
Self Check-InDMH❓ untracked—phone re-entry

6 — Reviews

ScreenCritSurfStatusTracked inHardest bit
Restaurant Review DetailDMH🟡 in progress#464, #466, #468valibot
Restaurant Reviews ListDMH🟡#465valibot + qs + humps
Submit Booking Review⭐DMH🟡#469image compression + vuelidate

7 — Vouchers & Gift cards (entire cluster ❓ untracked)

ScreenCritSurfStatusTracked inHardest bit
Gift Card Buy⭐DMH❓ untracked—Omise + GBPrimePay payment
Restaurant Voucher Detail⭐DMH❓——
Voucher Group Detail⭐DM❓——
Voucher Group TransactionDM❓——
Gift Card LandingDMH❓——
Gift Card ShareDM❓——

8 — Profile — account core

ScreenCritSurfStatusTracked inHardest bit
BiteList (Favourites)⭐DM🟦 done by dev86d33dw4hNetcore
Profile Main⭐DMH❓ untracked—Firebase + Netcore
Edit Profile⭐DM❓—Firebase + Netcore
Benefits (Loyalty)DM❓—Netcore
Tier DetailM❓—Netcore
Point HistoryDM❓—Netcore
Cuisine PreferencesM❓——
Referral / Invite FriendsDM❓—tippy.js
Profile History (stub)DMH❓—(stub)

9 — Profile — orders & wallet (entire cluster ❓ untracked)

ScreenCritSurfStatusTracked inHardest bit
Payment Methods⭐DMH❓ untracked—Stripe Elements + card-brand routing (TH-only saved cards)
Booking & Voucher CollectionDMH❓—hybrid refresh guard + swiper
Offers & Gift CardsDMH❓—hybrid link bridge + config banner
Redeemed VoucherMH❓—mobile-only route
Voucher Term of UseDMH❓—modal registry
My Vouchers (legacy URL)DMH❓——

10 — Settings (entire cluster ❓ untracked)

ScreenCritSurfStatusTracked inHardest bit
Settings Hub⭐DMH❓ untracked——
Edit Language & Currency⭐MH❓——
Edit Password⭐DMH❓——
Notification PreferencesMH❓——
Delete Account⭐DMH❓—modal from Hub — owns no routes (critic fix: legacy_routes: [])

11 — Onboarding & Auth

ScreenCritSurfStatusTracked inHardest bit
Login Modal⭐DMH🟦 implementing86d2uka0kFirebase auth + fb-pixel/GA4/Netcore
Register Modal⭐DMH🟦 implementing86d2um0xtNetcore/GA4
Onboarding Welcome⭐DMH🟦 done/impl86d388ad7, splash 86d2w6nmqwhite-screen end-to-end
Onboarding Get Started⭐DMH🟦86d388ad7—
Onboarding Birthday⭐DMH🟦——
Onboarding Terms of Service⭐DMH🟦——
SurveyDMH❓ untracked——

12 — Promotions & Misc

ScreenCritSurfStatusTracked inHardest bit
Root Index Redirector⭐DMH🟡country-by-IP 86d2xm0xtserverRedirection + group-landing rewrite
Reservation Landing (QR vs Confirmation)⭐DMH🔴 not startedFirebase realtime #850, #852realtime reservation + localStorage watch
Promotions Banner GridDM❓ untracked——
Careers PageDMH❓—external ClickUp doc
500 Internal Server ErrorDMH❓—sentry
404 Not FoundDMH❓—(trivial)
Health Check Endpointinfran/a—CF monitoring (not user-facing)

Cross-cutting integration backbone

Surveyed separately (integrations-surveyor) — these underpin many screens and must be rebuilt as shared infra, not per-screen:

TopicLegacy shapeMonorepo migration risk
Payments4 tokenisation SDKs (Stripe.js, Omise, Xendit, GBPrimePay) routed per-restaurant by BookingCreditCardProvider, per-country public keys (SG/MY/TH)Two tokenisation paths (gateway-direct vs intent-based); appears in Checkout, QR Pay, Gift Card Buy, Payment Methods — 3 of those 4 are untracked
FirebaseOne SDK, three uses: Auth (Google/FB login), Realtime DB (live payment status), analyticsTwo parallel Firebase singletons (firebaseCore.ts vs firebase.ts) — realtime watcher drives payment success/failed redirects
AnalyticsMulti-vendor bus: fb-pixel, GA4, TikTok, Netcore/Smartech (CleverTap)Each guarded by window.* check (script-load race); booking-funnel coupling — Phase 3 event-parity (#181–183)
i18n13-locale on-demand dictionary, provide('translate') per islandHard-coded AVAILABLE_LANGUAGES tuple; monorepo moving to Paraglide (86d2uyhzw, #834–839)
StatePinia (domain stores) + Nanostores (city/config) coexistingPinia is a client-side singleton to survive Astro island re-mounts — monorepo is pure SPA, re-evaluate
HTTPSingle useHttp (ofetch) chokepoint: snake/camel conversion, X-HH-Language + Bearer, refreshAll traffic flows one composable; key-case conversion is an implicit contract
AuthTwo rails (email/password /oauth/token.json + Firebase social) → shared Pinia user store, cookie token storageCookie keys hungryhub_access_token / _expired_in / _refresh_token — session continuity across cutover

Critic findings (2026-06-16, 92% coverage)

  • 11 uncovered routes — all under src/pages/[lang]/[slug]/* (legacy dynamic-slug family): payment-success, payment-failed, payment-landing (3 files each, mirror the restaurant-scoped variants already mapped) + bare [lang]/[slug]/index.astro (a 301 hub with 6 legacy URL patterns → falls through to HomeWrapper). Fix: add a “Generic Slug Landing” row to cluster 1 + the three [slug]/payment-* rows to cluster 5.
  • Settings “Delete Account” route bug — listed 5 routes it doesn’t own (modal-driven from Settings Hub). Fix: legacy_routes: [] (reflected above).
  • src/pages/_app.ts — Vue app entry, not a route. Remove from _routes.txt.
  • 15 API-only routes — 10 unreferenced (cache-invalidation hooks, group-landing helpers). Highest-priority backfill: api/cache/clear/{cloudflare,home-page,home-sections}.ts.
  • 0 stale references — every legacy_routes entry maps to a real file.

Definition of “verified” (✅) — unchanged

A screen is ✅ only when all hold: code ported + matches legacy UX; unit tests at layer coverage target; critical screens have green E2E on staging across the device matrix; QA (Detta) signed off; analytics/conversion events fire identically (funnel screens).

Provenance: raw agent output lives in hh-pegasus/.cutover/parity/*.json (gitignored scratch; regenerate via 10-parity-extraction-runbook.md). Re-run after a wave of ports lands to refresh status.