Commit Graph
56 Commits
Author SHA1 Message Date
isaaccladandCursor afca49039b Fix missing AiController import in web routes.
Deploy Ladill POS / deploy (push) Successful in 1m36s
Restores route resolution after multi-branch route additions.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 06:35:13 +00:00
isaaccladandCursor 9d7dac6c24 Add multi-branch POS with team roles and branch-scoped cashiers.
Deploy Ladill POS / deploy (push) Successful in 1m58s
Pro and Business users can manage branches, invite cashiers with branch assignment, and switch registers; sales and register flows respect acting location.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 06:05:30 +00:00
isaaccladandCursor cac7c60415 Add receipt logo upload and redesign thermal receipt header.
Deploy Ladill POS / deploy (push) Successful in 1m32s
Per-location logo in settings with remove/replace support; receipt template reserves space at the top when a logo is set.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 05:48:40 +00:00
isaaccladandCursor 9a2d196d84 Add barcode scanner, thermal receipt printing, and printer settings.
Deploy Ladill POS / deploy (push) Successful in 1m42s
Register supports USB keyboard-wedge scanners with SKU lookup (local catalog
and CRM in retail mode). Sales get a thermal receipt print template (58/80mm)
with configurable header/footer, plus optional auto-print after cash sales.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 05:40:14 +00:00
isaaccladandCursor 74bc89a68a Update POS favicon.
Deploy Ladill POS / deploy (push) Successful in 55s
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 00:00:42 +00:00
isaaccladandCursor 9c67150c77 Update POS logo and Give/POS launcher icons from monolith.
Deploy Ladill POS / deploy (push) Successful in 35s
Redeploy refreshed branding assets for the POS app.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 22:48:06 +00:00
isaacclad 86ffa2629b Show boot splash on app open/reload for logged-in users.
Deploy Ladill POS / deploy (push) Successful in 54s
Replace the once-per-session sessionStorage guard (which suppressed the loading
screen after its first appearance) with entry-aware logic: show on app entry
and reloads, suppress on internal link navigations and back/forward.
2026-07-07 20:35:18 +00:00
isaacclad c9186300e0 Sync app launcher from registry
Deploy Ladill POS / deploy (push) Successful in 39s
2026-07-07 14:42:53 +00:00
isaacclad bedd546fd4 Prefer system npm in deploy CI when portable node-gyp is broken.
Deploy Ladill POS / deploy (push) Successful in 29s
Falls back to downloading Node only when host npm is unavailable, fixing npm ci failures on ladill-deploy-runner.
2026-07-07 00:46:54 +00:00
isaacclad 622847c3a8 Sync app launcher from registry
Deploy Ladill POS / deploy (push) Failing after 4s
2026-07-07 00:21:55 +00:00
isaaccladandCursor ac5e513dd2 Standardize settings pages on shared centered card layout.
Deploy Ladill POS / deploy (push) Successful in 41s
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-05 21:11:48 +00:00
isaaccladandCursor 3d34543d44 Fix products routes missing ProductController import.
Deploy Ladill POS / deploy (push) Successful in 42s
Resolve 500 on /products caused by unresolved controller class in web routes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-04 20:18:53 +00:00
isaaccladandCursor 7ce95d05ab Propagate shared copy-button component and clipboard helper.
Deploy Ladill POS / deploy (push) Successful in 56s
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-03 23:04:20 +00:00
isaacclad 1359b49c97 Sync mobile notification badge and dashboard icon-link partials.
Deploy Ladill POS / deploy (push) Successful in 1m2s
Align mobile unread badge with desktop and add plus icon support for panel actions.
2026-07-03 22:41:01 +00:00
isaacclad 8e0cad7fc7 Sync app launcher from registry
Deploy Ladill POS / deploy (push) Successful in 1m26s
2026-07-01 17:05:01 +00:00
isaaccladandCursor 88e1c28aac Add dashboard upgrade banner for free POS plans.
Deploy Ladill POS / deploy (push) Successful in 1m0s
Highlight Pro and Business plans on the register overview for merchants on the free tier.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-30 18:13:22 +00:00
isaaccladandCursor e1053746ac Throttle platform SSO session checks to cut per-request auth latency.
Deploy Ladill POS / deploy (push) Successful in 33s
Verify auth.ladill.com at most once every 90s; recommend Redis for session/cache in .env.example.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-30 16:49:38 +00:00
isaaccladandCursor 2d8714de7f Show consolidated prepaid totals on plan pricing cards.
Deploy Ladill POS / deploy (push) Successful in 39s
When 6/12/24 month Paystack is selected, Pro and Business prices display the full term amount instead of /mo.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-30 11:39:26 +00:00
isaaccladandCursor d66e656b9c Add Business tier and Paystack prepaid billing for POS.
Deploy Ladill POS / deploy (push) Successful in 35s
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-30 01:55:38 +00:00
isaaccladandCursor f800f0c1ca Add POS Pro subscription billing and free-tier limits.
Deploy Ladill POS / deploy (push) Successful in 43s
Wallet-backed Pro unlocks unlimited products, restaurant mode, catalog imports, and ecosystem sync features.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-30 00:51:35 +00:00
isaacclad 68255786e1 Add Queue to app launcher config and icon.
Deploy Ladill POS / deploy (push) Successful in 1m6s
Propagated from ladill monorepo launcher sync.
2026-06-29 22:12:15 +00:00
isaacclad b7216d191c Sync app launcher from registry
Deploy Ladill POS / deploy (push) Successful in 54s
2026-06-29 17:53:13 +00:00
isaaccladandCursor fbff76a92d Cap launcher dropdown at 15 visible apps (5 rows).
Deploy Ladill POS / deploy (push) Has been cancelled
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 17:45:58 +00:00
isaaccladandCursor f7ccbda7ad Hide launcher down arrow when scrolled to the end.
Deploy Ladill POS / deploy (push) Successful in 31s
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 14:49:25 +00:00
isaaccladandCursor b9b0598e87 Revert launcher scroll rail and fade; keep down arrow hint.
Deploy Ladill POS / deploy (push) Successful in 44s
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 14:02:54 +00:00
isaaccladandCursor 0f4a5623ee Make launcher scroll affordance visible on open.
Deploy Ladill POS / deploy (push) Has been cancelled
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-29 13:53:33 +00:00
isaacclad 13dc3ce10a Sync app launcher from registry
Deploy Ladill POS / deploy (push) Successful in 44s
2026-06-29 13:29:41 +00:00
isaacclad ccb97bf0d0 Always show launcher scroll indicator and cap at 18 apps.
Deploy Ladill POS / deploy (push) Successful in 56s
Apply ladill-launcher-apps scroll styles unconditionally with a persistent
scrollbar track; propagate launcher blade and CSS across all Ladill apps.
2026-06-29 13:06:00 +00:00
isaaccladandCursor 154a418149 Use + icon buttons on mobile dashboards.
Deploy Ladill POS / deploy (push) Successful in 36s
Sync mobile-header-btn partials, mobile x-btn.create, and update dashboard header actions for consistent mobile FABs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-28 16:21:40 +00:00
isaaccladandCursor e716f1a43a Place wallet widget after Billing link in mobile profile sheet.
Deploy Ladill POS / deploy (push) Successful in 49s
Remove duplicate Billing header above Home; wallet card follows Billing
in menu order to match the desktop avatar dropdown.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-28 14:08:52 +00:00
isaaccladandCursor 11a7502381 Sync mobile profile wallet card and 24h session idle timeout.
Deploy Ladill POS / deploy (push) Successful in 1m35s
Show wallet balance prominently in the mobile profile bottom sheet with refresh
on open; align session lifetime with the platform default.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-28 12:46:20 +00:00
isaaccladandCursor 4f0a35485d Add mobile bottom nav and hide header avatar on small screens.
Deploy Ladill POS / deploy (push) Successful in 1m1s
POS now uses the shared Ladill mobile header and bottom navigation pattern.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-28 12:03:57 +00:00
isaacclad ca632e0d7b Sync app launcher from registry — add Frontdesk.
Deploy Ladill POS / deploy (push) Successful in 28s
2026-06-28 01:46:27 +00:00
isaaccladandCursor ff51c1e897 Sync app launcher from registry
Deploy Ladill POS / deploy (push) Successful in 1m7s
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-27 19:03:58 +00:00
isaaccladandCursor 501ebd8449 Sync app launcher from registry
Deploy Ladill POS / deploy (push) Successful in 53s
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-27 18:28:04 +00:00
isaacclad 848c9a2be1 Sync app launcher from registry
Deploy Ladill POS / deploy (push) Successful in 29s
2026-06-27 15:15:58 +00:00
isaaccladandClaude Opus 4.8 2335bea0c4 Add Accounting to the app launcher
Deploy Ladill POS / deploy (push) Successful in 36s
Ladill Accounting is now live at accounting.ladill.com; add its row + icon to
the shared app launcher (byte-identical across all Ladill apps).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 13:46:14 +00:00
isaaccladandClaude Opus 4.8 9fcea24680 Add bulk CSV product import for POS (retail + restaurant)
Deploy Ladill POS / deploy (push) Successful in 1m39s
Customers with large catalogs can upload a CSV instead of adding products one by
one. Mode-aware: restaurant imports into the local catalog (chunked INSERT,
categories resolved/created by name); retail batches to the CRM products/bulk
endpoint. Streamed parsing + batched writes handle thousands of rows in one
request. Includes a downloadable template, an Import button on both product
pages, and a skipped-rows report.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 09:20:40 +00:00
isaaccladandClaude Opus 4.8 62e396195b Fix confirm-dialog flashes: cloak panel + align transition timing
Deploy Ladill POS / deploy (push) Successful in 30s
The inner panel lacked x-cloak (brief FOUC on load/navigation) and its
leave/enter durations (300/200ms) outlasted the backdrop's (200/150ms), so the
card animated without its backdrop on open/close. Cloak the panel and align all
durations to 200ms so backdrop and card move together.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 08:11:01 +00:00
isaaccladandClaude Opus 4.8 09df8e181a Replace native confirm() with in-app dialog for cancel/delete sale
Deploy Ladill POS / deploy (push) Successful in 42s
The Cancel sale / Delete sale actions used the browser's native confirm()
('pos.ladill.com says…'). Render the store-driven ladillConfirm prompt (already
registered in app.js but never displayed) via a new partials/confirm-prompt and
have the two forms open it instead — branded, with sale-specific copy.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 08:05:02 +00:00
isaaccladandClaude Opus 4.8 2103708ab6 Add a branded boot splash (Ladill Mail style) to app pages
Deploy Ladill POS / deploy (push) Successful in 31s
InjectBootSplash middleware injects a full-screen loading splash — the app's
launcher icon (pulsing), an animated progress bar, and "Loading <app>…" — into
authenticated HTML pages, then fades it out on load. Shows once per browser
session (sessionStorage), so it masks the app's client-side boot without
flashing on every navigation. Self-branding from the app's own subdomain icon,
so the same partial/middleware drops into every Ladill app.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 22:08:36 +00:00
isaaccladandClaude Opus 4.8 f64a28cb21 Allow cancelling and deleting pending POS sales
Deploy Ladill POS / deploy (push) Successful in 37s
On a sale's detail page, unpaid sales (retail or restaurant) can now be
cancelled or deleted:
- Cancel (pending only) marks it cancelled and frees its table / clears it from
  the kitchen (PosSaleService::cancelSale).
- Delete removes the sale and cascades its lines, modifiers and payments, freeing
  the table first (deleteSale). Paid sales are protected — they can't be deleted.
Status badge now distinguishes cancelled/failed. Covered by PosRestaurantTest.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 21:52:51 +00:00
isaaccladandClaude Opus 4.8 5d8e185223 Link retail POS products to the CRM products API (restaurant stays local)
Deploy Ladill POS / deploy (push) Successful in 28s
Products are now mode-aware:
- Retail: the catalog lives in Ladill CRM. The Products page proxies CRUD to the
  CRM products API (CrmClient gains product/create/update/delete), and the
  register reads CRM products live; a sold line is stored as a name/price
  snapshot (product_id null, since CRM products aren't local rows). Resilient —
  the register shows an empty catalog if CRM is unreachable. CRM import is hidden
  in Settings (not needed when reading live).
- Restaurant: unchanged — the local pos_products catalog keeps its POS-only depth
  (category, kitchen station, course, modifier groups).

ProductController routes take a raw {product} id (CRM id in retail, local id in
restaurant). Suite green (17), covering both modes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 12:27:19 +00:00
isaaccladandClaude Opus 4.8 0d816daed3 Add retail/restaurant mode toggle to the register
Deploy Ladill POS / deploy (push) Successful in 45s
A segmented Retail | Restaurant control in the register header flips the
location's service_style in place (RegisterController@setMode → pos.mode.set).
Switching to restaurant lands on the Floor and reveals Floor/Kitchen/Menu in the
sidebar; switching to retail stays on the register. Covered by PosRestaurantTest.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 12:03:46 +00:00
isaaccladandClaude Opus 4.8 1bbc9490f1 Fix Mini fork leftovers in POS config
Deploy Ladill POS / deploy (push) Successful in 59s
After an auto-logout, silent re-auth fails with login_required and
SsoLoginController@callback redirects to config('ladill.marketing_url') — which
still defaulted to https://ladill.com/products/mini, dumping POS users on Mini's
product page. Point ladill.product_slug/marketing_url at POS.

Also fix the identity service key (config/identity.php + services.ladill_identity
read IDENTITY_API_KEY_MINI; POS provisions IDENTITY_API_KEY_POS) and tidy the
remaining Mini defaults (app.name, ladill_sso redirect, mobile-topbar app_name).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 06:00:32 +00:00
isaaccladandClaude Opus 4.8 e9d483394c Only ingest online orders for accounts running a POS kitchen
Deploy Ladill POS / deploy (push) Successful in 38s
Guard ingestExternalOrder: skip (200, no ticket created) when the owner has no
restaurant-mode POS location, so pushing from Merchant is harmless for accounts
that don't use the POS kitchen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 23:50:52 +00:00
isaaccladandClaude Opus 4.8 9780591e74 Split bills + kitchen ingest for online orders
Deploy Ladill POS / deploy (push) Successful in 36s
Split bills (restaurant tickets):
- New pos_payments ledger; a tab is settled across one or more cash/Ladill Pay
  payments. The ticket shows total / paid / balance, an amount field with Full /
  ½ / ⅓ / ¼ helpers, and the payments taken. Partial payments keep the tab open;
  the sale finalises (and frees the table) only when the balance hits zero.
  Pay splits get their own checkout + callback (pos.payments.callback).

Pipe online orders to the KDS:
- POST /api/kitchen/orders — a first-party, service-keyed ingest
  (config pos.kitchen_api_keys, scoped by owner, idempotent by external_ref) that
  creates a paid, already-fired ticket (order_type=online, lines source=online).
- The KDS feed is now payment-agnostic (any kitchen-active sale), so paid online
  orders sit on the board next to dine-in tabs and bump the same way; they're
  badged "online".

Schema additive: pos_payments, pos_sales.external_ref. Suite green (14).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 23:49:01 +00:00
isaaccladandClaude Opus 4.8 6c42f18186 Realtime KDS via Server-Sent Events
Deploy Ladill POS / deploy (push) Successful in 1m22s
Replace the kitchen display's 4s polling with a pushed feed. GET /kitchen/stream
holds an SSE connection and emits the board the moment it changes (~1s tick,
heartbeat between changes), so fired/bumped/guest orders land on screen near
instantly. Bounded to ~25s per connection so PHP-FPM workers recycle — the
browser's EventSource reconnects automatically; if EventSource is unavailable it
falls back to polling /kitchen/feed. Sends X-Accel-Buffering: no so nginx streams
it, and releases the session early (DB sessions don't lock, but be safe).

feed()/stream() now share buildTickets(); behaviour of the JSON feed (initial
load + fallback) is unchanged. Suite green (12).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 20:59:36 +00:00
isaaccladandClaude Opus 4.8 d4f4821d96 Restaurant mode Phase 3: table-QR self-ordering into the kitchen
Deploy Ladill POS / deploy (push) Successful in 23s
The "links" slice — a guest scans a table's QR, browses the menu (with
modifiers), and submits an order that lands on that table's open tab and fires
straight to the Kitchen Display.

- Public, auth-free flow scoped by an unguessable table short_code:
  GET /t/{code} (menu + client cart), POST /t/{code}/order (throttled),
  GET /t/{code}/done. Orders open/append the table's dine-in tab, add lines as
  source=guest, and send to the kitchen.
- Staff print a per-table QR (Settings → table → QR; renders client-side to the
  public menu URL). short_code is generated lazily.
- Guest lines are badged on the ticket and the KDS so staff can tell them apart;
  staff still settle the tab as usual (cash / Ladill Pay).
- Extracted PosSaleService::buildProductLine as the single product+modifier
  price resolver, now shared by staff and guest ordering (client prices never
  trusted).

Schema additive: pos_tables.short_code, pos_sale_lines.source. New
PosRestaurantTest covers the guest order firing to the kitchen; suite green (12).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 20:13:28 +00:00
isaaccladandClaude Opus 4.8 50b170b0af Restaurant mode Phase 2: menu depth — categories, stations, modifiers, courses
Deploy Ladill POS / deploy (push) Successful in 35s
Builds on Phase 1 with the menu structure restaurants need:
- Menu setup page (restaurant mode): categories, kitchen stations, and modifier
  groups with options (price deltas).
- Products gain category, kitchen station, default course, and attached modifier
  groups (managed on the product form).
- Ordering: the ticket groups the catalog by category and, when a product has
  modifier groups, opens a picker (respects min/max select) for options + notes +
  course before adding. Effective price = base + modifier deltas (resolved
  server-side; client prices are never trusted).
- Fire-by-course: send the whole tab or just one course to the kitchen.
- KDS: filter by station; each item shows its station, course, modifiers and notes.

Schema additive (pos_categories, pos_stations, pos_modifier_groups, pos_modifiers,
product↔group pivot, pos_sale_line_modifiers; category/station/course columns on
products and lines). PosRestaurantTest covers modifiers, course and station routing;
suite green (11 passed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 19:58:57 +00:00