TrendDEXH0 bonus article

Building TrendDEXa Global Fantasy Market with Vercel v0 and Amazon Aurora DSQL

A technical field note on turning a v0-generated trading surface into a Vercel app backed by Aurora DSQL order matching, live rooms, and a virtual-market ledger.

Stack

Vercel + Aurora DSQL

Theme

Fantasy market ledger

Tag

#H0Hackathon

I created this article for the purposes of entering H0: Hack the Zero Stack with Vercel v0 and AWS Databases.

#H0Hackathon

The internet already behaves like a market.

A creator uploads one video and becomes the main character for a week. A meme appears from nowhere, crosses TikTok, Twitch, X, and Discord, then vanishes by Friday. A sports moment, album rollout, AI demo, streamer drama, or movie trailer can move millions of people in a few hours.

TrendDEX turns that behavior into a fantasy entertainment exchange.

Users do not trade real securities. There is no cash-out, no investment advice, and no claim of ownership over a creator or trend. Instead, users receive virtual buying power and trade fantasy shares of creators, memes, and live culture moments. The game is taste plus timing: can you spot what the internet will care about before everyone else does?

The frontend was accelerated with Vercel v0. The backend is powered by Amazon Aurora DSQL.

That combination is the point of the project: a polished trading-style interface is only interesting if the ledger underneath it is deliberate, consistent, and built for concurrency.

The Product

TrendDEX has four main surfaces:

  • A public market screen with creator, meme, sports, music, tech, film, lifestyle, and entertainment markets.
  • A trade screen with price charts, Long/Short actions, functional time ranges, and virtual portfolio context.
  • Live market rooms with order book depth, trade tape, chat, presence, and open-order controls.
  • A portfolio screen with holdings, allocation, realized activity, and an immutable ledger feed.
  • Locked ops pages that show Aurora DSQL health, row counts, fee-vault accounting, and the automated market pipeline.

Guests can browse the market, but trading requires sign-in and onboarding. TrendDEX uses Shoo Google sign-in for hackathon-fast identity, then creates a local HTTP-only session. The onboarding flow is called Market Integrity Onboarding, not KYC, because this is not a legal identity product. It asks for verified email, acceptance of virtual-market terms, and privacy-light velocity checks using hashed device/IP subjects.

The goal is not to pretend this is a bank. The goal is to show a credible path from a fast v0 prototype to a product with real backend engineering decisions.

Why A Fantasy Market Needs A Real Ledger

The most important control in TrendDEX is not visually complicated. It is the order ticket: Long or Short, Market or Limit.

But behind that ticket, an order or fill has to update several pieces of state together:

  • reserved cash or reserved shares
  • the user's virtual cash balance
  • both counterparties' portfolio positions
  • immutable trade and fill rows
  • fee-vault accounting
  • sharded market volume buckets
  • derived price tick inputs

If cash updates but the portfolio does not, the app is broken. If a retry creates two trades, the app is broken. If a resting order fills twice, the app is broken. If thousands of users all hit the same market and every request updates one global row, the app is fragile.

That is why TrendDEX treats trading as a ledger problem, not a CRUD problem.

Why I Chose Aurora DSQL

The hackathon allowed Aurora PostgreSQL, Aurora DSQL, or DynamoDB. I chose Aurora DSQL because TrendDEX needs relational data modeling and ACID transactions, but the product concept is naturally global and bursty.

Live culture does not create gentle traffic. It creates spikes.

A creator goes live, a game trailer drops, a finals game ends, a drama clip spreads, and everyone reacts at once. That is exactly when the database model matters.

DynamoDB would be strong for very high-volume event ingestion, but the core TrendDEX ledger benefits from relational queries and transactional updates across users, portfolios, assets, trades, price ticks, fee records, and market candidates.

A traditional regional PostgreSQL database would be familiar and productive, but Aurora DSQL gives the project a stronger distributed SQL story while keeping a PostgreSQL-compatible programming model.

The technical position is:

v0 gave me speed on the interface. Aurora DSQL gave me a serious transactional backend for the ledger.

The Data Model

TrendDEX stores money-like values as integer cents and share quantities as integer micro-shares. No floats are used for ledger math.

The core tables include:

  • users: account profile and virtual cash balance
  • auth_accounts: Shoo identity mapping with hashed email storage
  • user_sessions: hashed local sessions with expiration and revocation
  • user_integrity_profiles: onboarding and cooldown state
  • assets: tradable fantasy markets
  • portfolios: user holdings by asset
  • trades: immutable user ledger rows with order/fill/counterparty/liquidity metadata
  • order_book_orders: open, partially filled, filled, cancelled, and expired orders
  • order_book_fills: matched buyer/seller fills with linked ledger trades
  • asset_volume_buckets: sharded buy/sell volume counters
  • price_ticks: derived price history for charts and execution
  • room_events and room_presence: live market-room feed and authenticated presence
  • market_candidates: discovered markets waiting for review or listing
  • market_pipeline_runs: audit trail for pipeline runs

Two choices matter a lot:

  1. Trades are immutable.
  2. Market volume is sharded.

A naive implementation might store current_price and volume on the assets row and update that row on every trade. That makes the popular asset row the bottleneck exactly when traffic spikes.

TrendDEX avoids that pattern. Trades are append-only, volume is written into per-minute sharded buckets, and chart prices are stored as derived price_ticks.

Handling Optimistic Concurrency

Aurora DSQL uses optimistic concurrency control. In practice, a conflicting transaction can return SQLSTATE 40001.

TrendDEX treats that as a normal distributed-database condition. The app retries the whole transaction with bounded exponential backoff and jitter. It does not retry one random query in the middle of the transaction.

The retry is safe because each order request includes an idempotency key.

The order flow looks like this:

  1. Resolve the current user from the signed HTTP-only session.
  2. Check whether the idempotency key already has an order result.
  3. Load the user and asset.
  4. Reject missing users, missing assets, or inactive assets.
  5. Load the latest price tick.
  6. Reserve cash for Long limit orders or shares for Short limit orders.
  7. Match against eligible resting orders by price-time priority.
  8. Allow partial fills and rest remaining limit quantity.
  9. Route unfilled market-order quantity to the system-liquidity account.
  10. Write immutable fills and buyer/seller trade rows.
  11. Update cash, portfolios, the fee account, room events, and volume buckets.
  12. Commit.

If Aurora DSQL returns SQLSTATE 40001, TrendDEX retries the full transaction.

That is the core technical story of the app.

Real Long/Short Behavior

TrendDEX started as a fantasy trading demo, but I did not want it to behave like a fake "number goes up" simulator.

The current market model includes:

  • maximum supply per asset
  • Long/Short market and limit orders
  • price-time matching
  • partial fills
  • cancellation and reserve refunds
  • system-liquidity fallback for instant market orders
  • fee calculation
  • fee-vault accounting
  • realized portfolio changes
  • trade history for leaderboard inspection

When a user places a Long limit, TrendDEX reserves the maximum needed cash plus taker fee. When a user places a Short limit, TrendDEX reserves shares from the portfolio. Fills consume those reserves; cancellations and expiries refund whatever remains. Fees are tracked in a dedicated fee account through linked trade/fill metadata so the ops page can explain where each fee came from.

It is still a fantasy market, not a real exchange. There is no real securities settlement and no cash-out. But the app has a real ledger and avoids the worst demo bug: letting users enter and exit positions with inconsistent price math.

The Market Pipeline

TrendDEX also includes an automated market pipeline.

The pipeline can ingest no-key public or curated trend sources, score candidates, and decide whether they should be listed, rejected, or sent to ops review.

Each candidate receives four visible scores:

  • Vel: velocity, or how quickly the trend is moving
  • Vol: volume, or how much public activity exists
  • Safe: heuristic moderation and duplicate confidence
  • Score: weighted composite score

High-confidence candidates can be auto-listed by cron. Manual ops runs show unresolved candidates for review, while already listed and rejected candidates stay hidden from that queue.

When a market is listed, TrendDEX creates:

  • an assets row
  • an initial price_ticks row
  • category and symbol metadata
  • future eligibility for trading and chart updates

Vercel Cron runs the pipeline daily for the hackathon-friendly deployment. The cron endpoint requires a bearer secret and does not trust spoofable User-Agent headers.

Realtime Without A Realtime Vendor

I wanted live freshness without adding another hosted service.

TrendDEX uses a simple hybrid approach:

  • After a successful trade, the browser emits a BroadcastChannel("trenddex-events") message.
  • Other open tabs in the same browser receive it and call router.refresh().
  • All tabs also poll /api/live/version.
  • Visible pages poll more often than hidden pages.
  • Asset rooms use short-lived SSE streams with snapshot polling fallback.
  • Room snapshots include order book depth, recent fills, recent room events, presence, and the

current user's open orders.

This is not WebSockets, and it does not pretend to be. But for the hackathon demo it solves the important problem: if I place or cancel an order in one tab, the other tab refreshes without a manual reload, and asset rooms feel alive without a separate realtime provider.

Vercel And v0

v0 was useful because it let me start from a polished mobile-first trading interface instead of spending the whole hackathon fighting layout.

The initial UI direction was:

  • dark mode
  • compact mobile-first trading surface
  • market leaderboard
  • asset chart
  • Long/Short order ticket
  • Market/Limit segmented control
  • market room panels
  • portfolio screen
  • Recharts charts
  • shadcn-style components
  • Lucide icons

From there, I turned the generated interface into a production Next.js app:

  • Server Components fetch dashboard data.
  • Client components handle tabs, charts, and local interactions.
  • Server Actions execute trades.
  • Route Handlers expose health, auth, cron, and live-version endpoints.
  • Vercel hosts the frontend and serverless backend.
  • Aurora DSQL stores the ledger and market state.
  • Vercel OIDC is used for AWS database access instead of committing long-lived AWS keys.

That last point matters for the submission. Secrets and AWS credentials are not stored in the repository.

Ops Proof

The app includes locked ops pages for judges and demo recording.

The /ops page shows:

  • Aurora DSQL configured status
  • database health
  • redacted cluster host
  • region
  • Vercel OIDC status
  • row counts
  • fee-vault accounting
  • order book depth and room events
  • architecture proof

The /ops/markets page shows:

  • market candidate review
  • manual pipeline runs
  • score explanations
  • recent pipeline run history
  • list/reject actions

This is useful for the hackathon because the project is not only a UI demo. The database state is inspectable.

What I Learned

The biggest lesson was that "full-stack" does not just mean frontend plus a database connection string.

The hard parts were the boundaries:

  • Where should the user identity be resolved?
  • Which trade inputs should the client be allowed to send?
  • How do retries stay idempotent?
  • Which rows become hot under load?
  • What state should be append-only?
  • What should be derived?
  • How do I prove the database is actually being used?

Aurora DSQL made me think carefully about optimistic concurrency and transaction scope. Vercel made deployment fast. v0 made the frontend fast. The interesting work was connecting those pieces in a way that could survive more than a happy-path demo.

What I Would Build Next

Given more time, I would add:

  • richer public trend source adapters
  • creator opt-out and moderation workflows
  • private leagues for friend groups
  • event-specific markets for tournaments, awards shows, and livestreams
  • deeper order-book mechanics like expiries UI, advanced order types, and maker/taker analytics
  • CloudWatch dashboards for transaction volume and SQLSTATE 40001 conflict rates
  • stronger anti-abuse checks beyond proof-of-personhood lite

TrendDEX is a fantasy market, but the architecture underneath it is intentionally serious.

Frontend in minutes with v0. A globally consistent virtual trading ledger with Aurora DSQL.

#H0Hackathon