Fix test suite, add Swapter/NYM/Revolut plugins, and add isolated v2 dashboard - #230
Open
j0ntz wants to merge 3 commits into
Open
Fix test suite, add Swapter/NYM/Revolut plugins, and add isolated v2 dashboard#230j0ntz wants to merge 3 commits into
j0ntz wants to merge 3 commits into
Conversation
Contributor
Author
j0ntz
force-pushed
the
jon/reports-v2-dashboard
branch
2 times, most recently
from
July 31, 2026 22:36
77d5d6d to
25b646d
Compare
Adds an isolated /v2/config route returning per-provider rev-share rates and fiat/swap classification. No v1 route is modified. The rates live on the app doc in reports_apps, as an optional revShareRate beside each partner's apiKeys. The rate is a property of the app-partner deal, so it is per app AND per partner, and it sits with the credentials that define the relationship: onboarding a partner is one doc edit, with no separate rates map to forget. The rates are commercial terms and this repo is public, so they are never committed or placed in config.json. A partner without one contributes 0 estimated revenue.
Ports the redesign prototype into src/demoV2 as a standalone dashboard served at /v2/, built into dist/v2 by a separate parcel invocation so v1's entry, bundle, and output are untouched. The prototype's sample-data layer is replaced by the real /v1 API (getAppId auth, getPluginIds, one analytics POST for all providers) plus /v2/config for rev-share and provider types. A bad or missing apiKey now redirects to a key-entry screen instead of hanging: getAppId returns plain text on 400, so the response is checked before parsing and fetch errors are surfaced.
Some partner APIs report Edge's actual fee per order; estimating that same number as volume times a configured rate discards a fact we already hold. This adds the pair StandardTx.revenueUsd / revenueSource: the actual USD figure, stored at ingest as a fact about the order, and the vocabulary that lets downstream consumers tell a reported figure from a derived one. Revolut is the first reporter: fees_partner_currency.partner_fee, pre-converted to USD by Revolut, taken only on settled orders (an unsettled attempt's fee is not revenue) and only when the settlement currency is USD (a conversion this plugin cannot do honestly). The cache engine sums reported revenue into the analytics buckets, and the v2 dashboard uses it directly wherever a provider reports, marked with a check in the provider table. Providers that report nothing keep the estimate, computed at read time from the app doc's per-partner revShareRate, so correcting a rate fixes history immediately while reported figures stay immutable. Pair rows attribute bucket revenue proportionally to volume share, the same rule the existing tx attribution uses. The revenue keys are optional at the type level rather than spelled out as explicit undefineds across every partner plugin; the cleaner still validates them when present. Cache docs written before this field lack it until the next cache rebuild, which fills history from stored txs with no partner re-query.
j0ntz
force-pushed
the
jon/reports-v2-dashboard
branch
from
July 31, 2026 23:03
25b646d to
cf6000c
Compare
Bugbot is paused — on-demand spend limit reachedBugbot uses usage-based billing for this team and has hit its on-demand spend limit. A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



CHANGELOG
Does this branch warrant an entry to the CHANGELOG?
Dependencies
none
Description
Batched integration branch for the reports-server umbrella: the broken test suite is repaired first (everything else depends on it), then three partner plugins, then the isolated v2 dashboard and partner-reported revenue. One commit per unit of work.
Asana: https://app.asana.com/1/9976422036640/project/1213843652804305/task/1217040330890732
Commits
Fix broken mocha test suiteutil.test.tsimport and stale analytics fixtures sonpm testpasses. Unblocks every landing in this repo.Add CI job to run the test suite.github/workflows/test.ymlrunsnpm teston every PR, so the suite cannot silently rot again.Add Swapter partner pluginAdd NYM Swap (nymswap) reporting pluginAdd Revolut fiat payment providerAdd v2 dashboard config endpoint and rev-share ratesGET /v2/config.Add isolated v2 reports dashboard/v2/dashboard itself.Track partner-reported revenue through to the dashboardStandardTx.revenueUsd/revenueSource, summed through the cache.Superseded PRs stay open until this lands: #211 and #219 are partner-owned fork branches (not ours to close), #224 is already closed.
Providers in scope but not in this branch: nexchange, Bridgeless, Simplex. They remain open on the umbrella.
v2 dashboard
v1 is untouched. v2 has its own entry point (
src/demoV2/), its own parcel bundle (built intodist/v2/by a separate parcel invocation), and its own URL. v1's parcelsource, routes, components and build output are unchanged. Shared v1 code is duplicated into v2 rather than refactored.src/demoV2/index.html— the full prototype UI (summary card; Providers and Currency pairs sections, each with a trend chart, a hover-linked donut + ranked-bar share card, and a detail table; global range/type/provider/pair filters; top-8-plus-Other color rules; paginated pair table). The rendering/interaction engine is ported verbatim; only the data layer changed.apiKeycookie (or?apiKey=), validates viaGET /v1/getAppId, then fetchesGET /v2/config,GET /v1/getPluginIds, and onePOST /v1/analytics(day buckets, last 24 months, all providers in a single call) and builds the per-provider daily series the engine consumes.getAppIdreturns plain text on a 400,response.json()throws, the mount promise dies silently and the page spins forever) is fixed: the response is checked before parsing and a bad/missing key redirects to a key-entry screen. No new auth system.src/routes/v2/getConfig.ts— new isolatedGET /v2/configreturning per-partner rev-share rates and fiat/swap classification. No v1 route is modified.src/demoV2/README.md— what v2 is, the endpoints it consumes, and local build/serve steps.Revenue
Where a partner's API reports Edge's actual fee per order, the plugin stores it on the transaction as
revenueUsdwithrevenueSource: 'reported', the cache engine sums it into the analytics buckets, and the dashboard uses it directly, marked with a check in the provider table. That figure is a fact about the order and is never recomputed. Revolut is the first reporter (fees_partner_currency.partner_fee, taken only on settled orders and only when the settlement currency is USD).Everywhere a partner reports nothing, the dashboard falls back to an estimate of
volume * revShareRate, computed at read time. Rates live on thereports_appsapp doc, beside each partner'sapiKeys, not inconfig.json: the rate is a property of the app-partner deal, it is commercial terms, and this repo is public. A partner with no rate contributes 0. Correcting a rate fixes history immediately, while reported figures stay immutable.Cache docs written before this change lack the revenue field until the next cache rebuild, which fills history from stored txs with no partner re-query.
Testing
npm testpasses (and now runs in CI on every PR).v2 verified end to end against a local CouchDB and the real API (
npm run build.dist→npm run start.api→/v2/). See attached screenshots:Endpoint checks:
getAppIdvalid→appId / invalid→400,/v2/configvalid→JSON / invalid→401,getPluginIds→registered providers,analyticsPOST→expected bucket shape.tscis clean; both v1 and v2 parcel bundles build. No browser console errors.Note: the dashboard screenshots predate the revenue commit, so the provider table in them has no reported-revenue check column.