Compare commits
3 Commits
2d7b65c77a
...
c5769e2fbb
| Author | SHA1 | Date | |
|---|---|---|---|
| c5769e2fbb | |||
|
|
43b6ceca3e | ||
|
|
4acfd27ab1 |
@@ -164,7 +164,12 @@ export async function ListemIcerik({
|
||||
kilitAcilisi={kilitAcilisi}
|
||||
kilitliBaslangic={user.hasPaket ? undefined : ACIK_SATIR}
|
||||
kredi={user.creditBalance}
|
||||
raporKredi={RAPOR_KREDI}
|
||||
raporKredi={
|
||||
/* Liste ve revizyon pakete dâhil (bkz. rapor-actions.ts'teki
|
||||
maliyet): paketliye bedel 0 iner ki arayüz sunucunun yaptığını
|
||||
söylesin. */
|
||||
user.hasPaket ? 0 : RAPOR_KREDI
|
||||
}
|
||||
sohbetGecmisi={sohbetGecmisi as Mesaj[]}
|
||||
ozet={danismanOzeti}
|
||||
ilkYorum={ilkYorum}
|
||||
|
||||
@@ -6,10 +6,12 @@
|
||||
// alanların değiştiğini gösterir ve listeyi yeni tercihlere göre yeniden
|
||||
// kurmayı önerir.
|
||||
//
|
||||
// Yeniden kurulum normal üretimle AYNI kapıdan geçer (listeOlustur): 3 kredi,
|
||||
// aynı requestId idempotency'si, aynı kredi-yetersiz/iade davranışı. Ayrı bir
|
||||
// "güncelleme" ürünü ya da indirimli yol yok — kullanıcı yeni bir liste alıyor,
|
||||
// bedeli de yeni liste bedeli.
|
||||
// Yeniden kurulum normal üretimle AYNI kapıdan geçer (listeOlustur): aynı
|
||||
// bedel, aynı requestId idempotency'si, aynı kredi-yetersiz/iade davranışı.
|
||||
// Ayrı bir "güncelleme" ürünü ya da indirimli yol yok — kullanıcı yeni bir
|
||||
// liste alıyor, bedeli de yeni liste bedeli. Paketli kullanıcıda o bedel 0:
|
||||
// liste ve revizyon pakete dâhil (raporKredi prop'u listem-icerik.tsx'te
|
||||
// koşullanır), krediler yalnız danışman sorusuna gider.
|
||||
//
|
||||
// Renk: modalın kabuğu marka primary'si (bg-primary/10 ikon hücresi), ana
|
||||
// aksiyon ise ürünün CTA turuncusu — kilidi açan, kredi harcayan, ödemeye
|
||||
@@ -127,6 +129,10 @@ export function TercihDegistiModali({
|
||||
}
|
||||
|
||||
const krediYeter = kredi >= raporKredi;
|
||||
// Paketliye liste ve revizyon dâhil olduğu için bedel 0 iner (raporKredi
|
||||
// prop'u listem-icerik.tsx'te koşullanıyor). Tek türetilmiş bayrak: modalın
|
||||
// üç kredi cümlesi buna bakar, kredi mantığı olduğu gibi kalır.
|
||||
const ucretsiz = raporKredi === 0;
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
@@ -184,8 +190,17 @@ export function TercihDegistiModali({
|
||||
tablosunda zaten duruyor; açıklama yalnızca sonucu ve
|
||||
bedeli söylüyor. */}
|
||||
<DialogDescription>
|
||||
Listen eski tercihlerinle kuruldu. Yeni liste bunun yerine
|
||||
geçer ve {raporKredi} kredi düşer.
|
||||
{ucretsiz ? (
|
||||
<>
|
||||
Listen eski tercihlerinle kuruldu. Yeni liste bunun yerine
|
||||
geçer; güncelleme paketine dâhil, kredi düşmez.
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
Listen eski tercihlerinle kuruldu. Yeni liste bunun yerine
|
||||
geçer ve {raporKredi} kredi düşer.
|
||||
</>
|
||||
)}
|
||||
</DialogDescription>
|
||||
</div>
|
||||
</div>
|
||||
@@ -245,7 +260,7 @@ export function TercihDegistiModali({
|
||||
{durum.ad === "hata" ? (
|
||||
<p className="text-sm text-red-700">{durum.mesaj}</p>
|
||||
) : null}
|
||||
{!krediYeter && durum.ad !== "hata" ? (
|
||||
{!ucretsiz && !krediYeter && durum.ad !== "hata" ? (
|
||||
<p className="text-xs text-slate-500">
|
||||
Güncelleme {raporKredi} kredi; bakiyen {kredi} kredi.
|
||||
</p>
|
||||
@@ -272,7 +287,9 @@ export function TercihDegistiModali({
|
||||
onClick={() => void guncelle()}
|
||||
className="cursor-pointer bg-orange-500 text-white transition-[background-color,transform] duration-200 active:scale-[0.97] hover:bg-orange-600"
|
||||
>
|
||||
Listemi güncelle — {raporKredi} kredi
|
||||
{ucretsiz
|
||||
? "Listemi güncelle"
|
||||
: `Listemi güncelle — ${raporKredi} kredi`}
|
||||
<ArrowRight className="size-4" aria-hidden />
|
||||
</Button>
|
||||
) : (
|
||||
|
||||
@@ -149,10 +149,18 @@ async function listeOlusturKilitli(
|
||||
params: RaporParams,
|
||||
requestId: string,
|
||||
): Promise<ListeSonuc> {
|
||||
// Paket vaadi (docs/urun/vizyon.md): liste ve revizyon pakete dâhil; krediler
|
||||
// yalnız danışman sorusu için. Çağrı BİLEREK duruyor — ledger'daki
|
||||
// UNIQUE(reason, ref_id) (appdb/schema.ts:133) üretimin tek idempotency
|
||||
// çapası; paketliye delta 0 satır yazılır, aynı requestId ikinci kez
|
||||
// DUPLICATE döner. hasPaket tek yerden okunur (zaten elimizdeki user
|
||||
// nesnesi) ki harcama ile iade aynı değeri görsün.
|
||||
const maliyet = user.hasPaket ? 0 : RAPOR_KREDI;
|
||||
|
||||
// 3 kredi düş (idempotent: aynı requestId ile retry çifte harcamaz)
|
||||
const harcama = await spendCredits({
|
||||
userId: user.id,
|
||||
amount: RAPOR_KREDI,
|
||||
amount: maliyet,
|
||||
reason: "report_generate",
|
||||
refId: requestId,
|
||||
});
|
||||
@@ -208,10 +216,13 @@ async function listeOlusturKilitli(
|
||||
try {
|
||||
sonuc = await raporUret(params);
|
||||
} catch (err) {
|
||||
// Üretim başarısız → krediyi iade et
|
||||
// Üretim başarısız → krediyi iade et. Satır paketlide de yazılır (delta 0):
|
||||
// yukarıdaki DUPLICATE dalı "önceki deneme başarısız mıydı" sorusunu tam
|
||||
// olarak bu refund kaydının varlığıyla cevaplıyor. Tutar koşullu, yoksa
|
||||
// harcaması 0 olan paketliye her başarısız denemede bedava kredi yazardık.
|
||||
await grantCredits({
|
||||
userId: user.id,
|
||||
delta: RAPOR_KREDI,
|
||||
delta: maliyet,
|
||||
reason: "refund",
|
||||
refId: requestId,
|
||||
}).catch(() => {});
|
||||
@@ -240,7 +251,7 @@ async function listeOlusturKilitli(
|
||||
rapor: user.hasPaket ? sonuc : raporMaskele(sonuc),
|
||||
params,
|
||||
revisionCount: 0,
|
||||
kredi: user.creditBalance - RAPOR_KREDI,
|
||||
kredi: user.creditBalance - maliyet,
|
||||
hasPaket: user.hasPaket,
|
||||
};
|
||||
}
|
||||
@@ -282,9 +293,15 @@ export async function listeRevize(input: {
|
||||
const params = rapor.params as RaporParams;
|
||||
const onceki = rapor.result as RaporSonuc;
|
||||
|
||||
// Revizyon pakete dâhil (bkz. listeOlusturKilitli'deki aynı not). Yukarıdaki
|
||||
// hasPaket kapısı yüzünden burada maliyet her zaman 0; ifade yine de koşullu
|
||||
// yazılıyor ki kapı ileride gevşerse paketsiz kullanıcıdan ücret düşmeye
|
||||
// devam etsin. Revizyon hakkını MAX_REVIZYON sayacı sınırlıyor, kredi değil.
|
||||
const maliyet = user.hasPaket ? 0 : RAPOR_KREDI;
|
||||
|
||||
const harcama = await spendCredits({
|
||||
userId: user.id,
|
||||
amount: RAPOR_KREDI,
|
||||
amount: maliyet,
|
||||
reason: "report_revision",
|
||||
refId: input.requestId,
|
||||
});
|
||||
@@ -336,9 +353,11 @@ export async function listeRevize(input: {
|
||||
listeOzetiCikar(onceki, params.sira),
|
||||
);
|
||||
} catch (err) {
|
||||
// İade satırı burada da yazılır (paketlide delta 0) — DUPLICATE dalındaki
|
||||
// "önceki deneme başarısızdı" çıkarımı buna dayanıyor.
|
||||
await grantCredits({
|
||||
userId: user.id,
|
||||
delta: RAPOR_KREDI,
|
||||
delta: maliyet,
|
||||
reason: "refund",
|
||||
refId: input.requestId,
|
||||
}).catch(() => {});
|
||||
@@ -360,7 +379,7 @@ export async function listeRevize(input: {
|
||||
rapor: sonuc,
|
||||
params,
|
||||
revisionCount: rapor.revisionCount + 1,
|
||||
kredi: user.creditBalance - RAPOR_KREDI,
|
||||
kredi: user.creditBalance - maliyet,
|
||||
hasPaket: true,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user