The 'Watching' block is the only sidebar flex child that sets `min-h-0`,
so it is the only one the column is allowed to squeeze below its content
height. With a longer watchlist on a short viewport it collapsed while the
list kept painting outside the box, covering the Help / API docs / About /
Terms links and the sponsor card.
Give the list its own scroll container and keep the section label pinned.
The OpenStock team launched Onto today. A card in the corner of every page
and a line at the top of the README ask for an upvote. The card closes for
the current page only and stops on 3 Oct.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- README: a call-out under the intro and a rewritten Sponsor section.
It covers who uses OpenStock, the funding plan (OpenStock Cloud will
pay for hosting; sponsors fund reviews, fixes and features), tiers
with GitHub Sponsors links that preselect the amount, a one-time
option, the contact route and who receives the money.
- Sponsor page: 13,000+ registered users in the hero and stats card
and in the Partner perk. A "Cloud pays for hosting, sponsors keep
the community moving" pair of cards under where the money goes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>
Functions ran in iad1 (Washington) while MongoDB Atlas is in Mumbai,
so every query crossed the globe (~230ms). Signed-in pages and sign-in
make several queries each, and a cold connection needs a few round
trips just for TLS and auth: ~3s before a page could render. bom1 puts
them a few milliseconds apart. Finnhub calls cross the ocean instead,
but those are cached.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The file is odsLogo.svg but the page asked for odslogo.svg. macOS
ignores the case difference; Vercel's Linux file system doesn't.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TradingView's autosize sets the container's inline height to 100%,
overwriting the 560px height React set on it. The parent had no
height, so every iframe fell back to 150px. At that size Leaders
showed "No data here yet" and Quotes showed empty columns. The height
now lives on the frame, which TradingView never touches.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From the CodeRabbit and Copilot reviews on #106:
- Tab close is a real button beside the link, not nested inside it.
- Pulse tiles refresh on screen in realtime mode, so "Live · 15s" is
true. The freshness time is formatted after mount (no hydration
mismatch).
- Deleting an alert refreshes the list. Social sign-in errors are
caught.
- The sponsors band only shows logos for company and partner tiers.
The sponsor page only states a monthly total when every cost is
known.
- README and check-env list INNGEST_EVENT_KEY. OAuth keys are shown
as optional.
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>
Sponsorships go to the founder's personal GitHub Sponsors account, so the page
now says so and lists what they pay for (hosting, market data, database, AI and
email, maintenance). Each line takes an optional monthly amount; once real bills
are filled in, the page shows amounts, shares and the monthly total.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Without GOOGLE_/GITHUB_ client ids the buttons still rendered and every click
failed with "not available right now". The auth layout now passes the enabled
providers down (same condition as the auth config), and the buttons and the
"or" divider hide when none are configured.
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>
Nodemailer already skips sending without credentials, but the welcome-email job
still logged "sent successfully" and the README and env checker listed the
Gmail variables as required. The job now reports skipped sends, and the docs and
check-env treat NODEMAILER_EMAIL/NODEMAILER_PASSWORD as optional.
Ported from #69 (its Nodemailer changes were already on main).
Closes#69
Co-authored-by: keshav-005 <keshavchaudhary0005@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fullscreen changed the widget height, which re-ran the embed effect and re-created
the TradingView iframe, wiping any indicators the user had added (the redesign's
portal made it remount too). The embed now mounts once per script + config and
fullscreen resizes the same element in place. Verified the iframe survives
expand and exit.
Ported from #68 onto the redesigned widget.
Closes#68
Co-authored-by: keshav-005 <keshavchaudhary0005@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The country list labels TW as "Taiwan, Province of China". Override the label
while keeping the library list, in both the dropdown and the selected value.
Ported from #70 onto the restyled picker (sign-up and profile).
Closes#70
Co-authored-by: keshav-005 <keshavchaudhary0005@gmail.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>
- Landing at / (app moved to /dashboard) with a live NYSE session dial and the
real product preview; About, Help, Architecture and Terms made public and rebuilt.
- /sponsor page with monthly tiers, one-time and custom options, prefilled GitHub
Sponsors checkout links, and a sponsors band (open slots, previous sponsors) on
every public page. Siray moved to previous sponsors.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Every Finnhub call has a 5s timeout (a stalled socket held pages for 300s),
at most 2 in flight per key, de-duplicated, stale-while-revalidate, and a 60s
failure cool-down.
- FINNHUB_API_KEYS pool rotated per request, token sent as a header so cache keys
are shared; falls back on 429.
- NEXT_PUBLIC_OPENSTOCK_DATA_MODE: cached (hourly, default) or realtime (15s).
- /api/quotes + useLiveQuotes for on-screen prices; honest freshness labels.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Floated shell with a dark sidebar and browser-style tabs, hatch shells, bento tiles,
warm OKLCH palette with OpenStock teal, Plus Jakarta Sans + IBM Plex Mono.
Rebuilt stock page (native header, streaming), watchlist (real table, alerts pane,
news rows), auth pages (live product preview, choice chips), search palette,
alert modal and donate popup. Removes Header/Footer/NavItems/UserDropdown/SirayBanner
and the unused watchlist widgets.
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>
functions.ts used the v4 createFunction signature on the v3 package, so all four
jobs registered with empty triggers and never ran. Triggered price alerts now email
their owner instead of only logging; the alert job runs one at a time.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Watchlist and alert actions took a userId from the client, so any signed-in user
could add, remove or delete another user's data. They now read the session.
- middleware/index.ts was never loaded by Next.js (empty middleware manifest); moved
to middleware.ts so signed-out requests redirect before any page code runs.
- Mongo connection log no longer prints the password.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Expand required vars from 6 to 9 (add INNGEST_SIGNING_KEY, NODEMAILER_EMAIL/PASSWORD)
- Add 7 optional vars for AI providers, Adanos, Kit, and AI_PROVIDER selection
- Detect deprecated FINNHUB_API_KEY and suggest migration to NEXT_PUBLIC_FINNHUB_API_KEY
- Add contextual hints for each missing required variable
- Implement value masking (shows first 4 + last 4 chars)
- Add clear summary with counts and exit codes
- Improve output formatting with categorized sections
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.
- Fix mojibake emoji sequences (⚠️) in console.warn messages on lines 41 and 71
- Ensure UTF-8 encoding is preserved for all unicode characters
- Addresses CodeRabbit feedback on emoji rendering in logs
These changes ensure warning messages display correctly in logs when email
credentials are not configured. The emoji was previously double-encoded,
displaying as 'âš ï¸' instead of the proper '⚠️' warning symbol.
Resolves: Open-Dev-Society/OpenStock#37
- Create MARKET_SUPPORT.md with comprehensive guide to supported exchanges
- Document TradingView and Finnhub API limitations
- Add troubleshooting section for 'symbol only available on TradingView' error
- Update README.md table of contents with new Market Support section
- Addresses issue #83 by clearly explaining why NSE and other markets may have limitations
- Add PasswordRequirements component showing rules with live checkmarks
- Add PASSWORD_RULES and PASSWORD_VALIDATION constants
- Update sign-up and reset-password forms to show requirements