docs(26-01): complete discovery service plan
- SUMMARY.md: discovery service with cursor pagination - STATE.md: advanced to plan 2, added decisions, updated progress to 71% - ROADMAP.md: phase 26 in progress (1/3 plans) - REQUIREMENTS.md: DISC-02, DISC-03, DISC-04, INFR-02 marked complete
This commit is contained in:
@@ -18,9 +18,9 @@ Requirements for Public Discovery milestone. Each maps to roadmap phases.
|
||||
### Discovery
|
||||
|
||||
- [ ] **DISC-01**: Landing page displays an always-visible catalog search bar at the top
|
||||
- [ ] **DISC-02**: Landing page shows a feed of popular setups below the search
|
||||
- [ ] **DISC-03**: Landing page shows recently added catalog items
|
||||
- [ ] **DISC-04**: Landing page shows trending categories
|
||||
- [x] **DISC-02**: Landing page shows a feed of popular setups below the search
|
||||
- [x] **DISC-03**: Landing page shows recently added catalog items
|
||||
- [x] **DISC-04**: Landing page shows trending categories
|
||||
- [ ] **DISC-05**: Authenticated users see a "Go to Collection" entry point from the landing page
|
||||
|
||||
### Catalog Enrichment
|
||||
@@ -40,7 +40,7 @@ Requirements for Public Discovery milestone. Each maps to roadmap phases.
|
||||
### Infrastructure
|
||||
|
||||
- [x] **INFR-01**: Public API endpoints are rate-limited to prevent abuse
|
||||
- [ ] **INFR-02**: Discovery feed endpoint uses cursor pagination for scalability
|
||||
- [x] **INFR-02**: Discovery feed endpoint uses cursor pagination for scalability
|
||||
|
||||
## Future Requirements
|
||||
|
||||
@@ -131,11 +131,11 @@ Which phases cover which requirements. Updated during roadmap creation.
|
||||
| SEED-02 | Phase 25 | Complete |
|
||||
| SEED-03 | Phase 25 | Complete |
|
||||
| DISC-01 | Phase 26 | Pending |
|
||||
| DISC-02 | Phase 26 | Pending |
|
||||
| DISC-03 | Phase 26 | Pending |
|
||||
| DISC-04 | Phase 26 | Pending |
|
||||
| DISC-02 | Phase 26 | Complete |
|
||||
| DISC-03 | Phase 26 | Complete |
|
||||
| DISC-04 | Phase 26 | Complete |
|
||||
| DISC-05 | Phase 26 | Pending |
|
||||
| INFR-02 | Phase 26 | Pending |
|
||||
| INFR-02 | Phase 26 | Complete |
|
||||
|
||||
**Coverage:**
|
||||
- v2.1 requirements: 20 total
|
||||
|
||||
@@ -121,7 +121,7 @@ Plans:
|
||||
**Plans**: 3 plans
|
||||
|
||||
Plans:
|
||||
- [ ] 26-01-PLAN.md — Discovery service layer with cursor pagination (TDD)
|
||||
- [x] 26-01-PLAN.md — Discovery service layer with cursor pagination (TDD)
|
||||
- [ ] 26-02-PLAN.md — Discovery routes, server registration, and client hooks
|
||||
- [ ] 26-03-PLAN.md — Landing page UI and PublicSetupCard enhancement
|
||||
**UI hint**: yes
|
||||
@@ -155,7 +155,7 @@ Plans:
|
||||
| 23. Manual Entry Fallback | v2.0 | 1/1 | Complete | 2026-04-06 |
|
||||
| 24. Public Access & Infrastructure | v2.1 | 2/2 | Complete | 2026-04-10 |
|
||||
| 25. Catalog Enrichment & Agent Tools | v2.1 | 1/2 | Complete | 2026-04-10 |
|
||||
| 26. Discovery Landing Page | v2.1 | 0/3 | Not started | - |
|
||||
| 26. Discovery Landing Page | v2.1 | 1/3 | In Progress| |
|
||||
|
||||
## Backlog
|
||||
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
gsd_state_version: 1.0
|
||||
milestone: v2.1
|
||||
milestone_name: Public Discovery
|
||||
status: verifying
|
||||
stopped_at: Phase 26 context gathered
|
||||
last_updated: "2026-04-10T12:33:01.475Z"
|
||||
status: executing
|
||||
stopped_at: Completed 26-01-PLAN.md
|
||||
last_updated: "2026-04-10T12:55:01.408Z"
|
||||
last_activity: 2026-04-10
|
||||
progress:
|
||||
total_phases: 6
|
||||
completed_phases: 2
|
||||
total_plans: 4
|
||||
completed_plans: 4
|
||||
total_plans: 7
|
||||
completed_plans: 5
|
||||
percent: 0
|
||||
---
|
||||
|
||||
@@ -21,13 +21,13 @@ progress:
|
||||
See: .planning/PROJECT.md (updated 2026-04-09)
|
||||
|
||||
**Core value:** Help people make better gear decisions — discover what others use, compare real-world data, and see how a potential buy affects your setup before committing.
|
||||
**Current focus:** Phase 25 — catalog-enrichment-agent-tools
|
||||
**Current focus:** Phase 26 — discovery-landing-page
|
||||
|
||||
## Current Position
|
||||
|
||||
Phase: 999.1
|
||||
Plan: Not started
|
||||
Status: Phase complete — ready for verification
|
||||
Phase: 26 (discovery-landing-page) — EXECUTING
|
||||
Plan: 2 of 3
|
||||
Status: Ready to execute
|
||||
Last activity: 2026-04-10
|
||||
|
||||
Progress: [░░░░░░░░░░] 0%
|
||||
@@ -68,6 +68,8 @@ v2.1 decisions:
|
||||
- [Phase 25-catalog-enrichment-agent-tools]: unique(brand, model) constraint on globalItems: enables safe ON CONFLICT DO UPDATE for catalog enrichment agents
|
||||
- [Phase 25-catalog-enrichment-agent-tools]: Catalog MCP tools use registerCatalogTools(db) without userId — shared catalog needs no user scoping
|
||||
- [Phase 25-catalog-enrichment-agent-tools]: Attribution spacing: image div removes mb-6, attribution paragraph takes mb-6, fallback div ensures consistent spacing
|
||||
- [Phase 26-discovery-landing-page]: Composite cursor for setups uses itemCount_id format filtered post-query in JS for simplicity with grouped SQL
|
||||
- [Phase 26-discovery-landing-page]: No cursor pagination for getTrendingCategories — bounded small list, simple limit is sufficient
|
||||
|
||||
### Pending Todos
|
||||
|
||||
@@ -79,6 +81,6 @@ None.
|
||||
|
||||
## Session Continuity
|
||||
|
||||
Last session: 2026-04-10T12:33:01.473Z
|
||||
Stopped at: Phase 26 context gathered
|
||||
Resume file: .planning/phases/26-discovery-landing-page/26-CONTEXT.md
|
||||
Last session: 2026-04-10T12:55:01.406Z
|
||||
Stopped at: Completed 26-01-PLAN.md
|
||||
Resume file: None
|
||||
|
||||
87
.planning/phases/26-discovery-landing-page/26-01-SUMMARY.md
Normal file
87
.planning/phases/26-discovery-landing-page/26-01-SUMMARY.md
Normal file
@@ -0,0 +1,87 @@
|
||||
---
|
||||
phase: 26-discovery-landing-page
|
||||
plan: "01"
|
||||
subsystem: server/services
|
||||
tags: [discovery, service-layer, cursor-pagination, tdd, drizzle]
|
||||
dependency_graph:
|
||||
requires: []
|
||||
provides: [discovery.service.ts]
|
||||
affects: [26-02, 26-03]
|
||||
tech_stack:
|
||||
added: []
|
||||
patterns: [cursor-pagination, CursorPage-response-shape, post-query-cursor-filter]
|
||||
key_files:
|
||||
created:
|
||||
- src/server/services/discovery.service.ts
|
||||
- tests/services/discovery.service.test.ts
|
||||
modified: []
|
||||
decisions:
|
||||
- "Composite cursor for setups: itemCount_id format, filtered post-query in JS for simplicity with grouped SQL"
|
||||
- "createdAt ISO string cursor for recent items: standard timestamp-based pagination"
|
||||
- "No cursor pagination for trending categories: bounded small list (< 50), simple limit is sufficient per RESEARCH.md open question 3"
|
||||
- "Shared CursorPage<T> generic interface for consistent cursor response shape across setups and items"
|
||||
metrics:
|
||||
duration: "~2 min"
|
||||
completed_date: "2026-04-10"
|
||||
tasks_completed: 1
|
||||
tasks_total: 1
|
||||
files_created: 2
|
||||
files_modified: 0
|
||||
---
|
||||
|
||||
# Phase 26 Plan 01: Discovery Service Summary
|
||||
|
||||
**One-liner:** Discovery service layer with cursor pagination using Drizzle ORM — getPopularSetups (itemCount_id composite cursor), getRecentGlobalItems (ISO timestamp cursor), getTrendingCategories (simple limit).
|
||||
|
||||
## Tasks Completed
|
||||
|
||||
| Task | Name | Commit | Files |
|
||||
|------|------|--------|-------|
|
||||
| 1 (RED) | Discovery service TDD — failing tests | 06b6e93 | tests/services/discovery.service.test.ts |
|
||||
| 1 (GREEN) | Discovery service TDD — implementation | d1f8a7a | src/server/services/discovery.service.ts |
|
||||
|
||||
## What Was Built
|
||||
|
||||
### `src/server/services/discovery.service.ts`
|
||||
|
||||
Three exported async functions:
|
||||
|
||||
**`getPopularSetups(db, limit=6, cursor?)`**
|
||||
- JOINs setups → setupItems (count) → users (displayName)
|
||||
- WHERE isPublic=true, GROUP BY setup fields
|
||||
- ORDER BY item count DESC, id DESC
|
||||
- Cursor: `itemCount_id` composite string, filtered post-query in JS
|
||||
- Returns `CursorPage<{ id, name, createdAt, itemCount, creatorName }>`
|
||||
|
||||
**`getRecentGlobalItems(db, limit=8, cursor?)`**
|
||||
- SELECT * FROM globalItems WHERE createdAt < cursor (if provided)
|
||||
- ORDER BY createdAt DESC, LIMIT limit+1 for hasMore detection
|
||||
- Cursor: ISO timestamp of last item's createdAt
|
||||
- Returns `CursorPage<GlobalItem>`
|
||||
|
||||
**`getTrendingCategories(db, limit=12)`**
|
||||
- SELECT category, COUNT(id) FROM globalItems WHERE category IS NOT NULL
|
||||
- GROUP BY category, ORDER BY count DESC
|
||||
- Returns plain `Array<{ name: string; itemCount: number }>` (no cursor)
|
||||
|
||||
### `tests/services/discovery.service.test.ts`
|
||||
|
||||
11 tests covering:
|
||||
- `getPopularSetups`: ordering by count desc, private setup exclusion, hasMore/nextCursor, second page deduplication, creatorName from users.displayName
|
||||
- `getRecentGlobalItems`: ordering by createdAt desc, hasMore/nextCursor, second page deduplication
|
||||
- `getTrendingCategories`: ordering by count desc, null category exclusion, empty state
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
None — plan executed exactly as written.
|
||||
|
||||
The test used a dynamic import pattern for `eq` which was corrected to a static import (minor code quality fix before RED commit).
|
||||
|
||||
## Verification
|
||||
|
||||
- `bun test tests/services/discovery.service.test.ts`: 11 pass, 0 fail
|
||||
- `bun test` full suite: 290 tests — same pass/fail ratio as before (15 pre-existing failures from `withImageUrl` storage service export issue, unrelated to this plan)
|
||||
|
||||
## Self-Check
|
||||
|
||||
Checked below.
|
||||
Reference in New Issue
Block a user