feat(dashboard): add custom cover image for workflow cards#5704
feat(dashboard): add custom cover image for workflow cards#5704Ma77Ball wants to merge 11 commits into
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #5704 +/- ##
============================================
- Coverage 55.25% 55.23% -0.02%
- Complexity 2993 3001 +8
============================================
Files 1117 1118 +1
Lines 43195 43306 +111
Branches 4657 4670 +13
============================================
+ Hits 23866 23921 +55
- Misses 17930 17982 +52
- Partials 1399 1403 +4
*This pull request uses carry forward flags. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
| config | throughput | MB/s | latency | max Δ latest / 7d | |
|---|---|---|---|---|---|
| 🔴 | bs=10 sw=10 sl=64 | 380 | 0.232 | 25,834/42,442/42,442 us | 🔴 +20.7% / 🔴 +172.5% |
| 🟢 | bs=100 sw=10 sl=64 | 810 | 0.494 | 122,425/140,173/140,173 us | 🟢 -5.4% / 🔴 +27.9% |
| ⚪ | bs=1000 sw=10 sl=64 | 925 | 0.565 | 1,081,833/1,127,587/1,127,587 us | ⚪ within ±5% / 🔴 +7.3% |
Baseline details
Latest main 7944c09 from same runner
| config | metric | PR | latest main | 7d avg | Δ latest | Δ 7d |
|---|---|---|---|---|---|---|
| bs=10 sw=10 sl=64 | throughput | 380 tuples/sec | 417 tuples/sec | 758.88 tuples/sec | -8.9% | -49.9% |
| bs=10 sw=10 sl=64 | MB/s | 0.232 MB/s | 0.254 MB/s | 0.463 MB/s | -8.7% | -49.9% |
| bs=10 sw=10 sl=64 | p50 | 25,834 us | 23,024 us | 12,965 us | +12.2% | +99.3% |
| bs=10 sw=10 sl=64 | p95 | 42,442 us | 35,153 us | 15,578 us | +20.7% | +172.5% |
| bs=10 sw=10 sl=64 | p99 | 42,442 us | 35,153 us | 18,378 us | +20.7% | +130.9% |
| bs=100 sw=10 sl=64 | throughput | 810 tuples/sec | 823 tuples/sec | 968.9 tuples/sec | -1.6% | -16.4% |
| bs=100 sw=10 sl=64 | MB/s | 0.494 MB/s | 0.502 MB/s | 0.591 MB/s | -1.6% | -16.5% |
| bs=100 sw=10 sl=64 | p50 | 122,425 us | 119,548 us | 102,767 us | +2.4% | +19.1% |
| bs=100 sw=10 sl=64 | p95 | 140,173 us | 148,140 us | 109,629 us | -5.4% | +27.9% |
| bs=100 sw=10 sl=64 | p99 | 140,173 us | 148,140 us | 118,129 us | -5.4% | +18.7% |
| bs=1000 sw=10 sl=64 | throughput | 925 tuples/sec | 920 tuples/sec | 997.01 tuples/sec | +0.5% | -7.2% |
| bs=1000 sw=10 sl=64 | MB/s | 0.565 MB/s | 0.561 MB/s | 0.609 MB/s | +0.7% | -7.2% |
| bs=1000 sw=10 sl=64 | p50 | 1,081,833 us | 1,083,953 us | 1,009,306 us | -0.2% | +7.2% |
| bs=1000 sw=10 sl=64 | p95 | 1,127,587 us | 1,133,734 us | 1,051,088 us | -0.5% | +7.3% |
| bs=1000 sw=10 sl=64 | p99 | 1,127,587 us | 1,133,734 us | 1,082,535 us | -0.5% | +4.2% |
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,525.89,200,128000,380,0.232,25834.07,42441.74,42441.74
1,100,10,64,20,2468.85,2000,1280000,810,0.494,122424.88,140172.86,140172.86
2,1000,10,64,20,21620.29,20000,12800000,925,0.565,1081833.32,1127587.30,1127587.30|
/request-review @xuang7 @aglinxinyuan |
There was a problem hiding this comment.
Pull request overview
This PR adds support for optional, per-workflow custom cover images on the dashboard workflow cards, persisted on the backend so the cover syncs across sessions/browsers for users with access.
Changes:
- Adds a new
workflow_cover_imagetable plus Liquibase migration entry. - Adds
GET/PUT/DELETE /workflow/{wid}/coverendpoints with access gating and basic validation. - Adds a frontend
WorkflowCoverService(downscale + JPEG re-encode) and workflow-card UI controls (upload/reset) with unit tests.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| sql/updates/25.sql | Adds migration to create workflow_cover_image. |
| sql/texera_ddl.sql | Adds workflow_cover_image to the base schema DDL. |
| sql/changelog.xml | Registers Liquibase changeSet 25. |
| amber/src/main/scala/.../WorkflowResource.scala | Implements cover CRUD endpoints and validation. |
| amber/src/test/scala/.../WorkflowResourceCoverSpec.scala | Adds backend regression tests for cover endpoints and authorization/validation. |
| frontend/src/app/dashboard/service/user/workflow-cover/workflow-cover.service.ts | Adds frontend service to fetch/set/clear cover images and resize uploads. |
| frontend/src/app/dashboard/service/user/workflow-cover/workflow-cover.service.spec.ts | Adds unit tests for the new cover service. |
| frontend/src/app/dashboard/component/.../card-item.component.ts | Loads cover on init; adds upload/reset handlers and edit gating. |
| frontend/src/app/dashboard/component/.../card-item.component.html | Adds cover controls (camera/reset) and hidden file input. |
| frontend/src/app/dashboard/component/.../card-item.component.scss | Styles hover-revealed cover controls. |
| frontend/src/app/dashboard/component/.../card-item.component.spec.ts | Adds component tests for cover behaviors and gating. |
| common/workflow-operator/src/test/.../ImageTaskCodegenSpec.scala | Adds HuggingFace image codegen tests (appears unrelated to the dashboard cover feature). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
/request-review @aglinxinyuan |
Automated Reviewer SuggestionsBased on the
|
|
@xuang7 and @aglinxinyuan, please review the changes and let me know if they look good. |
There was a problem hiding this comment.
A couple of things before this goes in:
- Per-card cover fetch (N+1) — flagged inline on
card-item.component.ts. This is the main one. - PR description vs. diff — the description says the branch also bundles a
hugging-face-image-uploadcomponent and theHuggingFace.pngasset, but the diff only containsImageTaskCodegenSpec.scala(the other two appear to already be on main). Could you either split that unrelated HF test into its own PR, or at minimum update the description so it matches the 12 files actually changed?
The rest are inline nits — non-blocking.
043f8e8 to
5144a5d
Compare
|
Please resolve the conflicts, and we can merge. |
912a58f to
1880e39
Compare
1880e39 to
00480c7
Compare
What changes were proposed in this PR?
Workflow card cover image
workflow_cover_image(wid, image)table (cover stored as a downscaled JPEG data URL, FK toworkflowwithON DELETE CASCADE) intexera_ddl.sqlplus asql/updates/25.sqlmigration.GET/PUT/DELETE /workflow/{wid}/coverendpoints onWorkflowResource: read access to fetch (404 when unset), write access to set/delete. Set validation rejects null/blank bodies and enforces a size limit plus a base64 raster MIME allowlist (PNG/JPEG/GIF/WebP; SVG and non-base64 forms rejected to limit stored-XSS surface).WorkflowCoverService(frontend) that downscales/re-encodes the chosen file to a small JPEG data URL before upload, fetches the cover, and clears it.previewImagenow prefers the stored cover. Controls are keyboard-accessible (aria-label,type="button", revealed on:focus-within).HuggingFace image-upload operator
hugging-face-image-uploadfrontend component, theHuggingFace.pngoperator asset, andImageTaskCodegenSpeccovering the image-task codegen.Any related issues, documentation, discussions?
Closes: #5703
How was this PR tested?
WorkflowResourceCoverSpec(uses theMockTexeraDBembedded-Postgres harness) covers all three cover endpoints: 404 when unset, set/get round-trip, read by a user with read access, upsert replace, data-URL/blank/null/size validation rejections, read- and write-access gating, no-persist on validation failure, and idempotent delete. Runsbt "WorkflowExecutionService/testOnly *WorkflowResourceCoverSpec".WorkflowCoverServicespec covers GET mapping the image, 404 resolving to undefined, DELETE being issued, andsetCoverFromFilePUTting the resized data URL. Runcd frontend && yarn test --include='**/workflow-cover.service.spec.ts' --watch=false.CardItemComponentspec covers the cover behaviors (owner-in-private-search gating, cover load on init, default-image fallback, upload success / non-image rejection / upload failure, reset success / failure). Runcd frontend && yarn test --include='**/card-item.component.spec.ts' --watch=false.Was this PR authored or co-authored using generative AI tooling?
Co-authored with Claude Opus 4.8 in compliance with ASF