1. Production Bug Fix — Unauthorized Access
Fixed a bug where existing tenants on older subscription plans were being blocked with "You don't have permission to view this page" errors in production. The root cause: a legacy-plan flag required a one-off manual database migration script that had been run on staging but never on production. Rather than relying on that fragile manual step, I changed the access-check logic so any plan with no explicit feature list automatically gets full access — this self-heals for every environment going forward, with no migration script needed ever again.
2. Dispute Handling Overhaul
Several gaps were found and closed around how disputed orders are handled:
Frozen orders: Once a dispute is raised, staff can no longer advance the order's status, cancel items, remove items, or issue refunds on it — both in the UI and enforced on the backend, so it can't be bypassed by calling the API directly.
Kitchen displays cleaned up: Disputed orders no longer show on the Kitchen Display or Kitchen Orders screens, since they shouldn't be actively prepared while under dispute.
Partial vs. full disputes distinguished: Previously, disputing even one item out of several made the whole order look "DISPUTED." Now it correctly shows "PARTIALLY DISPUTED" with a per-item indicator (e.g. "Disputed: 1/2") so staff can see exactly what's affected.
Full dispute history visible: The order details screen now shows the dispute's reason, status, and resolution directly in the order's timeline, instead of the dispute being invisible after it's raised.
3. Pre-Order Safeguards
Pre-orders (scheduled ahead of time) could previously be modified by staff before they were actually due — a status update, for example, could jump the gun before the kitchen should even see it. Now, a pre-order is locked from status changes until our scheduler automatically promotes it into an active order (currently set to happen automatically an hour before the scheduled time). We also added a visual marker so that once a pre-order becomes active, staff can still tell at a glance that it started life as a scheduled order and see its original scheduled time.
4. Simplified Checkout Fee Display (Customer App)
Customers were seeing four separate line items (Delivery Fee, Tax, Processing Fee, Tip) cluttering the checkout summary. These are now combined into one clean "Fees & Tax" line, with an info icon customers can tap to see the full breakdown if they want it — cleaner checkout, same transparency.
5. Loading Skeletons Across the App
Replaced plain spinning-loader indicators with modern "skeleton" placeholders (greyed-out content shapes) that match what's about to load — used by most major apps (LinkedIn, Facebook, YouTube, etc.) because it feels faster and more polished than a blank spinner. Rolled this out across roughly 85 pages in the staff-facing POS system and 12 pages in the customer-facing site — dashboards, order lists, menu grids, kitchen screens, and more.
6. New "Small Order Fee"
Added a new configurable fee that restaurant admins/managers can turn on in Settings — a flat charge (capped at $5) automatically applied to Takeaway and Delivery orders only, since dine-in customers already have utensils at the table. Customers see it labeled "Small Order Fee" on their cart, checkout, receipt, and order history; staff see it as "Utensils Fee" in the POS system and on printed bills.
7. Codebase Cleanup
Removed 23 leftover one-off debug and test scripts that had accumulated in the backend project over time (things like ad-hoc database checks and one-time fix scripts that were no longer needed), keeping the codebase tidier for anyone working in it going forward.