Commit Graph

2 Commits

Author SHA1 Message Date
Paul Nothaft 40eb03f0d8 fix(tests): raise jest timeouts to survive the growing migration chain (#860)
The 3.94.0-beta.0 release PR (#859) failed its backend job on
workflowEngine.test.js: bootCrmDb() runs every core migration in
beforeAll, and with migrations 163-165 merged the setup crossed the
suite's jest.setTimeout(30000) on CI runners — the log shows migration
099 still seeding after the hook timed out. Same pass is green locally
and passed on #857's rebase minutes earlier: borderline-slow, not
deterministic.

- jest.config.js: testTimeout 120000 as the default, so bootCrmDb
  suites without an explicit pin stop being time bombs as the chain
  grows
- every suite-level jest.setTimeout below 120s raised to 120s — local
  pins OVERRIDE the config default, so the 30s/60s ones would keep
  flaking regardless of the global bump

No test logic changed anywhere.

Co-authored-by: Paul Nothaft <paul@MacStudio-von-Paul.local>
2026-07-22 21:27:12 +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