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

HungryHub Restaurant Registration System

Description / Background

The HungryHub Restaurant Registration System is a comprehensive platform for onboarding new restaurant partners. It streamlines the process of bringing new restaurants onto the HungryHub platform by providing a user-friendly registration form for partners and an internal operations portal for staff to review, enrich, and submit applications to the HungryHub production system.

The system consists of two main portals that work together to ensure efficient and accurate restaurant onboarding:

  1. Partner Onboarding Portal - Public-facing form for restaurant partners to register
  2. Operations Team Portal - Internal admin tool for reviewing and submitting restaurant applications

This system supports multi-country operations (Thailand, Singapore, Malaysia) with country-specific fields and localization.

Objectives

  • Simplify the restaurant partner onboarding process
  • Provide a structured 4-step registration flow for restaurant partners
  • Enable operations staff to review and enrich restaurant data before submission
  • Integrate with Google Places API for accurate location data
  • Support multiple countries with localized fields and options
  • Automate data submission to HungryHub production system via N8N workflows
  • Maintain data consistency through database-driven tags and dropdowns
  • Send automated confirmation emails to partners upon registration

Scope

Partner Onboarding Portal Features

  • Multi-language support (Thai/English toggle)
  • Google Places integration for address autocomplete
  • Country-specific fields (Thailand, Singapore, Malaysia)
  • 4-step registration process:
    • Business Information
    • Restaurant Details
    • Banking Information
    • Review & Submit
  • Real-time form validation
  • Confirmation page with next steps

Operations Team Portal Features

  • Application list view with status tracking
  • Detailed restaurant data entry with additional fields
  • Data enrichment via N8N integration
  • Submit to HungryHub API with HMAC authentication
  • Advanced scheduling with inventory groups
  • SEO metadata management in multiple languages

Admin Manager Features

  • Form section management
  • Question configuration
  • Tag management for dropdowns

Location

Base URL: (https://onboarding.hungryhub.com)

  • Partner Onboarding Portal: / (Home page)
  • Operations Team Portal: /operations-team
  • Admin Manager: /admin_manager
  • Login Page: /login

How to find Restaurant Applications

As Operations Staff:

  1. Navigate to /operations-team
  2. Login with credentials (default: admin@hungryhub.com / Admin@123)
  3. View all pending restaurant applications in the list
  4. See submission date, restaurant name, country, and status
  5. Click on any application to load detailed information

As Restaurant Partner:

  1. Navigate to the home page /
  2. Complete the 4-step registration form
  3. Submit application
  4. Receive confirmation email with application details

How to Register a New Restaurant

Step 1: Business Information

  1. Select country (Thailand, Singapore, or Malaysia)
  2. Enter booking alert email and SMS number
  3. Provide primary contact person details:
    • Name
    • Email
    • Phone number
  4. Search restaurant via Google Places
  5. Enter basic restaurant information:
    • Restaurant name (English/Thai)
    • Phone number
    • Full address
    • Latitude/Longitude (auto-filled from Google Places)

Step 2: Restaurant Details

  1. Set operating hours schedule:
    • Select days of the week
    • Add multiple time slots per day
  2. Select cuisine types (multi-select)
  3. Select dining styles (multi-select)
  4. Select facilities (multi-select)
  5. Choose location tags and popular zones
  6. Select city, MRT station, and nearby malls
  7. Enter restaurant descriptions:
    • English description
    • Thai description
  8. Add SEO metadata:
    • Meta title
    • Meta description
    • Meta keywords

Step 3: Banking Information

  1. Enter bank details for payments:
    • Bank name
    • Account number
    • Account holder name
  2. Provide company registration information:
    • Company name
    • Tax ID
    • Registration number
  3. Add accounting team contact details:
    • Name
    • Email
    • Phone number

Step 4: Review & Submit

  1. Review all entered information
  2. Edit any section if needed
  3. Submit application
  4. View confirmation page with next steps
  5. Receive confirmation email

Sequence Diagram / Flow

Partner Registration Flow

Operations Team Flow

ERD

Main Tables

restaurants_applications

  • id (Primary Key)
  • submission_date
  • country
  • status
  • restaurant_name_en
  • restaurant_name_th
  • contact_name
  • contact_email
  • contact_phone
  • booking_alert_email
  • booking_alert_sms
  • address
  • latitude
  • longitude
  • google_place_id
  • operating_hours (JSONB)
  • cuisines (Array)
  • dining_styles (Array)
  • facilities (Array)
  • location_tags (Array)
  • popular_zones (Array)
  • city_id
  • mrt_station_id
  • mall_id
  • description_en
  • description_th
  • meta_title
  • meta_description
  • meta_keywords
  • bank_name
  • account_number
  • account_holder_name
  • company_name
  • tax_id
  • registration_number
  • accounting_contact_name
  • accounting_contact_email
  • accounting_contact_phone
  • created_at
  • updated_at

users

  • id (Primary Key)
  • email
  • password_hash
  • role
  • failed_login_attempts
  • lockout_until
  • created_at
  • updated_at

form_sections

  • id (Primary Key)
  • name
  • display_order
  • active

form_questions

  • id (Primary Key)
  • section_id (Foreign Key)
  • question_text
  • field_type
  • required
  • display_order

database_tags

  • id (Primary Key)
  • tag_type (cuisine, dining_style, facility, location_tag, popular_zone, city, mrt_station, mall, bts_station)
  • name_en
  • name_th
  • country_code
  • active
  • display_order

Frontend Implementation

Technology Stack

  • Framework: React 18 with TypeScript
  • Build Tool: Vite
  • Styling: Tailwind CSS + Shadcn/UI components
  • Routing: Wouter
  • Data Fetching: TanStack Query
  • Form Management: React Hook Form
  • State Management: React Context API

Key Components

Partner Portal Components:

  • OnboardingForm.tsx - Main registration form wrapper
  • Step1BusinessInfo.tsx - Business information step
  • Step2RestaurantDetails.tsx - Restaurant details step
  • Step3BankingInfo.tsx - Banking information step
  • Step4Review.tsx - Review and submit step
  • GooglePlacesAutocomplete.tsx - Google Places integration
  • OperatingHoursScheduler.tsx - Schedule management
  • CountrySelector.tsx - Country selection with flags
  • LanguageToggle.tsx - Thai/English language switcher

Operations Portal Components:

  • ApplicationList.tsx - List of pending applications
  • ApplicationDetail.tsx - Detailed application view
  • RestaurantDataForm.tsx - Comprehensive data entry form
  • EnrichDataButton.tsx - Data enrichment trigger
  • SubmitToAPI.tsx - HungryHub API submission
  • InventoryGroupManager.tsx - Advanced scheduling

Admin Manager Components:

  • FormSectionManager.tsx - Section CRUD operations
  • QuestionManager.tsx - Question configuration
  • TagManager.tsx - Tag management interface

Country-Specific Behavior

Thailand:

  • Shows BTS stations dropdown
  • Displays Thai language fields
  • Thai popular zones and cities
  • Thai MRT stations

Singapore:

  • Hides Thai-specific fields
  • Shows Singapore MRT stations
  • Singapore popular zones and cities
  • SGD currency

Malaysia:

  • Hides Thai-specific fields
  • Shows Malaysian cities and MRT stations
  • Malaysian popular zones
  • MYR currency

Validation Rules

  • Email format validation
  • Phone number format (country-specific)
  • Required field validation
  • Address validation via Google Places
  • Operating hours validation (no overlapping slots)
  • Bank account number format
  • Tax ID format (country-specific)

Backend Implementation

PRs: #7175, #7383

Core Features

  • Added Admin HMAC authentication middleware for secure API access
  • Implemented Api::Admin::BaseController with error handling and authentication
  • Created POST /api/admin/restaurants endpoint for restaurant onboarding
  • Built RestaurantService::CreateFromApi service for creating restaurants with nested data (owner, tags, locations)
  • Implemented RestaurantService::TagAssignment for robust tag assignment with search index updates
  • Auto-confirm owner email on API onboarding by setting confirmed_at: Time.current in owner creation
  • Added request body read and rewind functionality in EncryptableHelper for HMAC signature verification
  • Removed obsolete documentation files (RESTAURANT_ONBOARDING_API.md, RESTAURANT_ONBOARDING_VALIDATION_RULES.md)

Technology Stack

  • Framework: Ruby on Rails (HH-Server), Express.js with TypeScript (Onboarding Portal)
  • Database: PostgreSQL (Neon)
  • ORM: Drizzle ORM (Portal), Active Record (Rails)
  • Authentication: Session-based with bcrypt (Portal), HMAC authentication (Admin API)
  • Security: HMAC authentication for HungryHub API calls

PRD & Task

  • GitHub Repository: [hungryhub-onboarding-system]
  • N8N Workflows:
    • Confirmation Email Workflow
    • Data Enrichment Workflow
    • Restaurant Creation Workflow

Design

Partner Portal Design

  • Clean, modern interface with step indicators
  • Progress bar showing completion percentage
  • Responsive design for mobile and desktop
  • Country flag icons for country selection
  • Thai/English language toggle in header
  • Google Maps integration for visual confirmation
  • Multi-select dropdowns with search functionality
  • Time picker for operating hours
  • Drag-and-drop for image uploads (future enhancement)

Operations Portal Design

  • Dashboard-style layout
  • Sidebar navigation
  • Data table with sorting and filtering
  • Tabbed interface for different data sections
  • Inline editing capabilities
  • Action buttons (Enrich Data, Save to HungryHub)
  • Status badges for application states
  • Toast notifications for actions

Admin Manager Design

  • CRUD interface for all manageable entities
  • Drag-and-drop for reordering
  • Inline editing
  • Bulk actions support
  • Import/export functionality

API Blueprint

Partner Portal APIs

MethodPathURLDescriptionPayload
POST/api/onboarding/submitFull URLSubmit restaurant application{ businessInfo, restaurantDetails, bankingInfo }
GET/api/tags/:tagTypeFull URLGet tags by typeQuery: type=cuisine|dining_style|facility|etc
GET/api/tags/country/:countryCodeFull URLGet country-specific tagsPath: countryCode=TH|SG|MY

Operations Portal APIs

MethodPathURLDescriptionPayload
GET/api/applicationsFull URLList all applicationsQuery: status, country, page, limit
GET/api/applications/:idFull URLGet application detailsPath: id
POST/api/applications/:id/enrichFull URLTrigger N8N enrichment{ applicationId }
POST/api/applications/:id/submitFull URLSubmit to HungryHub API{ restaurantData, googleReserveData, seoData }
PUT/api/applications/:idFull URLUpdate application{ ...updatedFields }

Authentication APIs

MethodPathURLDescriptionPayload
POST/api/auth/loginFull URLUser login{ email, password }
POST/api/auth/logoutFull URLUser logoutNone
GET/api/auth/checkFull URLCheck authenticationNone

Webhook Integration

Partner Portal Webhook

  • URL: https://n8n.hungryhub.com/webhook/confirmation_email
  • Method: POST
  • Purpose: Sends confirmation email to partner after submission
  • Trigger: When partner submits application via onboarding form
  • Payload:
{
  "restaurantName": "string",
  "contactName": "string",
  "contactEmail": "string",
  "applicationId": "string",
  "submissionDate": "ISO 8601 date"
}

Operations Team Webhook

  • URL: https://n8n.hungryhub.com/webhook/add_restau_to_db
  • Method: POST
  • Purpose: Formats data and creates restaurant in HungryHub system
  • Trigger: When operations staff clicks “Save to HungryHub System”
  • Authentication: HMAC signature in headers
  • Headers:
{
  "X-App-Id": "HungryHub App ID",
  "X-Timestamp": "Unix timestamp",
  "X-Signature": "HMAC SHA-256 signature"
}
  • Payload: Complete restaurant data in HungryHub API format

DB Schema / Database Migration

Database Tags

The system uses database-driven tags for all dropdown options:

Tag TypeCountDescription
Cuisine40Restaurant cuisine types (Italian, Japanese, Thai, etc.)
Dining Style31Restaurant styles (Casual, Fine Dining, Rooftop, etc.)
Facility29Amenities (Parking, WiFi, Pet Friendly, Wheelchair Access, etc.)
Location Tag188Geographic areas and neighborhoods
Popular Zone128+Popular areas by country
City84+Cities across Thailand, Singapore, Malaysia
MRT Station172+Train stations across all countries
Mall194+Shopping malls for proximity tagging
BTS Station62Bangkok Skytrain stations (Thailand only)

Migration Scripts

Initial Schema:

CREATE TABLE restaurants_applications (
  id SERIAL PRIMARY KEY,
  submission_date TIMESTAMP DEFAULT NOW(),
  country VARCHAR(2) NOT NULL,
  status VARCHAR(50) DEFAULT 'pending',
  restaurant_name_en VARCHAR(255) NOT NULL,
  restaurant_name_th VARCHAR(255),
  contact_name VARCHAR(255) NOT NULL,
  contact_email VARCHAR(255) NOT NULL,
  contact_phone VARCHAR(50) NOT NULL,
  booking_alert_email VARCHAR(255),
  booking_alert_sms VARCHAR(50),
  address TEXT NOT NULL,
  latitude DECIMAL(10, 8),
  longitude DECIMAL(11, 8),
  google_place_id VARCHAR(255),
  operating_hours JSONB,
  cuisines TEXT[],
  dining_styles TEXT[],
  facilities TEXT[],
  location_tags TEXT[],
  popular_zones TEXT[],
  city_id INTEGER,
  mrt_station_id INTEGER,
  mall_id INTEGER,
  description_en TEXT,
  description_th TEXT,
  meta_title VARCHAR(255),
  meta_description TEXT,
  meta_keywords TEXT,
  bank_name VARCHAR(255),
  account_number VARCHAR(100),
  account_holder_name VARCHAR(255),
  company_name VARCHAR(255),
  tax_id VARCHAR(100),
  registration_number VARCHAR(100),
  accounting_contact_name VARCHAR(255),
  accounting_contact_email VARCHAR(255),
  accounting_contact_phone VARCHAR(50),
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  email VARCHAR(255) UNIQUE NOT NULL,
  password_hash VARCHAR(255) NOT NULL,
  role VARCHAR(50) DEFAULT 'operations',
  failed_login_attempts INTEGER DEFAULT 0,
  lockout_until TIMESTAMP,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

CREATE TABLE database_tags (
  id SERIAL PRIMARY KEY,
  tag_type VARCHAR(50) NOT NULL,
  name_en VARCHAR(255) NOT NULL,
  name_th VARCHAR(255),
  country_code VARCHAR(2),
  active BOOLEAN DEFAULT true,
  display_order INTEGER DEFAULT 0,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

CREATE INDEX idx_applications_status ON restaurants_applications(status);
CREATE INDEX idx_applications_country ON restaurants_applications(country);
CREATE INDEX idx_applications_submission_date ON restaurants_applications(submission_date);
CREATE INDEX idx_tags_type ON database_tags(tag_type);
CREATE INDEX idx_tags_country ON database_tags(country_code);

Environment Variables

Required Secrets

VariableDescriptionExample
DATABASE_URLPostgreSQL connection stringpostgresql://user:pass@host:5432/dbname
VITE_GOOGLE_MAPS_API_KEYGoogle Maps API keyAIza...
HUNGRYHUB_APP_IDHungryHub API app IDhh_app_123
HUNGRYHUB_APP_SECRETHungryHub API secretsecret_key_xyz
HUNGRYHUB_API_URLHungryHub API base URLhttps://api.hungryhub.com
SESSION_SECRETExpress session secretrandom_secret_string
N8N_WEBHOOK_URLN8N webhook base URLhttps://n8n.hungryhub.com/webhook

User Roles

RoleAccessCapabilities
PartnerPublicSubmit restaurant application, receive confirmation
Operations StaffLogin requiredReview, edit, enrich, and submit applications to HungryHub
AdminLogin requiredManage form fields, tags, and system configuration

Improvement:

Feature NameDateWhat ChangedDescription