main
rb 37 lines 1.38 KB
Raw
1 # frozen_string_literal: true
2
3 # A user's siGit plan + Stripe subscription state. Source of truth is Stripe;
4 # this caches what the cloud gate needs. A user with no Subscription row is
5 # treated as Free (local-only, no cloud).
6 class Subscription < ApplicationRecord
7 belongs_to :user
8
9 enum :plan, { free: 0, pro: 1, team: 2 }
10 enum :status, { active: 0, past_due: 1, canceled: 2, trialing: 3, incomplete: 4 }
11
12 # Monthly siGit Code Cloud request allowance per plan. Tunable pricing knobs —
13 # these are the included cloud requests before the cap kicks in.
14 CLOUD_ALLOWANCE = { "pro" => 2_000, "team" => 6_000 }.freeze
15
16 # During the free trial, cap cloud usage well below the paid allowance so a
17 # trial can't run up an unbounded upstream bill. Enough to feel the product.
18 TRIAL_ALLOWANCE = 300
19
20 # Entitled to siGit Code Cloud: on a paid plan in good standing (incl. trial).
21 def entitled_to_cloud?
22 (pro? || team?) && (active? || trialing?)
23 end
24
25 # Included cloud requests for this period. The trial gets a tighter cap.
26 def cloud_allowance
27 return TRIAL_ALLOWANCE if trialing?
28
29 CLOUD_ALLOWANCE.fetch(plan, 0)
30 end
31
32 # Identifies the current billing period so usage resets each cycle. Uses the
33 # Stripe period end when known; falls back to the calendar month.
34 def billing_period_key
35 current_period_end&.utc&.to_date&.iso8601 || Time.current.utc.strftime("%Y-%m")
36 end
37 end