Skip to content

Commit 4422b2e

Browse files
committed
refactor(services): tighten billing lifecycle scenario types and drop single-use helpers
1 parent 1308141 commit 4422b2e

1 file changed

Lines changed: 24 additions & 21 deletions

File tree

packages/services/src/billing-lifecycle.ts

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { db, eq, websites as websitesTable } from "@databuddy/db";
1+
import { db, eq, websites } from "@databuddy/db";
22
import { clickHouse, TABLE_NAMES } from "@databuddy/db/clickhouse";
33
import { PLAN_IDS } from "@databuddy/shared/types/features";
44
import { splitTraits, upsertProfile } from "./identity";
55

6-
const SCENARIO_EVENTS: Record<string, string> = {
6+
const SCENARIO_EVENTS = {
77
new: "subscription_started",
88
upgrade: "plan_upgraded",
99
downgrade: "plan_downgraded",
@@ -12,20 +12,21 @@ const SCENARIO_EVENTS: Record<string, string> = {
1212
expired: "subscription_expired",
1313
past_due: "payment_past_due",
1414
scheduled: "plan_change_scheduled",
15-
};
15+
} as const;
1616

17-
const PLAN_SETTING_SCENARIOS = new Set([
17+
export type BillingScenario = keyof typeof SCENARIO_EVENTS;
18+
19+
const PLAN_SETTING_SCENARIOS = new Set<BillingScenario>([
1820
"new",
1921
"upgrade",
2022
"downgrade",
2123
"renew",
2224
]);
2325

24-
function selfWebsiteId(): string {
25-
return process.env.SELF_ANALYTICS_WEBSITE_ID || "";
26-
}
27-
28-
function planAfterScenario(scenario: string, planId: string): string | null {
26+
function planAfterScenario(
27+
scenario: BillingScenario,
28+
planId: string
29+
): string | null {
2930
if (PLAN_SETTING_SCENARIOS.has(scenario)) {
3031
return planId;
3132
}
@@ -42,9 +43,9 @@ async function insertLifecycleEvent(
4243
properties: Record<string, string>
4344
): Promise<void> {
4445
const [website] = await db
45-
.select({ organizationId: websitesTable.organizationId })
46-
.from(websitesTable)
47-
.where(eq(websitesTable.id, websiteId))
46+
.select({ organizationId: websites.organizationId })
47+
.from(websites)
48+
.where(eq(websites.id, websiteId))
4849
.limit(1);
4950
if (!website) {
5051
return;
@@ -69,15 +70,14 @@ async function insertLifecycleEvent(
6970
export async function recordPlanChange(opts: {
7071
customerId: string;
7172
planId: string;
72-
scenario: string;
73+
scenario: BillingScenario;
7374
}): Promise<void> {
74-
const websiteId = selfWebsiteId();
75+
const websiteId = process.env.SELF_ANALYTICS_WEBSITE_ID;
7576
if (!websiteId) {
7677
return;
7778
}
7879

7980
const plan = planAfterScenario(opts.scenario, opts.planId);
80-
const eventName = SCENARIO_EVENTS[opts.scenario];
8181

8282
await Promise.all([
8383
plan
@@ -88,11 +88,14 @@ export async function recordPlanChange(opts: {
8888
"billing"
8989
)
9090
: Promise.resolve(null),
91-
eventName
92-
? insertLifecycleEvent(websiteId, opts.customerId, eventName, {
93-
plan: opts.planId,
94-
scenario: opts.scenario,
95-
})
96-
: Promise.resolve(),
91+
insertLifecycleEvent(
92+
websiteId,
93+
opts.customerId,
94+
SCENARIO_EVENTS[opts.scenario],
95+
{
96+
plan: opts.planId,
97+
scenario: opts.scenario,
98+
}
99+
),
97100
]);
98101
}

0 commit comments

Comments
 (0)