Architecture & High-Level Design

Architecture, integrations, security boundaries and design decisions.

Architecture and High-Level Design

Solution Context, Components, Integrations and Quality Attributes

ICICI Direct • Interactive Brokers • Revolut

Embedded document image

Figure 1. Target architecture and principal trust boundaries.

Design intent Provide a secure personal portfolio hub that accommodates three incompatible source-integration patterns while maintaining cached availability and simple operations.

1. Architecture overview

The system uses a browser-facing Oracle Ubuntu platform as the consolidation layer. Nginx terminates HTTPS, serves static pages and proxies API traffic to a Flask service managed by PM2. Broker data is normalised into JSON snapshots. Market prices are obtained server-side, cached, and combined with holdings data for dashboards.

2. Logical layers

LayerComponentsResponsibilities
Presentation$hail's Dashboard, ICICI page, ibkr.html, Revolut.html, upload pagesNavigation, status, cards, charts, tables and controlled user actions.
Edge / webNginx, TLS, basic authentication, route-specific agent exceptionStatic delivery, reverse proxy, authentication boundary and HTTPS.
ApplicationFlask breeze-api, Revolut processor/upload blueprint, IBKR agent-control blueprintBroker orchestration, validation, secure actions, job state and snapshot publication.
Local IBKR integrationTWS/IB Gateway, export_ibkr.py, ibkr_windows_agent.pyAuthenticated local socket access, portfolio export and secure outbound upload.
DataSnapshot JSON, external price JSON, mappings, logs, backupsState, auditability, last-known-good values and recovery.
SchedulingUbuntu cronWeekday price refreshes at configured UTC times.
External servicesICICI Breeze, Twelve Data, Alpha VantagePortfolio data and supported market prices/FX.

3. Integration patterns

ICICI Direct: synchronous API

The browser calls Oracle /api routes; Flask authenticates to Breeze using server-side environment values and returns portfolio JSON.

IBKR: asynchronous command and agent

The browser queues a job. A Windows agent polls outbound over HTTPS, claims the job, calls TWS locally and uploads the resulting snapshot.

Revolut: secure file ingestion

The browser uploads CSV files to Flask. Private upload directories and a full-history processor produce a normalised snapshot.

Pricing: scheduled cache

Cron invokes Python scripts. Providers are called server-side, and the browser reads only cached JSON.

4. Deployment topology

NodeRuntime / assetsConnectivity
Oracle Ubuntu VMNginx, Flask, PM2, Python virtual environment, cron, /var/www/html, private app directoriesInbound HTTPS; outbound HTTPS to broker/price APIs.
Windows laptop(s)TWS, Python, export script, polling agent, private configLocal TWS socket; outbound HTTPS to Oracle agent endpoints.
Browser deviceModern browserHTTPS to Oracle; may be different from TWS laptop.
External providersBreeze, Twelve Data, Alpha VantageHTTPS API calls from Oracle only.

5. Security architecture

6. Data flow summary

FlowSource → DestinationPayloadControl
ICICI readBrowser → Nginx → Flask → BreezeJSON request/responseSite auth; Breeze server credentials
IBKR requestBrowser → Flask state fileJob ID/statusSite auth + admin PIN
IBKR agentWindows agent → FlaskClaim/progress/uploadPrivate agent token
Revolut uploadBrowser → Flask private upload directoryTwo CSV filesSite auth + admin PIN + validation
Price refreshCron → provider APIs → cache filesQuote/FX JSONServer-side API keys + throttling
Dashboard displayBrowser → static snapshots/cachesJSONSite authentication

7. Availability and resilience

8. Capacity and constraints

Twelve Data Basic is used within its published credit limits for supported US equities, FX and crypto. Alpha Vantage free access is treated as scarce and reserved primarily for mapped UK/EU symbols. TWS API access requires a running TWS or IB Gateway process and network connectivity from the local agent to that process.

9. High-level operational schedule

JobScheduleOutcome
refresh_revolut_prices.py22:30 UTC, Monday–FridayUpdate Revolut supported prices and FX cache.
refresh_ibkr_prices.py22:40 UTC, Monday–FridayUpdate IBKR price cache and enrich snapshot values.
IBKR holdings refreshOn demandTWS agent creates and uploads a current snapshot.
Revolut holdings refreshOn demandFull-history CSV upload rebuilds snapshot.

10. Key design decisions

DecisionRationaleTrade-off
JSON snapshots instead of a databaseSimple, inspectable and suitable for personal scale.Limited querying/concurrency.
Polling Windows agentWorks behind home NAT without opening inbound laptop ports.Agent and TWS must be running for holdings refresh.
Server-side price cachingProtects keys, controls quotas and improves dashboard speed.Prices are as fresh as the scheduled/manual refresh.
Full Revolut rebuildReduces duplicate/delta reconciliation errors.Processing grows with statement length.
Provider fallbackMaintains usability when coverage or quota fails.Data freshness may vary by symbol.

References