Requirements
Living specification of what Vintage Value does, by module. Last updated 13 August 2026.
Case study (JSON)
The full written case study — problem, solution, architecture, AI role, human controls, security, and results — as a structured JSON file ready for publishing.
Capture
Get an item and its photos into the system with as little friction as possible.
- CAP-1Users can take photos with the device camera or upload existing files.
- CAP-2Acquisition cost and collection are optional at capture time.
- CAP-3Photos stay local while the user reviews them. Saving uploads both prepared sizes, creates an Item plus one ItemImage per photo, marks the first primary, and rolls the item back if photo-record creation fails.
- CAP-5Each captured photo is stored in two sizes: a store-sized copy (1600px) used for display and ConsignCloud, and a smaller research copy (900px) used for AI identification.
- CAP-6Photos are always re-encoded as JPEG on upload, so device-specific formats such as HEIC never reach storage or the store.
- CAP-9A photo's orientation never changes during resizing. Phone cameras record rotation in EXIF rather than in the pixels, and re-encoding discards EXIF, so the rotation is applied to the pixels before the copy is written — in the browser by decoding with the image's own orientation, and on the server by reading the EXIF orientation tag and rotating or mirroring to match.
- CAP-7Profile offers a one-time cleanup that re-encodes photos captured before downscaling existed, replacing the full-size file with the current two sizes and reporting how much storage was freed.
- CAP-8The cleanup runs in the browser, processes one photo at a time with visible progress, and skips any photo it cannot read without aborting the rest.
- CAP-4Identification is triggered automatically after save.
Identification
Turn photos into a confident, named identification.
- IDN-1Vision analysis returns ranked candidates with confidence scores.
- IDN-5Identification sends the smaller research copy of each photo, so analysis starts faster without any loss of accuracy — vision models downsample large images regardless.
- IDN-2Each candidate carries category, era, maker, and a short history.
- IDN-3Users select one candidate as the working identification for the item.
- IDN-4Users can refine with extra detail and re-run identification.
- IDN-6Each candidate stores its own generated history. Selecting a different candidate refreshes the displayed history and clears the current pricing recommendation, confidence, basis, and snapshot pointer so evidence from the previous identification cannot be presented as current.
- IDN-7Identification candidates are persisted as one batch and the running state always clears after success or failure, so a failed multi-record save cannot leave the screen permanently busy.
Pricing
Estimate resale value from real market data and recommend a decision.
- PRC-1Comparables are pulled from eBay and Etsy, with AI market synthesis as fallback.
- PRC-2Estimates expose a low, mid, and high band plus the basis used and a confidence label.
- PRC-3Commission and flat fees default from the user profile and remain editable per item.
- PRC-4Recommendation badge is one of strong buy, buy, caution, or pass, with a stated reason.
- PRC-5Snapshots are saved so pricing history can be tracked over time.
- PRC-6Acquisition cost and resale price each have a direct Save action that persists immediately to the item and refreshes dependent lists; saving a pricing snapshot is not required.
- PRC-7All pricing is explicitly USD. Existing legacy amounts were confirmed as USD without changing their numeric values, and every new or edited amount saves with an explicit USD marker; no currency conversion is performed.
- PRC-8Every market reference is labelled separately as a verified completed sale, auction result, active asking price, or AI estimate. eBay and Etsy API results are active listings and are never represented as completed sales.
- PRC-9Pricing confidence is evidence-weighted: verified sold records contribute most, active listings contribute less, estimates contribute least, and source diversity contributes modestly. Confidence is capped when no verified sold evidence exists.
- PRC-10The valuation band uses verified sold evidence when available; otherwise it uses active asking prices, and uses AI estimates only when neither stronger evidence type exists. The evidence counts and confidence score are shown to the user.
- PRC-11A re-search deliberately bypasses the five-minute cache, writes the replacement comparable set before removing the old set, and removes the replacement set if the old set cannot be removed.
- PRC-12Zero-dollar acquisition costs remain valid zero values. A snapshot cannot be saved until at least one comparable is included, and a failed snapshot save removes its orphan snapshot and clears the saving state.
Inventory & Collections
Organise and retrieve everything the user has researched.
- INV-1Items can belong to zero or one collection and be reassigned at any time.
- INV-2Search filters by free text, status, and recommendation badge.
- INV-3Portfolio summary reports total cost, expected resale, profit, and margin.
- INV-4Search, collection detail, dashboard summaries, portfolio totals, and store-send lists are filtered or aggregated on the server. The browser receives only the requested 25-record page or summary instead of the full inventory.
- INV-5Item deletion uses one confirmed server-side cascade from both item detail and collection views, removing the item plus its photos, candidates, comparables, pricing snapshots, history, and community-derived record. A copy already sent to the store is not deleted.
- INV-6Deleting a collection paginates every owned item, removes related graphs in chunks of 100, and verifies that no owned items remain before deleting the collection. Failed chunks keep the collection available for retry.
ConsignCloud Integration
Push researched inventory into the live consignment store.
- CC-1The store API key is held as a server-side secret and never exposed to the browser.
- CC-2Account linking matches strictly on the signed-in email address — a user can only ever link the consignor account whose email matches their own, and cannot browse or link other consignors.
- CC-7If no consignor account uses the signed-in email, the app explains the mismatch and tells the user to have the store add that email to their consignor record.
- CC-8Signup advises users intending to send items to use the same email as their consignor account.
- CC-3Inventory type (consignment, buy outright, retail) and split are configurable per user.
- CC-4Push maps title, description, details, category, cost, tag price, and SKU (the item id).
- CC-24Only the user's own item notes are sent as the store description. Internal research output — the buy / caution / pass rationale and any estimated margin or net-profit figure — is never sent to ConsignCloud, because store records are customer-facing.
- CC-5Item photos are uploaded and attached automatically during the push, up to eight per item.
- CC-6Items store their ConsignCloud id and sent date; already-sent items cannot be sent again.
- CC-7Push failures are recorded on the item and surfaced to the user with the reason.
- CC-8A user can only push their own items, and only into the account linked on their own profile.
- CC-9A public field mapping page documents every field sent to ConsignCloud, the transform applied, what is deliberately not sent, and what is written back after a successful push.
- CC-10Sending is blocked, and the block is logged, when the user has no linked consignor account.
- CC-11The consignment split is the consignor's share of each sale, stored by ConsignCloud as a decimal fraction (0.86 = consignor keeps 86%, store keeps 14%).
- CC-12The split is read from ConsignCloud automatically — taken from the split already used on the consignor's existing items — when the account is linked, and re-read at send time if it is not yet stored.
- CC-13Users cannot enter or edit their split. It is displayed read-only as "you keep X% / the store keeps Y%", because only the store can change consignment terms.
- CC-14Acquisition cost is sent to the store's "Purchase Price" field, which accepts a value on every inventory type including consignment. It is additionally sent as the built-in cost per item for buy-outright and retail only, because ConsignCloud rejects a cost per item on consignment inventory.
- CC-16Resale price maps to the item Price (tag price) in ConsignCloud.
- CC-17Each item is given a Vintage Value SKU in the form Vv000001 — the letters "Vv" followed by six digits, numbered sequentially across the whole app from Vv000001 onward — so any record in ConsignCloud is immediately identifiable as originating here.
- CC-18A SKU is assigned once, on the first successful send, and is then stored on the item and never changed or reused.
- CC-19Photos are downscaled in the browser when captured (longest edge 1600px, JPEG) so every stored photo stays within the 2MB request ceiling ConsignCloud enforces on base64 uploads.
- CC-20If a photo still cannot be sent, the item is created without it and the user is shown a warning naming the reason; the same warning is recorded in the integration log rather than being silently dropped.
- CC-21If the store-sized photo is rejected, the smaller research copy is tried automatically so the item still arrives with a picture.
- CC-22Items already in ConsignCloud offer a "Resend photos" action that re-uploads and re-attaches their photos to the existing store record, without creating a duplicate item.
- CC-23Resending photos is logged like any other integration call, and is refused with a clear reason when the item has no photos or has never been sent.
- CC-15An item without a positive, explicitly confirmed USD resale price is held back before the call is made, because ConsignCloud requires a tag price on every item.
- CC-25Every send and photo resend re-fetches the linked ConsignCloud account and verifies its email against the signed-in user; inventory type and split come from that verified live account, not browser-editable profile values.
- CC-26Existing remote item IDs are verified against both the linked account and the stored Vintage Value SKU before the app treats an item as sent or patches its photos.
- CC-27Remote creation is idempotent: a create-attempt marker is persisted before POST, uncertain outcomes are reconciled by account and SKU, and an unresolved attempt is blocked rather than creating a possible duplicate.
- CC-28SKUs are allocated from an admin-only atomic counter using compare-and-set updates, preventing two concurrent sends from receiving the same Vv number.
- CC-29Store sends require the connected store itself to report USD. Monetary values are converted to integer cents exactly once at the API boundary; currency conversion is not performed.
- CC-30Store sends are capped at three items per request to prevent photo-heavy timeouts. Successful items refresh into Already sent, while failed item IDs remain selected with the first failure reason shown for correction and retry.
Diagnostics & Logging
Make integration failures visible and diagnosable without guesswork.
- LOG-1Every ConsignCloud call writes a log entry recording the action, user, item, outcome, message, HTTP status, and duration.
- LOG-2Outcomes are classified as success, failure (external error or exception), or blocked (stopped by a precondition).
- LOG-3Successful and failed pushes store the exact payload sent, so mapping problems can be inspected after the fact.
- LOG-4Logs are readable, writable, and deletable only by admin accounts, enforced by row-level security.
- LOG-5Logging is written with the service role and never throws, so a logging failure cannot break the operation being logged.
- LOG-6Admins reach the log from Profile and can filter by outcome and expand any entry for full technical detail.
- LOG-7Every stored record type carries an optional free-text description field (up to 1000 characters) so records can be labelled in plain language for search indexing and admin review. It is optional everywhere and no existing behaviour reads or writes it.
Performance
Keep inventory navigation, research, and photo handling responsive as an account grows.
- PERF-1Owner inventory is paged and aggregated on the server for Search, Collections, Home, Dashboard, Portfolio, and store-send screens; matching client queries remain cached for two minutes and are invalidated after writes.
- PERF-2The inventory service reads owner-scoped records in 500-record pages but returns only the requested 25 records or compact aggregate totals to the browser.
- PERF-3Visible item thumbnails and collection covers are fetched together across as many 500-image pages as needed, with no fixed 250-image truncation, and smaller research images are preferred.
- PERF-4Item galleries load the selected store-quality image while thumbnails use smaller research copies with deferred decoding and lazy loading.
- PERF-5Multiple photos are prepared locally two at a time and are not uploaded merely for preview. On Save, each store and research copy uploads in parallel and all photo records are persisted in one bulk request.
- PERF-6Identification deduplicates research image URLs and sends at most the first six ordered photos, limiting upload and analysis overhead while retaining multiple angles.
- PERF-7Marketplace searches run eBay and Etsy concurrently, enforce eight-second marketplace and authentication timeouts, reuse identical research for five minutes, and make an explicit Re-search fresh.
- PERF-8Server photo cleanup queries only unfinished, non-deferred photos, checks sizes in parallel windows, marks large or unmeasurable photos for browser cleanup so they are not rechecked, and decodes images sequentially.
Public Site & Navigation
Explain the product and make supporting material easy to find.
- NAV-1Header navigation groups pages under three hover dropdowns: How, Why, and FAQ.
- NAV-2The FAQ dropdown contains FAQ, Demo, Help Center, and ConsignCloud Field Mapping.
- NAV-3Contact sits as a direct header link; Change Log, Requirements, and legal pages sit in the footer.
- NAV-4All header dropdowns share one component and highlight the label when a page inside it is open.
- NAV-5The Requirements page offers a public download of the written case study as a structured JSON file (vintage-value-case-study.json), covering the problem, solution, architecture, AI role, human controls, security, results, and disclosure. The file is generated in the browser and requires no sign-in.
- NAV-6The case study states only functionality that exists in this specification. No time-saved, margin, accuracy, or user-count figures are claimed, because none was measured against a baseline; outcomes are labelled as demonstrated rather than measured.
Onboarding & Setup
Get a brand-new user from sign-up to their first researched item without confusion.
- ONB-1A new account is taken to a guided four-step setup wizard — currency, selling fees, store connection, privacy — one decision per screen, with a progress bar and a "Step N of 4" label.
- ONB-2Each step saves as the user advances, so setup can be left and resumed without losing answers, and Back never discards an entered value.
- ONB-3Only currency is answered by default; the fees, store, and privacy steps are marked optional and can be passed through without entering anything.
- ONB-4Every field is explained in plain language with a worked example (e.g. a 20% commission on a $100 sale leaves you $80) instead of bare labels.
- ONB-5Setup ends on a confirmation screen whose primary action photographs the first item, with a secondary link to review settings.
- ONB-6Profile shows a "Finish setting up" checklist listing what is still outstanding and linking back into the wizard; it disappears once nothing is left.
- ONB-7Profile itself is a plain settings page — it no longer doubles as the onboarding screen and no longer redirects after a save.
Accounts & Privacy
Keep each user isolated and in control of their data.
- ACC-1Email/password and Google sign-in, with OTP verification on registration.
- ACC-2Row-level security scopes items, images, collections, profiles, identifications, comparables, and pricing snapshots to their owner — enforced server-side, not in the browser.
- ACC-4The app supports unlimited users; each sees only their own inventory, collections, pricing, and settings.
- ACC-5Every owned record stores an owner at creation time, and every list view filters on the signed-in user.
- ACC-6Only accounts with the admin role can see cross-user aggregate data, and only where the contributor consented.
- ACC-3Community data and photo reuse consent are opt-in and versioned with an audit record.
