- Industry
- Indian equity & derivatives software
- Type
- Portfolio, market, strategy & SaaS admin
- Role
- Architecture + full-stack + realtime
- Realtime
- Customer quotes/book · admin ops snapshots
- Stack
- FastAPI · PostgreSQL · Next.js
- Proof
- Product UI: dashboard, P&L, Kite-ready orders, templates
Screenshots are from a local product session. Account emails are redacted. Rupee figures are that session’s book — not a published track record.
Product walkthrough
The same product on video — public landing through portfolio and strategy surfaces. It is a walkthrough, not a published return and not a broker pitch.
Open the dedicated demo page → · Watch on YouTube →
The problem
Indian investors already have brokers, screeners, Excel and chat groups. What they usually do not have is one system of record for the book, the live tape, the rules they said they would follow, and the operator who has to run subscriptions and support.
Constraints
Delivery stayed inside the client's stack, tenancy, compliance and media-ownership boundaries. Where a choice was forced (suite vs owned plane, BYOC vs CPaaS, local vs cloud models), the architecture section below records the trade-off rather than a marketing rewrite.
- Holdings in one app, charts in another, P&L in a spreadsheet that is already stale
- Decisions on delayed prices and manual MTM
- No structured entry/exit or risk limits — only intent
- Weak visibility of exposure, drawdown and what actually made or lost money
- Public site, blog, legal pages and support sitting outside the product
A chatbot that “picks stocks” is the wrong product. The hard parts are identity, live quotes that match the book, strategy state you can audit, and an admin plane that can store Paytm and Google credentials without leaking them back to the UI.
Business requirements
One path for a customer: sign in, see portfolio value and P&L, watch instruments live, attach alerts, run a rule-based strategy through a backtest, and ask support without leaving the product. One path for ops: users, plans, subscriptions, market sync, blog, legal pages and chats. Public pages stay SEO-shaped so the product can explain itself.
This page does not publish invented AUM, win rates or “boosted returns.” Those are sales claims. The engineering claim is a complete surface map.
The solution
FastAPI owns REST, WebSockets, ORM models and integrations. PostgreSQL is the system of record. Next.js (App Router, Tailwind) renders public marketing, customer workspaces and admin. JWT covers email/password sessions; Google OAuth uses client id/secret stored through admin (masked on read). An Indian stock-market API client feeds instruments and quotes. Zerodha Kite Connect is the advertised broker-shaped integration for holdings, positions and orders. OpenAI is optional and sits behind FAQ matching on support chat.
Three audiences, one codebase:
- Customers — dashboard, portfolio, market, strategies, analytics, alerts
- Admins — users/roles, logs, subscriptions, customers, payments, plans, Paytm/Google creds, market sync, blog, legal, support, FAQs
- Public visitors — landing, features, analytics, strategies, pricing, about, blog, support, legal pages
The Next.js UI is role-aware (admin vs customer). Backend role enforcement is designed to tighten on the current-user contract — this page does not pretend every admin route is already a fortress.
The public shell is a marketing site, not a second product: Features, Analytics, Strategies, Pricing, About, with Sign In, a separate Admin entry, and Get Started. Login is email/password plus Continue with Google, and a distinct admin login path.
How the system flows
Portfolio data flows from ingestion through analytics to investor-facing dashboards — API-first with role-based access.
flowchart LR Ingest[Market and portfolio ingest] --> Store[Normalized store] Store --> Analytics[Analytics engine] Analytics --> Dash[Investor dashboards] Dash --> Alert[Alerts and reports]
Architecture
The book and the tape are services. The LLM is not the book.
flowchart TB UI[Web dashboards admin investor] API[Backend APIs auth] DB[(Database analytics store)] Jobs[Scheduled jobs ETL] Ext[External market feeds] UI --> API Ext --> Jobs Jobs --> DB API --> DB
Key components
Backend
FastAPI, SQLAlchemy, Alembic. Auth, market, portfolio, orders/trades, strategies, alerts, admin, blog, legal, support. WebSocket handlers close DB sessions promptly.
Frontend
Next.js App Router, Tailwind, JWT helper, WebSocket hook, chat widget on public and app pages. Sidebar/topbar change with role.
Realtime
Customer channel for portfolio, positions and quotes. Admin channel for subscriptions, customers, payments and a seats/MRR-style snapshot. Polling remains as a fallback.
Integrations
Indian market data client. Kite Connect as the advertised broker sync. Paytm and Google OAuth secrets stored in api_keys and masked on read. OpenAI only if configured.
What the product actually covers
Customer workspace
The signed-in shell is a left nav, not a pile of unrelated apps: Dashboard; Portfolio (Holdings, Positions, P&L Breakdown); Market (Watchlist, Instruments, Live Price Board); Trading (Place Order, Orders Book, Trades); Strategies (List, Builder, Backtesting Lab); Analytics; Alerts (including Alerts Center); Settings. A floating chat widget sits on these screens.
- Dashboard — portfolio value, open positions, gainers/losers, margins, unrealized vs realized P&L, a positions heatmap panel, prediction insight, and Sync from Kite. This session showed WebSocket status in the chrome. Heatmap and prediction still showed connect-later placeholders — the panels exist; they were not fully live here.
- Portfolio — holdings and positions, plus P&L breakdown: portfolio value, unrealized vs realized, daily (30 days) and monthly (12 months) charts. This session had no monthly series yet and showed Live WS disabled with a Refresh action.
- Market — watchlist, instrument search, live price board
- Trading — unified broker submission marked Kite-ready: portfolio, provider (Zerodha Kite), symbol, side, type, qty, limit price. Copy on the form: credentials must be configured in integrations. Orders book and trades sit beside it.
- Strategies — list, builder, backtesting lab, plus templates (RSI Oversold Bounce, EMA Crossover, Breakout, Mean Reversion, Momentum) with when-to-use / when-not-to-use notes
- Analytics & alerts — performance and indicator views; condition-based alerts with email / SMS / webhook as product channels
Admin and public
- Admin — users and roles, logs, subscriptions, customers, payments, plans, market sync, docs, Paytm and Google credential screens
- Public — landing, features, analytics, strategies, pricing, about, blog listing/detail, support, privacy / terms / cookies / security. Feature cards on the marketing site: real-time portfolio tracking, analytics, strategy builder and backtesting, alerts, risk management, live market data. The public Analytics page shows sample Sharpe / CAGR / drawdown / win-rate tiles — those are marketing fixtures, not a verified live book.
Quantity auto-sizing from ATR and “recommendation: Hold/Buy/Caution” are UI contracts on computed fields. They are not a promise of profit. The landing “14-day free trial” line is public CTA copy — this case study still does not claim a finished Paytm checkout.
Realtime
Two WebSocket surfaces, not one kitchen-sink socket:
- Customer — portfolio, positions, quotes (and related book events)
- Admin — subscriptions, customers, payments plus an MRR/seats snapshot
The client hook registers handlers for portfolio, quotes, positions, alerts and admin summary. If the socket drops, periodic polling still refreshes the screens. That is how a trading UI survives a flaky network without pretending the tape is a REST list. The dashboard session showed a connected WebSocket; the P&L screen in the same run showed Live WS disabled plus Refresh — both states are part of the product, not a contradiction hidden off the page.
Auth, payments and OAuth
- Auth — email/password JWT; Continue with Google; separate Sign In vs Admin entries on the public nav. Google client id/secret is stored through admin and masked on read
- Paytm — credentials stored masked in the database. Initiate / callback / status are designed to be extended. This case study does not claim a live public checkout
- Secrets — Paytm and Google payloads live in
api_keys; reads return masks. Encryption-at-rest can wrap that column; this page does not claim a HSM
Plans, subscriptions, customer accounts and payment transactions are first-class rows so ops can see seats and status without opening a spreadsheet.
Content, FAQ and support chat
The same API that serves the book also serves trust surfaces.
- Blog — admin CRUD, categories, featured image, SEO fields, public listing and slug pages
- Legal — privacy, terms, cookies, security as CMS pages, not hardcoded HTML only
- FAQs — keyword matching, view/helpfulness counters, common FAQs in the widget
- Support — floating chat on pages plus a full support route. Flow: FAQ match → wait if an admin just replied → optional OpenAI → fallback copy. Admin can reply and close chats
OpenAI is optional. If the key is absent, FAQ matching and fallback messages still work. That is the correct failure mode for a support widget.
Data model (what matters)
Identity: users, roles, permissions, API keys. Commercial: customer accounts, plans, subscriptions, payment transactions. Book: portfolios, positions, orders, trades, margin snapshots. Tape: quotes, ticks, indicators cache. Discretion: strategies, alerts, alert events. CMS: blog posts, legal pages, support chats/messages, FAQs.
Relationships are ordinary and therefore auditable: a portfolio owns positions; orders own trades; alerts own events; a chat owns messages with cascade delete; plans feed subscriptions. Alembic owns schema change. Seed data exists for local bring-up — credentials for that seed are not published here.
Engineering challenges
- Stale book vs live tape — WebSocket push plus polling, not a single GET that looks live
- Role split — customer must not see admin billing; admin summary is a different channel
- Secrets in the product — Paytm and Google must be configurable without landing in git or in JSON responses
- AI after data — predictions and support copy consume computed or FAQ context; they do not invent quantity
- Payments honesty — storing Paytm credentials is not the same as a finished checkout
How those were solved
Market and portfolio services write to PostgreSQL; sockets publish snapshots. Admin credential screens mask on read. Support tries FAQ before the model. Payment tables exist so checkout can be completed without redesigning billing. Docker Compose plus Alembic is the documented deploy path; this page does not paste env files.
My role
Architecture + full-stack + realtime. API and schema, market/portfolio/strategy surfaces, WebSocket channels, CMS and support, admin credential storage, Next.js role-aware UI. Live client books stay off this page.
Technology stack
These technologies are the documented stack. This page does not add brokers, exchanges or certifications that were not part of the work.
Production considerations
- Market data and P&L disclaimers — not a broker/depository product.
- User portfolio isolation and encrypted credentials storage.
Engineering outcomes
No invented AUM, CAGR or “users made X%.” What this system actually established:
- A customer path from login → live book and tape → strategies/alerts → analytics, with the signed-in nav matching the screenshots on this page
- Kite-shaped order ticket and Sync from Kite on the dashboard — credentials still configured in integrations, not implied as a live broker session
- An admin path for users, plans, subscriptions, market sync, CMS and support
- Public SEO pages fed from the same CMS tables
- FAQ-first support with optional OpenAI and human takeover
- Masked storage for Paytm and Google OAuth, with payment initiation left extendable
Screenshots and diagrams
Architecture on this page is the HTML diagram above. The walkthrough is also on the Portfolio analysis platform demo page and in How AI is changing the way India invests in the share market.
Architectural insight
A wealth product is a book, a tape, a rule engine and an ops console. If the LLM owns the positions, you do not have a product you can defend. If PostgreSQL owns the book and the model only comments or answers FAQs, you do.
Disclaimer: Portfolio analysis platform is software for analysis and operations. It is not a broker, PMS, investment adviser or exchange. Nothing here is a recommendation to buy or sell securities. Vendor capabilities (Kite Connect, Paytm, Google OAuth, OpenAI) are described as advertised integrations in this build.
FAQ — buyer & architecture questions
Ten common questions about this case study, fit, and engagement.
Building a market-data or portfolio product?
Share the book, the tape, the roles and whether checkout is in scope. The first reply is whether the gap is realtime, broker sync, strategy rules or admin SaaS.
Discuss Your Project