- Create community-price.service.ts with ownership validation, upsert, median aggregation
- Create community-prices route (GET stats public, POST requires auth + ownership)
- Register community-prices route with public GET access
- Add priceCurrency to both getSetupWithItems and getSetupWithItemsById
- Aggregation uses PERCENTILE_CONT(0.5) with 3-report minimum threshold
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Create market-price.service.ts with getMarketPrices, upsertMarketPrice
- Create exchange-rates route (GET /api/exchange-rates, public)
- Create market-prices route (GET/POST /api/market-prices/global-items/:id/prices)
- Register new routes in server index with public GET access
- Add priceCurrency to item service getAllItems/getItemById/createItem
- Add foundPriceCents/Currency/Date to thread candidate select and create/update
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Detect ?share=token query param on setup detail page, fetch via
/api/shared/:token, and display read-only view with "Shared setup"
banner. Hide all owner controls (add items, share, delete, classification)
in shared view. Show "Link not available" error for invalid tokens.
Plan: 32-04 (Setup Sharing System - Shared Setup Viewer)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Create ShareModal component with three-tier visibility picker
(private/link/public), share link creation with configurable expiration,
clipboard copy, and link revocation. Wire into setup detail page
replacing the static visibility badge with an interactive share button.
Plan: 32-03 (Setup Sharing System - Share Modal UI)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Create share.service.ts with token generation (128-bit base64url),
CRUD operations, validation, and visibility transition side effects.
Add share endpoints under /api/setups/:id/shares, shared access at
/api/shared/:token, and /s/:token short URL redirect.
Plan: 32-02 (Setup Sharing System - Share Link Backend)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 plans across 3 waves covering market-aware pricing, exchange rates,
community price data, and currency-normalized display.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace isPublic boolean with visibility enum (private/link/public) across
the full stack. Add shares table to schema for future share link support.
Update all services, routes, schemas, hooks, components, and tests.
Plan: 32-01 (Setup Sharing System - Schema Migration)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Plans 03 and 04 both modify setups/$setupId.tsx. Per wave assignment
rules, file overlap requires sequential execution. Plan 04 now depends
on Plan 03 and runs in Wave 4.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
Moved the crop button from below the image into the ImageUpload
component as an absolute-positioned overlay next to the trash icon,
matching the visual pattern.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The crop icon button was in the view-mode branch but conditioned on
isEditing, making it unreachable. Moved it below ImageUpload in the
edit-mode branch where it belongs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ImageUpload was discarding the dominantColor returned by the upload
API. Now it passes the color through onChange and the item detail
page saves it to the item record immediately after upload.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The OIDC session token retains the old email after a Logto email
change. Now the server returns the new email in the response and
the frontend optimistically updates the auth cache.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>