Skip to content

Generate and store a Scorechain screening report PDF#4098

Merged
TaprootFreak merged 3 commits into
developfrom
feat/scorechain-screening-pdf-document
Jul 6, 2026
Merged

Generate and store a Scorechain screening report PDF#4098
TaprootFreak merged 3 commits into
developfrom
feat/scorechain-screening-pdf-document

Conversation

@TaprootFreak

Copy link
Copy Markdown
Collaborator

What

Every time a Scorechain screening is newly performed (not served from cache) for a transaction tied to a customer, render a one-page PDF report and store it as a compliance document on the user's userData.

Why

The Scorechain scoring response is currently only persisted as raw data on scorechain_screening. Compliance needs a human-readable, self-contained document per check, filed alongside the customer's other KYC/AML documents — the same way name-check results are stored.

How

  • ScorechainPdfService (integration/scorechain) — renders the stored screening (score, severity, address, blockchain, proof-of-authenticity, per-section counterparty breakdown) into a PDF with pdfkit + the shared PdfUtil, mirroring CustodyPdfService.
  • ScorechainDocumentService (kyc subdomain) — generates the PDF and stores it via KycDocumentService.uploadFile as FileType.UserNotes / FileSubType.BlockchainAddressAnalysis (an existing, previously unused subtype), mirroring the name-check document flow.
  • A transient isNewlyScreened flag on the entity is set only on the provider path (performScreening), so cache hits never re-emit a document.
  • Wired into both AML preparation gates (buy-crypto, sell-crypto) and the manual re-trigger endpoint.
  • Rendering/storing failures are logged and swallowed — they must never break the AML flow.

No DB migration (reuses kyc_file and an existing subtype).

Verification

format:check, lint, type-check, full jest (1925 passed), build, and a DI-boot of the compiled app all pass locally — the last confirms the new forwardRef wiring between the KYC and buy/sell-crypto modules resolves cleanly.

…liance document

For every newly-performed Scorechain screening (not cache hits) tied to a customer, render a
one-page PDF report (score, severity, address, proof-of-authenticity, counterparty breakdown) and
store it as a KycFile (UserNotes / BlockchainAddressAnalysis) on the userData — mirroring the
NameCheck document flow. Wired into the buy-crypto/sell-crypto AML gates and the manual re-trigger.
Failures to render/store never break the AML flow (logged, swallowed). No DB migration.
The generate() promise only rejected on synchronous throws; an async pdfkit stream 'error' event
would have left it pending forever and stalled the awaiting AML flow. Wire pdf.on('error', reject)
so a render failure always surfaces (and is then swallowed by the document service as intended).
@TaprootFreak

Copy link
Copy Markdown
Collaborator Author

Design note for reviewers: a report is emitted per actually performed screening, keyed off the transient isNewlyScreened flag that is only set on the live provider path — cache hits never emit a document. The manual re-trigger endpoint deliberately produces a fresh report on each call, and a genuine re-screen (e.g. a withdrawal to a not-yet-seen address, whose NotFound/unsigned verdict is intentionally non-cacheable) will likewise produce its own report. This is by design: every stored PDF corresponds to one real screening event, so there is no transaction-level de-duplication.

@TaprootFreak TaprootFreak marked this pull request as ready for review July 6, 2026 08:37
@TaprootFreak TaprootFreak requested a review from davidleomay as a code owner July 6, 2026 08:37
@TaprootFreak TaprootFreak merged commit 41fb778 into develop Jul 6, 2026
7 checks passed
@TaprootFreak TaprootFreak deleted the feat/scorechain-screening-pdf-document branch July 6, 2026 10:49
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.

1 participant