feat: idiomatic graphql api - #769

Merged
coodos merged 4 commits into
mainfrom
feat/idiomatic-graphql-api
Feb 4, 2026
Merged

feat: idiomatic graphql api#769
coodos merged 4 commits into
mainfrom
feat/idiomatic-graphql-api

Conversation

@sosweetham

@sosweethamsosweetham commented Feb 4, 2026

Copy link
Copy Markdown
Member

Description of change

adds idiomatic graphql methods

Issue Number

Closes#724

Type of change

  • New (a change which implements a new feature)

How the change has been tested

n/a

Change checklist

  • I have ensured that the CI Checks pass locally
  • I have removed any unnecessary logic
  • My code is well documented
  • I have signed my commits
  • My code follows the pattern of the application
  • I have self reviewed my code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added pagination and filtering support to MetaEnvelope queries
    • Introduced Relay-style cursor-based pagination with configurable search modes
    • Enhanced error reporting with structured error payloads in mutations
    • Required X-ENAME header for all GraphQL operations
  • API Changes

    • Renamed GraphQL queries and mutations to follow idiomatic naming conventions
    • Envelope field renamed from ontology to fieldKey
    • Legacy API endpoints preserved for backward compatibility
  • Documentation

    • Updated API documentation with new operation names and usage examples
    • Added Legacy API section with mappings to new equivalents

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@sosweetham has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 13 minutes and 30 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

This pull request refactors the GraphQL API to follow idiomatic conventions: query names shift from REST-style (getMetaEnvelopeById, findMetaEnvelopesByOntology) to noun-based patterns (metaEnvelope, metaEnvelopes); list queries now support Relay-style cursor pagination with filtering and search; mutation payloads are restructured with explicit error blocks; envelope field ontology is renamed to fieldKey; X-ENAME header becomes required; legacy endpoints are preserved for backward compatibility.

Changes

Cohort / File(s)Summary
Documentation & Getting Started
docs/docs/Infrastructure/eVault.md, docs/docs/W3DS Basics/getting-started.md
Updated GraphQL documentation and examples to reflect new idiomatic API names (createMetaEnvelope, metaEnvelope, metaEnvelopes, removeMetaEnvelope); documented fieldKey replacing ontology; added Legacy API section with mappings; included X-ENAME header requirement and updated response payload shapes with error blocks.
Type System
infrastructure/evault-core/src/core/db/types.ts, infrastructure/evault-core/src/core/protocol/typedefs.ts
Added Relay-style pagination types (PageInfo, MetaEnvelopeEdge, MetaEnvelopeConnection), search/filter inputs (SearchMode enum, MetaEnvelopeSearchInput, MetaEnvelopeFilterInput), structured mutation payloads (CreateMetaEnvelopePayload, UpdateMetaEnvelopePayload, DeleteMetaEnvelopePayload), and new FindMetaEnvelopesPaginatedOptions.
Database Layer
infrastructure/evault-core/src/core/db/db.service.ts
Implemented new findMetaEnvelopesPaginated method with support for Relay-style cursor-based pagination, ontology filtering, flexible term-based search with case sensitivity and match modes, cursor computation, and totalCount metrics.
GraphQL API Implementation
infrastructure/evault-core/src/core/protocol/graphql-server.ts
Added idiomatic queries (metaEnvelope, metaEnvelopes with pagination/filtering) and mutations (createMetaEnvelope, updateMetaEnvelope, removeMetaEnvelope) with X-ENAME validation; implemented webhook delivery flow and operation logging; retained legacy endpoints for backward compatibility; introduced fieldKey field resolver and internal helpers.
Examples & Test Coverage
infrastructure/evault-core/src/core/protocol/examples/examples.ts, infrastructure/evault-core/src/core/protocol/idiomatic-graphql-api.spec.ts
Updated protocol examples to demonstrate new API names, pagination patterns, filtering, and error response shapes; added comprehensive E2E test suite covering all CRUD operations, pagination with cursors, filtering/search, error handling, and backward compatibility with legacy endpoints.

Sequence Diagram(s)

sequenceDiagram
participant Client
participant GraphQLServer as GraphQL Server
participant DbService as DB Service
participant Registry as Platform Registry
participant WebhookTarget as Webhook Platform
Client->>GraphQLServer: createMetaEnvelope(input, X-ENAME)
GraphQLServer->>GraphQLServer: Validate X-ENAME header
GraphQLServer->>DbService: Store envelope data
DbService-->>GraphQLServer: Envelope created
GraphQLServer->>GraphQLServer: Compute envelopeHash
GraphQLServer->>GraphQLServer: Construct payload with envelopes + errors
GraphQLServer->>Registry: getActivePlatforms()
Registry-->>GraphQLServer: Platform URLs
GraphQLServer->>WebhookTarget: deliverWebhooks(POST)
WebhookTarget-->>GraphQLServer: Success/Error (async)
GraphQLServer-->>Client: CreateMetaEnvelopePayload {metaEnvelope, errors}
Loading
sequenceDiagram
participant Client
participant GraphQLServer as GraphQL Server
participant DbService as DB Service
Client->>GraphQLServer: metaEnvelopes(filter, first, after, X-ENAME)
GraphQLServer->>GraphQLServer: Validate X-ENAME header
GraphQLServer->>DbService: findMetaEnvelopesPaginated(eName, options)
DbService->>DbService: Execute count query
DbService->>DbService: Apply filter (ontologyId)
DbService->>DbService: Apply search (term, caseSensitive, fields, mode)
DbService->>DbService: Decode cursor (after/before)
DbService->>DbService: Fetch edges + compute cursors
DbService->>DbService: Build PageInfo (hasNextPage, hasPreviousPage)
DbService-->>GraphQLServer: MetaEnvelopeConnection {edges, pageInfo, totalCount}
GraphQLServer-->>Client: Connection with paginated results
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

evault-refactor

Suggested reviewers

  • coodos
  • xPathin
  • JulienAuvo

Poem

🐰 Hops with glee at GraphQL's new shape,
No more REST-like queries to escape!
Cursors glide through pages neat,
Fieldkeys shine, errors complete,
Idiomatic wisdom—oh, what a feat!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Title check✅ PassedThe title 'feat: idiomatic graphql api' directly reflects the PR's main change of implementing an idiomatic GraphQL API as described in the objectives.
Description check✅ PassedThe PR description includes all required template sections: issue number (#724), type of change (New), testing status, and completed checklist items.
Linked Issues check✅ PassedThe PR comprehensively implements all coding requirements from issue #724: noun-based queries (metaEnvelope, metaEnvelopes), cursor-based pagination with MetaEnvelopeConnection, typed search input (MetaEnvelopeSearchInput), separated ontologyId/fieldKey, structured mutation payloads with errors, and delete mutation with deletedId/success.
Out of Scope Changes check✅ PassedAll changes align with issue #724 objectives: GraphQL API refactoring, pagination implementation, type safety, and mutation payload structuring. Documentation updates and test additions are scope-appropriate for the feature.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/idiomatic-graphql-api

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 and usage tips.

@coderabbitaicoderabbitaiBot 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

🤖 Fix all issues with AI agents
In `@infrastructure/evault-core/src/core/db/db.service.ts`:
- Around line 1068-1255: Add validation to reject mixed-direction cursors and
fix pageInfo backward-flag checks: extend the existing pagination validation
that currently checks "first & last" and "after & before" to also throw when
first is provided with before and when last is provided with after (refer to the
variables first, last, before, after and the validation block at the top of the
function). Then update the pageInfo construction so backward pagination
(isBackward) uses before for hasNextPage and hasExtraRecord for hasPreviousPage,
i.e. set hasNextPage = isBackward ? (before !== undefined) : hasExtraRecord and
hasPreviousPage = isBackward ? hasExtraRecord : (after !== undefined) (refer to
isBackward and pageInfo).
🧹 Nitpick comments (2)
infrastructure/evault-core/src/core/protocol/typedefs.ts (2)

15-21: Minor: Consider using ID! for MetaEnvelope.id for consistency.

The new idiomatic queries/mutations use ID! for identifier parameters (e.g., metaEnvelope(id: ID!), DeleteMetaEnvelopePayload.deletedId: ID!), but the type definition uses String!. While they serialize identically, using ID! throughout communicates identifier semantics more clearly and improves schema consistency.

♻️ Suggested change
 type MetaEnvelope {
- id: String!+ id: ID!
"The ontology schema ID (W3ID)"
ontology: String!
envelopes: [Envelope!]!
parsed: JSON
}

Same applies to Envelope.id on line 6.


96-108: Consider using non-nullable empty array for errors field.

Currently errors: [UserError!] is nullable, meaning clients must distinguish between null (no errors) and [] (empty array). Using [UserError!]! (non-nullable, possibly empty) simplifies client handling—an empty array always means success.

This is a stylistic choice; the current pattern (null = no errors) is also valid and commonly used.

Comment threadinfrastructure/evault-core/src/core/db/db.service.ts
@coodos
coodos merged commit 14450ca into mainFeb 4, 2026
6 checks passed
@coodos
coodos deleted the feat/idiomatic-graphql-api branch February 4, 2026 15:48
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 4, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 23, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 12, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 24, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request May 2, 2026
6 tasks
Sign up for freeto 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.

feat: Make GraphQL protocol more idiomatic

2 participants

@sosweetham@coodos
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat: idiomatic graphql api - #769

Merged
coodos merged 4 commits into
mainfrom
feat/idiomatic-graphql-api
Feb 4, 2026
Merged

feat: idiomatic graphql api#769
coodos merged 4 commits into
mainfrom
feat/idiomatic-graphql-api

Conversation

@sosweetham

@sosweethamsosweetham commented Feb 4, 2026

Copy link
Copy Markdown
Member

Description of change

adds idiomatic graphql methods

Issue Number

Closes#724

Type of change

  • New (a change which implements a new feature)

How the change has been tested

n/a

Change checklist

  • I have ensured that the CI Checks pass locally
  • I have removed any unnecessary logic
  • My code is well documented
  • I have signed my commits
  • My code follows the pattern of the application
  • I have self reviewed my code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added pagination and filtering support to MetaEnvelope queries
    • Introduced Relay-style cursor-based pagination with configurable search modes
    • Enhanced error reporting with structured error payloads in mutations
    • Required X-ENAME header for all GraphQL operations
  • API Changes

    • Renamed GraphQL queries and mutations to follow idiomatic naming conventions
    • Envelope field renamed from ontology to fieldKey
    • Legacy API endpoints preserved for backward compatibility
  • Documentation

    • Updated API documentation with new operation names and usage examples
    • Added Legacy API section with mappings to new equivalents

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@sosweetham has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 13 minutes and 30 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

This pull request refactors the GraphQL API to follow idiomatic conventions: query names shift from REST-style (getMetaEnvelopeById, findMetaEnvelopesByOntology) to noun-based patterns (metaEnvelope, metaEnvelopes); list queries now support Relay-style cursor pagination with filtering and search; mutation payloads are restructured with explicit error blocks; envelope field ontology is renamed to fieldKey; X-ENAME header becomes required; legacy endpoints are preserved for backward compatibility.

Changes

Cohort / File(s)Summary
Documentation & Getting Started
docs/docs/Infrastructure/eVault.md, docs/docs/W3DS Basics/getting-started.md
Updated GraphQL documentation and examples to reflect new idiomatic API names (createMetaEnvelope, metaEnvelope, metaEnvelopes, removeMetaEnvelope); documented fieldKey replacing ontology; added Legacy API section with mappings; included X-ENAME header requirement and updated response payload shapes with error blocks.
Type System
infrastructure/evault-core/src/core/db/types.ts, infrastructure/evault-core/src/core/protocol/typedefs.ts
Added Relay-style pagination types (PageInfo, MetaEnvelopeEdge, MetaEnvelopeConnection), search/filter inputs (SearchMode enum, MetaEnvelopeSearchInput, MetaEnvelopeFilterInput), structured mutation payloads (CreateMetaEnvelopePayload, UpdateMetaEnvelopePayload, DeleteMetaEnvelopePayload), and new FindMetaEnvelopesPaginatedOptions.
Database Layer
infrastructure/evault-core/src/core/db/db.service.ts
Implemented new findMetaEnvelopesPaginated method with support for Relay-style cursor-based pagination, ontology filtering, flexible term-based search with case sensitivity and match modes, cursor computation, and totalCount metrics.
GraphQL API Implementation
infrastructure/evault-core/src/core/protocol/graphql-server.ts
Added idiomatic queries (metaEnvelope, metaEnvelopes with pagination/filtering) and mutations (createMetaEnvelope, updateMetaEnvelope, removeMetaEnvelope) with X-ENAME validation; implemented webhook delivery flow and operation logging; retained legacy endpoints for backward compatibility; introduced fieldKey field resolver and internal helpers.
Examples & Test Coverage
infrastructure/evault-core/src/core/protocol/examples/examples.ts, infrastructure/evault-core/src/core/protocol/idiomatic-graphql-api.spec.ts
Updated protocol examples to demonstrate new API names, pagination patterns, filtering, and error response shapes; added comprehensive E2E test suite covering all CRUD operations, pagination with cursors, filtering/search, error handling, and backward compatibility with legacy endpoints.

Sequence Diagram(s)

sequenceDiagram
participant Client
participant GraphQLServer as GraphQL Server
participant DbService as DB Service
participant Registry as Platform Registry
participant WebhookTarget as Webhook Platform
Client->>GraphQLServer: createMetaEnvelope(input, X-ENAME)
GraphQLServer->>GraphQLServer: Validate X-ENAME header
GraphQLServer->>DbService: Store envelope data
DbService-->>GraphQLServer: Envelope created
GraphQLServer->>GraphQLServer: Compute envelopeHash
GraphQLServer->>GraphQLServer: Construct payload with envelopes + errors
GraphQLServer->>Registry: getActivePlatforms()
Registry-->>GraphQLServer: Platform URLs
GraphQLServer->>WebhookTarget: deliverWebhooks(POST)
WebhookTarget-->>GraphQLServer: Success/Error (async)
GraphQLServer-->>Client: CreateMetaEnvelopePayload {metaEnvelope, errors}
Loading
sequenceDiagram
participant Client
participant GraphQLServer as GraphQL Server
participant DbService as DB Service
Client->>GraphQLServer: metaEnvelopes(filter, first, after, X-ENAME)
GraphQLServer->>GraphQLServer: Validate X-ENAME header
GraphQLServer->>DbService: findMetaEnvelopesPaginated(eName, options)
DbService->>DbService: Execute count query
DbService->>DbService: Apply filter (ontologyId)
DbService->>DbService: Apply search (term, caseSensitive, fields, mode)
DbService->>DbService: Decode cursor (after/before)
DbService->>DbService: Fetch edges + compute cursors
DbService->>DbService: Build PageInfo (hasNextPage, hasPreviousPage)
DbService-->>GraphQLServer: MetaEnvelopeConnection {edges, pageInfo, totalCount}
GraphQLServer-->>Client: Connection with paginated results
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

evault-refactor

Suggested reviewers

  • coodos
  • xPathin
  • JulienAuvo

Poem

🐰 Hops with glee at GraphQL's new shape,
No more REST-like queries to escape!
Cursors glide through pages neat,
Fieldkeys shine, errors complete,
Idiomatic wisdom—oh, what a feat!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Title check✅ PassedThe title 'feat: idiomatic graphql api' directly reflects the PR's main change of implementing an idiomatic GraphQL API as described in the objectives.
Description check✅ PassedThe PR description includes all required template sections: issue number (#724), type of change (New), testing status, and completed checklist items.
Linked Issues check✅ PassedThe PR comprehensively implements all coding requirements from issue #724: noun-based queries (metaEnvelope, metaEnvelopes), cursor-based pagination with MetaEnvelopeConnection, typed search input (MetaEnvelopeSearchInput), separated ontologyId/fieldKey, structured mutation payloads with errors, and delete mutation with deletedId/success.
Out of Scope Changes check✅ PassedAll changes align with issue #724 objectives: GraphQL API refactoring, pagination implementation, type safety, and mutation payload structuring. Documentation updates and test additions are scope-appropriate for the feature.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/idiomatic-graphql-api

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 and usage tips.

@coderabbitaicoderabbitaiBot 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

🤖 Fix all issues with AI agents
In `@infrastructure/evault-core/src/core/db/db.service.ts`:
- Around line 1068-1255: Add validation to reject mixed-direction cursors and
fix pageInfo backward-flag checks: extend the existing pagination validation
that currently checks "first & last" and "after & before" to also throw when
first is provided with before and when last is provided with after (refer to the
variables first, last, before, after and the validation block at the top of the
function). Then update the pageInfo construction so backward pagination
(isBackward) uses before for hasNextPage and hasExtraRecord for hasPreviousPage,
i.e. set hasNextPage = isBackward ? (before !== undefined) : hasExtraRecord and
hasPreviousPage = isBackward ? hasExtraRecord : (after !== undefined) (refer to
isBackward and pageInfo).
🧹 Nitpick comments (2)
infrastructure/evault-core/src/core/protocol/typedefs.ts (2)

15-21: Minor: Consider using ID! for MetaEnvelope.id for consistency.

The new idiomatic queries/mutations use ID! for identifier parameters (e.g., metaEnvelope(id: ID!), DeleteMetaEnvelopePayload.deletedId: ID!), but the type definition uses String!. While they serialize identically, using ID! throughout communicates identifier semantics more clearly and improves schema consistency.

♻️ Suggested change
 type MetaEnvelope {
- id: String!+ id: ID!
"The ontology schema ID (W3ID)"
ontology: String!
envelopes: [Envelope!]!
parsed: JSON
}

Same applies to Envelope.id on line 6.


96-108: Consider using non-nullable empty array for errors field.

Currently errors: [UserError!] is nullable, meaning clients must distinguish between null (no errors) and [] (empty array). Using [UserError!]! (non-nullable, possibly empty) simplifies client handling—an empty array always means success.

This is a stylistic choice; the current pattern (null = no errors) is also valid and commonly used.

Comment threadinfrastructure/evault-core/src/core/db/db.service.ts
@coodos
coodos merged commit 14450ca into mainFeb 4, 2026
6 checks passed
@coodos
coodos deleted the feat/idiomatic-graphql-api branch February 4, 2026 15:48
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 4, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 23, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 12, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 24, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request May 2, 2026
6 tasks
Sign up for freeto 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.

feat: Make GraphQL protocol more idiomatic

2 participants

@sosweetham@coodos
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: idiomatic graphql api - #769

Merged
coodos merged 4 commits into
mainfrom
feat/idiomatic-graphql-api
Feb 4, 2026
Merged

feat: idiomatic graphql api#769
coodos merged 4 commits into
mainfrom
feat/idiomatic-graphql-api

Conversation

@sosweetham

@sosweethamsosweetham commented Feb 4, 2026

Copy link
Copy Markdown
Member

Description of change

adds idiomatic graphql methods

Issue Number

Closes#724

Type of change

  • New (a change which implements a new feature)

How the change has been tested

n/a

Change checklist

  • I have ensured that the CI Checks pass locally
  • I have removed any unnecessary logic
  • My code is well documented
  • I have signed my commits
  • My code follows the pattern of the application
  • I have self reviewed my code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added pagination and filtering support to MetaEnvelope queries
    • Introduced Relay-style cursor-based pagination with configurable search modes
    • Enhanced error reporting with structured error payloads in mutations
    • Required X-ENAME header for all GraphQL operations
  • API Changes

    • Renamed GraphQL queries and mutations to follow idiomatic naming conventions
    • Envelope field renamed from ontology to fieldKey
    • Legacy API endpoints preserved for backward compatibility
  • Documentation

    • Updated API documentation with new operation names and usage examples
    • Added Legacy API section with mappings to new equivalents

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@sosweetham has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 13 minutes and 30 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

This pull request refactors the GraphQL API to follow idiomatic conventions: query names shift from REST-style (getMetaEnvelopeById, findMetaEnvelopesByOntology) to noun-based patterns (metaEnvelope, metaEnvelopes); list queries now support Relay-style cursor pagination with filtering and search; mutation payloads are restructured with explicit error blocks; envelope field ontology is renamed to fieldKey; X-ENAME header becomes required; legacy endpoints are preserved for backward compatibility.

Changes

Cohort / File(s)Summary
Documentation & Getting Started
docs/docs/Infrastructure/eVault.md, docs/docs/W3DS Basics/getting-started.md
Updated GraphQL documentation and examples to reflect new idiomatic API names (createMetaEnvelope, metaEnvelope, metaEnvelopes, removeMetaEnvelope); documented fieldKey replacing ontology; added Legacy API section with mappings; included X-ENAME header requirement and updated response payload shapes with error blocks.
Type System
infrastructure/evault-core/src/core/db/types.ts, infrastructure/evault-core/src/core/protocol/typedefs.ts
Added Relay-style pagination types (PageInfo, MetaEnvelopeEdge, MetaEnvelopeConnection), search/filter inputs (SearchMode enum, MetaEnvelopeSearchInput, MetaEnvelopeFilterInput), structured mutation payloads (CreateMetaEnvelopePayload, UpdateMetaEnvelopePayload, DeleteMetaEnvelopePayload), and new FindMetaEnvelopesPaginatedOptions.
Database Layer
infrastructure/evault-core/src/core/db/db.service.ts
Implemented new findMetaEnvelopesPaginated method with support for Relay-style cursor-based pagination, ontology filtering, flexible term-based search with case sensitivity and match modes, cursor computation, and totalCount metrics.
GraphQL API Implementation
infrastructure/evault-core/src/core/protocol/graphql-server.ts
Added idiomatic queries (metaEnvelope, metaEnvelopes with pagination/filtering) and mutations (createMetaEnvelope, updateMetaEnvelope, removeMetaEnvelope) with X-ENAME validation; implemented webhook delivery flow and operation logging; retained legacy endpoints for backward compatibility; introduced fieldKey field resolver and internal helpers.
Examples & Test Coverage
infrastructure/evault-core/src/core/protocol/examples/examples.ts, infrastructure/evault-core/src/core/protocol/idiomatic-graphql-api.spec.ts
Updated protocol examples to demonstrate new API names, pagination patterns, filtering, and error response shapes; added comprehensive E2E test suite covering all CRUD operations, pagination with cursors, filtering/search, error handling, and backward compatibility with legacy endpoints.

Sequence Diagram(s)

sequenceDiagram
participant Client
participant GraphQLServer as GraphQL Server
participant DbService as DB Service
participant Registry as Platform Registry
participant WebhookTarget as Webhook Platform
Client->>GraphQLServer: createMetaEnvelope(input, X-ENAME)
GraphQLServer->>GraphQLServer: Validate X-ENAME header
GraphQLServer->>DbService: Store envelope data
DbService-->>GraphQLServer: Envelope created
GraphQLServer->>GraphQLServer: Compute envelopeHash
GraphQLServer->>GraphQLServer: Construct payload with envelopes + errors
GraphQLServer->>Registry: getActivePlatforms()
Registry-->>GraphQLServer: Platform URLs
GraphQLServer->>WebhookTarget: deliverWebhooks(POST)
WebhookTarget-->>GraphQLServer: Success/Error (async)
GraphQLServer-->>Client: CreateMetaEnvelopePayload {metaEnvelope, errors}
Loading
sequenceDiagram
participant Client
participant GraphQLServer as GraphQL Server
participant DbService as DB Service
Client->>GraphQLServer: metaEnvelopes(filter, first, after, X-ENAME)
GraphQLServer->>GraphQLServer: Validate X-ENAME header
GraphQLServer->>DbService: findMetaEnvelopesPaginated(eName, options)
DbService->>DbService: Execute count query
DbService->>DbService: Apply filter (ontologyId)
DbService->>DbService: Apply search (term, caseSensitive, fields, mode)
DbService->>DbService: Decode cursor (after/before)
DbService->>DbService: Fetch edges + compute cursors
DbService->>DbService: Build PageInfo (hasNextPage, hasPreviousPage)
DbService-->>GraphQLServer: MetaEnvelopeConnection {edges, pageInfo, totalCount}
GraphQLServer-->>Client: Connection with paginated results
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

evault-refactor

Suggested reviewers

  • coodos
  • xPathin
  • JulienAuvo

Poem

🐰 Hops with glee at GraphQL's new shape,
No more REST-like queries to escape!
Cursors glide through pages neat,
Fieldkeys shine, errors complete,
Idiomatic wisdom—oh, what a feat!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Title check✅ PassedThe title 'feat: idiomatic graphql api' directly reflects the PR's main change of implementing an idiomatic GraphQL API as described in the objectives.
Description check✅ PassedThe PR description includes all required template sections: issue number (#724), type of change (New), testing status, and completed checklist items.
Linked Issues check✅ PassedThe PR comprehensively implements all coding requirements from issue #724: noun-based queries (metaEnvelope, metaEnvelopes), cursor-based pagination with MetaEnvelopeConnection, typed search input (MetaEnvelopeSearchInput), separated ontologyId/fieldKey, structured mutation payloads with errors, and delete mutation with deletedId/success.
Out of Scope Changes check✅ PassedAll changes align with issue #724 objectives: GraphQL API refactoring, pagination implementation, type safety, and mutation payload structuring. Documentation updates and test additions are scope-appropriate for the feature.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/idiomatic-graphql-api

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 and usage tips.

@coderabbitaicoderabbitaiBot 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

🤖 Fix all issues with AI agents
In `@infrastructure/evault-core/src/core/db/db.service.ts`:
- Around line 1068-1255: Add validation to reject mixed-direction cursors and
fix pageInfo backward-flag checks: extend the existing pagination validation
that currently checks "first & last" and "after & before" to also throw when
first is provided with before and when last is provided with after (refer to the
variables first, last, before, after and the validation block at the top of the
function). Then update the pageInfo construction so backward pagination
(isBackward) uses before for hasNextPage and hasExtraRecord for hasPreviousPage,
i.e. set hasNextPage = isBackward ? (before !== undefined) : hasExtraRecord and
hasPreviousPage = isBackward ? hasExtraRecord : (after !== undefined) (refer to
isBackward and pageInfo).
🧹 Nitpick comments (2)
infrastructure/evault-core/src/core/protocol/typedefs.ts (2)

15-21: Minor: Consider using ID! for MetaEnvelope.id for consistency.

The new idiomatic queries/mutations use ID! for identifier parameters (e.g., metaEnvelope(id: ID!), DeleteMetaEnvelopePayload.deletedId: ID!), but the type definition uses String!. While they serialize identically, using ID! throughout communicates identifier semantics more clearly and improves schema consistency.

♻️ Suggested change
 type MetaEnvelope {
- id: String!+ id: ID!
"The ontology schema ID (W3ID)"
ontology: String!
envelopes: [Envelope!]!
parsed: JSON
}

Same applies to Envelope.id on line 6.


96-108: Consider using non-nullable empty array for errors field.

Currently errors: [UserError!] is nullable, meaning clients must distinguish between null (no errors) and [] (empty array). Using [UserError!]! (non-nullable, possibly empty) simplifies client handling—an empty array always means success.

This is a stylistic choice; the current pattern (null = no errors) is also valid and commonly used.

Comment threadinfrastructure/evault-core/src/core/db/db.service.ts
@coodos
coodos merged commit 14450ca into mainFeb 4, 2026
6 checks passed
@coodos
coodos deleted the feat/idiomatic-graphql-api branch February 4, 2026 15:48
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 4, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 23, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 12, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 24, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request May 2, 2026
6 tasks
Sign up for freeto 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.

feat: Make GraphQL protocol more idiomatic

2 participants

@sosweetham@coodos
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: idiomatic graphql api - #769

Merged
coodos merged 4 commits into
mainfrom
feat/idiomatic-graphql-api
Feb 4, 2026
Merged

feat: idiomatic graphql api#769
coodos merged 4 commits into
mainfrom
feat/idiomatic-graphql-api

Conversation

@sosweetham

@sosweethamsosweetham commented Feb 4, 2026

Copy link
Copy Markdown
Member

Description of change

adds idiomatic graphql methods

Issue Number

Closes#724

Type of change

  • New (a change which implements a new feature)

How the change has been tested

n/a

Change checklist

  • I have ensured that the CI Checks pass locally
  • I have removed any unnecessary logic
  • My code is well documented
  • I have signed my commits
  • My code follows the pattern of the application
  • I have self reviewed my code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added pagination and filtering support to MetaEnvelope queries
    • Introduced Relay-style cursor-based pagination with configurable search modes
    • Enhanced error reporting with structured error payloads in mutations
    • Required X-ENAME header for all GraphQL operations
  • API Changes

    • Renamed GraphQL queries and mutations to follow idiomatic naming conventions
    • Envelope field renamed from ontology to fieldKey
    • Legacy API endpoints preserved for backward compatibility
  • Documentation

    • Updated API documentation with new operation names and usage examples
    • Added Legacy API section with mappings to new equivalents

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@sosweetham has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 13 minutes and 30 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

This pull request refactors the GraphQL API to follow idiomatic conventions: query names shift from REST-style (getMetaEnvelopeById, findMetaEnvelopesByOntology) to noun-based patterns (metaEnvelope, metaEnvelopes); list queries now support Relay-style cursor pagination with filtering and search; mutation payloads are restructured with explicit error blocks; envelope field ontology is renamed to fieldKey; X-ENAME header becomes required; legacy endpoints are preserved for backward compatibility.

Changes

Cohort / File(s)Summary
Documentation & Getting Started
docs/docs/Infrastructure/eVault.md, docs/docs/W3DS Basics/getting-started.md
Updated GraphQL documentation and examples to reflect new idiomatic API names (createMetaEnvelope, metaEnvelope, metaEnvelopes, removeMetaEnvelope); documented fieldKey replacing ontology; added Legacy API section with mappings; included X-ENAME header requirement and updated response payload shapes with error blocks.
Type System
infrastructure/evault-core/src/core/db/types.ts, infrastructure/evault-core/src/core/protocol/typedefs.ts
Added Relay-style pagination types (PageInfo, MetaEnvelopeEdge, MetaEnvelopeConnection), search/filter inputs (SearchMode enum, MetaEnvelopeSearchInput, MetaEnvelopeFilterInput), structured mutation payloads (CreateMetaEnvelopePayload, UpdateMetaEnvelopePayload, DeleteMetaEnvelopePayload), and new FindMetaEnvelopesPaginatedOptions.
Database Layer
infrastructure/evault-core/src/core/db/db.service.ts
Implemented new findMetaEnvelopesPaginated method with support for Relay-style cursor-based pagination, ontology filtering, flexible term-based search with case sensitivity and match modes, cursor computation, and totalCount metrics.
GraphQL API Implementation
infrastructure/evault-core/src/core/protocol/graphql-server.ts
Added idiomatic queries (metaEnvelope, metaEnvelopes with pagination/filtering) and mutations (createMetaEnvelope, updateMetaEnvelope, removeMetaEnvelope) with X-ENAME validation; implemented webhook delivery flow and operation logging; retained legacy endpoints for backward compatibility; introduced fieldKey field resolver and internal helpers.
Examples & Test Coverage
infrastructure/evault-core/src/core/protocol/examples/examples.ts, infrastructure/evault-core/src/core/protocol/idiomatic-graphql-api.spec.ts
Updated protocol examples to demonstrate new API names, pagination patterns, filtering, and error response shapes; added comprehensive E2E test suite covering all CRUD operations, pagination with cursors, filtering/search, error handling, and backward compatibility with legacy endpoints.

Sequence Diagram(s)

sequenceDiagram
participant Client
participant GraphQLServer as GraphQL Server
participant DbService as DB Service
participant Registry as Platform Registry
participant WebhookTarget as Webhook Platform
Client->>GraphQLServer: createMetaEnvelope(input, X-ENAME)
GraphQLServer->>GraphQLServer: Validate X-ENAME header
GraphQLServer->>DbService: Store envelope data
DbService-->>GraphQLServer: Envelope created
GraphQLServer->>GraphQLServer: Compute envelopeHash
GraphQLServer->>GraphQLServer: Construct payload with envelopes + errors
GraphQLServer->>Registry: getActivePlatforms()
Registry-->>GraphQLServer: Platform URLs
GraphQLServer->>WebhookTarget: deliverWebhooks(POST)
WebhookTarget-->>GraphQLServer: Success/Error (async)
GraphQLServer-->>Client: CreateMetaEnvelopePayload {metaEnvelope, errors}
Loading
sequenceDiagram
participant Client
participant GraphQLServer as GraphQL Server
participant DbService as DB Service
Client->>GraphQLServer: metaEnvelopes(filter, first, after, X-ENAME)
GraphQLServer->>GraphQLServer: Validate X-ENAME header
GraphQLServer->>DbService: findMetaEnvelopesPaginated(eName, options)
DbService->>DbService: Execute count query
DbService->>DbService: Apply filter (ontologyId)
DbService->>DbService: Apply search (term, caseSensitive, fields, mode)
DbService->>DbService: Decode cursor (after/before)
DbService->>DbService: Fetch edges + compute cursors
DbService->>DbService: Build PageInfo (hasNextPage, hasPreviousPage)
DbService-->>GraphQLServer: MetaEnvelopeConnection {edges, pageInfo, totalCount}
GraphQLServer-->>Client: Connection with paginated results
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

evault-refactor

Suggested reviewers

  • coodos
  • xPathin
  • JulienAuvo

Poem

🐰 Hops with glee at GraphQL's new shape,
No more REST-like queries to escape!
Cursors glide through pages neat,
Fieldkeys shine, errors complete,
Idiomatic wisdom—oh, what a feat!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Title check✅ PassedThe title 'feat: idiomatic graphql api' directly reflects the PR's main change of implementing an idiomatic GraphQL API as described in the objectives.
Description check✅ PassedThe PR description includes all required template sections: issue number (#724), type of change (New), testing status, and completed checklist items.
Linked Issues check✅ PassedThe PR comprehensively implements all coding requirements from issue #724: noun-based queries (metaEnvelope, metaEnvelopes), cursor-based pagination with MetaEnvelopeConnection, typed search input (MetaEnvelopeSearchInput), separated ontologyId/fieldKey, structured mutation payloads with errors, and delete mutation with deletedId/success.
Out of Scope Changes check✅ PassedAll changes align with issue #724 objectives: GraphQL API refactoring, pagination implementation, type safety, and mutation payload structuring. Documentation updates and test additions are scope-appropriate for the feature.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/idiomatic-graphql-api

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 and usage tips.

@coderabbitaicoderabbitaiBot 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

🤖 Fix all issues with AI agents
In `@infrastructure/evault-core/src/core/db/db.service.ts`:
- Around line 1068-1255: Add validation to reject mixed-direction cursors and
fix pageInfo backward-flag checks: extend the existing pagination validation
that currently checks "first & last" and "after & before" to also throw when
first is provided with before and when last is provided with after (refer to the
variables first, last, before, after and the validation block at the top of the
function). Then update the pageInfo construction so backward pagination
(isBackward) uses before for hasNextPage and hasExtraRecord for hasPreviousPage,
i.e. set hasNextPage = isBackward ? (before !== undefined) : hasExtraRecord and
hasPreviousPage = isBackward ? hasExtraRecord : (after !== undefined) (refer to
isBackward and pageInfo).
🧹 Nitpick comments (2)
infrastructure/evault-core/src/core/protocol/typedefs.ts (2)

15-21: Minor: Consider using ID! for MetaEnvelope.id for consistency.

The new idiomatic queries/mutations use ID! for identifier parameters (e.g., metaEnvelope(id: ID!), DeleteMetaEnvelopePayload.deletedId: ID!), but the type definition uses String!. While they serialize identically, using ID! throughout communicates identifier semantics more clearly and improves schema consistency.

♻️ Suggested change
 type MetaEnvelope {
- id: String!+ id: ID!
"The ontology schema ID (W3ID)"
ontology: String!
envelopes: [Envelope!]!
parsed: JSON
}

Same applies to Envelope.id on line 6.


96-108: Consider using non-nullable empty array for errors field.

Currently errors: [UserError!] is nullable, meaning clients must distinguish between null (no errors) and [] (empty array). Using [UserError!]! (non-nullable, possibly empty) simplifies client handling—an empty array always means success.

This is a stylistic choice; the current pattern (null = no errors) is also valid and commonly used.

Comment threadinfrastructure/evault-core/src/core/db/db.service.ts
@coodos
coodos merged commit 14450ca into mainFeb 4, 2026
6 checks passed
@coodos
coodos deleted the feat/idiomatic-graphql-api branch February 4, 2026 15:48
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 4, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 23, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 12, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 24, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request May 2, 2026
6 tasks
Sign up for freeto 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.

feat: Make GraphQL protocol more idiomatic

2 participants

@sosweetham@coodos
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat: idiomatic graphql api - #769

Merged
coodos merged 4 commits into
mainfrom
feat/idiomatic-graphql-api
Feb 4, 2026
Merged

feat: idiomatic graphql api#769
coodos merged 4 commits into
mainfrom
feat/idiomatic-graphql-api

Conversation

@sosweetham

@sosweethamsosweetham commented Feb 4, 2026

Copy link
Copy Markdown
Member

Description of change

adds idiomatic graphql methods

Issue Number

Closes#724

Type of change

  • New (a change which implements a new feature)

How the change has been tested

n/a

Change checklist

  • I have ensured that the CI Checks pass locally
  • I have removed any unnecessary logic
  • My code is well documented
  • I have signed my commits
  • My code follows the pattern of the application
  • I have self reviewed my code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added pagination and filtering support to MetaEnvelope queries
    • Introduced Relay-style cursor-based pagination with configurable search modes
    • Enhanced error reporting with structured error payloads in mutations
    • Required X-ENAME header for all GraphQL operations
  • API Changes

    • Renamed GraphQL queries and mutations to follow idiomatic naming conventions
    • Envelope field renamed from ontology to fieldKey
    • Legacy API endpoints preserved for backward compatibility
  • Documentation

    • Updated API documentation with new operation names and usage examples
    • Added Legacy API section with mappings to new equivalents

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@sosweetham has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 13 minutes and 30 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

This pull request refactors the GraphQL API to follow idiomatic conventions: query names shift from REST-style (getMetaEnvelopeById, findMetaEnvelopesByOntology) to noun-based patterns (metaEnvelope, metaEnvelopes); list queries now support Relay-style cursor pagination with filtering and search; mutation payloads are restructured with explicit error blocks; envelope field ontology is renamed to fieldKey; X-ENAME header becomes required; legacy endpoints are preserved for backward compatibility.

Changes

Cohort / File(s)Summary
Documentation & Getting Started
docs/docs/Infrastructure/eVault.md, docs/docs/W3DS Basics/getting-started.md
Updated GraphQL documentation and examples to reflect new idiomatic API names (createMetaEnvelope, metaEnvelope, metaEnvelopes, removeMetaEnvelope); documented fieldKey replacing ontology; added Legacy API section with mappings; included X-ENAME header requirement and updated response payload shapes with error blocks.
Type System
infrastructure/evault-core/src/core/db/types.ts, infrastructure/evault-core/src/core/protocol/typedefs.ts
Added Relay-style pagination types (PageInfo, MetaEnvelopeEdge, MetaEnvelopeConnection), search/filter inputs (SearchMode enum, MetaEnvelopeSearchInput, MetaEnvelopeFilterInput), structured mutation payloads (CreateMetaEnvelopePayload, UpdateMetaEnvelopePayload, DeleteMetaEnvelopePayload), and new FindMetaEnvelopesPaginatedOptions.
Database Layer
infrastructure/evault-core/src/core/db/db.service.ts
Implemented new findMetaEnvelopesPaginated method with support for Relay-style cursor-based pagination, ontology filtering, flexible term-based search with case sensitivity and match modes, cursor computation, and totalCount metrics.
GraphQL API Implementation
infrastructure/evault-core/src/core/protocol/graphql-server.ts
Added idiomatic queries (metaEnvelope, metaEnvelopes with pagination/filtering) and mutations (createMetaEnvelope, updateMetaEnvelope, removeMetaEnvelope) with X-ENAME validation; implemented webhook delivery flow and operation logging; retained legacy endpoints for backward compatibility; introduced fieldKey field resolver and internal helpers.
Examples & Test Coverage
infrastructure/evault-core/src/core/protocol/examples/examples.ts, infrastructure/evault-core/src/core/protocol/idiomatic-graphql-api.spec.ts
Updated protocol examples to demonstrate new API names, pagination patterns, filtering, and error response shapes; added comprehensive E2E test suite covering all CRUD operations, pagination with cursors, filtering/search, error handling, and backward compatibility with legacy endpoints.

Sequence Diagram(s)

sequenceDiagram
participant Client
participant GraphQLServer as GraphQL Server
participant DbService as DB Service
participant Registry as Platform Registry
participant WebhookTarget as Webhook Platform
Client->>GraphQLServer: createMetaEnvelope(input, X-ENAME)
GraphQLServer->>GraphQLServer: Validate X-ENAME header
GraphQLServer->>DbService: Store envelope data
DbService-->>GraphQLServer: Envelope created
GraphQLServer->>GraphQLServer: Compute envelopeHash
GraphQLServer->>GraphQLServer: Construct payload with envelopes + errors
GraphQLServer->>Registry: getActivePlatforms()
Registry-->>GraphQLServer: Platform URLs
GraphQLServer->>WebhookTarget: deliverWebhooks(POST)
WebhookTarget-->>GraphQLServer: Success/Error (async)
GraphQLServer-->>Client: CreateMetaEnvelopePayload {metaEnvelope, errors}
Loading
sequenceDiagram
participant Client
participant GraphQLServer as GraphQL Server
participant DbService as DB Service
Client->>GraphQLServer: metaEnvelopes(filter, first, after, X-ENAME)
GraphQLServer->>GraphQLServer: Validate X-ENAME header
GraphQLServer->>DbService: findMetaEnvelopesPaginated(eName, options)
DbService->>DbService: Execute count query
DbService->>DbService: Apply filter (ontologyId)
DbService->>DbService: Apply search (term, caseSensitive, fields, mode)
DbService->>DbService: Decode cursor (after/before)
DbService->>DbService: Fetch edges + compute cursors
DbService->>DbService: Build PageInfo (hasNextPage, hasPreviousPage)
DbService-->>GraphQLServer: MetaEnvelopeConnection {edges, pageInfo, totalCount}
GraphQLServer-->>Client: Connection with paginated results
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

evault-refactor

Suggested reviewers

  • coodos
  • xPathin
  • JulienAuvo

Poem

🐰 Hops with glee at GraphQL's new shape,
No more REST-like queries to escape!
Cursors glide through pages neat,
Fieldkeys shine, errors complete,
Idiomatic wisdom—oh, what a feat!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Title check✅ PassedThe title 'feat: idiomatic graphql api' directly reflects the PR's main change of implementing an idiomatic GraphQL API as described in the objectives.
Description check✅ PassedThe PR description includes all required template sections: issue number (#724), type of change (New), testing status, and completed checklist items.
Linked Issues check✅ PassedThe PR comprehensively implements all coding requirements from issue #724: noun-based queries (metaEnvelope, metaEnvelopes), cursor-based pagination with MetaEnvelopeConnection, typed search input (MetaEnvelopeSearchInput), separated ontologyId/fieldKey, structured mutation payloads with errors, and delete mutation with deletedId/success.
Out of Scope Changes check✅ PassedAll changes align with issue #724 objectives: GraphQL API refactoring, pagination implementation, type safety, and mutation payload structuring. Documentation updates and test additions are scope-appropriate for the feature.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/idiomatic-graphql-api

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 and usage tips.

@coderabbitaicoderabbitaiBot 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

🤖 Fix all issues with AI agents
In `@infrastructure/evault-core/src/core/db/db.service.ts`:
- Around line 1068-1255: Add validation to reject mixed-direction cursors and
fix pageInfo backward-flag checks: extend the existing pagination validation
that currently checks "first & last" and "after & before" to also throw when
first is provided with before and when last is provided with after (refer to the
variables first, last, before, after and the validation block at the top of the
function). Then update the pageInfo construction so backward pagination
(isBackward) uses before for hasNextPage and hasExtraRecord for hasPreviousPage,
i.e. set hasNextPage = isBackward ? (before !== undefined) : hasExtraRecord and
hasPreviousPage = isBackward ? hasExtraRecord : (after !== undefined) (refer to
isBackward and pageInfo).
🧹 Nitpick comments (2)
infrastructure/evault-core/src/core/protocol/typedefs.ts (2)

15-21: Minor: Consider using ID! for MetaEnvelope.id for consistency.

The new idiomatic queries/mutations use ID! for identifier parameters (e.g., metaEnvelope(id: ID!), DeleteMetaEnvelopePayload.deletedId: ID!), but the type definition uses String!. While they serialize identically, using ID! throughout communicates identifier semantics more clearly and improves schema consistency.

♻️ Suggested change
 type MetaEnvelope {
- id: String!+ id: ID!
"The ontology schema ID (W3ID)"
ontology: String!
envelopes: [Envelope!]!
parsed: JSON
}

Same applies to Envelope.id on line 6.


96-108: Consider using non-nullable empty array for errors field.

Currently errors: [UserError!] is nullable, meaning clients must distinguish between null (no errors) and [] (empty array). Using [UserError!]! (non-nullable, possibly empty) simplifies client handling—an empty array always means success.

This is a stylistic choice; the current pattern (null = no errors) is also valid and commonly used.

Comment threadinfrastructure/evault-core/src/core/db/db.service.ts
@coodos
coodos merged commit 14450ca into mainFeb 4, 2026
6 checks passed
@coodos
coodos deleted the feat/idiomatic-graphql-api branch February 4, 2026 15:48
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 4, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 23, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 12, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 24, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request May 2, 2026
6 tasks
Sign up for freeto 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.

feat: Make GraphQL protocol more idiomatic

2 participants

@sosweetham@coodos
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: idiomatic graphql api - #769

Merged
coodos merged 4 commits into
mainfrom
feat/idiomatic-graphql-api
Feb 4, 2026
Merged

feat: idiomatic graphql api#769
coodos merged 4 commits into
mainfrom
feat/idiomatic-graphql-api

Conversation

@sosweetham

@sosweethamsosweetham commented Feb 4, 2026

Copy link
Copy Markdown
Member

Description of change

adds idiomatic graphql methods

Issue Number

Closes#724

Type of change

  • New (a change which implements a new feature)

How the change has been tested

n/a

Change checklist

  • I have ensured that the CI Checks pass locally
  • I have removed any unnecessary logic
  • My code is well documented
  • I have signed my commits
  • My code follows the pattern of the application
  • I have self reviewed my code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added pagination and filtering support to MetaEnvelope queries
    • Introduced Relay-style cursor-based pagination with configurable search modes
    • Enhanced error reporting with structured error payloads in mutations
    • Required X-ENAME header for all GraphQL operations
  • API Changes

    • Renamed GraphQL queries and mutations to follow idiomatic naming conventions
    • Envelope field renamed from ontology to fieldKey
    • Legacy API endpoints preserved for backward compatibility
  • Documentation

    • Updated API documentation with new operation names and usage examples
    • Added Legacy API section with mappings to new equivalents

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@sosweetham has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 13 minutes and 30 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

This pull request refactors the GraphQL API to follow idiomatic conventions: query names shift from REST-style (getMetaEnvelopeById, findMetaEnvelopesByOntology) to noun-based patterns (metaEnvelope, metaEnvelopes); list queries now support Relay-style cursor pagination with filtering and search; mutation payloads are restructured with explicit error blocks; envelope field ontology is renamed to fieldKey; X-ENAME header becomes required; legacy endpoints are preserved for backward compatibility.

Changes

Cohort / File(s)Summary
Documentation & Getting Started
docs/docs/Infrastructure/eVault.md, docs/docs/W3DS Basics/getting-started.md
Updated GraphQL documentation and examples to reflect new idiomatic API names (createMetaEnvelope, metaEnvelope, metaEnvelopes, removeMetaEnvelope); documented fieldKey replacing ontology; added Legacy API section with mappings; included X-ENAME header requirement and updated response payload shapes with error blocks.
Type System
infrastructure/evault-core/src/core/db/types.ts, infrastructure/evault-core/src/core/protocol/typedefs.ts
Added Relay-style pagination types (PageInfo, MetaEnvelopeEdge, MetaEnvelopeConnection), search/filter inputs (SearchMode enum, MetaEnvelopeSearchInput, MetaEnvelopeFilterInput), structured mutation payloads (CreateMetaEnvelopePayload, UpdateMetaEnvelopePayload, DeleteMetaEnvelopePayload), and new FindMetaEnvelopesPaginatedOptions.
Database Layer
infrastructure/evault-core/src/core/db/db.service.ts
Implemented new findMetaEnvelopesPaginated method with support for Relay-style cursor-based pagination, ontology filtering, flexible term-based search with case sensitivity and match modes, cursor computation, and totalCount metrics.
GraphQL API Implementation
infrastructure/evault-core/src/core/protocol/graphql-server.ts
Added idiomatic queries (metaEnvelope, metaEnvelopes with pagination/filtering) and mutations (createMetaEnvelope, updateMetaEnvelope, removeMetaEnvelope) with X-ENAME validation; implemented webhook delivery flow and operation logging; retained legacy endpoints for backward compatibility; introduced fieldKey field resolver and internal helpers.
Examples & Test Coverage
infrastructure/evault-core/src/core/protocol/examples/examples.ts, infrastructure/evault-core/src/core/protocol/idiomatic-graphql-api.spec.ts
Updated protocol examples to demonstrate new API names, pagination patterns, filtering, and error response shapes; added comprehensive E2E test suite covering all CRUD operations, pagination with cursors, filtering/search, error handling, and backward compatibility with legacy endpoints.

Sequence Diagram(s)

sequenceDiagram
participant Client
participant GraphQLServer as GraphQL Server
participant DbService as DB Service
participant Registry as Platform Registry
participant WebhookTarget as Webhook Platform
Client->>GraphQLServer: createMetaEnvelope(input, X-ENAME)
GraphQLServer->>GraphQLServer: Validate X-ENAME header
GraphQLServer->>DbService: Store envelope data
DbService-->>GraphQLServer: Envelope created
GraphQLServer->>GraphQLServer: Compute envelopeHash
GraphQLServer->>GraphQLServer: Construct payload with envelopes + errors
GraphQLServer->>Registry: getActivePlatforms()
Registry-->>GraphQLServer: Platform URLs
GraphQLServer->>WebhookTarget: deliverWebhooks(POST)
WebhookTarget-->>GraphQLServer: Success/Error (async)
GraphQLServer-->>Client: CreateMetaEnvelopePayload {metaEnvelope, errors}
Loading
sequenceDiagram
participant Client
participant GraphQLServer as GraphQL Server
participant DbService as DB Service
Client->>GraphQLServer: metaEnvelopes(filter, first, after, X-ENAME)
GraphQLServer->>GraphQLServer: Validate X-ENAME header
GraphQLServer->>DbService: findMetaEnvelopesPaginated(eName, options)
DbService->>DbService: Execute count query
DbService->>DbService: Apply filter (ontologyId)
DbService->>DbService: Apply search (term, caseSensitive, fields, mode)
DbService->>DbService: Decode cursor (after/before)
DbService->>DbService: Fetch edges + compute cursors
DbService->>DbService: Build PageInfo (hasNextPage, hasPreviousPage)
DbService-->>GraphQLServer: MetaEnvelopeConnection {edges, pageInfo, totalCount}
GraphQLServer-->>Client: Connection with paginated results
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

evault-refactor

Suggested reviewers

  • coodos
  • xPathin
  • JulienAuvo

Poem

🐰 Hops with glee at GraphQL's new shape,
No more REST-like queries to escape!
Cursors glide through pages neat,
Fieldkeys shine, errors complete,
Idiomatic wisdom—oh, what a feat!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Title check✅ PassedThe title 'feat: idiomatic graphql api' directly reflects the PR's main change of implementing an idiomatic GraphQL API as described in the objectives.
Description check✅ PassedThe PR description includes all required template sections: issue number (#724), type of change (New), testing status, and completed checklist items.
Linked Issues check✅ PassedThe PR comprehensively implements all coding requirements from issue #724: noun-based queries (metaEnvelope, metaEnvelopes), cursor-based pagination with MetaEnvelopeConnection, typed search input (MetaEnvelopeSearchInput), separated ontologyId/fieldKey, structured mutation payloads with errors, and delete mutation with deletedId/success.
Out of Scope Changes check✅ PassedAll changes align with issue #724 objectives: GraphQL API refactoring, pagination implementation, type safety, and mutation payload structuring. Documentation updates and test additions are scope-appropriate for the feature.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/idiomatic-graphql-api

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 and usage tips.

@coderabbitaicoderabbitaiBot 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

🤖 Fix all issues with AI agents
In `@infrastructure/evault-core/src/core/db/db.service.ts`:
- Around line 1068-1255: Add validation to reject mixed-direction cursors and
fix pageInfo backward-flag checks: extend the existing pagination validation
that currently checks "first & last" and "after & before" to also throw when
first is provided with before and when last is provided with after (refer to the
variables first, last, before, after and the validation block at the top of the
function). Then update the pageInfo construction so backward pagination
(isBackward) uses before for hasNextPage and hasExtraRecord for hasPreviousPage,
i.e. set hasNextPage = isBackward ? (before !== undefined) : hasExtraRecord and
hasPreviousPage = isBackward ? hasExtraRecord : (after !== undefined) (refer to
isBackward and pageInfo).
🧹 Nitpick comments (2)
infrastructure/evault-core/src/core/protocol/typedefs.ts (2)

15-21: Minor: Consider using ID! for MetaEnvelope.id for consistency.

The new idiomatic queries/mutations use ID! for identifier parameters (e.g., metaEnvelope(id: ID!), DeleteMetaEnvelopePayload.deletedId: ID!), but the type definition uses String!. While they serialize identically, using ID! throughout communicates identifier semantics more clearly and improves schema consistency.

♻️ Suggested change
 type MetaEnvelope {
- id: String!+ id: ID!
"The ontology schema ID (W3ID)"
ontology: String!
envelopes: [Envelope!]!
parsed: JSON
}

Same applies to Envelope.id on line 6.


96-108: Consider using non-nullable empty array for errors field.

Currently errors: [UserError!] is nullable, meaning clients must distinguish between null (no errors) and [] (empty array). Using [UserError!]! (non-nullable, possibly empty) simplifies client handling—an empty array always means success.

This is a stylistic choice; the current pattern (null = no errors) is also valid and commonly used.

Comment threadinfrastructure/evault-core/src/core/db/db.service.ts
@coodos
coodos merged commit 14450ca into mainFeb 4, 2026
6 checks passed
@coodos
coodos deleted the feat/idiomatic-graphql-api branch February 4, 2026 15:48
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 4, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 23, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 12, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 24, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request May 2, 2026
6 tasks
Sign up for freeto 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.

feat: Make GraphQL protocol more idiomatic

2 participants

@sosweetham@coodos
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: idiomatic graphql api - #769

Merged
coodos merged 4 commits into
mainfrom
feat/idiomatic-graphql-api
Feb 4, 2026
Merged

feat: idiomatic graphql api#769
coodos merged 4 commits into
mainfrom
feat/idiomatic-graphql-api

Conversation

@sosweetham

@sosweethamsosweetham commented Feb 4, 2026

Copy link
Copy Markdown
Member

Description of change

adds idiomatic graphql methods

Issue Number

Closes#724

Type of change

  • New (a change which implements a new feature)

How the change has been tested

n/a

Change checklist

  • I have ensured that the CI Checks pass locally
  • I have removed any unnecessary logic
  • My code is well documented
  • I have signed my commits
  • My code follows the pattern of the application
  • I have self reviewed my code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added pagination and filtering support to MetaEnvelope queries
    • Introduced Relay-style cursor-based pagination with configurable search modes
    • Enhanced error reporting with structured error payloads in mutations
    • Required X-ENAME header for all GraphQL operations
  • API Changes

    • Renamed GraphQL queries and mutations to follow idiomatic naming conventions
    • Envelope field renamed from ontology to fieldKey
    • Legacy API endpoints preserved for backward compatibility
  • Documentation

    • Updated API documentation with new operation names and usage examples
    • Added Legacy API section with mappings to new equivalents

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@sosweetham has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 13 minutes and 30 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

This pull request refactors the GraphQL API to follow idiomatic conventions: query names shift from REST-style (getMetaEnvelopeById, findMetaEnvelopesByOntology) to noun-based patterns (metaEnvelope, metaEnvelopes); list queries now support Relay-style cursor pagination with filtering and search; mutation payloads are restructured with explicit error blocks; envelope field ontology is renamed to fieldKey; X-ENAME header becomes required; legacy endpoints are preserved for backward compatibility.

Changes

Cohort / File(s)Summary
Documentation & Getting Started
docs/docs/Infrastructure/eVault.md, docs/docs/W3DS Basics/getting-started.md
Updated GraphQL documentation and examples to reflect new idiomatic API names (createMetaEnvelope, metaEnvelope, metaEnvelopes, removeMetaEnvelope); documented fieldKey replacing ontology; added Legacy API section with mappings; included X-ENAME header requirement and updated response payload shapes with error blocks.
Type System
infrastructure/evault-core/src/core/db/types.ts, infrastructure/evault-core/src/core/protocol/typedefs.ts
Added Relay-style pagination types (PageInfo, MetaEnvelopeEdge, MetaEnvelopeConnection), search/filter inputs (SearchMode enum, MetaEnvelopeSearchInput, MetaEnvelopeFilterInput), structured mutation payloads (CreateMetaEnvelopePayload, UpdateMetaEnvelopePayload, DeleteMetaEnvelopePayload), and new FindMetaEnvelopesPaginatedOptions.
Database Layer
infrastructure/evault-core/src/core/db/db.service.ts
Implemented new findMetaEnvelopesPaginated method with support for Relay-style cursor-based pagination, ontology filtering, flexible term-based search with case sensitivity and match modes, cursor computation, and totalCount metrics.
GraphQL API Implementation
infrastructure/evault-core/src/core/protocol/graphql-server.ts
Added idiomatic queries (metaEnvelope, metaEnvelopes with pagination/filtering) and mutations (createMetaEnvelope, updateMetaEnvelope, removeMetaEnvelope) with X-ENAME validation; implemented webhook delivery flow and operation logging; retained legacy endpoints for backward compatibility; introduced fieldKey field resolver and internal helpers.
Examples & Test Coverage
infrastructure/evault-core/src/core/protocol/examples/examples.ts, infrastructure/evault-core/src/core/protocol/idiomatic-graphql-api.spec.ts
Updated protocol examples to demonstrate new API names, pagination patterns, filtering, and error response shapes; added comprehensive E2E test suite covering all CRUD operations, pagination with cursors, filtering/search, error handling, and backward compatibility with legacy endpoints.

Sequence Diagram(s)

sequenceDiagram
participant Client
participant GraphQLServer as GraphQL Server
participant DbService as DB Service
participant Registry as Platform Registry
participant WebhookTarget as Webhook Platform
Client->>GraphQLServer: createMetaEnvelope(input, X-ENAME)
GraphQLServer->>GraphQLServer: Validate X-ENAME header
GraphQLServer->>DbService: Store envelope data
DbService-->>GraphQLServer: Envelope created
GraphQLServer->>GraphQLServer: Compute envelopeHash
GraphQLServer->>GraphQLServer: Construct payload with envelopes + errors
GraphQLServer->>Registry: getActivePlatforms()
Registry-->>GraphQLServer: Platform URLs
GraphQLServer->>WebhookTarget: deliverWebhooks(POST)
WebhookTarget-->>GraphQLServer: Success/Error (async)
GraphQLServer-->>Client: CreateMetaEnvelopePayload {metaEnvelope, errors}
Loading
sequenceDiagram
participant Client
participant GraphQLServer as GraphQL Server
participant DbService as DB Service
Client->>GraphQLServer: metaEnvelopes(filter, first, after, X-ENAME)
GraphQLServer->>GraphQLServer: Validate X-ENAME header
GraphQLServer->>DbService: findMetaEnvelopesPaginated(eName, options)
DbService->>DbService: Execute count query
DbService->>DbService: Apply filter (ontologyId)
DbService->>DbService: Apply search (term, caseSensitive, fields, mode)
DbService->>DbService: Decode cursor (after/before)
DbService->>DbService: Fetch edges + compute cursors
DbService->>DbService: Build PageInfo (hasNextPage, hasPreviousPage)
DbService-->>GraphQLServer: MetaEnvelopeConnection {edges, pageInfo, totalCount}
GraphQLServer-->>Client: Connection with paginated results
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

evault-refactor

Suggested reviewers

  • coodos
  • xPathin
  • JulienAuvo

Poem

🐰 Hops with glee at GraphQL's new shape,
No more REST-like queries to escape!
Cursors glide through pages neat,
Fieldkeys shine, errors complete,
Idiomatic wisdom—oh, what a feat!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Title check✅ PassedThe title 'feat: idiomatic graphql api' directly reflects the PR's main change of implementing an idiomatic GraphQL API as described in the objectives.
Description check✅ PassedThe PR description includes all required template sections: issue number (#724), type of change (New), testing status, and completed checklist items.
Linked Issues check✅ PassedThe PR comprehensively implements all coding requirements from issue #724: noun-based queries (metaEnvelope, metaEnvelopes), cursor-based pagination with MetaEnvelopeConnection, typed search input (MetaEnvelopeSearchInput), separated ontologyId/fieldKey, structured mutation payloads with errors, and delete mutation with deletedId/success.
Out of Scope Changes check✅ PassedAll changes align with issue #724 objectives: GraphQL API refactoring, pagination implementation, type safety, and mutation payload structuring. Documentation updates and test additions are scope-appropriate for the feature.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/idiomatic-graphql-api

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 and usage tips.

@coderabbitaicoderabbitaiBot 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

🤖 Fix all issues with AI agents
In `@infrastructure/evault-core/src/core/db/db.service.ts`:
- Around line 1068-1255: Add validation to reject mixed-direction cursors and
fix pageInfo backward-flag checks: extend the existing pagination validation
that currently checks "first & last" and "after & before" to also throw when
first is provided with before and when last is provided with after (refer to the
variables first, last, before, after and the validation block at the top of the
function). Then update the pageInfo construction so backward pagination
(isBackward) uses before for hasNextPage and hasExtraRecord for hasPreviousPage,
i.e. set hasNextPage = isBackward ? (before !== undefined) : hasExtraRecord and
hasPreviousPage = isBackward ? hasExtraRecord : (after !== undefined) (refer to
isBackward and pageInfo).
🧹 Nitpick comments (2)
infrastructure/evault-core/src/core/protocol/typedefs.ts (2)

15-21: Minor: Consider using ID! for MetaEnvelope.id for consistency.

The new idiomatic queries/mutations use ID! for identifier parameters (e.g., metaEnvelope(id: ID!), DeleteMetaEnvelopePayload.deletedId: ID!), but the type definition uses String!. While they serialize identically, using ID! throughout communicates identifier semantics more clearly and improves schema consistency.

♻️ Suggested change
 type MetaEnvelope {
- id: String!+ id: ID!
"The ontology schema ID (W3ID)"
ontology: String!
envelopes: [Envelope!]!
parsed: JSON
}

Same applies to Envelope.id on line 6.


96-108: Consider using non-nullable empty array for errors field.

Currently errors: [UserError!] is nullable, meaning clients must distinguish between null (no errors) and [] (empty array). Using [UserError!]! (non-nullable, possibly empty) simplifies client handling—an empty array always means success.

This is a stylistic choice; the current pattern (null = no errors) is also valid and commonly used.

Comment threadinfrastructure/evault-core/src/core/db/db.service.ts
@coodos
coodos merged commit 14450ca into mainFeb 4, 2026
6 checks passed
@coodos
coodos deleted the feat/idiomatic-graphql-api branch February 4, 2026 15:48
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 4, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 23, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 12, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 24, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request May 2, 2026
6 tasks
Sign up for freeto 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.

feat: Make GraphQL protocol more idiomatic

2 participants

@sosweetham@coodos
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat: idiomatic graphql api - #769

Merged
coodos merged 4 commits into
mainfrom
feat/idiomatic-graphql-api
Feb 4, 2026
Merged

feat: idiomatic graphql api#769
coodos merged 4 commits into
mainfrom
feat/idiomatic-graphql-api

Conversation

@sosweetham

@sosweethamsosweetham commented Feb 4, 2026

Copy link
Copy Markdown
Member

Description of change

adds idiomatic graphql methods

Issue Number

Closes#724

Type of change

  • New (a change which implements a new feature)

How the change has been tested

n/a

Change checklist

  • I have ensured that the CI Checks pass locally
  • I have removed any unnecessary logic
  • My code is well documented
  • I have signed my commits
  • My code follows the pattern of the application
  • I have self reviewed my code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added pagination and filtering support to MetaEnvelope queries
    • Introduced Relay-style cursor-based pagination with configurable search modes
    • Enhanced error reporting with structured error payloads in mutations
    • Required X-ENAME header for all GraphQL operations
  • API Changes

    • Renamed GraphQL queries and mutations to follow idiomatic naming conventions
    • Envelope field renamed from ontology to fieldKey
    • Legacy API endpoints preserved for backward compatibility
  • Documentation

    • Updated API documentation with new operation names and usage examples
    • Added Legacy API section with mappings to new equivalents

@coderabbitai

coderabbitaiBot commented Feb 4, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@sosweetham has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 13 minutes and 30 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

This pull request refactors the GraphQL API to follow idiomatic conventions: query names shift from REST-style (getMetaEnvelopeById, findMetaEnvelopesByOntology) to noun-based patterns (metaEnvelope, metaEnvelopes); list queries now support Relay-style cursor pagination with filtering and search; mutation payloads are restructured with explicit error blocks; envelope field ontology is renamed to fieldKey; X-ENAME header becomes required; legacy endpoints are preserved for backward compatibility.

Changes

Cohort / File(s)Summary
Documentation & Getting Started
docs/docs/Infrastructure/eVault.md, docs/docs/W3DS Basics/getting-started.md
Updated GraphQL documentation and examples to reflect new idiomatic API names (createMetaEnvelope, metaEnvelope, metaEnvelopes, removeMetaEnvelope); documented fieldKey replacing ontology; added Legacy API section with mappings; included X-ENAME header requirement and updated response payload shapes with error blocks.
Type System
infrastructure/evault-core/src/core/db/types.ts, infrastructure/evault-core/src/core/protocol/typedefs.ts
Added Relay-style pagination types (PageInfo, MetaEnvelopeEdge, MetaEnvelopeConnection), search/filter inputs (SearchMode enum, MetaEnvelopeSearchInput, MetaEnvelopeFilterInput), structured mutation payloads (CreateMetaEnvelopePayload, UpdateMetaEnvelopePayload, DeleteMetaEnvelopePayload), and new FindMetaEnvelopesPaginatedOptions.
Database Layer
infrastructure/evault-core/src/core/db/db.service.ts
Implemented new findMetaEnvelopesPaginated method with support for Relay-style cursor-based pagination, ontology filtering, flexible term-based search with case sensitivity and match modes, cursor computation, and totalCount metrics.
GraphQL API Implementation
infrastructure/evault-core/src/core/protocol/graphql-server.ts
Added idiomatic queries (metaEnvelope, metaEnvelopes with pagination/filtering) and mutations (createMetaEnvelope, updateMetaEnvelope, removeMetaEnvelope) with X-ENAME validation; implemented webhook delivery flow and operation logging; retained legacy endpoints for backward compatibility; introduced fieldKey field resolver and internal helpers.
Examples & Test Coverage
infrastructure/evault-core/src/core/protocol/examples/examples.ts, infrastructure/evault-core/src/core/protocol/idiomatic-graphql-api.spec.ts
Updated protocol examples to demonstrate new API names, pagination patterns, filtering, and error response shapes; added comprehensive E2E test suite covering all CRUD operations, pagination with cursors, filtering/search, error handling, and backward compatibility with legacy endpoints.

Sequence Diagram(s)

sequenceDiagram
participant Client
participant GraphQLServer as GraphQL Server
participant DbService as DB Service
participant Registry as Platform Registry
participant WebhookTarget as Webhook Platform
Client->>GraphQLServer: createMetaEnvelope(input, X-ENAME)
GraphQLServer->>GraphQLServer: Validate X-ENAME header
GraphQLServer->>DbService: Store envelope data
DbService-->>GraphQLServer: Envelope created
GraphQLServer->>GraphQLServer: Compute envelopeHash
GraphQLServer->>GraphQLServer: Construct payload with envelopes + errors
GraphQLServer->>Registry: getActivePlatforms()
Registry-->>GraphQLServer: Platform URLs
GraphQLServer->>WebhookTarget: deliverWebhooks(POST)
WebhookTarget-->>GraphQLServer: Success/Error (async)
GraphQLServer-->>Client: CreateMetaEnvelopePayload {metaEnvelope, errors}
Loading
sequenceDiagram
participant Client
participant GraphQLServer as GraphQL Server
participant DbService as DB Service
Client->>GraphQLServer: metaEnvelopes(filter, first, after, X-ENAME)
GraphQLServer->>GraphQLServer: Validate X-ENAME header
GraphQLServer->>DbService: findMetaEnvelopesPaginated(eName, options)
DbService->>DbService: Execute count query
DbService->>DbService: Apply filter (ontologyId)
DbService->>DbService: Apply search (term, caseSensitive, fields, mode)
DbService->>DbService: Decode cursor (after/before)
DbService->>DbService: Fetch edges + compute cursors
DbService->>DbService: Build PageInfo (hasNextPage, hasPreviousPage)
DbService-->>GraphQLServer: MetaEnvelopeConnection {edges, pageInfo, totalCount}
GraphQLServer-->>Client: Connection with paginated results
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

evault-refactor

Suggested reviewers

  • coodos
  • xPathin
  • JulienAuvo

Poem

🐰 Hops with glee at GraphQL's new shape,
No more REST-like queries to escape!
Cursors glide through pages neat,
Fieldkeys shine, errors complete,
Idiomatic wisdom—oh, what a feat!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check nameStatusExplanation
Title check✅ PassedThe title 'feat: idiomatic graphql api' directly reflects the PR's main change of implementing an idiomatic GraphQL API as described in the objectives.
Description check✅ PassedThe PR description includes all required template sections: issue number (#724), type of change (New), testing status, and completed checklist items.
Linked Issues check✅ PassedThe PR comprehensively implements all coding requirements from issue #724: noun-based queries (metaEnvelope, metaEnvelopes), cursor-based pagination with MetaEnvelopeConnection, typed search input (MetaEnvelopeSearchInput), separated ontologyId/fieldKey, structured mutation payloads with errors, and delete mutation with deletedId/success.
Out of Scope Changes check✅ PassedAll changes align with issue #724 objectives: GraphQL API refactoring, pagination implementation, type safety, and mutation payload structuring. Documentation updates and test additions are scope-appropriate for the feature.
Docstring Coverage✅ PassedNo functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/idiomatic-graphql-api

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 and usage tips.

@coderabbitaicoderabbitaiBot 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

🤖 Fix all issues with AI agents
In `@infrastructure/evault-core/src/core/db/db.service.ts`:
- Around line 1068-1255: Add validation to reject mixed-direction cursors and
fix pageInfo backward-flag checks: extend the existing pagination validation
that currently checks "first & last" and "after & before" to also throw when
first is provided with before and when last is provided with after (refer to the
variables first, last, before, after and the validation block at the top of the
function). Then update the pageInfo construction so backward pagination
(isBackward) uses before for hasNextPage and hasExtraRecord for hasPreviousPage,
i.e. set hasNextPage = isBackward ? (before !== undefined) : hasExtraRecord and
hasPreviousPage = isBackward ? hasExtraRecord : (after !== undefined) (refer to
isBackward and pageInfo).
🧹 Nitpick comments (2)
infrastructure/evault-core/src/core/protocol/typedefs.ts (2)

15-21: Minor: Consider using ID! for MetaEnvelope.id for consistency.

The new idiomatic queries/mutations use ID! for identifier parameters (e.g., metaEnvelope(id: ID!), DeleteMetaEnvelopePayload.deletedId: ID!), but the type definition uses String!. While they serialize identically, using ID! throughout communicates identifier semantics more clearly and improves schema consistency.

♻️ Suggested change
 type MetaEnvelope {
- id: String!+ id: ID!
"The ontology schema ID (W3ID)"
ontology: String!
envelopes: [Envelope!]!
parsed: JSON
}

Same applies to Envelope.id on line 6.


96-108: Consider using non-nullable empty array for errors field.

Currently errors: [UserError!] is nullable, meaning clients must distinguish between null (no errors) and [] (empty array). Using [UserError!]! (non-nullable, possibly empty) simplifies client handling—an empty array always means success.

This is a stylistic choice; the current pattern (null = no errors) is also valid and commonly used.

Comment threadinfrastructure/evault-core/src/core/db/db.service.ts
@coodos
coodos merged commit 14450ca into mainFeb 4, 2026
6 checks passed
@coodos
coodos deleted the feat/idiomatic-graphql-api branch February 4, 2026 15:48
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 4, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Feb 23, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 12, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request Mar 24, 2026
6 tasks
@coderabbitaicoderabbitaiBot mentioned this pull request May 2, 2026
6 tasks
Sign up for freeto 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.

feat: Make GraphQL protocol more idiomatic

2 participants

@sosweetham@coodos