Files
GearBox/.planning/PROJECT.md

9.3 KiB

GearBox

What This Is

A gear management and discovery platform. Users catalog their gear collections (bikepacking, sim racing, or any hobby), track weight, price, and source details, research purchases through planning threads with side-by-side comparison, and compose named setups (loadouts) with weight classification and visualization. A global item database with crowd-verified specs and structured reviews helps users make informed purchase decisions. Multi-user with public setup sharing and gear discovery.

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.

Requirements

Validated

  • ✓ Gear collection with item CRUD (name, weight, price, category, notes, product link) — v1.0
  • ✓ Image uploads for gear items — v1.0
  • ✓ User-defined categories with automatic weight/cost totals — v1.0
  • ✓ Planning threads for purchase research with candidate products — v1.0
  • ✓ Thread resolution: pick a winner, it moves to collection — v1.0
  • ✓ Named setups (loadouts) composed from collection items — v1.0
  • ✓ Live weight and cost totals per setup — v1.0
  • ✓ Dashboard home page with summary cards — v1.0
  • ✓ Onboarding wizard for first-time setup — v1.0
  • ✓ Thread creation with category assignment via modal dialog — v1.1
  • ✓ Planning tab with educational empty state and pill tab navigation — v1.1
  • ✓ Image display on item detail views and gear cards with placeholders — v1.1
  • ✓ Hero image upload area with preview and click-to-upload — v1.1
  • ✓ Lucide icon picker for categories (119 curated icons, 8 groups) — v1.1
  • ✓ Automatic emoji-to-Lucide icon migration for existing categories — v1.1
  • ✓ Search items by name with instant filtering — v1.2
  • ✓ Filter collection items by category with icon-aware dropdown — v1.2
  • ✓ Combined text search with category filter and result count — v1.2
  • ✓ One-action filter clear — v1.2
  • ✓ Weight unit selection (g, oz, lb, kg) with persistence — v1.2
  • ✓ All weight displays respect selected unit across entire app — v1.2
  • ✓ Per-setup item classification (base weight, worn, consumable) — v1.2
  • ✓ Setup weight subtotals by classification — v1.2
  • ✓ Donut chart visualization with category/classification toggle — v1.2
  • ✓ Chart hover tooltips with weight and percentage — v1.2
  • ✓ Candidate status tracking (researching/ordered/arrived) — v1.2
  • ✓ Planning category filter with Lucide icons — v1.2

Active

Current Milestone: v2.0 Platform Foundation

Goal: Transform GearBox from a single-user gear tracker into a multi-user platform where people discover gear, research purchases using crowd-verified data, and share their setups.

Target features:

  • External auth provider (self-hosted, open-source) for multi-user registration
  • Migrate from SQLite to Postgres
  • Multi-user data model (user ownership on all entities, public/private visibility)
  • Global item database (seeded from manufacturer data, enrichable by users)
  • Public user profiles with shared setups
  • Structured item reviews (ratings + predefined fields, not freeform text)
  • Discovery feed (browse setups, new items, popular gear)
  • Item detail pages with aggregated specs, owner count, setup appearances

Future

  • Freeform reviews with moderation system
  • Comments on setups
  • Follow users / activity feeds
  • OAuth / social login providers
  • User-to-user messaging

Out of Scope

  • Custom comparison parameters — complexity trap, weight/price covers 80% of cases
  • Mobile native app — web-first, responsive design sufficient
  • Price tracking / deal alerts — requires scraping, fragile
  • Barcode scanning — poor UX, manual entry is fine with global database
  • Real-time weather integration — only outdoor-specific, GearBox is hobby-agnostic
  • Freeform UGC (reviews, comments) — defer until moderation infrastructure exists
  • User-to-user messaging — high moderation burden, not core to discovery
  • Wiki-style open item editing — structured contributions only for data quality
  • Maintaining SQLite single-user mode in parallel — diverged at v2.0

Context

Shipped through v1.4 with 11,333 LOC TypeScript across 90 files. Starting v2.0 platform transformation. Tech stack: React 19, Hono, Drizzle ORM, SQLite (migrating to Postgres), TanStack Router/Query, Tailwind CSS v4, Lucide React, Recharts, framer-motion, all on Bun. Primary use case is bikepacking gear but data model is hobby-agnostic. Existing auth: single-user with cookie sessions + API keys. Will be replaced by external auth provider. Existing features: MCP server (19 tools), E2E tests (Playwright), CSV import/export, item comparison, candidate ranking, setup impact preview. 21 test files (service-level, route-level integration, and E2E).

Constraints

  • Runtime: Bun — used as package manager and runtime
  • Design: Light, airy, minimalist — white/light backgrounds, lots of whitespace, no visual clutter
  • Navigation: Dashboard-based home page, not sidebar or top-nav tabs
  • Auth: External self-hosted provider — no in-house auth maintenance
  • Database: Postgres for platform deployment
  • UGC: Structured input only (ratings, predefined fields) — no freeform text until moderation exists
  • Scope: Multi-user platform with public discovery

Key Decisions

Decision Rationale Outcome
Cookie/API key auth Single user, public read + authenticated write ✓ Good
Generic data model Support any hobby, not just bikepacking ✓ Good
Dashboard navigation Clean entry point, not persistent nav ✓ Good
Bun runtime User preference ✓ Good
Service layer with DI Accept db as first param for testability ✓ Good
Hono context variables for DB Enables in-memory SQLite integration tests ✓ Good
Prices stored as cents Avoids float rounding issues ✓ Good
Vite proxy dev setup Required by TanStack Router plugin ✓ Good
drizzle-kit needs better-sqlite3 bun:sqlite not supported by CLI ✓ Good
Tab navigation via URL params Shareable URLs between gear/planning ✓ Good
Setup item sync: delete-all + re-insert Simpler than diffing, atomic in transaction ✓ Good
Onboarding state in SQLite settings Source of truth in DB, not Zustand ✓ Good
Stay with SQLite Single-user app, no need for Postgres complexity ✓ Good
Lucide Icons for categories Best outdoor/gear icon coverage, tree-shakeable, clean style ✓ Good
categoryId on threads (NOT NULL FK) Every thread belongs to a category ✓ Good
Modal dialog for thread creation Cleaner UX, supports category selection ✓ Good
Hero image area at top of forms Image-first UX, 4:3 aspect ratio consistent with cards ✓ Good
Emoji-to-icon automatic migration One-time schema rename + data conversion via Drizzle migration ✓ Good
ALTER TABLE RENAME COLUMN for SQLite Simpler than table recreation for column rename ✓ Good
Platform pivot at v2.0 Single-user model proven, now build for multi-user discovery — Pending
External auth provider Avoid in-house auth security burden, self-hosted + open-source — Pending
SQLite → Postgres Multi-user platform needs proper concurrent DB; auth provider needs Postgres anyway — Pending
Single-user mode diverges at v2.0 Platform features irrelevant for solo use; maintain as separate artifact if needed — Pending
Structured UGC only (no freeform) Minimize moderation burden; ratings + predefined fields cover 80% of value — Pending
Discovery-first, not social-first Users come to research gear decisions, not to build social graphs — Pending
Weight conversion precision: g=0dp, oz=1dp, lb=2dp, kg=2dp Matches common usage conventions ✓ Good
Unit toggle in TotalsBar (not settings page) Visible, quick access for frequent switching ✓ Good
CategoryFilterDropdown separate from CategoryPicker Filter vs form concerns are different ✓ Good
No debounce on search input Collection under 1000 items, instant feedback ✓ Good
StatusBadge popup with click-outside dismiss Consistent with CategoryPicker pattern ✓ Good
Classification on setupItems join table Same item can have different roles per setup ✓ Good
Click-to-cycle for ClassificationBadge Only 3 values, simpler than popup ✓ Good
Classification-preserving sync via Map Save metadata before delete, restore after re-insert ✓ Good
Recharts for charting Mature React chart library, composable API ✓ Good

Evolution

This document evolves at phase transitions and milestone boundaries.

After each phase transition (via /gsd:transition):

  1. Requirements invalidated? → Move to Out of Scope with reason
  2. Requirements validated? → Move to Validated with phase reference
  3. New requirements emerged? → Add to Active
  4. Decisions to log? → Add to Key Decisions
  5. "What This Is" still accurate? → Update if drifted

After each milestone (via /gsd:complete-milestone):

  1. Full review of all sections
  2. Core Value check — still the right priority?
  3. Audit Out of Scope — reasons still valid?
  4. Update Context with current state

Last updated: 2026-04-03 after v2.0 milestone start