Canteen Management System¶
Product Requirements Document — Full Feature Specification
| Field | Value |
|---|---|
| Document Version | v2.15 |
| Audience | Engineering, Product, Design, QA |
Part I — Overview¶
1. Product Overview¶
The Smartsapp Canteen Management System is a comprehensive school canteen operations platform that enables schools, catering vendors, and canteen staff to manage meals, orders, meal tickets, POS transactions, menus, student feeding eligibility, and financial reporting from a single, centralised Admin Portal.
It also powers parent-facing clients — the Parent App (mobile) and the Parent Portal (web) — through which parents pre-order meals, and connects to physical POS terminals for on-site canteen sales.
1.1 Document Structure¶
This PRD is organised into four parts:
| Part | Scope | Sections |
|---|---|---|
| Part I — Overview | Product context, goals, and order types | 1 |
| Part II — Admin Portal | Feeding list, meal tickets, menu management, student directory, reports, settings, and user management | 2–10 |
| Part III — Parent App | Viewing menus per child, browsing items, placing orders, and cancellations | 11 |
| Part IV — Parent Portal | Web client for parents: login, child calendars, meal planning, payment, order history | 12 |
1.2 Strategic Goals¶
- Support multiple meal-funding models: prepaid tickets, parent pre-orders, and walk-in POS purchases
- Give school administrators, catering vendors, and kitchen staff role-appropriate visibility into daily meal operations
- Produce accurate financial reporting for school administration
1.3 System Boundaries¶
The system spans three client applications:
Admin Portal (Part II) — used by school administrators, catering vendors, and canteen staff:
- Menu creation and meal scheduling
- Meal Ticket creation and student assignment
- Feeding List generation and real-time redemption tracking
- POS-based walk-in sales
- Sika ID / Wallet management
- Sales, order, and stock reporting
- User, role, and catering service management
Parent App (Part III) — used by parents on a mobile device:
- View menus available to their children
- Browse scheduled items with pricing, allergens, and stock
- Place pre-orders across multiple dates and children
- Cancel orders before the cancellation deadline
Parent Portal (Part IV) — used by parents from a desktop or mobile web browser:
- Authenticate using the same phone + PIN credentials as the Parent App
- View each child's weekly meal schedule grouped by serving period
- Plan and pay for meals across multiple children in a single batch
- Review and cancel pre-orders subject to the menu's cancellation deadline
- View order history across children with date-range filtering
1.4 Order Types¶
Three distinct order types feed into the central Feeding List:
| Order Type | Description | Who Initiates |
|---|---|---|
| Meal Ticket | Prepaid feeding plan covering daily, monthly, or termly meals from designated menu sections. Students are enrolled by an admin or parent. | Canteen Admin |
| Pre-Order | Meal ordered in advance by a parent through the Smartsapp Parent App before the ordering deadline. | Parent |
| POS Purchase | Meal purchased at the canteen counter by a student using a physical POS terminal. | Canteen Staff / Student |
Part II — Admin Portal¶
2. Core Concept: The Feeding List¶
Definition The Feeding List is the master operational record used by kitchen staff and canteen administrators to know: which students must be fed on a given day, what items they should receive, what payment method was used, and whether each meal has been redeemed. It consolidates all three order types: Meal Tickets, Pre-Orders, and POS Purchases into one unified view.
2.1 Feeding List Lifecycle¶
- A student becomes eligible via one of: a Meal Ticket assignment, a parent pre-order, or a POS walk-in purchase.
- An order is created with status Draft (for parent pre-orders) or Paid (for admin/POS orders). The order automatically appears on the Feeding List.
- On the day of service, kitchen staff use the portal (or POS scanner) to redeem meals.
- Meal status transitions according to the redemption events (see 2.2).
- Auto-redemption rules (configured in Settings) may trigger automatic status transitions.
- Completed daily feeding data rolls into reporting and stock reconciliation.
2.2 Order Status Definitions¶
| Status | Description |
|---|---|
| Draft | Order created by parent but not yet checked out. Parent is reviewing and can still edit or remove items. |
| Pending Payment | Parent has checked out and the legacy payment service has issued an invoice; awaiting the legacy invoice.paid event to finalise. The order is locked from edits and not yet on the kitchen's feeding list. |
| Paid | Invoice confirmed paid by the legacy payment service. Meal has not yet been served and the order appears on the Feeding List. |
| Served | All items in the order have been served. |
| Partially Served | Some items served; others outstanding. |
| Cancelled | Order was cancelled before or during service. |
2.3 Cancellation Rules¶
Monthly and Termly Meal Tickets CANNOT be cancelled from the Feeding List. Cancellation is only permitted for Pre-Orders (before the order cancellation deadline for parent), daily Ticket orders, and POS Purchases.
The Order Cancellation Deadline is configured per menu. Once the deadline has passed relative to the scheduled meal time, parents cannot cancel from the Parent App, and admin cancellation via the portal is allowed.
3. Dashboard¶
The Dashboard is the first screen seen after login. It provides a real-time operational snapshot of canteen activity for the current or selected date.
3.1 Key Metric Cards¶
| Metric | Description & Logic |
|---|---|
| Students Present & On Feeding List | Count of students marked present in the attendance system AND appearing on today's Feeding List. Drives kitchen prep numbers. |
| Meals Served vs. Unserved | Side-by-side count of Feeding List entries with status Served vs. Draft/Paid/Partially Served. Excludes Cancelled. |
| Students Absent But On Feeding List | Count of students marked absent who still have a Draft, Paid, or Partially Served entry on the Feeding List. These meals may need to be withheld or held. |
| Orders for the Day — by Item | Total quantity ordered per menu item, grouped by item with a nested variant breakdown. Each item shows: item name, total quantity across all variants, and a list of variants (each with variant name and quantity). Items without variants show an empty variant list. Example: Jollof Rice (total: 62) — Small x 40, Large x 22. |
| Orders for the Day — by Category | Aggregated order counts grouped by menu category (e.g., Snacks: 80, Lunch: 152, Drinks: 60). |
3.2 Dashboard Filters¶
All dashboard metrics must be filterable by the following dimensions simultaneously:
- Date (defaults to today; supports past and future dates)
- Campus
- Catering Service
- Canteen Personnel (the user who processed the order)
3.3 Dashboard Actions¶
- Export orders for the selected day as Excel (.xlsx)
- Quick-navigate to Feeding List filtered by selected metrics
4. Feeding List¶
The Feeding List displays all students expected to receive meals within a specified time period regardless of order type.
4.1 Feeding List View¶
The Feeding List is a query view over orders — there is no separate "feeding list" table. Any order that matches the date and filter criteria appears automatically. When a parent confirms and pays for a pre-order, or a POS order is created, it immediately appears on the Feeding List.
Displayed Fields:
- Order Number
- Student (ID, first name, last name, class name)
- Order Type (Ticket / Pre-Order / POS)
- Total Price
- Payment Mode
- Status (Draft / Paid / Served / Partially Served / Cancelled)
- Items (each with: name, variant, section, quantity, unit price, served status, served by, served at)
- Redemption Date
4.2 Filter Panel¶
The Feeding List must support simultaneous filtering by all of the following:
| Filter | Filter Options / Behaviour |
|---|---|
| Student Name | Free-text search; partial match supported |
| Item | Free-text search |
| Status | Draft, Paid, Served, Partially Served, Cancelled (multi-select) |
| Order Type | Ticket, Pre-Order, POS Purchase (multi-select) |
| Date Range | Start date (defaults to today) and End date (defaults to same as Start date). Both are optional — if neither is specified, defaults to today only. |
| Campus | Dropdown; multi-select |
| Class / Grade | Dropdown; multi-select; depends on Campus selection |
| Section | Menu section (e.g., Lunch, Snack Break) |
| Menu | Multi-select from published menus |
| Item Category | Multi-select from item categories |
| Attendance Status | Present, Absent |
| Catering Service | Multi-select from registered services |
| Salesperson / Personnel | Multi-select from canteen users |
| Payment Mode | Sika ID, Online Payment, Credit/Pay Later, Cash, Allocation (multi-select) |
4.3 Feeding List Actions¶
Export¶
- Export the currently filtered Feeding List as an Excel (.xlsx) file
- Export should respect all active filters
Print Labels¶
- Generate printable meal labels for kitchen preparation
- Each label includes: Student name, class, items ordered, quantity, and date
Bulk Redeem¶
- Admin can select multiple Paid orders and mark them as Served in one action
- Bulk serve applies only to Draft, Paid, and Partially Served entries
- System logs the time and user who performed the bulk redeem on each item
Cancel Order¶
- Admin can cancel Draft, Paid, and Served orders from the Feeding List
- Cancellation of Monthly and Termly Ticket orders is NOT permitted
- Cancellation of daily Ticket, Pre-Order, and POS orders is permitted
- Cancelled orders are not removed from the list; they remain with status Cancelled
- All cancelled order refunds must be credited to the student's Sika ID wallet, regardless of the original payment method (Sika ID, online) — Status: Pending:
OrderService.cancel()today only sets the status to Cancelled; it does not post a refund to the student's wallet. Refund wiring is a follow-up. - System records who cancelled and when
View Order Details¶
Clicking any entry opens an Order Detail panel showing:
- Order Number
- Student Name, Class, Campus
- Items ordered (name, variant, quantity, unit price, served status, served by, served at)
- Total Price
- Date ordered
- Created / ordered by (parent name or admin name)
- Payment Mode
- Order Type
- Current Status
- Status change history (who changed it and when)
Per-Item Serving: Items within the same order may be served at different times (e.g., lunch at 12:30, snack at 15:00). Each item tracks its own served status, who served it, and when. If only some items are served, the order status is Partially Served; once all items are served, the order becomes Served.
4.4 Adding Students to Feeding List (Ticket Enrolment)¶
Scope This action is specific to Meal Tickets only. Pre-Orders and POS Purchases are added via the parent app and POS to the Feeding List automatically; they do not require manual enrolment.
Enrolment Workflow¶
- Select a Ticket from the available published tickets
- Select Academic Term
- Select Target Students using one or more of: individual student search, class/grade selection, or entire campus
- Select Payment Mode: Sika ID / Wallet, Credit / Pay Later, or Already Paid (cash collected externally)
- System validates that the selected students are within the ticket's eligible audience (classes, campus, groups attached to the linked menu)
- System generates Feeding List entries for each valid menu day within the selected duration
- A confirmation summary shows: number of students enrolled, number of feeding days, and total amount charged
Business Rules for Enrolment¶
A student cannot be enrolled in the same ticket for the same day more than once.
If a student's Sika ID balance is insufficient for full payment, the system should warn the admin before proceeding. The admin may override and proceed (creating a credit entry).
Students not within the ticket's linked menu audience (campus/class/group) must be flagged and excluded unless the admin explicitly overrides.
Enrolment for a day already past is not permitted (this is debatable).
5. Meal Ticket Management¶
A Meal Ticket is a prepaid meal plan that grants a student access to meals from specific sections of a menu for a defined duration.
5.1 Creating a Ticket¶
Required Fields:
| Field | Description & Behaviour |
|---|---|
| Ticket Name | Descriptive name, e.g., "Term 1 Junior School Lunch Ticket" |
| Attached Menu | Select from published/unpublished menus. The menu determines what items are available and which classes/campuses/groups are eligible for the ticket. |
| Academic Term | Select the term during which this ticket is valid. This determines the valid date range. |
| Menu Sections | Select one or more sections of the attached menu that this ticket covers (e.g., Lunch only; or Lunch + Snack). Parents using the Parent App see ONLY the selected sections. Status: Pending — the MealTicket entity has no menuSectionIds field yet, and the admin ticket form currently collects class/grade IDs under a "Sections" label (not menu-section IDs). Both backend entity + API and the admin form need to be wired before this field ships. |
| Pricing Method | Daily, Monthly, or Termly (see 5.2) |
| Pricing Scheme | Uniform (same price for all groups) or Differential (different price per class, campus, or group) — see 5.3 |
5.2 Pricing Methods¶
| Method | Behaviour |
|---|---|
| Daily | A price is set per day. The total cost for a student is: daily_price x number_of_enrolled_days. |
| Monthly | A flat price is set per calendar month. Cancellation of individual days is NOT permitted under monthly pricing. The full month price applies regardless of absences. |
| Termly | A flat price is set for the entire academic term. Cancellation is NOT permitted. The full term price applies regardless of absences. |
5.3 Pricing Scheme¶
- Uniform Pricing: A single price applies to all classes, campuses, and groups within the ticket's scope.
- Differential Pricing: The admin sets a distinct price for each class, campus, or group. Prices must be set for every eligible segment before the ticket can be published.
5.4 Ticket Audience & Visibility¶
- A ticket is automatically available to the classes, campuses, and groups that are attached to the linked menu.
- Admins can view the count of students enrolled on ticket.
- Clicking the student count redirects to the Feeding List filtered for that ticket to show enrolled students.
5.5 Ticket Lifecycle Actions¶
| Action | Behaviour |
|---|---|
| Edit Ticket | All fields are editable before any student is enrolled. After enrolment, pricing changes require admin confirmation and may trigger recalculation of existing entries. |
| View Assigned Students | Displays count; clicking navigates to Feeding List filtered for this ticket. |
| Archive / Deactivate | Makes the ticket inactive when the validity period ends. Archived tickets remain visible in historical reports but cannot accept new enrolments. |
| Delete Ticket | Permitted only if no students are enrolled. System must display a warning listing enrolled student count if deletion is attempted on an active ticket. |
5.6 Business Rules — Tickets¶
Monthly and Termly tickets cannot be cancelled on a per-day basis from the Feeding List.
A ticket must have at least one menu section selected before it can be saved.
Differential pricing requires a price to be set for every class/campus/group in the audience before the ticket can be published.
Deleting a ticket with enrolled students is blocked; admin must unenrol all students first.
The Feeding List entries generated by a ticket are tied to the ticket's linked menu schedule. If the menu schedule changes, existing Feeding List entries are NOT automatically updated, admin must manually adjust.
6. Menu Management¶
Menu Management is the foundation of the canteen system. It allows admins to define food items, organise them into categories and sections, build menus, schedule meals, and publish menus to parents and students.
6.1 Item Categories¶
Categories group items for display and reporting purposes (e.g., Snacks, Lunch, Drinks, Desserts).
Category Fields:
- Category Name (required, must be unique)
- Description (optional)
Category Actions:
- Create new category
- Edit category name and description
- Delete category — blocked if any items are assigned to the category; system shows a warning listing the affected items
6.2 Menu Items¶
Items represent individual food products available for ordering or assignment to menus.
Item Fields:
| Field | Description |
|---|---|
| Item Name | Required; must be unique within a catering service |
| Product Image | Upload from computer OR browse/import from an online source directly within the portal |
| Description | Optional; visible to parents in the Parent App |
| Item Category | Select from existing categories |
| Catering Service | The item is owned by one catering service. Staff only see items belonging to their assigned service. |
| Stock Available | Numeric field representing current stock count. Decrements automatically when meals are redeemed. |
| Allergens | Multi-select tag field (e.g., Gluten, Nuts, Dairy, Eggs, Soy, Shellfish). Displayed on the Parent App and Feeding List labels. |
| Max Item Quantity Per Order | Maximum quantity of this item a parent can add to a single order for a given date. The limit resets each day. Set to a fixed number or null (unlimited). Default: 1. |
| Pricing Style | Fixed Price, Variant Pricing, or No Pricing (see 6.3) |
| Created By | System-tracked: the createdBy staff UUID is stamped on the item at creation and is read-only. First name and last name are resolved from the staff record at read time (via the response mapper), not stored on the item entity. |
6.3 Item Pricing Styles¶
The pricing style determines how the item is priced and what fields are required.
Fixed Price (FIXED)
A single price applies to the item. Set the defaultPrice field on the item — no variants needed.
| Field | Required | Description |
|---|---|---|
defaultPrice |
Yes | The price charged for this item (e.g., GHS 15.00) |
Variants are not allowed when pricing style is Fixed.
Variant Pricing (VARIANT)
The item has multiple variants, each with its own price. The defaultPrice field on the item is not used — pricing comes from the variants instead.
Each variant specifies:
| Field | Required | Description |
|---|---|---|
| Variant Name | Yes | Display name (e.g., "Small", "Medium", "Large") |
| Variant Price | Yes | Price for this variant (e.g., GHS 5.00, GHS 8.00, GHS 10.00) |
| Audience | Yes | All — available to all students, or Specific — restricted to selected targets |
| Target Campuses | If Specific | List of campus IDs this variant is available to. Required when audience is SPECIFIC. |
| Target Classes | If Specific | List of class/grade IDs this variant is available to. Required when audience is SPECIFIC. |
When audience is SPECIFIC, at least one target campus or class must be provided. Both can be set together (e.g., a variant available to Primary classes at the Main Campus only).
At least one variant must be created before the item can be used in a menu.
No Pricing (NO_PRICE)
The item has no price — it is treated as free (price = 0).
Both defaultPrice and variants are not used when pricing style is No Pricing.
Pricing Style Summary¶
| Style | defaultPrice |
Variants | Use case |
|---|---|---|---|
| Fixed | Required | Not allowed | Single-price items (e.g., Jollof Rice — GHS 15) |
| Variant | Not used | Required (1+) | Items with size/portion options (e.g., Small/Medium/Large) |
| No Pricing | Not used | Not used | Free items (price = 0) |
6.4 Item Actions¶
- Bulk import items from Excel / CSV template
- Edit any item field
- Delete item — blocked if the item is currently assigned to any published or unpublished menu; system shows warning with affected menu names
- Filter item list by catering service, item category, and/or free-text search by name
6.5 Item Library¶
The Item Library is a panel used during menu scheduling that lets staff browse and add items to the schedule.
Layout:
- Filter Tabs — filter items by catering service (All, or a specific service). Powered by the catering services registered for the school.
- Search Bar — free-text search by item name.
- Recently Used — the top section shows items that were most recently scheduled on menus (last 30 days), ordered by most recent. Allows quick re-scheduling of frequently used items.
- Items Grouped by Category — below recently used, items are grouped under their assigned category (e.g., "Hot Breakfasts", "Drinks"). Each group shows the category name and theme colour. Uncategorised items appear under an "Uncategorised" heading.
Item Display:
Each item in the library shows: name, product image, and pricing summary (default price for fixed-price items; variant names and prices for variant-priced items).
6.6 Menu Creation¶
Menu Fields:
| Field | Description | Condition |
|---|---|---|
| Menu Name | Required; descriptive (e.g., "Term 2 Junior School Menu") | Always |
| Description | Optional context for staff | Always |
| Menu Purpose | How parents view this menu: For Information Only (no ordering), Parents Can Order (see 6.9) | Always |
| Payment Type | Order and Pay (Item Pricing), Order Only (no payment required), or Order and Pay (Meal Ticket Pricing) — see 6.8 | Only when purpose = Parents Can Order |
| Menu Duration | Date range the menu is active | Always |
| Target Audience | Select campuses and/or classes this menu is published to. Individual students can be excluded. See 6.7. | Always |
| Visibility Window | How many days ahead of today parents can see the menu in the Parent App. Range 1–30. Admin sets a number of days (or picks weeks in the UI, which is converted to days at submit). Default 30. | Always |
| Ordering Settings | Configured separately (see 6.10) | Only when purpose = Parents Can Order |
| Last Updated By | System-tracked: name and ID of the staff member who last modified the menu. Set automatically on create, update, publish, and unpublish. | Always (read-only) |
When purpose is For Information Only, the following fields are not required and are ignored by the system: Payment Type, Ordering Deadline Type, Daily Cutoff Time, Weekly Cutoff Day, and Order Cancellation Deadline. These fields only apply when the menu purpose is Parents Can Order.
6.7 Target Audience¶
Target audience defines which students can see and interact with this menu. It is set during menu creation and can be edited before or after publishing.
Audience Fields:
| Field | Required | Description |
|---|---|---|
| Campuses | At least one campus or class required | Select one or more campuses. All students enrolled in the selected campuses see this menu in the Parent App. |
| Classes / Grades | At least one campus or class required | Select one or more classes. Only students in the selected classes see this menu. Can be used alongside or instead of campus selection for finer targeting. |
| Excluded Students | Optional | Individual students to exclude from the menu, even if they belong to a selected campus or class. Exclusions are searched and added by student name. |
Target Audience Business Rules:
At least one campus or class must be selected before the menu can be saved.
Excluded students are removed from the menu's visibility regardless of their campus or class membership.
Changing the audience on a published menu immediately affects visibility in the Parent App — newly added campuses/classes see the menu right away, and removed ones lose access.
Audience scope determines which students are eligible for Meal Tickets linked to this menu (see section 5.4).
6.8 Payment Type Options¶
Applicability: Payment type only applies to menus with purpose Parents Can Order. Menus with purpose For Information Only do not use payment settings.
| Payment Type | Behaviour |
|---|---|
| Order and Pay (Item Pricing) | Parent selects items and pays at per-item prices set on each menu item. |
| Order Only | Parent selects items but no payment is required. Items are treated as free at ordering time. |
| Order and Pay (Meal Ticket Pricing) | Parent selects items but pays using the pricing defined on the associated Meal Ticket rather than per-item prices. |
6.9 Menu Purpose Options¶
| Purpose | Behaviour |
|---|---|
| For Information Only | Menu is visible to parents but no ordering is enabled. Parents see what is being served each day. |
| Parents Can Order | Parents can place pre-orders from the Parent App. Parents can select meals across multiple days in a single session and pay for all of them in one transaction. Payment type applies. |
6.10 Ordering Configuration¶
Applicability: Ordering configuration only applies to menus with purpose Parents Can Order. Menus with purpose For Information Only do not use ordering settings.
Ordering Deadline Types¶
| Deadline Type | Description |
|---|---|
| Daily Cutoff | Parents can order between the same day and up to 5 days ahead, at a specified cut-off time before the meal is served. Example: order by 7:00 AM on the day of service, or any time up to 5 days prior. |
| Weekly Cutoff | Admin selects a specific day of the week as the absolute ordering deadline for the following week's meals. Example: all orders for next week must be placed by Thursday 11:59 PM of the current week. |
Important Weekends and public holidays are included in deadline calculations. The system must count calendar days, not school days, when computing deadlines.
Order Cancellation Deadline¶
Parents may cancel pre-orders up to a configured number of hours before the meal is served. After this deadline, cancellation from the Parent App is blocked.
- Example: cancellation not allowed within 12 hours of meal service
- Admins can still cancel via the Admin Portal
6.11 Menu Sections¶
Sections subdivide a menu into meal groupings (e.g., Breakfast, Lunch, Snack Break). Sections are used to:
- Organise the ordering experience for parents
- Control which parts of the menu a Ticket covers
- Define serving times for ordering deadline calculations
Section Fields:
| Field | Required | Description |
|---|---|---|
| Section Name | Yes | Descriptive name (e.g., "Breakfast", "Lunch", "Snack Break") |
| Serving Start Time | No | Start of the serving window (e.g., 12:00 PM). Displayed in the Parent App and used to calculate ordering and cancellation deadlines relative to meal service. |
| Serving End Time | No | End of the serving window (e.g., 1:30 PM). Together with start time, defines the period during which meals from this section are served. |
| Selection Mode | Yes | Single Selection — parent must choose exactly one item from this section per order. Multiple Selection — parent can choose more than one item from this section per order. |
| Theme Colour | No | Hex colour code (e.g., #FF5733) used to visually distinguish sections in the UI. |
6.12 Menu Scheduling¶
Items must be scheduled to specific calendar days within a section before they become visible to parents on that menu. Unscheduled items do not appear in the Parent App, even if they exist in the system.
Scheduling Scope:
Admins can narrow what they are scheduling to either:
- A single item — schedule one specific item to a day or set of days within a section
- An entire category — all items belonging to that category appear on the scheduled day(s). Individual items within the category can be excluded before confirming.
Scheduling Methods:
| Method | Description |
|---|---|
| Single-day | Assign an item or category to one specific calendar date within a section. e.g., Monday 12 May → Jollof Rice in the Breakfast section. |
| Repeat — Every day | Item or category appears on every day within the menu's duration. |
| Repeat — Every weekday | Item or category appears Monday through Friday within the menu's duration. |
| Repeat — Specific day(s) | Item or category appears on selected day(s) of the week (e.g., every Monday; every Monday, Wednesday, and Friday) within the menu's duration. |
Repeat scheduling generates individual date entries for each matching day across the menu's active duration. These entries can be individually edited or removed without affecting the rest of the pattern.
Scheduling Controls:
- View item details for any scheduled day
- Edit or remove items on any scheduled day after scheduling
- When a category is added to a scheduled day, newly added items to that category in the future do NOT automatically appear on that day — a manual reschedule is required
Preview & Publish:
- Admin can preview exactly how the menu will appear in the Parent App before publishing
- Publish action makes the menu visible to the target audience
- Published menus can be unpublished; unpublishing hides the menu from the Parent App
6.13 Menu Actions¶
| Action | Behaviour & Rules |
|---|---|
| Edit Menu | Items scheduled are editable. |
| Edit Configuration | Menu name, description, audience, ordering settings are editable before and after publishing. |
| View Audience | Shows count of students the menu is published to, with ability to view the full student list. |
| Export Menu | Export the full menu schedule as Excel (.xlsx) with items, categories, dates, and pricing. |
| Unpublish Menu | Hides menu from Parent App. Existing pre-orders for future dates are preserved but parents cannot place new ones. |
| Delete Menu | Permitted only for Unpublished menus with no pending or future orders. System shows a warning if orders exist. |
6.14 Business Rules — Menus & Items¶
An item cannot be deleted if it is assigned to any menu (published or unpublished).
A menu cannot be deleted if it has any orders placed for today or any future date.
Weekends and public holidays count as calendar days in ordering deadline calculations.
The Order Cancellation Deadline is enforced for parent-initiated cancellations; admin overrides are always available.
Items must be scheduled to at least one day within a section before they are visible to parents on that menu. Unscheduled items never appear in the Parent App.
A menu section must have at least one item scheduled before a parent can view it.
Repeat-scheduled entries can be individually overridden or removed for specific dates without affecting the remaining entries in the pattern.
When a category is added to a scheduled day, newly added items to that category in the future do NOT automatically appear on that day — a manual reschedule is required.
A menu with "For Information Only" purpose cannot be used for Ticket creation or parent ordering.
Stock counts decrease when a meal is redeemed, not when ordered.
7. Student Directory¶
The Student Directory provides canteen administrators with a read-only view of relevant student information to support canteen operations.
7.1 Student Profile Data¶
- Full Name
- Student ID
- Class / Grade
- Sika ID / Wallet Balance (with positive/negative indicator)
- Recorded Allergies (sourced from student profile)
7.2 Student List Filters¶
- Student Name (free-text search)
- Menus Available (multi-select)
- Active Feeding Ticket (multi-select)
- Sika ID Balance: Positive, Zero, Negative
- Debt Status: Owing (negative Sika ID balance) / Not Owing
- Class / Campus
7.3 Student Directory Actions¶
- Export student list with canteen-relevant fields as Excel (.xlsx)
- Click through to student's Feeding List
- Click through to student's Sika ID transaction history
8. Reports¶
The Reports module provides financial, operational, and analytical insights into canteen performance. All reports support date range filtering and export.
Period Comparison — All report endpoints accept an optional
compareflag. When enabled, the system automatically computes the previous period of equal length (e.g. requesting Mar 8–14 compares against Mar 1–7) and returns both periods with absolute and percentage deltas for each KPI metric. The comparison applies only to top-level KPI fields (e.g. total revenue, order count), not to detail lists (transactions, item rankings).
8.1 Overview Report¶
- Total orders for the period
- Stock remaining per item (closing stock = opening stock - redeemed/ordered meals)
- Quick summary of redeemed vs. unredeemed meals
8.2 Order Summary — Go-To-Market Report¶
This report is designed for kitchen procurement and preparation planning.
- Summary of all orders for the upcoming week
- Quantity ordered per item with variant breakdown
- Orders grouped by category
- Export as Excel
8.3 Sales Report¶
Filters:
- Date range
- Salesperson / Canteen Personnel
- Campus
Metrics:
- Total Sales Revenue (sum of all paid transactions)
- Total Credit Sales (sum of Credit / Pay Later transactions)
- Total Number of Customers served
- Sales performance trend over the selected duration (chart)
- Detailed transaction history log (line-by-line transaction view): Invoice number, Student name, Payer/created by, Amount, Payment method, Item, Date, Time, Status
- Item search within the transaction history
- Export sales history as Excel
8.4 Order Report¶
Filters:
- Date range
- Salesperson / Canteen Personnel
- Campus
Summary Metrics (each clickable, navigating to filtered Feeding List):
- Total Number of Orders -> navigates to Feeding List for period
- Total Order Amount -> navigates to Feeding List for period
- Total Cancelled Orders -> navigates to Feeding List filtered for Cancelled status
Performance Analytics:
- Order volume trend chart over selected duration
- Order type frequency chart — preorder vs walk-ins per section
- Individual Item Performance Ranking — sortable best-to-worst and worst-to-best
- Item search within the ranking list
8.5 Ticket Report¶
Filters:
- Date range
- Campus
Summary Metrics:
- Total Tickets Purchased -> clickable, navigates to Feeding List for ticket orders
- Total Tickets Served -> clickable, navigates to Feeding List filtered for Served ticket orders
- Total Tickets Unserved -> clickable, navigates to Feeding List filtered for unserved ticket orders
Per-Ticket Breakdown:
| Column | Description |
|---|---|
| Ticket Name | Name of the meal ticket |
| Number Sold | Total enrolments for the ticket in the period |
| Number Served | Total feeding entries served against this ticket |
| Serve Rate | Served / Sold x 100% |
8.6 Sika ID Report¶
Filters:
- Date range
- Campus
Summary Metrics:
- Total Sika ID Deposits (all wallet top-ups in the period)
- Total Debt Owed (aggregate of all negative wallet balances) -> clicking navigates to Student Directory filtered for students with negative balance
Transaction History:
- Line-by-line Sika ID transaction log: student name, grade, transaction type (purchase/topup/refund), amount, date, type/platform (POS, Preorder, online, offline), status and user who processed it
9. Settings¶
9.1 Meal Redemption Mode¶
Admins configure system-wide how meals are redeemed. This setting affects all entries on the Feeding List.
| Redemption Mode | Behaviour |
|---|---|
| Auto Serve | Meals are automatically marked as Served at 10:00 AM each school day for all students with a Paid entry on the Feeding List, regardless of attendance status. |
| Auto Serve Present | Meals are automatically marked as Served only when the student is marked as Present in the Smartsapp attendance system AND has a Paid entry on the Feeding List. Absent students' meals remain Paid. |
| Scan to Redeem | No automatic redemption occurs. Each meal must be manually redeemed by canteen staff via the Admin Portal or by scanning the student's ID / QR code on a POS terminal. |
Integration Dependency Auto Redeem Present requires a live integration with the Smartsapp School attendance system. If the attendance system is unavailable, the redemption mode should fall back gracefully and alert the admin.
9.2 Catering Services¶
Schools may operate with multiple catering vendors. Each vendor is set up as a Catering Service.
Default School Catering Service¶
When a school is created, the system automatically creates a default Catering Service using the school's own details (name, logo, email, phone). This ensures the school can immediately create items and menus without additional setup.
- The default service is pre-populated from the School entity's details
- It is fully editable (name, logo, contact details can be changed)
- It cannot be deleted while it is the only catering service for the school
- Additional external catering services can be added alongside it
Catering Service Fields:
- Company Logo (image upload)
- Service Name
- Email Address
- Phone Number
Catering Service Actions:
- Add a new catering service
- Edit existing service details
- Delete a catering service — system should warn if the service has active items, menus, or assigned staff. The default school service cannot be deleted if it is the only service.
Catering Service Isolation:
- Canteen staff assigned to a Catering Service can only view and manage items, orders, and reports related to their service
- A Canteen Admin with multiple canteen service access can view and manage all services
10. User Management¶
Canteen Admins manage who has access to the Canteen Admin Portal and what they can do within it.
10.1 User Types¶
School Employee A user who is already registered in the Smartsapp School Platform.
- Search by phone number or email to locate the school record
- Assign to a Catering Service
- Assign a Role
External Person A user not in the school system (e.g., a catering company employee).
- Manually enter: Full Name, Phone Number, Email Address
- Assign to a Catering Service
- Assign a Role
10.2 User Roles¶
| Role | Permissions | Restrictions |
|---|---|---|
| Canteen Admin | Full access to all canteen modules: menus, tickets, feeding list, reports, settings, user management. | None — highest privilege role. |
| Canteen Manager | Full operational access: menus, tickets, feeding list, reports, settings, catering services. | Cannot manage users (add, edit, delete, or change roles). |
| POS Operator | Can sell items via POS terminal. Can view their own sales summary. | No access to menus, tickets, feeding list configuration, reports, or settings. |
10.3 User Management Business Rules¶
Only a Canteen Admin can add, edit, deactivate, or delete other users.
A user must be assigned to at least one Catering Service before they can be saved.
A Canteen Admin cannot downgrade their own role; another admin must make that change.
Deleting a user who has processed transactions (orders, redemptions) is not permitted; the user should be deactivated instead to preserve audit history.
POS Operators have no access to the Admin Portal beyond their sales view — they operate exclusively through the POS terminal interface.
Part III — Parent App¶
11. Menu Browsing & Ordering¶
This section describes the parent-facing experience in the Smartsapp Parent App. A parent can view menus available to their children, browse scheduled items, and place pre-orders — all from a single session that supports multiple children.
11.1 Viewing Menus for a Child¶
A parent sees only menus that are:
- Published — unpublished menus are never visible in the Parent App
- Within the target audience — the child's campus or class is included in the menu's audience (see 6.7)
- Not excluded — the child is not on the menu's exclusion list
- Within the menu duration — the current date falls within or before the menu's end date
Multiple children:
- If a parent has more than one child enrolled, they can switch between children or view menus per child
- Each child may see different menus depending on their campus, class, and exclusion status
Informational menus (INFO_ONLY):
- Displayed to the parent with a clear label indicating the menu is for viewing only
- No ordering actions are shown — the parent can browse what is being served but cannot place orders
11.2 Browsing Menu Items¶
When a parent opens a menu:
- Sections are displayed (e.g., Breakfast, Lunch, Snack Break) with their serving times
- Scheduled items appear under each section for the available dates
- Only items that are scheduled for a visible date appear — unscheduled items are never shown
Item details visible to parents:
| Field | Description |
|---|---|
| Item Name | Display name of the item |
| Image | Product image (if uploaded) |
| Description | Optional description set by admin |
| Allergens | Allergen tags (e.g., Gluten, Nuts, Dairy) |
| Price | For FIXED pricing: the default price. For VARIANT pricing: list of variant options with prices. For NO_PRICE: shown as free. |
| Stock Available | Remaining stock for that item on the selected date |
| Serving Time | Inherited from the section — the start and end time window when this meal is served |
Date navigation:
- Parents can browse upcoming dates within the menu's duration
- Dates past the ordering deadline are displayed but marked as non-orderable
- Dates in the past are not shown
- An optional date range filter (start date / end date) can narrow which dates are displayed; defaults to today through the menu's end date
11.3 Placing an Order¶
Parents can build an order across multiple dates and multiple children in a single session.
Ordering flow:
- Parent selects a child (or multiple children)
- Parent selects a menu available to that child
- Parent browses sections and selects items for one or more dates
- Each item is associated with the section it was picked from (e.g., Lunch, Snack Break)
- Selection respects the section's selection mode:
SINGLE— parent must choose exactly one item from the section per dateMULTIPLE— parent can choose multiple items from the section per date- Parent adds items to a cart (which can span multiple dates and children)
- The system creates a batch — all orders from this cart share a batch ID
- Items are grouped into orders by child + date — each child on each date gets one order containing all their items
- Orders are created with status Draft — no payment mode is required yet
- Parent reviews the batch on the checkout page and can edit or remove individual draft orders before checking out
- Parent selects a payment mode (Sika ID, Mobile Money, or Card) and checks out the entire batch
- On checkout, the backend asks the payment-switch facade to create an invoice on the legacy payment service. A platform service fee (config default with optional per-school override) is added to the batch total and the combined
chargedTotalis sent on the invoice. The returned invoice ID is stored on every order in the batch and orders move to status Pending Payment - The legacy payment service handles the actual debit (mobile money pull, card auth, or Sika ID wallet debit) and publishes an
invoice.paidevent on Kafka when the parent has paid - The backend's invoice-paid consumer flips the matching orders to Paid, stamps
paidAt, and they appear on the Feeding List. Until that event arrives, orders stay in Pending Payment and are not visible to the kitchen - Order Only menus skip the invoice flow entirely — orders move Draft → Paid synchronously since no money changes hands
Order grouping:
Items are grouped into separate orders by child and date. For example, if a parent orders for Kwame on Monday and Tuesday, and for Ama on Monday:
| Order | Child | Date | Items |
|---|---|---|---|
| 1 | Kwame | Monday | Jollof Rice, Smoothie |
| 2 | Kwame | Tuesday | Jollof Rice |
| 3 | Ama | Monday | Jollof Rice |
All three orders share the same batch ID and are confirmed/paid together.
Batch total and currency:
- The batch displays a total price (sum of all orders in the batch) and the currency (ISO 4217 code, e.g., GHS, USD), derived from the items' currency
- Each individual order also shows its own total price and currency
Multi-child ordering:
- A parent can add items for multiple children into the same cart
- Each child's order per date is a separate Feeding List entry (linked to that child)
- Payment is consolidated into a single transaction via the batch
11.4 Order Constraints¶
The following constraints are enforced when a parent attempts to place an order:
| Constraint | Behaviour |
|---|---|
| Ordering deadline | Dates past the daily cutoff time or weekly cutoff day cannot be ordered. The system hides the order action for those dates. |
| Max item quantity per order | Each item has an optional per-day limit (e.g., max 2 per child per day). The Parent App prevents exceeding this limit. |
| Stock availability | If an item's stock reaches zero, it is shown as "Sold out" and cannot be added to the cart. Stock is checked at checkout, not when added to cart. |
| Menu purpose | Only PARENTS_CAN_ORDER menus allow ordering. INFO_ONLY menus show no order actions. |
| Audience eligibility | A child not in the menu's target audience (or explicitly excluded) cannot see or order from that menu. |
11.5 Cancelling an Order¶
Parents can cancel pre-orders from the Parent App subject to the menu's cancellation deadline.
Cancellation rules:
- The Order Cancellation Deadline is configured per menu as a number of hours before the section's serving time
- Before the deadline: parent can cancel freely from the Parent App
- After the deadline: cancellation is blocked in the Parent App; only an admin can cancel via the Admin Portal
- Cancelled orders remain on the Feeding List with status Cancelled
- Refunds for cancelled orders are credited to the student's Sika ID wallet, regardless of the original payment method
11.6 Viewing Order History¶
Parents can view their orders from the Parent App.
Order listing:
- By default, orders are shown from today onward — upcoming and same-day orders appear first
- Orders are grouped by scheduled date, sorted chronologically
- A parent can view orders across all children or filtered to a single child
- An optional date range filter (start date / end date) allows viewing past orders or narrowing to a specific period
Order details visible to parents:
| Field | Description |
|---|---|
| Child | Name and profile photo of the child the order is for |
| Order Number | Unique order reference |
| Scheduled Date | The date the meal is scheduled for |
| Items | Item names, variant names, quantities, and unit prices |
| Total Price | Sum of all items in the order |
| Payment Mode | How the order was paid (Sika ID, Mobile Money, Card, etc.) |
| Status | Draft, Pending Payment, Paid, Served, Partially Served, or Cancelled |
11.7 Business Rules — Parent App¶
A parent can only see and order from menus where their child is in the target audience and not excluded.
A parent cannot place orders for dates past the ordering deadline.
Stock is validated at checkout, not when items are added to the cart. If stock runs out between cart addition and checkout, the parent is notified and the out-of-stock item is removed from the cart.
Multi-child orders produce separate Feeding List entries per child per date, grouped into a batch and paid in a single transaction.
Informational menus are always read-only in the Parent App — no ordering, no cart interaction.
Order history defaults to showing orders from today onward. Past orders are accessible via the date range filter.
A parent can edit or remove individual Draft orders from a batch before confirming. Editing replaces all items in the order and recalculates the total. Only Draft orders can be edited or removed.
Payment mode is not required at order creation — it is provided when the parent confirms the batch.
All order status transitions are recorded in a status history log (from status, to status, timestamp, who triggered the change).
Part IV — Parent Portal¶
12. Parent Portal (Web)¶
The Parent Portal is a web client that gives parents the same canteen ordering capabilities as the Parent App, accessible from any modern desktop or mobile browser. All ordering, cancellation, and order-history rules specified in section 11 apply identically to the Parent Portal — this section only describes what is unique to the web client.
12.1 Scope¶
The Parent Portal v1 covers:
- Authentication using existing parent credentials
- Child selection for parents with more than one enrolled child
- Weekly meal planning — picking items per child per day per section
- Batch checkout & payment — confirming a multi-day, multi-child cart in one transaction
- Order history — viewing upcoming and past orders with date-range filtering
- Order cancellation — cancelling pre-orders subject to the menu's cancellation deadline
Behaviours inherited unchanged from section 11: menu visibility rules (11.1), item display fields (11.2), order grouping by child + date (11.3), order constraints (11.4), cancellation deadline & refund handling (11.5), order history fields (11.6), business rules (11.7).
12.2 Authentication¶
The Parent Portal uses the same identity model as the Parent App. A parent who can sign in to the Parent App can sign in to the Parent Portal with the same credentials.
Login flow:
- Parent enters their phone number in E.164 format
- The system checks whether an account exists for that phone number
- If the account exists: parent enters their 6-digit PIN to sign in
- If the account does not exist: parent completes OTP verification (SMS) and sets a PIN to register
- On successful sign-in, the system returns a JWT access token and the parent's
parentId - The portal immediately fetches the parent's children (and any delegated children) to populate the child switcher
Backed by: the shared platform-auth SDK client. The same backend endpoints serve the mobile and web clients — no new auth endpoints are required.
Forgot PIN: parents reset their PIN through the same OTP flow used at registration.
12.3 Session & Token Storage¶
| Concern | Behaviour |
|---|---|
| Token type | JWT access token returned at login |
| Storage | The portal stores the token in browser memory and in an httpOnly, Secure, SameSite=Lax cookie. Tokens are never written to localStorage or sessionStorage. |
| Refresh | Tokens are refreshed via the existing POST /api/v1/accounts/token/refresh endpoint before expiry; the user is not prompted unless refresh fails |
| Inactivity timeout | Sessions expire after a period of inactivity; the parent is redirected to the login screen |
| Logout | Clears the cookie, in-memory token, and any cached child / order data |
12.4 Layout & Navigation¶
The Parent Portal is a single-page web application with three top-level surfaces:
| Surface | Purpose |
|---|---|
| Plan Meals | The default landing surface after sign-in. Shows a week view with each day as a column header and meal sections as collapsible rows. Each section lists the parent's enrolled children; an "+ Add" action opens an item-selection modal. |
| Order History | Lists the parent's orders grouped by scheduled date with the same fields and filters as section 11.6. Supports cancellation actions where the deadline has not passed. |
| Account | Profile, children, sign-out. |
Child switcher:
- A parent with one child sees that child by default with no switcher
- A parent with multiple children sees a switcher in the header that toggles between All children and a single child
- The Plan Meals view always shows all of a parent's enrolled children inline within each section, regardless of the switcher state, so meals can be planned across children in one pass
Week navigation:
- The Plan Meals view defaults to the current week starting today
- Previous-week navigation is disabled (past dates are not orderable)
- Next-week navigation advances by one week and is bounded by the menu's
visibilityDays(section 6.6) - A date picker allows jumping directly to a specific week within the visibility window
12.5 Meal Planning Flow¶
The planning flow on web mirrors section 11.3 with the following web-specific UX:
- The parent picks a day from the week strip
- Each menu section for that day is rendered as a collapsible card showing the section name, a "meals added" count, and the list of enrolled children
- For each child row, the parent clicks "+ Add" to open a modal listing the items scheduled for that section on that date
- The modal respects the section's
selectionMode(SINGLE/MULTIPLE) and item-level constraints from section 11.4 - Selected items appear inline under the child's row with a thumbnail, name, and a remove (×) action
- Selections accumulate in a batch spanning all days, sections, and children (same batch model as section 11.3)
- A persistent Continue action at the bottom of the screen takes the parent to the checkout view
- Checkout shows the batch grouped per child per date, the per-order totals, and the batch total with currency (section 11.3)
- The parent selects a payment mode and checks out the batch — orders transition Draft → Pending Payment, then to Paid asynchronously when the legacy
invoice.paidevent arrives (section 11.3, steps 12–14)
The batch, order grouping, and Draft → Pending Payment → Paid state machine are identical to the Parent App; the portal is a different rendering of the same underlying transactions.
12.6 Payment¶
Payment modes available in the portal are the same as the Parent App. The web client adds the following handling:
| Payment Mode | Web Handling |
|---|---|
| Sika ID (Wallet) | Routed through the payment-switch facade to the legacy service like every other parent-checkout mode; the legacy service debits the child's Sika ID wallet and publishes invoice.paid on success |
| Mobile Money | Same flow — payment-switch issues an invoice; the legacy service drives the mobile-money pull and publishes invoice.paid on success |
| Card | Same flow — payment-switch issues an invoice; the legacy service drives the card authorisation (hosted page or in-portal redirect) and publishes invoice.paid on success |
| Other modes | Where supported by the menu's payment configuration, behave as in section 11.3, steps 12–14 |
Failed payments: the legacy service does not publish invoice.paid; orders remain in Pending Payment. The parent can retry checkout, which issues a new invoice. (Pending: a "cancel pending invoice" surface — today the failed Pending Payment orders simply stay locked until a new checkout supersedes them.)
12.7 Order History & Cancellation¶
The Order History surface implements section 11.6 (listing & filtering) and section 11.5 (cancellation rules) without modification. Web-specific notes:
- The default view is "from today onward" (section 11.6)
- Each order card shows a Cancel action only when the menu's cancellation deadline has not yet passed
- Cancellations show a confirmation dialog naming the refund destination (the student's Sika ID wallet, per section 11.5)
- Past orders are accessed via the date range filter
12.8 Out of Scope for v1¶
The following are explicitly not in the Parent Portal v1 release:
- Push or in-app notifications (the Parent App remains the channel for these)
- Editing a Draft order's items in-place (parents remove and re-add)
- Account creation by an unauthenticated visitor on the web (registration is supported, but parents are still expected to onboard via the school's existing channels)
- Delegate management (viewing delegated children is supported; granting/revoking delegation is admin-only)
- Wallet top-up flows (parents top up via existing Parent App or POS channels)
12.9 Business Rules — Parent Portal¶
The Parent Portal does not introduce any new ordering, cancellation, or stock rules. All such rules are defined in section 11 and apply to the portal unchanged.
The Parent Portal uses the same authentication credentials as the Parent App. A parent who can sign in to one can sign in to the other.
JWTs in the Parent Portal are stored in
httpOnly,Securecookies and never in browser local or session storage.Past dates are never shown on the Plan Meals view; the week strip starts from today.
Payment failures leave the batch in Pending Payment state — the legacy
invoice.paidevent simply never arrives. The parent can retry checkout to issue a new invoice without rebuilding their cart.
Revision History¶
| Version | Date | Author | Changes |
|---|---|---|---|
| v1.0 | 2025-01-15 | — | Initial draft covering core canteen modules |
| v2.0 | 2025-03-20 | — | Full feature specification: added Feeding List lifecycle, Meal Ticket management, Menu scheduling, Reports, Settings, and User Management |
| v2.1 | 2026-03-20 | — | Clarified that ordering fields are conditional on menu purpose (PARENTS_CAN_ORDER only) |
| v2.2 | 2026-03-20 | — | Added serving time to menu sections, detailed repeat scheduling patterns (daily, weekday, specific days), added item visibility rule (items must be scheduled before appearing to parents) |
| v2.3 | 2026-03-20 | — | Renamed payment types: Select and Pay → Order and Pay (Item Pricing), Select Only → Order Only, Pay Using Ticket Pricing → Order and Pay (Meal Ticket Pricing). Added dedicated Payment Type Options section. |
| v2.4 | 2026-03-20 | — | Added detailed Target Audience section (6.6) — campuses, classes, student exclusions. Removed groups from audience targeting. Renumbered sections 6.6–6.12 → 6.7–6.13. |
| v2.5 | 2026-03-20 | — | Added Parent App — Menu Browsing & Ordering: viewing menus per child, browsing items, multi-child cart, placing orders, cancellation rules. |
| v2.6 | 2026-03-20 | — | Reorganised PRD into three parts: Part I (Overview), Part II (Admin Portal), Part III (Parent App). Moved Parent App to section 11. Renumbered 7–10 for Admin Portal, 11 for Parent App. |
| v2.7 | 2026-03-21 | — | Added section 11.6 (Viewing Order History): orders grouped by date, child info, date range filtering, defaults to today onward. Added date range filter note to section 11.2 (menu schedule). |
| v2.8 | 2026-03-21 | — | New order statuses: Draft → Paid → Served / Partially Served / Cancelled (replaced Pending, Redeemed, Partial Redeem). Orders start as Draft for parent review, confirmed to Paid. Items track which section they were picked from. Updated all status references across feeding list, dashboard, reports, and settings. |
| v2.9 | 2026-03-21 | — | Added batch concept: orders from one checkout share a batch ID, confirmed/paid together. Orders grouped per child per date. Payment mode deferred to confirm step. Parents can remove Draft orders from batch. Order status history tracking added. |
| v2.10 | 2026-03-21 | — | Per-item serving: each order item tracks served status, served by (staff name), and served at. Date range filter defaults start date to today; end date is optional (omit for "onward"). Updated order detail view and bulk redeem to reflect per-item tracking. |
| v2.11 | 2026-03-21 | — | Batch displays total price and currency (ISO 4217). Each order also shows its own currency. (Implementation note: currency ships on FeedingListEntryResponse today; Pending on OrderDetailResponse — still to be propagated to the order-detail payload.) |
| v2.12 | 2026-03-21 | — | Feeding list: structured student data (ID, name, class) replaces flat strings; items shown with full detail (name, variant, section, served status). Clarified that the feeding list is a query view over orders — no separate table. Date range defaults both dates to today. Renamed ONLINE payment mode to ONLINE_PAYMENT. |
| v2.13 | 2026-03-29 | — | Reports: added period comparison capability — all report endpoints accept an optional compare flag that returns the previous period of equal length with absolute and percentage deltas for KPI metrics. |
| v2.14 | 2026-04-03 | — | Added Item Library (6.5) for menu scheduling — items grouped by category with recently-used section, catering service filter tabs, and search. Item list now supports filtering by catering service, category, and name search. Menus track Last Updated By (staff name and ID). Renumbered sections 6.5–6.13 → 6.6–6.14. |
| v2.15 | 2026-04-03 | — | Menu sections: replaced single Serving Time with Serving Start Time and Serving End Time; added optional Theme Colour (hex). Dashboard: clarified Orders by Item structure — items grouped with total quantity and nested variant breakdown. Menu items: added Created By tracking (staff ID, first name, last name, set on creation). |
| v2.16 | 2026-04-11 | — | Menu Visibility Window: added required visibilityDays field (1–30, default 30) to menu fields (section 6.6). Controls how many days ahead parents can see the menu in the Parent App. Backend stores days only; the admin UI's days/weeks toggle is converted at submit time. |
| v2.17 | 2026-04-12 | — | Added Part IV — Parent Portal: section 12 specifies the new web client for parents. Authentication mirrors the Parent App (phone + PIN, OTP for new accounts, shared platform-auth endpoints). Tokens stored in httpOnly cookies. All ordering, cancellation, and order-history rules inherit from section 11 unchanged — section 12 documents only what is unique to the web client (login, session storage, layout, payment redirect handling, out-of-scope list). Updated section 1.1 (Document Structure) and 1.3 (System Boundaries) to add the new client. |
| v2.18 | 2026-04-19 | — | Sync pass against implementation: marked the Sika ID wallet refund rule (4.3 Cancel Order) and the Meal Ticket Menu Sections field (5.1) as Pending — not yet implemented. Reconciled the Item "Created By" field (6.2) to describe the resolve-at-read-time pattern (entity stores createdBy UUID only; names enriched by response mapper). Flagged v2.11 currency as Pending on OrderDetailResponse. No product scope changed. |
| v2.19 | 2026-04-26 | — | Parent checkout overhaul: renamed the batch confirm action to checkout (PUT /api/canteen/parent/orders/batch/{batchId}/checkout) and introduced a new Pending Payment order status between Draft and Paid. All parent payment modes (Sika ID, Mobile Money, Card) now route through the new paymentswitch platform module to the legacy payment service: the backend issues an invoice (with a platform service fee on top of the batch total), stamps invoiceId + snapshotted serviceFee on the orders, and waits for the legacy invoice.paid Kafka event before transitioning to Paid. PaymentMode enum updated: ONLINE_PAYMENT removed in favour of explicit MOBILE_MONEY + CARD. Pending Payment orders are intentionally excluded from the kitchen Feeding List until paid. |