Show listing age, seller type and promotion; filter watches by them #20

Merged
kubus merged 3 commits from feat/olx-listing-signals into main 2026-10-01 12:31:15 +00:00
Owner

Step 2b of the reseller roadmap. OLX and Vinted already send these with every search result, so no extra requests are made.

What changes

  • OLX: posted time (created_time, stored once), last refresh or bump, paid placement or highlight (top_ad/highlighted/urgent), and the business flag. The posting time used to be stored as Scout's observedAt; now they are separate fields.
  • Vinted: promotion and business flags, read per item id from the catalog page's embedded JSON (all 96 cards matched on a live page), plus the catalog-API fallback.
  • Allegro Lokalnie: its search page reports neither, so it stays unknown.
  • UI: rows, search results and the drawer show chips like Posted 14 mo ago · bumped 2 h ago, Promoted and Business. The age chip is green under a day old and orange over 30 days.
  • New today now counts listings posted today (or first seen today where no posting time exists), not listings merely re-seen today.
  • Deal watch settings: Seller: Any / Private only / Business only and Skip promoted listings.
    • OLX filters seller type natively (owner_type), so the one page Scout fetches is filled with the right sellers.
    • Elsewhere a listing is dropped only when its flag is known to be the other kind.
    • Filtered listings are neither learned from nor alerted on.
  • Manual search: the Seller filter now applies to Vinted too, and "Save as watch" carries it over.
  • Research watches are not filtered, so price bands still cover the whole market.
  • Migration 030.

Live check (2026-09-30)

  • OLX "rtx 3070" in Karty graficzne: 26 of 49 offers were posted more than 30 days ago. 48 private and 1 business; private only returned 49/49 private.
  • Unscoped, 15 of 61 results were promoted.
  • Vinted: 79/79 had a seller type.

Verification

  • npm run typecheck, npm test (253/253), npm run build, and npm audit --omit=dev (0 vulnerabilities) all pass.
  • Live smoke test on a temporary DB and loopback server.
  • iOS: no UI changes. The new fields are optional and iOS PATCHes only the fields it knows, so settings are kept when saving from iOS.

🤖 Generated with Claude Code

Step 2b of the reseller roadmap. OLX and Vinted already send these with every search result, so **no extra requests** are made. ## What changes - **OLX:** posted time (`created_time`, stored once), last refresh or bump, paid placement or highlight (`top_ad`/`highlighted`/`urgent`), and the `business` flag. The posting time used to be stored as Scout's `observedAt`; now they are separate fields. - **Vinted:** promotion and business flags, read per item id from the catalog page's embedded JSON (all 96 cards matched on a live page), plus the catalog-API fallback. - **Allegro Lokalnie:** its search page reports neither, so it stays *unknown*. - **UI:** rows, search results and the drawer show chips like *Posted 14 mo ago · bumped 2 h ago*, *Promoted* and *Business*. The age chip is green under a day old and orange over 30 days. - **New today** now counts listings posted today (or first seen today where no posting time exists), not listings merely re-seen today. - **Deal watch settings:** *Seller: Any / Private only / Business only* and *Skip promoted listings*. - OLX filters seller type natively (`owner_type`), so the one page Scout fetches is filled with the right sellers. - Elsewhere a listing is dropped only when its flag is known to be the other kind. - Filtered listings are neither learned from nor alerted on. - **Manual search:** the *Seller* filter now applies to Vinted too, and "Save as watch" carries it over. - **Research watches are not filtered**, so price bands still cover the whole market. - Migration 030. ## Live check (2026-09-30) - OLX "rtx 3070" in Karty graficzne: 26 of 49 offers were posted more than 30 days ago. 48 private and 1 business; *private only* returned 49/49 private. - Unscoped, 15 of 61 results were promoted. - Vinted: 79/79 had a seller type. ## Verification - `npm run typecheck`, `npm test` (253/253), `npm run build`, and `npm audit --omit=dev` (0 vulnerabilities) all pass. - Live smoke test on a temporary DB and loopback server. - iOS: no UI changes. The new fields are optional and iOS PATCHes only the fields it knows, so settings are kept when saving from iOS. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Show listing age, seller type and promotion; filter watches by them
Some checks failed
ci / verify (pull_request) Has been cancelled
59eb247a2d
OLX and Vinted already send these with every search result, so no extra
requests are made.

- OLX: posted time (created_time, stored once), last refresh/bump, paid
  placement or highlight, and business flag. The posting time no longer
  masquerades as Scout's observedAt.
- Vinted: promotion and business flags, read per item id from the catalog
  page's embedded JSON (and from the catalog API fallback).
- Allegro Lokalnie reports neither, so it stays unknown.
- Rows, search results and the drawer show "Posted 14 mo ago · bumped 2 h
  ago", Promoted and Business chips. "New today" counts listings posted today
  (or first seen today) instead of re-sightings.
- Deal watches can keep private or business sellers only (OLX natively,
  elsewhere only when the flag is known) and skip promoted listings. Manual
  search's Seller filter now applies to Vinted too. Research watches are not
  filtered, so bands still cover the whole market.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Align side-by-side form fields when only one has a hint line
Some checks failed
ci / verify (pull_request) Has been cancelled
f47e5da583
The Seller field's hint pushed its select down a line, so the Condition
select beside it stretched to fill the row. Fields in two-column rows and
the search filter grid now sit at the bottom of their cell.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Merge branch 'main' into feat/olx-listing-signals
Some checks failed
ci / verify (pull_request) Has been cancelled
0ea8e6a279
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
kubus merged commit d2b5329a19 into main 2026-10-01 12:31:15 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
kubus/scout!20
No description provided.