fix(search): make the sidebar People tab actually query /users/search (LC-392) #404

Merged
longjacksonle merged 1 commit from fix/lc-392-people-search into main 2026-06-20 06:41:45 +02:00

Fixes LC-392. The sidebar search "People" tab returned nothing - typing a name surfaced no users.

Root cause

The LC-369 search input is server-rendered with hx-get="/search" (messages). The People tab switch did input.setAttribute('hx-get', '/users/search'). But htmx resolves an element's request verb + path once, at process time, and binds them into the trigger-handler closure - it does not re-read hx-get on each fire (the attribute name is even built dynamically as "hx-"+verb, so the literal never appears in the source). So mutating the attribute had no effect on the input's own debounced input / focus / Enter triggers: they kept issuing GET /search. The tab handler's immediate htmx.ajax('GET', '/users/search', ...) used the explicit path, so it only flickered people results before the next keystroke reverted to messages.

Backend was fine: /users/search -> users::get_user_search -> db::auth::search_users works, and is_profile_public defaults to 1, so public profiles are findable.

Fix

Track the active mode and rewrite the request path in an htmx:configRequest listener (fires before every htmx request, exposes detail.path + detail.elt, and takes effect regardless of the captured path), scoped to #sidebar-search-input so other /search callers (room-scoped search, etc.) are untouched. The placeholder/aria swap and the immediate re-fire are unchanged.

Testing

  • ./dev/cargo check clean.
  • just check, just test, just test-saas all green (exit 0, zero failures).
  • The fix is in the sidebar's inline JS (htmx request pipeline), which the integration suites don't exercise; validation is the compile + the manual flow: People tab + type -> matching users listed (each links to their DM); switching tabs re-queries the right backend with no flicker; Messages tab unaffected.

No operator-visible change (UI only): no [operator-action] marker.

Fixes LC-392. The sidebar search "People" tab returned nothing - typing a name surfaced no users. ## Root cause The LC-369 search input is server-rendered with `hx-get="/search"` (messages). The People tab switch did `input.setAttribute('hx-get', '/users/search')`. But htmx resolves an element's request **verb + path once, at process time**, and binds them into the trigger-handler closure - it does not re-read `hx-get` on each fire (the attribute name is even built dynamically as `"hx-"+verb`, so the literal never appears in the source). So mutating the attribute had no effect on the input's own debounced `input` / `focus` / Enter triggers: they kept issuing `GET /search`. The tab handler's immediate `htmx.ajax('GET', '/users/search', ...)` used the explicit path, so it only flickered people results before the next keystroke reverted to messages. Backend was fine: `/users/search` -> `users::get_user_search` -> `db::auth::search_users` works, and `is_profile_public` defaults to 1, so public profiles are findable. ## Fix Track the active mode and rewrite the request path in an `htmx:configRequest` listener (fires before every htmx request, exposes `detail.path` + `detail.elt`, and takes effect regardless of the captured path), scoped to `#sidebar-search-input` so other `/search` callers (room-scoped search, etc.) are untouched. The placeholder/aria swap and the immediate re-fire are unchanged. ## Testing - `./dev/cargo check` clean. - `just check`, `just test`, `just test-saas` all green (exit 0, zero failures). - The fix is in the sidebar's inline JS (htmx request pipeline), which the integration suites don't exercise; validation is the compile + the manual flow: People tab + type -> matching users listed (each links to their DM); switching tabs re-queries the right backend with no flicker; Messages tab unaffected. No operator-visible change (UI only): no `[operator-action]` marker.
fix(search): make the sidebar People tab actually query /users/search (LC-392)
All checks were successful
check-secrets / Nosey parker (pull_request) Successful in 5s
check-secrets / Kingfisher (pull_request) Successful in 5s
Create release / Create release from merged PR (pull_request) Has been skipped
check-secrets / TruffleHog (push) Successful in 4s
check-secrets / Nosey parker (push) Successful in 4s
check-secrets / Kingfisher (push) Successful in 5s
check-secrets / TruffleHog (pull_request) Successful in 4s
Check / clippy + fmt + tests (pull_request) Successful in 2m59s
db65327efb
htmx resolves an element's request verb+path once at process time and binds them into the trigger closure; it does not re-read hx-get per fire. The LC-369 tab switch did input.setAttribute('hx-get', '/users/search'), which therefore never redirected the input's own debounced input/focus/Enter triggers - they kept hitting /search, so People search returned message results (or nothing) and looked dead. The immediate htmx.ajax fire used the explicit path, so it only flickered.

Track the active mode and rewrite the request path in an htmx:configRequest listener (fires before every request, takes effect regardless of the captured path), scoped to #sidebar-search-input so other /search callers are untouched. The placeholder/aria swap and immediate re-fire are unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
longjacksonle deleted branch fix/lc-392-people-search 2026-06-20 06:41:45 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/lets-chat!404
No description provided.