/** * Plan hakları ve kota uygulaması. * Önceden billing.mjs'te `sinirlar` tanımlıydı ama HİÇBİR yerde kontrol * edilmiyordu — herkes her şeyi kullanabiliyordu. Burada gerçekten uygulanır. */ import { getUser, documentUsage, listApiKeys, getData, getTrackedTenderKeys } from './user-store.mjs'; export const PLAN_HAKLARI = { ucretsiz: { ad: 'Ücretsiz', takip: 10, // takip edilebilecek ihale ekip: 1, // ekip üyesi bildirimKriteri: 1, // otomatik bildirim kriteri belgeAdet: 5, belgeBayt: 25 * 1024 * 1024, apiAnahtari: 0, ozellikler: ['arama', 'favori', 'push'], }, pro: { ad: 'Pro', takip: null, // sınırsız ekip: 5, bildirimKriteri: 10, belgeAdet: 200, belgeBayt: 2 * 1024 * 1024 * 1024, apiAnahtari: 0, ozellikler: ['arama', 'favori', 'push', 'kanban', 'rakip', 'fiyat', 'ai', 'pdf', 'eposta'], }, kurumsal: { ad: 'Kurumsal', takip: null, ekip: null, bildirimKriteri: null, belgeAdet: null, belgeBayt: 20 * 1024 * 1024 * 1024, apiAnahtari: 10, ozellikler: ['arama', 'favori', 'push', 'kanban', 'rakip', 'fiyat', 'ai', 'pdf', 'eposta', 'kirmizibayrak', 'kik', 'ted', 'api'], }, }; /** Kullanıcının etkin planı (süresi dolmuşsa ücretsize düşer). */ export function planOf(email, { isAdmin = false } = {}) { if (isAdmin) return 'kurumsal'; // yöneticiler tam erişimli const u = getUser(email); if (!u) return 'ucretsiz'; if (u.plan_bitis && new Date(u.plan_bitis) < new Date()) return 'ucretsiz'; return PLAN_HAKLARI[u.plan] ? u.plan : 'ucretsiz'; } export function haklar(email, opts) { return PLAN_HAKLARI[planOf(email, opts)] || PLAN_HAKLARI.ucretsiz; } export function ozellikVar(email, ozellik, opts) { return haklar(email, opts).ozellikler.includes(ozellik); } /** Mevcut kullanım — arayüzde "3/10" göstermek için. */ export function kullanim(email, opts) { const h = haklar(email, opts); const belge = documentUsage(email); const ekip = (getData(email, 'ekip') || []).length; const takip = getTrackedTenderKeys(email).length; // Yönetici hesapları her zaman tam erişimlidir; bu, satın alınan aboneliği // GİZLEMEMELİ — arayüz ikisini ayrı gösterebilsin diye ikisini de döndürüyoruz. const u = getUser(email); const abonelik = u && PLAN_HAKLARI[u.plan] && !(u.plan_bitis && new Date(u.plan_bitis) < new Date()) ? u.plan : 'ucretsiz'; return { plan: planOf(email, opts), planAdi: h.ad, yonetici: Boolean(opts?.isAdmin), abonelik, // gerçekten satın alınan plan abonelikAdi: PLAN_HAKLARI[abonelik]?.ad || 'Ücretsiz', abonelikVar: abonelik !== 'ucretsiz', iptalEdilebilir: Boolean(u?.stripe_sub_id) && abonelik !== 'ucretsiz', haklar: h, kullanilan: { belgeAdet: belge.adet, belgeBayt: belge.bayt, ekip, apiAnahtari: listApiKeys(email).length, takip, }, }; } /** * Kota kontrolü. Aşılırsa açıklayıcı hata fırlatır. * @param {string} tur 'ekip' | 'belgeAdet' | 'belgeBayt' | 'apiAnahtari' | 'bildirimKriteri' | 'takip' */ export function kotaKontrol(email, tur, mevcutSayi, ekleme = 1, opts) { const h = haklar(email, opts); const limit = h[tur]; if (limit === null || limit === undefined) return; // sınırsız if (mevcutSayi + ekleme > limit) { const isim = { ekip: 'ekip üyesi', belgeAdet: 'belge', belgeBayt: 'belge alanı', apiAnahtari: 'API anahtarı', bildirimKriteri: 'bildirim kriteri', takip: 'ihale takibi', }[tur] || tur; const e = new Error(`${h.ad} planında en fazla ${limit} ${isim} hakkınız var. Yükseltmek için Planlar sekmesine bakın.`); e.kod = 'KOTA_ASILDI'; e.limit = limit; e.plan = h.ad; throw e; } }