How I Built a Multi-Asset Investment Platform with Next.js, PostgreSQL, Docker and AI A developer built ApexPulse, an open-source multi-asset investment dashboard that unifies Binance crypto holdings, Trading 212 stocks and ETFs, and Nigerian Stock Exchange positions behind a modular monolith on Next.js 15 and TypeScript, with PostgreSQL and Prisma as the shared data layer. A dedicated pricing engine routes each holding to its source (Binance, Yahoo Finance, synced broker data, or the Mansa API with a scraper fallback) and normalises all prices to USD, while a separate cron worker syncs holdings, builds market snapshots, and generates AI swing signals through OpenAI with a DeepSeek fallback, storing only signals above an 80% confidence threshold and emailing daily briefs via Resend. External price providers are treated as best-effort dependencies, falling back to a holding's cost basis when a live quote is unavailable. Most investment dashboards are easy to build when every asset comes from one provider. The real engineering challenge starts when your portfolio is spread across different markets, currencies, APIs, and data sources. That is the problem I am solving with ApexPulse . ApexPulse is a multi-asset investment dashboard designed to bring together: • Binance crypto holdings • Trading 212 stocks and ETFs • Nigerian Stock Exchange NGX positions • Different currencies and pricing sources • AI-generated market signals • Automated portfolio updates and daily intelligence Instead of forcing every data provider into the UI directly, I designed ApexPulse as a modular monolith with clear responsibilities. The core application runs on Next.js 15 + TypeScript , while PostgreSQL and Prisma provide the shared data layer. A dedicated pricing engine routes each holding to the correct source: Crypto → Binance US stocks → Yahoo Finance Trading 212 → synced broker data NGX → Mansa API with scraper fallback All prices are normalised internally into USD so the rest of the application works with one consistent pricing model. That removes a major source of complexity from the dashboard itself. Another important part of the architecture is background processing. A separate cron worker handles work that should not depend on a user opening the application. It: • Synchronises Binance holdings automatically • Builds market snapshots • Generates AI swing signals • Applies an 80%+ confidence threshold • Stores qualified signals in PostgreSQL • Sends daily portfolio intelligence through Resend For deployment flexibility, I also included GitHub Actions as an alternative scheduling mechanism . That means scheduled jobs do not have to depend entirely on the application process itself. GitHub Actions can trigger automation independently when that deployment model makes more sense. The system also uses: 🔐 NextAuth v5 for authentication 🐘 PostgreSQL + Prisma for persistence ⚡ TanStack Query for client-side caching and refresh 🤖 OpenAI with DeepSeek fallback for AI signals 📩 Resend + React Email for daily briefs 🐳 Docker for consistent local and production environments ⚙️ GitHub Actions for workflow automation and optional scheduling 🧠 Redis reserved for caching and rate limiting One architectural requirement I considered carefully was resilience. Financial APIs are not always available. A provider may become rate-limited, return incomplete data, or temporarily fail. ApexPulse therefore treats external price providers as best-effort dependencies . When a live quote cannot be retrieved, the system can fall back to the holding's existing cost basis rather than returning zero, removing the asset, or breaking the dashboard. That design decision matters because availability should not depend entirely on one external API. I also deliberately avoided moving immediately to microservices. At this stage, a modular monolith gives ApexPulse: • Clear domain separation • Simpler deployment • Lower operational complexity • Shared transactional data • Easier local development • A clear path to split services later if scale requires it Redis, managed workers, queues, and further service separation can be introduced when there is an actual scaling requirement rather than adding infrastructure prematurely. Building ApexPulse has reinforced something I think matters in software engineering: Architecture is not about using the largest number of technologies. It is about designing boundaries, failure behaviour, automation, and data flow around the problem being solved. I have made the project public for anyone interested in reviewing the implementation or architecture: 🔗 https://github.com/bhoyee/ApexPulse https://github.com/bhoyee/ApexPulse I would particularly like feedback from engineers working with distributed systems, fintech platforms, backend architecture, or cloud infrastructure: Which part of this architecture would you separate first if the platform started scaling significantly?