chore: archive v2.2 User Experience Polish milestone
Phases 28-31 archived to milestones/v2.2-phases/ Requirements and roadmap snapshots archived to milestones/ Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,68 @@
|
||||
# Milestones
|
||||
|
||||
## v2.2 User Experience Polish (Shipped: 2026-04-13)
|
||||
|
||||
**Phases completed:** 36 phases, 68 plans, 120 tasks
|
||||
|
||||
**Key accomplishments:**
|
||||
|
||||
- Parameterized formatWeight with g/oz/lb/kg conversion and useWeightUnit settings hook, backed by 21 TDD tests
|
||||
- Segmented g/oz/lb/kg toggle in TotalsBar with all 8 weight display call sites wired to user-selected unit
|
||||
- Candidate status tracking (researching/ordered/arrived) with schema migration, service/Zod updates, 5 TDD tests, and clickable StatusBadge popup on CandidateCard
|
||||
- Sticky search/filter toolbar on gear tab with text+category filtering, and shared icon-aware CategoryFilterDropdown on both gear and planning tabs
|
||||
- Per-setup item classification (base/worn/consumable) with click-to-cycle badge, classification-preserving sync, and full test coverage
|
||||
- Recharts donut chart with category/classification toggle, weight subtotals card, and hover tooltips inside setup detail page
|
||||
- Nullable pros/cons TEXT columns added to thread_candidates from SQLite schema through Drizzle migration, service layer, Zod validation, React form inputs, and CandidateCard visual badge
|
||||
- sortOrder REAL column, reorderCandidates transaction service, and PATCH /api/threads/:id/candidates/reorder endpoint with active-thread guard
|
||||
- 1. [Rule 2 - Missing] Added pros/cons fields to CandidateWithCategory in useThreads.ts
|
||||
- Side-by-side candidate comparison table with sticky labels, weight/price delta highlighting, and resolved-thread winner marking via a new "compare" candidateViewMode
|
||||
- PostgreSQL schema with 13 pgTable definitions, postgres.js connection, PGlite test infrastructure, and initial migration
|
||||
- PostgreSQL 16 Docker Compose for dev and production, lean Dockerfile without native SQLite build dependencies
|
||||
- All 9 service files (30 functions) converted from synchronous SQLite to async PostgreSQL operations with PGlite smoke test validation
|
||||
- All 9 route files and auth middleware converted to properly await async service/DB calls, preventing Promise-as-JSON responses
|
||||
- One-time data migration script converting all 13 tables from SQLite to PostgreSQL with timestamp/boolean type conversions and serial sequence reset
|
||||
- All 18 test files converted to async PGlite with 161 tests passing across service, route, and MCP layers
|
||||
- Logto OIDC provider added to Docker Compose with Postgres init script, users/sessions tables removed from schema
|
||||
- Three-way auth middleware with @hono/oidc-auth for browser sessions, API keys for programmatic access, and MCP OAuth consent flow
|
||||
- OIDC login redirect page, cleaned auth hooks (string user id, no credential forms), API-key E2E seed, and three-way auth test coverage
|
||||
- pgTable schema with users table, userId FK on 6 entity tables, composite constraints, and auth middleware resolving userId for all auth methods
|
||||
- All 7 service files accept userId parameter with and(eq) isolation on every query — no unscoped reads or writes remain
|
||||
- Complete userId propagation chain from auth middleware through routes and MCP tools to service layer
|
||||
- Route tests, MCP tests, and cross-user isolation tests updated with userId context for multi-user data model
|
||||
- S3 storage abstraction with uploadImage/deleteImage/getImageUrl using @aws-sdk/client-s3, plus MinIO in Docker Compose with automatic bucket creation
|
||||
- Replaced all local filesystem image operations with S3 storage service calls across routes, services, and MCP tools
|
||||
- Replaced all client /uploads/ path references with presigned S3 URLs and created one-time image migration script
|
||||
- Global items table, item-global links, user profile columns, setup visibility, Zod schemas, and 18-item bikepacking seed catalog
|
||||
- Global item catalog backend with LIKE search, owner count aggregation, item linking, idempotent seeding, and full test coverage
|
||||
- Profile service with CRUD and public profile data, public setup viewing, setup visibility toggle, and auth middleware bypass for public endpoints
|
||||
- Global catalog browse/search page, item detail with owner count, and link-to-catalog component using TanStack Router and Query
|
||||
- Profile edit UI in settings with avatar upload, public profile page with setup listing, and setup visibility toggle with globe icon
|
||||
- Database schema updated with direct globalItemId FK on items/candidates, tags system tables, and data migration from itemGlobalLinks
|
||||
- COALESCE merge pattern in item/thread services for transparent reference item data, branched thread resolution, and link/unlink endpoint removal
|
||||
- Tag-filtered global item search with AND logic, owner count via direct FK, and COALESCE merge propagated to setup/totals/profile/CSV services
|
||||
- Tags endpoint with alphabetical ordering, global-items route registration, UIStore FAB/catalog-search state, and tag-aware useGlobalItems hook
|
||||
- Global FAB with animated mini menu and full-screen catalog search overlay with debounced search, tag chip AND-filtering, and result card grid
|
||||
- Private item detail page with edit mode toggle at /items/:id, and enhanced catalog detail page with Add to Collection stub button
|
||||
- Candidate detail page with edit mode toggle at /threads/:threadId/candidates/:candidateId, thread route directory restructured for nested routes, add-candidate modal replacing slide-out panel
|
||||
- All card components rewired from slide-out panels to detail page navigation, panels removed from root layout, UIStore cleaned of panel state
|
||||
- AddToCollectionModal with category/notes/price fields, sonner toasts, and wired catalog search + detail page entry points
|
||||
- AddToThreadModal with existing thread picker, new thread + candidate creation, and session thread memory for catalog search flow
|
||||
- ManualEntryForm component with CategoryPicker, ImageUpload, and cents conversion wired into CatalogSearchOverlay as inline mode with entry points, success card, and context-sensitive navigation
|
||||
- createRateLimit(max, windowMs) factory with browse (120/min) and detail (60/min) tiers applied to all public GET endpoints before auth middleware
|
||||
- globalItems attribution columns (sourceUrl, imageCredit, imageSourceUrl) with unique(brand, model) constraint, upsertGlobalItem/bulkUpsertGlobalItems service functions, and Zod schemas — 21 tests passing
|
||||
- POST /api/global-items, POST /api/global-items/bulk, upsert_catalog_item and bulk_upsert_catalog MCP tools, and catalog detail page attribution display — 61 tests passing, lint clean, build succeeds
|
||||
- One-liner:
|
||||
- One-liner:
|
||||
- Discovery landing page replacing personal dashboard — hero search trigger, popular setups feed, recent catalog items, trending categories, with auth-conditional CTA and PublicSetupCard enhanced with item counts and creator names
|
||||
- 1. [Rule 1 - Bug] Used 'house' icon instead of plan-specified 'home'
|
||||
- One-liner:
|
||||
- TopNav replaces TotalsBar across all pages, BottomTabBar wired for mobile, hero removed from landing page, and /setups added as a public route
|
||||
- Shared hobby config, popular-items-by-tags endpoint with owner count ordering, and batch onboarding completion service with auto-category creation
|
||||
- 5-step catalog-driven onboarding with hobby cards, selectable item grid, review list, and CSS step transitions following UI-SPEC design contract
|
||||
- Replaced old OnboardingWizard with new OnboardingFlow in root route, deleted old component, verified build and no stale references
|
||||
|
||||
---
|
||||
|
||||
## v2.0 Platform Foundation (Shipped: 2026-04-08)
|
||||
|
||||
**Phases completed:** 10 phases, 32 plans
|
||||
|
||||
Reference in New Issue
Block a user