import { betterAuth } from "better-auth"; import { drizzleAdapter } from "better-auth/adapters/drizzle"; import { magicLink } from "better-auth/plugins"; import { appDb, schema } from "./appdb"; import { grantCredits, DENEME_KREDISI } from "./credits"; import { magicLinkEpostasi } from "./eposta"; import { epostaGonder } from "./eposta-gonder"; async function sendMagicLinkEmail(email: string, url: string) { if (process.env.NODE_ENV !== "production") { // Dev paneli "anında giriş" için son üretilen linki yakalar (bkz. // src/lib/dev/actions.ts) — prod'da asla çalışmaz. (globalThis as { __sonMagicLink?: string }).__sonMagicLink = url; } if (!process.env.RESEND_API_KEY) { // Dev fallback: Resend anahtarı yoksa linki terminale yaz console.log(`\n[giris] Magic link for ${email}:\n${url}\n`); return; } // Gönderim hatası better-auth'a fırlatılır — aksi halde kullanıcı // "gönderildi" ekranını görür ama mail hiç çıkmaz. await epostaGonder(email, magicLinkEpostasi(url)); } export const auth = betterAuth({ baseURL: process.env.BETTER_AUTH_URL ?? "http://localhost:3000", secret: process.env.BETTER_AUTH_SECRET, database: drizzleAdapter(appDb, { provider: "sqlite", schema: { user: schema.user, session: schema.session, account: schema.account, verification: schema.verification, }, }), session: { // Session'ı imzalı cookie'de önbelle: her istekte session tablosu // sorgusu yapılmaz. Kredi/paket tazeliği getCurrentUser()'daki ayrı // user sorgusuyla korunur (src/lib/session.ts). cookieCache: { enabled: true, maxAge: 5 * 60 }, }, user: { additionalFields: { creditBalance: { type: "number", defaultValue: 0, input: false }, hasPaket: { type: "boolean", defaultValue: false, input: false }, }, }, socialProviders: { google: { clientId: process.env.GOOGLE_CLIENT_ID ?? "", clientSecret: process.env.GOOGLE_CLIENT_SECRET ?? "", }, }, plugins: [ magicLink({ sendMagicLink: async ({ email, url }) => { await sendMagicLinkEmail(email, url); }, }), ], databaseHooks: { user: { create: { after: async (newUser) => { // refId = userId → UNIQUE(reason, refId) ile tek seferlik await grantCredits({ userId: newUser.id, delta: DENEME_KREDISI, reason: "trial_grant", refId: newUser.id, }); }, }, }, }, }); export type Session = typeof auth.$Infer.Session;