Skip to content
→ All work

Case study 23 / 26

Puffer

A full-stack stock tracker with watchlists, market search and AI-written news digests delivered by background jobs.

Status
In development
Period
2025 — 2026
Domain
web · ai
Language
TypeScript
Last push
01 APR 2026
License
None stated
Source of claims
package.json, lib/inngest/functions.ts, lib/better-auth/auth.ts, components/SearchCommand.tsx, app/(root)/stocks/[symbol]/page.tsx

Puffer pairs a Next.js App Router interface — symbol search, per-stock pages built from TradingView widgets, and personal watchlists — with event-driven background jobs that use Gemini to write personalised welcome emails and daily, watchlist-aware market news summaries.

01/The problem

Market data is everywhere; context is not. Puffer is an attempt at a tracker that follows what you watch and tells you, in plain language, what happened to it today.

02/The system

Puffer pairs a Next.js App Router interface — symbol search, per-stock pages built from TradingView widgets, and personal watchlists — with event-driven background jobs that use Gemini to write personalised welcome emails and daily, watchlist-aware market news summaries.

Interface and background pipeline7 components
  • Next.js App Router to Better Auth
  • Next.js App Router to MongoDB
  • Next.js App Router to Finnhub
  • Better Auth to Inngest
  • MongoDB to Inngest
  • Finnhub to Inngest
  • Inngest to Gemini
  • Inngest to Nodemailer

03/Implementation

  1. 01Per-symbol pages (/stocks/[symbol]) composed from six TradingView widgets: symbol info, candlestick and baseline charts, technical analysis, company profile and financials.
  2. 02Command-palette symbol search (cmdk) backed by Finnhub, debounced at 300 ms.
  3. 03Watchlists persisted in MongoDB through a Mongoose model and server actions.
  4. 04Email-and-password authentication with Better Auth on a MongoDB adapter; sign-up captures country, investment goals, risk tolerance and preferred industry.
  5. 05An `app/user.created` Inngest event triggers a Gemini-written, profile-aware welcome email sent through Nodemailer.
  6. 06A daily cron job gathers each user's watchlist news from Finnhub — at most six articles, falling back to general market news — has Gemini summarise it, and emails the digest.

04/Engineering

Durable steps for AI work

Each stage of the digest — fetch users, gather news, summarise, send — is an Inngest step, so a failed model call retries in isolation instead of re-running the whole pipeline.

Graceful degradation per user

Failures are caught per user: one bad watchlist or summary produces an empty result for that user and the batch continues.

Bounded model input

News is capped at six articles per user before prompting, keeping summaries focused and token cost predictable.

05/Interface

No product screenshots are published for this project. The visual above is a code-driven representation of how it behaves, built from the repository source — not a screenshot.

06/Tech stack

  • Next.js 15
  • React 19
  • TypeScript
  • MongoDB
  • Mongoose
  • Better Auth
  • Inngest
  • Gemini
  • Finnhub
  • Nodemailer
  • Tailwind CSS
  • Radix UI

07/Result

Verified outcomes

  • Under active development — not presented as production-ready.

08/Links

Next case study

AI Detector →