CardApp Feature Map

Complete catalog of all implemented features as of 2026-04-11.


Authentication & Accounts

EndpointMethodDescription
/api/auth/login/emailPOSTSend magic link email
/api/auth/verifyGETMagic link callback (sets cookie, redirects)
/api/auth/login/{provider}GETInitiate OAuth redirect (Google, Microsoft, Discord)
/api/auth/callback/{provider}GETOAuth callback
/api/auth/passkey/login-optionsPOSTGet WebAuthn assertion challenge
/api/auth/passkey/loginPOSTValidate assertion and sign in
/api/auth/passkey/register-optionsPOSTGet WebAuthn registration challenge (auth required)
/api/auth/passkey/registerPOSTComplete passkey registration (auth required)
/api/auth/meGETGet current user info
/api/auth/logoutPOSTSign out
/api/accountGETGet account details
/api/accountPUTUpdate display name
/api/account/upgradePOSTUpgrade to Vendor account
/api/account/loginsGETList linked OAuth providers
/api/account/link/{provider}GETInitiate provider linking
/api/account/link/callbackGETProvider linking callback
/api/account/link/{provider}DELETEUnlink provider
/api/account/passkeysGETList registered passkeys
/api/account/passkeys/{id}DELETERemove a passkey

Frontend pages: /login, /account

Details:

  • Three sign-in methods: passkeys (WebAuthn/FIDO2), OAuth (Google, Microsoft, Discord), magic link email
  • ASP.NET Identity with cookie-based authentication (30-day sliding window)
  • No client-side tokens — browser sends cookie automatically via credentials: "include"
  • Account linking: connect multiple OAuth providers to a single account
  • Passkey management: register, list, and remove passkeys from account settings
  • Roles: User, Vendor, Admin, Owner, Banned
  • Owner auto-promotion via Auth:OwnerEmail config
  • See authentication.md for full details

Card Catalog & Search

EndpointMethodDescription
/api/cardsGETSearch cards with filters, sorting, pagination
/api/cards/{id}GETSingle card detail with prices and collection qty
/api/setsGETList all card sets
/api/metadataGETAvailable filter values (types, rarities, etc.)

Frontend pages: / (search), /cards/[id] (detail)

Details:

  • ~15,000+ Pokemon TCG cards loaded in-memory from JSON submodule
  • Full-text search across card name, artist, flavor text, abilities, and attacks
  • Filter by: set, type, rarity, artist, supertype, subtypes
  • Sort by: name, number, rarity, HP, release date, price
  • Infinite scroll pagination
  • Cards enriched with collection quantity badges and market prices

Inventory Management

EndpointMethodDescription
/api/inventoryGETList all user's inventory items
/api/inventoryPOSTAdd card (auto-increments if duplicate)
/api/inventory/{id}PUTUpdate quantity and/or purchase price
/api/inventory/{id}DELETERemove from collection
/api/inventory/valueGETPortfolio valuation with per-item gain/loss
/api/inventory/batchPOSTBatch operations (vendor only)

Frontend page: /inventory

Details:

  • Per-user collections with quantity tracking
  • Purchase price tracking with gain/loss calculation
  • Market value aggregation across all owned cards
  • Quick-add from search results

Pricing & Price History

EndpointMethodDescription
/api/prices/{cardId}GETPrice history (configurable days, source, variants)

Details:

  • Price history charts with configurable date range (Recharts line chart)
  • Multiple variants: holofoil, reverse holofoil, normal, 1st edition
  • Price types: low, mid, high, market, direct low
  • 7 price sources: Scrydex (primary), TCGdex, PokeTrace, PokemonPriceTracker, PriceCharting, TAG, PokemonAPI
  • Scheduled price fetching via K8s CronJob (daily at 6 AM UTC)

Price Alerts

EndpointMethodDescription
/api/alertsGETList recent price alerts
/api/alerts/unread-countGETUnread alert count
/api/alerts/{id}/readPOSTMark alert as read
/api/alerts/read-allPOSTMark all alerts as read
/api/alerts/thresholdGETGet alert threshold percentage
/api/alerts/thresholdPUTSet alert threshold

Frontend component: AlertBell in navbar

Details:

  • Triggered when market price changes exceed user-configured threshold
  • Unread count badge with 60-second polling
  • Dropdown with alert history, card navigation, threshold configuration

Vendor: Inventory Tags

EndpointMethodDescription
/api/inventory/tagsGETList user's tags
/api/inventory/tagsPOSTCreate tag with name and color
/api/inventory/tags/{id}PUTUpdate tag
/api/inventory/tags/{id}DELETEDelete tag (cascades to assignments)
/api/inventory/{itemId}/tagsPOSTAssign tags to item
/api/inventory/{itemId}/tags/{tagId}DELETERemove tag from item

Frontend components: TagManager, TagBadge

Details:

  • Color-coded tags for organizing inventory
  • Filter inventory by tag
  • Tags auto-created during CSV import
  • Unique per user (name + userId constraint)

Vendor: Custom Pricing

EndpointMethodDescription
/api/inventory/{itemId}/priceGETGet custom price
/api/inventory/{itemId}/pricePUTSet custom price (strategy + value)
/api/inventory/{itemId}/priceDELETERemove custom price

Frontend component: PriceEditor

Details:

  • Three strategies: Fixed, MarkupPercent, MarkupFlat
  • MarkupPercent: market * (1 + markup/100)
  • MarkupFlat: market + markup
  • Markup prices auto-recalculate when market prices update

Vendor: Bulk Import/Export

EndpointMethodDescription
/api/inventory/importPOSTCSV file upload
/api/inventory/exportGETCSV download

Frontend page: /vendor/import

Details:

  • CSV columns: CardId, Quantity, PurchasePrice, Tags
  • Validates CardId against in-memory card catalog
  • Upserts: increments quantity for existing cards
  • Tags column: semicolon-separated, auto-creates missing tags
  • Returns detailed report: added/updated/failed counts with per-row failure reasons

Vendor: Batch Operations

OperationDescription
updateQuantitySet quantity on all selected items
addTagsAssign tags to all selected items
removeTagsRemove tags from all selected items
deleteDelete all selected items (cascades prices + tags)

Frontend component: BatchToolbar on inventory page

Details:

  • Multi-select checkbox UI on inventory table
  • Vendor-only access
  • Ownership validation (only operates on user's own items)

Vendor: Analytics Dashboard

EndpointMethodDescription
/api/vendor/analyticsGETDashboard data (value history, top cards, trade stats)

Frontend page: /vendor/dashboard

Details:

  • Collection value over time (Recharts LineChart, configurable days)
  • Top 10 most valuable cards with images and market prices
  • Trade stats placeholder (wired for Phase 3)

Vendor: Public Storefront

EndpointMethodDescription
/api/vendors/{displayName}GETPublic storefront data

Frontend page: /vendors/[displayName]

Details:

  • Public (no auth required)
  • Shows vendor's inventory with custom prices and tags
  • Search by card name, filter by tags
  • Pagination support
  • Displays shop name and description from VendorProfile

Trading System

EndpointMethodDescription
/api/tradesGETList user's trades (filterable by status)
/api/trades/{id}GETTrade detail with items and history
/api/tradesPOSTPropose a new trade
/api/trades/{id}/acceptPOSTAccept trade (atomic inventory transfer)
/api/trades/{id}/declinePOSTDecline trade
/api/trades/{id}/counterPOSTCounter with modified items
/api/trades/{id}/cancelPOSTCancel trade
/api/notificationsGETList trade notifications
/api/notifications/unread-countGETUnread notification count
/api/notifications/{id}/readPOSTMark notification as read
/api/notifications/read-allPOSTMark all notifications as read

SignalR Hubs:

  • /hubs/trade — Per-trade groups, events: TradeUpdated, TradeItemsChanged, TradeCompleted
  • /hubs/notifications — Per-user groups, events: NewNotification, UnreadCountChanged

Frontend pages: /trades, /trades/[id], /trades/propose

Details:

  • Request-based trading: propose, counter, accept/decline/cancel
  • Real-time updates via SignalR when both parties are online
  • Atomic inventory transfer on accept (database transaction)
  • Trade history with JSON snapshots at each state change
  • Counter flow: modify card selections, roles flip
  • Conflict detection: validates quantities at accept time
  • Pokemon-inspired trade completion animation (4-phase CSS keyframes)
  • Trade notification bell with real-time unread count
  • All party combinations: user-to-user, vendor-to-user, vendor-to-vendor

Trade Animation

4-phase sequence (~3.5s total), Catppuccin Macchiato themed:

  1. Reveal (0.8s) — Cards fade in on opposite sides with glow
  2. Approach (1.0s) — Cards slide to center with rotation and energy trails
  3. Flash & Swap (0.7s) — Yellow radial glow, cards cross over
  4. Settle (1.0s) — Swapped positions, "Trade Complete!" text, shimmer particles
  • Pure CSS @keyframes, no animation libraries
  • Actual card images from pokemon-tcg-data
  • Multi-card: stacked with offset, top card leads
  • prefers-reduced-motion: skips to end state
  • Dismissible via click or Escape
  • Rendered as React portal overlay
  • Triggered by TradeCompleted SignalR event

Wishlist

EndpointMethodDescription
/api/wishlistGETList wishlist items
/api/wishlistPOSTAdd card to wishlist
/api/wishlist/{id}DELETERemove from wishlist

Frontend page: /wishlist

Details:

  • Per-user wishlist for tracking cards you want
  • Quick-add from card detail page
  • Cards display with images, names, and market prices

Artists

EndpointMethodDescription
/api/artistsGETList all artists with aggregate stats

Frontend page: /artists

Details:

  • Browse all card artists
  • Aggregate stats per artist (card count, collection count, total value)
  • Click artist to filter card search by that artist

Grading

EndpointMethodDescription
/api/grading/{cardId}GETPopulation data from grading services

Frontend page: /cards/[id]/grading

Details:

  • Population data from grading services (PSA, CGC, TAG, ACE)
  • EV calculator for expected grading value analysis
  • Population chart visualization

Admin Features

EndpointMethodDescription
/api/admin/usersGETList users with roles
/api/admin/users/{id}/rolePUTAssign role to user
/api/admin/expensesGET/POSTExpense ledger management
/api/admin/rarity-ranksGET/PUTCustom rarity ordering
/api/admin/margin-rulesGET/POST/PUT/DELETEVendor margin rules

Frontend pages: /admin, /admin/users, /admin/expenses, /admin/price-sync, /admin/rarity-ranks

Details:

  • User management with role assignment (User, Vendor, Admin, Owner, Banned)
  • Price sync control panel for on-demand price fetching
  • Expense ledger for tracking operational costs
  • Rarity rank editor for custom rarity ordering

Exchange Rates

Details:

  • Background service periodically refreshes currency exchange rates
  • Multi-currency display via CurrencyContext on the frontend
  • Cached exchange rates stored in database

Custom Items

EndpointMethodDescription
/api/custom-itemsGET/POSTUser-created non-card inventory items
/api/custom-items/{id}PUT/DELETEManage custom items

Details:

  • Users can add non-card items to their inventory (e.g., accessories, sealed products)
  • Custom pricing support

Database Schema

TableDescription
AspNetUsersUser accounts (extends IdentityUser with DisplayName, CreatedAt, UpdatedAt)
AspNetRolesRoles (User, Vendor, Admin, Owner, Banned)
AspNetUserRolesUser-role assignments
AspNetUserLoginsLinked OAuth providers (LoginProvider, ProviderKey)
AspNetUserClaims/RoleClaims/UserTokensIdentity infrastructure
StoredPasskeysWebAuthn credentials (CredentialId, PublicKey, SignCount, FriendlyName)
VendorProfilesShop name, description, public flag
InventoryItemsCard ownership per user (quantity, purchase price, condition)
CustomItemsNon-card inventory items
InventoryTagsUser-created color-coded tags
InventoryItemTagsTag-to-item assignments (join table)
CustomPricesVendor pricing (strategy: Fixed, MarkupPercent, MarkupFlat)
MarginRulesAutomated vendor pricing rules
PriceSnapshotsDaily market prices per card/variant/source
SalesSnapshotsSales data per card/variant/source
PriceAlertsPrice change notifications
GradePopulationsGrading stats from PSA, CGC, TAG, ACE
WishlistItemsCards users want to acquire
TradesTrade proposals between users (status, timestamps)
TradeItemsCards offered by each side in a trade
TradeHistoryState change log with JSON snapshots
NotificationsTrade event notifications per user
ExpenseLedgerEntriesOperational cost tracking
ExchangeRatesCached currency exchange rates
RarityRanksCustom rarity ordering
DocumentationSnapshotsPrice source documentation cache
AppSettingsKey-value config (alert thresholds)

Infrastructure

ComponentTechnology
FrontendNext.js 16, React 19, Tailwind CSS 4, shadcn/ui, Recharts, @microsoft/signalr
Real-timeASP.NET Core SignalR (WebSocket with fallback)
AuthASP.NET Identity, FIDO2 (passkeys), OAuth 2.0 (Google, Microsoft, Discord)
BackendASP.NET Core 10, EF Core 10
DatabasePostgreSQL 15
Card Datapokemon-tcg-data git submodule (~15,000+ cards)
Pricing7 price sources (Scrydex primary), daily CronJob at 6 AM UTC
EmailPostfix (SMTP, magic link delivery)
DeploymentKubernetes, Terraform, Traefik ingress with TLS
Auto-deployKeel (polls GHCR every 2 min)
CI/CDGitHub Actions → GitHub Container Registry (GHCR)

Frontend Page Map

RouteAuthDescription
/NoCard search with filters and infinite scroll
/cards/[id]NoCard detail with prices, grading link, add-to-inventory
/cards/[id]/gradingNoGrading population data and EV calculator
/loginNoSign-in page (passkey, OAuth, magic link)
/accountYesProfile, connected accounts, passkey management
/inventoryYesPersonal collection with value tracking
/wishlistYesWishlist items
/artistsNoBrowse artists with aggregate stats
/tradesYesTrade list with status filter tabs
/trades/[id]YesTrade detail with actions and real-time updates
/trades/proposeYesPropose trade with card selection
/vendor/dashboardVendorAnalytics with charts
/vendor/importVendorBulk CSV import/export
/vendors/[displayName]NoPublic vendor storefront
/adminAdminAdmin dashboard
/admin/usersAdminUser management with role assignment
/admin/expensesAdminExpense ledger
/admin/price-syncAdminPrice fetcher control panel
/admin/rarity-ranksAdminRarity rank editor