feat: establish auth listing and image vertical slices
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).
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user