Skip to content

feat(reports): async attestation render + report.ready event (B3a)#646

Merged
remyluslosius merged 1 commit into
mainfrom
feat/reports-b3a-async-render
Jun 22, 2026
Merged

feat(reports): async attestation render + report.ready event (B3a)#646
remyluslosius merged 1 commit into
mainfrom
feat/reports-b3a-async-render

Conversation

@remyluslosius

Copy link
Copy Markdown
Contributor

Summary

Phase B3a moves attestation bulk-face rendering off the request path and emits a report.ready event — the first producer of the in-app notification bell.

What changes

  • eventbus: new EventKindReportReady (report.ready) + ReportReady event (snapshot id, kind, rendered faces, generating principal), added to the AllEventKinds closed set.
  • report/job.go: a report.render job (RenderJobType + RenderPayload) and a RenderProcessor. Generate(attestation), when async is enabled (WithAsyncRender), marks the bulk faces (csv/oscal_sar/pdf) pending and enqueues the job, returning immediately; the executive summary stays synchronous (tiny rollup). The processor renders each face via Export (flipping pending → ready; a render error marks the face failed and fails the job for retry), completes the job, and publishes ReportReady.
  • worker: a ReportRenderer interface + WithReportProcessor + a report.render dispatch case (interface-typed so worker doesn't import report). server: WithReportWorker registers it on the in-process worker. main.go: builds the report service WithAsyncRender + a RenderProcessor over the bus.

Async is an optimization, not a correctness gate: Export stays the lazy fallback, so a download arriving before the job runs still renders inline; enqueue failures are logged and don't fail Generate.

How the bell consumes it (for later — B3c)

ReportReady flows through the existing generic SSE bridge automatically (it marshals any subscribed event). The frontend notification bell (still stubbed) is the remaining B3c slice and needs product decisions before building.

Spec / tests

  • api-reports v1.10.0: new C-16 + AC-22 (DB test: pending faces + queued job → RenderProcessor → ready faces + completed job + a ReportReady event with the snapshot/kind/faces/principal). The eventbus AC-07 closed-set test updated for the new kind.
  • gofmt silent, go vet clean, go build ./... clean; specter check 111 specs structural + 0 annotation errors; go test ./internal/report/ ./internal/eventbus/ ./internal/worker/ green.

Validation

  • gofmt / go vet / go build
  • go test report + eventbus + worker
  • specter check (structural + annotation hygiene)

@github-actions github-actions Bot added documentation Improvements or additions to documentation size/L labels Jun 22, 2026
Move attestation bulk-face rendering off the request path and emit a
report.ready event - the first producer of the in-app notification bell.

- eventbus: new EventKindReportReady (report.ready) + ReportReady event
  (snapshot id, kind, rendered faces, generating principal), added to the
  AllEventKinds closed set.
- report/job.go: a report.render job (RenderJobType + RenderPayload) and a
  RenderProcessor. Generate(attestation), when async is enabled
  (WithAsyncRender), marks the bulk faces (csv/oscal_sar/pdf) 'pending' and
  enqueues the job, returning immediately; the executive summary stays
  synchronous. The processor renders each face via Export (flipping
  'pending' -> 'ready'; a render error marks the face 'failed' and fails the
  job for retry), completes the job, and publishes ReportReady.
- worker: a ReportRenderer interface + WithReportProcessor + a
  'report.render' dispatch case (interface-typed so worker does not import
  report). server: WithReportWorker registers it on the in-process worker.
- main.go: build the report service WithAsyncRender + a RenderProcessor over
  the bus, and register both.

Async is an optimization, not a correctness gate: Export stays the lazy
fallback, so a download arriving before the job runs still renders inline;
enqueue failures are logged and do not fail Generate.

Spec api-reports v1.10.0: C-16 + AC-22 (DB test: pending faces + queued
job -> processor -> ready faces + completed job + ReportReady event).
eventbus AC-07 closed-set test updated for the new kind.
@remyluslosius remyluslosius force-pushed the feat/reports-b3a-async-render branch from b69dc02 to 6ffae49 Compare June 22, 2026 03:39
@remyluslosius remyluslosius reopened this Jun 22, 2026
@remyluslosius remyluslosius merged commit 7afb6ed into main Jun 22, 2026
15 of 16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant