Skip to content

Conversation

@koriym
Copy link
Member

@koriym koriym commented Nov 10, 2025

Summary

  • Add comprehensive documentation to cache attributes
  • Add docblocks to interceptor classes
  • Include usage examples and interceptor binding information
  • Clarify Event-Driven Content concepts

Changes

Cache Attributes Documentation

#[Cacheable] - TTL-based caching

  • Add usage examples (expirySecond, expiry presets, expiryAt)
  • Document bound interceptors (CacheInterceptor, CommandInterceptor)
  • Link to manual section

#[HttpCache] - HTTP Cache-Control header

  • Add examples from basic to advanced (maxAge, mustRevalidate, isPrivate, sMaxAge)
  • Remove misleading no-cache/no-store example
  • Encourage use of #[NoHttpCache] for disabling cache

#[NoHttpCache] - Disable HTTP caching

  • Add interceptor binding information
  • Link to manual

#[CacheableResponse] - Event-driven full response caching

  • Explain fundamentally static content with predictable changes
  • Highlight ETag and 304 (Not Modified) benefits
  • Add usage example with RefreshCache
  • Document bound interceptors

#[DonutCache] - Event-driven donut caching

  • Explain use case for non-cacheable embedded content
  • Add usage example with Embed
  • Clarify no ETag generation

#[Purge] / #[Refresh] - Cache invalidation

  • Add usage examples with URI templates
  • Document bound interceptors (RefreshInterceptor, CommandInterceptor)

#[RefreshCache] - Donut cache refresh

  • Document bound interceptor (DonutCacheInterceptor)

Interceptor Classes Documentation

CacheInterceptor - TTL-based caching on CQRS queries
CommandInterceptor - Cache invalidation on CQRS commands
HttpCacheInterceptor - HTTP Cache-Control header
DonutCacheInterceptor - Donut caching on CQRS queries
DonutCacheableResponseInterceptor - Full response caching on CQRS queries
DonutCommandInterceptor - Donut cache invalidation on CQRS commands
RefreshInterceptor - Cache refresh for non-Cacheable classes

All interceptors now include:

  • Clear description of purpose
  • Which attributes they bind to
  • CQRS query vs command distinction
  • Links to attribute classes and manual sections

Benefits

  • Developers can understand interceptor binding without reading module code
  • Usage examples provide quick reference
  • Clear distinction between TTL-based and event-driven caching
  • Better understanding of CQRS pattern in caching system

Summary by Sourcery

Document cache annotations and interceptor classes with detailed docblocks, usage examples, binding information, and links to the manual

Enhancements:

  • Add comprehensive docblocks to cache annotation classes with usage examples, interceptor binding details, and manual links
  • Add detailed documentation to interceptor classes describing their purpose, attribute bindings, and CQRS context

Documentation:

  • Clarify event-driven content concepts and distinctions between TTL-based and HTTP caching modes in the documentation

- Document which interceptors are bound to each cache attribute
- Add direct links to BEAR.Sunday manual sections with hash fragments
- Improve code readability for developers understanding the caching system

Attributes updated:
- Cacheable: CacheInterceptor, CommandInterceptor
- HttpCache/NoHttpCache: HttpCacheInterceptor
- Purge/Refresh: RefreshInterceptor, CommandInterceptor
- DonutCache: DonutCacheInterceptor
- CacheableResponse: DonutCacheableResponseInterceptor, DonutCommandInterceptor
- RefreshCache: DonutCacheInterceptor
- Emphasize EDC is for content that is fundamentally static
- Changes are predictable via resource methods (onPut, onDelete, etc.)
- Add 304 Not Modified benefit for network transfer cost reduction
- Add practical examples to HttpCache, Cacheable, Purge, Refresh
- Add class-level examples to DonutCache and CacheableResponse
- Show URI template placeholders usage in Purge/Refresh
- Demonstrate CDN cache configuration patterns in HttpCache
- Remove example combining noCache and noStore (common misuse)
- Keep simple reference to use NoHttpCache for no-caching scenarios
- Avoid confusion between no-cache (revalidate) and no-store (don't cache)
- HttpCache is for configuring cache control, not disabling it
- NoHttpCache is the dedicated attribute for disabling cache
- Keep HttpCache examples focused on actual cache configuration
- Better separation of concerns between attributes
- Document which attributes each interceptor binds to
- Clarify CQRS query (onGet) vs command (onPut/onPatch/onDelete) distinction
- Add links to attribute classes and manual sections
- Explain cache behavior and ETag generation differences

Interceptors documented:
- CacheInterceptor: TTL-based caching for queries
- CommandInterceptor: Cache invalidation for commands
- HttpCacheInterceptor: HTTP Cache-Control header
- DonutCacheInterceptor: Donut caching for queries
- DonutCacheableResponseInterceptor: Full response caching for queries
- DonutCommandInterceptor: Donut cache invalidation for commands
- RefreshInterceptor: Cache refresh for non-Cacheable classes
@sourcery-ai
Copy link

sourcery-ai bot commented Nov 10, 2025

Reviewer's Guide

This PR enriches the caching system with detailed docblocks across all cache annotations and interceptor classes, embedding usage examples, bound-interceptor listings, manual links, and clarifications between TTL-based and event-driven (ETag/304) caching.

Class diagram for updated cache attribute annotations and interceptors

classDiagram
    class Cacheable {
        <<Attribute>>
        +expirySecond: int
        +expiry: string
        +expiryAt: string
        "TTL-based caching"
        "Bound Interceptors: CacheInterceptor (onGet), CommandInterceptor (onPut/onPatch/onDelete)"
    }
    class CacheableResponse {
        <<Attribute>>
        "Event-driven full response caching"
        "Bound Interceptors: DonutCacheableResponseInterceptor (onGet), DonutCommandInterceptor (onPut/onPatch/onDelete), DonutCacheInterceptor (method)"
    }
    class DonutCache {
        <<Attribute>>
        "Event-driven donut caching for resources with non-cacheable embedded content"
        "Bound Interceptors: DonutCacheInterceptor (onGet or method)"
    }
    class HttpCache {
        <<Attribute>>
        +maxAge: int
        +mustRevalidate: bool
        +isPrivate: bool
        +sMaxAge: int
        "HTTP Cache-Control header"
        "Bound Interceptors: HttpCacheInterceptor (onGet)"
    }
    class NoHttpCache {
        <<Attribute>>
        "Disable HTTP caching"
        "Bound Interceptors: HttpCacheInterceptor (onGet)"
    }
    class Purge {
        <<Attribute>>
        +uri: string
        "Cache invalidation after command execution"
        "Bound Interceptors: RefreshInterceptor (non-Cacheable), CommandInterceptor (Cacheable)"
    }
    class Refresh {
        <<Attribute>>
        +uri: string
        "Cache refresh after command execution"
        "Bound Interceptors: RefreshInterceptor (non-Cacheable), CommandInterceptor (Cacheable)"
    }
    class RefreshCache {
        <<Attribute>>
        "Donut cache refresh after command execution"
        "Bound Interceptors: DonutCacheInterceptor"
    }
    class CacheInterceptor {
        <<Interceptor>>
        "TTL-based caching on CQRS queries"
        "Binds to: Cacheable"
    }
    class CommandInterceptor {
        <<Interceptor>>
        "Cache invalidation on CQRS commands"
        "Binds to: Purge, Refresh (Cacheable)"
    }
    class HttpCacheInterceptor {
        <<Interceptor>>
        "HTTP Cache-Control header"
        "Binds to: HttpCache, NoHttpCache"
    }
    class DonutCacheInterceptor {
        <<Interceptor>>
        "Donut caching on CQRS queries"
        "Binds to: DonutCache, RefreshCache"
    }
    class DonutCacheableResponseInterceptor {
        <<Interceptor>>
        "Full response caching on CQRS queries"
        "Binds to: CacheableResponse"
    }
    class DonutCommandInterceptor {
        <<Interceptor>>
        "Donut cache invalidation on CQRS commands"
        "Binds to: CacheableResponse, DonutCache"
    }
    class RefreshInterceptor {
        <<Interceptor>>
        "Cache refresh for non-Cacheable classes"
        "Binds to: Purge, Refresh (non-Cacheable)"
    }

    Cacheable <|.. CacheInterceptor
    Cacheable <|.. CommandInterceptor
    CacheableResponse <|.. DonutCacheableResponseInterceptor
    CacheableResponse <|.. DonutCommandInterceptor
    DonutCache <|.. DonutCacheInterceptor
    DonutCache <|.. DonutCommandInterceptor
    HttpCache <|.. HttpCacheInterceptor
    NoHttpCache <|.. HttpCacheInterceptor
    Purge <|.. RefreshInterceptor
    Purge <|.. CommandInterceptor
    Refresh <|.. RefreshInterceptor
    Refresh <|.. CommandInterceptor
    RefreshCache <|.. DonutCacheInterceptor
Loading

Flow diagram of attribute to interceptor binding

flowchart TD
    A["#[Cacheable]"] --> B["CacheInterceptor (onGet)"]
    A --> C["CommandInterceptor (onPut/onPatch/onDelete)"]
    D["#[CacheableResponse]"] --> E["DonutCacheableResponseInterceptor (onGet)"]
    D --> F["DonutCommandInterceptor (onPut/onPatch/onDelete)"]
    D --> G["DonutCacheInterceptor (method)"]
    H["#[DonutCache]"] --> I["DonutCacheInterceptor (onGet or method)"]
    J["#[HttpCache]"] --> K["HttpCacheInterceptor (onGet)"]
    L["#[NoHttpCache]"] --> K
    M["#[Purge]"] --> N["RefreshInterceptor (non-Cacheable)"]
    M --> O["CommandInterceptor (Cacheable)"]
    P["#[Refresh]"] --> N
    P --> O
    Q["#[RefreshCache]"] --> I
Loading

File-Level Changes

Change Details Files
Enhanced documentation for cache annotation attributes
  • Added usage examples and expiry presets in #[Cacheable], #[HttpCache], #[NoHttpCache], #[CacheableResponse], #[DonutCache], #[Purge], #[Refresh], #[RefreshCache]
  • Documented bound interceptors for each annotation
  • Inserted links to the manual for quick reference
  • Clarified TTL-based vs event-driven caching concepts and removed misleading examples
src-annotation/CacheableResponse.php
src-annotation/Cacheable.php
src-annotation/DonutCache.php
src-annotation/HttpCache.php
src-annotation/Purge.php
src-annotation/Refresh.php
src-annotation/RefreshCache.php
src-annotation/NoHttpCache.php
Added comprehensive docblocks to interceptor classes
  • Described each interceptor’s purpose and CQRS query vs command binding
  • Listed associated attributes for binding and included manual section URLs
  • Clarified behavior (e.g., ETag generation, TTL handling, invalidation flows)
src/CacheInterceptor.php
src/CommandInterceptor.php
src/DonutCacheInterceptor.php
src/DonutCacheableResponseInterceptor.php
src/DonutCommandInterceptor.php
src/HttpCacheInterceptor.php
src/RefreshInterceptor.php

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 10, 2025

Important

Review skipped

Auto reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

This PR enhances documentation across cache annotation and interceptor classes through comprehensive PHPDoc blocks, removes unused imports from interceptor references, and introduces property promotion with #[Commands] attribute in CommandInterceptor. No functional logic changes to core behaviors.

Changes

Cohort / File(s) Summary
Annotation Classes – Documentation Enhancements
src-annotation/Cacheable.php, src-annotation/CacheableResponse.php, src-annotation/DonutCache.php, src-annotation/HttpCache.php, src-annotation/NoHttpCache.php, src-annotation/Purge.php, src-annotation/Refresh.php, src-annotation/RefreshCache.php
Added/expanded comprehensive PHPDoc blocks documenting cache expiration strategies, event-driven invalidation, ETag support, and interceptor bindings. Removed unused interceptor imports (DonutCacheableResponseInterceptor, DonutCommandInterceptor, RefreshInterceptor). Replaced internal @see references with external documentation URLs.
Core Interceptor – Constructor Update
src/CommandInterceptor.php
Added class docblock describing cache invalidation via CQRS commands. Updated constructor to use property promotion with #[Commands] attribute: public function __construct(#[Commands] private array $commands).
Interceptor Classes – Documentation Enhancements
src/CacheInterceptor.php, src/DonutCacheInterceptor.php, src/DonutCacheableResponseInterceptor.php, src/DonutCommandInterceptor.php, src/HttpCacheInterceptor.php, src/RefreshInterceptor.php
Added comprehensive PHPDoc blocks describing interceptor purposes, binding behaviors, and references. DonutCacheInterceptor introduces protected constant IS_ENTIRE_CONTENT_CACHEABLE = false. All other changes are documentation-only.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

  • CommandInterceptor.php — Only non-documentation change; review property promotion syntax and #[Commands] attribute binding.
  • Annotation and interceptor imports — Verify removed imports are indeed unused across the codebase.
  • DonutCacheInterceptor constant — Confirm IS_ENTIRE_CONTENT_CACHEABLE value aligns with expected caching behavior.

Possibly related PRs

  • Optimize for PHP 8.2 readonly classes #166 — Modifies the same interceptor and annotation classes (CacheInterceptor, CommandInterceptor, DonutCommandInterceptor, HttpCache, RefreshInterceptor) at the class/constructor/property level with overlapping file changes.
  • Migrate from doctrine/annotations to PHP 8 Attributes #165 — Updates the same annotation classes (Cacheable, HttpCache, Purge, Refresh) by migrating doctrine-style annotations to PHP 8 attributes, complementing this documentation and import cleanup PR.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Document cache attributes and interceptors' directly and accurately reflects the primary objective of the changeset—adding comprehensive documentation to cache-related attributes and interceptor classes.
Description check ✅ Passed The description is well-structured and comprehensive, covering all major changes including cache attribute documentation, interceptor class documentation, and stated benefits—all of which align with the actual changeset.

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.

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

  • Consider centralizing the interceptor binding lists into a shared doc template or trait to reduce duplication across annotations and interceptors.
  • Use a constant or config for the manual’s base URL to ensure consistency and simplify updates when the docs path changes.
  • Standardize the indentation and formatting of the code examples in the docblocks for consistency across all annotations.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider centralizing the interceptor binding lists into a shared doc template or trait to reduce duplication across annotations and interceptors.
- Use a constant or config for the manual’s base URL to ensure consistency and simplify updates when the docs path changes.
- Standardize the indentation and formatting of the code examples in the docblocks for consistency across all annotations.

## Individual Comments

### Comment 1
<location> `src-annotation/Cacheable.php:21-22` </location>
<code_context>
+ * #[Cacheable(expirySecond: 3600)]
+ *
+ * // Cache with predefined expiry preset
+ * #[Cacheable(expiry: 'short')]  // short, medium, long, never
+ *
+ * // Cache until specific time from body field
</code_context>

<issue_to_address>
**suggestion:** The list of expiry presets could be referenced to a source or defined.

If these presets are defined or configurable elsewhere, please reference their source or clarify their definitions for better maintainability.

```suggestion
 * // Cache with predefined expiry preset
 * #[Cacheable(expiry: 'short')]  // short, medium, long, never
 * // See preset definitions in CacheInterceptor::$expiryPresets or config/cache.php
```
</issue_to_address>

### Comment 2
<location> `src-annotation/DonutCache.php:13-22` </location>
<code_context>
 /**
+ * Enables event-driven cache invalidation for fully cacheable responses
+ *
+ * For content that is fundamentally static but changes predictably via resource
+ * methods (onPut, onDelete, etc.). Unlike #[Cacheable] which uses TTL-based
+ * expiration, this enables tag-based invalidation driven by resource dependencies.
</code_context>

<issue_to_address>
**suggestion:** Clarify the behavior when applied to method versus class.

Please clarify how DonutCacheInterceptor behaves when applied at the class level versus the method level, so users understand the scope and effect of the attribute in each case.
</issue_to_address>

### Comment 3
<location> `src-annotation/Purge.php:19-21` </location>
<code_context>
+ * #[Cacheable(expiryAt: 'expires_at')]
+ * ```
+ *
+ * Interceptors bound:
+ * - CacheInterceptor (onGet methods)
+ * - CommandInterceptor (onPut/onPatch/onDelete methods)
</code_context>

<issue_to_address>
**suggestion:** Clarify the difference in behavior for Cacheable vs non-Cacheable classes.

Expand the documentation to explain how the bound interceptors differ for Cacheable and non-Cacheable classes, clarifying the impact of using the Cacheable attribute.
</issue_to_address>

### Comment 4
<location> `src-annotation/Refresh.php:18-20` </location>
<code_context>
+ * #[Cacheable(expiryAt: 'expires_at')]
+ * ```
+ *
+ * Interceptors bound:
+ * - CacheInterceptor (onGet methods)
+ * - CommandInterceptor (onPut/onPatch/onDelete methods)
</code_context>

<issue_to_address>
**suggestion:** Clarify the distinction between interceptor behavior for Cacheable and non-Cacheable classes.

Add a short note explaining how refresh logic operates differently for Cacheable versus non-Cacheable classes to improve maintainability.
</issue_to_address>

### Comment 5
<location> `src-annotation/NoHttpCache.php:15-16` </location>
<code_context>
+ * #[Cacheable(expiryAt: 'expires_at')]
+ * ```
+ *
+ * Interceptors bound:
+ * - CacheInterceptor (onGet methods)
+ * - CommandInterceptor (onPut/onPatch/onDelete methods)
</code_context>

<issue_to_address>
**suggestion:** Consider clarifying the effect of NoHttpCache on HTTP headers.

Briefly note how NoHttpCache modifies HTTP headers to clarify its practical impact for users.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +21 to +22
* // Cache with predefined expiry preset
* #[Cacheable(expiry: 'short')] // short, medium, long, never
Copy link

Choose a reason for hiding this comment

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

suggestion: The list of expiry presets could be referenced to a source or defined.

If these presets are defined or configurable elsewhere, please reference their source or clarify their definitions for better maintainability.

Suggested change
* // Cache with predefined expiry preset
* #[Cacheable(expiry: 'short')] // short, medium, long, never
* // Cache with predefined expiry preset
* #[Cacheable(expiry: 'short')] // short, medium, long, never
* // See preset definitions in CacheInterceptor::$expiryPresets or config/cache.php

Comment on lines +15 to +16
* Interceptors bound:
* - HttpCacheInterceptor (onGet methods)
Copy link

Choose a reason for hiding this comment

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

suggestion: Consider clarifying the effect of NoHttpCache on HTTP headers.

Briefly note how NoHttpCache modifies HTTP headers to clarify its practical impact for users.

@koriym
Copy link
Member Author

koriym commented Nov 10, 2025

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 10, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@codecov
Copy link

codecov bot commented Nov 10, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (a039994) to head (374a20e).
⚠️ Report is 9 commits behind head on 1.x.

Additional details and impacted files
@@             Coverage Diff             @@
##                 1.x      #167   +/-   ##
===========================================
  Coverage     100.00%   100.00%           
  Complexity       243       243           
===========================================
  Files             52        52           
  Lines            734       734           
===========================================
  Hits             734       734           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src-annotation/CacheableResponse.php (1)

19-29: Consider completing the method signatures in the example.

The example code shows method signatures without bodies or continuation indicators. While the intent is clear, adding { ... } or a comment would make the example more syntactically complete and easier to understand.

Apply this diff to improve the example clarity:

  * Example:
  * ```php
  * #[CacheableResponse]
  * class Article extends ResourceObject
  * {
- *     public function onGet(int $id): static
+ *     public function onGet(int $id): static
+ *     {
+ *         // ...
+ *     }
  *
  *     #[RefreshCache]
- *     public function onDelete(int $id): static
+ *     public function onDelete(int $id): static
+ *     {
+ *         // ...
+ *     }
  * }
  * ```
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a039994 and ec6327c.

📒 Files selected for processing (15)
  • src-annotation/Cacheable.php (1 hunks)
  • src-annotation/CacheableResponse.php (1 hunks)
  • src-annotation/DonutCache.php (1 hunks)
  • src-annotation/HttpCache.php (1 hunks)
  • src-annotation/NoHttpCache.php (1 hunks)
  • src-annotation/Purge.php (1 hunks)
  • src-annotation/Refresh.php (1 hunks)
  • src-annotation/RefreshCache.php (1 hunks)
  • src/CacheInterceptor.php (1 hunks)
  • src/CommandInterceptor.php (1 hunks)
  • src/DonutCacheInterceptor.php (1 hunks)
  • src/DonutCacheableResponseInterceptor.php (1 hunks)
  • src/DonutCommandInterceptor.php (1 hunks)
  • src/HttpCacheInterceptor.php (1 hunks)
  • src/RefreshInterceptor.php (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.php

📄 CodeRabbit inference engine (CLAUDE.md)

Adhere to PSR-12 coding standards using PHP_CodeSniffer for all PHP source files

Files:

  • src/DonutCacheableResponseInterceptor.php
  • src-annotation/DonutCache.php
  • src-annotation/Purge.php
  • src/HttpCacheInterceptor.php
  • src/DonutCacheInterceptor.php
  • src/RefreshInterceptor.php
  • src/CommandInterceptor.php
  • src-annotation/Refresh.php
  • src-annotation/CacheableResponse.php
  • src/CacheInterceptor.php
  • src/DonutCommandInterceptor.php
  • src-annotation/NoHttpCache.php
  • src-annotation/Cacheable.php
  • src-annotation/HttpCache.php
  • src-annotation/RefreshCache.php
{src,tests}/**/*.php

📄 CodeRabbit inference engine (CLAUDE.md)

{src,tests}/**/*.php: Ensure code passes PHPStan at max level as configured by phpstan.neon
Ensure code passes Psalm at error level 1 as configured by psalm.xml

Files:

  • src/DonutCacheableResponseInterceptor.php
  • src/HttpCacheInterceptor.php
  • src/DonutCacheInterceptor.php
  • src/RefreshInterceptor.php
  • src/CommandInterceptor.php
  • src/CacheInterceptor.php
  • src/DonutCommandInterceptor.php
src-annotation/**/*.php

📄 CodeRabbit inference engine (CLAUDE.md)

Define and maintain cache-related attributes #[Cacheable], #[HttpCache], #[Refresh], #[Purge] in src-annotation/

Files:

  • src-annotation/DonutCache.php
  • src-annotation/Purge.php
  • src-annotation/Refresh.php
  • src-annotation/CacheableResponse.php
  • src-annotation/NoHttpCache.php
  • src-annotation/Cacheable.php
  • src-annotation/HttpCache.php
  • src-annotation/RefreshCache.php
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: bearsunday/BEAR.QueryRepository PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-21T05:23:58.622Z
Learning: Applies to src-annotation/**/*.php : Define and maintain cache-related attributes #[Cacheable], #[HttpCache], #[Refresh], #[Purge] in src-annotation/
📚 Learning: 2025-10-21T05:23:58.622Z
Learnt from: CR
Repo: bearsunday/BEAR.QueryRepository PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-10-21T05:23:58.622Z
Learning: Applies to src-annotation/**/*.php : Define and maintain cache-related attributes #[Cacheable], #[HttpCache], #[Refresh], #[Purge] in src-annotation/

Applied to files:

  • src/DonutCacheableResponseInterceptor.php
  • src-annotation/DonutCache.php
  • src-annotation/Purge.php
  • src/HttpCacheInterceptor.php
  • src/DonutCacheInterceptor.php
  • src/RefreshInterceptor.php
  • src-annotation/Refresh.php
  • src-annotation/CacheableResponse.php
  • src/CacheInterceptor.php
  • src/DonutCommandInterceptor.php
  • src-annotation/NoHttpCache.php
  • src-annotation/Cacheable.php
  • src-annotation/HttpCache.php
  • src-annotation/RefreshCache.php
📚 Learning: 2024-11-01T14:52:06.297Z
Learnt from: koriym
Repo: bearsunday/BEAR.QueryRepository PR: 144
File: src-deprecated/ResourceStorageCacheableTrait.php:24-24
Timestamp: 2024-11-01T14:52:06.297Z
Learning: When deprecating the `ResourceStorageCacheableTrait` in `src-deprecated/ResourceStorageCacheableTrait.php`, it is acceptable to only add the `deprecated` annotation without adding a runtime deprecation notice using `trigger_deprecation()`.

Applied to files:

  • src-annotation/Cacheable.php
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Sourcery review
🔇 Additional comments (10)
src/CommandInterceptor.php (2)

15-24: Excellent documentation!

The docblock provides clear, comprehensive information about the interceptor's purpose, binding, and execution context. This aligns perfectly with the PR's goal of making it easier to understand interceptor bindings without reading module code.


28-30: No changes required — the #[Commands] attribute usage is properly implemented.

The attribute is correctly defined as a #[Qualifier] in src-annotation/Commands.php and properly bound in CacheableModule.php to inject an array of command implementations via CommandsProvider. The constructor property promotion syntax is PSR-12 compliant and follows standard Ray\DI patterns. Static analysis configurations are in place.

src-annotation/Purge.php (1)

9-24: Excellent documentation improvements!

The comprehensive PHPDoc block clearly explains the cache purging behavior, provides practical examples with URI templates, and documents the interceptor binding logic for both Cacheable and non-Cacheable classes. This directly addresses the previous review feedback about clarifying interceptor behavior differences.

src/DonutCacheInterceptor.php (1)

7-20: Well-documented new interceptor class.

The PHPDoc block clearly explains the donut caching strategy for CQRS queries, binding behavior, and the key distinction that no ETag is generated for the entire response. The IS_ENTIRE_CONTENT_CACHEABLE = false constant appropriately differentiates this from DonutCacheableResponseInterceptor.

src/DonutCacheableResponseInterceptor.php (1)

7-16: Clear documentation of full response caching.

The PHPDoc block effectively explains the interceptor's role in caching entire responses with ETag generation and 304 Not Modified support. The documentation clearly contrasts with DonutCacheInterceptor by emphasizing full response caching.

src-annotation/Refresh.php (1)

9-23: Comprehensive documentation addressing previous feedback.

The enhanced PHPDoc block clearly documents cache refresh behavior, provides a practical example, and explicitly addresses the previous review comment by clarifying how interceptor binding differs between Cacheable and non-Cacheable classes.

src/RefreshInterceptor.php (1)

14-23: Well-documented interceptor binding behavior.

The PHPDoc block clearly explains the interceptor's role in cache invalidation for non-Cacheable classes, its binding to Purge/Refresh attributes, and the execution flow. This complements the documentation in the corresponding attribute classes.

src-annotation/DonutCache.php (1)

10-33: Comprehensive documentation addressing previous feedback.

The extensive PHPDoc block clearly explains donut caching use cases, provides a practical example with embedded resources, and explicitly addresses the previous review comment by clarifying interceptor binding behavior when applied at class versus method level (line 29). The contrast with TTL-based #[Cacheable] is particularly helpful.

src/DonutCommandInterceptor.php (1)

22-31: Clear documentation of command-side cache invalidation.

The PHPDoc block effectively explains the interceptor's role in CQRS command handling, its binding to write operations (onPut/onPatch/onDelete) on CacheableResponse classes, and the cache refresh behavior after successful writes.

src-annotation/RefreshCache.php (1)

9-16: Concise and clear documentation.

The PHPDoc block effectively documents the donut cache refresh behavior and its binding to DonutCacheInterceptor, with an appropriate manual reference for cache invalidation.

koriym and others added 2 commits November 10, 2025 15:23
… classes

- Explain automatic binding for Cacheable classes (CommandInterceptor)
- Explain explicit attribute requirement for non-Cacheable classes (RefreshInterceptor)
- Cross-reference related interceptors in documentation
- Address review comment: #167 (comment)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Add method bodies ({ ... }) to all example method signatures to make
the code syntactically complete and easier to understand.

Address CodeRabbit review comment.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@koriym koriym merged commit a5b1a14 into 1.x Nov 10, 2025
49 of 50 checks passed
@koriym koriym deleted the attribute-interceptor-docs branch November 10, 2025 06:43
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.

2 participants