From 44c9809deb8f9b130f6e9666a1ed45b05d8b1b9e Mon Sep 17 00:00:00 2001 From: ht Date: Sun, 6 Sep 2026 13:42:25 +0300 Subject: [PATCH] Show Telegram status errors and keep setup instructions admin-only --- docs/quality/qa-telegram-status.json | 16 ++++++++ docs/quality/uygulama-durumu.md | 7 ++++ src/components/tools/TelegramBaglanti.jsx | 48 +++++++++++++++-------- tests/browser-qa.mjs | 4 ++ 4 files changed, 59 insertions(+), 16 deletions(-) create mode 100644 docs/quality/qa-telegram-status.json diff --git a/docs/quality/qa-telegram-status.json b/docs/quality/qa-telegram-status.json new file mode 100644 index 0000000..a37116b --- /dev/null +++ b/docs/quality/qa-telegram-status.json @@ -0,0 +1,16 @@ +{ + "date": "2026-09-06", + "environment": "localhost:5183 normal user, injected GET 503 then real GET", + "checks": { + "errorVisible": true, + "retryVisible": true, + "recovered": true, + "adminInstructionsHidden": true, + "oldErrorCleared": true + }, + "limits": [ + "No Telegram message or link request sent", + "Only status error recovery and normal-user configuration view tested", + "Bot pairing challenge and external delivery remain open" + ] +} diff --git a/docs/quality/uygulama-durumu.md b/docs/quality/uygulama-durumu.md index e4aada6..3fc75c7 100644 --- a/docs/quality/uygulama-durumu.md +++ b/docs/quality/uygulama-durumu.md @@ -924,3 +924,10 @@ Taslak türü seçicisine erişilebilir ad eklendi. Üretim derlemesi geçti. Ö - Usul alanı explicit usul/ihaleUsulu/alimTuru değerlerinden eşleşir; Mal Alımı değerinden Açık İhale tahmini yapılmaz. Kaynakta usul yoksa usule göre filtrelenmiş sonuçta gösterilmez. - 209 otomatik test ve derleme geçti. 81 il kapsamı, Türkçe normalizasyon, beş ölçütün taşınması, geçersiz bölge ve usul/kategori ayrımı test edildi. Yerel 5 sentetik ihalede bölge filtresi 1 Giresun kaydına daralttı; bölgeyi kaldırınca 5 kayıt geri geldi; yenileme sonrası sol panelden tekrar uygulandı. 4 kontrol qa-saved-filter-application.json içinde. - İl bazında bölgeleme coğrafi sınırın ilçelerdeki ayrıntısını temsil etmez. Gerçek kaynak usul/şehir doğruluğu ve bütün ölçütlerin birleşik tarayıcı senaryosu ayrıca kabul edilmelidir. Bu işlem bildirim aboneliği oluşturmaz. + +### Telegram durum ekranında hata ve rol görünümü — 6 Eylül 2026 +- İlk GET hatasında d=null olduğu için bölüm tamamen kayboluyordu. Yükleme/hata/yeniden deneme ekranı eklendi; bağlantı durumunun boolean alanları doğrulanır. Sonradan durum yenileme düğmesi de vardır. +- Hesap/token anahtarıyla panel ayrılır; kapalı/eski panelin yanıtı UI'ye uygulanmaz. Tek işlem kilidi, duruma göre başarı/hata mesajları ve erişilebilir status/alert rolleri eklendi. Yenileme başarısızlığı yutulup başarı gibi sunulmaz. +- Bot kurulum talimatları yalnız yöneticide gösterilir. Normal kullanıcı hizmetin etkin olmadığını ve yöneticiyle görüşmesi gerektiğini görür. Bağlama başarısı mesajının dış onay mesajını gönderildi varsayması kaldırıldı. +- 5183 yeni izole QA örneğinde ilk GET 503, ardından gerçek API yanıtıyla kurtarma sınandı. 5 kontrol geçti: hata, retry, kurtarma, normal kullanıcıda kurulum ayrıntılarının gizli olması ve hatanın temizlenmesi. Kanıt qa-telegram-status.json. Dış mesaj veya bağlama isteği gönderilmedi. +- Derleme geçti. Sunucu iş mantığı değişmediği için önceki 209 otomatik test tekrar çalıştırılmadı. Bot eşleme kodunun yaşam döngüsü ve gerçek teslim kabulü açık. diff --git a/src/components/tools/TelegramBaglanti.jsx b/src/components/tools/TelegramBaglanti.jsx index 9de12a8..7d3b847 100644 --- a/src/components/tools/TelegramBaglanti.jsx +++ b/src/components/tools/TelegramBaglanti.jsx @@ -1,4 +1,6 @@ -import React, { useEffect, useState } from 'react'; +import {useApp} from '../../context/AppContext'; +import {getToken} from '../../services/auth'; +import React, { useEffect, useState, useRef } from 'react'; import { Send, CheckCircle2, AlertTriangle, Loader2, Unplug } from 'lucide-react'; import { telegramDurum, telegramBagla, telegramTest, telegramSil } from '../../services/account'; @@ -10,22 +12,36 @@ import { telegramDurum, telegramBagla, telegramTest, telegramSil } from '../../s const kodUret = () => String(Math.floor(100000 + Math.random() * 900000)); export const TelegramBaglanti = () => { + const {authUser,isAdmin}=useApp(); + return ; +}; +const TelegramPanel = ({isAdmin}) => { const [d, setD] = useState(null); const [kod] = useState(kodUret); const [busy, setBusy] = useState(null); const [mesaj, setMesaj] = useState(null); - const yenile = () => telegramDurum().then(setD).catch((e) => setMesaj({ tur: 'hata', metin: e.message })); - useEffect(() => { yenile(); }, []); - - const calistir = async (ad, fn, basari) => { - setBusy(ad); setMesaj(null); - try { await fn(); setMesaj({ tur: 'ok', metin: basari }); await yenile(); } - catch (e) { setMesaj({ tur: 'hata', metin: e.message }); } - finally { setBusy(null); } + const alive=useRef(true),locked=useRef(false); + const yenile = async () => { + const data=await telegramDurum(); + if(typeof data.bagli!=='boolean'||typeof data.yapilandirilmis!=='boolean')throw new Error('Telegram bağlantı durumu doğrulanamadı.'); + if(alive.current)setD(data); }; + const calistir = async (ad, fn, basari) => { + if(locked.current)return;locked.current=true; + setBusy(ad);setMesaj(null); + try {await fn();if(!alive.current)return;if(ad!=='load')await yenile();if(alive.current&&basari)setMesaj({tur:'ok',metin:basari});} + catch(e){if(alive.current)setMesaj({tur:'hata',metin:e.message});} + finally{locked.current=false;if(alive.current)setBusy(null);} + }; + useEffect(()=>{alive.current=true;void calistir('load',yenile);return()=>{alive.current=false;};},[]); - if (!d) return null; + if(!d)return
+

Telegram Bildirimi

+ {busy&&

Bağlantı durumu yükleniyor…

} + {mesaj&&

{mesaj.metin}

} + +
; return (
@@ -39,19 +55,18 @@ export const TelegramBaglanti = () => {

- Yeni ihale özetleri, takipteki ihalede zeyilname/düzeltme ilanı ve sonuç - ("X firması Y'ye aldı, %Z kırım") e-postanın yanında Telegram'a da gelir. + Telegram bağlantısı ve ilgili bildirim hizmetleri etkinse ihale özetleri bu kanaldan gönderilebilir. Gönderim, okunma veya her kaynak değişikliğinin yakalanması garanti edilmez.

{!d.yapilandirilmis ? (
-

Sunucuda Telegram botu henüz tanımlı değil. Kurulum (yönetici, bir kez):

+ {isAdmin ? <>

Sunucuda Telegram botu henüz tanımlı değil. Kurulum (yönetici, bir kez):

  1. Telegram'da @BotFather'a yazın: /newbot → bir ad ve …bot ile biten kullanıcı adı verin.
  2. BotFather'ın verdiği tokenı Coolify → ihaleist → Environment'a TELEGRAM_BOT_TOKEN olarak ekleyin, Redeploy.
  3. Bu sayfa yeniden açıldığında aşağıdaki bağlama adımları görünür.
-

Token yalnızca sunucuda durur; uygulamaya girilmez.

+

Token yalnızca sunucuda durur; uygulamaya girilmez.

:

Telegram bildirim hizmeti henüz etkin değil. Kurulum için yöneticinizle görüşün.

}
) : d.bagli ? (
@@ -78,15 +93,16 @@ export const TelegramBaglanti = () => {
  • Bota şu kodu yazıp gönderin: {kod}
  • Sonra buraya dönüp Doğrula'ya basın.
  • -
    )} + {mesaj && ( -
    +
    {mesaj.tur === 'ok' ? : } {mesaj.metin}
    diff --git a/tests/browser-qa.mjs b/tests/browser-qa.mjs index 6ac8914..f243092 100644 --- a/tests/browser-qa.mjs +++ b/tests/browser-qa.mjs @@ -39,7 +39,11 @@ const qaDelivery=qaSubscriptionStore.reserveDelivery(qaReviewSub.id,{to:user.ema qaSubscriptionStore.failDelivery(qaDelivery,'Sentetik belirsiz sağlayıcı sonucu.'); qaSubscriptionStore.reserveDelivery(qaReviewSub.id,null,[]); let subscriptionFailure='read'; +let telegramFailure=true; const ui=await createServer({server:{host:'127.0.0.1',port:0,proxy:{'/api':{target:'http://127.0.0.1:'+port}}},plugins:[{name:'qa-fixtures',configureServer(server){server.middlewares.use(async(req,res,next)=>{ + if(req.url==='/qa-telegram-controls'){res.setHeader('Content-Type','text/html; charset=utf-8');res.end(`

    Yerel Telegram testi

    `);return;} + if(req.url==='/qa-telegram-recover'&&req.method==='POST'){telegramFailure=false;res.end('ok');return;} + if(req.url==='/api/me/telegram'&&req.method==='GET'&&telegramFailure){res.writeHead(503,{'Content-Type':'application/json'});res.end(JSON.stringify({success:false,error:'QA: Telegram durumu alınamadı.'}));return;} if(req.url==='/qa-subscription-controls'){res.setHeader('Content-Type','text/html; charset=utf-8');res.end(`

    Yerel abonelik testi

    `);return;} if(req.url?.startsWith('/qa-subscription-failure?')&&req.method==='POST'){subscriptionFailure=new URL(req.url,'http://localhost').searchParams.get('mode');res.end('Abonelik test durumu: '+subscriptionFailure);return;} if(req.url?.startsWith('/api/notify/subscriptions')&&((subscriptionFailure==='read'&&req.method==='GET')||(subscriptionFailure==='delete'&&req.method==='DELETE'))){res.writeHead(503,{'Content-Type':'application/json'});res.end(JSON.stringify({success:false,error:'QA: Abonelik deposuna erişilemiyor.'}));return;}