Commit graph

448 commits

Author SHA1 Message Date
Dave
80a08a742b feat(mcp): enhance API documentation and add new tools
- Updated `docs/api-mcp-layer.md` to reflect the current state of the API, including new endpoints and tools.
- Added `category` field to `QUOTE_ITEM_PATCH_FIELDS` and `ORDER_ITEM_PATCH_FIELDS` to support item categorization.
- Introduced 22 new MCP tools to cover previously missing REST functionalities, increasing the total tool count from 103 to 125.
- Improved descriptions for several existing tools to clarify their usage and parameters.
- Regenerated the API documentation to ensure accuracy and completeness.
2026-08-15 00:06:40 +02:00
Dave
48053a6205 feat: add support for stock purchase attachments
- update backend service to fetch stock purchase attachments
- refactor dedupe logic to avoid filename collisions between customer and stock attachments
- adjust PoCard to generate correct file URLs for stock attachments
- update test expectations for the modified service query
2026-08-14 18:25:05 +02:00
Dave
e27184245b refactor(agent scan route): remove debug logs and redundant sanity check
Remove dev-time console logging and the unnecessary stock_purchases collection probe check to clean up the route handler.
2026-08-14 17:55:58 +02:00
Dave
162e47e80e refactor: clean imports, update types and fix issues
- move CollectionConfirmValidationError imports from stock-purchase-items-service to collection-confirm-service
- update ConfirmRow type: add supplier_sku field and remove unused nested expand properties
- refactor sortRowsByField generic in orders-service to fix type access errors
- add non-null assertion to firstRow.stock_purchase_id in collection confirm page upload handler
2026-08-14 17:13:04 +02:00
Dave
59f245d798 feat(collection-confirm): add stock item edits
- Add new POST API endpoints at `/api/v1/stock-purchase-items/[id]/sku` and `/api/v1/stock-purchase-items/[id]/cost` for updating stock purchase item details
- Update ItemsTable to support cost and SKU edits for all row types, add supplier SKU column and editing for stock rows
- Extend PoCard to pass edit callbacks and add stock-specific invoice upload functionality
- Update all related test suites to cover new editing and UI features
- Adjust invoice upload messaging to differentiate between customer and stock purchase orders
2026-08-14 16:39:46 +02:00
Dave
9e74968b5e feat: add PO agent workflow and inline SKU editing
Add full purchase order agent tooling and supporting changes:
- Add server-side purchase-order-agent-service for scanning both stock and customer POs, with complete test coverage
- Add inline SKU and supplier SKU editing flows to stock order detail pages
- Update MCP API route to support new PO agent tools (purchase_orders.scan, diff, record_diff_report) and stock_purchase_items.list
- Fix flaky CollectionPoolPage tests by wrapping state-dependent assertions in waitFor
- Refactor CollectionPoolPage auto-collapse logic to avoid react-hooks lint trap and run exactly once on initial load
- Delete temporary .tmp-inspect-pool.mjs development script
2026-08-14 12:37:13 +02:00
Dave
541676dabb refactor(invoicing): remove intermediate trimmedOverride variable 2026-08-14 11:25:10 +02:00
Dave
999948861e feat: add server-side quote search & PO number format update
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.
2026-08-14 11:15:38 +02:00
Dave
3b8bc0fc35 feat(delivery-notes, migrations): add tabs, grouping, markup, and fix DN relations
- Add shared env loader for migration scripts to load .env and .env.local files at module init
- Add migration script to fix broken delivery note relation fields and backfill missing company data
- Update delivery notes list page: add status filter tabs, company-based collapsible grouping, increased fetch limit, and improved global search
- Add per-item cost price, markup calculations, and total summary rows for cost, selling price, markup, and margin to delivery note detail pages
2026-08-14 09:41:14 +02:00
Dave
43de97501c feat(tv): add TV dashboard + refine workflows
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
2026-08-13 20:55:22 +02:00
Dave
dce9bfb04a feat(invoicing, dn): add surplus tracking, fix qty, update branding
- Fix resolveInvoiceLineDefaults to prioritize customer order quantity over supplier-collected quantity, ensuring invoices reflect what the customer actually ordered
- Add surplusQty utility function to calculate supplier MOQ overflow that should be booked to stock via /api/v1/stock/surplus-book
- Add surplus stock indicators in order and delivery note modals with descriptive tooltips explaining the surplus amount
- Expand supported letterhead codes to include WESTSCOTT GROUP, and configure all delivery notes to use the Westcott Group letterhead globally per business branding rules
- Improve error handling and logging in the delivery notes API POST route to include PocketBase error details and request context for easier debugging
- Add comprehensive unit tests for the updated invoice line logic and new surplusQty function to prevent regressions
2026-08-13 13:02:37 +02:00
Dave
8a224a7a24 feat(delivery-notes): add order disambiguation, fix PDF layout, update combine flow and qty resolution
- Fix delivery note PDF signature section overlapping page contents by removing fixed absolute positioning
- Add client-side picker for duplicate order numbers when merging delivery notes
- Add orderId parameter to combine delivery notes API for direct order lookup
- Update resolveDeliveryNoteLineQty to prioritize operator-edited quantity first
- Refactor combine delivery notes service and API to handle order lookup errors and candidate selection
2026-08-13 12:00:51 +02:00
Dave
617c5b3422 feat(delivery-notes): add inline qty editing and bulk combine features
Add inline quantity editing for delivery note items:
- New PATCH API endpoint and service function to update item quantities
- Optimistic UI updates on the detail page with error and loading states
- Input validation and status gating for draft/sent delivery notes

Add bulk delivery note combine functionality:
- New POST API endpoint and service to merge multiple draft/sent notes
- Row selection support in DataTable across pagination
- Confirmation modal with selected notes preview and optional order linking
- Automatic audit trail updates for merged and cancelled records

Extend OrderItem TypeScript interface with optional order expand field
Fix minor type casting issues in createAdHocDeliveryNote utility
2026-08-13 11:24:05 +02:00
Dave
4dd5898007 feat(delivery-notes): add pdf regeneration and fix ad-hoc pdf saves
Add new POST API endpoint at /api/v1/delivery-notes/[id]/regenerate-pdf to re-render and save delivery note PDFs from current line items. Add a "Regenerate PDF" button to the delivery note detail page with loading state and single-flight protection to prevent duplicate requests. Update ad-hoc delivery note creation to automatically attach PDFs to order items so print and download buttons work immediately after creation. Add helper utilities for resolving relation names and calculating line item quantities for PDF rendering.
2026-08-13 10:59:22 +02:00
Dave
18397bc9be feat(counter): add standalone counter order PWA
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.
2026-08-13 09:27:20 +02:00
Dave
c0ec3c99ef feat(orders,invoicing): add duplicate order cleanup and soft cancellation
Add a complete workflow for managing duplicate intake orders:
- Add new server API endpoints for single order cancellation, duplicate detection, and bulk duplicate cancellation
- Add client UI components for bulk duplicate cleanup and single order soft cancellation
- Add a "Duplicates" button to the orders dashboard for quick access to the cleanup tool
- Refactor invoicing module: rename customerNameSimilarity to nameSimilarity, update QB customer picker to use radio buttons and remove automatic preselection
- Add comprehensive test coverage for the new order service utilities
2026-08-13 09:02:27 +02:00
Dave
756597068e fix(delivery-notes): correct DN cancellation and filter issues
Update the cancel delivery note dialog description to correctly state items are marked as cancelled
Fix PocketBase expand field whitelisting for delivery items to avoid missing related entity data
Change order item status to "cancelled" instead of "completed" when cancelling a delivery note, with updated JSDoc explaining the choice of status
Update the buyer tasks PO sent filter and its regression test to cover all current ItemStatus values
2026-08-12 15:36:31 +02:00
Dave
9eea138662 feat(delivery-notes): add mark complete and cancel delivery note functionality
Add backend API routes and service functions for delivery note status updates with strict validation rules
Add UI action buttons and cancellation confirmation modal to the delivery note detail page
Update table layouts and styling across delivery notes and invoicing pages to improve responsiveness
Fix text overflow issues by adding whitespace-nowrap and break-words classes
Refactor order items table to display status inline and reduce redundant layout code
2026-08-12 08:55:56 +02:00
Dave
8efb952c76 feat(order-status): add delivery_note and fix tab mappings
- add `delivery_note` to the ItemStatus union type
- move delivery_note visual config from EXTRA_ITEM_STATUS_VISUAL to ITEM_STATUS_VISUAL
- update tab group mappings: add delivery_note to processing tab, expand collected tab with post-pickup statuses
- move removed status to the cancelled tab group
- replace silent fallback in itemStatusToTabGroup with explicit error for unmapped statuses
- add comprehensive regression test to ensure all ItemStatus values are mapped to a tab
2026-08-12 08:09:36 +02:00
Dave
8856146023 fix(orders,delivery-notes): resolve build type errors after supplier removal 2026-08-12 01:42:19 +02:00
Dave
6344948b0b feat: add driverless collection confirm and new order tooling
This commit adds several key features, improvements, and cleanups across the codebase:
- Add `order_items.confirm_collected` MCP/REST endpoint to mark order items as collected without requiring driver assignment
- Add standalone order creation and order split APIs for flexible order management
- Update order list sort to oldest-first to align with user workflow of working through oldest orders first
- Improve order search to show cross-tab matches and display source tab indicators on search results
- Add customer name similarity check to warn about mismatched QuickBooks customers during invoice creation
- Remove supplier name column from delivery note PDFs and clean up related data passing across delivery note routes
- Add validation and debug logging to ItemIntelPopover for missing item ID on apply actions
- Remove unused OrderItemContextPopoverTrigger component from order detail page
- Add delivery note regeneration script and update test suites for new and existing functionality
- Update documentation and add test coverage for the new collection confirm tool
2026-08-12 01:13:46 +02:00
Dave
cfc56f5c86 feat(quotes): add approval page and email updates
- add operator (claimer) display section to quote approval review page
- add per-line-item supplier pricing proof popover with lazy-loaded attachment previews
- improve customer/company text styling and responsive layout on approvals pages
- fix markup and selling price rounding to whole currency values for cleaner outputs
- completely overhaul default quote email templates for better readability and clear CTAs
- update sticky action bar styling and responsive behavior on approval page
- remove hardcoded "The Sales Team" fallback sender name in email templates
2026-08-11 16:09:40 +02:00
Dave
7d4e4c34f2 feat(api/v1/items): add item intel refresh route
Add a new Next.js POST API endpoint that regenerates AI item insights for specific quote_item or order_item records. Support dry-run mode to preview insights without persisting changes, validate input parameters and existing records to return clear error responses, and use admin-level PocketBase access for trusted server-side callers including n8n webhooks and batch cron jobs.
2026-08-11 11:28:51 +02:00
Dave
397df8e2b2 fix: correct quote expiry handling for PocketBase's 0 default
PocketBase returns 0 for unset number fields, which broke the original
null-coalescing check in effectiveValidityDays, leading to PDFs showing
"Valid until: today" for all new quotes created via email ingest.

Changes include:
- Update effectiveValidityDays to treat 0, negatives, null/undefined as falling back to 30-day default
- Add test cases for 0 and negative validity_days inputs
- Explicitly set validity_days to QUOTE_VALID_DAYS when creating new quotes
- Add one-time idempotent migration script to backfill legacy invalid validity values
- Refactor item intel popover patch logic to use PocketBase SDK for authenticated requests
- Add n8n workflow for AI-powered item insight matching
2026-08-11 08:32:17 +02:00
Dave
608a6ab978 feat(invoicing): widen the recent-window filter from 3 to 5 days
Single-line behavioural change: buildRecentInvoiceRange now subtracts
5 days from today instead of 3. The "in last 3 days OR unprinted" rule
shipped in the previous commit picks up the new window automatically —
the window affects which old-but-unprinted rows are still considered
"in the window" (purely a UX nuance; the unprinted branch already
covers anything older).

Also tighten the section-header + empty-state copy and the test
fixtures to reflect the new window. The "INV-OLD-*" dates in the
range test had to push back from 2026-07-05 to 2026-07-02 — 2026-07-05
fell inside the new 5-day window, which would have flipped the test's
expectation (it was asserting that printed-old dates are hidden).

Files:
- src/app/(app)/invoicing/view-model.ts — buildRecentInvoiceRange: -3 → -5
- src/app/(app)/invoicing/view-model.test.ts — expected `from` date
  shifts by 2 days; test name updated
- src/app/(app)/invoicing/page.tsx — section header + empty state +
  inline comments mention "5 days" instead of "3 days"
- src/app/(app)/invoicing/page.test.tsx — test name updated;
  INV-OLD-*/INV-OLD-PRINTED fixture dates pushed back from 07-05 to 07-02
  to stay outside the new 5-day window
2026-08-11 07:43:05 +02:00
Dave
228caf1680 feat(invoicing): surface all unprinted invoices + delivery notes on the Invoiced tab
The Invoiced tab used to filter to the last 3 days only, which
meant an invoice or delivery note that fell off the window would
disappear from the operator's list even if they hadn't printed
it yet. The only way back was the per-row "Print" button on a row
that no longer existed in the tab.

Change the filter rule from "in last 3 days" to "in last 3 days OR
unprinted". A row surfaces if either:
  - its date falls inside recentInvoiceRange, OR
  - it has not been printed yet (printed !== true).

This means an invoice or DN stays on the operator's list until it's
printed, regardless of age. The list doubles as the "what's still
outstanding" view — print a row, it drops off the next reload.

Stock bookings are unchanged (still windowed to the last 3 days
only) — there's no print tracking on stock_purchases yet, so
"unprinted stock booking" is undefined.

Also broaden the bulk-print button from "Print Today's Unprinted"
to "Print All Unprinted" so the operator can clear the backlog
in one pass instead of having to print each row individually.
The button iterates every invoice + DN group whose items haven't
all been printed, regardless of date.

Section header + empty state text updated to reflect the new rule.

Files:
- src/app/(app)/invoicing/page.tsx — filter logic, button copy,
  section header, empty state, bulk-print handler
- src/app/(app)/invoicing/page.test.tsx — updated existing tests
  to match the new behaviour; renamed "bulk prints only today's
  unprinted invoices" to "bulk prints every unprinted invoice,
  regardless of date"
2026-08-11 07:36:01 +02:00
Dave
3a59fa104c feat(item-intel): add new item intel popover and backend workflows
This commit replaces the legacy item history and AI insights system with a standardized, fuzzy-matched item intel workflow:
- Update AiItemHistoryTrigger component to support both quote and order items via the `collection` prop, replacing the old `insights` prop with `intel`
- Add full `ItemIntel` type definitions to `src/lib/types.ts` for the new standardized insight payload
- Create new REST API endpoints for fetching and computing item intel for `quote_items` and `order_items`
- Rewrite the MCP insight endpoint to use the new shared `item-intel-service` instead of legacy individual insight functions
- Reorder quotes page tabs to place Delivery Note quotes alongside New quotes for better daily operator workflow
- Add item intel triggers to quote process and order process pages
- Remove deprecated document-level `AiInsightsPanel` components from quote and order detail pages
- Add bulk backfill endpoint for populating intel across existing active items
2026-08-11 02:57:57 +02:00
Dave
47d58db0c9 feat(mcp): add price_list.add_items tool for agent-driven catalogue upsert
Add a new MCP tool that lets the agent read a supplier PDF, quote PDF,
or pasted supplier email with its native vision, extract the per-line
fields, and commit them to the price_list catalogue in one round-trip.

Why: the only pre-existing path was operator upload via /pricelist ->
n8n ingest -> raw_price_list -> AI extraction -> price_list. That flow
is async, human-in-the-loop, and gates on n8n being healthy. This
tool gives the agent a synchronous shortcut for ad-hoc catalogue
updates -- paste a PDF, get the catalogue updated, no async hops.

The agent does the OCR; the tool does the commit. No LLM work moves
into the MCP server.

Behaviour:

- Dedupe by (sku, supplier) -- exact match. Different suppliers with
  the same SKU get separate rows.
- Upsert policy: cost_price overwrites (latest price wins).
  Description, selling_price, unit, category, subcategory, brand,
  markup, stock_qty, search_text, sku_normalised also patched in
  place on update.
- sku_normalised auto-computed (uppercase, strip non-alphanumeric --
  same canonical form price-list-match.ts uses).
- search_text auto-computed (lowercased, space-separated concat of
  sku + description + brand + supplier + category + subcategory +
  synonyms).
- Skipped items returned with per-item reason (missing_sku,
  missing_supplier, invalid_cost_price, pb_write_failed). Never
  silent.
- Bulk cap 500 items per call; larger lists rejected with
  too_many_items reason.
- source_file_id + source_label supported so new rows can be
  traced back to a raw_price_list upload (optional).
- Supplier stored verbatim on price_list.supplier (free-text field,
  no FK resolution -- same as the live schema).

Files:

- src/lib/server/price-list-service.ts (new) -- addPriceListItems +
  buildSearchText + computeSellingPrice helpers
- src/lib/server/price-list-service.test.ts (new) -- 17 tests
  covering validation, upsert, dedupe filter shape, normalisation
- src/app/api/mcp/route.ts -- new tool definition + dispatch block
- src/app/api/mcp/route.test.ts -- 2 dispatch tests + tool-list
  assertion update
- .agents/skills/wfdash-giellie/SKILL.md -- new section "8. Price-
  list catalogue" documenting input/output shapes + failure modes

Tests:

- 134/134 pass across the affected files
- 1775/1778 in the full suite (3 pre-existing failures unrelated
  to this change: pocketbase-admin.test.ts PB mock mismatch,
  quotes/items/[id]/attachments/upload/route.test.ts timeout,
  supplier-form.test.tsx race -- all reproducible on main)
- npm run build clean
2026-08-10 12:45:05 +02:00
Dave
e9ffa6df4e feat(quotes/process): add mobile card layout for quote items
Replace the cramped horizontal table layout on mobile viewports with responsive vertical cards for each quote item. The new `ProcessItemCard` component provides full-width form fields, properly sized 44px tap targets for all actions, and maintains full parity with the desktop table implementation by reusing the same state handlers and callbacks. Add comprehensive test coverage for the new component, and fix existing mobile overflow issues in the quote process page header and table layout.
2026-08-10 10:47:36 +02:00
Dave
d9c60aff6d feat: add split views, stock picking slips, and invoice viewer
Comprehensive changes including:
- Refactor picking slip line handling for multiple document types across print endpoints
- Add new `/api/v1/stock-purchases/picking-slip` API for stock booking picking slips
- Implement reusable Splitter component and useSplitRatio hook for resizable panels
- Add floating/fullscreen invoice viewer to collection confirm page
- Add real-time stock booking update event for invoicing tab
- Add full test coverage for all new components and APIs
- Include temporary chat attachment images for testing purposes
2026-08-09 23:16:55 +02:00
Dave
9eef1fbd56 feat(mcp): add partial=true flag to PO invoice matching for buyer-side mark-and-flip
When the supplier ships a partial invoice (BREATHER on PO26080502STK was
not invoiced this round, but the other 7 lines were), the buyer wants
to:
  - mark and flip what we can confirm came in
  - leave the rest for the buyer to reconcile manually

Adding a new 'partial: true' flag to stock_purchases.match_and_receive_from_invoice
that:
  - widens the verdict gate to allow 'unmatched_po_lines' and 'cost_mismatch'
    to proceed when partial=true (the buyer is explicitly accepting these)
  - passes per-line quantity_received:0 overrides for unmatched PO lines
    into the existing receiveStockPurchase(items) override path, so only
    matched lines get booked into stock_ledger
  - surfaces 'skipped_po_line_ids' in the response so the buyer sees
    exactly what was held back
  - leaves the customer-PO path unchanged (every matched line is stamped,
    partial semantics only apply to stock purchases for now)

Hard stops regardless of partial: qty_mismatch on matched lines,
unmatched_invoice_lines, supplier_mismatch, wrong_status.

Test coverage: +1 dispatch test (partial flag forwarding) plus the
existing 'partial: false' assertion on the dry-run dispatch test.

Live-validated on PO26080502STK + invoice WR248939 (G-Man #1, 7 lines):
- 6 matched CIRCLIP/KM/MB lines booked, qty_received bumped
- BREATHER 3/4 line skipped via qty_received=0, surfaced in
  skipped_po_line_ids for manual reconciliation
- PO status flipped sent -> received
2026-08-09 20:41:27 +02:00
SJCoetz
87cead1bcf feat(mcp): expand stock purchase invoice matching service with 5 phases
Build out the buyer-side PO reconciliation workflow that landed in
60d3204 ('stock purchase invoice reconciliation tool') into a full
3-document × 2-PO-kind matching service. The tool now covers every
real-life supplier document the buyer can receive.

Renamed the service entry point from matchAndReceiveFromInvoice to
matchAndReceiveFromPoDocument (old name kept as a back-compat alias).
The MCP tool name stays stock_purchases.match_and_receive_from_invoice
so existing callers don't break; the input arg shape changed from
'invoice:' to 'document:' (old 'invoice:' arg still accepted for
back-compat).

Phase 1 — supplier_sku backfill (prep work, not in service code)
Phase 2 — auto-detect stock vs customer POs (single tool, both kinds)
Phase 3 — GRN (delivery-note) mode via new mode: 'grn' flag
Phase 4 — pack-size inference (Orapi case: per-unit vs per-pack)
Phase 5 — PO reference normalisation (PO202608017 vs PO-2026-08-017)

Also adds 3 new MCP tools for the collection-confirm buyer workflow:
collection_confirm.list, collection_confirm.upload_invoice,
collection_confirm.confirm_order_items.

Docs: updated .agents/skills/wfdash-giellie/SKILL.md and
src/app/api/mcp/FEATURE-REQUESTS.md to describe the new modes and
shape. 1,661/1,664 vitest tests pass; the 3 failing tests are
pre-existing (PocketBase SDK mock mismatch in pocketbase-admin.test,
5s timeout in quotes/items/[id]/attachments/upload/route.test —
both reproducible on main without this change).
2026-08-09 20:23:36 +02:00
SJCoetz
f88f451d6e fix(invoicing): print bundle fails on production due to self-fetch
The /api/invoicing/print-bundle route was doing a self-fetch through
its own public URL to download the invoice PDF it needed to bundle:

  fetch(`${origin}/api/v1/files/order_items/${id}/${token}`)

That works on local because Node inside the container can hit
localhost:3000 as a loopback. On production (Coolify / Docker) the
container's fetch to its own public hostname fails — DNS resolves to
an external IP that doesn't route back, the outbound TCP is blocked,
or the TLS handshake fails. Node's fetch throws 'fetch failed' at
that point, which bubbles up to the browser as a 500 toast.

Fix: fetch the invoice PDF directly from PocketBase with admin auth,
the same pattern /api/v1/files/... uses internally and that
delivery-note-pdf already uses. Drop the now-unused 'origin'
parameter from handlePrintBundle and the GET/POST wrappers.

Tests updated to mock pb.files.getURL + pb.authStore.token and assert
the new PB file URL + Authorization header.

All 65 tests across the print-bundle, picking-slip, view-model, and
invoicing page suites pass. The 2 pre-existing pocketbase-admin.test
failures are unrelated (reproducible on main without this change).
2026-08-09 20:23:26 +02:00
SJCoetz
60d320411d feat(mcp): add stock purchase invoice reconciliation tool
Add the full buyer-side supplier invoice reconciliation workflow:
- Include the new `stock_purchases.match_and_receive_from_invoice` MCP tool for deterministic PO-invoice matching
- Create core matching service with strict, rule-based line matching (sku → supplier_sku → description overlap)
- Support dry-run default mode to validate matches before committing
- Add automatic attachment handling with standard `supplier_invoice_*` naming convention
- Add full test suite for the matching logic
- Update documentation and agent skill profile to document the new tool and workflow

Pre-existing test failures (3 total) are unrelated to this change.
2026-08-09 16:59:44 +02:00
SJCoetz
63048e51c9 feat: add AI quote processing pipeline and admin settings UI
Add complete end-to-end AI-powered quote extraction workflow:
- Disable PB SDK auto-cancellation to support parallel batch requests
- Add required runtime dependencies for AI processing and document parsing
- Implement AI settings backend, operator UI, and REST API routes
- Add quote ingestion, insight population, and manual re-run AI endpoints
- Build service layers for quote items, AI settings, and structured item insights
- Fix attachment upload handling and quote item history blob parsing
- Add supporting migrations, smoke tests, and shared utility functions
- Export previously private helper functions for cross-service reuse
2026-08-09 16:17:29 +02:00
SJCoetz
b52de77f8c fix(sprint): filter stale quote items, add cleanup migrations
- Update sprint page query to only show unprocessed items from active (new/claimed) quotes, plus orphans
- Add one-shot migration to mark existing stale unprocessed quote items as processed
- Add one-shot migration to fix duplicate Q202608235 quote number entries
- Refine comments in the sprint page component for better maintainability
2026-08-07 20:15:46 +02:00
SJCoetz
30cc4fc5d2 Merge feat/order-item-context-block: replace AI Insights with deterministic context block
Co-authored-by: Orca <help@stably.ai>
2026-08-07 07:17:35 +02:00
SJCoetz
2de8cf1a56 chore(context): lint + build adjustments
Co-authored-by: Orca <help@stably.ai>
2026-08-07 03:04:28 +02:00
SJCoetz
f5185d3a2c feat(context): swap orders-page AI history ⓘ for context popover
Co-authored-by: Orca <help@stably.ai>
2026-08-07 02:59:27 +02:00
SJCoetz
995b7ed675 feat(context): swap sprint modal AI Insights for context panel
Co-authored-by: Orca <help@stably.ai>
2026-08-07 02:58:47 +02:00
SJCoetz
c5fbb7422f test(context): OrderItemContextPopoverTrigger UI tests
Co-authored-by: Orca <help@stably.ai>
2026-08-07 02:55:39 +02:00
SJCoetz
f75c1b2bbd feat(context): OrderItemContextPopoverTrigger (ⓘ on orders page)
Co-authored-by: Orca <help@stably.ai>
2026-08-07 02:55:14 +02:00
SJCoetz
b3a73c0040 test(context): OrderItemContextPanel UI tests
Co-authored-by: Orca <help@stably.ai>
2026-08-07 02:54:24 +02:00
SJCoetz
efd2ad6540 feat(context): OrderItemContextPanel (inline expandable, 4 rows)
Co-authored-by: Orca <help@stably.ai>
2026-08-07 02:53:21 +02:00
SJCoetz
5291fd2fd1 test(context): /api/v1/order-items/[id]/context route tests
Co-authored-by: Orca <help@stably.ai>
2026-08-07 02:50:44 +02:00
SJCoetz
7ad7375dd2 feat(context): GET /api/v1/order-items/[id]/context route
Co-authored-by: Orca <help@stably.ai>
2026-08-07 02:46:18 +02:00
SJCoetz
351c1b2b96 test(context): getOrderItemContext unit tests (null, quote, stock low/out, invoiced)
Co-authored-by: Orca <help@stably.ai>
2026-08-07 02:42:57 +02:00
SJCoetz
ced25be47a feat(context): implement getOrderItemContext (5 PB reads, fuzzy fallback)
Co-authored-by: Orca <help@stably.ai>
2026-08-07 02:34:45 +02:00
SJCoetz
18afe7d2d9 feat(context): add order-item-context-service skeleton + types
Co-authored-by: Orca <help@stably.ai>
2026-08-07 02:23:45 +02:00
Claude
357decbb2b docs(plan): order-item context block — 12 TDD tasks
Implementation plan for the spec at
docs/superpowers/specs/2026-08-07-order-item-context-block-design.md.

Tasks: backend service skeleton + impl + tests, /api/v1/.../context
endpoint + tests, OrderItemContextPanel + tests,
OrderItemContextPopoverTrigger + tests, sprint modal wire-in, orders
page wire-in, full test suite + build smoke.

Each task follows a TDD cycle: write failing test, run to confirm,
implement minimal code, run to confirm pass, commit.

Co-Authored-By: Claude <noreply@anthropic.com>

Co-authored-by: Orca <help@stably.ai>
2026-08-07 02:18:28 +02:00