16 KiB
PerAuset Platform Review -- Daily Operations Gaps
Reviewer: Alex (Product Manager) Date: 2026-03-19 Scope: Full platform review from the perspective of a daily coordinator, kitchen lead, boat coordinator, and facilitator Method: Reviewed all 66 RPC functions, 15+ frontend pages, 13 database migrations, and the role/permission system
Critical (Blocks Daily Operations)
1. [Dashboard] All stats are hardcoded "--" except notifications
The dashboard shows "Active Stays: --", "Upcoming Boats: --", "Open Tasks: --". There is no backend function to fetch dashboard summary stats. A coordinator opening the app every morning gets zero situational awareness.
What to build: A getDashboardStats RPC that queries active stays count, upcoming boat trips count, and open task count. Update the dashboard page to call it.
2. [Kitchen] Cannot create a meal service from the UI
The "Create Meal" button on the kitchen page is explicitly disabled. The backend createMealService RPC exists, but the frontend form to call it is missing. A kitchen lead cannot plan any meals.
What to build: A meal creation drawer/page that calls createMealService with service_type, service_date, planned_headcount, and menu_notes.
3. [Kitchen] No way to see who is eating (meal headcount from stays/retreats)
The meal_attendance table exists and links to stays and retreats, but there is no RPC to list meal attendance, no RPC to auto-populate attendance from active stays, and the frontend shows zero attendance data. A kitchen lead cannot know how many mouths to feed or what dietary needs exist for a given meal.
What to build: (a) listMealAttendance RPC filtered by meal_service_id. (b) generateMealAttendance RPC that auto-creates attendance records from active stays and retreat participants for a date range. (c) Frontend attendance list on each meal card showing headcount and dietary summary.
4. [Kitchen] No dietary summary per meal
Dietary profiles exist per user, but there is no function that aggregates dietary requirements for a specific meal (e.g., "3 vegan, 2 gluten-free, 1 nut allergy"). Without this, the kitchen lead has to manually cross-reference every guest's profile.
What to build: getMealDietarySummary RPC that joins meal_attendance with dietary_profile and returns counts. Show this on each meal card.
5. [Retreats] People tab is always empty -- not wired to backend
The retreat detail page hardcodes const people: any[] = [] and const schedule: any[] = []. Despite addRetreatPerson and addRetreatScheduleItem RPCs existing, there is no listRetreatPersons or listRetreatScheduleItems RPC, and the "Add Person" button is disabled. A facilitator cannot manage retreat participants or view the schedule.
What to build: (a) listRetreatPersons and listRetreatScheduleItems RPCs. (b) Wire the retreat detail page to call them. (c) Enable the "Add Person" and "Add Schedule Item" forms calling the existing RPCs.
6. [Retreats] No getRetreat RPC -- detail page re-fetches all retreats
The retreat detail page calls listRetreats and filters client-side by ID. This means no additional detail (persons, schedule) is loaded. There is no single-retreat fetch endpoint.
What to build: getRetreat RPC that returns the retreat with its persons and schedule items in one call.
7. [Stays] No "who is here right now" view
There is no way to see currently checked-in guests. The stays list shows all stays but does not filter by "checked_in" status or date overlap with today. A coordinator doing a morning roll call has no tool for this.
What to build: Add a "Currently Checked In" filter/tab to the stays page that queries stays with status='checked_in' or where today falls within start_at/end_at. Ideally also surface this count on the dashboard.
8. [Rooms] No room availability / availability calendar
You can see rooms and their allocations, but there is no way to check "which rooms are available from date X to date Y?" before making an allocation. This means room assignment is guesswork.
What to build: checkRoomAvailability RPC that accepts a date range and returns rooms with their open capacity. Frontend calendar or date-picker view on the rooms page.
Important (Significantly Impacts Efficiency)
9. [Kitchen] No weekly menu planning
Meals are individual records with no concept of a menu or weekly plan. A kitchen lead has to create each meal one at a time with no template or copy-week functionality.
What to build: generateWeeklyMeals RPC that bulk-creates meal_service records for breakfast/lunch/dinner across a date range. Frontend weekly calendar view for kitchen.
10. [Kitchen] No shopping list generation from menu
There is no meal_ingredient or recipe table. The menu_notes field is free text. There is no connection between meals and inventory items. A kitchen lead cannot generate a shopping list from the planned menu.
What to build: New meal_ingredient table linking meal_service to inventory_item with quantity. generateShoppingList RPC that diffs meal ingredients against inventory.
11. [Boats] No passenger manifest view
The trip detail page shows seat requests, but there is no consolidated manifest showing confirmed passengers with their names, cargo notes, and special requirements. The boat coordinator needs a printable list.
What to build: getBoatManifest RPC that returns confirmed seat requests joined with user profiles. Frontend manifest card on the trip detail page.
12. [Boats] No weather cancellation / rebooking workflow
Cancelling a trip (cancelBoatTrip) does not notify affected passengers or offer rebooking. Seat requests just sit in their current state.
What to build: When a trip is cancelled, auto-create notifications for all confirmed seat request holders. Add a rebookSeatRequest RPC that moves a request to another trip.
13. [Tasks] No recurring task generation from templates
Task templates have a recurrence_cron field, but there is no scheduler or function that creates task instances from templates based on the cron expression. Recurring tasks (daily cleaning, weekly maintenance) must be created manually every time.
What to build: A scheduled function (cron job) generateRecurringTasks that reads active templates with recurrence_cron and creates task instances for upcoming periods.
14. [Tasks] No task history / completion stats
There is no way to see completed tasks over time, completion rates, or who completed the most tasks. No analytics view exists.
What to build: getTaskStats RPC returning completion counts by category, by user, and by time period. Frontend stats view on the tasks page.
15. [Inventory] No stocktake functionality
You can edit item quantities one at a time, but there is no bulk stocktake flow where someone walks through the storage room updating all quantities at once.
What to build: submitStocktake RPC that accepts an array of {itemId, actualQuantity} and updates all in one transaction with audit trail. Frontend stocktake page with a checklist.
16. [Inventory] No consumption history
When quantities are manually edited, the old value is lost (only the audit log captures it). There is no inventory_transaction table tracking additions/removals with reasons.
What to build: New inventory_transaction table (item_id, quantity_change, reason, user_id, created_at). adjustInventory RPC that creates a transaction record. Frontend history tab per item.
17. [Inventory] No automatic reorder alerts
Items have minimum_quantity, and the UI shows a yellow warning icon, but there is no notification sent when stock drops below minimum. The kitchen lead has to manually check the inventory page.
What to build: Trigger (database or application-level) that creates a notification when current_quantity drops below minimum_quantity.
18. [Finance] No totals, summaries, or reports
The finance page lists individual records but shows no totals by category, no monthly summaries, no income-vs-expense breakdown. You cannot generate a monthly report.
What to build: getFinanceSummary RPC returning totals by category, by record_type, and by month. Frontend summary cards at the top of the finance page.
19. [Finance] No link to retreat or project for cost tracking
The finance_link table exists and the linkFinanceRecord RPC exists, but the frontend has no UI to link a finance record to a retreat, boat trip, stay, or inventory request. You cannot track per-retreat costs.
What to build: Add a "Link to Entity" button on finance records that opens a selector for retreat/trip/stay/item. Show linked entity badges on the finance table.
20. [Finance] No approval workflow
finance_record has no approved_by or approval_status field. Anyone with finance.manage permission (which is missing from the roles entirely -- only admin has it via wildcard) can create records. There is no review step.
What to build: Add approval_status and approved_by_user_id to finance_record. Add finance.manage and finance.view permissions to relevant roles. Add approval workflow RPCs.
21. [Notifications] No way to send bulk or event-triggered notifications
The notification table is write-only from the application side. There is no createNotification or sendBulkNotification RPC. Notifications are only created as side effects (if even implemented). A coordinator cannot send a message like "boat departing in 2 hours" to all passengers.
What to build: createNotification RPC (admin/coordinator only) that creates notifications for one or more users. sendBulkNotification for a group (retreat participants, today's boat passengers, all active stays).
22. [Users] No way to invite new users
The users page shows existing users and lets admins edit roles, but there is no invite flow. New users can only join by signing in through auth.js. There is no way to pre-register someone with a role.
What to build: inviteUser RPC that creates a user record with email and role in 'invited' status. Send an email (or at minimum create the record so they can sign in).
Nice to Have (Would Improve the Experience)
23. [Dashboard] No today's arrivals/departures widget
The dashboard does not show who is arriving or departing today, which is critical for room turnover planning.
24. [Dashboard] No upcoming tasks widget
The dashboard does not show the user's assigned or claimable tasks for today.
25. [Stays] No direct link from stay to room allocation
A stay exists independently of room allocation. To see which room a guest is in, you have to go to room allocations and search by stay ID. No inline room info on the stays page.
26. [Rooms] No cleaning/turnover tracking
There is no concept of room status (clean, dirty, in-progress) or housekeeping tasks auto-generated on checkout.
27. [Boats] Route names not human-readable
Boat trips display "Route abc123..." (UUID truncation). Routes need a human-readable name (e.g., "Aswan to Village"). No listBoatRoutes function exists for the frontend.
28. [Boats] Boat names not shown
Similar to routes -- boats are shown as UUIDs. No listBoats function for the frontend. Should show boat name/capacity.
29. [Retreats] No retreat-specific meal planning
Meals can be linked to a retreat via retreat_id on meal_service, but there is no UI to plan meals for a specific retreat or view retreat meals in the retreat detail page.
30. [Retreats] No notifications to retreat participants
Publishing a retreat does not notify registered participants. There is no mechanism to send updates to a retreat group.
31. [Tasks] Cannot assign tasks to specific roles (only users)
task_assignment links to a specific user. There is no way to say "this task is for any kitchen_lead" -- you must know the person.
32. [Profile] No user preferences beyond dietary
No notification preferences, no timezone setting, no language preference. The dietary profile is the only user preference.
33. [Kitchen] No meal feedback mechanism
There is no way for guests to rate or comment on meals.
34. [Stays] No stay extension or modification workflow
Once a stay is created, there is no way to extend dates or modify the stay type without cancelling and recreating.
35. [Audit Log] No filtering
The audit log shows all entries with no ability to filter by table, user, action, or date range.
Data Model Issues
finance_record
- Missing
approved_by_user_idandapproval_statusfields - No
finance.manageorfinance.viewpermissions in the roles system (only admin via wildcard can access)
inventory_item
- No transaction/history table to track quantity changes over time
- No
last_restocked_atorsupplierfield
meal_service
- No
meal_ingredienttable linking meals to inventory items with quantities menu_notesis free text with no structured recipe/ingredient support
task_template
recurrence_cronexists but nothing reads it -- no scheduler generates instances
room
- No
cleaning_statusorlast_cleaned_atfield - No
floororbuildingfield for larger villages
stay
- No
room_preferencefield (onlyrooms.request_preferencepermission exists but no schema support)
boat_trip
- No
weather_statusorcancellation_reasonfield - No
max_passengersormax_cargo_weightfield on the trip (only on boat, which is a UUID reference)
notification
- No
channelfield (in-app vs email vs SMS) - No
scheduled_atfield for future notifications
retreat
- No
budgetorpricingfields - No
retreat_tagorcategoryfor filtering retreat types
user
- No
invited_by_user_idorinvited_atfor tracking invitations - No
last_active_atfor activity monitoring - No
preferencesJSONB field for user settings
Specific Recommendations (Priority Order)
Tier 1 -- Do This Week (unblocks daily operations)
-
Wire the dashboard stats: Create
getDashboardStatsfunction, update dashboard page. Half-day effort. -
Enable meal creation: Remove
disabledfrom the Create Meal button, add a creation form callingcreateMealService. Half-day effort. -
Wire retreat people and schedule: Add
listRetreatPersonsandlistRetreatScheduleItemsRPCs. Wire the retreat detail page to call them. Enable the Add Person and Add Schedule Item buttons. 1-day effort. -
Add "Currently Checked In" view: Add a filtered tab to stays page. 2-hour effort.
Tier 2 -- Do This Sprint (high-impact workflows)
-
Meal attendance auto-generation: Build the function that creates attendance records from active stays/retreats for a date. Show headcount and dietary summary per meal. 2-day effort.
-
Boat manifest view: Add a confirmed-passenger manifest to trip detail. 1-day effort.
-
Room availability check: Build the availability query and date-range picker. 1-day effort.
-
Finance summary/totals: Add summary cards to the finance page. 1-day effort.
-
Recurring task generation: Implement the cron-based task generator from templates. 1-day effort.
Tier 3 -- Do Next Sprint (important but not blocking)
- Inventory transaction history and stocktake. 2-day effort.
- Low-stock notifications. Half-day effort.
- Bulk notification sending. 1-day effort.
- Finance entity linking UI. 1-day effort.
- Shopping list from menu (requires meal_ingredient table). 3-day effort.
- User invitation flow. 1-day effort.
- Boat route/boat name display (add list functions + display). Half-day effort.
Summary
The platform has a solid data model and a comprehensive set of CRUD operations. The core tables, enum types, and permission system are well-designed. However, the gap between "data exists" and "a human can use this daily" is significant in several areas:
- Kitchen module is essentially non-functional from the UI (cannot create meals, no attendance, no dietary aggregation)
- Retreat detail page is a shell (people and schedule are hardcoded empty arrays)
- Dashboard provides no operational value (all stats are "--")
- Cross-entity workflows are missing (menu to shopping list, stay to meal attendance, cancellation to rebooking, checkout to room cleaning)
- Finance has no summaries, no approval flow, and no entity linking UI
The backend functions are about 70% complete. The frontend is about 50% complete relative to what the backend supports. The biggest wins come from wiring existing backend capabilities to the frontend (retreat persons, meal creation) and adding the handful of missing aggregation/summary functions that make the data actionable.