Closes #15, #22, #24, #25. Closes #1 and #27 (already shipped in 0.2.0). ## CI/CD (#22) - .forgejo/workflows/ci.yml — Python lint (ruff) + pytest + Vue typecheck + vitest on every PR/push. Installs cf-core from GitHub mirror for the CI runner. - .forgejo/workflows/release.yml — Docker build/push (api + web) to Forgejo registry on v* tags; git-cliff changelog; multi-arch amd64+arm64. - .forgejo/workflows/mirror.yml — push to GitHub + Codeberg mirrors. ## Self-hosted installer (#25) - install.sh rewritten to match CF installer pattern: coloured output, named functions, --docker / --bare-metal / --help flags, auto-detect Docker/conda/ Python/Node/Chromium/Xvfb, license key prompting with format validation. ## Nginx docs (#24) - docs/nginx-self-hosted.conf — sample nginx config: SPA fallback, SSE proxy (proxy_buffering off), long-term asset cache headers. - docs/getting-started/installation.md — bare-metal install section with nginx setup, Chromium/Xvfb note, serve-ui.sh vs nginx trade-off. ## cf-orch agent (#15) - compose.override.yml — cf-orch-agent sidecar service (profiles: [orch]). Starts only with docker compose --profile orch. Registers with coordinator at CF_ORCH_COORDINATOR_URL (default 10.1.10.71:7700). - .env.example — CF_ORCH_URL / CF_ORCH_COORDINATOR_URL comments expanded. ## Docs - mkdocs.yml + full docs/ tree (getting-started, reference, user-guide) staged from prior session work. Bump version 0.2.0 → 0.3.0.
2.3 KiB
Architecture
Stack
| Layer | Technology |
|---|---|
| Frontend | Vue 3, Pinia, UnoCSS |
| API | FastAPI (Python), host networking |
| Database | SQLite (WAL mode) |
| Scraper | Playwright + Chromium + Xvfb |
| Container | Docker Compose |
Data flow
graph LR
User -->|search query| VueSPA
VueSPA -->|GET /api/search| FastAPI
FastAPI -->|Browse API or Playwright| eBay
eBay --> FastAPI
FastAPI -->|score_batch| TrustScorer
TrustScorer --> FastAPI
FastAPI -->|BTF enrich queue| XvfbScraper
XvfbScraper -->|seller profile| eBayProfile
eBayProfile --> XvfbScraper
XvfbScraper -->|account_age update| SQLite
FastAPI -->|SSE push| VueSPA
Database layout
Snipe uses two SQLite databases in cloud mode:
| Database | Contents |
|---|---|
shared.db |
Sellers, listings, market comps, community signals, scammer blocklist |
user.db |
Trust scores, saved searches, user preferences, background tasks |
In local (self-hosted) mode, everything uses a single snipe.db.
WAL (Write-Ahead Logging) mode is enabled on all connections for concurrent reader safety.
Seller enrichment pipeline
eBay's Browse API returns listings without seller account ages. Snipe fetches account ages by loading the seller's eBay profile page in a headed Chromium instance via Xvfb.
Each enrichment session uses a unique Xvfb display number (:200–:299, cycling) to prevent lock file collisions across parallel sessions. Kasada bot protection blocks headless Chrome and curl-based requests — only a full headed browser session passes.
Affiliate URL wrapping
All listing URLs are wrapped with an eBay Partner Network (EPN) affiliate code before being returned to the frontend. Resolution order:
- User opted out → plain URL
- User has BYOK EPN ID (Premium) → wrap with user's ID
- CF affiliate ID configured in
.env→ wrap with CF's ID - Not configured → plain URL
Licensing
| Layer | License |
|---|---|
| Discovery pipeline (scraper, trust scoring, search) | MIT |
| AI features (photo analysis, description reasoning) | BSL 1.1 |
| Fine-tuned model weights | Proprietary |
BSL 1.1 is free for personal non-commercial self-hosting. SaaS re-hosting requires a commercial license. Converts to MIT after 4 years.