Add photo upload for PDQ Z-reports and receipt evidence

DB:
- Add attachment_type ('pdq_z_report' | 'receipt_error' | 'other') and
  label columns to cash_count_attachments; migrate existing rows via
  ALTER TABLE IF NOT EXISTS (no data loss)

Backend:
- Upload route now reads attachment_type and label from multipart form
  fields alongside the file, stores them in the DB

Frontend:
- PhotoUploader component: thumbnail grid, upload button (images + PDF),
  spinner during upload, ✕ delete button on each photo, click opens in
  new tab
- DailyCashUp: PDQ Z-Reports card (one section per machine — Front Desk /
  Restaurant Bar) appears after Card Machines when a cash up exists
- DailyCashUp: Receipt Evidence card at bottom for any discrepancy photos;
  stays editable even on final cash ups so receipts can be added later

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jtricerolph 2026-07-02 09:22:22 +00:00
parent 1f5f1639c7
commit 43c332be9b
5 changed files with 166 additions and 21 deletions

View file

@ -21,9 +21,16 @@ export const api = {
delete: <T>(path: string) => req<T>('DELETE', path),
}
export async function uploadAttachment(cashUpId: number, file: File) {
export async function uploadAttachment(
cashUpId: number,
file: File,
attachmentType: 'pdq_z_report' | 'receipt_error' | 'other' = 'other',
label?: string,
) {
const fd = new FormData()
fd.append('file', file)
fd.append('attachment_type', attachmentType)
if (label) fd.append('label', label)
const res = await fetch(`${BASE}/attachments/upload/${cashUpId}`, {
method: 'POST',
credentials: 'include',