Includes MFA-capable authentication, session and CSRF security, password recovery, listing lifecycle and ownership rules, inventory image metadata, local ImageStorage, migrations, tests, and implementation status documentation. Verification: npm test (62 passing) and integration suite (14 passing).
177 lines
4.6 KiB
Markdown
177 lines
4.6 KiB
Markdown
# Functional Requirements
|
||
|
||
## Public
|
||
|
||
### Homepage
|
||
- Minimal, search-first landing page.
|
||
- Search updates as the visitor types.
|
||
- Recently added available items appear below search.
|
||
- No-match state: `No relevant matches found.`
|
||
|
||
### Search
|
||
Search may include product name, Pokémon name, set, card number, category, description, event, year, brand, and tags.
|
||
|
||
Public search must use the same underlying search abstraction as admin search while respecting public visibility.
|
||
|
||
### Inventory
|
||
Filters include status, newly added, category, set, condition, price range, and event. Available filter values are derived from current data where appropriate.
|
||
|
||
Sorting includes:
|
||
- Recently Added
|
||
- Recently Updated
|
||
- Name A–Z
|
||
- Name Z–A
|
||
- Price Low→High
|
||
- Price High→Low
|
||
- Market Value Low→High
|
||
- Market Value High→Low
|
||
|
||
Sold is hidden by default but can be included through an explicit public filter/search.
|
||
|
||
Pending listings are public and clearly marked.
|
||
|
||
### Item details
|
||
Show images, title, product details, condition, asking price, market value where available, market update time, seller description, and configured seller contact methods.
|
||
|
||
Public pages have stable, shareable URLs.
|
||
|
||
## Inventory creation
|
||
|
||
Guided flow:
|
||
|
||
`Find/Create Product → Link Market Sources → Inventory Details → Images → Pricing → Review → List`
|
||
|
||
Required for an item to become Available:
|
||
- Product name
|
||
- Category
|
||
- Asking price
|
||
- Images
|
||
- Physical inventory record
|
||
- Condition
|
||
|
||
Provider matching is not mandatory.
|
||
|
||
### Existing Product
|
||
Admin can add another physical copy, reuse prior item data as a starting point, or create a new physical record after a previous copy sold.
|
||
|
||
### Provider matching
|
||
When creating a new Product, the system searches applicable configured providers and presents candidate matches. Admin can refine/search manually and confirm a mapping.
|
||
|
||
Mappings belong to Products and are reused by physical copies.
|
||
|
||
A provider may be marked Not Applicable. A Product may exist without any provider mapping.
|
||
|
||
## Inventory lifecycle
|
||
|
||
Inventory status:
|
||
- `ACTIVE`
|
||
- `SOLD`
|
||
- `ARCHIVED`
|
||
|
||
Listing status:
|
||
- `DRAFT`
|
||
- `AVAILABLE`
|
||
- `PENDING`
|
||
- `CLOSED`
|
||
- `ARCHIVED`
|
||
|
||
Owned items may have no active listing and may be designated for sale, personal collection, display, or other purposes.
|
||
|
||
Pending and sold items are locked against ordinary edits. Controlled corrections remain possible with audit history.
|
||
|
||
Relisting creates a new physical Inventory Item rather than reopening the sold physical record.
|
||
|
||
## Conditions
|
||
|
||
Card profile:
|
||
- NM
|
||
- LP
|
||
- MP
|
||
- HP
|
||
- Damaged
|
||
|
||
Merchandise profile:
|
||
- New
|
||
- Like New
|
||
- Used
|
||
- Damaged
|
||
|
||
Profiles and labels are configurable.
|
||
|
||
## Pricing
|
||
|
||
- Multiple providers supported.
|
||
- Median is the default valuation strategy.
|
||
- Outliers are retained and flagged.
|
||
- One valid source may produce a low-confidence value.
|
||
- Manual market-value overrides require a private reason.
|
||
- Provider errors are retained for admin visibility.
|
||
- Public sees only calculated/overridden market value, not source-level observations.
|
||
- Canonical currency is USD.
|
||
- Condition-specific values are used only when reliable data exists.
|
||
- No fabricated values.
|
||
- Pricing can refresh by item, Product, or bulk.
|
||
- Bulk refresh is asynchronous.
|
||
|
||
## Images
|
||
|
||
- Multiple images per physical item.
|
||
- Multiple-file upload and drag/drop.
|
||
- Reorder, primary selection, deletion, and later additions.
|
||
- Configurable image count limit.
|
||
- Automatic validation and optimization.
|
||
- Original retained where practical.
|
||
- Responsive derivatives generated.
|
||
- Seller can edit generated alt-text suggestions.
|
||
|
||
## Acquisition
|
||
|
||
Private acquisition information includes cost, date, source, location, shipping, tax, fees, trade value, and notes.
|
||
|
||
Total cost basis is calculated from component costs.
|
||
|
||
## Sales
|
||
|
||
Record Sale requires sold price and supports date, location/platform, fees, shipping, taxes, buyer information, and notes.
|
||
|
||
Multiple inventory items may belong to one sale.
|
||
|
||
Sale correction/undo is controlled and audited.
|
||
|
||
## Bulk operations
|
||
|
||
Supported:
|
||
- status change
|
||
- archive
|
||
- pricing refresh
|
||
- tags
|
||
|
||
Mark Sold uses the dedicated sale workflow and cannot bypass sold-price validation.
|
||
|
||
## Dashboard
|
||
|
||
Dashboard should meaningfully present:
|
||
- inventory count
|
||
- available listings
|
||
- sold count
|
||
- total acquisition cost
|
||
- total asking value
|
||
- total market value
|
||
- potential profit
|
||
- recently added items
|
||
- stale pricing
|
||
- missing images
|
||
- missing pricing
|
||
- provider errors
|
||
- recent activity
|
||
|
||
Actionable alerts link to filtered management views.
|
||
|
||
## Exports
|
||
|
||
Admin-only CSV, Excel, and JSON exports. Large exports may run asynchronously.
|
||
|
||
## Settings
|
||
|
||
General, inventory, pricing, and security settings are configurable as described in the supporting documentation.
|