Skip to content

Expand disclosure latency providers - #120

Merged
jaywedgeworth22 merged 1 commit into
mainfrom
codex/app-update-hardening-20260629
Jun 30, 2026
Merged

Expand disclosure latency providers#120
jaywedgeworth22 merged 1 commit into
mainfrom
codex/app-update-hardening-20260629

Conversation

@jaywedgeworth22

@jaywedgeworth22 jaywedgeworth22 commented Jun 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • expand disclosure latency monitoring beyond FMP with provider status/summary support
  • keep provider timestamp migration separate from the original latency table migration
  • remove local Xcode workspace metadata generated while inspecting the iOS project

Verification

  • cd app && npm ci
  • cd app && npm run typecheck
  • cd app && npm test
  • preview deploy already passed before merge prep

Note

Medium Risk
Touches cron ingestion probes and external API credentials; schema migration adds columns but matching logic changes could affect latency metrics accuracy.

Overview
Disclosure latency monitoring is generalized from an FMP-only race to a multi-provider benchmark against FMP, Unusual Whales, and Quiver, with Finnhub, AInvest, and Capitol Trades listed in admin status but not auto-probed.

New filings now create pending candidates per direct provider; the scheduled probe fetches each provider’s latest feed, matches rows (including Quiver upload timestamps when present), and stores provider_published_at alongside monitor first-seen times. Admin APIs add GET /disclosure-latency/summary (aggregates plus a publicSummary without doc/member IDs), provider filtering on the list endpoint, and ?providers= on the manual probe. Config moves to DISCLOSURE_LATENCY_* env vars while keeping legacy FMP watch flags.

Also adds a CodeQL workflow for JS/TS, documents new API keys in .dev.vars.example, migration 0023 for provider timestamps, and removes stray Xcode workspace metadata files.

Reviewed by Cursor Bugbot for commit 4400274. Configure here.

@cursor

cursor Bot commented Jun 30, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_78d8df1b-d8f2-42de-8a43-c18fc4fb9e17)

@jaywedgeworth22
jaywedgeworth22 force-pushed the codex/app-update-hardening-20260629 branch from 4400274 to 1bb938e Compare June 30, 2026 20:25
@jaywedgeworth22
jaywedgeworth22 force-pushed the codex/app-update-hardening-20260629 branch from 1bb938e to 2eb6e6c Compare June 30, 2026 20:30
@jaywedgeworth22
jaywedgeworth22 merged commit e435a90 into main Jun 30, 2026
2 checks passed
@jaywedgeworth22
jaywedgeworth22 deleted the codex/app-update-hardening-20260629 branch June 30, 2026 20:31

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4400274851

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

);
} catch (err) {
if (!storageMissing(err)) console.warn('disclosure latency candidate write failed:', (err as Error).message);
for (const provider of DIRECT_PROVIDER_IDS) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Only create latency candidates for active providers

When DISCLOSURE_LATENCY_PROVIDERS excludes a provider or that provider's key is not configured, this still creates pending rows for every direct provider. Those rows are not part of a simultaneous race; if Unusual Whales or Quiver is enabled later, the first match will use the later first-poll time and can generate false Congress.Trade-ahead deltas/alerts, while summary totals are inflated even for fmp-only runs. Candidate creation should be gated to the providers actually selected/configured at discovery time.

Useful? React with 👍 / 👎.

}

async function fetchUnusualWhalesRows(apiKey: string, max: number, fetchImpl: typeof fetch): Promise<DisclosureProviderRow[]> {
const url = `https://api.unusualwhales.com/api/congress/recent-trades?limit=${Math.min(max, 200)}`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Query Unusual Whales by filing recency

This polls /api/congress/recent-trades with only limit, but the Unusual Whales docs describe that endpoint's date filter as a Market Date defaulting to the last trading date, while PTR filings commonly report transactions from days or weeks earlier. In that case newly filed disclosures with older transaction_date values never enter disclosure_provider_observations, so the provider looks pending/missing even though filed_at_date may be current; use a filing/report-recency query or page recent reports instead of the default last-trading-date slice.

Useful? React with 👍 / 👎.

return { ...base, configured: false, enabled: false, fetchedRows: 0, pending: 0, matched: 0, errors, reason: `${provider.secretNames[0]} missing` };
}

const nowIso = now.toISOString();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Timestamp provider observations when fetched

When multiple providers are configured, every provider run receives the same now from the scheduled/probe call, and this line records that value as first_observed_at even for providers fetched after earlier network calls complete. A slow earlier provider can therefore make later providers appear to have been observed seconds or minutes before they actually were, corrupting the latency comparison; capture a fresh timestamp around each provider response or run the probes in parallel with per-provider observation times.

Useful? React with 👍 / 👎.

return parseUnusualWhalesDisclosureRows(await fetchJson(url, { authorization: `Bearer ${apiKey}` }, fetchImpl));
}

async function fetchQuiverRows(apiKey: string, _max: number, fetchImpl: typeof fetch): Promise<DisclosureProviderRow[]> {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Honor the Quiver latency row limit

When a Quiver key is configured, the scheduled probe ignores DISCLOSURE_LATENCY_WATCH_LIMIT/FMP_DISCLOSURE_WATCH_LIMIT for this provider and writes however many rows the live House and Senate endpoints return each minute. If those feeds return more than the intended latest slice, this can burn API/D1 work and make probes much heavier than configured; apply the limit in the request if supported or slice the parsed rows before upserting.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant