Commit graph

5 commits

Author SHA1 Message Date
11f2a3c2b3 feat(snipe): keyword must-include/must-exclude filtering
- Two sidebar fields: 'Must include' and 'Must exclude' (comma-separated)
- Must-exclude terms forwarded to eBay _nkw as -term prefixes (native eBay
  support) so exclusions reduce the eBay result set at the source — improves
  market comp quality as a side effect
- Must-include applied client-side only (substring, case-insensitive)
- Both applied client-side via passesFilter() for instant response without
  re-fetching (cache-friendly)
- Exclude input has subtle red border tint (color-mix) to signal intent
- Hint text: 're-search to apply to eBay' reminds user negatives need a
  new search to take effect at the eBay level
2026-03-25 22:54:24 -07:00
ea78b9c2cd feat(snipe): parallel search+comps, pagination, title fix, price flag fix
- Parallel execution: search() and get_completed_sales() now run
  concurrently via ThreadPoolExecutor — each gets its own Store/SQLite
  connection for thread safety. First cold search time ~halved.

- Pagination: SearchFilters.pages (default 1) controls how many eBay
  result pages are fetched. Both search and sold-comps support up to 3
  parallel Playwright sessions per call (capped to avoid Xvfb overload).
  UI: segmented 1/2/3/5 pages selector in filter sidebar with cost hint.

- True median: get_completed_sales() now averages the two middle values
  for even-length price lists instead of always taking the lower bound.

- Fix suspicious_price false positive: aggregator now checks
  signal_scores.get("price_vs_market") == 0 (pre-None-substitution)
  so listings without market data are never flagged as suspicious.

- Fix title pollution: scraper strips eBay's hidden screen-reader span
  ("Opens in a new window or tab") from listing titles via regex.
  Lazy-imports playwright/playwright_stealth inside _get() so pure
  parsing functions are importable without the full browser stack.

- Tests: 48 pass on host (scraper tests now runnable without Docker),
  new regression guards for all three bug fixes.
2026-03-25 22:16:08 -07:00
58263d814a feat(snipe): FastAPI layer, Playwright+Xvfb scraper, caching, tests
- FastAPI service (port 8510) wrapping scraper + trust scorer
- Playwright+Xvfb+stealth transport to bypass eBay Kasada bot protection
- li.s-card selector migration (eBay markup change from li.s-item)
- Three-layer caching: HTML (5min), phash (permanent), market comp (6h SQLite)
- Batch DB writes (executemany + single commit) — warm requests <1s
- Unique Xvfb display counter (:200–:299) prevents lock file collisions
- Vue 3 nginx web service (port 8509) proxying /api/ to FastAPI
- Auction card de-emphasis: opacity 0.72 for listings with >1h remaining
- 35 scraper unit tests updated for new li.s-card fixture markup
- tests/ volume-mounted in compose.override.yml for live test editing
2026-03-25 20:09:30 -07:00
720744f75e chore: remove node_modules from tracking 2026-03-25 15:13:06 -07:00
7a704441a6 feat(snipe): Vue 3 frontend scaffold + Docker web service
- web/: Vue 3 + Vite + UnoCSS + Pinia, dark tactical theme (amber/#0d1117)
- AppNav, ListingCard, SearchView with filters/sort, composables
  (useSnipeMode, useKonamiCode, useMotion), Pinia search store
- Steal shimmer, auction countdown, Snipe Mode easter egg all native in Vue
- docker/web/: nginx + multi-stage Dockerfile (node build → nginx serve)
- compose.yml: api (8510) + web (8509) services
- Dockerfile CMD updated to uvicorn for upcoming FastAPI layer
- Clean build: 0 TS errors, 380 modules
2026-03-25 15:11:35 -07:00