···
// Clean up expired sessions every hour
setInterval(cleanupExpiredSessions, 60 * 60 * 1000);
102
+
// Helper function to sync user subscriptions from Polar
103
+
async function syncUserSubscriptionsFromPolar(
108
+
const { polar } = await import("./lib/polar");
110
+
// Search for customer by email
111
+
const customers = await polar.customers.list({
112
+
organizationId: process.env.POLAR_ORGANIZATION_ID,
116
+
if (!customers.result.items || customers.result.items.length === 0) {
117
+
console.log(`[Sync] No Polar customer found for ${email}`);
121
+
const customer = customers.result.items[0];
123
+
// Get all subscriptions for this customer
124
+
const subscriptions = await polar.subscriptions.list({
125
+
customerId: customer.id,
128
+
if (!subscriptions.result.items || subscriptions.result.items.length === 0) {
129
+
console.log(`[Sync] No subscriptions found for customer ${customer.id}`);
133
+
// Update each subscription in the database
134
+
for (const subscription of subscriptions.result.items) {
136
+
`INSERT INTO subscriptions (id, user_id, customer_id, status, current_period_start, current_period_end, cancel_at_period_end, canceled_at, updated_at)
137
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
138
+
ON CONFLICT(id) DO UPDATE SET
139
+
user_id = excluded.user_id,
140
+
status = excluded.status,
141
+
current_period_start = excluded.current_period_start,
142
+
current_period_end = excluded.current_period_end,
143
+
cancel_at_period_end = excluded.cancel_at_period_end,
144
+
canceled_at = excluded.canceled_at,
145
+
updated_at = excluded.updated_at`,
149
+
subscription.customerId,
150
+
subscription.status,
151
+
subscription.currentPeriodStart
153
+
new Date(subscription.currentPeriodStart).getTime() / 1000,
156
+
subscription.currentPeriodEnd
158
+
new Date(subscription.currentPeriodEnd).getTime() / 1000,
161
+
subscription.cancelAtPeriodEnd ? 1 : 0,
162
+
subscription.canceledAt
163
+
? Math.floor(new Date(subscription.canceledAt).getTime() / 1000)
165
+
Math.floor(Date.now() / 1000),
171
+
`[Sync] Linked ${subscriptions.result.items.length} subscription(s) to user ${userId} (${email})`,
175
+
`[Sync] Failed to sync subscriptions for ${email}:`,
176
+
error instanceof Error ? error.message : "Unknown error",
178
+
// Don't throw - registration should succeed even if sync fails
// Sync with Whisper DB on startup
await whisperService.syncWithWhisper();
···
const user = await createUser(email, password, name);
254
+
// Attempt to sync existing Polar subscriptions
255
+
syncUserSubscriptionsFromPolar(user.id, user.email).catch(() => {
256
+
// Silent fail - don't block registration
req.headers.get("x-forwarded-for") ??
req.headers.get("x-real-ip") ??
···
return Response.json({ error: "Invalid user ID" }, { status: 400 });
1508
-
const { polar } = await import("./lib/polar");
1512
-
.query<{ email: string }, [number]>(
1513
-
"SELECT email FROM users WHERE id = ?",
1518
-
return Response.json(
1519
-
{ error: "User not found" },
1524
-
console.log(`[Admin] Looking for Polar customer with email: ${user.email}`);
1596
+
.query<{ email: string }, [number]>(
1597
+
"SELECT email FROM users WHERE id = ?",
1526
-
// Search for customer by email
1527
-
const customers = await polar.customers.list({
1528
-
organizationId: process.env.POLAR_ORGANIZATION_ID,
1529
-
query: user.email,
1533
-
`[Admin] Found ${customers.result.items?.length || 0} customer(s) matching email`,
1602
+
return Response.json(
1603
+
{ error: "User not found" },
1536
-
if (!customers.result.items || customers.result.items.length === 0) {
1537
-
return Response.json(
1538
-
{ error: "No Polar customer found with this email" },
1543
-
const customer = customers.result.items[0];
1544
-
console.log(`[Admin] Customer ID: ${customer.id}`);
1546
-
// Get all subscriptions for this customer
1547
-
const subscriptions = await polar.subscriptions.list({
1548
-
customerId: customer.id,
1552
-
`[Admin] Found ${subscriptions.result.items?.length || 0} subscription(s) for customer`,
1555
-
if (!subscriptions.result.items || subscriptions.result.items.length === 0) {
1556
-
return Response.json(
1557
-
{ error: "No subscriptions found for this customer" },
1562
-
// Update each subscription in the database
1563
-
for (const subscription of subscriptions.result.items) {
1565
-
`INSERT INTO subscriptions (id, user_id, customer_id, status, current_period_start, current_period_end, cancel_at_period_end, canceled_at, updated_at)
1566
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
1567
-
ON CONFLICT(id) DO UPDATE SET
1568
-
user_id = excluded.user_id,
1569
-
status = excluded.status,
1570
-
current_period_start = excluded.current_period_start,
1571
-
current_period_end = excluded.current_period_end,
1572
-
cancel_at_period_end = excluded.cancel_at_period_end,
1573
-
canceled_at = excluded.canceled_at,
1574
-
updated_at = excluded.updated_at`,
1578
-
subscription.customerId,
1579
-
subscription.status,
1580
-
subscription.currentPeriodStart
1582
-
new Date(subscription.currentPeriodStart).getTime() /
1586
-
subscription.currentPeriodEnd
1588
-
new Date(subscription.currentPeriodEnd).getTime() /
1592
-
subscription.cancelAtPeriodEnd ? 1 : 0,
1593
-
subscription.canceledAt
1595
-
new Date(subscription.canceledAt).getTime() / 1000,
1598
-
Math.floor(Date.now() / 1000),
1604
-
`[Admin] Synced ${subscriptions.result.items.length} subscription(s) for user ${userId} (${user.email})`,
1609
+
await syncUserSubscriptionsFromPolar(userId, user.email);
message: "Subscription synced successfully",