Skip to content

Service reports with customer signature (PDF) - #33

Merged
Installation-04 merged 6 commits into
mainfrom
claude/feature-service-reports
Nov 5, 2026
Merged

Installation-04 merged 6 commits into
mainfrom
claude/feature-service-reports

Conversation

@Installation-04

Copy link
Copy Markdown
Owner

Summary

  • On a work order, the technician fills a service report (work done, parts, time spent, observations). The customer signs on a touch/mouse canvas pad. A PDF (company header, client, work order, report, signature, date) can be downloaded or attached to the client's documents.
  • New table service_reports (in both backend/src/db/schema.js and backend/db/init.sql, idempotent). The signature is stored as PNG in a BYTEA column.
  • Signature validation: PNG data URL only, 64 kB cap on the decoded PNG, PNG magic and IHDR checked, max 2000 px per side, signer name required.
  • Authz: admin, assignee or creator of the work order only (403 otherwise). Saving without a fresh signature drops the previous one, since the signature covers the content.
  • PDF: pdfkit (pure JS, no system libs, fine on node:alpine). Attached PDFs are stored in the uploads dir and listed as ordinary documents; re-attaching replaces the previous one. Header name via COMPANY_NAME (default TechIBase).
  • Netlify: the PDF download/attach routes return 501 there (documents are in Blobs). The report text and signature still work. The functions-bundle-check esbuild command passes locally.
  • UI in French, with dark-mode variants. The signature pad uses Pointer Events with touch-action: none on a white surface, so it works on phones.

Tests

  • Backend: 175/175 pass with Postgres, including the new service-reports.test.js (valid %PDF buffer, signature validation, authz, create/sign/download/attach/replace).
  • Frontend: 25/25 pass, including pure helpers in serviceReport.mjs; vite build OK.

Not verified

  • Signature pad on a real touch device; PDF visual rendering. Docker images not built.

Generated by Claude Code

Technicians fill a service report on a work order, the customer signs on
a canvas pad (PNG, 64 kB cap, magic-byte and dimension checks), and a PDF
is generated with pdfkit, downloadable or attached to the client's documents.
Access is limited to admins, the assignee and the creator of the work order.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01StC4huMbM6BRB9r4XFXvXv
Download and attach re-saved the report first; with an empty signature pad
that PUT dropped the signature that had just been saved, so the PDF came out
"Non signé" and attach failed. Skip the save when nothing changed. Also
associate the form labels with their fields.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01StC4huMbM6BRB9r4XFXvXv
- Validate the PNG for real: chunk walk, no trailing bytes after IEND, no
  interlacing, IDAT inflated with an output cap (8 MB) that must match the
  IHDR geometry, so bombs and corrupt streams are refused at save time instead
  of breaking every later PDF render.
- Replace characters Helvetica cannot draw (CJK, Cyrillic, emoji) with "?"
  instead of printing unrelated glyphs; keep all French accents, oe and euro.
- Keep a very long COMPANY_NAME on one line in the header band.
- Attach: swap the document link atomically (row lock) so concurrent attaches
  leave one document, and remove the new file and row if a step fails.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01StC4huMbM6BRB9r4XFXvXv
On the CI's Node 20 the decoder maps 0x80-0x9F to control characters, which
turned oe, euro and OE into '?'. The character set is now spelled out.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01StC4huMbM6BRB9r4XFXvXv
# Conflicts:
#	CHANGELOG.md
#	backend/src/app.js
@Installation-04
Installation-04 marked this pull request as ready for review November 5, 2026 03:11
@Installation-04
Installation-04 merged commit 699bb1f into main Nov 5, 2026
6 checks passed
@Installation-04 Installation-04 mentioned this pull request Nov 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants