Optimization in the IRIS browser and API
How IRIS proxies optimize requests to DIONYSUS, what the browser sends, and how production auth differs from local dev.
Two URLs, one capability
| Layer | Typical path | Notes |
|---|---|---|
| IRIS (BFF) | POST /api/optimize | What the browser calls. Session cookies + server-side forwarding. |
| DIONYSUS (service) | POST /api/v1/portfolios/optimize | Canonical service route; OpenAPI documents request/response models. |
Retail users should stay on IRIS. Integrators and operators may hit DIONYSUS directly only with the right auth and network policy (Cloud Run often requires IAM + OIDC ID token with audience = service URL).
What the browser payload should contain
Conceptually, the body matches PortfolioRequest: at minimum name, total_capital (≥ $1,000 validated server-side), and risk_settings (fractions 0–1 for max risk and position size in the API contract).
Legacy field names
Some UIs historically sent portfolio_name or portfolio_capital. IRIS may normalize those to name / total_capital before forwarding—if your integration still uses legacy keys, confirm against the current OpenAPI spec.
Risk percentages vs fractions
Onboarding flows sometimes collect whole-number percents (e.g. “2.5” meaning 2.5%). The API expects fractions (0.025). IRIS includes heuristic normalization for certain paths so advanced screens do not silently send 100× too large a risk budget. If numbers look wildly off, verify whether you are in percent vs fraction mode in the UI before filing a bug.
Investor profile and constraint packs
Structured flows may attach:
investor_profile— quiz snapshot for audit (goal/horizon may be stored even when they do not drive numeric policy v1).constraint_pack— sector caps, vol target, turnover budget (see Constraint packs and optimizer diagnostics).prior_book_weights— for rebalance-style runs (see Rebalancing and turnover limits).
Authentication: local vs production
- Local IRIS — You are logged in with Firebase session; the Flask app forwards your identity to backends.
- Production — IRIS on App Engine (or similar) often calls Cloud Run services with Google OIDC ID tokens (audience = target service URL) in addition to end-user context headers. Anonymous public calls to DIONYSUS are not the supported model.
Do not paste service URLs into a browser expecting a JSON form without auth—you will get 403/401 by design.
Timeouts and heavy portfolios
Optimization can be CPU- and IO-heavy (batch Firestore reads, parallel scoring). If the UI times out while the server still runs, you may see 504 or empty responses. Retry once, then wait and check whether a portfolio was partially created (support can correlate trace_id from logs). Widen client timeouts only if your platform team approves—blind retries can duplicate work.
After optimize succeeds
IRIS typically navigates you to portfolio detail or a review step. Allocated vs remaining capital on the response should match what you see after Firestore sync; if not, refresh and check /status for ATLAS/Firestore health.
Developers
Retail cross-links
Progress is saved in this browser. Cloud sync requires PUBLIC_IRIS_API_BASE, IRIS CORS allowlist,
and window.__trinityIdToken.