Daily portfolio data quality queue for Addepar ops teams

By General Input

Open one screen each morning, work through flagged holdings and missing client data in Addepar, fix what you can inline, and escalate the rest.

Integrations

  • Addepar
  • Jira
  • Slack Bot

Type

App

Categories

  • Operations
  • Finance

Build me an app that my portfolio data operations team opens every morning to work a firm-wide data quality exception queue in Addepar. The people using it are data ops reviewers who each own a set of households, plus a team lead who watches the whole queue burn down through the day.

The main screen is the exception queue: a list of flagged holdings and entities grouped into exception types. Start with three types. First, stale valuations: assets with no valuation posted in the last N days, where N is a setting that defaults to 5 business days. Second, incomplete records: positions whose owner entity or owned entity is missing attributes that its entity type requires, which I find by reading the required attributes for each type with Addepar List Entity Types and comparing them against what the entity actually has. Third, large moves: holdings whose market value moved more than a set threshold since the prior close, defaulting to 15 percent. Each row shows the entity name, the household it rolls up to, the exception type, the specific detail such as days since last valuation or percent moved, and its current review state. Let me sort and filter within a group, and show a count next to every exception type header.

Loading the queue matters a lot here because Addepar rate limits are per firm, at 50 requests per 15 minute window and 1000 per 24 hours. Build the queue from a small number of batched Addepar Query Portfolio Data calls that pull market value, prior close value and last valuation date as columns across many holdings at once. Do not fetch per row. Compute the exception types in the handler from those batched results. There is no bulk list endpoint for snapshots, so detect valuation staleness from Query Portfolio Data columns rather than trying to list snapshots. Use Addepar List Entities and List Positions to resolve entity names, types and ownership links for the rows in the queue, again in batches. Any single Addepar request that runs longer than 60 seconds fails, so if the firm-wide extract is large, submit it with Addepar Submit Async Portfolio Job and poll for the result. Cache the loaded queue in the app's own storage, show a last refreshed timestamp, and give me a manual refresh button instead of refetching on every page view.

Clicking a row opens a detail pane beside the list. The pane shows the full entity record from Addepar Get Entity including its attributes and which required ones are blank, the ownership link from Addepar Get Position showing owner and owned entity with inception details, and recent activity from Addepar Get Transaction for the transactions tied to that holding so the reviewer can see what last moved.

The pane has inline fixes so most exceptions never leave the app. A form to fill missing attributes and save them with Addepar Update Entity, showing which fields the entity type requires. A form to correct inception details, display name or custom attributes on the ownership link with Addepar Update Position. And a form to post a refreshed value for a stale asset with Addepar Create Snapshot or Valuation, taking a value and an as of date, using a snapshot for share or percent based assets and a valuation for value based assets like real estate, private equity and hedge funds. After any successful write, update that row in place and mark it cleared rather than reloading the whole queue.

Anything the team cannot fix inline gets escalated from the same pane. An escalate action opens a form prefilled with the entity name and the exception detail, creates a ticket with Jira Create Issue in a project I configure, and posts a note to our ops channel with Slack Send a Message that names the entity, the exception type, the reviewer who escalated it and a link to the Jira issue. Store the resulting issue key on the exception so the row shows it and nobody escalates the same thing twice.

Review state has no home in Addepar, so persist it in the app's own storage. Each exception can be marked reviewed or accepted with a free text note, and I want to see who set it and when. Let each reviewer filter the queue to just the households they are assigned, with the assignment list editable in a settings view, and remember each person's last filter. Show an open versus cleared counter at the top that updates as rows are worked, so the team can watch the queue burn down through the day. Keep the settings for the staleness window, the move threshold, the Jira project and the Slack channel in one settings view rather than hardcoded.

Related prompts

Explore more prompts
A brand asset library your marketing team actually searchesTurn Mailjet email clicks into ranked HubSpot follow-upsClean out the Looker dashboards and Looks nobody opensLiveKit live operations console for room moderationWake up dormant Keap leads with a researched reasonLiveChat coverage board for planning next week's shiftsPhone routing control panel for LiveKit voice agentsLinkedIn Ads budget pacing dashboard for every client accountGive your team Looker numbers without buying more seatsPause marketing emails to escalated customers, then restore them