Skip to content

fix(api): server-side column filters for transactions (rant 2026-08-25T10:33:26) - #146

Merged
argszero merged 1 commit into
mainfrom
fix/tx-column-filters
Aug 25, 2026
Merged

fix(api): server-side column filters for transactions (rant 2026-08-25T10:33:26)#146
argszero merged 1 commit into
mainfrom
fix/tx-column-filters

Conversation

@argszero

Copy link
Copy Markdown
Owner

Summary

Fix the transactions-page column filters so they apply to the full dataset server-side instead of only the currently loaded page. This was a regression introduced by the backend pagination refactor (PR #135, v0.7.15): each page only loads page_size rows, so the local filterRows only ever filtered those rows and the remaining thousands of records never entered the scope — filter results were untrustworthy.

Related Issue

Rant 2026-08-25T10:33:26 (verbatim):

交易记录页表格列筛选(类型/模型/用户/Key/状态/点数)只对当前加载页生效,不是全量筛选 —— 后端分页重构后(PR #135)的严重回归:每页只加载 page_size 条(默认 10/25),列筛选只对当前页本地过滤,其余几千条(dev 7000+)永远不在筛选范围,筛选结果不可信。

Changes

  • Backend (src/routes/wallet.rs):
    • New TxColFilters struct (model/user_name/key_name LIKE, status exact on DB values, pts_min/pts_max range), flattened into TxQuery and TxTrendQuery
    • tx_where() applies the column filters via LEFT JOIN users/api_keys/keys; summary, total, list and trend all use the same filtered SQL (consistent counts/summary across the whole set)
    • Type whitelist now also accepts withdraw (the UI column filter offers it; previously it would 400)
  • Frontend (ui/js/app.js):
    • loadTransactions() serializes txTable.filters into both the list and trend requests (user_name/model/key_name/status/pts_min/pts_max; i18n labels reverse-mapped to English type keys / Chinese DB status values)
    • txFilterSig() guard: a filter change now triggers a server reload (previously only page/pageSize changes did)
    • renderTxSummary() always uses the backend summary, which is now filter-aware (local page-only summation removed from the login path)
  • Test: transactions_column_filters — LIKE (model/user_name/key_name), exact (status), range (pts_min/max), combined type+column filters, and trend consistency
  • Cache-bust bumped to 20260824-14

Tests

  • cargo test — 147/147 pass
  • cargo fmt --check — clean
  • cargo clippy — no new warnings
  • node --check ui/js/app.js — OK

Checklist

  • Conventional commit message, branch fix/<description>
  • PR based on main (default branch)
  • New functionality covered by unit tests

…5T10:33:26)
Column filters (type/user/model/key/pts/status) on the transactions page
previously only filtered the currently loaded page locally, making results
untrustworthy across thousands of rows (regression of PR #135 pagination).
- backend: TxColFilters (model/user_name/key_name LIKE, status exact,
pts_min/pts_max range) flattened into TxQuery/TxTrendQuery; tx_where()
applies them joined to users/api_keys/keys; summary/total/trend all use
the same filtered SQL; type whitelist now also accepts withdraw (the UI
column filter offers it)
- frontend: loadTransactions() sends filter params on list + trend
requests; txFilterSig() guard reloads when filters change; renderTxSummary
always uses the now filter-aware backend summary
- test: transactions_column_filters (LIKE/exact/range/combined/trend)
- cache-bust 20260824-14
@argszero
argszero merged commit aab051b into mainAug 25, 2026
1 check passed
@argszero
argszero deleted the fix/tx-column-filters branch August 25, 2026 02:45
argszero added a commit that referenced this pull request Aug 25, 2026
…oses focus (rant 2026-08-25T11:15:16) (#148)
Column-filter inputs on the transactions page lost focus after every
keystroke (regression of PR #146 server-side filters, v0.7.18): the
debounced filter change triggered an async fetch, and the fetch-return
render rebuilt the whole table via innerHTML, destroying the focused
input. Focus-restore ran after the wrong render.
Fix (host-confirmed option B): the header filter row is now rendered
once and survives rebuilds — buildDataTable only rebuilds tbody and the
pager; the input DOM is never destroyed so focus is naturally preserved.
- split thead (sort buttons + filter row) into tableTheadHtml, rendered
only when the container has no <table> yet (values seeded from
state.filters; afterwards the inputs are the DOM source of truth)
- tbody (tableBodyHtml) and pager rebuilt on every render as before
- per-render event binding replaced with one-time container-level
delegation (sort / filter input / pager / page-size / IME), reading
the latest config via container._dt so events survive rebuilds
- IME composition tracked (compositionstart/end + focusout safety):
no table rebuild / no setSelectionRange while composing, refresh
debounced once after compositionend — Chinese IME input is not
interrupted
- focus restore only as fallback when the input is not focused
- cache-bust 20260825-2
Co-authored-by: argszero <argszero@argszerodeMac-mini.local>
Sign up for freeto 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

@argszero