PO numbers were "read the month's highest, add one", so POs for several
suppliers on one order created together got the same number — 34 numbers
by 2026-10-19 (e.g. PO202610008LIF for BarloWorld CAT and John Ratcliffe,
created 71 ms apart).
- createPurchaseOrderWithNumber (po-number.ts): numbers and creates POs
one at a time in the server, retries (up to 5) when the unique index
rejects a clash; ignores any po_number passed in.
- buyer-tasks / MCP generate_po use it.
- The Process page's Send PO and in-stock PO buttons now call
POST /api/v1/orders/[id]/purchase-orders (browser session) instead of
numbering in the browser; the client generatePONumber is removed from
pb-helpers.
- npm run pb:migrate:po-number-unique adds a partial unique index on
purchase_orders.po_number for POs created from then on; the 34 existing
duplicates are left as they are.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Implement new server-side ranked quote search endpoint at `/api/v1/quotes/search`, replacing the legacy 500-row client-side substring scan that missed older quotes and didn't rank results by relevance. The new search scores matches across quote identifiers, customer/company headers, and line item fields.
Update PO number generation and validation to use a dashless format (POYYYYMMNNNXXX) with per-company scoped sequence numbers, and ignore legacy PO formats when calculating new sequences.
Remove legacy `searchQuotesWithItems` function and its associated test file, then update the quotes page to use the new server-side search API.
Add comprehensive unit and integration tests for the new quote search service and updated PO number logic.
Add full PIN-protected TV dashboard stack including auth, redirects, map view, APIs, and server services.
Also include these critical refinements:
- Overhaul PO number generation to use per-company monthly sequences
- Rework quote rejection to bounce quotes back to operator queues instead of marking them terminal
- Add post_processing order tab group for clearer workflow visibility
- Fix collection pool tooltip positioning, overflow clipping, and default collapsed state
- Refactor customer list API, clean up unused form props, and fix item intel popover target ID handling
- Add comprehensive tests for new components and update existing test expectations
generatePoForGroup was creating purchase_orders records without
`po_number`, which is required by the PB schema. PB rejected the
create with 500 ("Failed to create record.") and the operator never
got a PO. Fix:
- New src/lib/server/po-number.ts — server-side generatePONumber()
that mirrors the client version in pb-helpers.ts (PO-YYYY-MM-NNN
format) but uses getAdminPocketBase(). Per the data-access rules,
don't extend pb-helpers.ts; server business logic lives under
lib/server/.
- generatePoForGroup now generates the PO number, includes
total_amount (sum of costPrice * quantity) and order_item
(back-link to the items) in the create payload — mirrors the
canonical /orders/[id]/process PO-creation flow so the PB admin
row shows related lines without an extra getList call.
- Test updated to assert the new payload (po_number regex,
total_amount computed, order_item back-link).
UI while here:
- BuyerTaskGroupCard now renders a deterministic supplier colour
stripe on the left edge. New src/lib/supplier-color.ts hashes the
supplierId into a small Tailwind 600 palette (18 colours) so the
same supplier always shows the same colour, and the supplier name
gets tinted with the same colour for quick scanning.
- PO number is now shown prominently at the top of the card (in a
warm-toned badge that matches the AI Insights theme) when one
exists — po_draft and po_sent tabs. Needs PO tab omits it.
Co-authored-by: Orca <help@stably.ai>