feat: locked-feature upgrade prompts route to billing + track upgrade interest (v0.81.0)
UpgradeDialog's CTA now sends users to Settings > Billing (with a feature-specific banner) instead of a generic support-ticket prefill, and fires a best-effort tracking beacon recording which feature triggered the click. New feature_upgrade_clicks table + Admin > Insights chart ("Most-requested locked features") gives admins visibility into which locked features actually drive upgrade interest.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
CREATE TABLE "feature_upgrade_clicks" (
|
||||
"id" text PRIMARY KEY NOT NULL,
|
||||
"user_id" text NOT NULL,
|
||||
"feature_key" text NOT NULL,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "feature_upgrade_clicks" ADD CONSTRAINT "feature_upgrade_clicks_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -456,6 +456,13 @@
|
||||
"when": 1784885885146,
|
||||
"tag": "0064_thick_drax",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 65,
|
||||
"version": "7",
|
||||
"when": 1784894764837,
|
||||
"tag": "0065_cooing_carnage",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -18,3 +18,17 @@ export const featureFlags = pgTable("feature_flags", {
|
||||
export const featureFlagsRelations = relations(featureFlags, ({ one }) => ({
|
||||
updatedBy: one(users, { fields: [featureFlags.updatedById], references: [users.id] }),
|
||||
}));
|
||||
|
||||
// One row per "I'm interested" click from a locked-feature upgrade dialog —
|
||||
// lets admins see which locked features are actually driving upgrade
|
||||
// interest (Admin -> Insights), not just that upgrades happen.
|
||||
export const featureUpgradeClicks = pgTable("feature_upgrade_clicks", {
|
||||
id: text("id").primaryKey(),
|
||||
userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
|
||||
featureKey: text("feature_key").notNull(),
|
||||
createdAt: timestamp("created_at").notNull().defaultNow(),
|
||||
});
|
||||
|
||||
export const featureUpgradeClicksRelations = relations(featureUpgradeClicks, ({ one }) => ({
|
||||
user: one(users, { fields: [featureUpgradeClicks.userId], references: [users.id] }),
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user