Implementing Dynamic GitHub Sync Limits Based on Subscription Tiers

Our landing project, which facilitates generating posts by syncing with user GitHub activity, recently required a more refined approach to feature access. To enhance our subscription model and ensure fair usage, we introduced dynamic GitHub sync limits based on a user's subscription plan.

The Scenario

Previously, all users might have had a uniform or basic GitHub sync limit. The objective was to implement a tiered system for historical GitHub data synchronization:

  • Free users: A limit of 7 days of historical sync.
  • Monthly subscribers: An extended limit of 3 months (90 days) of historical sync.
  • Annual or Lifetime plan holders: Unlimited historical data synchronization.

This change aimed to provide clearer value propositions for each subscription tier and encourage upgrades while ensuring free users still had a functional, albeit limited, experience.

Identifying User Tiers

The foundational step for this feature was to accurately identify a user's subscription status within the application. For our Laravel application, this meant enhancing the User model with methods to check subscription types. This centralizes the logic and makes it reusable across different parts of the application.

Here’s a simplified example of how such methods might be implemented in a Laravel User model:

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Cashier\Billable;

class User extends Authenticatable
{
    use Billable;

    // ... other properties and methods

    /**
     * Determine if the user is subscribed to a monthly plan only.
     *
     * @return bool
     */
    public function isSubscribedToMonthlyOnly(): bool
    {
        // Example logic: check if subscribed and not on an annual/lifetime plan
        return $this->subscribed('default') && 
               !$this->subscription('default')->onTrial() && 
               !$this->hasAnnualOrLifetimePlan();
    }

    /**
     * Determine if the user has an annual or lifetime plan.
     *
     * @return bool
     */
    public function hasAnnualOrLifetimePlan(): bool
    {
        // Example logic: check for specific plan names or features
        return $this->subscribedToPlan('annual-plan', 'default') || 
               $this->subscribedToPlan('lifetime-plan', 'default');
    }

    /**
     * Get the GitHub sync limit in days based on subscription.
     *
     * @return int|null
     */
    public function getGithubSyncLimitDays(): ?int
    {
        if ($this->hasAnnualOrLifetimePlan()) {
            return null; // Unlimited
        } elseif ($this->isSubscribedToMonthlyOnly()) {
            return 90; // 3 months
        } else {
            return 7; // Free tier
        }
    }
}

This code snippet illustrates how the User model can encapsulate the logic for determining subscription status and, subsequently, the specific GitHub sync limit. isSubscribedToMonthlyOnly() and hasAnnualOrLifetimePlan() provide clear predicates, and getGithubSyncLimitDays() centralizes the decision-making for the actual limit.

Applying the Limits

With the User model capable of identifying subscription tiers, the next step was to integrate this logic into the user interface. Specifically, the datepickers used in the Dashboard and PostGenerator components were updated to respect these new limits. This involved dynamically setting minimum and maximum selectable dates based on the user's plan.

Furthermore, to ensure a smooth user experience, clear helper text and error messages were added. These messages guide users on their current sync capabilities and explain why certain date ranges might be unavailable, subtly encouraging them to consider upgrading their plans for more extensive features. The entire implementation also included comprehensive testing for subscription type detection and translations (EN, ES, FR, DE) to support our global user base.

The Outcome

By implementing this dynamic limit system, users now encounter a transparent and fair feature set directly aligned with their subscription. Free users understand their limitations, while paying subscribers receive the value they expect, enhancing both user satisfaction and the overall integrity of our subscription model.

The Lesson

Tailoring feature access based on subscription tiers is a powerful strategy for SaaS growth and user management. Centralizing subscription logic within your application's core models, like the User model in Laravel, ensures consistency, maintainability, and simplifies the process of extending or modifying feature gating in the future. Always provide clear user feedback when applying such limits to guide their experience effectively.

Implementing Dynamic GitHub Sync Limits Based on Subscription Tiers
GERARDO RUIZ

GERARDO RUIZ

Author

Share: