Commit graph

17 commits

Author SHA1 Message Date
d3132ab7f6 feat(collection-confirm): collected stock orders go through Collection Confirm
The driver app records the full quantity as received when it collects a
stock pickup, and Collection Confirm only listed stock lines that were
not fully received — so collected stock orders skipped it and sat at
"sent", outside the accountant's booking queue, until someone clicked
Mark received (29 stuck on 2026-10-19).

- STOCK_ON_PAGE_FILTER / stockLineOnPage: a collected stock line stays on
  Collection Confirm until its stock order is received; cancelled orders
  never show. Shared by the list and the AI check (so those lines get
  photos read and ticks too).
- Confirm stock: markStockOrdersReceived flips each stock order to
  "received" once every line is collected/booked (→ booking queue);
  orders with lines still out stay open, reported as stillOpen. The
  route returns { updatedIds, received, stillOpen }; the toast says so.
- Stock photos: `npm run pb:migrate:stock-photos` makes
  stock_purchases.additional_attachments multi-file;
  addStockPurchaseAttachment, Move photo and Delete photo add/remove with
  `+`/`-` instead of replacing the single slot.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 17:03:33 +02:00
f017a7f985 fix: number customer POs one at a time (duplicate PO numbers)
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>
2026-10-19 15:08:12 +02:00
924f7b764e fix: uploads to an order line add files instead of replacing them
A PocketBase file PATCH under the bare field name replaces the whole
list. On 2026-10-19 a buyer's "Add supplier invoice" on PO202610008LIF
deleted the driver's delivery-note photo (uploaded 14:38, read by the AI
14:40, replaced 14:41). Generating or regenerating a delivery-note PDF
did the same to every line on the DN.

- New src/lib/server/order-item-files.ts: addAttachmentForm() adds with
  `order_item_attachements+` and removes (`-`) only older stored copies
  of the same document; pickStoredCopy() finds a file by its uploaded
  name (PB stores "DN26101913.pdf" as "dn26101913_<10>.pdf").
- Used by the Collection Confirm invoice upload, DN create, DN regenerate
  (replaces only its own previous PDF) and /api/invoicing/delivery-note.
- /api/invoicing/delivery-note-pdf finds the DN PDF by name instead of
  taking the line's first file (falls back to the old behaviour for
  legacy names).
- AGENTS.md: always add, never replace.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 14:46:37 +02:00
d73fb6f0ab feat(collection-ai): read invoice discounts and set the discounted cost
HYCO (I009753) prints full prices on the lines and "Discount 25.00%" in
the totals; Swagelok (622831) has a "Disc %" column on each line. The AI
compared our cost (already the discounted price) with the printed price,
so the Price tick went red on both.

- The read now captures a line's discount_percent and a whole-document
  doc_discount_percent (prompt rule 5b) and stores net_unit_price on each
  line (both discounts stacked).
- The Price tick compares the cost with the price after discount; the
  tooltip and the document-lines panel spell it out
  ("R15.10 less 25% invoice discount = R11.33").
- Owner's call: when a "sure" tax-invoice line has a discount and our
  cost isn't the discounted price, the AI sets the cost to it (customer
  lines through updateOrderItemCost, which adds a cost note; stock lines
  through updateStockPurchaseItem) and records why in ai_check.cost_changed,
  shown in purple under the line. No discount, a delivery note or a
  "likely" match: the cost is never touched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 13:18:21 +02:00
f8294b4e1d feat(pocketbase): switch on the audit-log hooks
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 15:41:20 +02:00
0890835e91 chore(pocketbase): publish hooks to WFDASH-PBHOOKS for the VPS sync
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 15:35:54 +02:00
6b99f52dac chore(pocketbase): track live quotes hook and add git-based hook sync
quotes.pb.js is copied byte-for-byte from the live WFDASH PocketBase.
DEPLOY lists the hooks the VPS cron syncs into the hooks volume; the
audit hooks stay undeployed for now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 15:34:41 +02:00
8c3cfd45fc feat(collection-ai): settings section, runbook
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 09:55:44 +02:00
144971779f feat(quote-assistant): settings section, n8n tick, runbook
Quote assistant card in Settings, AI (on/off, interval, min confidence,
editable prompt with reset, last-run line); parseSettingsForm handles the
qa_* fields. docs/quote-assistant.md has the runbook and the n8n tick
workflow spec; AGENTS.md gets a short section.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 20:10:02 +02:00
a4b7089ac6 docs(giellie): document args-aware policy, trust semantics, env and PB rules
Also log the upstream assertBrowserSession 401s for orders.review,
orders.find_duplicates and dashboard.daily_summary as an open MCP request.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 00:36:55 +02:00
67a1482f2e docs: document the Giellie agent and its tool-policy rule
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 00:19:59 +02:00
7555196166 feat(audit): implement audit trail for delivery notes and orders
- Added an audit trail feature that logs every create, update, and delete action on delivery notes and orders, capturing detailed changes per field.
- Introduced the `AuditTimeline` component to display the history of changes for delivery notes and orders, enhancing traceability.
- Updated the `page.tsx` files for delivery notes and orders to fetch and display audit logs, ensuring users can view the history of modifications.
- Enhanced the `package.json` with a new migration script for setting up the audit log functionality.

This feature improves accountability and transparency in the management of delivery notes and orders.
2026-09-30 01:48:44 +02:00
058803d90f chore: update AGENTS.md 2026-09-02 01:17:05 +02:00
SJCoetz
3d3a012174 fix(api,layout): sprint 500 chunk + add 9 missing top-level agent routes + metadataBase; drop unused collection_pool feature; quote counter fix migration
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.
2026-07-26 22:18:49 +02:00
SJCoetz
ae88a2f3bc feat(invoicing): add complete delivery note workflow
This commit adds the full end-to-end delivery note workflow for the invoicing system:
- Added `letterheadForCompany` utility to infer the correct letterhead from a company name
- Created the DeliveryNoteDocument PDF component and server-side render function
- Added API endpoints for delivery note creation, PDF retrieval, printing, and print tracking
- Updated the PickingSlip component to support both invoice and delivery note headers
- Added view models for grouping, filtering, and displaying delivery note items
- Updated AGENTS.md with PocketBase schema and attachment best practices for new workflows
- Added comprehensive test coverage for all new components and API routes
2026-07-14 17:35:36 +02:00
SJCoetz
c4e1c62882 chore: standardize line endings and add full test + config scaffolding
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.
2026-06-11 20:30:02 +02:00
SJCoetz
363786ea36 feat: add UI components for separator, sheet, sonner, switch, table, tabs, textarea, tooltip
- 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.
2026-05-24 16:31:01 +02:00