Scaling Subscriptions: Implementing Flexible Plan and Agent Management in Inmotech-Backend

Imagine a gym membership system where every family member needs their own access, but the family's main plan dictates how many members can join and when their access expires. This challenge is similar to what we tackled in Inmotech-Backend, enhancing our subscription management to support more flexible agency and agent-level plans.

The Challenge: From Static to Dynamic

Previously, our subscription model might have been simpler, perhaps focusing solely on agency-level plans. However, as our platform grew, the need arose for greater granularity. Agencies required the ability to manage a specific number of agents under a given plan, with each agent having their own distinct subscription, all while respecting an overall agency plan expiration.

This meant our existing Plan and Agencia (Agency) entities needed significant enhancements, and a new Suscripcion (Subscription) model had to be introduced to track individual agents' access.

The Solution: A Granular Subscription Model

To address this, we introduced several key features:

  • Plan.maxAgentes: This new attribute on the Plan entity defines the maximum number of agents an agency can provision under that specific plan. It acts as a hard limit, preventing agencies from exceeding their purchased capacity.
  • Agencia.fechaExpiracionPlan: Each agency now has a fechaExpiracionPlan (plan expiration date). This date dictates the end of the agency's current plan and, by extension, affects all individual agent subscriptions linked to that agency.
  • Individual Suscripcion for Agents: Instead of a single agency-wide subscription, each Agente (Agent) now receives their own Suscripcion object. This allows for individual tracking of an agent's active status, features, and links directly to the agency's overarching plan and its constraints.
  • AgencyPlanModel: To tie everything together, an AgencyPlanModel was developed, representing the comprehensive view of an agency's plan, its associated limits, and the status of its agents' subscriptions.

This new structure provides the flexibility needed for agencies to upgrade or downgrade plans, and for agents to join or leave, all within a clear, governed framework.

Implementing the Logic

Managing these new entities and their relationships required careful design, leveraging patterns like the Repository Pattern for data persistence and retrieval. When an agency attempts to add a new agent, or when an existing agent's subscription is renewed, the system now performs several checks:

  1. Agent Limit Check: Does the agency's current Plan allow for another agent (maxAgentes)?
  2. Plan Expiration Check: Is the agency's fechaExpiracionPlan still valid? An agent cannot have an active subscription if the agency's plan has expired.

Here's a simplified Java example demonstrating how such a check might be integrated when creating a new agent subscription:

public class SubscriptionService {

    private AgentRepository agentRepository; // Injected via constructor or Spring @Autowired
    private AgencyRepository agencyRepository;
    private PlanRepository planRepository;

    public Subscription createAgentSubscription(String agencyId, String agentName) throws Exception {
        Agency agency = agencyRepository.findById(agencyId);
        if (agency == null) {
            throw new IllegalArgumentException("Agency not found.");
        }

        Plan currentPlan = planRepository.findById(agency.getPlanId());
        if (currentPlan == null) {
            throw new IllegalStateException("Agency plan not found.");
        }

        long activeAgents = agentRepository.countActiveAgentsByAgency(agencyId);
        if (activeAgents >= currentPlan.getMaxAgents()) {
            throw new IllegalStateException("Agent limit reached for current plan.");
        }

        if (agency.getFechaExpiracionPlan().before(new Date())) {
            throw new IllegalStateException("Agency plan has expired.");
        }

        // Logic to create and persist new Agent and Subscription entities
        Agent newAgent = new Agent(agentName, agencyId);
        Subscription newSubscription = new Subscription(newAgent.getId(), currentPlan.getId(), agency.getFechaExpiracionPlan());

        agentRepository.save(newAgent);
        // subscriptionRepository.save(newSubscription); // Assuming a separate repo for subscriptions
        return newSubscription;
    }
}

This code snippet illustrates how the SubscriptionService would use repositories to fetch Agency and Plan data, perform validation based on maxAgentes and fechaExpiracionPlan, and then proceed with creating the Agent and Subscription.

The Benefits

This refactoring provides significant advantages:

  • Enhanced Flexibility: Agencies can now pick plans that precisely match their operational scale.
  • Improved Billing Accuracy: Individual subscriptions allow for more granular tracking and billing.
  • Scalability: The modular approach makes it easier to introduce new plan features or subscription types in the future.
  • Clearer Data Model: The relationships between plans, agencies, agents, and their subscriptions are now explicit and well-defined.

By building this more robust and flexible subscription infrastructure, we've laid the groundwork for future growth and more tailored service offerings within Inmotech-Backend.


Generated with Gitvlg.com

Scaling Subscriptions: Implementing Flexible Plan and Agent Management in Inmotech-Backend
JAIME ANDRÉS MONSERRATE VILLA

JAIME ANDRÉS MONSERRATE VILLA

Author

Share: