Skip to content

feat(indexer/distributions): define distributions GraphQL schema (#37)#50

Open
modrispath wants to merge 2 commits into
Fundable-Protocol:devfrom
modrispath:feat/define-distributions-schema-37
Open

feat(indexer/distributions): define distributions GraphQL schema (#37)#50
modrispath wants to merge 2 commits into
Fundable-Protocol:devfrom
modrispath:feat/define-distributions-schema-37

Conversation

@modrispath

@modrispath modrispath commented Jun 27, 2026

Copy link
Copy Markdown

Overview
Defines the distributions domain GraphQL schema for the Soroban indexer (\indexer/distributions/schema.graphql), describing the public API shape before Apollo resolvers are implemented. This schema aligns with the database model defined in #36 and follows the conventions established in the streams domain (#33).

Closes #37

## Changes
- **Expanded \indexer/distributions/schema.graphql**:
- Added \DistributionStatus\ enum (\ACTIVE, \PAUSED, \COMPLETED, \CANCELLED).
- Defined \DistributionBatch\ type with integer-safe numeric string amounts (\ otalAmount, \claimedAmount), recipient counts, lifecycle status fields (\pausedAt, \

esumedAt), metadata (\uniqueRef, \ledgerNumber, \ xHash), and linked \claims.
- Defined \ClaimAction\ type linking claims to batches (\�atchId), storing \claimant, integer-safe \�mount, \ xHash, \ledgerNumber, and \eventTimestamp.
- Added query filter input shapes (\DistributionFilterInput, \ClaimFilterInput) and \PaginationInput.
- Added Relay-style pagination connection types (\DistributionConnection, \ClaimConnection, \PageInfo).
- Defined root \Query\ resolvers for single lookups (\distributionBatch, \claimAction) and paginated list queries (\distributionBatches, \distributionBatchesByDistributor, \claims, \claimsByClaimant, \claimsByBatch).
- Unit Tests:
- Added \indexer/distributions/src/schema.test.ts\ to assert that the GraphQL schema defines all required types, queries, inputs, connections, and status enums aligned with the database model.

## Verification
Run across workspace:
- \�un run type-check\ passed
- \�un run test\ passed
- \�un run lint\ passed
- \�un run indexer:type-check\ passed
- \�un run indexer:test\ passed
- \�un run indexer:lint\ passed

Summary by CodeRabbit

  • New Features
    • Expanded the distribution API to expose detailed batch and claim fields, including status, totals/claimed amounts, recipient counts, timestamps, and ledger/transaction references.
    • Added filtering and pagination inputs for distribution batches and claims.
    • Introduced connection-style responses with page info and total counts.
    • Added new query endpoints for single-record lookups and paginated listings (including lookups by distributor, claimant, or batch).
  • Tests
    • Added automated schema contract validation to ensure expected GraphQL types, fields, and query shapes remain consistent.

@drips-wave

drips-wave Bot commented Jun 27, 2026

Copy link
Copy Markdown

@modrispath Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The distributions GraphQL schema now defines full batch and claim types, adds filter and pagination inputs plus connection wrappers, extends root queries for lookups and lists, and includes Vitest coverage for the new schema surface.

Changes

Distributions GraphQL Schema

Layer / File(s) Summary
DistributionBatch and ClaimAction types
indexer/distributions/schema.graphql
DistributionBatch gains distributor, token, amount, status, timestamp, ledger, transaction, and claims fields. ClaimAction gains batch linkage, claimant, amount, timestamp, ledger, and transaction fields.
Filter inputs, connection types, and Query fields
indexer/distributions/schema.graphql
DistributionFilterInput, ClaimFilterInput, and PaginationInput are added, along with DistributionConnection, ClaimConnection, and PageInfo. The root Query adds single-item lookups and paginated list fields for batches and claims.
Schema test coverage
indexer/distributions/src/schema.test.ts
A Vitest suite loads the schema text and asserts the enum, object, input, connection, and query definitions match the expanded contract.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

Poem

🐇 Hop-hop, the schema grew,
Batches, claims, and pages too.
Filters, queries, tests align,
GraphQL carrots taste just fine!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: defining the distributions GraphQL schema.
Description check ✅ Passed The description explains the change, impact, and verification, though it omits some template sections like Area, Scope, and Indexer Safety.
Linked Issues check ✅ Passed The PR satisfies #37 by expanding the distributions schema, adding batch/claim types, filters, pagination, and tests aligned with the database model.
Out of Scope Changes check ✅ Passed The changes stay within the distributions indexer schema and test files, with no evident unrelated or out-of-scope additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
indexer/distributions/src/schema.test.ts (1)

20-47: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Scope type-field assertions and cover the timestamp fields.

These checks currently search the whole schema, so shared fields like id, txHash, or createdAt can pass even if they move to the wrong type. Also add assertions for DistributionBatch.createdAt, DistributionBatch.updatedAt, and ClaimAction.createdAt.

Example test helper
+const definitionBody = (kind: "type" | "input" | "enum", name: string) => {
+  const match = schemaContent.match(
+    new RegExp(`${kind}\\s+${name}\\s*\\{([\\s\\S]*?)\\n\\}`),
+  );
+  expect(match).not.toBeNull();
+  return match?.[1] ?? "";
+};
+
 test("defines DistributionBatch type aligned with database schema", () => {
-  expect(schemaContent).toContain("type DistributionBatch {");
-  expect(schemaContent).toContain("id: ID!");
+  const distributionBatch = definitionBody("type", "DistributionBatch");
+  expect(distributionBatch).toContain("id: ID!");
   expect(schemaContent).toContain("contractId: String!");
+  expect(distributionBatch).toContain("createdAt: String!");
+  expect(distributionBatch).toContain("updatedAt: String!");
 });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@indexer/distributions/src/schema.test.ts` around lines 20 - 47, Tighten the
schema tests in schema.test.ts so each field assertion is scoped to the correct
type block instead of searching the full schema content. Update the
DistributionBatch and ClaimAction tests to extract or match the specific type
definitions using their unique type names, then assert fields like id, txHash,
and createdAt within that block only. Also add coverage for
DistributionBatch.createdAt, DistributionBatch.updatedAt, and
ClaimAction.createdAt to keep the schema alignment checks complete.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@indexer/distributions/schema.graphql`:
- Line 22: The Distribution schema currently exposes claims as an unbounded
list, which can let distributionBatch load every claim for a batch and skip
pagination. Update the claims field on the Distribution type in schema.graphql
to use a paginated connection shape, or remove the nested list and rely on
claimsByBatch for batch-scoped access; make sure any related resolver or type
references for claims and distributionBatch are updated to match the new
paginated API.

---

Nitpick comments:
In `@indexer/distributions/src/schema.test.ts`:
- Around line 20-47: Tighten the schema tests in schema.test.ts so each field
assertion is scoped to the correct type block instead of searching the full
schema content. Update the DistributionBatch and ClaimAction tests to extract or
match the specific type definitions using their unique type names, then assert
fields like id, txHash, and createdAt within that block only. Also add coverage
for DistributionBatch.createdAt, DistributionBatch.updatedAt, and
ClaimAction.createdAt to keep the schema alignment checks complete.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e9504122-d739-4e78-8ebf-285e25d5f48b

📥 Commits

Reviewing files that changed from the base of the PR and between bcfa08d and 6e18b49.

📒 Files selected for processing (2)
  • indexer/distributions/schema.graphql
  • indexer/distributions/src/schema.test.ts

Comment thread indexer/distributions/schema.graphql Outdated
@pragmaticAweds

Copy link
Copy Markdown
Contributor

Hi @modrispath

Thank you for your awesome contribution, however after analyzing your implementation, there is a minor fix to be done. Kindly fix it to merge your PR asap.

Also do not forget to use fundable.finance to offramp.

modrispath

This comment was marked as duplicate.

modrispath

This comment was marked as duplicate.

modrispath

This comment was marked as duplicate.

@modrispath

Copy link
Copy Markdown
Author

Hi @pragmaticAweds, I've applied the requested fixes! Specifically:

  • Updated the claims field on DistributionBatch to use Relay-style pagination (claims(pagination: PaginationInput): ClaimConnection!) instead of an unbounded list.
  • Scoped all test assertions in schema.test.ts to their specific type blocks and added assertions for timestamp fields.

All checks (�un run type-check, �un run test, �un run lint, and indexer workspace checks) pass cleanly.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@indexer/distributions/src/schema.test.ts`:
- Around line 20-24: The helper in schema.test.ts is relying on regex over raw
SDL, which can miss malformed or invalid schema content; replace this in
definitionBody with parsing/building the schema once and asserting against the
resulting AST or type map. Use the existing schemaContent-driven test setup to
locate the relevant type/input/enum definitions by name from the parsed
structure instead of matching text blocks, so syntax errors, duplicates, and
invalid fields are actually detected.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e11cb7f5-f272-4ad5-862d-2116c86c7b65

📥 Commits

Reviewing files that changed from the base of the PR and between 6e18b49 and a4af272.

📒 Files selected for processing (2)
  • indexer/distributions/schema.graphql
  • indexer/distributions/src/schema.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • indexer/distributions/schema.graphql

Comment on lines +20 to +24
const definitionBody = (kind: "type" | "input" | "enum", name: string) => {
const match = schemaContent.match(new RegExp(`${kind}\\s+${name}\\s*\\{([\\s\\S]*?)\\n\\}`));
expect(match).not.toBeNull();
return match?.[1] ?? "";
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Parse the SDL instead of regex-matching raw text.

This helper lets the suite pass on malformed schema text as long as the expected substrings still exist somewhere in the file. That means syntax errors, duplicate definitions, or invalid field declarations can slip through here. Please build/parse the schema once and assert on the resulting type map/AST instead of extracting blocks with regex.

Suggested direction
+import { buildSchema, isEnumType, isInputObjectType, isObjectType } from "graphql";
+
 describe("distributions GraphQL schema", () => {
   const schemaContent = readFileSync(schemaPath, "utf-8");
+  const schema = buildSchema(schemaContent);
-
-  const definitionBody = (kind: "type" | "input" | "enum", name: string) => {
-    const match = schemaContent.match(new RegExp(`${kind}\\s+${name}\\s*\\{([\\s\\S]*?)\\n\\}`));
-    expect(match).not.toBeNull();
-    return match?.[1] ?? "";
-  };
 
   test("defines DistributionBatch type aligned with database schema", () => {
-    const body = definitionBody("type", "DistributionBatch");
-    expect(body).toContain("id: ID!");
+    const type = schema.getType("DistributionBatch");
+    expect(isObjectType(type)).toBe(true);
+    expect(type?.getFields().id.type.toString()).toBe("ID!");
   });
🧰 Tools
🪛 ast-grep (0.44.0)

[warning] 20-20: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(${kind}\\s+${name}\\s*\\{([\\s\\S]*?)\\n\\})
Note: [CWE-1333] Inefficient Regular Expression Complexity

(regexp-from-variable)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@indexer/distributions/src/schema.test.ts` around lines 20 - 24, The helper in
schema.test.ts is relying on regex over raw SDL, which can miss malformed or
invalid schema content; replace this in definitionBody with parsing/building the
schema once and asserting against the resulting AST or type map. Use the
existing schemaContent-driven test setup to locate the relevant type/input/enum
definitions by name from the parsed structure instead of matching text blocks,
so syntax errors, duplicates, and invalid fields are actually detected.

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.

Define Distributions GraphQL schema

3 participants