[Art Studio][Backend] Wire api/artstudio/submit to apply stageMethodSelections, presetId & per-stage skip (composer selections currently dropped) #397

Closed
opened 2026-07-05 13:27:37 +00:00 by spikerj · 2 comments
Owner

Epic #382 / relates #378 (W1/W2). Surfaced by #385 (composer): the frontend sends per-stage method selections (W1 StageMethodOptions), presetId (W2 ArtWorkflowPreset), and per-stage skip, but api/artstudio/submit currently binds only name/assetType/sourceType/prompt/image — the rest is silently dropped. Net effect: the W1 method choice, W2 preset application, and skip are non-functional end-to-end (the pipeline always runs its default stage plan/methods regardless of what the user picked).

Scope (event-handler-driven): wire the submit action to parse stageMethodSelections (JSON), presetId, and skippedStages, resolve the preset + per-stage method overrides against the existing W1/W2 domain, and thread the resolved plan into the pipeline kickoff — the stage command / workflow doc that ArtPipeProcessor consumes (RequestArtAssetStageCommand / the art.asset.lifecycle planning path) — so the chosen method/model actually runs per stage and skipped stages are omitted from the plan. Keep heavy work out of Api (MediatR → workers per worker-architecture rule); trace context preserved.

First: DISCOVER the intended flow — the W1/W2 domain exists; determine whether submit was meant to consume it (designed-but-unwired) or whether selections were meant to arrive via a separate endpoint. Don't fabricate a second path if submit is the right home.

Deps: the #385 composer already sends these fields forward-compatibly (staff-gated skip). Type: backend. Test: submit with method/preset/skip → the resulting stage plan/command reflects them (unit); untouched submit still yields the default plan (regression).

Epic #382 / relates #378 (W1/W2). Surfaced by #385 (composer): the frontend sends per-stage **method selections** (W1 `StageMethodOptions`), **`presetId`** (W2 `ArtWorkflowPreset`), and per-stage **skip**, but `api/artstudio/submit` currently binds only `name/assetType/sourceType/prompt/image` — the rest is **silently dropped**. Net effect: the W1 method choice, W2 preset application, and skip are non-functional end-to-end (the pipeline always runs its default stage plan/methods regardless of what the user picked). **Scope (event-handler-driven):** wire the submit action to parse `stageMethodSelections` (JSON), `presetId`, and `skippedStages`, resolve the preset + per-stage method overrides against the existing W1/W2 domain, and thread the resolved plan into the pipeline kickoff — the stage command / workflow doc that `ArtPipeProcessor` consumes (`RequestArtAssetStageCommand` / the `art.asset.lifecycle` planning path) — so the chosen method/model actually runs per stage and skipped stages are omitted from the plan. Keep heavy work out of Api (MediatR → workers per worker-architecture rule); trace context preserved. **First: DISCOVER the intended flow** — the W1/W2 domain exists; determine whether submit was meant to consume it (designed-but-unwired) or whether selections were meant to arrive via a separate endpoint. Don't fabricate a second path if submit is the right home. **Deps:** the #385 composer already sends these fields forward-compatibly (staff-gated skip). **Type:** backend. **Test:** submit with method/preset/skip → the resulting stage plan/command reflects them (unit); untouched submit still yields the default plan (regression).
Author
Owner

Correction after discovery — the gap was narrower than filed. Tracing ArtStudioController.Submit → SubmitArtAssetCommandHandler → RequestArtAssetStageCommand → ArtPipeProcessor showed that stageMethodSelections (W1) and presetId (W2) are already fully wired — the controller binds them, the handler resolves per-stage methods, loads/merges the preset, composes the prompt, attaches failover, and persists provenance. The #385 composer's "backend doesn't parse them" note was mistaken (it read a stale/partial view). Only skippedStages was genuinely dropped.

Fixed in local branch feature/artstudio-submit-selections-397 (unpushed): controller binds + JSON-parses skippedStages (400 on malformed), threads it through the command; handler normalizes + staff-gates it (reusing the W1 AllowStudentMethodChoice gate; non-staff skips rejected + audited via new StageSkipRejected), filters the persisted StagePlan (empty-plan guard), and prunes method overrides for skipped stages. Worker unchanged — it already walks StagePlan. No-skip path proven byte-identical (regression tests). Build clean; filtered ~ArtStudio|~Submit|~StageMethod|~Preset = 540 pass, +15 new tests. Semantic skip-validity (e.g. skipping modeling starves downstream) deliberately left to staff/pipeline — no mandatory-stage concept exists in the codebase to enforce. Will close on merge.

**Correction after discovery — the gap was narrower than filed.** Tracing `ArtStudioController.Submit → SubmitArtAssetCommandHandler → RequestArtAssetStageCommand → ArtPipeProcessor` showed that `stageMethodSelections` (W1) and `presetId` (W2) are **already fully wired** — the controller binds them, the handler resolves per-stage methods, loads/merges the preset, composes the prompt, attaches failover, and persists provenance. The #385 composer's "backend doesn't parse them" note was mistaken (it read a stale/partial view). **Only `skippedStages` was genuinely dropped.** Fixed in local branch `feature/artstudio-submit-selections-397` (unpushed): controller binds + JSON-parses `skippedStages` (400 on malformed), threads it through the command; handler normalizes + **staff-gates** it (reusing the W1 `AllowStudentMethodChoice` gate; non-staff skips rejected + audited via new `StageSkipRejected`), filters the persisted `StagePlan` (empty-plan guard), and prunes method overrides for skipped stages. **Worker unchanged** — it already walks `StagePlan`. No-skip path proven byte-identical (regression tests). Build clean; filtered `~ArtStudio|~Submit|~StageMethod|~Preset` = **540 pass**, +15 new tests. Semantic skip-validity (e.g. skipping `modeling` starves downstream) deliberately left to staff/pipeline — no mandatory-stage concept exists in the codebase to enforce. Will close on merge.
Author
Owner

Merged to master via spikersoft-backend#101. Submit skip/method-selections wiring landed in SubmitArtAssetCommandHandler (staff-gated stage skipping, persisted StagePlan filter). Build 0 errors; 534 ArtStudio tests green.

✅ Merged to master via **spikersoft-backend#101**. Submit skip/method-selections wiring landed in `SubmitArtAssetCommandHandler` (staff-gated stage skipping, persisted StagePlan filter). Build 0 errors; 534 ArtStudio tests green.
Sign in to join this conversation.