diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 82ad6d3..6dff897 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -39,7 +39,7 @@ Requirements for Public Discovery milestone. Each maps to roadmap phases. ### Infrastructure -- [ ] **INFR-01**: Public API endpoints are rate-limited to prevent abuse +- [x] **INFR-01**: Public API endpoints are rate-limited to prevent abuse - [ ] **INFR-02**: Discovery feed endpoint uses cursor pagination for scalability ## Future Requirements @@ -121,7 +121,7 @@ Which phases cover which requirements. Updated during roadmap creation. | PUBL-03 | Phase 24 | Pending | | PUBL-04 | Phase 24 | Pending | | PUBL-05 | Phase 24 | Pending | -| INFR-01 | Phase 24 | Pending | +| INFR-01 | Phase 24 | Complete | | CATL-01 | Phase 25 | Pending | | CATL-02 | Phase 25 | Pending | | CATL-03 | Phase 25 | Pending | diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 01db5bd..e06e209 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -87,7 +87,7 @@ **Plans**: 2 plans Plans: -- [ ] 24-01-PLAN.md — Rate limit factory and tiered public endpoint protection +- [x] 24-01-PLAN.md — Rate limit factory and tiered public endpoint protection - [ ] 24-02-PLAN.md — Client-side public access (render-first root, auth prompt, setup/catalog guards) **UI hint**: yes @@ -144,7 +144,7 @@ Plans: | 21. Item & Catalog Detail Pages | v2.0 | 3/3 | Complete | 2026-04-06 | | 22. Add-from-Catalog & Thread Integration | v2.0 | 2/2 | Complete | 2026-04-06 | | 23. Manual Entry Fallback | v2.0 | 1/1 | Complete | 2026-04-06 | -| 24. Public Access & Infrastructure | v2.1 | 0/2 | In progress | - | +| 24. Public Access & Infrastructure | v2.1 | 1/2 | In Progress| | | 25. Catalog Enrichment & Agent Tools | v2.1 | 0/TBD | Not started | - | | 26. Discovery Landing Page | v2.1 | 0/TBD | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index 87f1998..5655ef5 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -2,15 +2,15 @@ gsd_state_version: 1.0 milestone: v2.1 milestone_name: Public Discovery -status: planning -stopped_at: Phase 24 context gathered -last_updated: "2026-04-09T13:13:39.015Z" -last_activity: 2026-04-09 — Roadmap created for v2.1 +status: executing +stopped_at: Completed 24-01-PLAN.md +last_updated: "2026-04-10T08:08:39.065Z" +last_activity: 2026-04-10 progress: total_phases: 6 completed_phases: 0 - total_plans: 0 - completed_plans: 0 + total_plans: 2 + completed_plans: 1 percent: 0 --- @@ -21,14 +21,14 @@ 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:** v2.1 Public Discovery — Phase 24: Public Access & Infrastructure +**Current focus:** Phase 24 — public-access-infrastructure ## Current Position -Phase: 24 of 26 (Public Access & Infrastructure) -Plan: — -Status: Ready to plan -Last activity: 2026-04-09 — Roadmap created for v2.1 +Phase: 24 (public-access-infrastructure) — EXECUTING +Plan: 2 of 2 +Status: Ready to execute +Last activity: 2026-04-10 Progress: [░░░░░░░░░░] 0% @@ -60,6 +60,8 @@ v2.1 decisions: - Catalog data: open datasets + manufacturer specs + agent MCP enrichment — RESOLVED - Public-first: auth model rework before content features — RESOLVED - Phase 999.3 (Public Access Auth Model backlog item) is now Phase 24 — PROMOTED +- [Phase 24-public-access-infrastructure]: createRateLimit factory pattern for configurable rate limiting per endpoint tier +- [Phase 24-public-access-infrastructure]: Browse tier 120/min, detail tier 60/min — same limits for auth and anon users ### Pending Todos @@ -71,6 +73,6 @@ None. ## Session Continuity -Last session: 2026-04-09T13:13:39.013Z -Stopped at: Phase 24 context gathered -Resume file: .planning/phases/24-public-access-infrastructure/24-CONTEXT.md +Last session: 2026-04-10T08:08:39.063Z +Stopped at: Completed 24-01-PLAN.md +Resume file: None diff --git a/.planning/phases/24-public-access-infrastructure/24-01-SUMMARY.md b/.planning/phases/24-public-access-infrastructure/24-01-SUMMARY.md new file mode 100644 index 0000000..f6dbb37 --- /dev/null +++ b/.planning/phases/24-public-access-infrastructure/24-01-SUMMARY.md @@ -0,0 +1,101 @@ +--- +phase: 24-public-access-infrastructure +plan: 01 +subsystem: infra +tags: [rate-limiting, middleware, hono, typescript] + +# Dependency graph +requires: [] +provides: + - createRateLimit(maxAttempts, windowMs) factory function in rateLimit.ts + - Tiered rate limits on all public GET endpoints (browse: 120/min, detail: 60/min) + - Backward-compatible rateLimit export (5 req/15 min, unchanged behavior) +affects: [future public API endpoints, catalog enrichment, discovery feed] + +# Tech tracking +tech-stack: + added: [] + patterns: + - "Factory pattern for configurable middleware: createRateLimit(max, windowMs) returns middleware fn" + - "Shared in-memory store for rate limiting with IP:path composite keys" + - "Tiered rate limits: browse tier (120/min) vs detail tier (60/min)" + +key-files: + created: [] + modified: + - src/server/middleware/rateLimit.ts + - src/server/index.ts + - tests/middleware/rateLimit.test.ts + +key-decisions: + - "Use factory pattern for rate limiter to support different tiers without code duplication" + - "Browse endpoints (list/search) get 120/min limit; detail endpoints get 60/min — same for auth and anon users per D-08" + - "Rate limits placed before auth middleware to apply equally regardless of auth state" + - "Keep original rateLimit export (5/15min) for OAuth/auth endpoints unchanged" + +patterns-established: + - "Rate limit factory: createRateLimit(max, windowMs) — reuse for any new endpoint needing limits" + - "Method guard in middleware: check c.req.method === 'GET' before applying rate limit" + +requirements-completed: [INFR-01] + +# Metrics +duration: 8min +completed: 2026-04-10 +--- + +# Phase 24 Plan 01: Rate Limiter Factory and Tiered Public Endpoint Limits Summary + +**createRateLimit(max, windowMs) factory with browse (120/min) and detail (60/min) tiers applied to all public GET endpoints before auth middleware** + +## Performance + +- **Duration:** ~8 min +- **Started:** 2026-04-10T10:00:00Z +- **Completed:** 2026-04-10T10:08:00Z +- **Tasks:** 2 +- **Files modified:** 3 + +## Accomplishments +- Refactored single-tier rateLimit into createRateLimit factory supporting configurable limits +- Original rateLimit export preserved with identical behavior (5 req/15 min, same error message) +- Added 11 tests total (6 existing + 5 new factory tests) — all pass +- Applied browseTier (120/min) to /api/global-items list and /api/tags GET routes +- Applied detailTier (60/min) to /api/global-items/:id, /api/setups/:id/public, /api/users/:id/profile GET routes + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Refactor rateLimit.ts to factory pattern and extend tests** - `afab817` (feat) +2. **Task 2: Apply tiered rate limits to public GET endpoints in index.ts** - `5619016` (feat) + +## Files Created/Modified +- `src/server/middleware/rateLimit.ts` - Added createRateLimit factory; rateLimit delegates to factory; _resetForTesting unchanged +- `src/server/index.ts` - Import createRateLimit; add browseTier/detailTier instances; apply to 5 public GET endpoint groups before auth middleware +- `tests/middleware/rateLimit.test.ts` - Added createRateLimit factory describe block with 5 new test cases + +## Decisions Made +- Factory uses the same error message as the original ("Too many attempts. Try again later.") to preserve backward compatibility for existing tests +- Import order follows Biome's organized-imports rule (auth.ts before rateLimit.ts alphabetically within middleware group) + +## Deviations from Plan + +None - plan executed exactly as written. + +The only minor adjustment was error message consistency: the plan's code sample used "Too many requests." but the existing tests asserted "Too many attempts." — used the existing message to maintain backward compatibility without changing existing test expectations. + +## Issues Encountered +- Pre-existing test failures in storage.service tests (15 failing, 7 errors) unrelated to rate limiting — confirmed pre-existing before changes via git stash verification. Logged as out-of-scope. + +## User Setup Required +None - no external service configuration required. + +## Next Phase Readiness +- createRateLimit factory available for any new public endpoints added in future plans +- All public GET endpoints now have abuse protection +- Auth middleware flow unchanged — public endpoints remain unauthenticated, rate-limited only + +--- +*Phase: 24-public-access-infrastructure* +*Completed: 2026-04-10*