Implement the complete collection confirm feature set: - Add new `/collection-confirm` operational page for reviewing and confirming collected order items - Add sidebar navigation entries for Collection Confirm and Invoicing - Add `order_items` to the file proxy API whitelist for attachment access - Install required testing dependencies and configure Vitest test setup - Add full design documentation, test suite, and page overview screenshot - Update package.json and build configuration files
6.9 KiB
Collection Confirm Enhancements Design
Date: 2026-07-07
Area: src/app/(app)/collection-confirm/page.tsx
Status: Drafted for review
Goal
Extend the /collection-confirm page so operators can view driver-side attachments, upload a supplier invoice from each row, and confirm a row for invoicing with a structured invoice date and number captured in the new order_item_details field. Confirming flips item_status to ready_invoice.
User Need
Drivers already attach files to a collected row, but operators currently have no way to see those files or to capture supplier invoice details when they sign off the row for invoicing. The page should:
- show the driver attachments that already exist on the row,
- allow the operator to upload a supplier invoice to the same attachments field,
- require supplier invoice date and number on confirm,
- write invoice details into
order_item_detailsso invoicing has structured data to read.
Approved Direction
- Treat
order_item_attachmentsas a single multi-file PocketBasefilefield onorder_items. - Show those attachments inline on each collected row.
- Add an
Attachicon button on every row for supplier invoice upload. - Replace the current confirm action with a confirm modal that requires
Supplier invoice dateandSupplier invoice number. - On confirm, write a structured
invoiceentry into the neworder_item_detailsJSON field and flipitem_statustoready_invoice.
Scope
In scope:
- reading
order_item_attachmentsand rendering each file inline, - adding an
Attachicon and an upload modal that writes toorder_item_attachments, - extending the view-model with helpers for the
order_item_detailsJSON shape, - replacing the confirm modal with one that captures invoice date and number plus a reason note,
- flipping
item_statustoready_invoiceon confirm, - continuing to append a
confirmentry to the unified notes feed.
Out of scope:
- changing the attachment field schema (the operator added it manually),
- changing
collection_photoor merging it withorder_item_attachments, - building a dedicated invoicing page or invoice record,
- rewriting the collection pool, collection map, or other pages.
Data Source
The page continues to read from order_items. New fields in scope:
order_item_attachments: single PBfilefield withmaxSelect > 1. Treated as the row-level attachments.order_item_details: JSON text field used for invoice date and number, plus future structured details.
Existing fields in scope:
qty_collected,order_qty,quantity,description,po_description,problem_flag,problem_type,problem_notes,drv_collected_at,collection_photo,notes(unified feed),- relation expands for supplier, customer, company, order, purchase order.
Row Content Updates
Each row keeps everything it has today and adds:
- the list of files in
order_item_attachmentsrendered as small inline chips with a way to open each one, - an
Attachicon button next to the existing photo preview area for invoice upload.
Row Actions
Updated action set:
Adjust Quantity— unchanged,Add Note— unchanged,Attach— new icon button; opens a small upload modal that writes toorder_item_attachments,Confirm for invoicing— now opens a confirm modal.
Confirm Modal
The confirm modal now collects:
Supplier invoice date(date input, required),Supplier invoice number(text input, required),Note(textarea, optional but recommended when a problem flag is set).
On submit:
- Build an
invoiceentry containingdate,number,ts, andactor. - Append it to
order_item_detailsJSON. - Append a
confirmentry to the unified notes feed. - Flip
item_statustoready_invoice. - Refresh the page list.
The existing canConfirmRow guard still applies: rows with problem_flag = true require a confirming note, which the modal now satisfies by making the note field recommended in that case.
order_item_details Shape
order_item_details is a JSON text field. We treat it as a single object with one known section today and room to grow:
{
"invoice": {
"date": "YYYY-MM-DD",
"number": "string",
"setBy": "actor id",
"setByName": "actor name",
"setAt": "ISO timestamp"
}
}
- New writes replace the
invoicesection only; other sections are preserved. - View-model helpers expose
readInvoiceDetailsandwriteInvoiceDetails. - Empty or malformed JSON resolves to
{}so the helper never throws.
Attachment Upload
- The
Attachbutton opens a small modal with a single file input. - Only one attachment can be uploaded at a time; PB handles appending it to the existing
order_item_attachmentsfield. - On success the modal closes, the row refreshes, and the new file appears in the attachment list.
- Failure keeps the modal open with a toast error.
Implementation Shape
src/app/(app)/collection-confirm/view-model.ts: addreadInvoiceDetails,writeInvoiceDetails, and the confirm-mutation helper that produces the newitem_statusand notes entry together.src/app/(app)/collection-confirm/page.tsx: add the Attach icon, attachment list rendering, attach upload modal, and the new confirm modal flow.- No new collections, no new sidebar entries, no changes to the router.
Error Handling
- Failed attachment uploads surface toast errors and keep the modal open.
- Failed confirm writes keep the modal open so the operator can retry.
- Missing or unreadable files render as broken attachment chips rather than crashing the row.
Validation Plan
After implementation, validate that:
- driver attachments from
order_item_attachmentsrender on each row, - the
Attachbutton uploads a new file intoorder_item_attachments, - the confirm modal requires both invoice date and number,
- confirming writes the invoice details into
order_item_detailsand flipsitem_statustoready_invoice, - the notes feed still records the confirm entry,
- problem-flagged rows still require a confirming note,
- the page stays reachable from the existing sidebar entry.
Risks And Guardrails
Primary risk: clobbering other future sections in order_item_details.
Guardrails:
- Read-modify-write the JSON, replacing only the
invoicesection. - Treat malformed JSON as
{}on read so a broken entry cannot take the page down. - Reuse the existing modal patterns.
Acceptance Criteria
This enhancement is complete when:
- driver attachments show on every collected row,
- an
Attachicon lets the operator upload a supplier invoice toorder_item_attachments, - the confirm modal captures
Supplier invoice dateandSupplier invoice number, - the confirm action writes the invoice details into
order_item_details, - confirming flips
item_statustoready_invoice, - the unified notes feed still receives a confirm entry,
- problem-flagged rows still require a confirming note,
- no schema changes are introduced by the app itself.