Skip to content

Meal Entry

Overview

The Meal Entry feature allows staff and carers to log food intake for care recipients, capturing the food item name, portion size, carbohydrates consumed, and carb level category. The primary purpose is bolus calculation support for diabetes management. Each entry can be later edited or deleted. A history view with client-side search provides an audit trail, and Excel export is available for reporting. CareRecipients themselves cannot edit or delete entries — only create them — preserving data accuracy.


Role Access

Role Create View Edit Delete Export
SuperAdmin All
Administrator All
Carer Linked CRs
SupportWorker Linked CRs
CareRecipient ✓ (own) Own
HealthCareProvider Linked CRs

Backend

Controller: MealEntryController/api/mealentry

Method Route Auth Description
POST /api/mealentry/entries Authorized Create a meal entry
GET /api/mealentry/entries Authorized List entries (role-scoped)
GET /api/mealentry/entries/{id} Anonymous Get a single entry
PUT /api/mealentry/entries/{id} Authorized (non-CR) Update an entry
DELETE /api/mealentry/entries/{id} Authorized (non-CR) Delete an entry
GET /api/mealentry/export/weekly Anonymous Weekly entries export with optional date range

Business Logic

POST /api/mealentry/entries - CareRecipient role: CareRecipientId is automatically set to self (from JWT id claim); the request's careRecipientId field is ignored. - Other roles: CareRecipientId may be specified or null (entry attributed to the user themselves).

PUT / DELETE /api/mealentry/entries/{id} - CareRecipient role: returns 403 Forbidden. Only Carer/SupportWorker/Admin roles may modify or delete entries.

GET /api/mealentry/entries - CareRecipient: returns entries where CareRecipientId == self OR UserId == self. - Other roles: accepts optional ?userId=N query param to filter by user.

GET /api/mealentry/export/weekly - Returns entries optionally filtered by ?startDate and ?endDate query params.

Key DTOs

CreateMealEntryRequest

foodItem         string     Max 200 characters (required)
portionSize      string     Max 100 characters (required)
carbsConsumed    decimal    Min 0 (required)
carbLevel        int        Corresponds to CarbLevel enum
comments         string?    Optional free text
careRecipientId  int?       Omit for CareRecipient self-entry

UpdateMealEntryRequest

foodItem         string
portionSize      string
carbsConsumed    decimal
carbLevel        int
comments         string?

MealEntryDto (response)

id               int
foodItem         string
portionSize      string
carbsConsumed    decimal
carbLevel        string     Label from CarbLevel enum
comments         string?
timestamp        DateTime
userId           int
userName         string
careRecipientId  int?
careRecipientName string?
lastUpdatedById  int?
lastUpdatedByName string?
lastUpdatedAt    DateTime?

Model: MealEntry

Field Type Notes
Id int PK
FoodItem string (200)
PortionSize string (100)
CarbsConsumed decimal (7,2)
CarbLevel CarbLevel enum Low / Medium / High / VeryHigh
Comments string?
Timestamp DateTime Server creation time
UserId int FK → User (creator)
CareRecipientId int? FK → User
LastUpdatedById int? FK → User (last editor)
LastUpdatedAt DateTime?

MealEntryService

File: server/src/Vitara.Api/Services/MealEntryService.cs

Dependencies: ApplicationDbContext

Key methods: - GetMealEntriesForCareRecipientAsync(userId) — returns entries where CareRecipientId == userId OR UserId == userId (covers both self-entry and staff-entered records for the same person). - GetWeeklyMealEntriesAsync(startDate?, endDate?) — date-range filter with optional bounds. - All reads include User, CareRecipient, and LastUpdatedBy navigation properties.


Frontend

Routes

Path Component Notes
/meal-entry/entry MealEntryComponent Create or edit a single entry
/meal-entry/history MealEntryHistoryComponent View and manage all entries

MealEntryComponent/meal-entry/entry

File: client/src/app/features/meal-entry/components/meal-entry.component.ts

Modes: - Create mode (default): form is empty; submission calls MealEntryService.createEntry(dto). - Edit mode: activated when ?id=N query param is present. On init, loads the entry via MealEntryService.getEntry(id), pre-fills all fields, and submission calls MealEntryService.updateEntry(id, dto).

Form fields: - foodItem — required text input (max 200). - portionSize — required text input (max 100). - carbsConsumed — required decimal input (≥ 0). - carbLevel — required dropdown: Low / Medium / High / Very High. - comments — optional textarea.

Offline fallback: MealEntryService.createEntry() enqueues to OfflineQueueService (type 'meal-entry') on network failure.

Navigation: On successful create, navigates to /meal-entry/history. On successful edit, navigates back with a success snackbar.

MealEntryHistoryComponent/meal-entry/history

File: client/src/app/features/meal-entry/components/meal-entry-history.component.ts

On init: Calls MealEntryService.getEntries().

Table columns: Food Item | Portion Size | Carbs (g) | Carb Level | Comments | Last Updated | Actions

Client-side search: Filters across food item, portion size, comments, and user name fields.

Edit action: Navigates to /meal-entry/entry?id=N.

Delete action: Triggers DialogService.confirmDelete(), then calls MealEntryService.deleteEntry(id).

HealthCareProvider: Delete button is hidden; read-only view.

Excel export: MealEntryService.getExportReport()GET /export/mealentry-report → downloads Bolus_History_Report_YYYY-MM-DD.xlsx blob.

Feature Service: MealEntryService

File: client/src/app/features/meal-entry/services/meal-entry.service.ts

Method HTTP Endpoint Notes
createEntry(dto) POST /mealentry/entries Offline fallback
getEntries(userId?) GET /mealentry/entries Optional userId filter
getEntry(id) GET /mealentry/entries/{id} For edit pre-fill
updateEntry(id, dto) PUT /mealentry/entries/{id}
deleteEntry(id) DELETE /mealentry/entries/{id}
getExportReport() GET /export/mealentry-report Returns Blob

Data Validation Rules

Field Rule
foodItem Required, max 200 characters
portionSize Required, max 100 characters
carbsConsumed Required, minimum 0
carbLevel Required, must be a valid enum value
CareRecipient edit/delete 403 Forbidden at server; hidden in UI

End-to-End Data Flow

Create Entry

Carer                       Angular                        API                   DB
  |                         |                               |                     |
  | Navigate /meal-entry/entry|                              |                     |
  | Fill form: Fish, 200g,  |                               |                     |
  | 30g carbs, Medium       |                               |                     |
  |                         |                               |                     |
  | Submit                  |-- POST /mealentry/entries  -->|                     |
  |                         |                               |-- INSERT MealEntry ->|
  |                         |<-- MealEntryDto --------------|                     |
  |<-- navigate /history    |                               |                     |

Edit Entry

Carer                       Angular                        API                   DB
  |                         |                               |                     |
  | Click Edit on row       |                               |                     |
  |<-- navigate /entry?id=5 |                               |                     |
  |                         |-- GET /mealentry/entries/5 -->|                     |
  |                         |<-- MealEntryDto --------------|                     |
  |<-- form pre-filled      |                               |                     |
  | Change portion to 250g  |                               |                     |
  | Submit                  |-- PUT /mealentry/entries/5 -->|                     |
  |                         |<-- Updated MealEntryDto ------|                     |
  |<-- snackbar + navigate  |                               |                     |