Jason Stutman
All projects

Maxwell Cyberlogic · 2024–present

TickerSpark

Subscription SaaS for retail investor research. The studio's test bed for AI-assisted content production at scale.

tickerspark.ai

What it is

A subscription SaaS for retail investor research. Free / Pro / Platinum / Lifetime tiers. Paying users. Live at tickerspark.ai.

The product surface: a personalized 15-page AI research-report generator, a conversational AI analyst with quick and deep modes, server-side technical analysis with AI interpretation, brokerage portfolio integration across 100+ brokers, a daily email briefing, and weekly macro content. Underneath that is a content infrastructure layer — persona system, prompt library, macro content cadence — that the editorial side actually runs on.

Spark Reports — the AI research-report generator

The marquee feature. A user picks any public stock; the system generates a personalized 15-page research report covering business model, financials, technicals, ownership, risks, and catalysts. Two people analyzing the same stock get meaningfully different reports — tuned to their stated risk tolerance and time horizon via the persona system.

Under the hood, each report fans out 21 parallel tool calls against fundamentals, valuation, ownership, earnings, technicals, news, filings, and ratings APIs, then runs the gathered data through a multi-pass synthesis. The OpenAI Responses API does live web search natively (no Tavily). Earnings transcripts get parsed with segment-level context preserved. 10-K filings get content-extracted for filings-grounded analysis.

The model emits structured JSON via text.format.json_object enforcement — a defined schema covering the written report sections, raw data for 7 chart types, and letter grades (F → A+) across four categories plus an overall recommendation. The frontend renders directly from that schema.

The Sankey P&L flow

One of the seven charts is a Sankey diagram of revenue flowing through cost structure into net income, with per-segment breakdown for companies that report segmented revenue. It's the first thing most users screenshot. ECharts handles it.

Branded PDF export

A separate edge function renders each report as a branded PDF — dark-theme HTML template with cover page, table of contents, server-rendered chart images via QuickChart.io, grade card, and price targets. PDFShift handles the conversion. Output cached after first generation so re-downloads are free.

Async dispatch + retry

Reports take 30–60 seconds to generate. The edge function returns immediately and the UI polls user_report_logs.status for transitions (pending → processing → completed/failed). On failure, users get one free retry that reuses the same log row — failed reports never burn quota. Admin retries are unlimited.

The AI Analyst Chat — quick + deep modes

Multi-turn conversational analyst running on a shared modular tool library (29 tools across discovery, price, fundamentals, earnings, ownership, valuation, filings, sentiment, and macro categories). Two execution profiles:

  • Quick mode — gpt-5.4-mini, 26 tools, 2 max tool loops. Fast, lightweight, no 10-K downloads or full transcript parsing.
  • Deep mode — gpt-5.4, 29 tools, 5 max loops, adds three heavy tools: earnings transcript parsing, 10-K content extraction, and IR deck search.

Tool execution is multi-round and parallel: each round dispatches all model-requested tools concurrently via Promise.all. The loop runs until the model stops requesting tools or the round budget is exhausted.

Quotas enforced server-side with rolling-window counts: Free gets 1 lifetime query, Pro 20/day, Platinum 50/day. Sessions are stored with smart deduplication on the optimistic UI — drafts prefixed draft- are local-only until first message succeeds, then atomically materialized into the database with the real session ID swapped in.

Spark Charts — server-side technical analysis

A user picks a ticker and timeframe; the platform computes nine indicators (RSI, MACD, Bollinger Bands, ATR, OBV, Stochastic, pivot points, SMA 20 / 50 / 200) on FMP price data, then runs them through an interpretation prompt to produce structured plain-English guidance: entry, stop, targets, key levels, conviction, and rationale.

The output includes a multi-timeframe signal table showing whether daily, weekly, and monthly are in alignment — the most useful ten-second answer in technical analysis. Quotas: Free 1 lifetime, Pro 5/30 days, Platinum 30/30 days.

My Portfolio — brokerage integration across 100+ brokers

A read-only brokerage connection flow built on the SnapTrade TypeScript SDK. Users link Fidelity, Schwab, Robinhood, E*TRADE, TD Ameritrade, IBKR — over 100 brokers — through SnapTrade's OAuth portal. The platform receives webhooks on holdings updates with HMAC-SHA256 signature verification over sorted-key JSON, then uses Supabase Realtime to push the change straight into the UI without a refresh.

Connection health monitoring covers the boring-but-critical edges: broken-connection banner with reconnect CTA, auto-sync on load if data is older than 6 hours, 1-hour manual sync cooldown, live refreshBrokerageAuthorization call before each sync. Cash accuracy: is_cash_equivalentholdings are subtracted from raw cash balance to prevent money-market double-counting (so positions like Fidelity SPAXX don't show up as both cash AND a fund).

AI portfolio analysis

Two cached analysis branches per portfolio:

  • Briefing — Tavily web search across recent news for every holding, synthesized into a single timely brief. 24-hour cache.
  • Overview — structural analysis (sector concentration, factor exposure, risk profile). No web search. 7-day cache.

Plus Portfolio Chat— a Platinum-only conversational analyst that knows the user's exact holdings. Direct, opinionated tone (not support-bot-y) running on gpt-4.1 with a sequential tool-calling loop up to 5 calls per turn, three tools (news search, quote, price history).

The persona system & content voice

Five editorial personas, one restriction set, four system prompts. Each persona has its own voice profile, risk-tolerance assumption, and time-horizon framing. The report generator picks the right one based on the user's onboarding answers, then drives the entire report through it.

Originally these lived in Contentful (the company's legacy CMS). Migrated them into a Supabase-native personastable so they're editable and versionable alongside the product. Same operation as moving any editorial style guide from a wiki into something an actual team can work with.

Macro content cadence + daily briefings

A weekly market preview (Mondays) and weekly recap (Fridays). Each consumes a curated macro tool library — economic calendar, key indicators, market overview — plus the persona system to emit publication-ready content. The forward-looking + backward-looking newsletter rhythm I ran for twelve years at Angel Publishing, rebuilt as in-house edge functions (replaced a Pipedream-based v2).

Daily Mon-Fri email briefings layer on top, delivered through Brevo with Contentful RichText rendering and custom styling. Plus weekly recap emails. Newsletter operations transferred straight into a software product.

The sales bot is pure prompt engineering

A direct-response sales letter rebuilt as a system prompt. Zero LLM tools. ~250 lines running gpt-4o-mini that classifies visitor intent into 10 buckets and routes to predefined pitch paths with a Hook → Substance → Differentiator → CTA structure. 11 hard boundaries. 13-test adversarial suite. Same craft as twelve years of measured-against-KPI sales copy, in a different format.

Marketing surfaces

Five PASTOR-framework Google Ads landing pages on a shared shell (AI Stock Research, Stock Analysis Report, Chart Analysis AI, Motley Fool Alternative, Stock Research Tool). Plus Python-driven Google Ads campaign generation — templates that fill in ticker symbols across headlines and descriptions, generate keyword variations, and output CSVs ready for bulk Google Ads upload. Server-side conversion tracking via Google Ads API for offline conversion uploads (so Smart Bidding optimizes against real paying customers, not signups). Full GCLID + ga_client_id attribution stored in Stripe subscription metadata.

Subscription tiers + Stripe integration

Four plan tiers: Free, Pro, Platinum, Lifetime.

  • Free — 1 report lifetime, 1 chart lifetime, no AI chat
  • Pro — $249/yr or $7.99/mo: 3 reports/mo, 5 charts/mo, 20 AI queries/day, full feed, daily briefings, AI-curated model portfolio
  • Platinum — $479/yr or $24.99/mo: 10 reports/mo, 30 charts/mo, 50 AI queries/day, everything in Pro plus brokerage portfolio + Portfolio Chat
  • Lifetime — one-time purchase

Stripe runs dual-mode (test/live keys via x-environmentheader — same edge function code path serves both environments). Single-form one-click checkout on Stripe's deferred-intent pattern (CC form visible on page load, no async wait). Self-healing customer-ID recovery — if a stored Stripe customer ID is invalid or deleted, the function creates a new one and updates the DB transparently. Webhook hardening: lifetime guard, dunning-safe invoice.payment_failed, charge.refunded handler, customer.subscription.deleted guarded against subscriber→lifetime race conditions. Promo code system with offers stored in an offers table.

/ops internal admin dashboard

A custom internal dashboard at /ops. The kind of tool most companies stitch together from Mixpanel, Stripe, HubSpot, and a dozen tabs — replaced by one purpose-built surface:

  • MRR/ARR tracking with billing-interval awareness (annual subscriptions get divided by 12 in the MRR calc) and cancel_at_period_end handling so cancellations reduce MRR before the period actually ends
  • Audience segmentation with per-segment filters and CSV export, login-based segments built without cross-schema auth access
  • At-risk users + stuck reports queues
  • Activity feed + user lookup
  • /ops/reports tab — Report Monitor with per-tool failure diagnostics from a tools_meta JSONB column on every report row (so when a report fails, you can see exactly which of the 21 tools blew up and why)
  • Engagement metrics — Spark Charts and brokerage connection counts alongside subscription metrics
  • Pagination past Supabase's 1,000-row default for accurate total accounts

The engineering layer

  • 29-tool modular library at _shared/tools/ with a generic runAgent() runner; curated tool registries co-located with each consumer
  • In-house generate-report-v3 running 21 parallel tool calls (replaced an external Pipedream flow)
  • SnapTrade brokerage integration across 100+ brokers with HMAC-signed webhooks and Supabase Realtime UI updates
  • Dual-mode Stripe with self-healing customer-ID recovery and webhook hardening
  • Hardened RLS on all sensitive tables, Sentry monitoring, async dispatch with status polling and retry quota separation
  • Postgres extensions: pgvector (RAG over internal archives), pg_cron (scheduled jobs), pgmq (async work queue), pg_net (HTTP from Postgres)
  • Branded PDF export pipeline via PDFShift + QuickChart.io with result caching
  • Custom internal /ops dashboard with MRR/ARR tracking, billing-interval awareness, audience segmentation, per-tool failure diagnostics
  • Frontend: React 19 + Vite 7, TanStack Query, Tailwind 4, ECharts (Sankey-capable), Lightweight Charts (TradingView-style), shadcn/ui, Stripe React 5.4