Fix Vinted prices, partial listing-action saves, and stale triage views #17

Merged
kubus merged 2 commits from fix/reseller-correctness-pass into main 2026-09-30 21:15:53 +00:00
Owner

Step 1 of the reseller roadmap: correctness fixes that every later profit feature depends on.

Changes

  • Vinted card prices: the price is read from the trailing comma-separated label segments. Before, the first digits followed by "zł" were used, so Rozmiar: 38, 89.00 zł parsed as 3 889 zł and GTX 1660, 450.00 zł as ~1.66 M zł. With both the item price and the total-with-fee present, the item price is used.
  • Structured data: offers with a non-PLN priceCurrency are skipped instead of being read as złoty.
  • PATCH /api/listing-actions merges: decision, note and hidden are all optional; omitted fields keep their stored value. The web hide toggle and iOS swipes now send only the changed field, so an out-of-date note can no longer overwrite the stored one or unhide the row.
  • Triage views: Buy/Watch/Pass and Hidden-only views no longer apply the 12 h freshness cutoff (the default feed still does).
  • Location filter: Vinted listings (no location, always shipped) are no longer dropped when a city is set.
  • Save as watch: the location starts at "Polska" instead of copying one region/city/district.
  • Drawer calculator: "Margin" was profit ÷ cost, so it is relabelled "ROI on cost"; "Margin on sale" (profit ÷ resale) is added.

Testing

  • npm run typecheck, npm test (234 pass), npm run build, npm audit --omit=dev (0 vulnerabilities)
  • New regression tests for Vinted label parsing, non-PLN structured prices, partial-save merging, stale marked/hidden rows, and Vinted without location.
  • iOS changes (patchListingAction, swipe, demo transport, ScoutKit test) were not compiled locally — no Swift toolchain; please rely on the macOS CI run.

Not included

  • Re-applying edited excluded terms to a watch's existing baseline (separate PR).
  • Storing the Vinted buyer fee (needs a migration; planned with the flip ledger).

🤖 Generated with Claude Code

Step 1 of the reseller roadmap: correctness fixes that every later profit feature depends on. ## Changes - **Vinted card prices**: the price is read from the trailing comma-separated label segments. Before, the first digits followed by "zł" were used, so `Rozmiar: 38, 89.00 zł` parsed as 3 889 zł and `GTX 1660, 450.00 zł` as ~1.66 M zł. With both the item price and the total-with-fee present, the item price is used. - **Structured data**: offers with a non-PLN `priceCurrency` are skipped instead of being read as złoty. - **`PATCH /api/listing-actions` merges**: `decision`, `note` and `hidden` are all optional; omitted fields keep their stored value. The web hide toggle and iOS swipes now send only the changed field, so an out-of-date note can no longer overwrite the stored one or unhide the row. - **Triage views**: Buy/Watch/Pass and Hidden-only views no longer apply the 12 h freshness cutoff (the default feed still does). - **Location filter**: Vinted listings (no location, always shipped) are no longer dropped when a city is set. - **Save as watch**: the location starts at "Polska" instead of copying one region/city/district. - **Drawer calculator**: "Margin" was profit ÷ cost, so it is relabelled "ROI on cost"; "Margin on sale" (profit ÷ resale) is added. ## Testing - `npm run typecheck`, `npm test` (234 pass), `npm run build`, `npm audit --omit=dev` (0 vulnerabilities) - New regression tests for Vinted label parsing, non-PLN structured prices, partial-save merging, stale marked/hidden rows, and Vinted without location. - iOS changes (`patchListingAction`, swipe, demo transport, ScoutKit test) were **not compiled locally** — no Swift toolchain; please rely on the macOS CI run. ## Not included - Re-applying edited excluded terms to a watch's existing baseline (separate PR). - Storing the Vinted buyer fee (needs a migration; planned with the flip ledger). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Fix Vinted prices, partial listing-action saves, and stale triage views
Some checks failed
ci / verify (pull_request) Has been cancelled
75e3b3c65a
- Vinted cards: read the price from the trailing label segments so sizes
  or model numbers ("Rozmiar: 38", "GTX 1660") are no longer glued onto it.
- Structured data: skip offers priced in a currency other than PLN.
- PATCH /api/listing-actions merges omitted fields with the stored row;
  the web hide toggle and iOS swipes send only the field they change, so a
  stale note is never written back.
- Buy/Watch/Pass and Hidden views keep rows older than the 12 h feed window.
- Location filter no longer drops Vinted listings, which carry no location.
- Save as watch starts country-wide instead of pinning one district.
- Drawer calculator: relabel "Margin" as ROI on cost and add margin on sale.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Merge branch 'main' into fix/reseller-correctness-pass
Some checks failed
ci / verify (pull_request) Has been cancelled
e28e2e3c4b
kubus merged commit a9c5a8545d into main 2026-09-30 21:15:53 +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!17
No description provided.