尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
A stock research and portfolio web app for beginner-to-intermediate investors. Live market data, AI-powered insights, crypto & commodity support, SEC filing analysis, investing education, and social features — all in one place, with a free tier and a Stripe-powered Pro subscription.檢視完整 README ↗A stock research and portfolio web app for beginner-to-intermediate investors. Live market data, AI-powered insights, crypto & commodity support, SEC filing analysis, investing education, and social features — all in one place, with a free tier and a Stripe-powered Pro subscription.
account_tier in Supabase), self-serve checkout and billing portalTermTooltip renders plain-language labels for beginners, full finance terms for advanced| Area | Technology |
|---|---|
| Framework | Next.js 16 (App Router), React 19 |
| Language | TypeScript (strict mode) |
| Styling | Tailwind CSS 4 |
| Database & Auth | Supabase — Postgres, Auth, Storage |
| Client data | TanStack Query v5 |
| Validation | Zod |
| UI | Radix UI / shadcn-ui, Framer Motion, Lucide icons, cmdk |
| Charts | Lightweight Charts (TradingView — price charts), Recharts (financials), D3 + d3-sankey (Sankey diagram) |
| AI — chat | Vercel AI SDK + Anthropic Claude |
| AI — analysis |
Primary market data: TwelveData (quotes, candles, stats, financials, earnings, logos)
News & fallbacks: Finnhub
SEC filings: EDGAR direct
Company logos: Logo.dev + TwelveData, persisted in Supabase Storage
| Source | Used for |
|---|---|
| TwelveData | Real-time & historical quotes, candles, statistics, financials, earnings, technical indicators, logos, symbol search |
| Finnhub | Market news, fallback quotes |
| SEC EDGAR | 10-K, 10-Q, 20-F, 8-K filing ingestion |
| Anthropic Claude | Bull chat, "Why Today?" price explanations, Daily Brief, AI Deep Dive reports, Bull's Weekly Pick, Academy content |
| Resend | Morning alert email, verification and billing email |
| SnapTrade | Brokerage OAuth + live holdings sync |
| Stripe | Pro subscription billing |
| Upstash | Redis for API rate limiting and market data caching; QStash for the hourly user-alerts schedule |
| Supabase | User accounts, holdings, watchlists, theses, daily briefs, Academy progress, company index |
| Discord | Changelog announcements, ops/cron alerts (internal webhooks) |
| Instagram Graph API | Automated content pipeline (earnings calendar and results, earnings deep dives, market movers, Weekly Pick scoreboard); publishes automatically and confirms in Discord |
npm install
Create .env.local in the project root. ENV_SETUP.md has the full variable list.
Required for core functionality:
NEXT_PUBLIC_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_ANON_KEY
SUPABASE_SERVICE_ROLE_KEY
ANTHROPIC_API_KEY # Every AI feature (Claude)
TWELVE_DATA_API_KEY # Primary market data
Optional / production:
FINNHUB_API_KEY # News + quote fallbacks
RESEND_API_KEY # Email notifications
CRON_SECRET # Protect cron endpoints
LOGO_DEV_KEY # Company logos
NEXT_PUBLIC_APP_URL # Used in email links
SNAPTRADE_CLIENT_ID # Brokerage OAuth
SNAPTRADE_CONSUMER_KEY
UPSTASH_REDIS_REST_URL # Rate limiting / caching
UPSTASH_REDIS_REST_TOKEN
STRIPE_SECRET_KEY # Pro subscription billing
STRIPE_WEBHOOK_SECRET
STRIPE_PRICE_PRO_MONTHLY
STRIPE_PRICE_PRO_ANNUAL
DISCORD_CHANGELOG_WEBHOOK_URL # Discord announcements
DISCORD_INSTAGRAM_WEBHOOK_URL
INSTAGRAM_APP_ID # Automated Instagram content pipeline
INSTAGRAM_APP_SECRET
INSTAGRAM_ACCESS_TOKEN
INSTAGRAM_USER_ID
See ENV_SETUP.md for the complete, current list.
Apply Supabase migrations:
npx supabase db push
npm run dev
Open http://localhost:3000.
BullPen/
├── app/
│ ├── api/ # 100+ API route handlers
│ ├── stock/[ticker]/ # Stock detail page
│ ├── asset/[slug]/ # Universal crypto/commodity page (BTC-USD, XAU-USD)
│ ├── etf/[ticker]/ # ETF page
│ ├── holdings/ # Portfolio dashboard
│ ├── watchlist/ # Watchlist
│ ├── tools/ # AI, screener, compare, filings, calendar, heatmap, deep-dive, …
│ ├── academy/ # Courses, daily challenges, leaderboard
│ ├── picks/ # Bull's Weekly Pick archive
│ ├── pricing/, upgrade/ # Pro subscription pages
│ ├── dashboard/ # Post-login landing dashboard
│ ├── notifications/ # In-app notification center
│ ├── share/[id]/ # Public shareable cards (no auth required)
│ ├── admin/ # Internal-only: AI cost tracking, feedback
│ ├── social/, users/ # Community features
│ └── (auth, onboarding, brokerage-callback routes)
├── components/ # React components (organised by domain)
│ ├── asset/ # Crypto/commodity cards and stats
│ ├── stock/ # Stock-specific components
│ ├── holdings/ # Portfolio components
│ ├── discover/ # Homepage widgets
│ ├── academy/ # Course cards, challenge cards
│ ├── billing/ # Pricing, checkout, entitlements UI
│ ├── deep-dive/ # AI Deep Dive lens picker and report blocks
│ ├── picks/ # Weekly Pick hero and history
│ ├── watchlist/
│ ├── ai/ # AI chat panel
│ ├── i18n/ # Language switcher
│ └── ui/ # Shared design system
├── hooks/ # Shared React hooks
├── lib/
│ ├── ai/ # Agent, system prompt, tool definitions; deep-dive/ and picks/ subpipelines
│ ├── assets/ # Asset type utilities (slugToSymbol, inferAssetType)
│ ├── billing/ # Stripe checkout, tiers, quotas, AI cost logging
│ ├── finance/ # Health score, signals, glossary
│ ├── twelvedata/ # TwelveData API client
│ ├── supabase/ # Typed Supabase clients
│ ├── security/ # Rate limiting, input validation
│ ├── currency/ # FX conversion
│ ├── i18n/ # Locale config + AI translation pipeline
│ ├── discord/ # Ops webhook posting
│ ├── instagram/ # Automated content generation/rendering
│ ├── shares/ # Public share-link generation
│ ├── onboarding/ # Post-signup flow state
│ └── ingestion/ # SEC filing ingestion pipeline
├── scripts/ # One-off CLI utilities
└── supabase/migrations/ # SQL migrations
| Script | Description |
|---|---|
npm run dev | Development server (localhost:3000) |
npm run build | Production build |
npm run lint | ESLint (primary code-quality gate) |
npm run i18n:translate -- --ns=<ns> | AI-translate new keys in a namespace (review the diff: it can reorder or rewrite other keys) |
npm run i18n:pseudo | Regenerate the qa pseudo-locale |
npm run test-cron-coverage | Check every cron route has a scheduler and vice versa |
npm run test-no-truncated-text | Fail on AI-written text cut off without a Show more |
npm run trigger-cron | Manually fire the daily brief cron |
npm run trigger-alerts | Manually fire the user-alerts cron |
npm run trigger-instagram-earnings | Manually fire the Instagram content-generation cron |
npm run instagram-publish | Publish a staged Instagram carousel |
npm run test-credit-budget | Test the shared TwelveData credit-budget guard |
npm run test-trends | Test trend detection |
npm run verify-picks-math | Sanity-check Bull's Weekly Pick performance calculations |
npm run set-gold-tier | Set a user's account_tier directly (admin utility) |
npm run post-changelog-discord | Announce a new changelog entry in Discord |
Many more one-off scripts (logo backfills, locale tooling, email/webhook smoke tests) live in scripts/ — see package.json for the full list.
Split across three schedulers. Every cron route requires the CRON_SECRET bearer header, whoever triggers it. The full table with schedules and reasons lives in docs/agent/scheduled-work.md; run npm run test-cron-coverage after touching any of them.
| Scheduler | Used for | Examples |
|---|---|---|
Vercel cron (vercel.json) | Jobs that run at most once a day | Daily Brief (06:30 UTC), Weekly Pick (Mon 06:30), morning alert email (08:30), earnings/dividend/price-move notifications, economic calendar sync, Academy content, Instagram posts |
| Upstash QStash | Sub-daily, time-sensitive jobs | User price/metric alerts, hourly through market hours |
GitHub Actions (.github/workflows/cron-*.yml) | Hours-long batch loops paced under the TwelveData rate limit, and jobs that commit to git | Market data and financials prefetch, calendar prefetch, screener refresh, search index refresh, index constituent sync |
Trigger manually with npm run trigger-cron (daily brief) or npm run trigger-alerts (user alerts).
main → production; push to preview → stable preview URLvercel.json's ignoreCommand decides which commits build: main always builds; Dependabot branches and changelog-only commits (docs(changelog)…) are skipped, which keeps deployment storage down.
Proprietary.
| Anthropic SDK — Claude (Why Today?, Daily Brief, Deep Dive, Bull's Weekly Pick, Academy) |
| Billing | Stripe — Pro subscription checkout, billing portal, webhooks |
| Resend |
| Rate limiting & cache | Upstash Redis |
| Brokerage OAuth | SnapTrade TypeScript SDK |
| i18n | i18next, react-i18next — 7 locales |
| Analytics | Vercel Analytics, Speed Insights |
| Ops notifications | Discord webhooks (changelog announcements, cron/error alerts) |