Skip to content

refactor: replace FeaturesRepository with DI-based feature repositories#27200

Merged
PeerRich merged 10 commits intomainfrom
chore/replace-feature-repository-usages
Feb 6, 2026
Merged

refactor: replace FeaturesRepository with DI-based feature repositories#27200
PeerRich merged 10 commits intomainfrom
chore/replace-feature-repository-usages

Conversation

@eunjae-lee
Copy link
Copy Markdown
Contributor

@eunjae-lee eunjae-lee commented Jan 23, 2026

Summary

This PR refactors the codebase to replace the legacy combined FeaturesRepository with separate DI-based repositories:

  • IFeatureRepository / PrismaFeatureRepository - Global feature flag checks (checkIfFeatureIsEnabledGlobally)
  • ITeamFeatureRepository / PrismaTeamFeatureRepository - Team-level feature checks (checkIfTeamHasFeature, getTeamsWithFeatureEnabled)
  • IUserFeatureRepository / PrismaUserFeatureRepository - User-level feature checks (checkIfUserHasFeature)

Key Changes

  1. Added checkIfFeatureIsEnabledGlobally to IFeatureRepository - Moved global feature check method to the correct interface

  2. Updated CalendarSubscriptionService - Now uses three separate feature repositories instead of the combined FeaturesRepository

  3. Updated SelectedCalendarRepository.findNextSubscriptionBatch - Changed from featureIds: string[] to teamIds: number[] parameter for more efficient team-based filtering

  4. Updated OnboardingPathService - Now uses DI container to get the feature repository

  5. Updated all callsites - Removed direct prisma parameter passing where DI containers are now used

Test plan

  • Unit tests updated and passing for CalendarSubscriptionService
  • Unit tests updated and passing for SelectedCalendarRepository
  • Type check passes

🤖 Generated with Claude Code

@eunjae-lee
Copy link
Copy Markdown
Contributor Author

@cubic-dev-ai review this PR

@cubic-dev-ai
Copy link
Copy Markdown
Contributor

cubic-dev-ai Bot commented Jan 23, 2026

@cubic-dev-ai review this PR

@eunjae-lee I have started the AI code review. It will take a few minutes to complete.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-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.

No issues found across 117 files

Note: This PR contains a large number of files. cubic only reviews up to 75 files per PR, so some files may not have been reviewed.

@eunjae-lee eunjae-lee force-pushed the chore/replace-feature-repository-usages branch from fcd9b24 to 0f825f1 Compare January 26, 2026 14:10
Base automatically changed from devin/1769178292-cleanup-features-repository to devin/1769164663-split-flag-repositories January 26, 2026 14:12
@eunjae-lee eunjae-lee force-pushed the chore/replace-feature-repository-usages branch from 0f825f1 to 3943f48 Compare January 26, 2026 14:13
Base automatically changed from devin/1769164663-split-flag-repositories to main February 2, 2026 13:26
@devin-ai-integration devin-ai-integration Bot force-pushed the chore/replace-feature-repository-usages branch from 3943f48 to c0ff989 Compare February 2, 2026 14:17
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 2, 2026

E2E results are ready!

Migrate from the legacy FeaturesRepository pattern to separate DI-based repositories:
- Add checkIfFeatureIsEnabledGlobally to IFeatureRepository
- Add getTeamsWithFeatureEnabled to ITeamFeatureRepository
- Update CalendarSubscriptionService to use featureRepository, teamFeatureRepository, and userFeatureRepository
- Update SelectedCalendarRepository.findNextSubscriptionBatch to filter by teamIds instead of featureIds
- Update OnboardingPathService to use DI via getFeatureRepository()
- Remove prisma parameter from OnboardingPathService callsites

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@eunjae-lee eunjae-lee force-pushed the chore/replace-feature-repository-usages branch from a8b519f to 329f75d Compare February 3, 2026 10:44
@keithwillcode keithwillcode added the core area: core, team members only label Feb 3, 2026
eunjae-lee and others added 2 commits February 3, 2026 15:08
Update CalendarSubscriptionService and SelectedCalendarRepository tests
to use the new separate repository interfaces:
- featureRepository for global feature checks
- teamFeatureRepository for team-level feature checks
- userFeatureRepository for user-level feature checks

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@eunjae-lee eunjae-lee changed the title refactor: replace the legacy feature repository usages refactor: replace FeaturesRepository with DI-based feature repositories Feb 3, 2026
Update cron and webhook routes to use the new separate repository
interfaces instead of the combined FeaturesRepository.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@pull-request-size pull-request-size Bot added size/XL and removed size/L labels Feb 3, 2026
eunjae-lee and others added 3 commits February 3, 2026 15:39
The OnboardingPathService method no longer requires a prisma argument
as it now uses DI containers internally.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update service instantiation tests to expect featureRepository,
teamFeatureRepository, and userFeatureRepository instead of the
old featuresRepository.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@eunjae-lee eunjae-lee marked this pull request as ready for review February 4, 2026 10:51
@eunjae-lee eunjae-lee requested review from a team as code owners February 4, 2026 10:51
@graphite-app graphite-app Bot added the consumer label Feb 4, 2026
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-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.

2 issues found across 21 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="packages/features/flags/repositories/PrismaFeatureRepository.ts">

<violation number="1" location="packages/features/flags/repositories/PrismaFeatureRepository.ts:73">
P2: This global feature check only needs the enabled flag, but it fetches the full FeatureDto via findBySlug. Querying all columns adds unnecessary DB I/O and data exposure. Use a targeted select for enabled.

(Based on your team's feedback about selecting only required Prisma fields.) [FEEDBACK_USED]</violation>
</file>

<file name="packages/features/calendar-subscription/lib/CalendarSubscriptionService.ts">

<violation number="1" location="packages/features/calendar-subscription/lib/CalendarSubscriptionService.ts:396">
P2: checkForNewSubscriptions no longer gates on the global cache feature flag. Because PrismaTeamFeatureRepository.getTeamsWithFeatureEnabled does not check global enablement, the subscription cron will run for team-enabled rows even when the global flag is disabled. Add a global flag guard before fetching team IDs to preserve previous behavior.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread packages/features/flags/repositories/PrismaFeatureRepository.ts Outdated
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 4, 2026

Devin AI is addressing Cubic AI's review feedback

A Devin session has been created to address the issues identified by Cubic AI.

View Devin Session

Copy link
Copy Markdown
Contributor

@supalarry supalarry left a comment

Choose a reason for hiding this comment

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

Review:

import type { PrismaClient } from "@calcom/prisma";
import { getFeatureRepository } from "@calcom/features/di/containers/FeatureRepository";

export class OnboardingPathService {
Copy link
Copy Markdown
Contributor

@supalarry supalarry Feb 5, 2026

Choose a reason for hiding this comment

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

Why are we calling getFeatureRepository within functions of OnboardingPathService instead of dependency injecting getFeatureRepository via constructor of OnboardingPathService when it is instantiated? How big of a lift it is to make that happen? Technically not scope of this PR but still wanted to note it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

it's named "Service" but I feel like it's more of a utility. So I'm not too sure if it makes sense to make OnboardingPathService DI-ed.

Comment thread packages/features/flags/repositories/PrismaTeamFeatureRepository.ts Outdated
eunjae-lee and others added 2 commits February 5, 2026 11:46
…iptions

- Use targeted select for only `enabled` field in checkIfFeatureIsEnabledGlobally
- Add global feature flag guard in checkForNewSubscriptions to avoid unnecessary
  DB queries and API calls when the cache feature is globally disabled

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@paragon-review
Copy link
Copy Markdown

paragon-review Bot commented Feb 5, 2026

Paragon: tests updated

2 updated tests generated for this PR.

Updated Tests

  • CachedTeamFeatureRepository - Additional coverage for checkIfTeamHasFeature, getEnabledFeatures, getTeamsWithFeatureEnabled, setAutoOptIn — Adding new test to existing file
  • CachedUserFeatureRepository - Additional coverage for checkIfUserHasFeature and checkIfUserHasFeatureNonHierarchical — Adding new test to existing file

Accept Changes Open in Paragon

Details

Updated Tests

  • CachedTeamFeatureRepository - Additional coverage for checkIfTeamHasFeature, getEnabledFeatures, getTeamsWithFeatureEnabled, setAutoOptIn (unit)
  • CachedUserFeatureRepository - Additional coverage for checkIfUserHasFeature and checkIfUserHasFeatureNonHierarchical (unit)

@supalarry supalarry self-requested a review February 5, 2026 10:59
@PeerRich PeerRich enabled auto-merge (squash) February 5, 2026 11:16
@PeerRich PeerRich merged commit 512002a into main Feb 6, 2026
50 of 51 checks passed
@PeerRich PeerRich deleted the chore/replace-feature-repository-usages branch February 6, 2026 09:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

consumer core area: core, team members only ready-for-e2e size/XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants