You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Bundled because both touch the same partial and controller, and shipping the format change without coordinating with #370 would leave admin and public on different taxonomies.
Change 1 — Min/Max price range
Today: a single <input type="number" name="min_value"> (app/views/admin/records/_filter_bar.html.erb:36-42), interpreted source-aware in the controller (app/controllers/admin/records_controller.rb:69-77). Both fields optional, default empty — same as today's Min $.
Recommendation: two adjacent number inputs (Min $ / Max $)
Simplest, most predictable, most accessible. Sliders look slicker but are wrong for this dataset:
Price distribution is heavily long-tailed ($0 to $5k+); a linear slider is unusable and a log slider is unintuitive for collectors entering specific thresholds.
A slider needs a known max, which forces an extra query per render.
The collector use-case is "show me $100–$500 records" — they want exact thresholds, not scrubbing.
Two number inputs are a one-line addition next to the existing Min $; no new JS.
UI sketch (replaces current Min $ block in the source row)
Source [Best Guide My$ Discogs] Price \$[ Min ] – \$[ Max ] Show [All ▾]
Existing debounce/auto-submit behavior carries over (data-controller=\"debounce\").
Alternatives considered
Option
Pros
Cons
Dual number inputs (recommended)
matches today's UX, no extra queries, a11y free
least visual flair
Range slider (noUiSlider etc.)
scrubbable, visual
bad fit for long-tailed prices; needs a ceiling query; new JS dep
Preset buckets ($0–10, $10–50, …)
one click
hides the long tail; collectors want exact thresholds
Single "100-500" combined input
compact
error-prone parsing; not standard
Implementation notes
Add params[:max_value], applied source-aware mirroring the existing Min block (<= ?) in Admin::RecordsController#index lines 69–77.
Add :max_value to the Clear filters slice list (_filter_bar.html.erb:123).
CSV export inherits the filter automatically (same scope).
Change 2 — Replace bespoke format buckets with RecordType
Today: Admin::RecordsController::FORMAT_CATEGORY_MAP (lines 12–46) hand-buckets ~30 raw record_formats.name strings into 7 collector-facing categories (LP, 7", 12" Single, 10", 78, Picture Disc / Sleeve, Promo). This:
duplicates work the schema already does — record_formats.record_type_id → record_types, and Record has_one :record_type, through: :record_format already exists (app/models/record.rb:48)
silently absorbs typo variants (e.g. Singles: 7-inch vs Singles: 7-Inch) instead of surfacing the data-quality issue
requires manual updates whenever a new raw format string appears in production data
Recommendation
Mirror #370 Phase 1 here: drop FORMAT_CATEGORY_MAP, use record_types directly in the dropdown, filter via record_format.record_type_id. Same 5 buckets the public page will use; one source of truth.
If/when #370 Phase 2 (cascading Format sub-facet under a selected Type) ships on /records, the admin page should follow with the same component.
Implementation notes
load_filter_options (lines 263–288): replace the raw_formats + category_counts block with a RecordType.joins(record_formats: :records).where(records: { user_id: COLLECTION_USER_ID }).group(\"record_types.name\") query.
index (lines 95–99): replace the FORMAT_CATEGORY_MAP.select { ... } lookup with where(record_formats: { record_type_id: ... }).
Rename param format_category → record_type_id (no external links rely on it).
Delete the FORMAT_CATEGORY_MAP constant.
Audit CSV export and any view code for stale references to the bucket name (none expected — bucket name was display-only).
Context
The admin Value Explorer at
/admin/recordshas two filter controls inapp/views/admin/records/_filter_bar.html.erbthat need work:FORMAT_CATEGORY_MAPconstant inAdmin::RecordsControllerinstead of the realrecord_typestable that Records index: replace granular Format filter with Record Type (with later format sub-facet) #370 is migrating/recordstoward.Bundled because both touch the same partial and controller, and shipping the format change without coordinating with #370 would leave admin and public on different taxonomies.
Change 1 — Min/Max price range
Today: a single
<input type="number" name="min_value">(app/views/admin/records/_filter_bar.html.erb:36-42), interpreted source-aware in the controller (app/controllers/admin/records_controller.rb:69-77). Both fields optional, default empty — same as today's Min $.Recommendation: two adjacent number inputs (Min $ / Max $)
Simplest, most predictable, most accessible. Sliders look slicker but are wrong for this dataset:
UI sketch (replaces current Min $ block in the source row)
Existing debounce/auto-submit behavior carries over (
data-controller=\"debounce\").Alternatives considered
Implementation notes
params[:max_value], applied source-aware mirroring the existing Min block (<= ?) inAdmin::RecordsController#indexlines 69–77.:max_valueto the Clear filters slice list (_filter_bar.html.erb:123).Change 2 — Replace bespoke format buckets with RecordType
Today:
Admin::RecordsController::FORMAT_CATEGORY_MAP(lines 12–46) hand-buckets ~30 rawrecord_formats.namestrings into 7 collector-facing categories (LP, 7", 12" Single, 10", 78, Picture Disc / Sleeve, Promo). This:record_formats.record_type_id → record_types, andRecord has_one :record_type, through: :record_formatalready exists (app/models/record.rb:48)/records(public), which is being migrated torecord_typesin Records index: replace granular Format filter with Record Type (with later format sub-facet) #370Singles: 7-inchvsSingles: 7-Inch) instead of surfacing the data-quality issueRecommendation
Mirror #370 Phase 1 here: drop
FORMAT_CATEGORY_MAP, userecord_typesdirectly in the dropdown, filter viarecord_format.record_type_id. Same 5 buckets the public page will use; one source of truth.If/when #370 Phase 2 (cascading Format sub-facet under a selected Type) ships on
/records, the admin page should follow with the same component.Implementation notes
load_filter_options(lines 263–288): replace theraw_formats+category_countsblock with aRecordType.joins(record_formats: :records).where(records: { user_id: COLLECTION_USER_ID }).group(\"record_types.name\")query.index(lines 95–99): replace theFORMAT_CATEGORY_MAP.select { ... }lookup withwhere(record_formats: { record_type_id: ... }).format_category→record_type_id(no external links rely on it).FORMAT_CATEGORY_MAPconstant.Out of scope
show.html.erbusesRecordFormat.order(:name)for the granular editor, which is correct)./recordsindex — covered by Records index: replace granular Format filter with Record Type (with later format sub-facet) #370.References
/records. Admin should land after or alongside Phase 1 there to keep taxonomies aligned.