wulf-pulse/.planning/phases/04-tickets-restyle/04-DISCUSSION-LOG.md
lorentz 9658640c04 fix(04-01): restore phase 2/3 work lost by worktree soft-reset
The soft reset to 77073ba inadvertently staged deletions of all phase 2
and 3 artifacts. This commit restores them from their source commits so
subsequent task commits build on the complete prior-phase foundation:
- components/mobile/{BottomNav,HeaderBar,KpiCardMobile,MoreDrawer,NeedsAttentionStrip,WorkerStatusRow}
- app/mobile/layout.tsx, dashboard/page.tsx, analyzer/page.tsx
- app/api/mobile/dashboard/route.ts
- All .planning/** files from phases 01-04
- CLAUDE.md, app/layout.tsx, app/styles/brand.css, public/manifest.json
2026-05-03 18:01:14 -04:00

4.6 KiB

Phase 4: Tickets Restyle - Discussion Log

Audit trail only. Do not use as input to planning, research, or execution agents. Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.

Date: 2026-05-03 Phase: 04-tickets-restyle Mode: auto (--auto --chain) Areas discussed: Filter strip, URL sync, Pagination model, Infinite scroll trigger, List row presentation, Detail page header, Empty/loading states


Filter strip

Option Description Selected
Always-expanded inline filters All controls visible by default — more taps reachable
Collapsible from shadcn, default collapsed TICK-01 spec; phone-first density
Drawer-based filter sheet Filters open in a Sheet — feels heavier, more taps

Auto choice rationale: TICK-01 explicitly says "default collapsed". Spec-locked.


Filter set

Option Description Selected
Status + priority + queue + assigned-to-me Spec set
Add company filter More flexibility; out of TICK-* scope
Add date range Could be useful; out of TICK-* scope

Auto choice rationale: TICK-01 enumerates the four filters. Anything more is scope creep.


URL sync mechanism

Option Description Selected
router.push() on every filter change Each filter tweak adds a back-stack entry
router.replace() on every filter change Filter tweaks don't pollute back stack
Manual history.replaceState() Lower-level; loses Next.js rerouting integration

Auto choice rationale: router.replace() is the App Router idiom for filter UIs. Back button should return to whatever surface the user came from, not 8 filter mutations ago.


Pagination model

Option Description Selected
Keep page-based ?page=N&limit=30 Simpler, current behavior
Cursor ?cursor=&limit=25 with last_activity_date+id Stable under writes; matches triage workflow
Cursor on created_date+id Stable but doesn't reflect "recent activity" priority

Auto choice rationale: TICK-05 mandates cursor-based ~25/page. Choosing last_activity_date DESC, id DESC because managers triage by "what just changed" not "what was created".


Infinite scroll trigger

Option Description Selected
react-intersection-observer library Hook abstraction, extra dep
Browser-native IntersectionObserver No dep, ~20 lines
Scroll-event listener with throttle Less precise, more re-renders

Auto choice rationale: CLAUDE.md prohibits adding new state libraries; native IntersectionObserver is sufficient.


"Load more" fallback

Option Description Selected
Skip — sentinel handles it Fails accessibility
Always-rendered focusable button below sentinel TICK-06 mandates accessibility
Show only when keyboard navigation detected Brittle, not robust

Auto choice rationale: TICK-06 requires the fallback button. Always-rendered keeps it focusable and visible to screen readers.


List row priority indicator

Option Description Selected
Existing dot (bg-color-N) Smaller, less prominent
Left-edge stripe via border-l-4 TICK-03 spec
Background tint of whole row Too heavy on phone

Auto choice rationale: TICK-03 explicitly specifies left-edge stripe.


Detail page header

Option Description Selected
Refactor full detail page Out of scope per TICK-07
Reskin in-page header only (back chevron + breadcrumb + ext link) TICK-07 spec

Auto choice rationale: TICK-07 explicitly says "header reskinned... body kept largely as-is".


Empty/loading states

Option Description Selected
Spinner only on load Janky, no skeleton
Skeleton rows initial + inline spinner subsequent + empty-state messages Polished, fits design tokens

Auto choice rationale: Standard mobile pattern; existing Skeleton shadcn primitive available.


Auto-resolved scope creep checks

  • Bulk actions — flagged and deferred (read-tap-detail is the manager workflow)
  • Saved presets — deferred to a future phase
  • Detail body refactor — explicitly excluded by TICK-07

External research

None. Decisions were derivable from spec + existing code patterns.