← All projects Next projectInvestment Tracker Platform
Private Investment Portal
A single-user, security-first portal that tracks crypto, Indian mutual funds and NSE/BSE stocks, and calls my phone when the market dips.
- Next.js 16
- TypeScript
- PostgreSQL
- Drizzle
- Docker
- Caddy
- AWS EC2
- GitHub Actions
The code is private because it runs against my own accounts. I'm happy to walk through it in an interview.
I wanted alerts I couldn't sleep through when a position moved sharply, and I didn't want my holdings sitting in a third-party app. So I built my own portal, treated it like a production service, and deployed it behind my own domain.
What it does
- Tracks holdings across crypto (CoinGecko), Indian mutual funds (MFAPI) and NSE/BSE stocks (Upstox) behind a pluggable price-provider interface.
- Average-cost holdings with realised and unrealised P&L, plus CSV import of past transactions.
- Alert rules for sharp dips or spikes within a window, 24h change thresholds and price targets.
- Alerts go out as Telegram messages with Acknowledge and Mute buttons, and escalate to a voice call for the serious ones.
Alerting that doesn't cry wolf
- Edge-triggered evaluation with per-rule cooldowns, so a sustained dip fires once instead of every minute.
- Quiet hours and a daily summary, all in IST.
- A background worker holds a Postgres advisory lock, so only one instance evaluates rules even if two are running.
- A dead-man's-switch ping tells me if the worker itself stops.
Security, as if it held someone else's money
- Mandatory TOTP 2FA, Argon2id password hashing and database-backed sessions.
- Login rate limiting and lockout, keyed on the client IP that the reverse proxy overwrites, so it can't be spoofed.
- Nonce-based Content Security Policy, CSRF origin checks on every mutation, and an audit log.
- Third-party API tokens encrypted at rest. Postgres is bound to loopback only, and containers run read-only with all capabilities dropped.
Shipping it
- CI runs lint, typecheck, tests and a build on every push. Merges to main build an image to GHCR.
- Deploys use GitHub OIDC → a narrowly scoped AWS role → SSM Run Command. There are no SSH keys and no long-lived AWS credentials in CI.
- The deploy script health-checks the new containers and rolls back automatically if they fail.