···2020# Origin - full URL of your app
2121# Must match exactly where users access your app
2222# ORIGIN=https://thistle.app
2323+2424+# Polar.sh payment stuff
2525+# Get your access token from https://polar.sh/settings (or sandbox.polar.sh for testing)
2626+POLAR_ACCESS_TOKEN=XXX
2727+# Get product ID from your Polar dashboard (create a product first)
2828+POLAR_PRODUCT_ID=3f1ab9f9-d573-49d4-ac0a-a78bfb06c347
2929+# Redirect URL after successful checkout (use {CHECKOUT_ID} placeholder)
3030+POLAR_SUCCESS_URL=http://localhost:3000/checkout?checkout_id={CHECKOUT_ID}
3131+# Webhook secret for verifying Polar webhook signatures (get from Polar dashboard)
3232+POLAR_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxx
3333+3434+# Environment (set to 'production' in production)
3535+NODE_ENV=development
···180180 ALTER TABLE class_waitlist DROP COLUMN section;
181181 `,
182182 },
183183+ {
184184+ version: 6,
185185+ name: "Add subscriptions table for Polar integration",
186186+ sql: `
187187+ -- Subscriptions table
188188+ CREATE TABLE IF NOT EXISTS subscriptions (
189189+ id TEXT PRIMARY KEY,
190190+ user_id INTEGER NOT NULL,
191191+ customer_id TEXT NOT NULL,
192192+ status TEXT NOT NULL,
193193+ current_period_start INTEGER,
194194+ current_period_end INTEGER,
195195+ cancel_at_period_end BOOLEAN DEFAULT 0,
196196+ canceled_at INTEGER,
197197+ created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
198198+ updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
199199+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
200200+ );
201201+202202+ CREATE INDEX IF NOT EXISTS idx_subscriptions_user_id ON subscriptions(user_id);
203203+ CREATE INDEX IF NOT EXISTS idx_subscriptions_status ON subscriptions(status);
204204+ CREATE INDEX IF NOT EXISTS idx_subscriptions_customer_id ON subscriptions(customer_id);
205205+ `,
206206+ },
183207];
184208185209function getCurrentVersion(): number {
···366366 role: UserRole;
367367 last_login: number | null;
368368 transcription_count: number;
369369+ subscription_status: string | null;
370370+ subscription_id: string | null;
369371}
370372371373export function getAllUsersWithStats(): UserWithStats[] {
···379381 u.created_at,
380382 u.role,
381383 u.last_login,
382382- COUNT(t.id) as transcription_count
384384+ COUNT(DISTINCT t.id) as transcription_count,
385385+ s.status as subscription_status,
386386+ s.id as subscription_id
383387 FROM users u
384388 LEFT JOIN transcriptions t ON u.id = t.user_id
389389+ LEFT JOIN subscriptions s ON u.id = s.user_id AND s.status IN ('active', 'trialing', 'past_due')
385390 GROUP BY u.id
386391 ORDER BY u.created_at DESC`,
387392 )