Files
ihaleist/server/entitlements.mjs
T

109 lines
3.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 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;
}
}