plane icon indicating copy to clipboard operation
plane copied to clipboard

[WEB-5804] refactor: decouple filter value types from filter configurations

Open prateekshourya29 opened this issue 1 week ago β€’ 2 comments

Description

Problem

Filter configurations were constrained to a single value type (e.g., TFilterConfig<'priority', TIssuePriorities>), but different operators for the same filter can accept different value types.

Solution

  • Remove value type parameter from filter configs: TFilterConfig<P, V> β†’ TFilterConfig<P>
  • Make value types operator-specific rather than filter-specific
  • Simplify all filter config creators across the codebase
  • Add forceUpdate parameter to updateConditionValue() for explicit updates

Impact

  • More accurate type representation
  • Better flexibility for diverse operator types
  • Simplified filter configuration APIs
  • No breaking runtime changes

Files Changed

  • Types: filter-config.ts, operator-configs/*
  • Filters: priority, state, user, date, cycle, label, module, project
  • State: enhanced updateConditionValue in filter.ts

Type of Change

  • [x] Code refactoring

[!NOTE] Refactor rich filter typing

  • Convert TFilterConfig<P, V> to TFilterConfig<P> and remove TFilterValue generics across config, manager, and factories; move value typing to operator-specific configs (TOperatorSpecificConfigs, TOperatorConfigMap).
  • Update FilterConfig, FilterConfigManager, and all work-item filter creators (state, priority, user, date, cycle, label, module, project) to new signatures.
  • Add forceUpdate?: boolean to updateConditionValue() in FilterInstance to allow explicit updates even when values are equal.
  • Minor UI: replace Calendar with CalendarLayoutIcon for created/updated date filters.

Written by Cursor Bugbot for commit ccce43ba3d3bbe863d1e3722eb0df1287efb6946. This will update automatically on new commits. Configure here.

Summary by CodeRabbit

  • New Features
    • Added an optional parameter to force filter condition reassessment, allowing manual re-evaluation of a filter even when its value hasn't changed.
  • Updated UI
    • Switched the date filter icon used for created/updated date filters to an updated calendar icon.

✏️ Tip: You can customize this high-level summary in your review settings.

prateekshourya29 avatar Dec 23 '25 14:12 prateekshourya29

Linked to Plane Work Item(s)

This comment was auto-generated by Plane

makeplane[bot] avatar Dec 23 '25 14:12 makeplane[bot]

Walkthrough

This PR removes the generic type parameter V from rich-filter operator and filter config types across the codebase so types use TFilterValue directly. It also adds an optional forceUpdate parameter to FilterInstance.updateConditionValue to allow forcing reassessment even when values are equal.

Changes

Cohort / File(s) Summary
Filter instance
packages/shared-state/src/store/rich-filters/filter.ts
Added optional forceUpdate?: boolean to IFilterInstance.updateConditionValue and implementation updateConditionValue(..., forceUpdate: boolean = false). Equality early-return now guarded by if (!forceUpdate && isEqual(...)) { return; }. JSDoc added.
Filter config runtime
packages/shared-state/src/store/rich-filters/config.ts, packages/shared-state/src/store/rich-filters/config-manager.ts
Dropped V generic from IFilterConfig, FilterConfig, IFilterConfigManager, and FilterConfigManager. Updated constructors, methods, public fields, maps, and internal collections to use TFilterValue / non‑generic TFilterConfig<P> types.
Type definitions (core & index)
packages/types/src/rich-filters/config/filter-config.ts, packages/types/src/rich-filters/operator-configs/core.ts, packages/types/src/rich-filters/operator-configs/index.ts, packages/types/src/rich-filters/operator-configs/extended.ts, packages/types/src/rich-filters/derived/core.ts
Removed the generic V extends TFilterValue from many operator and config type aliases; replaced V-parameterized unions/maps with non-generic equivalents that reference TFilterValue directly. Removed unused TFilterValue imports where applicable.
Utils β€” factories & helpers
packages/utils/src/rich-filters/factories/configs/shared.ts, packages/utils/src/rich-filters/factories/configs/properties/shared.ts, packages/utils/src/rich-filters/factories/configs/properties/shared.ts
Simplified createFilterConfig signature from <P, V> to <P>. Adjusted createOperatorConfigEntry and getSupportedDateOperators return types to use non-generic TOperatorConfigMap / TOperatorSpecificConfigs.
Work-item filters β€” call sites
packages/utils/src/work-item-filters/configs/filters/*
packages/utils/src/work-item-filters/configs/filters/cycle.ts, .../date.ts, .../label.ts, .../module.ts, .../priority.ts, .../project.ts, .../state.ts, .../user.ts, .../shared.ts
Removed second generic argument on createFilterConfig calls (e.g., createFilterConfig<P, string> β†’ createFilterConfig<P>) across multiple filter builders. Adjusted return types where they referenced operator map generics.
App hook β€” icons & config typing
apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx
Replaced Calendar with CalendarLayoutIcon for some filter icons. Updated exported TWorkItemFiltersConfig shape to use TFilterConfig<TWorkItemFilterProperty>[] and configMap entries to TFilterConfig<TWorkItemFilterProperty> (dropped TFilterValue generic).

Sequence Diagram(s)

(omitted β€” changes are type-level and a small update to a single-method behavior; conditions for sequence diagrams not met)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Pre-merge checks and finishing touches

βœ… Passed checks (3 passed)
Check name Status Explanation
Title check βœ… Passed The title clearly identifies the main change: decoupling filter value types from configurations, directly aligned with the PR's core objective.
Description check βœ… Passed The description includes the template's required sections: a detailed problem statement, solution approach, impact analysis, and explicitly marks this as a code refactoring, meeting all template requirements.
Docstring Coverage βœ… Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • [ ] πŸ“ Generate docstrings
πŸ§ͺ Generate unit tests (beta)
  • [ ] Create PR with unit tests
  • [ ] Post copyable unit tests in a comment
  • [ ] Commit unit tests in branch refactor-filter-types

πŸ“œ Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 28ebe65b427e2aeb3d2193ca35249b446653deae and ccce43ba3d3bbe863d1e3722eb0df1287efb6946.

πŸ“’ Files selected for processing (7)
  • apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx
  • packages/shared-state/src/store/rich-filters/config-manager.ts
  • packages/shared-state/src/store/rich-filters/config.ts
  • packages/types/src/rich-filters/derived/core.ts
  • packages/types/src/rich-filters/operator-configs/extended.ts
  • packages/utils/src/rich-filters/factories/configs/properties/shared.ts
  • packages/utils/src/work-item-filters/configs/filters/shared.ts
🧰 Additional context used
πŸ““ Path-based instructions (5)
**/*.{ts,tsx,mts,cts}

πŸ“„ CodeRabbit inference engine (.github/instructions/typescript.instructions.md)

**/*.{ts,tsx,mts,cts}: Use const type parameters for more precise literal inference in TypeScript 5.0+ Use the satisfies operator to validate types without widening them Leverage inferred type predicates to reduce the need for explicit is return types in filter/check functions Use NoInfer<T> utility to block inference for specific type arguments when they should be determined by other arguments Utilize narrowing in switch(true) blocks for control flow analysis (TypeScript 5.3+) Rely on narrowing from direct boolean comparisons for type guards Trust preserved narrowing in closures when variables aren't modified after the check (TypeScript 5.4+) Use constant indices to narrow object/array properties (TypeScript 5.5+) Use standard ECMAScript decorators (Stage 3) instead of legacy experimentalDecorators Use using declarations for explicit resource management with Disposable pattern instead of manual cleanup (TypeScript 5.2+) Use with { type: "json" } for import attributes; avoid deprecated assert syntax (TypeScript 5.3/5.8+) Use import type explicitly when importing types to ensure they are erased during compilation, respecting verbatimModuleSyntax flag Use .ts, .mts, .cts extensions in import type statements (TypeScript 5.2+) Use import type { Type } from "mod" with { "resolution-mode": "import" } for specific module resolution contexts (TypeScript 5.3+) Use new iterator methods (map, filter, etc.) if targeting modern environments (TypeScript 5.6+) Utilize new Set methods like union, intersection, etc., when available (TypeScript 5.5+) Use Object.groupBy / Map.groupBy standard methods for grouping instead of external libraries (TypeScript 5.4+) Use Promise.withResolvers() for creating promises with exposed resolve/reject functions (TypeScript 5.7+) Use copying array methods (toSorted, toSpliced, with) for immutable array operations (TypeScript 5.2+) Avoid accessing instance fields via super in classes (TypeScript 5....

Files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
  • packages/utils/src/rich-filters/factories/configs/properties/shared.ts
  • packages/shared-state/src/store/rich-filters/config.ts
  • packages/utils/src/work-item-filters/configs/filters/shared.ts
  • packages/types/src/rich-filters/derived/core.ts
  • apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx
  • packages/shared-state/src/store/rich-filters/config-manager.ts
**/*.{ts,tsx}

πŸ“„ CodeRabbit inference engine (AGENTS.md)

Enable TypeScript strict mode and ensure all files are fully typed

Files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
  • packages/utils/src/rich-filters/factories/configs/properties/shared.ts
  • packages/shared-state/src/store/rich-filters/config.ts
  • packages/utils/src/work-item-filters/configs/filters/shared.ts
  • packages/types/src/rich-filters/derived/core.ts
  • apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx
  • packages/shared-state/src/store/rich-filters/config-manager.ts
**/*.{js,jsx,ts,tsx,json,css}

πŸ“„ CodeRabbit inference engine (AGENTS.md)

Use Prettier with Tailwind plugin for code formatting, run pnpm fix:format

Files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
  • packages/utils/src/rich-filters/factories/configs/properties/shared.ts
  • packages/shared-state/src/store/rich-filters/config.ts
  • packages/utils/src/work-item-filters/configs/filters/shared.ts
  • packages/types/src/rich-filters/derived/core.ts
  • apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx
  • packages/shared-state/src/store/rich-filters/config-manager.ts
**/*.{js,jsx,ts,tsx}

πŸ“„ CodeRabbit inference engine (AGENTS.md)

**/*.{js,jsx,ts,tsx}: Use ESLint with shared config across packages, adhering to max warnings limits per package Use camelCase for variable and function names, PascalCase for components and types Use try-catch with proper error types and log errors appropriately

Files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
  • packages/utils/src/rich-filters/factories/configs/properties/shared.ts
  • packages/shared-state/src/store/rich-filters/config.ts
  • packages/utils/src/work-item-filters/configs/filters/shared.ts
  • packages/types/src/rich-filters/derived/core.ts
  • apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx
  • packages/shared-state/src/store/rich-filters/config-manager.ts
packages/shared-state/**/*.{ts,tsx}

πŸ“„ CodeRabbit inference engine (AGENTS.md)

Maintain MobX stores in packages/shared-state using reactive patterns

Files:

  • packages/shared-state/src/store/rich-filters/config.ts
  • packages/shared-state/src/store/rich-filters/config-manager.ts
🧠 Learnings (11)
πŸ““ Common learnings
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Leverage inferred type predicates to reduce the need for explicit `is` return types in filter/check functions
πŸ“š Learning: 2025-11-25T10:18:05.172Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Leverage inferred type predicates to reduce the need for explicit `is` return types in filter/check functions

Applied to files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
  • packages/shared-state/src/store/rich-filters/config.ts
  • packages/utils/src/work-item-filters/configs/filters/shared.ts
  • packages/types/src/rich-filters/derived/core.ts
  • packages/shared-state/src/store/rich-filters/config-manager.ts
πŸ“š Learning: 2025-11-25T10:18:05.172Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Use `const` type parameters for more precise literal inference in TypeScript 5.0+

Applied to files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
  • packages/shared-state/src/store/rich-filters/config.ts
  • packages/types/src/rich-filters/derived/core.ts
πŸ“š Learning: 2025-11-25T10:18:05.172Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Use the `satisfies` operator to validate types without widening them

Applied to files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
  • packages/utils/src/rich-filters/factories/configs/properties/shared.ts
  • packages/utils/src/work-item-filters/configs/filters/shared.ts
  • packages/types/src/rich-filters/derived/core.ts
πŸ“š Learning: 2025-11-25T10:18:05.172Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Rely on narrowing from direct boolean comparisons for type guards

Applied to files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
πŸ“š Learning: 2025-11-25T10:18:05.172Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Use constant indices to narrow object/array properties (TypeScript 5.5+)

Applied to files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
  • packages/types/src/rich-filters/derived/core.ts
πŸ“š Learning: 2025-11-25T10:18:05.172Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Trust preserved narrowing in closures when variables aren't modified after the check (TypeScript 5.4+)

Applied to files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
πŸ“š Learning: 2025-11-25T10:18:05.172Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: .github/instructions/typescript.instructions.md:0-0
Timestamp: 2025-11-25T10:18:05.172Z
Learning: Applies to **/*.{ts,tsx,mts,cts} : Use `NoInfer<T>` utility to block inference for specific type arguments when they should be determined by other arguments

Applied to files:

  • packages/types/src/rich-filters/operator-configs/extended.ts
πŸ“š Learning: 2025-12-12T15:20:36.542Z
Learnt from: CR
Repo: makeplane/plane PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-12T15:20:36.542Z
Learning: Applies to packages/shared-state/**/*.{ts,tsx} : Maintain MobX stores in `packages/shared-state` using reactive patterns

Applied to files:

  • packages/shared-state/src/store/rich-filters/config.ts
πŸ“š Learning: 2025-10-09T20:42:31.843Z
Learnt from: lifeiscontent
Repo: makeplane/plane PR: 7922
File: apps/admin/app/(all)/(dashboard)/ai/form.tsx:19-19
Timestamp: 2025-10-09T20:42:31.843Z
Learning: In the makeplane/plane repository, React types are globally available through TypeScript configuration. Type annotations like React.FC, React.ReactNode, etc. can be used without explicitly importing the React namespace. The codebase uses the modern JSX transform, so React imports are not required for JSX or type references.

Applied to files:

  • apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx
πŸ“š Learning: 2025-10-01T15:30:17.605Z
Learnt from: lifeiscontent
Repo: makeplane/plane PR: 7888
File: packages/propel/src/avatar/avatar.stories.tsx:2-3
Timestamp: 2025-10-01T15:30:17.605Z
Learning: In the makeplane/plane repository, avoid suggesting inline type imports (e.g., `import { Avatar, type TAvatarSize }`) due to bundler compatibility issues. Keep type imports and value imports as separate statements.

Applied to files:

  • apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx
🧬 Code graph analysis (5)
packages/utils/src/rich-filters/factories/configs/properties/shared.ts (3)
packages/utils/src/work-item-filters/configs/filters/shared.ts (1)
  • getSupportedDateOperators (15-21)
packages/utils/src/rich-filters/factories/configs/shared.ts (1)
  • TCreateDateFilterParams (53-53)
packages/types/src/rich-filters/operator-configs/index.ts (1)
  • TOperatorConfigMap (43-46)
packages/shared-state/src/store/rich-filters/config.ts (4)
packages/types/src/rich-filters/expression.ts (2)
  • TFilterProperty (19-19)
  • TFilterValue (24-24)
packages/types/src/rich-filters/config/filter-config.ts (1)
  • TFilterConfig (11-20)
packages/types/src/rich-filters/operators/index.ts (1)
  • TSupportedOperators (56-56)
packages/types/src/rich-filters/operator-configs/index.ts (1)
  • TOperatorSpecificConfigs (33-37)
packages/utils/src/work-item-filters/configs/filters/shared.ts (3)
packages/utils/src/rich-filters/factories/configs/properties/shared.ts (1)
  • getSupportedDateOperators (44-50)
packages/utils/src/rich-filters/factories/configs/shared.ts (1)
  • TCreateDateFilterParams (53-53)
packages/types/src/rich-filters/operator-configs/index.ts (1)
  • TOperatorConfigMap (43-46)
apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx (3)
packages/types/src/rich-filters/config/filter-config.ts (1)
  • TFilterConfig (11-20)
packages/types/src/view-props.ts (1)
  • TWorkItemFilterProperty (106-106)
packages/propel/src/icons/layouts/calendar-icon.tsx (1)
  • CalendarLayoutIcon (6-15)
packages/shared-state/src/store/rich-filters/config-manager.ts (3)
packages/shared-state/src/store/rich-filters/config.ts (1)
  • IFilterConfig (28-41)
packages/constants/src/rich-filters/option.ts (1)
  • TConfigOptions (6-6)
packages/types/src/rich-filters/config/filter-config.ts (1)
  • TFilterConfig (11-20)
⏰ 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). (3)
  • GitHub Check: Cursor Bugbot
  • GitHub Check: Build packages
  • GitHub Check: Analyze (javascript)
πŸ”‡ Additional comments (14)
packages/utils/src/rich-filters/factories/configs/properties/shared.ts (1)

44-50: LGTM! Type signature correctly updated to non-generic operator config map.

The return type change from TOperatorConfigMap<Date> to TOperatorConfigMap aligns with the PR's goal of decoupling value types from filter configurations. The function body remains unchanged, preserving runtime behavior while gaining flexibility for operator-specific value types.

packages/utils/src/work-item-filters/configs/filters/shared.ts (1)

15-21: LGTM!

The return type change from TOperatorConfigMap<Date> to TOperatorConfigMap correctly aligns with the refactored non-generic TOperatorConfigMap type definition. This is consistent with the similar function in packages/utils/src/rich-filters/factories/configs/properties/shared.ts.

apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx (3)

2-19: LGTM!

Import changes are clean - Calendar removed and replaced with CalendarLayoutIcon from the propel icons package. The import structure follows project conventions with separate value and type imports.


75-83: LGTM!

The simplified TFilterConfig<TWorkItemFilterProperty> type (without the value-type generic) correctly aligns with the updated type definition in packages/types/src/rich-filters/config/filter-config.ts. This makes the public API surface cleaner while maintaining type safety through operator-specific typing.


324-344: LGTM!

The icon change from Calendar to CalendarLayoutIcon for both created_at and updated_at filters is applied consistently. This provides visual alignment between the timestamp filters.

packages/shared-state/src/store/rich-filters/config-manager.ts (3)

25-39: LGTM!

The IFilterConfigManager interface correctly removes the value-type generic while maintaining the property type generic P. The type signatures for filterConfigs, allAvailableConfigs, getConfigByProperty, register, registerAll, and updateConfigByProperty are all consistent with the simplified IFilterConfig<P> and TFilterConfig<P> types.


117-119: LGTM!

The getConfigByProperty implementation correctly uses computedFn for MobX reactivity and the cast to IFilterConfig<P> aligns with the updated type definition. The implementation maintains proper MobX reactive patterns as per the coding guidelines.


168-178: LGTM!

Private computed properties _allConfigs and _allEnabledConfigs correctly updated to return IFilterConfig<P>[]. The filter operation on line 177 properly leverages TypeScript's type inference.

packages/shared-state/src/store/rich-filters/config.ts (4)

28-41: LGTM!

The IFilterConfig interface correctly removes the value-type generic V while maintaining proper typing:

  • getDisplayOperatorByValue and getAllDisplayOperatorOptionsByValue now use TFilterValue directly, which represents the union of all possible filter value types
  • mutate accepts Partial<TFilterConfig<P>> aligned with the simplified type
  • The method signatures are consistent with the PR's objective of making value types operator-specific rather than filter-specific

43-77: LGTM!

The FilterConfig class implementation correctly:

  • Simplifies the generic signature to FilterConfig<P extends TFilterProperty>
  • References IFilterConfig<P> for observable property types
  • Uses TFilterConfig<P> for constructor parameter
  • Maintains proper MobX observable/computed/action decorations

152-171: LGTM!

The getAllDisplayOperatorOptionsByValue method has been refactored with:

  • Clean for...of loop instead of more verbose alternatives
  • Consistent use of TFilterValue for the value parameter
  • Proper building of operator options array with both primary and additional options

The implementation correctly handles operator-specific value types through TFilterValue.


179-195: LGTM!

The mutate action correctly:

  • Accepts Partial<TFilterConfig<P>> aligned with simplified types
  • Uses runInAction for proper MobX batching
  • Casts to keyof TFilterConfig<P> for type safety

The private _getAdditionalOperatorOptions helper correctly uses TFilterValue for the _value parameter, maintaining consistency with the refactored type surface.

packages/types/src/rich-filters/operator-configs/extended.ts (1)

2-11: LGTM! Placeholder types simplified.

The removal of the generic V parameter from these extended operator config placeholders is consistent with the PR's goal to decouple value types from filter configurations. Since these are placeholder types (never and unknown) with no active logic, the generic parameter was unused and its removal simplifies the type signatures without any impact.

packages/types/src/rich-filters/derived/core.ts (1)

16-22: LGTM! Consistent refactoring across all operator helper types.

The systematic removal of the generic V parameter from TCoreOperatorSpecificConfigs across all four mapped types is correct and aligns with the PR's objective to make value types operator-specific rather than filter-specific. The parent types appropriately retain the V parameter for field config specialization (e.g., TDateFilterFieldConfig<V>), maintaining the correct semantics: "which operators from the (now non-generic) operator config map support field configs with value type V?"

The refactoring is applied consistently across date and select filter operator types, preserving type correctness while simplifying the operator config API.

Also applies to: 27-33, 50-56, 61-67


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.

coderabbitai[bot] avatar Dec 23 '25 14:12 coderabbitai[bot]