Work / Chitragupt / Wiki / Surfaces
settings-linked-brokers
Surfacecanonicalverified 2026-09-07
SURFACE.WEB.SETTINGS.LINKED-BROKERSSettings — Linked brokers
Summary
The durable, revisit-anytime surface for linking Dhan / Zerodha / Upstox / Angel One so Portfolio can sync holdings automatically, per 2026-09-01-broker-api-sync-as-source. A new top-level Settings rail item — deliberately named "Linked brokers," not "Connected accounts," since settings-profile.html already uses that exact phrase for Google sign-in; same label on two different Settings features would be ambiguous. Four states: empty (no brokers linked), connecting (transient OAuth redirect/callback), active (one or more linked, synced), sync-error (a linked broker's session expired and needs reconnect).
Raw wireframe
- .context/designs/web/settings/linked-brokers.html (empty)
- .context/designs/web/settings/linked-brokers-loading.html (transient)
- .context/designs/web/settings/linked-brokers-active.html (linked, incl. inline disconnect-confirm)
- .context/designs/web/settings/linked-brokers-error.html (needs reconnect)
Copy
- Heading: "Linked brokers"
- Empty-state sub: "Connect a broker so Chitragupt can read your current holdings automatically, instead of you uploading a statement each time. This is read-only — we can see your holdings and trades, never place an order."
- Explainer strip: "Every sync is saved as its own record, the same way an uploaded statement is — nothing here overwrites or hides what came before. You can disconnect any broker at any time; we delete the stored access straight away. Learn more →" (links settings-privacy-data)
- Per-broker card sub-labels: Dhan "Holdings only · no live price on this broker's feed"; Zerodha/Upstox/Angel One "Holdings + live price"
- Active-state badges: "Synced" (emerald) · "Session expired" (amber)
- Sync-error explainer: "Zerodha logs you out of connected apps daily. This isn't an error on our side — reconnect takes a few seconds and nothing you've already synced is affected."
- Disconnect confirm: "We'll delete the stored access immediately — Chitragupt can't read this account anymore until you reconnect. Holdings already synced stay in Portfolio as a record; they just stop updating."
- Footer (empty state): "Don't use one of these brokers? Keep uploading your broker's holdings statement in Inbox as usual — nothing changes there."
Behaviour
- Disconnect is styled destructive (rose), not the neutral gray
settings-profile.htmluses for unlinking Google sign-in — deliberate: disconnecting here kills live Portfolio sync, a bigger consequence than dropping an OAuth login method. - "Sync now" triggers an on-demand pull; each pull (scheduled or manual) persists its own immutable source artefact per 2026-09-01-broker-api-sync-as-source before it reaches Portfolio.
- Every state — including sync-error — keeps prior synced holdings visible in Portfolio; a stale/expired connection never blanks existing data, only stops it from updating.
- The per-broker auth shape is now resolved — see 2026-09-07-broker-connect-per-broker-auth. Three shapes, declared server-side and returned by
getBrokerConnectOptions, so the UI renders from data rather than a hard-coded branch:- Zerodha, Upstox — a real redirect to the broker's login page. The "connecting" state is the live route
/settings/brokers/callback, which finishes the connect itself rather than bouncing the single-use login code back through Settings. - Dhan — an inline paste-your-access-token field, expanding inside the broker's own row (same in-row expansion the disconnect confirm uses, not a modal).
- Angel One — an inline client-code + trading-PIN + authenticator-code form. The PIN and code are used once and never stored.
- Zerodha, Upstox — a real redirect to the broker's login page. The "connecting" state is the live route
- A broker this deployment has no app credentials for reports
available: false: its row greys out and reads "Not available yet — upload this broker's holdings statement in Inbox instead." Dhan needs no app registration, so it is always offered. - Sync status refreshes without a reload — the page subscribes to
users/{uid}/linked_broker_accountsdirectly, so the 05:30 IST scheduled sync updates the row in place. - Relative sync times render through the app-wide
formatRelativeTime("4m ago"), not the wireframe's longhand "4 minutes ago" — one time format across the product beats per-surface phrasing.
Flows that touch this surface
- new-user-to-dashboard — reachable via the optional onboarding-connect-broker nudge, and independently any time after.
Entities referenced
Sources
- .context/wiki/decisions/2026-09-07-broker-connect-per-broker-auth.md
- .context/wiki/decisions/2026-09-01-broker-connect-own-phase.md
- .context/wiki/decisions/2026-09-01-broker-api-sync-as-source.md
- .context/designs/web/settings/linked-brokers.html
Every project of mine is written down like this.
Read the résumé