Business Specification Document
Use Case Methodology and Business Process Flows
ICICI Direct • Interactive Brokers • Revolut
Figure 1. $hail's Dashboard is the single entry point to the three portfolio solutions.
| Document objective
Define the business scope, actors, use cases, rules, flows, acceptance criteria and operational exceptions for a personal multi-broker portfolio dashboard. |
|---|
1. Executive summary
The solution consolidates access to ICICI Direct, Interactive Brokers and Revolut portfolio views behind a single authenticated web dashboard. Each broker uses a different integration method: Breeze API for ICICI Direct, a TWS-connected Windows agent plus Oracle-hosted snapshot for IBKR, and secure CSV ingestion for Revolut. Daily external market prices are cached on Oracle to keep dashboards useful when source applications are not open.
2. Business objectives
- Provide one browser entry point for all portfolios.
- Separate holdings refresh from market-price refresh.
- Avoid exposing broker credentials and market-data API keys to browser clients.
- Retain usable cached values when an external provider fails or reaches a limit.
- Allow portfolio updates from another device while the TWS-connected laptop performs the local IBKR export.
- Support simple layperson operations with visible status messages and backups.
3. Scope
| In scope | Out of scope / deferred |
|---|
| ICICI funds, holdings and portfolio display through Breeze | Automated ICICI token issuance without user authentication |
| IBKR one-click snapshot request and daily cached pricing | Automated trade placement or order management |
| Revolut full-history CSV upload and portfolio reconstruction | Tax filing or certified tax-lot accounting |
| Twelve Data / Alpha Vantage cached pricing and FX | Guaranteed real-time data for every global exchange |
| Oracle hosting, security controls, backups and cron | Enterprise multi-user tenancy |
4. Actors
| Actor | Responsibility |
|---|
| Portfolio owner | Authenticates, renews Breeze token, uploads Revolut statements, starts TWS/Windows agent and requests IBKR snapshots. |
| Web browser | Displays dashboard pages and status; never holds provider API secrets. |
| Oracle Ubuntu platform | Hosts Nginx, Flask APIs, static pages, snapshots, caches, logs, schedules and backups. |
| ICICI Breeze API | Supplies ICICI portfolio and account data when the session is valid. |
| IBKR TWS / IB Gateway | Local authenticated IBKR source used by the Windows export agent. |
| Windows agent | Polls Oracle, claims a refresh request, runs export_ibkr.py and uploads the snapshot. |
| External price providers | Supply supported market prices and FX data to server-side refresh jobs. |
5. Use case catalogue
| ID | Use case | Primary actor | Precondition | Main flow | Postcondition |
|---|
| UC-01 | Open central dashboard | Portfolio owner | Authenticated site is reachable | Display cards for ICICI Direct, IBKR, Breeze token/login and Revolut | Selected portfolio page opens |
| UC-02 | Refresh ICICI portfolio | Portfolio owner | Valid Breeze session token | Open ICICI Direct Portfolio; dashboard calls Breeze-backed API | Funds and holdings appear |
| UC-03 | Renew Breeze token | Portfolio owner | ICICI login available | Generate token; open Breeze Session Token card; submit token and admin PIN | Server .env contains current token |
| UC-04 | Request IBKR snapshot | Portfolio owner | TWS logged in; Windows agent running | Click Refresh IBKR Snapshot; enter PIN; server queues job | Agent claims job |
| UC-05 | Export/upload IBKR snapshot | Windows agent | Queued job and valid agent token | Connect locally to TWS; run export; upload JSON | Oracle publishes a validated snapshot and dashboard reloads |
| UC-06 | Refresh IBKR prices | Cron scheduler | Price keys, mappings and prior snapshot available | Run refresh_ibkr_prices.py | Price cache and enriched snapshot updated |
| UC-07 | Upload Revolut statements | Portfolio owner | Full account CSV available; optional P&L CSV | Upload validated files with admin PIN | Revolut snapshot rebuilt and browser returns to dashboard |
| UC-08 | Refresh Revolut prices | Cron scheduler | Mappings and price keys available | Run refresh_revolut_prices.py | Supported prices/FX cached; Pending remains for unmapped symbols |
| UC-09 | View portfolio metrics | Portfolio owner | Snapshot/cache exists | Open/refresh portfolio page | Cards, charts, market value and P/L display |
6. Detailed primary flows
6.1 ICICI Direct refresh flow
- Open $hail's Dashboard.
- If the Breeze session is valid, open ICICI Direct Portfolio.
- If the session is expired, open ICICI Breeze Login and generate a current token.
- Open Breeze Session Token, submit the token and admin PIN.
- Return to ICICI Direct Portfolio and reload.
6.2 IBKR holdings and account flow
- Log in to TWS on a configured Windows laptop.
- Start ibkr_windows_agent.py and keep the PowerShell window open.
- From any browser, click Refresh IBKR Snapshot and submit the admin PIN.
- Oracle records a queued job. The first authenticated agent claims it.
- The agent runs export_ibkr.py against the local TWS socket.
- The agent uploads ibkr_snapshot.json using the private agent token.
- Oracle validates, backs up and publishes the snapshot. The browser polls status and reloads after success.
6.3 Revolut transaction flow
- Download a complete start-to-date account statement CSV and optional P&L CSV.
- Open the Revolut dashboard and choose Upload Revolut Statements.
- Select account and P&L files in the correct fields, enter the admin PIN and submit.
- The server validates extensions, size and required account columns.
- The processor reconstructs holdings, applies buys, sells, stock splits and merger adjustments, and ignores internal migration transfers.
- The prior snapshot is backed up; the new snapshot is published only after successful JSON validation.
- The browser returns to Revolut.html with a success message.
7. Business rules
| Rule | Definition |
|---|
| BR-01 | API keys, agent tokens and broker credentials must remain server-side or in protected local configuration. |
| BR-02 | A dashboard page load reads cached JSON and must not call external pricing providers directly. |
| BR-03 | IBKR holdings/account changes require a new TWS snapshot; external prices alone do not change quantities or cash. |
| BR-04 | Revolut updates use a full-history account statement to minimise duplicate or omitted transactions. |
| BR-05 | UK GBX quotes are divided by 100 before GBP valuation. |
| BR-06 | Unsupported symbols use Pending or an IBKR snapshot fallback; a failed provider call must not delete a previously valid cached price. |
| BR-07 | Revolut price refresh runs at 22:30 UTC weekdays; IBKR price refresh runs at 22:40 UTC weekdays. |
| BR-08 | Admin PIN authorises dashboard actions; the separate agent token authorises Windows agent endpoints. |
8. Alternate and exception flows
| Condition | Expected behaviour |
|---|
| Breeze token expired | ICICI page fails gracefully; user renews token and retries. |
| No Windows IBKR agent online | Request remains queued and dashboard displays Waiting for a Windows agent. |
| TWS unavailable or API socket disabled | Agent reports export failure; old snapshot remains. |
| Revolut files reversed | Validation reports missing account columns; old snapshot remains. |
| Alpha Vantage quota exhausted | Existing cache/fallback remains; error recorded; Twelve Data operations continue where applicable. |
| Unmapped Revolut symbol | Holding displays with Pending price; transaction-derived quantity/cost remains available. |
| Cron/API error | The log captures output; existing published cache remains available. |
9. Acceptance criteria
- Central page presents working links to all portfolio functions.
- ICICI portfolio loads when a valid Breeze token exists.
- IBKR refresh can be requested from one device and executed by a TWS-connected agent on another.
- Revolut upload rebuilds the portfolio and returns automatically to the dashboard.
- Scheduled price jobs update timestamped caches and preserve prior usable data after failures.
- Market value and unrealised P/L are calculated using current/cached price and cost basis.
- Sensitive secrets are absent from public HTML and JSON.
References
- Interactive Brokers API home: https://www.interactivebrokers.com/campus/ibkr-api-page/ibkr-api-home/
- Interactive Brokers TWS API introduction: https://interactivebrokers.github.io/tws-api/introduction.html
- Interactive Brokers TWS API connectivity: https://interactivebrokers.github.io/tws-api/connection.html
- Twelve Data pricing: https://twelvedata.com/pricing
- Alpha Vantage support and limits: https://www.alphavantage.co/support/
- Alpha Vantage API documentation: https://www.alphavantage.co/documentation/
- Ubuntu CronHowto: https://help.ubuntu.com/community/CronHowto
10. End-to-End Business Flow
This section provides the integrated business process that links the use cases into complete operational journeys. The flow begins at $hail’s Dashboard, separates holdings/account updates from price updates, and ends when the relevant portfolio page displays validated holdings, market values and P/L.
| End-to-end principle
The solution has two independent update cycles: (1) holdings/account data changes when broker or statement data changes, and (2) market prices change through scheduled external-price jobs. The dashboard combines the latest available result from both cycles. |
|---|
Figure 2. End-to-end business flow across ICICI Direct, IBKR and Revolut.
10.1 Overall process from the main dashboard
| Step | Business stage | Activity | Business outcome |
|---|
| 1 | Access | Portfolio owner signs in and opens $hail’s Dashboard. | Authenticated home page is displayed. |
| 2 | Select journey | Portfolio owner selects ICICI Direct, Interactive Brokers or Revolut. | Relevant portfolio page opens. |
| 3 | Determine update need | Portfolio owner decides whether holdings/account data changed or only prices need refreshing. | Correct manual or automatic path is selected. |
| 4 | Acquire source data | Breeze API, local TWS export, or Revolut CSV provides holdings/account data. | A current source payload is available. |
| 5 | Validate and publish | Oracle validates responses/files, creates backups and publishes a snapshot. | Last-known-good holdings snapshot is current. |
| 6 | Refresh market data | Scheduled jobs call supported external providers and apply cached/fallback values. | Timestamped price/FX cache is current. |
| 7 | Calculate portfolio | Market value and unrealised P/L are calculated from quantity, cost and price. | Portfolio metrics are available. |
| 8 | Present and monitor | Dashboard displays cards, charts, tables, status, timestamps and Pending/fallback conditions. | User can review the consolidated portfolio and take corrective action if needed. |
10.2 Trigger and routing decision
| Trigger | Portfolio | Required route | Manual action | Automatic action |
|---|
| Normal market day; no transactions | IBKR / Revolut | Price refresh only | Open/refresh dashboard after scheduled job. | Revolut 22:30 UTC; IBKR 22:40 UTC, weekdays. |
| ICICI session expired | ICICI Direct | Session renewal then portfolio read | Generate Breeze token; submit via Breeze Session Token card. | None. |
| IBKR buy, sale, cash or quantity changed | IBKR | TWS snapshot then price enrichment | Log in to TWS; start agent; click Refresh IBKR Snapshot. | Next price job enriches the new snapshot; existing cache remains available. |
| Revolut transaction/dividend changed | Revolut | Full-history statement rebuild | Upload complete account CSV and optional P&L CSV. | Next price job uses the rebuilt holdings. |
| Price missing | IBKR / Revolut | Fallback or mapping route | Map symbol later if required. | Use existing cache, IBKR snapshot fallback, or show Pending. |
10.3 ICICI Direct end-to-end journey
Figure 3. ICICI Direct journey and exception paths.
- Portfolio owner selects ICICI Direct Portfolio from $hail’s Dashboard.
- The system checks whether the Breeze session is usable when API data is requested.
- If valid, Flask calls Breeze for funds and portfolio holdings/positions and returns the response to the dashboard.
- If expired or invalid, the user opens ICICI Breeze Login, authenticates with ICICI, and obtains a new session token.
- The user opens Breeze Session Token, submits the new token with the admin PIN, and the server updates the protected environment file.
- The portfolio page is reopened or refreshed; cards, holdings, charts and P/L are displayed.
- If an API error or timeout occurs, the dashboard reports failure and the user retries after confirming the token and service availability.
| Entry criteria | Exit criteria | Failure state | Recovery |
|---|
| Authenticated dashboard; Breeze app credentials configured. | Funds/holdings displayed with current session. | Expired token, API error or timeout. | Generate/update token; retry portfolio page; inspect backend log if repeated. |
10.4 Interactive Brokers end-to-end journey
Figure 4. IBKR holdings/account and automated-pricing journeys.
10.4.1 Holdings and account change path
- Portfolio owner logs in to TWS or IB Gateway on a configured Windows laptop.
- Portfolio owner starts the Windows polling agent. The agent authenticates to Oracle with the private agent token.
- From any browser, portfolio owner clicks Refresh IBKR Snapshot and enters the admin PIN.
- Oracle creates a queued job. The first available agent claims the job and updates status to exporting.
- The agent runs export_ibkr.py, which connects to the local TWS socket and writes ibkr_snapshot.json.
- The agent uploads the snapshot to Oracle. Flask verifies the job ID and JSON, backs up the prior snapshot, and publishes the new file.
- The dashboard status changes to success and the browser reloads using the new account, position, cash and cost data.
10.4.2 Market-price path
- At the scheduled weekday time, cron runs refresh_ibkr_prices.py without requiring TWS.
- The script loads the latest IBKR positions and symbol mappings.
- Supported prices and FX are requested server-side. Provider pacing and daily limits are respected.
- Where an external quote is unavailable, the last IBKR snapshot market price is used as fallback.
- The script recalculates market value, cost basis, unrealised P/L and GBP totals, then publishes the cache and enriched snapshot.
- When the IBKR page is opened or refreshed, the updated cached/enriched values are displayed.
| Condition | Dashboard/system response | Business recovery |
|---|
| No agent online | Job remains queued; dashboard shows Waiting for a Windows agent. | Start agent on a TWS-connected laptop. |
| TWS not running or logged out | Agent cannot export and job becomes error. | Log in to TWS and request refresh again. |
| Order requests time out but portfolio saves | Exporter may still complete positions/account snapshot. | Confirm Connected: True, snapshot saved and expected position count. |
| Provider quota/error | Prior cache or snapshot fallback remains. | Wait for reset or use next scheduled cycle. |
10.5 Revolut end-to-end journey
Figure 5. Revolut statement-ingestion and automated-pricing journeys.
10.5.1 Transaction-change path
- Portfolio owner exports a complete start-to-date trading account statement CSV and, where available, the P&L statement CSV.
- Portfolio owner opens Revolut Portfolio and selects Upload Revolut Statements.
- The account statement is selected in the account field, the optional P&L statement in the P&L field, and the admin PIN is entered.
- Flask validates extension, file size, required account columns and file placement.
- The processor sorts the ledger, reconstructs FIFO lots, applies buys/sells/splits/mergers, excludes internal migration duplicates, and aggregates realised P/L and income.
- The old snapshot is backed up. The rebuilt JSON is validated and published only if processing completes successfully.
- The upload page redirects to Revolut.html and displays the holdings count and timestamp.
10.5.2 Market-price path
- At the scheduled weekday time, cron runs refresh_revolut_prices.py.
- The script reads the rebuilt holdings and symbol map, then refreshes supported US/UK prices and FX rates.
- Existing cached values are retained for failed requests; unmapped symbols remain Pending.
- Revolut.html combines quantity/cost from the snapshot with cached price/FX and calculates market value and unrealised P/L.
- The user refreshes the dashboard to view the latest published cache.
| Condition | Response | Recovery |
|---|
| Account/P&L files reversed | Required account columns are missing; upload is rejected. | Swap files and upload again. |
| Invalid CSV or PIN | No new snapshot is published. | Correct input/PIN and retry. |
| Corporate action | Processor applies configured split/merger logic. | Reconcile resulting holding count; update logic if a new format appears. |
| Unmapped external symbol | Price and price-dependent fields show Pending. | Confirm exact listing and enable mapping later. |
10.6 End-to-end controls and hand-offs
| Control point | Input owner | System control | Output / hand-off |
|---|
| Authentication | Portfolio owner | HTTPS/site authentication | Access to central dashboard. |
| Sensitive action | Portfolio owner | Admin PIN | Authorised token update, upload or IBKR request. |
| IBKR machine action | Windows agent | Private agent token + job ID | Validated outbound snapshot upload. |
| File ingestion | Portfolio owner / Revolut | Type, size and required-column checks | Private stored input and rebuilt snapshot. |
| Source publication | Oracle | Temporary write, JSON parse, backup, publish | Last-known-good snapshot. |
| External pricing | Cron / providers | Server-only keys, pacing, cache preservation | Timestamped prices and FX. |
| Presentation | Browser | Read-only snapshot/cache retrieval | Cards, charts, tables, status and timestamps. |
10.7 Use-case traceability to the end-to-end flow
| Business-flow segment | Use cases | Evidence of completion |
|---|
| Access and portfolio selection | UC-01, UC-09 | Central cards open the broker-specific views. |
| ICICI data acquisition | UC-02, UC-03 | Breeze session renewal and portfolio API flow. |
| IBKR holdings acquisition | UC-04, UC-05 | Dashboard request → agent claim → TWS export → snapshot upload. |
| IBKR valuation | UC-06, UC-09 | Scheduled price cache and enriched snapshot calculation. |
| Revolut holdings acquisition | UC-07 | Validated full-history CSV rebuild and redirect. |
| Revolut valuation | UC-08, UC-09 | Scheduled price/FX cache and client-side calculation. |
| Exception management | All | Status messages, rejected invalid input, cache/fallback and recoverable queued/error states. |