Skip to content

feat: @cacheTag composition for root query fields only - #3131

Open
SkArchon wants to merge 4 commits into
mainfrom
milinda/cacheTag-initial
Open

feat: @cacheTag composition for root query fields only#3131
SkArchon wants to merge 4 commits into
mainfrom
milinda/cacheTag-initial

Conversation

@SkArchon

@SkArchon SkArchon commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

This PR introduces @cacheTag, with the following limitations

  • does not handle entities - this will be done in the follow up PR
  • Is not added to the router execution config - this will be done in the follow up PR

Summary by CodeRabbit

  • New Features

    • Added support for the repeatable @cacheTag(format: String!) directive on query fields.
    • Enables cache-tag format strings with static text and $args placeholders, including nested input-value paths.
    • Extended entity caching configuration to include cache-tag configurations.
  • Validation

    • Improved validation and user-facing error messages for empty/malformed formats, brace/placeholder issues, invalid placement, unsupported namespaces, undefined argument references, and invalid argument leaf types.
  • Tests

    • Expanded directive and format-parsing test coverage for successful configurations and precise error payloads.

Checklist

Open Source AI Manifesto

This project follows the principles of the Open Source AI Manifesto. Please ensure your contribution aligns with its principles.

@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Changes

Cache tag directive

Layer / File(s) Summary
Directive contracts and configuration
composition/src/directive-definition-data/..., composition/src/v1/constants/..., composition/src/router-configuration/..., composition/src/utils/string-constants.ts
Defines repeatable @cacheTag(format: String!), registers it, adds placeholder regexes, and extends entity caching configuration.
Format parsing and normalization
composition/src/v1/normalization/..., composition/src/errors/...
Parses placeholders, validates Query-root usage, namespaces, argument paths, and supported leaf types, then stores valid cache-tag configurations.
Validation coverage
composition/tests/v1/directives/cache-tag.test.ts, composition/tests/v1/normalization-utils.test.ts
Covers valid and invalid cache-tag formats, placeholder parsing, brace handling, and generated error messages.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • wundergraph/cosmo#2983: Extends the same entity-caching configuration and normalization flow for cache invalidation.
  • wundergraph/cosmo#2984: Introduces the cache-directive normalization flow extended here for @cacheTag.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.38% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding @cacheTag composition for root Query fields only.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch

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

@codecov

codecov Bot commented Jul 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.44444% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 45.73%. Comparing base (c14711a) to head (5937f01).
⚠️ Report is 8 commits behind head on main.

Files with missing lines Patch % Lines
...tion/src/v1/normalization/normalization-factory.ts 98.94% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3131      +/-   ##
==========================================
- Coverage   48.87%   45.73%   -3.14%     
==========================================
  Files        1130      868     -262     
  Lines      157574   126773   -30801     
  Branches    10879    10937      +58     
==========================================
- Hits        77009    57982   -19027     
+ Misses      78696    68446   -10250     
+ Partials     1869      345    -1524     
Files with missing lines Coverage Δ
...ctive-definition-data/directive-definition-data.ts 100.00% <100.00%> (ø)
composition/src/errors/errors.ts 81.99% <100.00%> (+0.29%) ⬆️
composition/src/router-configuration/utils.ts 100.00% <100.00%> (ø)
composition/src/utils/string-constants.ts 100.00% <100.00%> (ø)
composition/src/v1/constants/constants.ts 100.00% <100.00%> (ø)
...position/src/v1/constants/directive-definitions.ts 100.00% <100.00%> (ø)
composition/src/v1/normalization/utils.ts 90.33% <100.00%> (+0.27%) ⬆️
...tion/src/v1/normalization/normalization-factory.ts 90.66% <98.94%> (+0.19%) ⬆️

... and 269 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
composition/src/errors/errors.ts (1)

2182-2184: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Wording is misleading for the unclosed-brace case.

This message fires both for an extra/stray brace and for an unclosed placeholder (e.g. "products-{$args.searchKey", per the "unclosed placeholder" test). "defines an extra curly brace" doesn't accurately describe a missing closing brace scenario.

✏️ Suggested wording fix
 export function unbalancedCacheTagFormatErrorMessage(format: string): string {
-  return `The "format" argument defines an extra curly brace; received "${format}".`;
+  return `The "format" argument contains an unbalanced curly brace; received "${format}".`;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@composition/src/errors/errors.ts` around lines 2182 - 2184, Update
unbalancedCacheTagFormatErrorMessage to use wording that accurately covers both
stray/extra braces and unclosed placeholders, without asserting that the format
specifically contains an extra curly brace.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@composition/src/v1/constants/directive-definitions.ts`:
- Around line 876-895: Run the repository’s Prettier formatter on
composition/src/v1/constants/directive-definitions.ts lines 876-895, including
the CACHE_TAG_DEFINITION block, and
composition/tests/v1/directives/cache-tag.test.ts lines 87-104; apply only the
formatting changes required for the composition lint check.

---

Nitpick comments:
In `@composition/src/errors/errors.ts`:
- Around line 2182-2184: Update unbalancedCacheTagFormatErrorMessage to use
wording that accurately covers both stray/extra braces and unclosed
placeholders, without asserting that the format specifically contains an extra
curly brace.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5273bd8c-d306-40bd-a0bc-1afa2e870c50

📥 Commits

Reviewing files that changed from the base of the PR and between 1c51219 and d9c8ae3.

📒 Files selected for processing (12)
  • composition/src/directive-definition-data/directive-definition-data.ts
  • composition/src/errors/errors.ts
  • composition/src/errors/types/params.ts
  • composition/src/router-configuration/types.ts
  • composition/src/router-configuration/utils.ts
  • composition/src/utils/string-constants.ts
  • composition/src/v1/constants/constants.ts
  • composition/src/v1/constants/directive-definitions.ts
  • composition/src/v1/normalization/normalization-factory.ts
  • composition/src/v1/normalization/types/types.ts
  • composition/src/v1/normalization/utils.ts
  • composition/tests/v1/directives/cache-tag.test.ts

Comment thread composition/src/v1/constants/directive-definitions.ts Outdated
@SkArchon
SkArchon marked this pull request as ready for review July 30, 2026 18:25
@SkArchon
SkArchon requested a review from a team as a code owner July 30, 2026 18:25

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

Claude Code Review is paused for this repository. To reconnect it, an admin of this repository's GitHub organization (or the account owner, for personal repositories) who can also manage your Claude organization's Code Review settings needs to re-link GitHub in Code Review settings. This is a one-time step.

Tip: disable this comment in your organization's Code Review settings.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
composition/src/v1/normalization/normalization-factory.ts (1)

4526-4538: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider documenting the unresolved-type fallback in isValidCacheTagLeaf.

Returning true when namedTypeData is undefined is consistent with this file's existing pattern of deferring "undefined type" errors to a later global check (see validateArguments and the main normalize() loop, which use // undefined types are handled elsewhere comments). A short inline comment here would make that intent explicit for future readers, since without it the fallback could look like an oversight.

📝 Optional clarifying comment
   isValidCacheTagLeaf({ namedTypeName, type }: FieldData | InputValueData): boolean {
     if (isTypeNodeListType(type)) {
       return false;
     }
     if (BASE_SCALARS.has(namedTypeName)) {
       return true;
     }
     const namedTypeData = this.parentDefinitionDataByTypeName.get(namedTypeName);
     if (!namedTypeData) {
+      // Undefined types are handled elsewhere (a separate undefined-type error is raised globally).
       return true;
     }
     return namedTypeData.kind === Kind.SCALAR_TYPE_DEFINITION || namedTypeData.kind === Kind.ENUM_TYPE_DEFINITION;
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@composition/src/v1/normalization/normalization-factory.ts` around lines 4526
- 4538, Add a brief inline comment in isValidCacheTagLeaf immediately before the
!namedTypeData fallback, documenting that unresolved or undefined types are
intentionally accepted here and validated later by the global checks. Keep the
existing return behavior unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@composition/src/v1/normalization/normalization-factory.ts`:
- Around line 4526-4538: Add a brief inline comment in isValidCacheTagLeaf
immediately before the !namedTypeData fallback, documenting that unresolved or
undefined types are intentionally accepted here and validated later by the
global checks. Keep the existing return behavior unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ea1d8ac1-bf7c-4002-b228-c3dce0176789

📥 Commits

Reviewing files that changed from the base of the PR and between 1c51219 and 5937f01.

📒 Files selected for processing (13)
  • composition/src/directive-definition-data/directive-definition-data.ts
  • composition/src/errors/errors.ts
  • composition/src/errors/types/params.ts
  • composition/src/router-configuration/types.ts
  • composition/src/router-configuration/utils.ts
  • composition/src/utils/string-constants.ts
  • composition/src/v1/constants/constants.ts
  • composition/src/v1/constants/directive-definitions.ts
  • composition/src/v1/normalization/normalization-factory.ts
  • composition/src/v1/normalization/types/types.ts
  • composition/src/v1/normalization/utils.ts
  • composition/tests/v1/directives/cache-tag.test.ts
  • composition/tests/v1/normalization-utils.test.ts
🚧 Files skipped from review as they are similar to previous changes (10)
  • composition/src/router-configuration/utils.ts
  • composition/src/v1/normalization/types/types.ts
  • composition/tests/v1/normalization-utils.test.ts
  • composition/src/directive-definition-data/directive-definition-data.ts
  • composition/src/utils/string-constants.ts
  • composition/src/v1/constants/directive-definitions.ts
  • composition/src/router-configuration/types.ts
  • composition/src/errors/errors.ts
  • composition/src/v1/constants/constants.ts
  • composition/tests/v1/directives/cache-tag.test.ts

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant