Commit Graph
2 Commits
Author SHA1 Message Date
Paul NothaftandPaul Nothaft 962f1d9586 fix(tests): raise jest timeouts to the 120s convention (stable) (#902)
Stable backport combining #860 (never reached stable) and #900:

- jest.config.js gains testTimeout: 120000 — stable still ran on Jest's
  5s default for anything unpinned, while its migration chain (134 core
  migrations via backports) is nearly as long as beta's.
- All 19 suite-level jest.setTimeout(30000/60000) pins raised to 120s;
  local pins override the config default (#860's rationale).
- All 15 hook-ARGUMENT timeout pins on migration-booting beforeAll
  hooks raised to 120s (#900's rationale — the 3.97.0-beta.0 release PR
  failed on exactly this class on the beta side).

Untouched: the three suites whose pinned hooks don't run migrations
(webhookDelivery, imageProcessor.storage, storageBackend) and
publicQuotes' 30s pin on the rate-limit lockout test.

No test logic changed.

Co-authored-by: Paul Nothaft <[email protected]>
2026-07-29 12:48:50 +02:00
Luca 4812fcdec3 feat(backup): admin endpoint to verify CRM document-artefact integrity
Diagnostic for the bug fixed in a9280ea — confirms every *_path
column on quotes / contracts / invoices points at a file that
actually exists on disk and (where a *_sha256 column is set) the
file's bytes still hash to the expected value. Read-only;
on-demand only; no scheduler.
Per the design decisions locked in this PR's design call:
  D1 — on-demand only for v1; scheduling deferred until we have
       runtime data on large installs
  D2 — not auto-triggered after restore; surface a "verify
       integrity now" CTA on the restore-completed screen instead
  D3 — wet-upload contracts hash-verified same as system-rendered
       (signed_pdf_sha256 is computed at upload time, no special
       case needed in the verifier)
Coverage (single source of truth in backupIntegrityService.CHECKS):
  quotes.pdf_path                           existence
  contracts.pdf_path + pdf_sha256           existence + hash
  contracts.signed_pdf_path + signed_pdf_sha256  existence + hash
  contracts.signed_customer_signature_path  existence  (PNG/JPG, no hash)
  contracts.signed_admin_signature_path     existence  (PNG/JPG, no hash)
  invoices.pdf_path                         existence
  invoices.imported_pdf_path                existence  (admin-uploaded scans)
Report shape buckets each row into verifiedOk / missing /
hashMismatches / existsButNoHash so callers can distinguish hash-
verified from existence-only — the latter is weaker evidence in
a legal dispute and the UI should reflect that.
Route GET /api/admin/system-health/backup-integrity accepts an
optional ?scope= CSV filter (quote | contract | contract-signature
| invoice). Unknown scope tokens are rejected with a 400 +
BACKUP_INTEGRITY_UNKNOWN_SCOPE code rather than silently scanning
everything.
Frontend half (BackupIntegrityCard on a System Health page) is
deferred until backlog #11 (System Health page) is scaffolded.
The endpoint is independently useful via curl in the meantime.
2026-05-29 13:00:18 +02:00