Back to portfolio

Full-Stack

J.J.J Investments - Family Portfolio Platform

A multi-user investment platform where the hard part is not the charts, it is keeping the numbers correct across currencies, roles and redeploys.

J.J.J Investments - Family Portfolio Platform

The problem

A family managing investments together has a problem a single-user app does not: several people touch the same portfolio, holdings sit in different currencies and on different exchanges, and every figure on screen has to reconcile with the transaction history behind it. On top of that, a portfolio app is only credible to a stranger if they can walk in and see real-looking data immediately, without creating an account.

Approach

  • The domain is modelled in Prisma across seven entities: users, family members, investments, portfolio items, transactions, alerts and investment goals, with roles and transaction types as enums rather than loose strings.
  • Roughly eighteen API routes cover portfolio, positions, transactions, family membership and invitations, goals, alerts and reports, so the front end never talks to the database directly.
  • Holdings span Brazilian equities on B3 and US equities on NASDAQ, so values are held per currency and converted through a dedicated exchange-rate endpoint instead of assuming one currency.
  • Authentication uses NextAuth with role-based access, and sign-in attempts pass through a rate limiter to make credential stuffing expensive.
  • A one-click demo account lets anyone in without registering. The seeding endpoint is written with upserts, so re-running it after a deploy refreshes prices instead of duplicating or destroying the demo data.
  • Errors and logging are centralized in their own modules rather than scattered console calls, which is what makes a production incident diagnosable.

What it proves

  • 121 automated tests: Jest for API routes, components and helpers, plus Playwright end-to-end specs covering authentication, dashboard and portfolio management.
  • Live demo with visible credentials (demo@jjj.com / Demo1234!) and realistic seeded data, no signup required.
  • The demo survives redeploys: an earlier deploy step used to wipe the demo user, and the seeding was made idempotent to fix it for good.
  • Multi-currency portfolio values reconcile with the underlying transaction history.
Next.js 14TypeScriptPrisma ORMPostgreSQLTailwind CSSNextAuth.jsRechartsshadcn/uiJestPlaywright

Building something like this?

Let's talk