Core trust scoring: - Five metadata signals (account age, feedback count/ratio, price vs market, category history), composited 0–100 - CV-based price signal suppression for heterogeneous search results (e.g. mixed laptop generations won't false-positive suspicious_price) - Expanded scratch/dent title detection: evasive redirects, functional problem phrases, DIY/repair indicators - Hard filters: new_account, established_bad_actor - Soft flags: low_feedback, suspicious_price, duplicate_photo, scratch_dent, long_on_market, significant_price_drop Search & filtering: - Browse API adapter (up to 200 items/page) + Playwright scraper fallback - OR-group query expansion for comprehensive variant coverage - Must-include (AND/ANY/groups), must-exclude, category, price range filters - Saved searches with full filter round-trip via URL params Seller enrichment: - Background BTF /itm/ scraping for account age (Kasada-safe headed Chromium) - On-demand enrichment: POST /api/enrich + ListingCard ↻ button - Category history derived from Browse API categories field (free, no extra calls) - Shopping API GetUserProfile inline enrichment for API adapter Market comps: - eBay Marketplace Insights API with Browse API fallback (catches 403 + 404) - Comps prioritised in ThreadPoolExecutor (submitted first) Infrastructure: - Staging DB fields: times_seen, first_seen_at, price_at_first_seen, category_name - Migrations 004 (staging tracking) + 005 (listing category) - eBay webhook handler stub - Cloud compose stack (compose.cloud.yml) - Vue frontend: search store, saved searches store, ListingCard, filter sidebar Docs: - README fully rewritten to reflect MVP status + full feature documentation - Roadmap table linked to all 13 Forgejo issues
43 lines
1.4 KiB
YAML
43 lines
1.4 KiB
YAML
# Snipe — cloud managed instance
|
|
# Project: snipe-cloud (docker compose -f compose.cloud.yml -p snipe-cloud ...)
|
|
# Web: http://127.0.0.1:8514 → menagerie.circuitforge.tech/snipe (via Caddy basicauth)
|
|
# API: internal only on snipe-cloud-net (no host port — only reachable via nginx)
|
|
#
|
|
# Usage: ./manage.sh cloud-start | cloud-stop | cloud-restart | cloud-status | cloud-logs | cloud-build
|
|
|
|
services:
|
|
api:
|
|
build:
|
|
context: ..
|
|
dockerfile: snipe/Dockerfile
|
|
restart: unless-stopped
|
|
env_file: .env
|
|
# No network_mode: host — isolated on snipe-cloud-net; nginx reaches it via 'api:8510'
|
|
volumes:
|
|
- /devl/snipe-cloud-data:/app/snipe/data
|
|
networks:
|
|
- snipe-cloud-net
|
|
|
|
web:
|
|
build:
|
|
context: .
|
|
dockerfile: docker/web/Dockerfile
|
|
args:
|
|
# Vite bakes these at image build time — changing them requires cloud-build.
|
|
# VITE_BASE_URL: app served under /snipe → asset URLs become /snipe/assets/...
|
|
# VITE_API_BASE: prepended to all /api/* fetch calls → /snipe/api/search
|
|
VITE_BASE_URL: /snipe
|
|
VITE_API_BASE: /snipe
|
|
restart: unless-stopped
|
|
ports:
|
|
- "8514:80" # Caddy (caddy-proxy container) reaches via host.docker.internal:8514
|
|
volumes:
|
|
- ./docker/web/nginx.cloud.conf:/etc/nginx/conf.d/default.conf:ro
|
|
networks:
|
|
- snipe-cloud-net
|
|
depends_on:
|
|
- api
|
|
|
|
networks:
|
|
snipe-cloud-net:
|
|
driver: bridge
|