Commit graph

4 commits

Author SHA1 Message Date
dca3c3f50b feat(prefs): display.currency preference with live exchange rate conversion
- Backend: validate display.currency against 10 supported ISO 4217 codes
  (USD, GBP, EUR, CAD, AUD, JPY, CHF, MXN, BRL, INR); return 400 on
  unsupported code with a clear message listing accepted values
- Frontend: useCurrency composable fetches rates from open.er-api.com
  with 1-hour module-level cache and in-flight deduplication; falls back
  to USD display on network failure
- Preferences store: adds display.currency with localStorage fallback for
  anonymous users and localStorage-to-DB migration for newly logged-in users
- ListingCard: price and market price now convert from USD using live rates,
  showing USD synchronously while rates load then updating reactively
- Settings UI: currency selector dropdown in Appearance section using
  theme-aware CSS classes; available to all users (anon via localStorage,
  logged-in via DB preference)
- Tests: 6 Python tests for the PATCH /api/preferences currency endpoint
  (including ordering-safe fixture using patch.object on _LOCAL_SNIPE_DB);
  14 Vitest tests for convertFromUSD, formatPrice, and formatPriceUSD
2026-04-20 11:02:59 -07:00
66ae9eb0b8 feat: reported sellers tracking + community blocklist opt-in
Some checks are pending
CI / Python tests (push) Waiting to run
CI / Frontend typecheck + tests (push) Waiting to run
Mirror / mirror (push) Waiting to run
Phase 2 (snipe#4): after bulk-reporting sellers to eBay T&S, Snipe now
persists which sellers were reported so cards show a muted "Reported to
eBay" badge and users aren't prompted to re-report the same seller.
- migration 012 adds reported_sellers table (user DB, UNIQUE on seller)
- Store.mark_reported / list_reported methods
- POST /api/reported + GET /api/reported endpoints
- reported store (frontend) with optimistic update + server persistence
- reportSelected wires into store after opening eBay tabs

Phase 3 prep (snipe#4): community blocklist share toggle
- Settings > Community section: "Share blocklist with community" toggle
  (visible only to signed-in cloud users, default OFF)
- Persisted as community.blocklist_share user preference
- Backend community signal publish now gated on opt-in preference;
  privacy-by-architecture: sharing is explicit, never implicit
2026-04-16 13:28:57 -07:00
8e40e51ed3 fix: prefix /api/session and /api/preferences with VITE_API_BASE
Some checks are pending
CI / Frontend typecheck + tests (push) Waiting to run
CI / Python tests (push) Waiting to run
Mirror / mirror (push) Waiting to run
Release / release (push) Waiting to run
Both stores hardcoded /api/* paths without reading VITE_API_BASE, causing
/api/session to hit the menagerie root (no /snipe prefix) and receive a
302 redirect to circuitforge.tech/login instead of a session response.
Every other store already read VITE_API_BASE correctly.
2026-04-16 12:51:39 -07:00
fb81422c54 feat: snipe beta backlog batch (tickets #22/#28/#30/#34/#35/#36/#37/#38)
Cloud/session:
- fix(_extract_session_token): return "" for non-JWT cookie strings (snipe_guest=uuid was
  triggering 401 → forced login redirect for all unauthenticated cloud visitors)
- fix(affiliate): exclude guest: and anonymous users from pref-store writes (#38)
- fix(market-comp): use enriched comp_query for market comp hash so write/read keys match (#30)

Frontend:
- feat(SearchView): unauthenticated landing strip with free-account CTA (#36)
- feat(SearchView): aria-pressed on filter toggles, aria-label on icon buttons, focus-visible
  rings on all interactive controls, live region for result count (#35)
- feat(SearchView): no-results empty-state hint text (#36)
- feat(SEO): og:image 1200x630, summary_large_image twitter card, canonical link (#37)
- feat(OG): generated og-image.png (dark tactical theme, feature pills) (#37)
- feat(settings): TrustSignalPref view wired to /settings route (#28)
- fix(router): /settings route added; unauthenticated access redirects to home (#34)

CI/CD:
- feat(ci): Forgejo Actions workflow (ruff + pytest + vue-tsc + vitest) (#22)
- feat(ci): mirror workflow (GitHub + Codeberg on push to main/tags) (#22)
- feat(ci): release workflow (Docker build+push + git-cliff changelog) (#22)
- chore: git-cliff config (.cliff.toml) for conventional commit changelog (#22)
- chore(pyproject): dev extras (pytest/ruff/httpx), ruff config with ignore list (#22)

Lint:
- fix: remove 11 unused imports across api/, app/, tests/ (ruff F401 clean)
2026-04-13 19:32:50 -07:00