Manage

Configured sellers and tracked phone models

Read-only

Editing is disabled until admin access is added. Anonymous write access to the database has been removed, and this app has no sign-in yet, so the controls below are shown for review only. Admin authentication arrives in a later phase; changes must be made directly in Supabase until then.

Collector status

loading…
Latest scan
unknown
—
Last successful scan
—
Products captured
0
Variants captured
0
Available / unavailable
0 / 0
from current live variant offers
Normalization
unknown
—
Normalized variants
0
Rejected variants
0
Products with zero variants
0
Parser version
—
Grouped offers produced
0
colours collapsed into storage-level offers
Adapter version
—

Normalization issues

loading…
Collection and normalization run from a local command, not from this page — a browser button would require the ingest token to be exposed to client code.

Seller reliability

no collector-backed sellers

No seller has a collector key yet, so there is no collection health to report.

A successful capture resets a seller's streak to zero. Three in a row means the collector needs a person, not another retry.

Unusual price changes

loading…

Comparing consecutive observations of the same seller, model, storage, condition and SIM offer. Effective threshold 25%. Flagged rows are held for review only — nothing is rejected or hidden from the dashboard.

An offer seen only once has no previous price, so it produces no trend rather than a change from zero.

Add a retailer

configuration-driven
  1. 1
    Confirm approval

    You have permission to collect, and the retailer's robots.txt and terms permit reading the pages you list. Never guess a storefront URL.

  2. 2
    Register the seller

    Add a row to suppliers with a unique collector_key, active = true and approved_at set. Collection is gated on this — the scraper registry alone grants nothing.

  3. 3
    Add a registry entry

    Copy scraper/retailers/example-retailer.template.mjs to retailers/<key>.mjs, fill in hosts, collection URLs, currency, defaults and option aliases, then import it in registry.mjs.

  4. 4
    Select an adapter

    Shopify storefronts reuse the generic adapter unchanged. Another platform needs an adapter before it can be collected.

  5. 5
    Dry run

    npm run dry-run:retailer -- <key> — reads the public pages and writes nothing.

  6. 6
    Review the output

    Check products found, source variants, grouped-offer estimate, duplicates, and any zero-variant products before going further.

  7. 7
    Add it to the server-side allowlist

    Add a matching entry to supabase/functions/_shared/retailer-registry.ts — key, collector key, hosts, currency, defaults — and deploy. Until then ingest-retailer rejects the key, and the scraper registry alone cannot write.

  8. 8
    First live write

    npm run write:retailer -- <key>, then npm run status:retailer -- <key> to confirm normalization.

Adding a Shopify retailer should need configuration only — no new collector, no new SQL.

Sellers

0 configured
NameWebsiteStatusActions

Tracked phone models

0 models
BrandModelStorageStatusActions

What these records are. The sellers and models listed above are configuration and demo entries only. Nothing on this page collects prices, and no automated collection is running — the prices on the dashboard are seeded sample rows, not observations from any seller's website.

How collection will work. A later phase adds a scan runner that executes outside this app and writes what it reads from approved public seller pages. Each approved seller — small, medium, or large — will carry its own configured collection method, so a large retailer with a structured catalogue and a small shop with a simple product list can both be supported. Sellers without an automated method remain supported through manual entry.

Paused records. Anything marked Paused here is excluded from the dashboard's comparison table, charts, and counts.