109 lines
3.8 KiB
JavaScript
109 lines
3.8 KiB
JavaScript
/**
|
||
* 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 } 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 = (getData(email, 'kanban') || []).filter?.((t) => t?.takipte)?.length ?? null;
|
||
// 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;
|
||
}
|
||
}
|