Some stock pages showed widgets that never loaded. I tested every
mapped exchange in a real-browser session:
- Hong Kong symbols broke in every widget: Finnhub pads codes
(0700.HK) but TradingView wants HKEX:700. The zero padding is now
stripped.
- TradingView refuses the candle chart in free embeds for 13
exchanges (Tokyo, Hong Kong, London, Korea, Taiwan, Singapore, New
Zealand, Thailand, Malaysia, Istanbul, TSX Venture, Mexico,
Johannesburg), each confirmed with two tickers. Those pages now say
so and link to the chart on TradingView. Financials, technicals and
profile still load.
- Prague mapped to PSE, which is the Philippine exchange on
TradingView; it is now PSECZ.
Every other widget loaded in repeated loads and client navigations.
A headless browser gets no chart data at all (TradingView blocks the
HeadlessChrome user agent), so test with a normal user agent.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Email price alerts now come with OpenStock Cloud ($5/month, coming
soon) and with self-hosted instances in realtime mode. The free hourly
site keeps charts, watchlists and research.
- createAlert refuses new alerts unless alertsEnabled (realtime mode).
The check is on the server, not just the UI.
- The alert checker job is only registered where alerts are on.
- The alert dialog (stock page button and watchlist bell) shows a
Cloud card instead of the form. The Alerts panel says it's a Cloud
feature. Existing alerts are listed as paused and can still be
deleted; nothing is removed from the database.
- Landing, About, Help, API docs, README and the welcome email no
longer promise free alerts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From the CodeRabbit and Copilot reviews on #106:
- Watchlist and alert reads are scoped to the session; no action takes a
user id or email from the client. Job-only helpers moved to a module
that is not 'use server', so they are no longer callable endpoints.
- createAlert validates the symbol, condition and price, and only
writes whitelisted fields. deleteAlert matches on the owner.
- Alert emails claim the alert atomically before sending and release
the claim if the send is skipped or fails, so no duplicate or lost
alerts.
- Account linking stays off until social sign-in ships, which removes
a pre-registration takeover path. Unused connect-provider UI removed.
- Symbols are escaped in alert emails, and Binance pairs show USDT.
- Stock search needs a session. A failed refresh keeps serving the
last good value during the cooldown.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#93 independently found the same bugs this branch fixes (Inngest trigger
registration, deleteAlert trusting the client, Mongo credentials in logs). Those
are covered by the v4 upgrade and session-scoped actions; this brings over its
deleteAlert tests, adapted to requireUserId, plus two for createAlert (ignores a
client-sent userId, refuses unpriceable symbols), and removes toggleAlert as #93 did.
Closes#93
Co-authored-by: fuxicodex <292959175+fuxicodex@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
formatNumber scaled undefined by 1e6 and rendered "NaN" for ETFs and many
non-US tickers. Returns "N/A" for missing or non-finite input, with tests.
Ported from #82 onto the redesigned watchlist.
Closes#82
Co-authored-by: Mubashir Rahim <mubashirrahim3431@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tested free coverage: Finnhub prices US stocks and crypto only; TradingView embeds
are live for US/crypto/forex, delayed for TSX/ASX, end of day for BSE/XETRA.
- Market registry and switcher (US, India, Germany, Canada, Australia, Crypto,
Forex) with session hours; defaults to the user's country.
- Stock pages fall back to TradingView for symbols Finnhub can't price; alerts are
limited to US stocks and crypto, enforced server-side.
- .NS symbols chart on BSE (NSE is blocked in free embeds).
- company-profile widget was retired by TradingView; switched to symbol-profile.
- MARKET_SUPPORT.md rewritten from the tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Better Auth handler at /api/auth (OAuth callbacks and reset links had no route).
- Reset emails double-encoded callbackURL (INVALID_CALLBACKURL); fixed with a test.
- Providers enable only when their env vars are set; documented in check-env.
- Session cookie cache and a per-request session helper; onboarding answers are
stored on the user as additional fields.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The MiniMax provider defaulted to a superseded model and did not expose
the current MiniMax-M3 model. Default to MiniMax-M3 while keeping the
MINIMAX_MODEL override, and update the tests that pinned the old default.
Expand formatSymbolForTradingView to map 40+ Finnhub exchange suffixes
to their TradingView prefix equivalents. Previously only .SS, .SZ, and
.HK were handled, causing international symbols like 2330.TW to fail
on the stock details page.
Add comprehensive test suite for utility functions including
formatSymbolForTradingView, formatMarketCapValue, formatChangePercent,
getChangeColorClass, and calculateNewsDistribution.
Closes#24
Introduce a configurable AI provider system (lib/ai-provider.ts) that
supports Gemini (default), MiniMax, and Siray.ai with automatic
fallback. The AI_PROVIDER env var selects the primary provider, and
on failure the system falls back to a secondary provider automatically.
- MiniMax M2.7 via OpenAI-compatible API (api.minimax.io/v1)
- Provider abstraction replaces hardcoded Gemini + Siray fallback
- 24 unit tests + 3 integration tests (vitest)