Solo ProjectSince 2022Full-Stack

WTB Market

Inventory management platform for sneaker and trading card resellers.

A production SaaS with Discord-based auth, Stripe subscriptions, real-time product enrichment from StockX and CardMarket, public storefronts with programmatic API access, and portfolio analytics via MongoDB aggregation pipelines.

0%Core Web Vitals
0K+page views / year
0K+visitors / year

Architecture

Next.js 15 FrontendApp Router · React Query · Zustand · Framer Motion
Express REST APIRoute-based architecture · Public & Private endpoints
MongoDBMongoose · Aggregation Pipelines
Cloudflare R2S3-compatible object storage
DiscordOAuth2 · Roles · Webhooks · DMs
StripeCheckout · Subscriptions · Webhooks
External APIsStockX · CardMarket · RapidAPI

Ecosystem

5 products, one ecosystem.

WTB Market

SaaS Dashboard

The core platform. Authenticated dashboard where resellers manage inventory, run analytics, import via CSV, and operate storefronts.

  • Inventory lifecycle: stock → sold
  • KPI dashboard + net worth charts
  • Dual view: user & store shells
  • Freemium quota enforcement
  • Stripe-powered premium plan

WTB Market List

Public Tool

Public Want-To-Buy lists per user. Accessible via browser or programmatically via API key — built for Discord bots and external automation.

  • Public URL per user: /public/lists/:user_id
  • Regenerable API key per list
  • Bot-friendly REST endpoints (add/edit/delete items)
  • Factory-based verifyApiKey middleware
  • External tools can manage lists without the web UI

Discord

Community Layer

Primary identity and notification channel. OAuth2 login, guild-based role management, webhook alerts for store monitors, and subscription events.

  • OAuth2 authentication + automatic guild join
  • Discord roles = application permissions (free/premium/beta)
  • Stripe events → role assignment + DM notification
  • Store monitor webhooks with retry logic (3 attempts)
  • discord.js bot for role management

WTB Market Instagram

Marketing

Public-facing Instagram integration. Form submission endpoint routed through the backend for community requests and store inquiries.

  • Dedicated /instagram route in the API
  • Form submission handling + validation
  • Stores submissions in MongoDB (instagrams schema)
  • Bridges social presence with backend data layer
Coming Soon

WTB Market App

Mobile App

Public-facing Instagram integration. Form submission endpoint routed through the backend for community requests and store inquiries.

  • Dedicated /instagram route in the API
  • Form submission handling + validation
  • Stores submissions in MongoDB (instagrams schema)
  • Bridges social presence with backend data layer

Frontend System

Next.js 15 App Router with parallel route slots (@user / @store) hosting two distinct product experiences under one shell. Cookie-driven slot selection, middleware-level session protection, and a hybrid server/client data strategy.

RoutingApp Router · parallel slots (@user/@store) · dynamic [slug] routes
StateTanStack Query for server state · Zustand for cross-view UI (checked rows, dialogs, bulk ops)
Table SystemTableLayout + row/cell abstraction serves stock, sales, shipments, keywords — different schemas, same platform
API LayerfetchWithAuth helper — cookie forwarding, 401 handling, {ok,data,error} envelope normalization
CSV ImportPapaParse → normalize → validate → inline edit → selective import. Bulk operations at scale.
Query KeysCentralized key factory (storeKeys, inventoryKeys, userKeys) for predictable cache invalidation

Backend System

Node.js/Express 4 API with 80+ endpoints across 13 route domains. Convention-based file-system route auto-discovery. Service/provider separation keeps business logic decoupled from external API adapters.

Route LoadingDynamic filesystem scan — file naming conventions determine URL structure. Zero manual route registration.
AuthDiscord OAuth2 + JWT + MongoDB session + browser cookies. All four must stay consistent per request.
Database11 Mongoose schemas · embedded subdocument arrays · aggregation pipelines for analytics · connection caching
MiddlewareIP/UA blocking → CORS → body parsers → session → rate limiting → route handlers → Sentry → error handler
API KeysFactory-based verifyApiKey middleware — same pattern protects WTB lists (keyed by user_id) and stores (keyed by store_id)
Error HandlingAppError class · asyncHandler wrapper · centralized errorHandler · consistent {ok,data,meta,error} envelope

Key Features

Inventory Lifecycle

Full purchase → stock → sold tracking for sneakers, Pokémon cards, and custom items with prices, tags, notes, and tracking codes.

Product Enrichment Pipeline

4-step cascade: local DB by ID → local DB by name → StockX API by ID → StockX API by name. Resolves messy user data into structured product records automatically.

Public Storefronts & WTB Lists

Users operate public storefronts and Want-To-Buy lists accessible via web UI or API keys — enabling Discord bots and external tools to manage inventory programmatically.

Stripe Subscriptions + Discord Sync

Stripe webhooks trigger a chain: verify → update DB → assign Discord roles → send DM → create inbox notification → handle referral trial extensions.

Net Worth Analytics

Portfolio value, profit/loss, and weekly/monthly trend data computed via MongoDB aggregation pipelines. No in-memory computation.

Bulk CSV Import

Parse → normalize → validate → edit inline → import. Users fix invalid rows in place before committing. Powered by PapaParse on the frontend.

Freemium Quota Enforcement

MongoDB aggregation-based usage counting across 5 resource types (inventory, sales, keywords, shipments, lists). Middleware-level gating before route handlers execute.

Notification Inbox

Typed in-app notifications (error, success, warning, info) from API, web, and Discord sources. Supports bulk read/delete operations.

Technical Challenges

Dashboard Slot Architecture

Frontend

Two distinct product experiences (user view + store view) hosted under one shell using Next.js App Router parallel routes (@user / @store). Cookie-driven slot selection without duplicating the entire app structure.

Discord + JWT + Cookie Triple Auth

Backend

Discord OAuth2 grants identity. A JWT encodes roles and expiry. MongoDB sessions persist state. Browser cookies mirror user info for the frontend. All three must stay consistent on every request.

Multi-Source Product Resolution

Backend

Users paste imprecise data (misspelled names, missing SKUs). The backend progressively resolves it through four strategies while balancing accuracy, external API costs, and latency.

Reusable Table Platform

Frontend

One table system (TableLayout + row/cell abstraction + Zustand + action hooks) serves stock, sales, shipments, and keywords — each with different schemas, actions, and cell types.

Cross-Service Event Orchestration

Backend

Stripe subscription events trigger a chain across Stripe, MongoDB, and Discord API with side effects that must be idempotent. Discord role assignment, DMs, referral extensions, and inbox notifications all in one webhook handler.

Embedded Document Performance

Backend

Inventory items stored as embedded arrays for atomic operations. As inventories grow, aggregation pipelines, filtered projections for pagination, and careful $push/$pull/$set operators keep performance acceptable.

Stack

Frontend
Next.jsReactTanStack QueryZustandFramer MotionTailwind CSSNextUIShadcn UI
Backend
Node.jsExpress.jsMongoDBMongooseOAuth2JWTStripeCloudflare R2
Infrastructure
VercelCloudflareGitHub ActionsNginxPM2Uptime KumaWinston LoggerPrettierMulti-Environment DeploymentSentry

Impact

2022In production since
80+REST endpoints
11MongoDB collections
© 2026 All rights reserved

Designed & Built by Jacopo Carta.