MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-381

6.9 Quick issue search (server-side issue-picker search)

Done
Description

The reusable server-side issue quick-search the pickers need — and the "Search Story" that Stories 1.5 / 2.4.9 / 2.5 defer to in prose but that was never planned (surfaced as finding #98). Today the link/blocker picker loads the 50 newest-created work items and filters client-side, so on a real tenant (the plan tenant has 400+ items) most issues are invisible to search and cannot be linked at all — you cannot pick an older issue as a blocker.

The verified shape (rung 1 — Atlassian docs). Jira’s issue-picker / link control SERVER-searches issues by key + summary as you type (a dedicated, bounded issue-picker read), never a fixed recent window filtered locally. Ours matches: a query-driven read over the 6.1.1 pg_trgm index (ILIKE contains on title + key prefix/exact), workspace-scoped + 6.4-permission-aware (you only find issues you may see), bounded to a page size (finding #57 — never an unbounded fetch), ordered by relevance (exact-key first, then title match).

The fix (closes #98). The link/blocker candidate read composes that quick-search with the existing direction-aware exclusions (self + already-linked for the chosen relationship), and the picker’s Combobox goes query-driven (debounced fetch per keystroke) instead of fetch-newest-50-then-client-filter. Both link surfaces (the 2.4.9 detail panel and the 2.4.10 create modal) ride the same control, so both are fixed at once.

Out of scope (recorded follow-on consumers, each its own future subtask). The cmd-K palette’s "Search" group (1.5’s anticipated consumer) and the /issues quick-find (2.5 ships a scoped contains today) are the SAME read’s other consumers; they are limited-but-functional, not broken like the picker, so they are deliberately NOT built here — they adopt 6.9.1 when those surfaces are next touched (no scope creep onto unbroken UI). No new migration: this rides the index 6.1.1 already shipped.

Verification

  • Pull the Story branch, pnpm install, pnpm prisma migrate dev (reports "No difference detected" — this story adds no schema; it reuses the 6.1.1 pg_trgm index), pnpm db:seed, pnpm dev.
  • pnpm test:coverage — Vitest (real Postgres) over the quick-search read (key + title trgm, permission scope, bound, ordering) and the link-candidate composition (exclusions preserved) ≥ 90% per-file branch/fn/line.
  • The #98 repro, now passing: sign in as zhuyue@motir.co / !QAZ1qaz → open a late-plan issue (e.g. an Epic-6 subtask) → relationships panel → Link issue → set "is blocked by" → type an early-plan issue’s key (e.g. PROD-3) or a title fragment → it appears (it is nowhere near the 50 newest) and links. Before this story the same search returned nothing.
  • Exclusion + permission: the current issue and already-linked issues never appear; an issue in a project the signed-in user cannot access (6.4) does not appear; the create-modal link control searches identically.
  • Scale: with the 400+-item seed the picker search returns matches across the WHOLE tenant (not just recent), bounded to the page size, with no full table scan (the trgm index is used — spot-check with EXPLAIN).
  • pnpm test:e2e --grep link — the picker journey (open → search an old issue → link → it renders in its group).
  • a11y: the link form (kind selector + searching Combobox: empty / typing / no-results / selected) passes the strict axe sweep; fully keyboard-operable; colour via --el-*.