feat: add BillingCacheService with 1-hour TTL for team subscription data#23934
feat: add BillingCacheService with 1-hour TTL for team subscription data#23934ThyMinimalDev merged 10 commits intomainfrom
Conversation
- Create BillingCacheService following CalendarsCacheService pattern - Use teamId-based cache keys with 1-hour TTL (3,600,000 ms) - Integrate caching into getBillingData method in BillingService - Add cache invalidation to all webhook handlers: - handleStripeSubscriptionDeleted - handleStripePaymentSuccess - handleStripePaymentFailed - handleStripePaymentPastDue - handleStripeCheckoutEvents - Add cache invalidation to cancelTeamSubscription method - Add RedisModule import to billing module - Add BillingCacheService to billing module providers - Add findTeamByPlatformBillingId method to OrganizationsRepository for cache invalidation Co-Authored-By: morgan@cal.com <morgan@cal.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
- Extract IBillingService interface with all public methods - Create BillingServiceCachingProxy that implements caching logic - Remove all caching logic from original BillingService - Simplify cache invalidation using billing.id = team.id - Update module to use proxy with proper dependency injection - Update controller to inject proxy interface - Remove unused BillingService import from controller This follows the proxy pattern requested in PR feedback, separating caching concerns from core billing logic for better maintainability. Co-Authored-By: morgan@cal.com <morgan@cal.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
|
Important Review skippedBot user detected. To trigger a single review, invoke the You can disable this status message by setting the Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Please see the documentation for more information. Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).Please share your feedback with us on this Discord post. Comment |
E2E results are ready! |
2eff232 to
a93deea
Compare
apps/api/v2/src/modules/billing/services/billing-service-caching-proxy.ts
Outdated
Show resolved
Hide resolved
…, prisma (#23832) * eslint rule * improve * fix * improve msg
- Remove BillingCacheService abstraction as suggested by @keithwillcode - Move cache methods directly into proxy as private methods - Update proxy to inject RedisService directly - Move BillingData type to interface for better type safety - Remove BillingCacheService from module providers - Delete unused billing-cache.service.ts file This simplifies the architecture by removing unnecessary abstraction and follows standard caching proxy patterns. Co-Authored-By: morgan@cal.com <morgan@cal.com>
18d49de to
c92d169
Compare
…ata (calcom#23934) * feat: add BillingCacheService with 1-hour TTL for team subscription data - Create BillingCacheService following CalendarsCacheService pattern - Use teamId-based cache keys with 1-hour TTL (3,600,000 ms) - Integrate caching into getBillingData method in BillingService - Add cache invalidation to all webhook handlers: - handleStripeSubscriptionDeleted - handleStripePaymentSuccess - handleStripePaymentFailed - handleStripePaymentPastDue - handleStripeCheckoutEvents - Add cache invalidation to cancelTeamSubscription method - Add RedisModule import to billing module - Add BillingCacheService to billing module providers - Add findTeamByPlatformBillingId method to OrganizationsRepository for cache invalidation Co-Authored-By: morgan@cal.com <morgan@cal.com> * refactor: implement BillingServiceCachingProxy pattern - Extract IBillingService interface with all public methods - Create BillingServiceCachingProxy that implements caching logic - Remove all caching logic from original BillingService - Simplify cache invalidation using billing.id = team.id - Update module to use proxy with proper dependency injection - Update controller to inject proxy interface - Remove unused BillingService import from controller This follows the proxy pattern requested in PR feedback, separating caching concerns from core billing logic for better maintainability. Co-Authored-By: morgan@cal.com <morgan@cal.com> * chore: add e2e for billing check * chore: eslint rule for blocking importing features from appstore, lib, prisma (calcom#23832) * eslint rule * improve * fix * improve msg * chore: fix any types set by devin * fix: add mising expect in test * refactor: move cache methods into BillingServiceCachingProxy - Remove BillingCacheService abstraction as suggested by @keithwillcode - Move cache methods directly into proxy as private methods - Update proxy to inject RedisService directly - Move BillingData type to interface for better type safety - Remove BillingCacheService from module providers - Delete unused billing-cache.service.ts file This simplifies the architecture by removing unnecessary abstraction and follows standard caching proxy patterns. Co-Authored-By: morgan@cal.com <morgan@cal.com> * fix: test and legacy starter --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: morgan@cal.com <morgan@cal.com> Co-authored-by: Benny Joo <sldisek783@gmail.com> Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
What does this PR do?
This PR implements Redis-based caching for the BillingService using a proxy pattern, following reviewer feedback to remove the
BillingCacheServiceabstraction. The implementation adds a 1-hour cache for billing subscription checks with proper cache invalidation when webhooks are received orcancelTeamSubscriptionis called.Key Changes:
IBillingServiceinterface for type safety and dependency injectionBillingServiceCachingProxythat directly usesRedisServiceBillingCacheServiceabstraction layerBillingDataArchitecture: The proxy intercepts
getBillingData()calls, checks Redis cache first, falls back to the underlying service on cache miss, and stores the result with 1-hour TTL. Cache is invalidated on billing-related events.Visual Demo (For contributors especially)
N/A - This is an internal caching optimization with no user-facing changes.
Mandatory Tasks (DO NOT REMOVE)
How should this be tested?
Environment Setup:
Test Scenarios:
GET /v2/billing/{teamId}/checkmultiple times - first call should query database, subsequent calls should return cached datacancelTeamSubscriptionand verify cache is invalidatedExpected Behavior:
Checklist
IBillingServicemethodsBillingDatatype matches actual service return typesLink to Devin run: https://app.devin.ai/sessions/adaf284159974bde9c4695f62e310f87
Requested by: morgan@cal.com
This refactor addresses Keith's feedback to simplify the architecture by removing the intermediate
BillingCacheServiceand having the proxy interact directly with Redis.