Declares ARG NEXT_PUBLIC_APP_COMMIT, supplied by Ship, and renders it as a
nearly transparent, click-through stamp. Renders nothing when unset.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
next/font/google downloads every font from fonts.googleapis.com during
`next build`, and the Coolify build kept failing on it (Nunito/Outfit on
2026-10-17, Lato and JetBrains Mono on 2026-10-20).
The ten families (Geist, Geist Mono, Inter, Space Grotesk, DM Sans,
Playfair Display, Lato, Nunito, Outfit, JetBrains Mono) are now Latin
.woff2 files in src/app/fonts (344 KB, downloaded from Google Fonts),
loaded with next/font/local under the same CSS variable names and
weights. Verified: `npm run build` succeeds with no network access, and
the login page renders in the local Inter with no font errors.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adding /rep to an iPad home screen and tapping it opened the main app,
not the rep app — while the shortcut URL was still /rep.
Cause: Next 16 renders `appleWebApp.capable: true` as the standardised
<meta name="mobile-web-app-capable"> and no longer emits the
apple-prefixed name. iOS only reads the apple-prefixed one. Without it
the icon is a plain Safari bookmark rather than a standalone app, so
tapping it foregrounds Safari on whatever tab was already open — which
presents exactly as "it opened the main app instead".
This was not specific to /rep. Verified against the running app that
/m (Boss Phone) had the same gap, so it has never actually launched
standalone on iOS either; /counter likewise. The comment in
(counter)/layout.tsx asserting the root layout already supplied this
tag was wrong — the root also only set `appleWebApp.capable`.
Declared in the root layout so all four surfaces inherit it, and
repeated in the (rep) and (mobile) layouts because a child's
`metadata.other` replaces the parent's rather than merging into it.
Corrected the misleading counter comment.
Verified by fetching each route and asserting the rendered head:
/rep, /m, /new-order and /dashboard now all emit
apple-mobile-web-app-capable="yes" while still resolving their own
manifest.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit adds a full unauthenticated PWA for in-store retail order taking:
- Dedicated `/new-order` route with complete order form, customer/company picker
- Public `/api/counter/*` endpoints for search, order creation, and photo uploads
- Photo capture and gallery selection with 10-photo per order limit
- Offline caching via dedicated service worker and app manifest
- Shortcut redirect at `/counter` for quick installation
- Comprehensive setup and usage documentation in `docs/counter-pwa.md`
- Minor cleanup to root layout metadata and service worker registration
- Small layout fix for collection pool row text truncation
Orders submitted via the PWA appear immediately in the main CRM's New tab, and the app is designed for trusted office kiosk phones without requiring user login.
src/app/api/v1/sprint/attachment-counts/route.ts
- Chunk itemIds into batches of 80 before building the PocketBase filter;
the live cap was hit at ~115 IDs × 15 chars and surfaced as a
generic Next 500 ("Something went wrong while processing your
request.") that hid the real cause. 7 chunks for the sprint
page's max of 500 items.
src/app/layout.tsx
- Add metadataBase derived from NEXT_PUBLIC_SITE_URL /
NEXT_PUBLIC_POCKETBASE_URL. Silences the per-page
"metadataBase not set" warning during dev renders and gives
OG / Twitter cards a stable canonical base.
src/app/api/v1/{quotes,order-items,purchase-orders,stock,
stock-purchases,users,sprint,driver,ai-insights}/route.ts (NEW)
- Add the missing top-level collection routes the agent API
needs. seven are straight passthroughs to their PB collection;
/sprint proxies to quote_items with optional claimStatus and
category query params; /driver lists PB users (no role field
in PB so callers narrow with ?filter=); /ai-insights returns
a roll-up count + most-recent regenerate timestamp across the
four collections that carry ai_* JSON fields.
src/app/api/v1/collection-pool/{route.ts,route.test.ts},
src/app/(app)/collection-pool/{page.tsx,page.test.tsx,
view-model.ts,view-model.test.ts,components.tsx} (DELETED)
- Drop the collection_pool feature entirely: PB has no
collection_pool collection on the live instance
(pb:migrate:orders-v2 was never run), the codebase comment
in purchase-orders-service.ts says "now-removed", and the
sidebar entrypoint has been migrated to /sprint + /deliveries.
The replacement operational status is the `item_status =
"collection_pool"` enum value on order_items, which stays.
src/lib/server/orders-service.ts (+ test), src/lib/pb-helpers.ts,
src/components/sidebar.tsx, src/components/ui/assign-driver-dialog.tsx,
src/app/(app)/collection-map/sidebar.tsx,
src/app/api/mcp/route.ts (+ test) (MODIFIED)
- Remove listCollectionPool + getCollectionPool +
updateCollectionPoolStatus, the /collection-pool sidebar entry,
the deep-link in assign-driver-dialog and collection-map
sidebar, and the collection_pool.list MCP tool (the tool,
handler, and test mock).
scripts/migrations/2026-07-26-fix-quote-counter-and-reassign-numbers.ts (NEW)
- One-shot migration script that:
1. Reads every quote, sorts by created ASC.
2. Reassigns clean Q202607001 … Q202607{N} over the whole
table (including the e+22 garbage and the legacy
Qnnnnnn rows).
3. Sets quote_counters.(year=2026, month=7).last_seq = N
so the next /api/v1/quotes/next-number returns a clean,
atomic, unique number.
Default mode = dry-run; pass --apply to write.
Already executed against the live cloud PB during this session
(verified: 200/200 rows updated, counter at 200, next-number
returns Q202607201, Q202607202, Q202607203 on consecutive calls).
AGENTS.md (MODIFIED)
- Add data-layer-discipline block matching the style of the
three existing blocks. Documents which layer is legacy (pb-helpers)
vs current (lib/server/*-service.ts via /api/v1/*), gives the
migration order (customers → orders → quotes → suppliers →
companies → rest), and includes the grep one-liner future AI
agents should run before extending pb-helpers.
Not in this commit (your WIP, untouched):
src/app/(app)/{dashboard,delivery-notes,layout,orders/[id],
quotes/[id],quotes/approvals,quotes,sprint}/page.tsx,
src/app/(auth)/login/page.tsx, src/components/charts/*,
src/components/{company-form,customer-form,quote-email-card,
sprint-item-pricing-modal,supplier-form,theme-bootstrap,
theme-picker}*.{tsx,test.tsx}, src/app/api/invoicing/delivery-note/*
src/app/api/v1/quotes/[id]/pdf/route.ts, src/app/globals.css,
src/lib/{item-status-ui,pdf/quote-document,quote-status*,themes,
types}.ts, src/lib/server/{order-item-status*,quotes-service}.ts,
src/styles/themes.css, APP_CAPABILITIES.md, README.md,
docs/SHIPPED.md, scripts/smoke/screenshot-pages.mjs,
and the new untracked files under docs/, scripts/migrations/
2026-07-19…25, src/app/{(app)/deliveries,(app)/delivery-notes,
api/v1/ai-insights/rerun,api/v1/deliveries,api/v1/delivery-notes,
api/v1/quotes/[id]/partial-approve,api/v1/quotes/[id]/split},
src/components/{ai-insights-panel,ai-insights-renderer,
ai-item-history-trigger,brand-stripe,delivery-notes,ui/stock-item-search,
ui/duplicate-warning,ui/duplicate-warning.test}.tsx, supplier-form.test.tsx,
src/lib/{pb-helpers-duplicate.test,server/deliveries-service*,
server/delivery-notes-service*}, public/wfdash-logo*.png,
opencode.jsonc.
- Standardize quote number format from Q-YYYY-MM-NNN to QYYYYMMNNN across all client, server, test and API code
- Add atomic backfill logic for quote counters to avoid sequence collisions with existing records
- Rearrange Delivery Notes and Repairs to the Operations sidebar section
- Add supplier count badge to pricelist catalogue and improve filter tab overflow styling
- Optimize font loading in root layout to skip preloading unused font weights
- Improve table styling for customer and company pages with better text wrapping and empty states
- Fix rep display logic in quotes page to show "Unassigned" when no rep is assigned
- Add supporting documentation, PocketBase counter schemas and setup migration scripts
- Remove embedded SupplierMap from suppliers page for cleaner layout
- Improve invoice card layout for company and customer info spacing
- Improve filter label styling and accessibility in collection map page
Add complete multi-theme dashboard system including:
- 8 selectable themes with persistent per-browser preferences
- Theme bootstrap script to prevent FOUC on page load
- 12+ reusable chart components (area, bar, donut, radial gauge, etc)
- Custom checkbox UI component
- New settings page for appearance customization
Other changes:
- Optimize supplier map API payload with getMappableSuppliers helper
- Add aria-label attributes to back buttons on detail pages for better accessibility
- Update next.config.ts to include new local development IP 192.168.1.128
- Update site manifest with all new favicon and PWA assets
- Fix styling and layout spacing in rewrite quote modal
- completely rewrite the Sonner toaster component with theme-aligned styling, default top-center position, brand-colored toast states, and improved spacing/sizing
- update root layout to remove hardcoded Toaster position prop since the component now handles its own positioning
- add toggle to show/hide completed quote items on the quote process page
- add empty state message when all quote items are fully processed
- memoize displayed quote items for stable sorting and filtering
Fix inconsistent line endings across all project files for cross-environment consistency.
Add complete unit test suite covering core utilities, API routes, and server services.
Add Playwright E2E test setup with smoke, auth, and agent API tests.
Update all project configuration files to match standardized formatting.
Fix MCP API error handling to properly propagate HTTP status codes and use correct JSON-RPC error codes.
Add VSCode workspace configuration, extensions, and example MCP config files.
Update .gitignore to exclude new test and build artifacts.
Introduce a new SupplierMap component and page to visualize suppliers on a Leaflet map (client-side, dynamic import). Wire the feature into the app by importing Leaflet CSS in the global layout and adding a Supplier Map entry to the sidebar. The map fetches suppliers, parses coordinates, groups nearby suppliers into proximity clusters, and shows markers, tooltips, and lists of missing coordinates. Update package.json to include leaflet, react-leaflet and types; remove a Windows-specific lightningcss package. Also normalize Dockerfile ENV formatting (no behavior change).
- Introduced a new Separator component for visual separation in UI.
- Added Sheet component for modal-like functionality with triggers and overlays.
- Implemented Toaster component for notifications using Sonner library.
- Created Switch component for toggle functionality.
- Developed Table component with headers, body, footer, and rows for structured data display.
- Added Tabs component for organizing content into tabbed interfaces.
- Implemented Textarea component for multi-line text input.
- Created Tooltip component for displaying additional information on hover.
feat: add PocketBase helpers and types
- Implemented various helper functions for interacting with PocketBase collections (customers, companies, suppliers, quotes, orders).
- Added type definitions for entities such as Customer, Company, Supplier, Quote, Order, and their respective items.
- Included utility functions for generating unique identifiers for quotes, orders, and purchase orders.
- Added functions for calculating totals and formatting currency and dates.
chore: add TypeScript configuration
- Added tsconfig.json for TypeScript support with strict type checking and module resolution.