Skip to content

[#374] E2E Indexer Verification Script#375

Merged
realproject7 merged 4 commits intomainfrom
task/374-e2e-indexer-verify
Mar 20, 2026
Merged

[#374] E2E Indexer Verification Script#375
realproject7 merged 4 commits intomainfrom
task/374-e2e-indexer-verify

Conversation

@realproject7
Copy link
Copy Markdown
Owner

Summary

  • Adds scripts/e2e-verify.ts — validates the web app correctly indexes every mainnet transaction from the contract E2E test suite (plotlink-contracts#27)
  • Reads tx hashes from Forge broadcast artifacts via e2e-results.json
  • Implements all 8 verification groups (V1–V8): storyline, plot, trade, donation indexing; price/TVL reads; content hash verification; idempotency; error handling
  • Outputs clear PASS/FAIL for each individual check with exit code 1 on any failure

Depends On

  • plotlink-contracts#28 (merged) — contract E2E test that produces e2e-results.json

Test plan

  • Run contract E2E first: cd plotlink-contracts && forge script script/E2ETest.s.sol --broadcast
  • Run verification: npx tsx scripts/e2e-verify.ts --from-file ../plotlink-contracts/e2e-results.json
  • Verify all V1–V8 groups pass
  • Verify idempotency (V7) — re-run produces no duplicates
  • Verify error handling (V8) — invalid/empty inputs return proper HTTP status codes

Fixes #374

🤖 Generated with Claude Code

Implements scripts/e2e-verify.ts — validates that the web app correctly
indexes every mainnet transaction from the contract E2E test suite.

Covers all 8 verification groups:
- V1: Storyline indexing (10 field checks)
- V2: Plot indexing (sequential indices, reconciliation)
- V3: Trade indexing (mint/burn events, price, supply)
- V4: Donation indexing (donor/amount/storyline)
- V5: Price & TVL on-chain reads
- V6: Content hash verification (incl. Unicode)
- V7: Idempotency (no duplicate records on re-index)
- V8: Error handling (invalid/unrelated tx, empty body)

Reads tx hashes from Forge broadcast artifacts referenced in
e2e-results.json. Queries Supabase directly for record verification.

Fixes #374

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

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

Verdict: REQUEST CHANGES

Summary

The verification script is close, but two implementation choices will cause it to fail against the merged contract E2E output. It currently targets the wrong chain by default for mainnet results, and it calls the storyline / plot indexers without the fallback content those routes require for the synthetic E2E content.

Findings

  • [high] The script ignores the chainId from e2e-results.json and defaults to Base Sepolia unless NEXT_PUBLIC_CHAIN_ID is set manually.

    • File: scripts/e2e-verify.ts:55
    • Suggestion: derive the viem client chain from results.chainId (or at least default to it after loading the results file). As written, the documented --from-file ../plotlink-contracts/e2e-results.json flow will query the wrong chain for mainnet outputs.
  • [high] Storyline and plot indexing are invoked without fallback content, but the current indexer routes require fallback content when IPFS fetch fails and then hash-check that content before inserting rows.

    • File: scripts/e2e-verify.ts:236
    • Suggestion: pass the exact genesis / plot content strings in the POST bodies (or extend the contract output so this script can reconstruct them). Right now the script only sends { txHash }, while /api/index/storyline and /api/index/plot return errors if IPFS content is unavailable or does not hash-match the onchain values.

Decision

Requesting changes because the script will not reliably pass against the actual contract E2E artifacts in its current form.

Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

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

T2b Review — APPROVED

The script is well-structured and comprehensive. All 8 verification groups (V1–V8) correctly align with the actual API endpoint contracts and Supabase schema. The pass/fail runner pattern with exit code 1 on failure is clean.

Non-blocking suggestions

1. Missing coverage for storylineA3 / edgeCasesF / royaltiesClaimed
The E2EResults interface (lines 130–137) declares these fields and main() logs them, but no verification group covers them. These represent the edge cases the contract E2E specifically tests (empty storyline, duplicate create, royalty claims). Consider adding a V9 group or expanding V1/V2.

2. V7.1 idempotency false-fail risk (line 756)
count === 1 assumes a single createStoryline tx emits exactly one log event. If the tx emits multiple events with different log_index values, this check false-fails. Safer pattern: capture count before re-indexing, then assert unchanged.

3. V4.4 BigInt(don.amount) crash on null (line 591)
If a donation record has null/undefined amount, BigInt(don.amount) throws an unhandled TypeError, crashing the entire script mid-run. Add a null guard:

if (!don.amount) { fail("V4.4", "amount present", "null/undefined"); continue; }

Minor

  • V1.2 test ID reused for A2 check (line 329) — consider V1.11 for output clarity
  • V2.5 (line 396–403) can never fail — both branches pass. Consider making the null-content path a skip/warn
  • V8.2 (line 855) counts skip as pass when no transfer txs exist — inflates pass count

…ases

- Use chainId from e2e-results.json instead of env default (T2a #1)
- Add postIndexWithFallback() that retries with known E2E content
  strings when IPFS fetch fails for test CIDs (T2a #2)
- Fix V7.1 idempotency: compare record count before/after re-index
  instead of assuming count === 1 (T2b #2)
- Add null guard for V4.4 BigInt conversion on donation amount (T2b #3)
- Add verification coverage for storylineA3 and edgeCasesF (T2b #1)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

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

Verdict: REQUEST CHANGES

Summary

The previous blockers are fixed, but the current revision introduces a runtime reference error in main(). The script now initializes resolvedChain, but still logs chain.name, which is no longer defined.

Findings

  • [high] main() references chain.name, but chain is undefined in this revision, so the script will throw before any verification runs.
    • File: scripts/e2e-verify.ts:979
    • Suggestion: log resolvedChain.name (or store the selected chain object in a variable that remains in scope for main()).

Decision

Requesting changes because this is a hard runtime failure in the top-level execution path.

Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

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

T2b re-review: all 3 items addressed cleanly. V7.1 before/after count pattern is correct, V4.4 null guard added, edge case coverage (A3, F1-F3) present. LGTM.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

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

Verdict: APPROVE

Summary

The follow-up fixes addressed the review blockers. The script now uses the chain from e2e-results.json, retries storyline and plot indexing with fallback content for the synthetic E2E CIDs, and the top-level runtime error from the chain.name refactor is fixed.

Findings

  • None.

Decision

Approving because the code review issues are resolved. Note: GitHub lint-and-typecheck was still pending at review time, so merge should still wait for that check to finish green.

- Restructure chainId/publicClient as const (prefer-const)
- Remove unused Hex import and hashChecked variable

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@realproject7 realproject7 merged commit 4af1c46 into main Mar 20, 2026
1 check passed
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.

[Test] E2E Indexer Verification Script — Validate Web App Indexes Mainnet Transactions

2 participants