[Art Studio][Backend] Emit quality-rating & curation-decision events so the #389 read-model can populate avg-quality + true accept-rate #396

Closed
opened 2026-07-05 12:58:14 +00:00 by spikerj · 1 comment
Owner

Epic #382. Surfaced by #389 (metrics read-model): three aggregates can't be populated today because the pipeline never emits the events that would carry them — the read-model correctly refuses to fabricate them.

The gap (event-handler architecture):

  • Avg qualitynull in the read-model. CurationRatings (#378 W6) are staff-authored Mongo data, never published as an event, so the projection has nothing to fold. Needs an art.asset.rated (or art.asset.quality.scored) event on art.asset.lifecycle emitted whenever a rating/quality score is set.
  • True accept-rate — today #389 exposes pipeline success (completed ÷ (completed+failed)). A real curation accept-rate needs an art.asset.review.resolved / art.asset.curation.decided event (approved vs. rejected) when a staff curation decision lands.
  • Review-backlog — currently a live indexed count over art-assets.flaggedForReview (isolated behind IArtStudioReviewBacklogReader) because the safety flag is set inline with no distinguishable event. Fine as-is, but an art.asset.flagged/unflagged event would let the projection own it consistently with the rest.

Scope: add these publishers at the points where the state actually changes (curation rating write path; staff review-resolution; safety-flag set/clear), on the existing art.asset.lifecycle topic exchange with W3C trace context (ActivityHelper) — then extend the #389 ArtStudioMetricsProjector (pure fold) + read-model to consume them. Additive/inert to existing consumers (topic fan-out).

Deps: #389 (read-model + projector to extend). Type: backend, event-handler-driven. Populates the Metrics dashboard (#391) + Activity panel (#390) with real quality/curation numbers instead of proxies.
Test: projector folds the new events into avg-quality / accept-rate / backlog correctly (unit); publishers emit on the real state-change paths (unit).

Epic #382. Surfaced by #389 (metrics read-model): three aggregates can't be populated today because **the pipeline never emits the events that would carry them** — the read-model correctly refuses to fabricate them. **The gap (event-handler architecture):** - **Avg quality** — `null` in the read-model. `CurationRatings` (#378 W6) are staff-authored Mongo data, never published as an event, so the projection has nothing to fold. Needs an `art.asset.rated` (or `art.asset.quality.scored`) event on `art.asset.lifecycle` emitted whenever a rating/quality score is set. - **True accept-rate** — today #389 exposes *pipeline success* (completed ÷ (completed+failed)). A real curation accept-rate needs an `art.asset.review.resolved` / `art.asset.curation.decided` event (approved vs. rejected) when a staff curation decision lands. - **Review-backlog** — currently a live indexed count over `art-assets.flaggedForReview` (isolated behind `IArtStudioReviewBacklogReader`) because the safety flag is set inline with no distinguishable event. Fine as-is, but an `art.asset.flagged`/`unflagged` event would let the projection own it consistently with the rest. **Scope:** add these publishers at the points where the state actually changes (curation rating write path; staff review-resolution; safety-flag set/clear), on the existing `art.asset.lifecycle` topic exchange with W3C trace context (`ActivityHelper`) — then extend the #389 `ArtStudioMetricsProjector` (pure fold) + read-model to consume them. Additive/inert to existing consumers (topic fan-out). **Deps:** #389 (read-model + projector to extend). **Type:** backend, event-handler-driven. Populates the Metrics dashboard (#391) + Activity panel (#390) with real quality/curation numbers instead of proxies. **Test:** projector folds the new events into avg-quality / accept-rate / backlog correctly (unit); publishers emit on the real state-change paths (unit).
Author
Owner

Merged to master via spikersoft-backend#101. Curation event publisher landed — RateGalleryAssetCommandHandler + ModerateGallerySubmissionCommandHandler publish art.asset.rated / art.asset.curation.decided (best-effort, post-SaveChanges). Build 0 errors; 534 ArtStudio tests green.

✅ Merged to master via **spikersoft-backend#101**. Curation event publisher landed — `RateGalleryAssetCommandHandler` + `ModerateGallerySubmissionCommandHandler` publish `art.asset.rated` / `art.asset.curation.decided` (best-effort, post-SaveChanges). Build 0 errors; 534 ArtStudio tests green.
Sign in to join this conversation.