HH Menu V3 and Comparing package
Description / Background
It’s difficult to compare menus between packages because each package needs the menu written separately, even when they’re mostly the same, just with different quantities. This takes time and can lead to mistakes. A better solution would allow using the same menu in different packages, only changing the quantities. This would save time and make it much easier to compare and manage packages.
Glossary
Private (https://app.clickup.com/9003122396/docs/8ca1fpw-35796/8ca1fpw-41516)
Objectives
- Admin can see the menu master list and menu group on admin dashboard
- Admin can set the menu master list on their own page
- Admin can set the menu group
- Admin can filter the menu master list and menu group
- Admin can print the menu group and it will downloaded as pdf
- Admin can duplicate the menu group and
- Admin can pick hh mneu v3 on edit package ➝ menu type
- Admin can pick the menu group and it will shows the menu section
- Admin can set the quantity of each menu section for how many items can be selected by the user from each menu section
- Admin can set the unlimited or free flow drink for each menu section
- Admin can set the time limit minutes on the edit package on the package comparison section

- The system will show "unlimited" when the menu section type is food
- The system will show "free flow drink" when the menu section type is beverage
- User can see the package comparison for each package type (AYCE, PP, XP)
Scope
HH menu
Sequence Diagram / Flow
ERD

Backend Implementation
- Main Form:
app/javascript/admin/pages/packages/MainForm.vue- Integrates a new
MenuTypecomponent. - Handles
selectedMenuTypeFromResponseand propagates it to child components. - Standardizes and simplifies form structure.
- Adds logic to normalize
package_typefor PartyPack and Ayce.
- Integrates a new
MenuType.vue: (New) Handles menu type selection.menuItem/MenuV1.vueandmenuItem/MenuV3.vue: (New) Support for menu management, including dynamic menu group and section selection, editing, and quantity/unlimited toggles.app/services/menu_data_service.rb: Fetches and processes menu data from external APIs, supports both Ayce and PartyPack.app/services/comparing_package_service.rb: Compares packages for a menu group and restaurant, returns formatted comparison data.app/services/branch_list_service.rb: Handles branch listing, filtering, and pagination.app/services/restaurant_list_service.rb: Handles restaurant listing, filtering, and pagination.app/controllers/hh_menu/comparing_package_lists_controller.rb: (New)- New endpoint for comparing packages (PartyPack & Ayce) by menu group and restaurant.
- Validates and normalizes
package_type. - Uses the new
ComparingPackageService.
app/controllers/hh_menu/packages_controller.rb- Normalizes
package_typeparameter for PartyPack and Ayce. - No longer relies on ambiguous values like
pp/ayce.
- Normalizes
app/controllers/hh_menu/restaurants_controller.rb- Adds new actions:
branch: Get branch details.branches: Paginated, filtered branch list usingBranchListService.restaurant_lists: Paginated, filtered restaurant list usingRestaurantListService.
- Now includes
ResponseCacheConcernfor caching.
- Adds new actions:
- Adds a new "Menu" dropdown for quick links to Menu Master List and Menu Groups in the admin panel.
- Utility for serializing restaurant packages, with optional inclusion of the restaurant.
- Wherever branches were filtered by their associated restaurants, the code used both
.activeand.not_expiredscopes together. Example:branch.restaurants.active.not_expired.count > 0- For master menu filtering:
branch.restaurants.active.not_expired
- The set of restaurants returned by this service is now broader, as restaurants do not need to be "active"—only "not expired" to be included.
- Adds support for
menu_v3. - If the package uses
menu_v3, it calls a new method:calculateOriginalPriceV3(). - Updates the warning to include
'HH Menu V3'. - New Helper Methods:
getMenuSectionsV3()- Fetches menu sections for the selected menu group (includes menus).
- Handles errors (menu group ID not found, API error).
getMenuGroupDetailsV3()- Fetches details for the menu group, including sections, menu group sections, and menus.
- Handles errors similarly.
- This change likely ensures that the rewards page for a specific user in the admin section uses the correct route, probably one that is scoped or protected for admin users.
-
HH MENU REPO:
- Adds new admin dashboard pages for managing
MasterMenuandMenuGroupresources, using the Administrate gem. - New filters and search options for master menus and menu groups (by ID, outlet, date, etc.).
- Modal UI for duplicating menu masters with outlet/branch selection.
- Custom table views and improved navigation.
admin/master_menus_controller.rbandadmin/menu_groups_controller.rbprovide CRUD, search, filtering, and duplication actions for admins.- Outlet/branch info is fetched from external APIs for display.
- Duplicating a master menu or group involves copying all associated menus/sections.
- New admin base controller with an access token check, and an
AuthControllerfor OAuth2 admin login/logout flows. - Adds
Api::V1::MenuGroupsController,Api::V1::MasterMenusController,Api::V1::BranchesController, etc., supporting CRUD, serialization, and bulk operations. - New API endpoints for creating, updating, and importing menu groups and master menus.
- Enhanced
SectionsControllerto support menu group associations and new attributes (likeunlimited). - Bulk import endpoints for menu groups/master menus via Excel files.
- New Models:
MenuGroup,MenuGroupSection, and supporting serializers and dashboards.
- Adds new columns to existing tables:
branch_idtomaster_menus,category_menus, etc.custom_menu_idtomenus.menu_group_id,section_type, andunlimitedtosections.main_language,optional_language,package_typetomenu_groups.
- Enforces at least one of
restaurant_idorbranch_idfor menu groups/master menus. - Updates model relationships for new entities.
- Adds new and customized ERB partials for the admin panel (navigation, sidebar, collection tables, modals, etc.).
- Improved flash messaging and layout structure.
- Gemfile: Adds the
administrategem for the new admin UI. - Dockerfile: Updates asset precompilation for Tailwind CSS.
- Routes: Extensive new admin and API routes for all new features.
- The controller responsible for admin master menus (
master_menus_controller.rb) was updated so its search now strictly uses only the outlet name. - This is enforced by initializing the GraphQL search input with
{ searchNameOnly: true }. - This prevents other search criteria from interfering, making results more precise and predictable.
- The code now contains explicit comments and inline documentation explaining the use of the
searchNameOnlyparameter. - The GraphQL query is documented to show how
$input: SearchInput!is expected and howsearchNameOnlyshould be passed. - This helps anyone maintaining or extending the code to avoid misuse or misunderstanding of the search input.
- Adds a
deleted_atcolumn (datetime) to thesectionstable. - Adds an index on this column for better query performance.
- Adds logic to set the
deleted_attimestamp when soft-deleting. - Adds scopes:
not_deleted: Returns sections wheredeleted_atis null.deleted: Returns sections wheredeleted_atis not null.
- Overrides the default
destroymethod to perform a soft-delete. - Adds a method to restore a deleted section by setting
deleted_atto null. - Updates the destroy action to perform a soft-delete instead of a hard delete.
- Adds a new
restoreaction to allow recovery of soft-deleted sections. - Ensures that deleted sections are excluded from standard queries and responses.
- Filters out soft-deleted sections when fetching menu groups.
- Adds support for branch filtering and section/package filters.
- Updates associations to use the new
not_deletedscope, ensuring soft-deleted sections are excluded unless specified. - Adds
all_sectionsassociation to get all sections including deleted ones if needed. - When returning restaurant IDs, only includes those associated with non-deleted sections.
- Adds caching hints for improved performance.
- Adds new routes to support the restore functionality (
PUT /restore) for sections under both packages and groups. - Updates schema comments to document the new
deleted_atfield. - Ensures API responses properly exclude deleted sections and reflect restoration status.
- The PR addresses an issue related to searching for outlets and branches in the codebase.
- It modifies 2 files, adding 14 lines of code and no deletions.
- The changes are likely focused on improving or correcting the search functionality for outlets and branches.
- The
menu_groups_controller.rbadds a destroy action that checks for linked sections before allowing deletion. If any sections are linked, deletion is blocked with an alert. - The
imports_controller.rbensures that when importing, if amenu_group_idormaster_menu_idis missing, the system automatically creates the required MenuGroup or MasterMenu and includes their IDs in the response. - improves restaurant and branch filtering for creating master menus.
[
github.com
https://github.com/hungryhub-team/hh-server/pull/7078/files
](https://github.com/hungryhub-team/hh-server/pull/7078/files)
[
github.com
https://github.com/hungryhub-team/hh-menu/pull/236
](https://github.com/hungryhub-team/hh-menu/pull/236)
[
github.com
https://github.com/hungryhub-team/hh-menu/pull/263/files
](https://github.com/hungryhub-team/hh-menu/pull/263/files)
[
github.com
https://github.com/hungryhub-team/hh-menu/pull/264/files
](https://github.com/hungryhub-team/hh-menu/pull/264/files)
[
github.com
https://github.com/hungryhub-team/hh-server/pull/6142/files
](https://github.com/hungryhub-team/hh-server/pull/6142/files)
[
github.com
https://github.com/hungryhub-team/hh-menu/pull/268/files
](https://github.com/hungryhub-team/hh-menu/pull/268/files)
[
github.com
https://github.com/hungryhub-team/hh-server/pull/7191/files
](https://github.com/hungryhub-team/hh-server/pull/7191/files)
[
github.com
https://github.com/hungryhub-team/hh-server/pull/7096/files
](https://github.com/hungryhub-team/hh-server/pull/7096/files)
[
github.com
https://github.com/hungryhub-team/hh-menu/pull/265/files
](https://github.com/hungryhub-team/hh-menu/pull/265/files)
[
github.com
https://github.com/hungryhub-team/hh-server/pull/7106/files
](https://github.com/hungryhub-team/hh-server/pull/7106/files)
[
github.com
https://github.com/hungryhub-team/hh-menu/pull/267/files
](https://github.com/hungryhub-team/hh-menu/pull/267/files)
[
github.com
https://github.com/hungryhub-team/hh-server/pull/7078/files
](https://github.com/hungryhub-team/hh-server/pull/7078/files)
Frontend Implementation
- New
/v3routes are added insrc/router/index.js:/v3/master/createand/v3/master/:idfor master menu creation and editing under the new flow./v3/package/:id,/v3/menu-group/create,/v3/menu-group/:idfor package and menu group handling./v3/layoutand/v3/printfor new layout and print views.
SectionMenuListCategory.vue(new): Displays menu sections grouped by category, including support for multi-language and price options.MenuCategory.vue(new): Simple component to display a category header.SectionComparison.vue(new): Provides a comparison table for packages (e.g., "All You Can Eat" vs. "Party Pack"), supporting dynamic columns based on package type.views/layout/v3/IndexV3.vue(new): The main container for the new v3 layout/print page. It loads and coordinates header, footer, package comparison, categories, and menu list, fetching required data from APIs.- Handles loading states, API calls, and error notifications.
stores/menuGroup.js(new): Manages the state for menu groups, including form data for branch, restaurant, name, and sections.stores/packageList.js: Adds asection_typefield (default "food") to section state for v3 handling.stores/master.js: Adds acustom_menu_idfield for menu item identification.views/master/MasterList.vue:Conditional rendering based on the route (checks if in v3 mode).- New logic for handling outlet/branch selection (
FormOutletSetting.vue). - Ability to create a master menu and its items in a single API call (
createNewMasterAndMenu), and redirect after creation. - The form now includes and persists
custom_menu_idfor each menu item. FormOutletSetting.vue: Allows users to select either an outlet or branch and search for them via API.views/package/FormSection.vue:- Adds a
section_typeradio selector ("food" or "beverage") for v3. - Adjusts logic for add/update section to support both save-and-edit and non-edit (for v3).
- Handles menu selection and availability based on new menu group data structure.
- Adds a
views/print/PrintMenu.vue:- Adds v3 support for template selection (package/group based) and group naming for print output.
- Changes parameter passing and URL construction logic for print/preview in v3 mode.
- Integrates new restaurant selection logic for v3 menu groups and branches.
SelectLang.vue: Button styling now rotates when open.FormLanguageSetting.vue: AddsusePriceanduseTranslateprops to control optional UI.- Many components: Conditional logic and props to control v3 vs. legacy flows.
- General code tidying: Use of
vue-typesfor prop validation, improved comments, and clearer method names. - Adds logic for handling 'Other' menu categories if items do not have a
category_menu_id. - Adds random key generation for list rendering stability in v3 components.
- Handles error and loading states gracefully in new and updated components.
- Generalizes several API endpoints to work with either branch or restaurant context.
- Menu images and gallery images now load reliably from the correct domains.
- The code is cleaner, with fewer hardcoded values and more flexible helpers.
[
github.com
https://github.com/hungryhub-team/hh-menu-frontend-new/pull/143
](https://github.com/hungryhub-team/hh-menu-frontend-new/pull/143)
[
github.com
https://github.com/hungryhub-team/hh-pegasus/pull/2039/files
](https://github.com/hungryhub-team/hh-pegasus/pull/2039/files)
[
github.com
https://github.com/hungryhub-team/hh-pegasus/pull/2039/files
](https://github.com/hungryhub-team/hh-pegasus/pull/2039/files)
[
github.com
https://github.com/hungryhub-team/hh-pegasus/pull/2030/files
](https://github.com/hungryhub-team/hh-pegasus/pull/2030/files)
[
github.com
https://github.com/hungryhub-team/hh-pegasus/pull/2039/files
](https://github.com/hungryhub-team/hh-pegasus/pull/2039/files)
PRD & Task
Private (https://app.clickup.com/9003122396/docs/8ca1fpw-7922/8ca1fpw-42456)
Private (https://app.clickup.com/t/86cuu81rm)
Design
API Blueprint
| Method | Path | URL | Description | Payload |
|---|---|---|---|---|
| GET | /api/v1/comparing_package_lists | API endpoint to compare package lists by menu group and package type. | menu_group_id, package_type, restaurant_id | |
| GET | /api/v1/menu_groups/check_data | to fetch detailed package-section data. | - | |
| GET | /api/v1/restaurants/branch/:id | Returns info (id, name) for a specific branch by ID. | id (in path) | |
| GET | /api/v1/branches | Returns a paginated list of branches with active, not-expired restaurants. Supports filtering by name and pagination parameters. | name_like, page, per_page | |
| GET | /api/v1/restaurant_lists | Returns a paginated list of active, not-expired restaurants. Supports name filtering, pagination, and caching. | name_like, page, per_page | |
| - | - | - | - | - |
| GET | /hh_menu/restaurant_lists.json | name_like (string, query) | ||
| GET | /hh_menu/restaurants/{id} | id (path) | ||
| GET | /hh_menu/branches.json | name_like (string, query) | ||
| GET | /hh_menu/restaurants/branch/{id} | id (path) | ||
| POST | /api/v1/master_menus/create_master_menu | { branch_id, restaurant_id, main_language, menu: [...] } (body, JSON) | ||
| GET | /api/v1/menu_groups/{id}/detail | id (path) | ||
| GET | /api/v1/branches/{id}/master_menu | id (path) | ||
| GET | /api/v1/restaurants/{id}/master_menu | id (path) |
New Query
-
DB Schema / Database Migration
- Creates the
userstable for Devise authentication. - Adds admin functionality and Devise “confirmable” to users
- Creates the
menu_groupstable. - Adds a
branch_idcolumn to themaster_menustable and an index on it. - Adds a
custom_menu_idcolumn to themenustable and an index on it. - Adds
menu_group_idto thesectionstable. - Adds an
unlimitedboolean column (default: false) tosections, indicating if the section has unlimited quantity. - A data migration that seeds two admin users.
- Adds
main_languageandoptional_language` tomenu_groups - Adds a
branch_idcolumn (bigint) and index tocategory_menus, enabling menus to be associated with a specific branch. - Creates a new table called
menu_group_sectionsto represent a many-to-many relationship betweenMenuGroupandSection. - Adds a
menu_group_idcolumn to all relevant package tables (e.g.,party_packs,ayce,hungry_sets, etc.) to relate packages to menu groups.
Improvement:
| Feature Name | Date | What Changed | Description |
|---|---|---|---|
| hh menu v3 |