Updates

Changelog

New features, improvements, and fixes shipped to ChainStreet Research.

IMPROVEMENTApr 25

Click any avatar to view a profile

Avatars are now clickable links throughout the app. In direct messages and group chats, click someone's avatar (or their name above the bubble, or the chat partner header at the top) and you go straight to their profile at `/dashboard/profile/<id>`. In the community feed, every author avatar on the standard post card, the feed-style post card, and inside comment threads is clickable. The same is true on the post detail page -- the large author avatar at the top, plus every commenter avatar below. Names next to those avatars are now linked too, so you can hit either the round photo or the name to navigate. The role badge overlay on each avatar is preserved, and the click is wired to stop event bubbling so you can click an avatar inside a card without accidentally opening the post. New users with no profile photo show the same letter-circle fallback as before, just clickable now.

View
NEW FEATUREApr 26

Trends Alerts, watchlist pin, and email-on-new-report

A four-piece drop on the research stack. (1) Trends Alerts (Pro+) -- click the bell next to any keyword in `/dashboard/research/google-trends` to set up an alert, with six presets (`Doubled in 24h`, `Tripled in 7 days`, `Crosses 80`, `Crashes below 20`, `Rising query`, `+30 pts jump`) plus a fully custom builder for absolute / delta / multiplier / rising-query triggers. The hourly evaluator pulls fresh interest data, fires when conditions hit, sends both an in-app notification and an email (if enabled), and respects per-alert cooldowns so you do not get spammed. Manage everything (pause / resume / test-fire / delete) at `/dashboard/research/google-trends/alerts`. Pro: 20 alerts, Elite: 50. (2) Research universe expanded to 25 symbols -- the EDGAR backfill picked up another 18 names beyond the original mega-cap seven (AVGO, AMD, NFLX, BRK-B, JPM, V, MA, UNH, XOM, JNJ, WMT, COST, HD, PG, BAC, CRM, ORCL, NFLX), so coverage at `/dashboard/research-reports` jumped from 17 docs across 7 tickers to ~200 docs across 25. (3) Pin-to-watchlist CTA -- the research-reports deep dive now exposes a one-click watchlist toggle right next to the View Source button, so an Elite reader can save a name without bouncing back to the stocks page. (4) AI report tab on stocks deep dive -- the existing Research tab on `/dashboard/stocks/<SYMBOL>` now leads with a new `ResearchPreviewPanel` that shows the latest AI report headline, TL;DR, top bullets, and tone badge inline, with a Full Report button that jumps to the deep dive. Below that, the existing AI Insight stream and Social Sentiment panels still render. Non-Elite users see a clean Pro-style upgrade card. (5) Email-on-new-report -- whenever the AI pipeline publishes a fresh report for a symbol you have on your watchlist (Elite tier only), you get both an in-app notification and an email with the headline, TL;DR, and a deep link, idempotently logged so you never get duplicate notifications for the same document.

View
NEW FEATUREApr 26

Research Reports: AI-summarized SEC filings now live for Elite

Phase B and C of the earnings research engine just shipped. Phase B (AI processing) ran every parsed 10-K through a single-shot prompt against our LLM, producing a one-sentence headline, 2-3 sentence TL;DR, 5-7 quick-look bullets, a management tone classifier (`confident` / `cautious` / `defensive` / `neutral`) with a -1..+1 numeric score, non-obvious alpha signals worth flagging to a trader, structured guidance (raised / reaffirmed / lowered + notes), explicit risks management called out, weighted themes (each with sentiment + up to 3 supporting excerpts and the section they came from), and ticker mentions -- every other public company referenced in the filing, classified as competitor / partner / customer / supplier / general with a sentiment label and confidence score. The first batch processed AAPL, MSFT, NVDA, GOOGL, AMZN, META, and TSLA -- 7 documents, 175 themes, and 25 cross-company mentions sitting in the database, ready to power downstream views. Phase C (public UI, Elite-only) ships a new Research Reports entry in the Elite section of the sidebar at `/dashboard/research-reports`. The index lists every analyzed symbol as a card showing its latest filing kind, AI headline, tone badge, and document count -- searchable by ticker / company / headline and filterable by tone. Click a card to drill into `/dashboard/research-reports/<SYMBOL>` for the full deep dive: headline + TL;DR + bullets, three side-by-side panels for alpha / guidance / risks, a themes section with excerpt quotes, a mentions table, and a sidebar of prior analyzed reports for the same symbol. Slash command `/research <SYMBOL>` works in every DM and group chat -- e.g. `/research AAPL` or `/research $NVDA` -- and renders a compact card with tone, headline, top bullets, alpha signals, and theme tags, linking to the full report. Coverage expands daily as the EDGAR cron pulls new filings.

View
NEW FEATUREApr 26

Earnings research engine -- SEC filings now flowing in

Phase A of the earnings research engine shipped today (admin-only for now). The system pulls 10-K, 10-Q, and earnings-relevant 8-K filings from SEC EDGAR, parses them into clean sections (CEO letter, business overview, risk factors, MD&A) and stores them in a unified `ResearchDocument` schema that is source-agnostic -- so when transcripts get plugged in via FMP later, they fall into the same store and the same downstream pipeline. The first backfill covered AAPL, MSFT, NVDA, GOOGL, AMZN, META, TSLA -- all parsed cleanly with sections ranging from 6k to 246k characters of clean text per filing. What is live: a new Research Engine entry under the admin sidebar lets you browse documents, inspect parsed sections + raw text in a side drawer, kick off ingestion runs against any ticker list, and manage the universe of tickers that get pulled daily. What is next: AI summarization, theme extraction, and cross-symbol mention search land in Phase B (Abacus LLM API). Public slash commands like `/research AAPL` come in Phase C. Earnings call transcripts plug in once the FMP Ultimate subscription is wired up. The daily 7am ET pull is scheduled and runs against the enabled universe automatically.

View
IMPROVEMENTApr 25

Unread DM badge across the app -- and forex `/price` works again

Two changes shipped together. Unread DM badge -- when a new direct message lands while you are anywhere outside `/dashboard/messages`, you will now see a red pill with the count on the Messages entry in the left sidebar (favorites and the regular nav both render it; the collapsed sidebar shows a small dot in the top-right). The same red pill also rides on the inbox icon in the top bar so you spot it from any page on desktop, and on mobile/tablet a separate pill appears next to the bell whenever you are not already on the messages page. The count refreshes every 25 seconds, pauses while the tab is hidden to save battery, and recomputes immediately when you switch back to the tab. The badge clears the moment you open the conversation -- there is no "mark all read" button to chase. Under the hood the count comes from a single shared poller so adding the badge to multiple places does not cause extra network traffic. Forex `/price` fixed -- `/price EURUSD`, `/price GBPJPY`, etc. were returning a `?` placeholder because the slash handler still expected the old flat forex API shape; it now unwraps the `{quote: {...}}` envelope the same way `/price` for stocks already does, and renders the live price + 24-hour change correctly for every supported pair. Crypto and stock `/price` were unaffected.

View
FIXApr 25

Slash /quote and /chart work again for stocks; profile View stats button surfaces correctly

Two bugs and one small UX fix. Slash /quote and /chart for stocks were broken since the Apr 24 data-feed migration -- `/quote TSLA` returned `No quote for TSLA` and `/chart NVDA 1d` showed `loading...` forever, because the underlying stock and forex API endpoints changed shape (now wrap the quote object and use `points` instead of `bars` for chart data) and the slash handlers and DM mini-chart parser were still reading the old shape. The handlers now unwrap the new `{quote: {...}}` envelope, the chart parser reads `points`, and the timeframe tokens (`7d`, `1m`, `3m`) are translated to the feed-compatible range strings (`5d`, `1mo`, `3mo`) so every chart timeframe renders correctly. Crypto charts and forex `/price` were never affected. Profile View stats button -- on user profiles, the stats button only surfaced when the user had `Show portfolio %` turned on in privacy settings, which meant a creator who only opted in to share `Show performance` had no entry point for their performance card. The button now appears whenever either privacy toggle is on, and is renamed `View stats` to match the leaderboard. The same fix applies on the leaderboard rows.

View
IMPROVEMENTApr 25

Leaderboard: light mode, earned badges, clickable socials -- plus slash commands in community posts

Three changes shipped together. Leaderboard now adapts to your theme -- the page was previously locked to a dark surface and looked broken in light mode; every row, header, dropdown, drawer, and chart now uses the active theme tokens so the leaderboard reads cleanly on white as well as dark. Earned badges on every row -- when a user has badges turned on in their profile, their top earned badges (showcase pins first, then highest-tier earned) now render inline next to their name on the leaderboard, mirroring how they appear on profile cards. The leaderboard already showed their clickable social handles (X, LinkedIn, GitHub, YouTube, Telegram, Discord, Reddit, website, email) but a few rows had stale link logic; every social icon now opens the correct platform URL in a new tab and stops the row click from navigating away. Slash commands work in community posts now -- the same `/` autocomplete you use in DMs is wired into the community composer. Type `/` and the dropdown opens with all 16 commands; pick one, fill in the args, and press `Cmd/Ctrl+Enter` to run it. The result is inserted inline into your post, so `/price BTC`, `/news crypto`, `/portfolio`, `/poll`, `/whale`, `/trends`, `/fng`, `/heatmap`, `/quote`, `/journal`, `/play`, `/ai`, `/me`, and `/gif` (which sets the post GIF) all work the same way they do in chats. Click the new Slash button in the composer toolbar for the full command catalog any time.

View
NEW FEATUREApr 25

DM photos, chart embeds, and 16 slash commands across all chats

Messages just got a major upgrade. Photo sharing: tap the new image icon in any DM or group chat composer to upload a JPEG, PNG, WebP, or GIF (up to 10 MB) -- the photo posts inline with a click-to-zoom card. Chart embeds: the line-chart icon opens a quick picker for any crypto, stock, or forex symbol with timeframe options (1d, 7d, 1m, 3m, 1y); the message renders a live mini sparkline that everyone in the chat sees. 16 slash commands ship today and work in every DM and group chat. Type `/` to open the autocomplete dropdown -- arrow keys to navigate, Enter to insert. Market data: `/price BTC`, `/quote TSLA`, `/chart NVDA 7d`, `/news crypto`, `/trends bitcoin`, `/heatmap`, `/fng`, `/whale`. Share what you are doing: `/portfolio`, `/play latest`, `/journal latest` post embed cards directly into the chat. Social: `/poll Question | A | B | C` creates an inline poll with one-tap voting, `/gif rocket` searches GIPHY, `/ai is BTC overbought?` posts a one-shot Copilot answer, `/me trims TSLA` renders an IRC-style emote. Type `/help` any time to see the full catalog. Cards render natively for every member of the conversation -- no link unfurls, no redirects.

View
FIXApr 25

Messages: tag chips & bubbles polished, Leaderboard avatars no longer 404

Three quick fixes shipped after Phase 15A. DM bubbles: the sent-message bubble was a hard primary fill that left `$TLSA` and `#defi` chips inside it almost unreadable; sent bubbles now use a soft tinted primary with a thin ring, and received bubbles get a matching ring for parity in both light and dark mode. Tag chips: chips inside DMs and the community feed are now opaque pill boxes — hashtags render in violet, $tickers in amber — with a 1px ring so they read clearly on white, dark, and inside any colored bubble. They still route to the same destinations: `#tag` opens the tag detail page, `$BTC` redirects to the coin page, `$AAPL` opens the stock page, and `$EURUSD` opens the forex page. Leaderboard 404: clicking another user's avatar or name on the leaderboard previously pointed at `/u/<username>`, which never existed; it now goes straight to `/dashboard/profile/<userId>` and loads cleanly.

View
NEW FEATUREApr 25

Research suite: Google Trends, Keyword Research, and 13 new news sources

The biggest research drop yet just shipped under a new Research section in the sidebar. Google Trends explorer at `/dashboard/research/google-trends` lets you compare up to 5 keywords at once across nine timeframes (1h, 4h, 1d, 7d, 1m, 3m, 12m, 5y, all-time) on a multi-line normalized interest chart, with Related Queries (rising and top) and a country-level Geo Breakdown for any keyword you click. Save up to 50 keywords to a personal Trends Watchlist and the system caches them server-side (Postgres) so the page loads instantly the next visit, with TTLs that match the timeframe (5 min for hourly windows up to 7 days for all-time). Keyword Research at `/dashboard/research/keywords` is wired to the KeywordsEverywhere API: type a single keyword for a 12-month volume bar chart, CPC, and competition score, or paste up to 100 keywords for a sortable, exportable bulk table with CSV download. Presets cover crypto, forex, stocks, indices, and meme tickers in one click. Server-side cache is a 7-day window so duplicate lookups never cost a second credit. Plus 13 new news sources wired into the firehose -- crypto picks up Bitcoin.com, CryptoSlate, CoinDesk, BeInCrypto, Bankless, and The Defiant; stocks adds Investing.com, ZeroHedge, and Seeking Alpha; forex adds ForexLive, DailyFX, and FXStreet. News default tab is now configurable -- pick your starting tab in `Settings → News Feed Defaults` and the news page opens to it on first visit (localStorage still wins per-session for power users).

View
NEW FEATUREApr 25

Re-issue analyst codes + admin email preview

Two operator tools shipped to round out the analyst program. Re-issue 40% codes (super-admin): open `Admin → Analyst Verification`, find the verified analyst whose 30-day codes are stale or expired, and click the new emerald `Re-issue codes` button. The system creates a fresh pair of single-use Lemon Squeezy codes (Elite Monthly + Elite Annual, 40% off, 30-day expiry), resets the drip clock so day-3 / 10 / 25 reminders fire again with the new codes, and dispatches a fresh "You are a verified analyst" email to the analyst with the new codes inline. The day-0 welcome email is preserved so it does not get re-sent. Useful for analysts who never redeemed their codes the first time around, or for hand-extending the 40% rate after the original 30 days lapse. Admin email preview (admin or super-admin): new `Admin → Email Preview` page renders any analyst-cohort transactional email in a sandboxed iframe with sample parameters you control (recipient name, monthly code, annual code, issue date, expiry date). Pick the email kind from the dropdown (analyst verified day-0, day-3 feature education, day-10 social proof, day-25 expiry reminder), and the iframe re-renders the exact HTML the production cron would dispatch. A "Send test to my email" button drops the rendered email into your inbox so you can sanity-check rendering across mail clients before shipping changes.

View
NEW FEATUREApr 25

Analyst drip campaign: Day 3, 10, and 25 follow-ups for verified analysts

Verified analysts now receive an automatic three-step follow-up after their welcome email. Day 3 walks them through the parts of Elite that earn their keep for analysts (unlimited Copilot, Signals, Whale, Options Flow, Heatmap, Journal exports, Strategy Builder). Day 10 shares a typical analyst week on the platform and points at the leaderboard. Day 25 lands as a heads-up that the 40% codes expire in roughly 5 days. Every email re-displays both Elite codes (Monthly and Annual) so they never have to dig through their inbox. The drip is fully idempotent (uses `User.analystEmailsSent`), automatically suppresses itself once an analyst upgrades to Elite, and skips users who never received codes (LS hiccup). One toggle controls the whole sequence under Notifications > Analyst Drip. Wired into the existing daily `/api/cron/trial-lifecycle` pass with a polite per-run cap of 200 sends.

View
NEW FEATUREApr 25

Manual discounts for any user + auto-issued 40% Elite codes for verified analysts

Two operator tools just shipped, both wired straight into Lemon Squeezy. Manual discount tool (admin and super-admin): open any user from `Admin → Users` and a new Discount panel sits right above the badge manager. Choose percent or fixed-amount, type the value, optionally restrict to Pro Monthly, Elite Monthly, or Elite Annual, set a reason and an expiry window, and click Issue. The system creates a single-redemption Lemon Squeezy code in the chosen variant scope, persists the issuer, the timestamp, and the expiry on the user record, and surfaces an active-discount card on the same panel. Replacing or revoking a code does a best-effort cleanup on the LS side too. Auto-issued analyst codes: when a super-admin clicks Verify on an analyst application from `Admin → Analyst Verification`, the system now creates two Lemon Squeezy codes for that user automatically: a 40% off Elite Monthly code and a 40% off Elite Annual code, both single-use, both 30-day expiry, both restricted to the matching variant. The codes are persisted and emailed to the analyst in a fresh "You are a verified analyst" email that walks them through redemption. The verified-analyst row on the admin board now shows an emerald `40% Elite codes sent` chip with the issue date so operators can confirm at a glance.

View
NEW FEATUREApr 25

Hashtags, $tickers, and the Trends board

A new tag layer just shipped across community and journals. Type `#thesis` or `$NVDA` anywhere in a community post or your private journal and the system tokenizes them into clickable chips that route to a brand-new tag detail page. Hashtags render in violet, asset cashtags in primary gold, and DMs render the same chips read-only without indexing private content. The Trends dashboard at `/dashboard/trends` ranks the most-mentioned tags across 24h, 7d, 30d, and 1y windows, with a separate filter for hashtags vs. assets. Click any row to open the full mention feed for that tag. Community posts surface the full body, while journals surface only the symbol and thesis (your P&L and notes never leave your private space). The omnibar (Cmd+K) also picks up tag matches when you type `#` or `$` followed by 1+ chars and shows live mention counts beside each suggestion. Heavy data engine under the hood: every post and journal is parsed once on save, mentions are deduped per source, and the Trending API uses a single grouped aggregate so the board loads instantly even with thousands of tags.

View
NEW FEATUREApr 25

Country flag badges + Analyst verification program

Two identity additions just shipped. Country flag badges: during onboarding you now pick your country from a searchable list of 197 nations. The flag emoji becomes a permanent badge on your profile, leaderboard cards, and posts — pinned automatically to slot 0 and impossible to remove. You can change it any time from `Settings → Public Profile → Country`. The badge picker on `/dashboard/achievements` shows it as always-pinned with a tooltip explaining the only way to swap it is via Settings. Analyst program: during onboarding you can self-declare as an analyst by ticking I publish original analysis or research and providing a LinkedIn URL plus one published sample. That immediately starts a 30-day Elite trial and adds an `Analyst (Pending)` badge. A super-admin reviews your application from the new `Admin → Analyst Verification` panel; once verified you keep the Elite trial, your badge upgrades to `Verified Analyst` (epic, amber-300), and you become eligible for a 50% Elite discount issued separately. Existing users can opt in any time from Settings (UI ships next).

View
NEW FEATUREApr 25

Daily Missions, streak shields, and 5 new badge ladders

Two big additions to the engagement system. Daily Missions: a new card on `/dashboard/home` shows you 3 rotating missions every UTC day — pick from `Chart Surfer`, `Watchlist Builder`, `Portfolio Mover`, `Paper Trader`, `Journal It`, `Town Crier` (community), `Backtest Lab`, `Class in Session` (college lessons), `Showed Up` (auto-claim for visiting), `Showcase Curator` (pin a badge), `Ask the Oracle` (AI chat), and more. Each completed mission awards 5–15 points when claimed; a balanced selector picks 1 mission per category bucket so you don't get 3 social tasks in a row. Streak Shields: earn one automatic shield every time you cross a 7 / 30 / 100 / 365 day streak milestone (max 3 stored). If you ever miss exactly one day, the system spends a shield silently and your streak survives. The number of shields you have is shown right in the missions card. 5 new badges: `Backtest Master` (5/25/100/500 backtests), `College Grad` (3/10/25/50 lessons completed), `Shield Bearer` (earned your first shield), `Mission Runner` (5/25/100/365 missions claimed), and a hidden `Streak Saved` badge that unlocks the first time a shield rescues your streak. Admin user-management got a sortable badges column + a "with badges" cohort filter, and the leaderboard now has a Top Badged sort tab so people who collect achievements get their own spotlight.

View
NEW FEATUREApr 25

Public profiles, follow / DM, and multi-trader portfolio compare

A whole social layer just shipped. Settings → Public Profile lets you add a 150-char bio plus links to X, LinkedIn, GitHub, YouTube, Discord, your website, Instagram, and Telegram, with separate toggles for what is shown publicly. Quest rows on `/dashboard/quests` are now clickable and take you straight to the page where you can complete each one. The leaderboard shows opt-in bios, clickable social icons, and Follow, DM, and View % buttons next to each trader. Direct messages are gated by mutual follow plus the recipient opt-in. Two new privacy toggles let other members see your portfolio % allocations and your profitable day, week, month, year, and all-time stats — your dollar values stay private. The leaderboard also has a Compare mode: pick 2 to 8 traders and open `/dashboard/leaderboard/compare` for a side-by-side weight matrix plus an AI-written desk note that calls out where the group agrees, where it splits, and one rebalance per investor.

View
FIXApr 25

Sidebar tier badges (PRO / ELITE / NEW / BETA) now readable in light mode

The little tier pills next to sidebar items — `PRO` next to Day Trading Desk, World Map, Predictions, Whale Tracker, AI Signals, etc., `ELITE` next to 13F Holdings, Earnings Transcripts, Custom Alerts, and `NEW` next to Quests — were rendering in `text-amber-200` / `text-amber-100` / `text-emerald-300` / `text-sky-300`. Those tones were tuned for the dark-mode sidebar; on the white sidebar background in light mode the badge text was almost invisible against the already-pale gradient backgrounds. Each badge now has an explicit light-mode pair with darker, more saturated text (`text-amber-800`, `text-rose-800`, `text-emerald-800`, `text-sky-800`) and a stronger ring (`ring-{color}-500/50`) on top of slightly more transparent backgrounds, while the original dark-mode appearance is preserved via `dark:` variants. The same fix was applied to the favorited-item pills at the top of the sidebar so a starred Pro/Elite item also reads correctly. Section headers also adjusted. The "ELITE" and "ADMIN" section labels were using `text-rose-400/80` and `text-amber-400/80` — both too light on white. They now use `text-rose-600` and `text-amber-600` in light mode while keeping the original `400/80` shades in dark mode, and the section dots got bumped from 400 → 500 weight for better visibility.

IMPROVEMENTApr 25

Pricing page now reads beautifully in BOTH light and dark mode

A coordinated visual polish pass on `/dashboard/pricing` so every section looks intentional regardless of theme. (1) Hero logo no longer shows a black rectangle on light mode. The previous full-logo PNG had a baked-in black background and we were patching it with `mix-blend-mode: screen` — which worked in dark mode but flattened oddly on white. Replaced with the transparent square icon + the wordmark rendered as HTML text that follows `text-foreground` and a subtle emerald "Research" subtitle that adapts per theme. (2) Founding Lifetime hero is theme-aware. The amber gradient and dark slate background that read perfectly at night completely washed out on white. Now uses `bg-amber-50 → orange-50` with `border-amber-300` and amber-700/800 text in light mode; the dark-mode appearance is unchanged. The amber callout, ladder rungs, "Current Wave Price", lock icon and the "What you get" list all carry a `dark:` variant so contrast stays strong in either theme. (3) Transparency callout, Enterprise tier card, comparison table & feature checks rebuilt. The Phase F highlight, the Talk-to-Sales violet hero, the Lifetime column header in the comparison table, and the green ✓ marks on every feature row all gained explicit light-mode colour pairs (`emerald-500`, `amber-600`, `violet-700` etc.) so they remain legible — no more pale-yellow-on-white or near-invisible green-on-white. (4) Tier CTA buttons are now dynamic. If you're on Elite and look at Retail/Pro, the button now reads "Downgrade to Retail" / "Downgrade to Pro" instead of always saying "Upgrade". The tier ranking is `explorer (0) → retail (1) → pro (2) → elite (3) → lifetime (4)`. Lifetime claims are still always presented as a one-time purchase. (5) Sidebar tier pill ("You: Elite", "You: Pro" etc.) is readable in light mode. The pill text was using `text-{color}-200` which is essentially invisible on a white background. Each tier now has explicit `{color}-800/900` for light mode + `{color}-200/100` for dark mode so the badge always stands out from the sidebar background. (6) Home page Commodities card. Was using an arbitrary `hsl(40_95%_60%)` value for its border/icon/bullets which Tailwind's alpha syntax can't cleanly compose with — it had a barely-visible border in light mode and slightly-off colour in dark mode. Replaced with `border-amber-400/30 + text-amber-500 dark:text-amber-400` to match the styling system used by the other six asset-class cards. (7) Footer "Data via" line expanded. Now lists the full set of providers we actually integrate against — CoinGecko, CryptoCompare, Yahoo Finance, TwelveData, Finnhub, SEC EDGAR, FRED, OKX, DefiLlama, Reddit, Polymarket, Manifold and alternative.me — instead of just five names. The same expansion was applied to the "Cross-Asset Data" stack card on the marketing landing page.

View
NEW FEATUREApr 25

Lifetime ladder repriced + new Enterprise tier for funds & institutions

Two pricing changes ship together. (1) Founding Lifetime ladder repriced upward. Looking at where competitive terminals price their lifetime/perpetual tiers and at the cost of the FMP Ultimate + premium AI inference we wire into Elite, the previous $1,997 → $3,997 ladder was meaningfully under-priced — to the point where it was hurting perceived value. The Founding 500 ladder is now: $2,997 (Founding 100, seats 1–100) → $4,997 (Early Bird, seats 101–250) → $7,497 (Growth, seats 251–400) → $9,997 (Final Wave, seats 401–500). The pricing-page hero headline switched from "Pay once. Elite access forever." to "Secure founder access before pricing becomes subscription-only." with a new amber urgency callout that makes the bargain explicit: after the 500th seat is sold, ChainStreet Research becomes subscription-only at $790/mo and up. This lifetime pricing will never be offered again. Two founder-only perks were also added to every lifetime wave: a Private Founders' Discord with direct line to the dev team plus monthly office hours, and a Quarterly 1:1 strategy call with the founder (30 min, founders only). All four ladder rungs, the Settings billing page, the FAQ, the welcome / trial / win-back drip emails, and the active LS plan registry have been updated to match the new prices in a single coordinated change. (2) New Enterprise tier — Talk to Sales. A fifth tier card landed below the Lifetime hero on `/dashboard/pricing`: Enterprise · Custom Solutions for hedge funds, prop firms, asset managers, banks, crypto funds, and family offices. It pitches three direct API products — Market Data API (crypto, equities, FX, futures), AI Signals API (directional + regime probabilities), and Sentiment API (news, social, on-chain feeds) — plus custom SLA, dedicated account manager, white-glove onboarding, and bespoke contracts. Pricing is intentionally listed as "Custom" (no public number); a "Talk to Sales" CTA opens a modal with an inquiry form (name, work email, company, phone, company size, primary use case, estimated API call volume, free-form message). On submit, the lead is persisted to a new `EnterpriseLead` table and an inquiry email is fired to [email protected] as well as mirrored to every super-admin so we never miss a hot lead. The endpoint at `POST /api/enterprise/inquiry` validates emails with an RFC-lite regex, rate-limits duplicates by email within 60 seconds, and softly flags free-provider domains (gmail/yahoo/outlook etc.) for quick human triage without rejecting them. New schema model `EnterpriseLead` with fields for name / workEmail / company / phone / companySize / useCase / apiVolume / message / source / status / notes / contactedAt — three indexes on (createdAt, status, workEmail) for fast triage queries.

View
FIXApr 25

Topbar avatar, transparent pricing logo, and User Management page restored

Three small but visible UX fixes shipped together. (1) Pricing-page logo now blends. The full "ChainStreet Research" logo at the top of `/dashboard/pricing` had a baked-in black background that clashed with the page (light/dark theme alike). We applied `mix-blend-mode: screen` on the image so the black flattens against whatever color sits behind it — the wordmark now reads cleanly on the gradient header without us regenerating the PNG asset. (2) Compact topbar user pill. The topbar previously had a wide rounded pill on the right showing your full name + the generic User icon + a Logout label, taking ~220 px and pushing the rest of the controls left. It is now two square 36×36 icon buttons: a circular avatar (your uploaded `avatarUrl`, falling back to your Google profile image, falling back to the User icon) that links to your Settings / Account page, and a Logout button right next to it. Same actions, half the footprint, and the avatar makes the pill feel like your account at a glance. (3) User Management page no longer crashes. `/dashboard/admin/users` was throwing "Application error: a client-side exception has occurred" for super-admins. Root cause: `lib/lemon-squeezy.ts` was reading `process.env.LEMON_VARIANT_` at module-load and throwing when any variant ID was missing. That works fine in server contexts, but the user-management client component imports `planFromVariantId` from the same file — so the entire registry got evaluated in the browser bundle, where those env vars are intentionally `undefined`, and the throw bubbled up as an unhandled error. We now read those env vars lazily and fall back to empty strings; the actual check (and a clear error message) was moved into `createCheckoutUrl`, the only function that genuinely needs them. The user table renders normally again.

View
IMPROVEMENTApr 25

Blog Studio and College moved to "My Space"

Two sidebar items have moved out of Research into My Space to better reflect what they actually are. Blog Studio and College are personal-content tools (your writing surface and your learning hub), not market research feeds — they belong next to Journal, Thesis, and Read Later where you already keep your own work. The Research section is now leaner and focused on news/SEC/articles/calendar/correlation only. No URLs changed, all bookmarks still work.

NEW FEATUREApr 25

Public leaderboard, quests, streaks, daily-login bonus, and discount codes admin

Phase 4 + Phase 5 of the engagement system shipped together. (1) Public Leaderboard (`/dashboard/leaderboard`). Top 50 members ranked by engagement points, with tabs for Today / This Month / This Year / All Time. Auto-refreshes every 30 seconds, your own row is highlighted in yellow with your live rank, badges (Satoshi, Super Admin, Influencer, Admin) render inline, and avatars + tier color-coded usernames. The endpoint at `/api/activity/leaderboard?period=...` is the same one your in-product widgets pull from. (2) Quests (`/dashboard/quests`). Thirteen one-time achievements that grant bonus points the moment you unlock them: complete your profile (+5), finish onboarding (+5), start a watchlist (+5), track 5 tickers (+10), set your first alert (+5), log your first journal entry (+10), write your first thesis (+20), share your first community post (+10), earn your first badge (+5), 3-day streak (+5), 7-day streak (+15), follow another investor (+5), get followed (+10). Quests auto-grant when their conditions are met — no manual claim needed — and a Sonner toast celebrates each unlock in real time. (3) Streaks + daily-login bonus. Every day you visit the dashboard you get +1 point (60 active seconds credited to the day-bucket and your lifetime total) once per UTC day. Visiting on consecutive days builds a streak counter (`streakDays`) — and crossing the 7 / 30 / 100 / 365-day thresholds awards extra one-time milestone bonuses (+5, +20, +75, +250 points respectively). The streak resets to 1 if you skip a day, and your best ever streak is preserved as `streakLongest`. The bonus is fired silently from the activity heartbeat the moment you load any dashboard page, milestones pop a celebratory toast, and the new Engagement Points card on the home dashboard (top of `/dashboard/home`, right under the onboarding checklist) shows your total + today + current streak with a 🔥 icon when you're on a 3+ day streak, plus quick links to the Leaderboard and Quests pages. (4) Discounts & Affiliates admin. New super-admin page at `/dashboard/admin/affiliates` with two tabs: Discount Codes (lists every active LS discount code with its name, percent / fixed amount, redemption count, expiry, and status — plus a + New Discount modal that lets you create codes with name, code string, percent or fixed amount, duration (once / repeating N months / forever), max redemptions, and an optional expiry date) and Affiliates (lists every enrolled LS affiliate with their code, sales count, visitors, gross / net revenue, and payout total — plus a deep-link to the LS dashboard for editing). Both tabs hit the LS API live; we never duplicate codes or affiliates locally. The Influencer flag on a user (set via the user-detail drawer on `/dashboard/admin/users`) is what auto-awards them the Influencer / Affiliate badge — link your manually-approved LS affiliates to platform users by toggling that flag. (5) Schema additions. `User.streakDays`, `streakLongest`, `streakLastDay`, `lastDailyBonusAt`, `totalLifetimeBonusPoints`, `lemonAffiliateId`; new `UserQuest` model with `(userId, questKey)` unique index. All additive, no data loss. New endpoints: `POST /api/activity/daily-bonus`, `GET /api/activity/streak`, `GET /api/quests`, `GET /api/admin/discounts`, `POST /api/admin/discounts`, `DELETE /api/admin/discounts/:id`, `GET /api/admin/affiliates`.

View
NEW FEATUREApr 25

Points, three new badges, and a Super-Admin role for the founding team

Three connected upgrades shipped together. (1) Activity Points. Every account now earns 1 point per 30 active minutes spent inside the terminal. "Active" means the tab is visible and focused, and you've interacted (mouse/keyboard) within the last 2 minutes — so background tabs and idle screens don't farm points. The client pings a heartbeat every 60 seconds, server-side rate-limits to one ping per 45 seconds, and caps each user at 16 hours of credited time per UTC day to prevent abuse. Lifetime totals are stored on your profile and broken down today/month/year/all-time at `/api/activity/stats` (a public leaderboard and an in-product Points card are coming in the next deploy). (2) Three new badges. Satoshi (orange Bitcoin icon, ranked above every other badge — pinned to founder #0 by email match), Super Admin (red shield, derived automatically from the new role flag), and Influencer / Affiliate (megaphone, derived from a per-account flag we'll wire to Lemon Squeezy affiliates next deploy). All three render exactly the same way as existing earned badges — on profiles, in the topbar pill, in the leaderboard, and in the admin user table. (3) Super-Admin role. A new tier above regular Admin. Super-Admins can edit any user's point total directly, toggle the Admin / Super-Admin / Author / Influencer flags on any account, and award/revoke any badge — all from the user-detail drawer at `/dashboard/admin/users`. `[email protected]` (admin #1) is the first Super-Admin. The auth layer also auto-elevates that exact email back to Super-Admin on every login as a permanent backstop, so the role is impossible to lock out of. Regular Admins keep all their existing capabilities; only the new "Super-Admin Tools" panel is gated.

View
IMPROVEMENTApr 25

Onboarding is now mandatory + every price labeled "USD" so currency is unambiguous

Two related cleanups landed together. (1) Onboarding wizard is now mandatory — every step. When we launched the four-step personalization wizard last release, we shipped it with a "Skip for now" button on every step. Looking at the data over the past 24 hours, a meaningful chunk of new accounts skipped one or more steps — which defeats the entire purpose: we need your asset-class + interest + experience + referral answers to actually personalize the trial drip, the dashboard layout, and the first plays we surface. So we've removed the Skip button entirely. Every step now requires a selection — at least one asset class on Step 1, at least one interest on Step 2, both experience-level and trading-frequency on Step 3, and a referral source on Step 4 — before the Next button enables. The whole flow still takes about 45 seconds, the answers still drive the personalized trial drip, and the data is still 100 % editable later from Settings → Personalization. The DELETE skip endpoint at `/api/onboarding/preferences` now returns 405 with a clear message. (2) Every dollar amount is now labeled "USD". Several Canadian users reported seeing the Lemon Squeezy hosted checkout display "CA$97.00" / "CA$197.00" instead of the USD prices we set — Lemon Squeezy auto-localizes the displayed currency based on customer IP location, but the underlying charge is always processed in USD at mid-market rates. To remove any ambiguity on our side, we've added an explicit "All prices in USD" badge under the billing-period toggle on `/dashboard/pricing`, a "USD" suffix on every individual price in the four tier cards, on every Lifetime ladder rung, on the current-wave hero price, on the Lifetime "Claim" CTA button, and on the active-plan price + lifetime-paid amount in `/dashboard/settings#billing` — so anyone evaluating the product knows that $149/mo means 149 US dollars per month, not whatever their browser's geo-IP locale converts that number to.

View
NEW FEATUREApr 25

Personalized onboarding wizard + 21-day trial drip + admin Profile column

A big day for personalization. (1) Onboarding wizard. New members now go through a four-step personalization wizard right after the legal disclaimer: pick the asset classes you trade (Crypto, Stocks, Options, Futures, Forex, Prediction Markets, Commodities), pick the interests you care most about (News, Sentiment, AI Copilot, Scanners, Macro Regime, Portfolio, Community, On-Chain), tell us your experience level + trading frequency, and how you found us. The whole flow takes 45 seconds, has Skip on every step (we never block you), and the answers immediately tailor the rest of the product. (2) Personalized 21-day trial drip. Every new account is now enrolled in a 10-email drip — Day 0 (welcome), Day 2 (recommended scanner picked specifically for your primary asset class), Day 5 (Plays of the Day), Day 8 (Macro Regime intro with a personalized overlay link), Day 12 (halfway check-in with three pages tied to your stated interests), Day 15 (a fully branched email — wallet-level alpha for crypto traders, institutional flows + insider buys for stock/options/futures traders, DXY + rate differentials for FX traders), Day 17 (AI Copilot with a sample prompt that fits your asset class), Day 19 (2-days-left + a plan recommendation tuned to your trading frequency), Day 21 (final reminder), Day 22 (gentle win-back). Every email is fully idempotent — your `trialEmailsSent` array tracks exactly which steps have fired so you never get duplicates, and conversion (any active subscription) immediately stops the drip. (3) Admin Profile column. The `/dashboard/admin/users` table gained a new "Profile" column that shows up to two of each user's asset-class tags (color-coded by class), an overflow pill for additional classes, and a tiny experience + interest-count summary underneath. The full preferences (assets, interests, experience, frequency, referral source, drip-emails-sent) are now returned by `/api/admin/users` so we can layer segmentation, filtering and per-segment broadcasts on top in upcoming releases. (4) Schema additions. New User columns: `assetClasses[]`, `interests[]`, `experienceLevel`, `tradingFrequency`, `referralSource`, `onboardedAt`, `trialEmailsSent[]` — all backwards-compatible (existing users were backfilled with `onboardedAt = now()` so they don't bounce into the wizard).

View
FIXApr 25

Bell badge clears instantly + Admin user table shows Plan, Card-on-file & Badges

A handful of polish updates landing together. (1) "Mark all read" actually clears the bell. The bell badge in the topbar was reading announcement read-state from a separate hook instance than the dropdown's "Mark all read" button — meaning the click did persist to localStorage and did clear the Updates-tab badge inside the popover, but the outer bell counter (the big "64") only refreshed on a full page reload. We now broadcast a custom `cs:announcements:read-changed` event whenever read-state mutates, and every hook instance subscribes to it (plus the cross-tab `storage` event for free), so all badges across the UI flip to zero the moment you click the button. (2) Bigger, more comfortable admin checkboxes. The bulk-select checkbox cell in `/dashboard/admin/users` was 40 px wide with a 16×16 hit target jammed against the row border; we widened the cell to 56 px, added vertical padding so the box sits centered between row separators, and gave the label a 32×32 invisible click target with a subtle hover background — it now feels like a proper enterprise admin grid. (3) Three new admin columns. The user table now shows: Plan (Monthly / Annual / Lifetime / Trial / Free / Past Due / Lapsed — derived from the Lemon variant ID + subscription status, with a renewal date hint underneath), Card (✓ Active / Failing / On File / N/A — green when the customer has a working card on file, red when payments are bouncing), and Badges (a compact row of earned-badge chips with overflow indicator, color-coded by tier). Plus the underlying API now returns the full subscription snapshot (`lemonCustomerId`, `lemonSubscriptionId`, `lemonVariantId`, `subscriptionStatus`, `subscriptionRenewsAt`, `subscriptionEndsAt`) and the user's badge cabinet alongside every row — so building further admin views on top of this becomes trivial. (4) Refreshed welcome email. New members now receive a proper branded welcome email with the ChainStreet Research full logo, a thank-you note, and a featured "Customer experience matters to us" section that invites direct reply-with-feedback — every reply goes straight to the founder.

View
FIXApr 25

Welcome email now fires for every new account + you land on Command Center after signup

Closed two related onboarding gaps. (1) Welcome email reliability. The "Welcome to ChainStreet Research" email had been firing for Credentials signups (email + password) but was silently skipped for users who registered via Google SSO — because the Google flow goes through NextAuth's OAuth callback, not the `/api/signup` route, and the welcome-email trigger lived only in the latter. We've now wired the same trigger into the JWT callback for first-time Google sign-ins (gated by `welcomeEmailSentAt` on your user record so you never get duplicates), so every new member — regardless of how they sign up — receives the email within seconds of completing onboarding. (2) Post-signup landing page. New accounts were finishing onboarding (avatar picker → continue) and landing on `/dashboard` (the Crypto market view) instead of `/dashboard/home` (the Command Center dashboard with your portfolio, watchlist, and active alerts at a glance). The four redirect defaults across `/signup`, `/onboarding/disclaimer`, `/onboarding/avatar`, and the avatar-client `safeNext` validator have all been flipped, and the credentials + Google CTAs on `/signup` now pre-attach `?next=/dashboard/home` so the entire onboarding cascade preserves the correct destination. As a small bonus, the login page now also defaults to Command Center when no callback URL is supplied — keeping returning users consistent with new ones.

View
FIXApr 25

Subscription checkout redirect now lands you on Settings instead of a 404

Closed a regression in the Lemon Squeezy hosted-checkout flow. After completing a paid plan upgrade we were redirecting users to `/dashboard/billing?checkout=success` — a route that didn't exist, so the moment payment cleared and Lemon clicked _Continue_ for the customer they hit a bare 404 instead of seeing their newly-upgraded account. Now the success-redirect drops you straight on `/dashboard/settings#billing` with a green confirmation toast ("Payment successful — your account is being upgraded"), the URL scrolls to the Billing section automatically, and we re-poll the billing-status endpoint for ten seconds in the background so the new tier, card-on-file, and renewal date appear without a manual refresh. As a backstop, both `/dashboard/billing` and `/dashboard/settings/billing` now render server redirects to the canonical anchor URL, so any old links — bookmarks, sidebar pills, third-party copy — keep working forever. Behind the scenes we also tightened the webhook's `order_created` handler to always store `lemonOrderId` on the user record (it was previously skipped for subscription orders where the variant id lives on the line-item rather than the order envelope), making invoice lookups deterministic.

View
FIXApr 24

Profile picture uploads now work end-to-end

Fixed a regression where uploading a custom profile picture would store a placeholder image in the database instead of the actual file you picked. The upload route was constructing a fake URL string instead of the real S3 object URL — so the file was reaching cloud storage successfully, but the link saved to your account pointed somewhere else, which is why you saw a generic image (or no change at all) in the avatar circle. Now the public S3 URL is generated correctly from your bucket + object key, and the new picture appears in your settings card, navbar, and across every community surface within a second of saving.