Skip to content

Send filters as AssetSelection queries, chunk id-based bulk calls - #6

Merged
ergofobe merged 1 commit into
mainfrom
fix/selection-semantics-and-id-chunking
Aug 28, 2026
Merged

Send filters as AssetSelection queries, chunk id-based bulk calls#6
ergofobe merged 1 commit into
mainfrom
fix/selection-semantics-and-id-chunking

Conversation

@ergofobe

Copy link
Copy Markdown
Owner

Audit

Read through src/commands/assets.rs, src/commands/albums.rs, src/commands/upload.rs, src/context.rs, and src/tui/ against imogen-sdk at 914e6a9 (AssetSelection { asset_ids, query, except }, server cap of 1000 ids / 10,000 except).

Confirmed the reported bug on current main, plus one the audit turned up:

  • assets::trash (main@4ed2aa6 src/commands/assets.rs:587-609) — given a --query-style filter, ctx.select() walked every matching page client-side via matching(), collected the ids, then sent them as a single AssetSelection::ids(&targets) call. Two problems: it enumerated instead of sending the filter as AssetSelection { query }, and the single call was never chunked, so trashing more than 1000 matches would 400 against the server's .max(1000).
  • assets::restore (src/commands/assets.rs:623-653) — same shape: walked all trashed assets via matching(), sent one unchunked AssetSelection::ids(&targets) call.
  • albums::add (src/commands/albums.rs:202-221) — also resolved a --query filter to ids via ctx.select() instead of sending it as a selection query. It was already chunking at 500 (ids.chunks(500)), so no cap bug there, just the unnecessary enumeration.
  • albums::remove (src/commands/albums.rs:244-259) — explicit ids only (no --query at the CLI level), but AssetSelection::ids(assets) was sent as one unchunked call — the same 1000-cap bug as trash/restore.
  • upload.rs and the TUI (src/tui/mod.rs) were already correct: upload.rs's post-upload album fill chunks at 500 (chunks(500)), and the TUI's trash/restore only ever act on a single selected photograph (vec![id]), so no chunking was needed there.
  • assets::edit enumerates client-side by necessity — there is no bulk-edit AssetSelection-based SDK endpoint, only per-asset PATCH, so this one is inherent to the API surface and was left unchanged.

Changes

  • Context::to_filter (src/context.rs) — new helper building an AssetFilter from QueryArgs, alongside a Context::count helper that resolves a filter's match count from the timeline's day buckets (one request, no page walk — the same technique the TUI already uses for its header count). Context::to_query now builds on to_filter rather than duplicating every field.
  • assets::trash / assets::restore — explicit ids are chunked at 500 and sent as AssetSelection::ids; a filter is resolved to a count for the confirmation prompt (Move 12,431 photographs to the trash?, never "all photos") and sent as AssetSelection { query: Some(filter) } in a single request, sidestepping the per-id cap entirely.
  • albums::add — same split: explicit --asset ids chunked at 500 as before; a --query filter now goes through as AssetSelection { query } after a cheap count check for "Nothing matched."
  • albums::remove — chunked at 500, closing the cap bug.

-y/--yes behavior is unchanged: it skips the prompt but the resolved count still prints in the final summary either way.

Verification

  • cargo fmt --check
  • cargo build --all-targets
  • cargo clippy --all-targets -- -D warnings
  • cargo test — 103 passed, 2 ignored (pre-existing, marked "for looking at, not for CI")

Tracking issues filed (not implemented here)

Co-Authored-By: Claude with claude-sonnet-5

trash/restore and album add enumerated every matching asset client-side
even when given a filter, then shipped the whole id list in one request
— silently broken past the server's 1000-id cap, and one round trip per
page of the library for a resolved-count confirmation prompt that didn't
need the assets themselves. They now send the filter straight through as
AssetSelection { query }, resolving just the count (from the timeline's
day buckets) to show in the prompt. Explicit id lists — the only case
that actually needs assetIds on the wire — are chunked at 500 for trash,
restore, and album add/remove, matching the chunking already used by
album add and upload's post-upload album fill.

Co-Authored-By: Claude with claude-sonnet-5
@ergofobe
ergofobe merged commit 194cbe3 into main Aug 28, 2026
2 checks passed
@ergofobe
ergofobe deleted the fix/selection-semantics-and-id-chunking branch August 28, 2026 14:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant