A social platform for sharing stock market insights, powered by an LLM-backed ranking engine.
Think StockTwits/Twitter, but optimized for deep stock analysis: posts are tagged, summarized, scored for quality, and ranked using both semantic signals and market data.
-
Insight posts
- Users create free-form posts about tickers.
- Tickers are stored and used for feeds, market data, and trending views.
-
LLM intelligence (via OpenRouter)
- Tagging: insight type, sector, catalyst, risk profile.
- Summarization: short summary for each post.
- Quality scoring: normalized 0–1 score.
- Embeddings: semantic search over posts.
-
Ranking engine
- Combines:
- LLM quality score
- Author reputation
- Engagement (likes/dislikes)
- (Planned) market alignment from
yfinance
- Drives the personalized / global feed.
- Combines:
-
Semantic search
- Embedding-based search endpoint to find related insights by meaning, not keywords.
-
Supabase-native backend
- Postgres +
pgvectorfor embeddings. - Supabase Auth for sessions.
- RLS policies set for app tables.
- Postgres +
-
Engagement
- Likes: Users can like/unlike posts to signal quality.
- Comments: Rich discussions on posts.
- Usernames: Posts display actual usernames from user profiles.
-
Modern frontend
- Next.js app with:
- Anonymous sign-in via Supabase Auth.
- Create-post UI.
- Ranked feed with summaries & scores.
- Enhanced Search: Fuzzy search with navigation bar.
- Next.js app with:
- Frontend: Next.js (React), TypeScript
- Backend: FastAPI (Python)
- Async workers: ARQ + Redis
- Database: Supabase Postgres (
pgvectorenabled) - Auth: Supabase Auth (JWT)
- LLMs: OpenRouter (free models like
openai/gpt-oss-20b:free, etc.) - Market data:
yfinance(for live prices / OHLC)
🚀 Quick Start: See SETUP_GUIDE.md for detailed setup instructions.
You'll need API keys from:
- Supabase (Project URL, Anon Key, Service Key)
- Cohere (for embeddings)
- OpenRouter (for LLM operations)
Option A - Use the helper script (Windows):
.\create-env-files.ps1Option B - Use the helper script (Mac/Linux):
chmod +x create-env-files.sh
./create-env-files.shOption C - Manual creation:
- Copy
env.examplecontents tobackend/.env - Copy
env.examplecontents tofrontend/.env.local(use only theNEXT_PUBLIC_*variables)
Edit the created files and replace placeholder values with your actual API keys.
See SETUP_GUIDE.md for detailed instructions on getting API keys.
Backend:
cd backend
pip install -r requirements.txtFrontend:
cd frontend
npm installBackend API:
cd backend
uvicorn app.main:app --reload --port 8000Health check: GET http://localhost:8000/health
Frontend:
cd frontend
npm run devApp will be at: http://localhost:3000
Worker (optional):
cd backend
arq app.worker.WorkerSettingsThe worker processes posts with LLM tagging, summarization, and scoring.
- User signs in (anon) via Supabase Auth; frontend gets a JWT.
- User creates a post from the Next.js UI.
- FastAPI:
- Stores the post in
posts(tying it to Supabaseauth.usersviaprofiles). - Marks
llm_status = 'pending'. - (Expected) enqueues
process_post(post_id)to Redis/ARQ.
- Stores the post in
- Worker:
- Calls OpenRouter to:
- Tag + summarize + score.
- Generate embeddings (content + summary).
- Writes to
insights,post_embeddings,llm_audit_logs, and updatesreputation. - Marks
llm_status = 'processed'.
- Calls OpenRouter to:
- Feed endpoint computes a
final_scoreusing:quality_score(LLM)reputation.overall_score- Engagement (likes/dislikes)
- Frontend feed:
- Calls
/feedusing the user’s token. - Renders posts with tickers, summary, quality score, and final ranking score.
- Calls
-
Health
GET /health→{ "status": "ok" }
-
Posts
POST /posts/create– create a new post (auth required).GET /posts/{id}– fetch a post.
-
Feed & search
GET /feed– ranked feed (global/personalized).POST /insights/search– semantic search over posts.
-
(Planned) Market data
GET /market/{ticker}– latest snapshot.- Background worker:
ingest_market_dataviayfinance.
-
Start:
uvicorn app.main:app --reload --port 8000arq app.worker.WorkerSettingsnpm run dev(frontend).
-
In the browser:
- Go to
http://localhost:3000. - Click “Sign in (anon)”.
- Create a post (with tickers like
AAPL, TSLA). - Wait a short time for the worker to process.
- Refresh feed:
- You should see:
- Your post.
- LLM summary.
- Quality score & final ranking score.
- You should see:
- Go to
-
Inspect Supabase tables:
posts,insights,post_embeddings,reputation,llm_audit_logsshould all have new rows.
Use curl/Postman:
GET /healthPOST /posts/create(withAuthorization: Bearer <supabase-jwt>)GET /feedPOST /insights/searchwith{ "query": "EV earnings", "limit": 10 }
- Full ticker pages with market data and per-ticker ranking.
- Trending tickers view.
- Rich comments and conversations.
- Advanced reputation metrics (sector expertise, historical accuracy).
- More robust auth (proper JWT verification, non-anonymous users).
- Production-grade monitoring, rate limiting, and prompt tuning.