Refactor out `Plan` details from `Namespace` and `GitlabSubscription`
Summary
Namespace and GitlabSubscription models both handle a lot of details from Plan especially by inspecting Plan's constants.
This is a Feature Envy issue that causes a lot of changes to be made or checked when something changes in Plan. E.g. recently we made some changes to introduce an explicit "free plan" record and changes leaked into related models. We should instead have Plan's collaborators to use class/instance methods rather than constants.
Improvements
Plan model is very small today but some domain logic related to it is scattered around models. We are also seeing some knowledge duplication between Plan::ALL_HOSTED_PLANS and Namespace::PLANS which violates the SSOT principle.
Some refactorings:
-
GitlabSubscription#has_a_paid_hosted_plan?could useplan.paid_hosted?instead of comparing strings withplan_name. -
GitlabSubscription#upgradable?could useplan.upgradable?instead of being coupled toplan_name != Plan::PAID_HOSTED_PLANS[-1] -
GitlabSubscription#plan_code=could usePlan.for_name(name)returning aPlan.freeifname.nil? -
GiltabSubscription.with_a_paid_hosted_planshould instead merge aPlan.paid_hostedscope instead of dealing withPlan's details -
Namespace#*_plan?should be moved toPlanand define a delegation toNamespace#actual_plan -
Namespace#eligible_for_trial?should useactual_plan.eligible_for_trial?rather than implementing thisPlan's policy itself. -
Namespace#trial_expired?should simply delegate toactual_plan.free?instead ofactual_plan_name == Plan::FREE -
Namespace#plan=could usePlan.for_name(name). However, we have the same code inGitlabSubscription#plan_code=but this instance does not default tofreeplan. Is this expected? Is it a bug? Seems like the should work exactly the same now that we havePlan.freeas explicit record. This code should then by DRYed.
Risks
Because we are refactoring code around Plan we need to be careful not to introduce bugs as it will have direct impact in customer's experience especially for billed customers.
I think this refactoring will consolidate policies around Plan, hence reduce changes of introducing bugs in the long term.
Optional: Missing test coverage
Need to check how good test coverage is around these 3 involved models.