尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證BistAiProject
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
AI-assisted market analysis for Borsa İstanbul equities. Real-time price data, technical charting, and plain-language signal explanations generated by a language model. 🔗 Live: bistai.vercel.app · 🇹🇷 Türkçe README Retail investors in Turkey have plenty of places to see a stock's price. What they don't have is anywhere that tells them what the numbers mean.檢視完整 README ↗
AI-assisted market analysis for Borsa İstanbul equities. Real-time price data, technical charting, and plain-language signal explanations generated by a language model.
🔗 Live: bistai.vercel.app · 🇹🇷 Türkçe README
Retail investors in Turkey have plenty of places to see a stock's price. What they don't have is anywhere that tells them what the numbers mean.
Open any brokerage app and you get RSI, MACD, moving averages, volume profiles — a wall of abbreviations with no interpretation. The information is technically present and practically useless to anyone who hasn't spent years learning to read it.
BistAI keeps the indicators and adds the missing layer: a short, readable explanation of what a given signal implies, written in Turkish, generated per stock.
Not investment advice. BistAI is an educational and analytical tool. It does not recommend buying or selling any security.
| Feature | Detail |
|---|---|
| Real-time BIST data | Price, volume and OHLC series pulled from Yahoo Finance's chart API |
| Interactive charting | Candlestick and line views via TradingView's lightweight-charts |
| AI signal explanations | Technical conditions passed to Claude, returned as plain-Turkish commentary |
| Personal watchlist | Per-user, persisted, isolated by row-level security |
| Guest mode | Browse without an account; AI assistant disabled, nothing persisted |
| Auth | Email/password, Google and Apple OAuth via Supabase |
flowchart TB
subgraph client["Browser"]
UI["Next.js App Router<br/>React Server + Client Components"]
CHART["lightweight-charts<br/>candlestick / line"]
end
subgraph server["Server (Vercel)"]
RSC["Server Components<br/>initial data fetch"]
API["Route Handlers<br/>/api/*"]
end
subgraph external["External services"]
YF["Yahoo Finance<br/>v8 chart API"]
CLAUDE["Anthropic API<br/>claude-haiku-4-5"]
end
subgraph data["Supabase"]
AUTH["Auth<br/>email · Google · Apple"]
DB[("PostgreSQL<br/>watchlists · signals")]
RLS["Row Level Security<br/>user_id = auth.uid()"]
end
UI --> RSC
UI --> API
CHART -.reads.-> UI
RSC --> YF
API --> YF
API --> CLAUDE
API --> DB
UI --> AUTH
AUTH --> DB
DB --- RLS
style CLAUDE fill:#0B6E9E,color:#fff
style RLS fill:#C4166F,color:#fff
The key boundary: the browser never talks to Yahoo Finance or Anthropic directly. Both run behind route handlers, so no third-party key is ever shipped to the client.
These are the choices that took the longest, and why they went the way they did.
The obvious implementation — call the Anthropic API from a client component — leaks the key to anyone who opens DevTools. Every model call goes through a server route handler instead. ANTHROPIC_API_KEY has no NEXT_PUBLIC_ prefix, which means Next.js will refuse to bundle it into client code even by accident.
Watchlists are private. The naive approach filters by user in the query (where user_id = ...) and trusts every code path to remember. One forgotten where clause leaks every user's data.
Instead the policy lives in the database:
create policy "own_watchlist" on watchlists
for all using (auth.uid() = user_id);
Now a query that forgets to filter returns zero rows rather than everyone's rows. The failure mode is "broken", not "breached" — which is the correct direction for a security bug to fail.
Financial charts look simple and are not: crosshairs, time-axis gaps for non-trading hours, log scales, responsive redraw. lightweight-charts handles all of it in ~40 KB gzipped. Writing this by hand would have cost a week and produced something worse.
Generating a two-sentence explanation of an RSI reading does not require deep reasoning. Using a Haiku-class model (claude-haiku-4-5) keeps latency low and cost per explanation negligible. The prompt does the heavy lifting; the model doesn't need to.
Stock pages are read far more often than they're interacted with. Fetching initial price data in a server component means the user sees real numbers on first paint instead of a loading skeleton, and search engines see actual content.
lightweight-chartsclaude-haiku-4-5)git clone https://github.com/Doguserkivac09/BistAi.git
cd BistAi
npm install
Create .env.local:
NEXT_PUBLIC_SUPABASE_URL=your-project-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
ANTHROPIC_API_KEY=your-api-key
NEXT_PUBLIC_APP_URL=http://localhost:3000
Apply the database schema — this creates the tables and their RLS policies. The app will not work correctly without the policies:
psql "$SUPABASE_DB_URL" -f supabase/schema.sql
Then:
npm run dev
Open http://localhost:3000.
Guest mode uses Supabase anonymous sign-in, which is off by default on new projects. Turn it on in the Supabase dashboard under Authentication → Providers → Anonymous sign-ins, or the guest button returns 422.
app/
(auth)/ sign-in, sign-up, callback routes
api/ route handlers — market data, AI explanations
stocks/[symbol]/ stock detail page (server component)
components/
charts/ lightweight-charts wrappers
ui/ shadcn/ui primitives
lib/
supabase/ browser and server clients
market/ Yahoo Finance fetch + normalisation
supabase/
schema.sql tables, indexes, RLS policies
Stated plainly, because pretending they don't exist helps nobody:
MIT