Skip to content

Commit 2fa87bd

Browse files
authored
Merge Add search, filter, sort capabilities and fix N+1 query bug pull request #24 from mjunaidca/012-task-search-filter-sort
feat(tasks): Add search, filter, sort capabilities and fix N+1 query bug
2 parents 8e0dbf1 + a752cfb commit 2fa87bd

21 files changed

Lines changed: 2966 additions & 88 deletions

File tree

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
---
2+
id: 0001
3+
title: task-search-filter-sort-specification
4+
stage: spec
5+
date: 2025-12-10
6+
surface: agent
7+
model: claude-opus-4-5-20251101
8+
feature: 012-task-search-filter-sort
9+
branch: 012-task-search-filter-sort
10+
user: agent-1
11+
command: /sp.specify task-search-filter-sort
12+
labels: [phase-v, performance, n+1-fix, search, filter, sort, api, frontend]
13+
links:
14+
spec: specs/012-task-search-filter-sort/spec.md
15+
ticket: null
16+
adr: null
17+
pr: null
18+
files:
19+
- specs/012-task-search-filter-sort/spec.md
20+
- specs/012-task-search-filter-sort/checklists/requirements.md
21+
tests:
22+
- N/A (spec phase - no tests)
23+
---
24+
25+
## Prompt
26+
27+
User requested implementation of search, filter, and sort capabilities for tasks, including fixing a critical N+1 performance bug (GitHub #14). Key inputs:
28+
- Time budget: 45-60 minutes
29+
- Priority: N+1 fix first (highest impact)
30+
- Existing search bar filters client-side (needs API wiring)
31+
- Sort dropdown is missing (needs new UI)
32+
- Reference: specs/011-phase-v-features-planner/AGENT-1-INSTRUCTIONS.md and agent-1-feature-fields-prd.md
33+
34+
## Response snapshot
35+
36+
Created comprehensive specification with:
37+
- 4 Success Evals (N+1 fix, server-side search, sort/filter correctness, backward compatibility)
38+
- 5 User Stories (P1: performance + search, P2: sorting, P3: tag/due date filters)
39+
- 15 Functional Requirements across backend API, frontend, and type definitions
40+
- 7 measurable Success Criteria
41+
- 5 edge cases with explicit handling
42+
- 6 non-goals to bound scope
43+
- 4 constraints including backward compatibility
44+
45+
Spec-architect validation identified missing Success Evals section (constitutional requirement) - auto-fixed by inserting evals after Problem Statement. Final verdict: READY for planning.
46+
47+
## Outcome
48+
49+
- ✅ Impact: Specification complete and validated by spec-architect
50+
- 🧪 Tests: N/A (spec phase)
51+
- 📁 Files: 2 files created (spec.md, checklists/requirements.md)
52+
- 🔁 Next prompts: /sp.plan task-search-filter-sort
53+
- 🧠 Reflection: Good separation of P1/P2/P3 priorities. N+1 fix is clearly highest impact/lowest risk.
54+
55+
## Evaluation notes (flywheel)
56+
57+
- Failure modes observed: Initial spec missing Success Evals section (constitutional violation)
58+
- Graders run and results (PASS/FAIL): spec-architect validation PASS (after fix)
59+
- Prompt variant (if applicable): standard /sp.specify flow
60+
- Next experiment (smallest change to try): None - proceed to planning
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
---
2+
id: 0002
3+
title: task-search-filter-sort-planning
4+
stage: plan
5+
date: 2025-12-10
6+
surface: agent
7+
model: claude-opus-4-5-20251101
8+
feature: 012-task-search-filter-sort
9+
branch: 012-task-search-filter-sort
10+
user: agent-1
11+
command: /sp.plan task-search-filter-sort
12+
labels: [phase-v, architecture, implementation-plan, api-design, frontend-integration]
13+
links:
14+
spec: specs/012-task-search-filter-sort/spec.md
15+
ticket: null
16+
adr: null
17+
pr: null
18+
files:
19+
- specs/012-task-search-filter-sort/plan.md
20+
tests:
21+
- N/A (plan phase - no implementation yet)
22+
---
23+
24+
## Prompt
25+
26+
Create implementation plan for task-search-filter-sort feature:
27+
- Fix N+1 query bug (51 queries → 2 queries)
28+
- Add search, tags, has_due_date filter parameters
29+
- Add sort_by and sort_order parameters
30+
- Update frontend with debounced search and sort dropdowns
31+
- Remove client-side filtering
32+
33+
## Response snapshot
34+
35+
Created comprehensive 970-line implementation plan covering:
36+
37+
**5 Architecture Decisions (ADRs)**:
38+
- AD-001: selectinload for N+1 fix
39+
- AD-002: PostgreSQL ILIKE for search
40+
- AD-003: Custom CASE for priority sort
41+
- AD-004: NULLSLAST/NULLSFIRST for due dates
42+
- AD-005: 300ms debounce with useDeferredValue
43+
44+
**4 Component Breakdown**:
45+
1. Backend routers/tasks.py (20 min)
46+
2. Frontend types/index.ts (5 min)
47+
3. Frontend lib/api.ts (5 min)
48+
4. Frontend app/tasks/page.tsx (15 min)
49+
50+
**8 Manual Test Cases** with explicit pass/fail criteria
51+
52+
**Performance Targets**:
53+
- 96% query reduction (51 → 2)
54+
- 60%+ response time improvement (500ms → <200ms)
55+
56+
## Outcome
57+
58+
- ✅ Impact: Complete implementation blueprint with code snippets
59+
- 🧪 Tests: 8 manual test cases defined with curl commands
60+
- 📁 Files: 1 plan file (970 lines), 4 files to modify
61+
- 🔁 Next prompts: /sp.tasks task-search-filter-sort
62+
- 🧠 Reflection: Sequential dependency chain clear (backend → types → api → UI)
63+
64+
## Evaluation notes (flywheel)
65+
66+
- Failure modes observed: None - plan generation successful
67+
- Graders run and results (PASS/FAIL): N/A (plan phase)
68+
- Prompt variant (if applicable): Routed to general-purpose agent (engineering work)
69+
- Next experiment (smallest change to try): Proceed to task generation
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
---
2+
id: 0003
3+
title: task-search-filter-sort-implementation
4+
stage: implement
5+
date: 2025-12-10
6+
surface: agent
7+
model: claude-opus-4-5-20251101
8+
feature: 012-task-search-filter-sort
9+
branch: 012-task-search-filter-sort
10+
user: agent-1
11+
command: /sp.implement task-search-filter-sort
12+
labels: [phase-v, n+1-fix, search, filter, sort, backend, frontend, performance]
13+
links:
14+
spec: specs/012-task-search-filter-sort/spec.md
15+
ticket: null
16+
adr: null
17+
pr: null
18+
files:
19+
- packages/api/src/taskflow_api/routers/tasks.py
20+
- web-dashboard/src/types/index.ts
21+
- web-dashboard/src/lib/api.ts
22+
- web-dashboard/src/app/tasks/page.tsx
23+
- specs/012-task-search-filter-sort/tasks.md
24+
tests:
25+
- Backend: 61 tests passed (pytest)
26+
- Frontend: TypeScript build successful (pnpm build)
27+
- Linting: All checks passed (ruff check, ruff format)
28+
---
29+
30+
## Prompt
31+
32+
Implement the task-search-filter-sort feature following the SDD workflow. The mission is to:
33+
1. Fix N+1 query bug (51 queries -> 2 queries for 50 tasks)
34+
2. Add server-side search, filter, and sort capabilities
35+
3. Update frontend to use API-based filtering with debounced search
36+
4. Remove client-side filtering
37+
38+
Time budget: 45-60 minutes
39+
Priority: N+1 fix first (highest impact)
40+
41+
## Response snapshot
42+
43+
Successfully implemented all components following the plan:
44+
45+
**Backend Changes (packages/api/src/taskflow_api/routers/tasks.py)**:
46+
- Added imports: `from sqlalchemy import case` and `from sqlalchemy.orm import selectinload`
47+
- Added new query parameters: `search`, `tags`, `has_due_date`, `sort_by`, `sort_order`
48+
- Fixed N+1 with `selectinload(Task.assignee)` for eager loading
49+
- Implemented search with `Task.title.ilike(f"%{search}%")`
50+
- Implemented tags filter with JSONB contains (AND logic)
51+
- Implemented has_due_date filter
52+
- Implemented dynamic sorting with custom priority order (critical>high>medium>low)
53+
- Due date sorting with nullslast/nullsfirst
54+
- Removed N+1 Python loop for assignee fetching
55+
56+
**Frontend Type Changes (web-dashboard/src/types/index.ts)**:
57+
- Extended `TaskFilterParams` with: search, tags, has_due_date, sort_by, sort_order
58+
59+
**Frontend API Client (web-dashboard/src/lib/api.ts)**:
60+
- Updated `getProjectTasks` to pass all new filter parameters
61+
62+
**Frontend UI (web-dashboard/src/app/tasks/page.tsx)**:
63+
- Added `useDeferredValue` for debounced search (~300ms)
64+
- Added sort state (sortBy, sortOrder)
65+
- Updated useEffect to pass search/sort params to API
66+
- Removed client-side filtering (`filteredTasks` -> `tasks`)
67+
- Added Sort By dropdown (Created, Due Date, Priority, Title)
68+
- Added Sort Order toggle (Ascending, Descending)
69+
70+
## Outcome
71+
72+
- ✅ Impact: N+1 bug fixed (96% query reduction: 51 -> 2), server-side search/filter/sort working
73+
- 🧪 Tests: 61 backend tests pass, frontend builds successfully
74+
- 📁 Files: 5 files modified (1 backend, 3 frontend, 1 task spec)
75+
- 🔁 Next prompts: Manual testing in browser, create PR
76+
- 🧠 Reflection: Clean implementation following plan exactly. Backend selectinload pattern worked as documented in constitution.
77+
78+
## Evaluation notes (flywheel)
79+
80+
- Failure modes observed: None - implementation followed plan successfully
81+
- Graders run and results (PASS/FAIL): pytest PASS (61/61), pnpm build PASS, ruff PASS
82+
- Prompt variant (if applicable): Routed to general-purpose agent (engineering work)
83+
- Next experiment (smallest change to try): Manual browser testing to verify debounce and sort UI
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
---
2+
id: 0004
3+
title: Task Search Filter Sort Commit PR
4+
stage: misc
5+
date: 2025-12-10
6+
surface: agent
7+
model: claude-opus-4-5-20251101
8+
feature: 012-task-search-filter-sort
9+
branch: 012-task-search-filter-sort
10+
user: mjs
11+
command: /sp.git.commit_pr
12+
labels: [git, commit, pr, workflow]
13+
links:
14+
spec: specs/012-task-search-filter-sort/spec.md
15+
ticket: "#14"
16+
adr: null
17+
pr: https://github.com/mjunaidca/taskforce/pull/24
18+
files:
19+
- packages/api/src/taskflow_api/routers/tasks.py
20+
- packages/api/src/taskflow_api/tests/test_tasks.py
21+
- web-dashboard/src/types/index.ts
22+
- web-dashboard/src/lib/api.ts
23+
- web-dashboard/src/app/tasks/page.tsx
24+
- specs/012-task-search-filter-sort/spec.md
25+
- specs/012-task-search-filter-sort/plan.md
26+
- specs/012-task-search-filter-sort/tasks.md
27+
- specs/012-task-search-filter-sort/checklists/requirements.md
28+
- history/prompts/012-task-search-filter-sort/0001-*.md
29+
- history/prompts/012-task-search-filter-sort/0002-*.md
30+
- history/prompts/012-task-search-filter-sort/0003-*.md
31+
tests:
32+
- test_list_tasks_search_by_title
33+
- test_list_tasks_search_empty_results
34+
- test_list_tasks_filter_has_due_date_true
35+
- test_list_tasks_filter_has_due_date_false
36+
- test_list_tasks_sort_by_title_asc
37+
- test_list_tasks_sort_by_title_desc
38+
- test_list_tasks_sort_by_priority_desc
39+
- test_list_tasks_sort_by_priority_asc
40+
- test_list_tasks_sort_by_due_date_asc_nulls_last
41+
- test_list_tasks_sort_by_due_date_desc_nulls_first
42+
- test_list_tasks_combined_search_and_sort
43+
- test_list_tasks_default_sort_unchanged
44+
- test_list_tasks_search_max_length
45+
---
46+
47+
## Prompt
48+
49+
/sp.git.commit_pr - Autonomous Git workflow to commit the feature implementation and create PR
50+
51+
## Response snapshot
52+
53+
Executed autonomous git workflow:
54+
1. Gathered context: On branch 012-task-search-filter-sort with 12 staged files
55+
2. Created commit: `90ed48e` with conventional commit message
56+
3. Pushed branch to origin with upstream tracking
57+
4. Created PR #24 to main branch
58+
59+
Commit: `feat(tasks): add search, filter, sort capabilities and fix N+1 query bug`
60+
61+
PR: https://github.com/mjunaidca/taskforce/pull/24
62+
63+
## Outcome
64+
65+
- Impact: Feature complete with N+1 fix, search/filter/sort, 15 new tests
66+
- Tests: 74 passed, 3 skipped (PostgreSQL-only)
67+
- Files: 12 files changed, 2410 insertions(+), 36 deletions(-)
68+
- Next prompts: Merge PR after review, deploy to staging
69+
- Reflection: Autonomous git workflow executed smoothly, all changes committed and PR created
70+
71+
## Evaluation notes (flywheel)
72+
73+
- Failure modes observed: None - clean execution
74+
- Graders run and results (PASS/FAIL): PASS - all tests pass, PR created successfully
75+
- Prompt variant (if applicable): Standard /sp.git.commit_pr
76+
- Next experiment (smallest change to try): None needed - workflow successful

0 commit comments

Comments
 (0)