Book-Bite (Partner Portal) — Architecture and Operations
Book-Bite is the HungryHub Partner Portal — the web and mobile app used by restaurant partners to manage their bookings, packages, menus, vouchers, allotments, analytics, and account settings.
- Repo: hungryhub-team/book-bite
- Production URL: partners.hungryhub.com
- Default branch:
main - Version: 2.0.8
Tech stack
| Category | Technology |
|---|---|
| Framework | Vue 3.5 + Vite 5 |
| UI library | Vuetify 3.8 (Material Design) |
| State management | Pinia 2 |
| Router | Vue Router 4 |
| HTTP client | Axios 1.15 (camelCase ↔ snake_case via Humps) |
| Mobile | Capacitor 6 (iOS + Android) |
| Error tracking | Rollbar 2.26 |
| Feature flags | GrowthBook 1.4 |
| Analytics | Google Analytics 4, Microsoft Clarity, MongoDB Charts |
| Validation | Valibot 1.0 |
| i18n | 4 languages: English, Thai, Chinese, Malay |
| Testing | Cypress 13 (component + e2e), Playwright 1.56 (e2e) |
| CI | GitHub Actions + Netlify |
What partners can do
| Area | Key actions |
|---|---|
| Bookings | View, create, edit, approve/reject, send SMS, send review links, check inventory |
| Packages | Create/edit AYCE, Party Pack, Xperience, Hungry@Home packages; pricing rules; add-ons |
| Allotments | Manage daily/monthly allotments; view edit history |
| Menus | Menu v1 & v2 management; gallery photos; QR codes; print |
| Vouchers | Create/edit vouchers; view usage history |
| Analytics | Dashboard KPIs; performance review; benchmark reports; ranking analytics |
| Reviews | View and respond to guest reviews |
| Account | User/staff management; billing; store setup; partner registration |
| Marketing | Campaign management |
Architecture
Browser / iOS / Android
│
▼
Vue 3 SPA (Vite build → dist/)
│
├── Pinia stores (client-side state)
├── src/api/ (26 domain API modules)
└── Axios (request.util.js)
│
├── Partner API: madison.hungryhub.com/api/partner/v1/
├── Restaurant API: .../api/v5/restaurants/
├── Price Engine: APP_BASE_API_PRICE_ENGINE_URL
├── HH Menu: menu.hungryhub.com
└── Chrome service: APP_CHROME_SERVICE (PDF/print)
Authentication: Bearer token stored in localStorage, auto-injected via Axios interceptor.
Mobile apps (iOS/Android) wrap the compiled Vue app via Capacitor — bundle ID com.hungryhub.partnerapp.
Repository structure
src/
api/ 26 domain API modules (booking, package, voucher, menu, ...)
stores/ 26 Pinia stores (one per domain)
pages/ 22 page sections
components/ Feature + base UI components
router/ 13 route files (one per domain)
composables/ Vue 3 composition hooks
locales/ i18n translations (en, th, zh, ms)
utils/ request.util.js, storage.util.js, ...
plugins/ Vue plugins
android/ Android native project (Capacitor)
ios/ iOS native project (Capacitor)
tests/ Playwright e2e tests
cypress/ Cypress e2e + component tests
Deployment
Platform: Netlify
| Environment | Trigger | URL |
|---|---|---|
| Production | Push to main | partners.hungryhub.com |
| Staging preview | Pull request | Auto-generated Netlify preview URL |
Build command: npm run build → outputs to dist/.
netlify.toml configuration:
- SPA redirect: all routes →
/index.html(200) - Assets cached for 1 year (
/assets/*) index.htmlnever cached (always fresh)
CI/CD workflows
| Workflow | Trigger | Purpose |
|---|---|---|
playwright.yml | PR | E2e tests against Netlify preview |
pr_agent.yml | PR | AI-powered PR review |
typos.yml | PR | Spell check on changed files |
clean-branches.yml | Daily | Delete branches older than 60 days |
Runners: self-hosted arc-runner-set-book-bite for heavy tests; ubuntu-latest for lightweight jobs.
Analytics
| Tool | Purpose | Prod property |
|---|---|---|
| Google Analytics 4 | Traffic, sessions, conversion events | Account 66127738 / Property 245030152 |
| Microsoft Clarity | Session recordings and heatmaps | Configured via APP_MICROSOFT_CLARITY_ID |
| MongoDB Charts | Custom business KPIs (booking volume, revenue) | Embedded in the Analytics section of the portal |
GA4 is initialised client-side via APP_GOOGLE_ANALYTICS_ID. Only the production build uses the real property; set a dev/staging measurement ID in non-prod environments to keep data clean.
Environment variables
| Variable | Purpose |
|---|---|
APP_BASE_API_URL | Partner API base URL |
APP_BASE_API_RESTAURANT_URL | Restaurant data API |
APP_BASE_API_PRICE_ENGINE_URL | Dynamic pricing engine |
APP_GOOGLE_API_KEY | Google Maps / geocoding |
APP_GOOGLE_ANALYTICS_ID | GA4 measurement ID (prod: property 245030152, account 66127738) |
APP_ROLLBAR_TOKEN | Error reporting token |
APP_MICROSOFT_CLARITY_ID | Clarity session analytics |
APP_GROWTHBOOK_API_HOST | GrowthBook feature flag host |
APP_GROWTHBOOK_CLIENT_KEY | GrowthBook SDK key |
APP_FIREBASE_* | Firebase push notifications (4 vars) |
APP_NETCORE_* | NetCore email/SMS (4 vars) |
APP_NODE_ENV | development or production |
APP_DEFAULT_LOCALE | Default language (en) |
Mobile apps
Both iOS and Android apps wrap the compiled Vue app via Capacitor.
- Bundle ID:
com.hungryhub.partnerapp - App name:
partner-portal - CapacitorCookies plugin enabled for session management
- Updates require a new App Store / Play Store release when native code changes; web-only changes deploy via Netlify without a new app release
Testing
# Component tests (Cypress)
npm run test:unit # interactive
npm run test:unit:ci # headless
# E2E tests (Cypress)
npm run test:e2e # interactive
npm run test:e2e:ci # headless
# E2E tests (Playwright)
npm run test:e2e:playwright
npm run test:e2e:playwright:ui # with UI mode
# Coverage
npm run coverage # Playwright + lcov report
Playwright tests cover: login, booking list, create booking, edit booking, inventory.
Local development
git clone git@github.com:hungryhub-team/book-bite.git
cd book-bite
npm install
npm run dev # starts on port 3001
Copy .env.example to .env and fill in API URLs and service keys.
Related
- Feature docs: Partner Portal Dashboard
- How to open staging: Open Partner Portal in Staging
- Backend API: served by
hh-server(madison.hungryhub.com)