[ArtStudio P5] Frontend Art Studio — pipeline wizard, three.js viewer, SignalR progress + queue position, my-assets library #351

Closed
opened 2026-07-04 05:11:28 +00:00 by spikerj · 4 comments
Owner

Sub-ticket of epic #346. Depends on #347 (API contracts); demo-able end-to-end once #348 lands. Can start against P1 endpoints in parallel with P2–P4.

What: the student-facing Art Studio on learn.spikersoft.com — a new feature library presenting the pipeline as a guided journey (concept → model → texture → rig → animate → export) so the educational structure of a real 3D pipeline is the UI, not hidden behind it.

Scope:

  • New libraries/features/art-studio lib copying the trellis-3d-generator structure (project.json tags layer:feature, barrel src/index.ts, tsconfig.base.json path alias @spikersoft/feature-art-studio); signals-in-root-service state (pattern: threed-generator.service.ts)
  • Lazy route in projects/spikersoft/src/routes.ts behind [AuthGuard] (students + staff); staff-only affordances via hasAnyRole(...) from role.guard.ts
  • Submission wizard: asset type (character / prop), prompt or drawing upload (FormData multipart, reuse book-upload patterns), model/preset choices kept simple for students
  • Pipeline progress view: per-stage timeline fed by SignalR (accessTokenFactory + skipNegotiation pattern from system-notification.service.ts), including queue position / "waiting for GPU" state — single shared card means honest waiting UX
  • three.js viewer (extend the trellis component's GLTFLoader/OrbitControls usage): textured model orbit view, skeleton overlay toggle after rigging, animation clip playback after animation stage; per-stage artifact tabs (concept image, texture maps, previews)
  • My Assets library: paged grid with thumbnails, stage status chips, restart-from-stage / cancel / delete actions, GLB (and texture-pack) download
  • Transloco i18n from day one (en + es — see the pain in #288/#289/#296); Storybook stories + specs per repo convention

Note: the existing trellis-3d-generator route should redirect into the studio (or be absorbed) once parity is reached — decide here, don't leave two 3D entry points.

Acceptance: a student submits a prompt, watches stages advance live with queue position shown, orbits the textured model, toggles the skeleton, plays the walk preset, and downloads the GLB — all in both languages; another student's assets are never visible.

Sub-ticket of epic #346. Depends on #347 (API contracts); demo-able end-to-end once #348 lands. Can start against P1 endpoints in parallel with P2–P4. **What:** the student-facing Art Studio on learn.spikersoft.com — a new feature library presenting the pipeline as a guided journey (concept → model → texture → rig → animate → export) so the educational structure of a real 3D pipeline is the UI, not hidden behind it. **Scope:** - [ ] New `libraries/features/art-studio` lib copying the `trellis-3d-generator` structure (`project.json` tags `layer:feature`, barrel `src/index.ts`, `tsconfig.base.json` path alias `@spikersoft/feature-art-studio`); signals-in-root-service state (pattern: `threed-generator.service.ts`) - [ ] Lazy route in `projects/spikersoft/src/routes.ts` behind `[AuthGuard]` (students + staff); staff-only affordances via `hasAnyRole(...)` from `role.guard.ts` - [ ] Submission wizard: asset type (character / prop), prompt or drawing upload (`FormData` multipart, reuse `book-upload` patterns), model/preset choices kept simple for students - [ ] Pipeline progress view: per-stage timeline fed by SignalR (`accessTokenFactory` + `skipNegotiation` pattern from `system-notification.service.ts`), including **queue position / "waiting for GPU"** state — single shared card means honest waiting UX - [ ] three.js viewer (extend the trellis component's GLTFLoader/OrbitControls usage): textured model orbit view, skeleton overlay toggle after rigging, animation clip playback after animation stage; per-stage artifact tabs (concept image, texture maps, previews) - [ ] My Assets library: paged grid with thumbnails, stage status chips, restart-from-stage / cancel / delete actions, GLB (and texture-pack) download - [ ] Transloco i18n from day one (en + es — see the pain in #288/#289/#296); Storybook stories + specs per repo convention **Note:** the existing `trellis-3d-generator` route should redirect into the studio (or be absorbed) once parity is reached — decide here, don't leave two 3D entry points. **Acceptance:** a student submits a prompt, watches stages advance live with queue position shown, orbits the textured model, toggles the skeleton, plays the walk preset, and downloads the GLB — all in both languages; another student's assets are never visible.
spikerj added the enhancement label 2026-07-04 05:11:28 +00:00
Author
Owner

Frontend direction from Joey (2026-07-04): Angular-native composable components — no monolithic page. The studio lives under the Tools section alongside the other dev tools, built as a series of small standalone components in the spirit of ProArt's own decomposition (asset types → stage pipeline → per-stage artifacts → library), composed by a thin shell:

  • art-prompt-composer — asset type + prompt/drawing submission
  • art-stage-timeline — the pipeline as a visible, honest sequence (queue position, per-stage state) — the educational spine of the UI
  • art-asset-viewer — three.js GLB orbit view; skeleton toggle + clip playback arrive with P4 stages
  • art-artifact-panel — per-stage outputs (concept image, texture maps, previews)
  • art-asset-card / art-asset-library — my-assets grid with status chips + actions
  • art-studio-shell — routed page composing the above; each piece independently reusable (e.g. the viewer alone can be embedded in gallery #353 or game playgrounds)

Each component standalone, signals-based, individually exportable from @spikersoft/feature-art-studio so P7 (gallery, games handoff) and the playground shell can reuse them without dragging in the whole studio.

Implementation starting against the PR spikersoft-backend#61 API contract; live progress remains polling-abstracted until #349's SignalR events exist.

Frontend direction from Joey (2026-07-04): **Angular-native composable components** — no monolithic page. The studio lives **under the Tools section** alongside the other dev tools, built as a series of small standalone components in the spirit of ProArt's own decomposition (asset types → stage pipeline → per-stage artifacts → library), composed by a thin shell: - `art-prompt-composer` — asset type + prompt/drawing submission - `art-stage-timeline` — the pipeline as a visible, honest sequence (queue position, per-stage state) — the educational spine of the UI - `art-asset-viewer` — three.js GLB orbit view; skeleton toggle + clip playback arrive with P4 stages - `art-artifact-panel` — per-stage outputs (concept image, texture maps, previews) - `art-asset-card` / `art-asset-library` — my-assets grid with status chips + actions - `art-studio-shell` — routed page composing the above; each piece independently reusable (e.g. the viewer alone can be embedded in gallery #353 or game playgrounds) Each component standalone, signals-based, individually exportable from `@spikersoft/feature-art-studio` so P7 (gallery, games handoff) and the playground shell can reuse them without dragging in the whole studio. Implementation starting against the PR [spikersoft-backend#61](https://git.spikersoft.com/spikerj/spikersoft-backend/pulls/61) API contract; live progress remains polling-abstracted until #349's SignalR events exist.
Author
Owner

First slice up: spikersoft-angular PR #112 — the full composable component set (art-prompt-composer, art-stage-timeline, art-asset-viewer, art-artifact-panel, art-asset-card/art-asset-library, art-studio-shell), registered under /tools (tools outlet + tools-shell entry, palette icon), signals service against the merged P1 API, polling progress behind the ART_ASSET_PROGRESS_SOURCE token for #349's SignalR swap, en+es i18n. Locally verified: lib build/lint, 21/21 vitest, full app dev build.

Ticket stays open for the later slices: SignalR source (#349), viewer skeleton/animation modes (needs P4 stages), quota display (needs #352), real thumbnails, delete confirmation.

First slice up: spikersoft-angular PR [#112](https://git.spikersoft.com/spikerj/spikersoft-angular/pulls/112) — the full composable component set (`art-prompt-composer`, `art-stage-timeline`, `art-asset-viewer`, `art-artifact-panel`, `art-asset-card`/`art-asset-library`, `art-studio-shell`), registered under `/tools` (tools outlet + tools-shell entry, palette icon), signals service against the merged P1 API, polling progress behind the `ART_ASSET_PROGRESS_SOURCE` token for #349's SignalR swap, en+es i18n. Locally verified: lib build/lint, 21/21 vitest, full app dev build. Ticket stays open for the later slices: SignalR source (#349), viewer skeleton/animation modes (needs P4 stages), quota display (needs #352), real thumbnails, delete confirmation.
Author
Owner

SignalR live-progress slice up for merge: backend PR #63 (worker publishes art.asset.stage.*/asset lifecycle events; API relay to NotificationsHub group user-{owner}, mirroring the existing Trellis3D mechanism) + Angular PR #113 (SignalRArtAssetProgressSource behind the existing token, automatic polling fallback, zero component changes). 157/157 backend + 28/28 frontend tests locally.

Deferred with rationale: queue-position — the GpuCoordinator lease AcquireAsync blocks with no queue index exposed, so honest queue position needs the coordinator to emit it; suggest a small follow-up ticket on GpuCoordinator rather than faking it worker-side. The timeline's queuePosition input stays plumbed and unfed until then.

SignalR live-progress slice up for merge: backend PR [#63](https://git.spikersoft.com/spikerj/spikersoft-backend/pulls/63) (worker publishes `art.asset.stage.*`/asset lifecycle events; API relay to `NotificationsHub` group `user-{owner}`, mirroring the existing Trellis3D mechanism) + Angular PR [#113](https://git.spikersoft.com/spikerj/spikersoft-angular/pulls/113) (`SignalRArtAssetProgressSource` behind the existing token, automatic polling fallback, zero component changes). 157/157 backend + 28/28 frontend tests locally. Deferred with rationale: **queue-position** — the GpuCoordinator lease `AcquireAsync` blocks with no queue index exposed, so honest queue position needs the coordinator to emit it; suggest a small follow-up ticket on GpuCoordinator rather than faking it worker-side. The timeline's `queuePosition` input stays plumbed and unfed until then.
Author
Owner

All three delivery PRs are merged to master: #112 (composable component set under Tools + polling progress), #113 (SignalR progress source with fallback), #115 (viewer skeleton overlay + animation playback, verified against real P4 rigged/animated GLBs). Acceptance is met end-to-end on the local stack: submit → live stage updates → orbit the textured model → toggle skeleton → play the walk clip → download the GLB, en+es throughout, ownership enforced.

Remaining polish (queue position — blocked on a GpuCoordinator emit, card thumbnails, delete confirm) is split out to the follow-up ticket just filed so this phase ticket can reflect reality. Closing.

All three delivery PRs are merged to `master`: #112 (composable component set under Tools + polling progress), #113 (SignalR progress source with fallback), #115 (viewer skeleton overlay + animation playback, verified against real P4 rigged/animated GLBs). Acceptance is met end-to-end on the local stack: submit → live stage updates → orbit the textured model → toggle skeleton → play the walk clip → download the GLB, en+es throughout, ownership enforced. Remaining polish (queue position — blocked on a GpuCoordinator emit, card thumbnails, delete confirm) is split out to the follow-up ticket just filed so this phase ticket can reflect reality. Closing.
Sign in to join this conversation.