Skip to content

add(pro-docs): price feed id changelog page#3536

Draft
aditya520 wants to merge 5 commits intomainfrom
feat/pro-price-feed-id-changelog
Draft

add(pro-docs): price feed id changelog page#3536
aditya520 wants to merge 5 commits intomainfrom
feat/pro-price-feed-id-changelog

Conversation

@aditya520
Copy link
Member

@aditya520 aditya520 commented Mar 9, 2026

Summary

  • Add a new Pyth Pro sibling docs page at /price-feeds/pro/price-feed-id-changelog with an Option C hybrid UX (daily rollups + expandable detail tables).
  • Add a snapshot/diff generator (generate:pro-price-feed-changelog) that fetches history/v1/symbols, stores UTC snapshots, and emits deterministic daily changelog JSON artifacts.
  • Use Pyth component-library primitives for the new UI and format day headings as human-readable UTC dates (for example, March 9, 2026 (UTC)).

Test plan

  • pnpm --filter @pythnetwork/shared-lib build
  • pnpm --filter @pythnetwork/component-library build
  • pnpm run build (in apps/developer-hub)
  • pnpm run generate:pro-price-feed-changelog (in apps/developer-hub)
  • Browser validation on /price-feeds/pro/price-feed-id-changelog:
    • baseline no-history state
    • multi-day rollup rendering (with temporary synthetic snapshots)
    • expand/collapse day cards
    • search + no-results + clear search
    • status-focused vs all-field toggle

Made with Cursor


Open with Devin

@aditya520 aditya520 requested a review from a team as a code owner March 9, 2026 21:05
@vercel
Copy link

vercel bot commented Mar 9, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
api-reference Ready Ready Preview, Comment Mar 12, 2026 4:13pm
component-library Ready Ready Preview, Comment Mar 12, 2026 4:13pm
developer-hub Ready Ready Preview, Comment Mar 12, 2026 4:13pm
entropy-explorer Ready Ready Preview, Comment Mar 12, 2026 4:13pm
insights Ready Ready Preview, Comment Mar 12, 2026 4:13pm
proposals Ready Ready Preview, Comment Mar 12, 2026 4:13pm
staking Ready Ready Preview, Comment Mar 12, 2026 4:13pm

Request Review

@vercel vercel bot temporarily deployed to Preview – proposals March 9, 2026 21:05 Inactive
@vercel vercel bot temporarily deployed to Preview – insights March 9, 2026 21:05 Inactive
@vercel vercel bot temporarily deployed to Preview – entropy-explorer March 9, 2026 21:05 Inactive
@vercel vercel bot temporarily deployed to Preview – api-reference March 9, 2026 21:05 Inactive
@vercel vercel bot temporarily deployed to Preview – staking March 9, 2026 21:05 Inactive
@github-actions
Copy link
Contributor

github-actions bot commented Mar 9, 2026

🤖 llms.txt Content Review

Analyzed documentation changes — no updates to curated content required.

Products reviewed: llms-price-feeds-pro.txt, llms-price-feeds.txt

Note: Product files contain curated content. Deep dive page URLs in each file link to individual .mdx pages for full detail.

Files analyzed
apps/developer-hub/content/docs/price-feeds/pro/price-feed-id-changelog.mdx

Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

View 5 additional findings in Devin Review.

Open in Devin Review

Comment on lines +91 to +97
if (
!includeAllFieldDiffs &&
change.changeType !== "went_live" &&
change.statusBefore === change.statusAfter
) {
return false
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🔴 Default filter hides added and removed entries when state is null

The visibility filter at line 91-97 only exempts went_live entries from being hidden when statusBefore === statusAfter. But added entries have statusBefore: null and if the record has no state field (or state: null), statusAfter is also null, so null === null → the entry is hidden in default view. The same issue applies to removed entries where the record's state was null. This means newly added or removed price feeds with no explicit state are invisible in the default view, contradicting the intent of the changelog page which should always surface structural additions/removals.

Example scenario

A new record is added to the API with state: null. The generate script produces:

{ "changeType": "added", "statusBefore": null, "statusAfter": null, ... }

In the UI filter:

  • !includeAllFieldDiffs → true (default)
  • change.changeType !== "went_live" → true (it's "added")
  • change.statusBefore === change.statusAfternull === null → true

Result: entry is filtered out and invisible to users unless they toggle "Include all property changes".

Suggested change
if (
!includeAllFieldDiffs &&
change.changeType !== "went_live" &&
change.statusBefore === change.statusAfter
) {
return false
}
if (
!includeAllFieldDiffs &&
change.changeType !== "went_live" &&
change.changeType !== "added" &&
change.changeType !== "removed" &&
change.statusBefore === change.statusAfter
) {
return false
}
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link

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

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: f5e1e81e12

ℹ️ 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".

Comment on lines +241 to +242
const beforeValue = beforeObject[key] ?? null
const afterValue = afterObject[key] ?? null

Choose a reason for hiding this comment

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

P2 Badge Distinguish missing keys from explicit nulls in field diff

When an API field flips between omitted and explicitly null, the record is marked as changed (deepEqual sees different objects) but diffValues drops the actual field change because both sides are coerced with ?? null. This produces change entries with no meaningful changedFields (shown as -), so the "Include all property changes" view becomes inaccurate for optional fields that are intermittently present.

Useful? React with 👍 / 👎.

@aditya520 aditya520 marked this pull request as draft March 9, 2026 21:19
@vercel vercel bot temporarily deployed to Preview – proposals March 10, 2026 13:24 Inactive
@vercel vercel bot temporarily deployed to Preview – staking March 10, 2026 13:24 Inactive
@vercel vercel bot temporarily deployed to Preview – api-reference March 10, 2026 13:24 Inactive
@vercel vercel bot temporarily deployed to Preview – insights March 10, 2026 13:24 Inactive
@vercel vercel bot temporarily deployed to Preview – entropy-explorer March 10, 2026 13:24 Inactive
@aditya520
Copy link
Member Author

@codex and @devin can you review this PR please?

Copy link

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

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: 1b70103432

ℹ️ 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".

Comment on lines +139 to +143
const result = symbolRecordSchema.safeParse(item);
if (result.success) {
records.push(sortKeys(result.data) as SymbolRecord);
}
}

Choose a reason for hiding this comment

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

P1 Badge Fail changelog generation when symbol records are invalid

fetchCurrentSymbols silently skips any API item that fails schema validation, which means a transient payload issue (for example one record with an unexpected pyth_lazer_id type) is treated as that feed disappearing from the snapshot; buildDailyRollup will then emit false removed/changed entries and publish incorrect changelog data instead of failing fast.

Useful? React with 👍 / 👎.

Comment on lines +171 to +173
} catch {
return {
generatedAt: new Date().toISOString(),

Choose a reason for hiding this comment

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

P2 Badge Do not swallow rollup parse errors

The broad catch in loadExistingRollup converts any read/parse failure into an empty rollup, so if daily-rollups.json is malformed the next successful write path will overwrite history with a fresh object and lose prior changelog days; this should only fall back on missing-file errors and otherwise surface invalid JSON.

Useful? React with 👍 / 👎.

aditya520 and others added 5 commits March 12, 2026 12:10
Add a new Pyth Pro changelog docs page that summarizes daily UTC feed-id changes and supports status-focused vs all-field views. Include a snapshot/diff generator pipeline and initial data artifacts so docs can render deterministic daily rollups.

Made-with: Cursor
…elog

- Extract shared types to src/data/pro-price-feed-changelog/types.ts with
  Zod schemas for runtime validation (fixes type duplication between
  generator and component)
- Move daily-rollups.json to public/ and fetch at runtime instead of
  static import (prevents unbounded client bundle growth)
- Make generator incremental: only loads previous + current snapshot,
  prepends new day to existing rollup (O(1) memory vs O(n))
- Add 10-day snapshot retention with automatic pruning
- Add Zod validation for API responses with AbortSignal.timeout
- Add search debounce (300ms) and URL-synced search query param
- Use matchSorter for search filtering (consistent with sibling components)
- Switch to State machine pattern matching PriceFeedIdsProTable
- Use compact JSON for snapshots, single shared pageSize state
- Filter prototype pollution keys in sortKeys, add JSDoc headers
- Add record count sanity check (>50k) as safety measure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fail fast when symbol records fail schema validation instead of
  silently skipping them, preventing false removed/changed entries
- Only catch ENOENT in loadExistingRollup so JSON parse errors and
  permission issues propagate instead of silently losing history
- Exempt added/removed change types from the status-unchanged filter
  so they always appear in the default view
- Distinguish missing keys from explicit nulls in field diffs using
  a MISSING sentinel symbol

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the public Symbols API data source with the private
pyth-lazer-governance repo. The generator now reads proposal directories
from a local clone (GOVERNANCE_REPO_PATH), applies a strict field
whitelist to ensure no sensitive data reaches the public output, and
diffs consecutive dates to produce daily changelog entries.

- Add shared lib with pure helpers and strict Zod schemas
- Add CI workflow with sparse checkout + validation step
- Add 25 fixture-based unit tests for all helper functions
- Remove 83K-line snapshot file from git
- Fix component: State.Failed→Error, use Next.js router for URL updates
- Constrain FieldDiff.before/after to scalar types only

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
P1: Validate existing rollup with Zod instead of unsafe `as` cast.
P1: Cache previous date's feeds across loop iterations to halve I/O.
P2: Remove unsafe `as ScalarValue` casts via typed DIFFABLE_KEYS array.
P2: Use strict equality in diffs — no more String() coercion.
P2: Remove dead SAFE_METADATA_KEYS export.
P2: Use Set for datesToProcess lookup (O(1) vs O(n)).
P2: Expand sensitive patterns + add structural key-walking validation.
P2: Tighten DIR_NAME_REGEX to prevent path traversal in suffixes.
P2: Remove YAGNI endpoint-to-source migration code.
P2: Fix useEffect re-render loop by removing searchParams from deps.
P2: Extract errorToString to shared src/lib/error-to-string.ts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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