Ürün Bilgileri
Analiz edilecek ürünü tanımlayın. Dosya ekleyerek rakip katalog ve pazar raporlarını da dahil edebilirsiniz.
Çin OEM FOB fiyatı
Müşteriye satış fiyatı
📎
Dosya ekle veya sürükle bırak
PDF, Word, Excel, TXT, CSV · Maks 10MB
* Zorunlu · 12 ajan · ~3-4 dakika · A-H bölümleri
Kaydedilmiş Analizler
AI Analiz Akışı — 12 Ajan
0 / 12
Faz 1 — Bilgi Toplama (Paralel)
Pazar Araştırma
TAM/SAM/SOM · CAGR · Segment
—
Rekabet Analizi
Rakipler · Fiyat · Engeller
—
Tedarik Zinciri
OEM · Sertifikasyon
—
Mevzuat & Uyumluluk
CE · GTİP · Dual-use
—
Fiyatlandırma
FOB→raf · Marj analizi
—
Finansal Projeksiyon
5 yıl · ROI · CCC
—
Faz 2 — Tartışma
Savunucu
"Portföye al" argümanı
—
Eleştirmen
"Portföye alma" argümanı
—
Faz 3 — Karar & Sentez
Karar Ajanı (H)
Ağırlıklı puan · Final karar
—
Risk Analizi
Risk matrisi · Mitigasyon
—
Stratejik Uyum (G)
SWOT · Şirket uyumu
—
Rapor Sentezi
A-H bölümleri · YK özeti
—
Analiz Raporu
—
/ 100 puan
Ürün
—
Hedef Pazar
—
${(currentUser.name||'U')[0].toUpperCase()}
${currentUser.name||currentUser.email}
${currentUser.plan.toUpperCase()}
${msg}
`;
}
function clearAuthMsg() { document.getElementById('authMsg').innerHTML = ''; }
async function doLogin() {
const email = document.getElementById('loginEmail').value.trim();
const pass = document.getElementById('loginPassword').value;
if(!email||!pass){ showAuthMsg('E-posta ve şifre gerekli'); return; }
const btn = document.getElementById('loginBtn');
btn.disabled=true; btn.textContent='Giriş yapılıyor...';
try {
const r = await apiFetch('/auth/login', 'POST', {email, password:pass});
const d = await r.json();
if(!r.ok){ showAuthMsg(d.detail||'Giriş başarısız'); return; }
authToken = d.access_token;
localStorage.setItem('ms_token', authToken);
currentUser = {
id: d.user.id, email: d.user.email, name: d.user.name,
plan:'free', analyses_used:0, analyses_limit:3, analyses_remaining:3
};
await loadUser();
closeAuth();
showApp();
toast('✓ Hoş geldiniz!');
} catch(e){ showAuthMsg('Bağlantı hatası: '+e.message); }
finally{ btn.disabled=false; btn.textContent='Giriş Yap'; }
}
async function doRegister() {
const name = document.getElementById('regName').value.trim();
const email = document.getElementById('regEmail').value.trim();
const pass = document.getElementById('regPassword').value;
if(!name||!email||!pass){ showAuthMsg('Tüm alanları doldurun'); return; }
if(pass.length<8){ showAuthMsg('Şifre en az 8 karakter olmalı'); return; }
const btn = document.getElementById('registerBtn');
btn.disabled=true; btn.textContent='Hesap oluşturuluyor...';
try {
const r = await apiFetch('/auth/register', 'POST', {email, password:pass, name});
const d = await r.json();
if(!r.ok){ showAuthMsg(d.detail||'Kayıt başarısız'); return; }
showAuthMsg('✓ Hesabınız oluşturuldu! E-postanızı doğrulayın, ardından giriş yapın.', 'success');
setTimeout(()=>switchAuthTab('login'), 3000);
} catch(e){ showAuthMsg('Bağlantı hatası: '+e.message); }
finally{ btn.disabled=false; btn.textContent='Hesap Oluştur — Ücretsiz'; }
}
async function doLogout() {
authToken=null; currentUser=null;
localStorage.removeItem('ms_token');
document.getElementById('navRight').innerHTML = `
`;
showLanding();
resetAll();
}
// ── API FETCH ─────────────────────────────────────────────────────────────────
async function apiFetch(path, method='GET', body=null) {
const opts = {
method,
headers: {'Content-Type':'application/json'},
};
if(authToken) opts.headers['Authorization'] = `Bearer ${authToken}`;
if(body) opts.body = JSON.stringify(body);
return fetch(API+path, opts);
}
// ── PROVIDER / MODEL ──────────────────────────────────────────────────────────
const CLAUDE_MODELS = [
{v:'claude-sonnet-4-6',l:'claude-sonnet-4-6'},
{v:'claude-opus-4-6',l:'claude-opus-4-6'},
{v:'claude-haiku-4-5-20251001',l:'claude-haiku-4-5'},
];
const OPENAI_MODELS = [
{v:'gpt-4o',l:'gpt-4o'},{v:'gpt-4o-mini',l:'gpt-4o-mini'},
{v:'gpt-4-turbo',l:'gpt-4-turbo'},{v:'o1-mini',l:'o1-mini'},
];
function setProvider(p) {
currentProvider = p;
document.getElementById('tabClaude').className = 'provider-tab' + (p==='claude' ? ' active claude' : '');
document.getElementById('tabOpenAI').className = 'provider-tab' + (p==='openai' ? ' active openai' : '');
document.getElementById('keyLabel').textContent = p==='claude' ? 'Claude' : 'OpenAI';
const sel = document.getElementById('modelSelect');
const models = p==='claude' ? CLAUDE_MODELS : OPENAI_MODELS;
sel.innerHTML = models.map(m=>``).join('');
document.getElementById('apiKey').placeholder = p==='claude' ? 'sk-ant-...' : 'sk-...';
checkKey();
}
function getExt(n){return n.split('.').pop().toLowerCase();}
function getIcon(n){return FILE_ICONS[getExt(n)]||'📎';}
function fmtSize(b){return b<1024?b+'B':b<1048576?(b/1024).toFixed(1)+'KB':(b/1048576).toFixed(1)+'MB';}
function onDragOver(e){e.preventDefault();document.getElementById('fileDrop').classList.add('dragover');}
function onDragLeave(){document.getElementById('fileDrop').classList.remove('dragover');}
function onDrop(e){e.preventDefault();document.getElementById('fileDrop').classList.remove('dragover');handleFiles(e.dataTransfer.files);}
function handleFiles(files){
Array.from(files).forEach(file=>{
if(file.size>10*1024*1024){toast('⚠ '+file.name+' 10MB sınırını aşıyor');return;}
if(uploadedFiles.find(f=>f.name===file.name&&f.size===file.size))return;
const idx=uploadedFiles.length;
uploadedFiles.push({name:file.name,size:file.size,content:null,error:null,isImage:false});
renderFileList();
readFile(file,idx);
});
}
function readFile(file,idx){
const ext=getExt(file.name);
const isImg=['png','jpg','jpeg'].includes(ext);
const isTxt=['txt','csv'].includes(ext);
if(isTxt){
const r=new FileReader();
r.onload=e=>{uploadedFiles[idx].content=e.target.result;renderFileList();};
r.readAsText(file,'UTF-8');
} else {
const r=new FileReader();
r.onload=async e=>{
const b64=e.target.result.split(',')[1];
uploadedFiles[idx].isImage=isImg;
uploadedFiles[idx].mimeType=file.type;
if(isImg){uploadedFiles[idx].content=b64;renderFileList();return;}
// Send to backend for extraction
try{
const resp=await apiFetch('/extract','POST',{filename:file.name,b64,mime_type:file.type});
if(resp.ok){
const d=await resp.json();
uploadedFiles[idx].content=d.text;
uploadedFiles[idx].chars=d.chars;
} else {
uploadedFiles[idx].content=null;
uploadedFiles[idx].fallbackB64=b64;
uploadedFiles[idx].error=ext==='pdf'?null:'Metin çıkarılamadı';
}
} catch {
uploadedFiles[idx].fallbackB64=b64;
}
renderFileList();
};
r.readAsDataURL(file);
}
}
function removeFile(i){uploadedFiles.splice(i,1);renderFileList();}
function renderFileList(){
const list=document.getElementById('fileList');
const badge=document.getElementById('fileBadge');
if(!uploadedFiles.length){list.innerHTML='';badge.style.display='none';return;}
badge.textContent=uploadedFiles.length+' dosya';badge.style.display='inline';
list.innerHTML=uploadedFiles.map((f,i)=>{
const loading=f.content===null&&!f.error&&!f.fallbackB64;
const status=f.error?`⚠ ${f.error}`:
loading?`⏳`:
f.chars?`✓ ${(f.chars/1000).toFixed(0)}K kr`:
f.isImage?`✓ Görsel`:
`✓ Hazır`;
return `${getIcon(f.name)}${f.name}${fmtSize(f.size)}${status}
`;
}).join('');
}
function buildFilePayload(){
return uploadedFiles.filter(f=>f.content&&!f.isImage).map(f=>({name:f.name,text:f.content.slice(0,8000)}));
}
// ── PIPELINE UI ───────────────────────────────────────────────────────────────
function setTile(i,state,text){
const el=document.getElementById('a'+i),st=document.getElementById('st'+i),out=document.getElementById('out'+i),exp=document.getElementById('exp'+i);
el.className='atile '+state;st.className='astatus '+state;
if(state==='running')st.innerHTML=' Çalışıyor';
else if(state==='done')st.textContent='✓ Tamam';
else if(state==='error')st.textContent='✗ Hata';
else st.textContent='—';
if(text){fullTexts[i]=text;const p=text.length>200?text.slice(0,200)+'…':text;out.textContent=p;if(text.length>200)exp.style.display='inline';}
}
function xp(i){
const out=document.getElementById('out'+i),btn=document.getElementById('exp'+i);
if(out.classList.contains('expanded')){out.textContent=fullTexts[i].slice(0,200)+'…';out.classList.remove('expanded');btn.textContent='daha fazla ↓';}
else{out.textContent=fullTexts[i];out.classList.add('expanded');btn.textContent='daralt ↑';}
}
function updProg(n){doneN=n;document.getElementById('progText').textContent=n+' / '+TOTAL;document.getElementById('progFill').style.width=Math.round(n/TOTAL*100)+'%';}
function toast(msg,d=2800){const t=document.getElementById('toast');t.textContent=msg;t.classList.add('show');setTimeout(()=>t.classList.remove('show'),d);}
// ── PROMPTS ───────────────────────────────────────────────────────────────────
function buildPrompts(info){
const fileCtx=uploadedFiles.filter(f=>f.content&&!f.isImage).map((f,i)=>`\n[Dosya ${i+1}: ${f.name}]\n${f.content.slice(0,8000)}`).join('\n');
const base=`Ürün: ${info.name}\nKategori: ${info.cat}\nHedef Pazar: ${info.market}\nAlış: ${info.buy||'bilinmiyor'} | Satış: ${info.sell||'bilinmiyor'}\nİş Modeli: ${info.biz}\nEk Bilgi: ${info.desc||'—'}${fileCtx?'\n\n=== YÜKLENEN DOSYALAR ===\n'+fileCtx+'\n=== DOSYA SONU ===':''}`;
const R=results;
return [
`${SYS}\n\nGörev: BÖLÜM A — PAZAR ANALİZİ\n\n${base}\n\n1. Türkiye/Avrupa/Orta Doğu: pazar büyüklüğü ($M) ve CAGR\n2. TAM→SAM→SOM (sayısal)\n3. Segmentasyon (3 segment, büyüklük+alıcı)\n4. Büyüme katalizörleri (4 madde)\n5. Baskılar ve riskler (3 madde)\n6. Hedef müşteri profili\nSon satır: PAZAR SKORU: X/5`,
`${SYS}\n\nGörev: BÖLÜM B — REKABET ANALİZİ\n\n${base}\n\n1. Ana rakipler (5+): isim·menşe·fiyat·güçlü/zayıf\n2. Konumlandırma haritası: Premium/Mid/Budget\n3. Giriş engelleri: marka·sertifika·kanal\n4. Farklılaşma matrisi\n5. Segment boşluğu\nSon satır: REKABET SKORU: X/5`,
`${SYS}\n\nGörev: BÖLÜM C — TEDARİKÇİ ANALİZİ\n\n${base}\n\n1. OEM tedarikçiler (3+): şehir·FOB·MOQ·güçlü/zayıf\n2. Sertifikasyon: CE/UKCA/ilgili\n3. Lead time ve stok\n4. Exclusivity/Private Label\n5. Tedarik zinciri riskleri\n6. Önerilen tedarikçi\nSon satır: TEDARİK SKORU: X/5`,
`${SYS}\n\nGörev: BÖLÜM F — UYUMLULUK & MEVZUAT\n\n${base}\n\n1. GTİP + gümrük + TAREKS\n2. Türkiye özel izinler\n3. AB direktifleri (CE, RoHS, RED vb.)\n4. Dual-use riski\n5. Sertifikasyon süresi ve maliyet\nSon satır: UYUMLULUK SKORU: X/5`,
`${SYS}\n\nGörev: BÖLÜM D — FİYATLANDIRMA\n\n${base}\n\n1. Birim maliyet: FOB·navlun·gümrük·depo·sertifika·ambalaj→TOPLAM COGS\n2. Kanal marjları: TR B2B·TR distribütör·Avrupa·Orta Doğu·blended\n3. Marj eşiği değerlendirmesi (%20 altı=tehlike)\n4. Fiyat stratejisi\nSon satır: MARJ SKORU: X/5`,
`${SYS}\n\nGörev: BÖLÜM E — FİNANSAL PROJEKSİYON\n\nPazar: ${R[0]||'—'}\nFiyat: ${R[4]||'—'}\n\n${base}\n\n1. 5Y senaryo (kötümser/baz/iyimser) — adet + $M\n2. Baz senaryo gelir tablosu 2026-2030: ciro·COGS·brüt kâr·opex·net kâr\n3. Yatırım gereksinimleri ve ROI\n4. Başabaş noktası\n5. Cash Conversion Cycle\nSon satır: FİNANSAL SKOR: X/5`,
`${SYS}\n\nGörev: SAVUNUCU\n\nPAZAR: ${R[0]}\nREKABET: ${R[1]}\nTEDARİK: ${R[2]}\nMEVZUAT: ${R[3]}\nFİYAT: ${R[4]}\nFİNANSAL: ${R[5]}\n\n${base}\n\nPortföye ALINMASI için en az 6 güçlü argüman. Rakipler ve eleştirmenlerin olası itirazlarını önceden yanıtla.`,
`${SYS}\n\nGörev: ELEŞTİRMEN\n\nSavunucu: ${R[6]}\nPAZAR: ${R[0]} | REK: ${R[1]} | TED: ${R[2]} | MEV: ${R[3]} | FİY: ${R[4]} | FİN: ${R[5]}\n\n${base}\n\nSavunucunun her argümanını çürüt. Gizli maliyetleri, iyimser varsayımları ortaya koy. Alternatif öneri yap.`,
`${SYS}\n\nGörev: BÖLÜM H — AĞIRLIKLI PUANLAMA & KARAR\n\nSAVUNUCU: ${R[6]}\nELEŞTİRMEN: ${R[7]}\nTüm veri: ${R[0].slice(0,300)}|${R[1].slice(0,200)}|${R[4].slice(0,200)}|${R[5].slice(0,200)}\n\n8 kriteri 1-5 puan (ağırlıklar: Pazar%20·Marj%20·Rekabet%15·Tedarik%15·Sertifika%10·Strateji%10·Operasyonel%5·ROI%5):\n\n| Kriter | Ağırlık | Puan | Ağırlıklı |\n|---|---|---|---|\n[her kriter için satır]\n| **TOPLAM** | **%100** | — | **XX/100** |\n\nTOPLAM PUAN: XX/100\nKARAR: [Onayli/Koşullu Onay/Ertelendi/Reddedildi]\nGEREKÇE: [2 cümle]\nAKSİYON PLANI:\n1. [aksiyon — sorumlu — süre]\n2. [aksiyon — sorumlu — süre]\n3. [aksiyon — sorumlu — süre]\n4. [aksiyon — sorumlu — süre]`,
`${SYS}\n\nGörev: RİSK MATRİSİ\n\nKarar: ${R[8]}\nSav: ${R[6].slice(0,200)} | Eleş: ${R[7].slice(0,200)}\n\nEn az 7 risk. Her biri: başlık · kategori · olasılık(Y/O/D) · etki(K/Ö/D) · mitigasyon\nSon satır: BİRLEŞİK RİSK: [Yüksek/Orta/Düşük] | Öncelikli aksiyon: [1 cümle]`,
`${SYS}\n\nGörev: BÖLÜM G — STRATEJİK UYUM\n\nPAZAR: ${R[0]}\nREKABET: ${R[1]}\nFİYAT: ${R[4]}\nFİNANSAL: ${R[5]}\n\n${base}\n\n1. SWOT (4 kutu, 3+ madde her biri)\n2. Portföy uyumu ve sinerji\n3. EMEA ölçeklenme potansiyeli\n4. Private Label / marka yatırımı — ne zaman?\n5. Stratejik tavsiye\nSon satır: STRATEJİK UYUM SKORU: X/5`,
`${SYS}\n\nGörev: NİHAİ RAPOR — A-H bölümlerini sentezle (özet format, bölüm başlıklarını AYNEN kullan):\n\n## BÖLÜM A — PAZAR ANALİZİ\n[3-4 cümle özet]\n\n## BÖLÜM B — REKABET ANALİZİ\n[3-4 cümle]\n\n## BÖLÜM C — TEDARİKÇİ ANALİZİ\n[3-4 cümle]\n\n## BÖLÜM D — FİYATLANDIRMA\n[3-4 cümle]\n\n## BÖLÜM E — FİNANSAL PROJEKSİYON\n[3-4 cümle]\n\n## BÖLÜM F — UYUMLULUK\n[3-4 cümle]\n\n## BÖLÜM G — STRATEJİK UYUM\n[3-4 cümle]\n\n## BÖLÜM H — PUANLAMA & KARAR\n${R[8]}\n\nKaynak: A=${R[0].slice(0,200)} B=${R[1].slice(0,200)} C=${R[2].slice(0,150)} D=${R[4].slice(0,200)} E=${R[5].slice(0,200)} F=${R[3].slice(0,150)} G=${R[10].slice(0,200)}`
];
}
// ── MAIN ANALYSIS FLOW ────────────────────────────────────────────────────────
async function startAnalysis(){
if(!currentUser){openAuth('login');return;}
const name=document.getElementById('pName').value.trim();
if(!name){toast('⚠ Ürün adı zorunlu');return;}
if(!document.getElementById('pCat').value){toast('⚠ Kategori seçin');return;}
if(running)return;
running=true;results=Array(TOTAL).fill('');fullTexts=Array(TOTAL).fill('');doneN=0;sectionTexts={};
curInfo={
name,cat:document.getElementById('pCat').value,
market:document.getElementById('pMarket').value,
buy:document.getElementById('pBuy').value.trim(),
sell:document.getElementById('pSell').value.trim(),
biz:document.getElementById('pBiz').value,
desc:document.getElementById('pDesc').value.trim()
};
document.getElementById('emptyState').style.display='none';
document.getElementById('reportWrap').classList.remove('show');
document.getElementById('pipelineEl').classList.add('show');
document.getElementById('inputCard').style.cssText='opacity:.4;pointer-events:none';
for(let i=0;iHenüz kaydedilmiş analiz yok.
Analiz tamamlandığında otomatik kaydedilir.
';
return;
}
list.innerHTML = history.map(function(h) {
var d = new Date(h.date).toLocaleString('tr-TR');
var vcls = h.verdictCol === 'green' ? 'hv-green' : h.verdictCol === 'red' ? 'hv-red' : 'hv-yellow';
var score = h.score ? h.score + '/100' : '—';
return 'Analiz tamamlandığında otomatik kaydedilir.
'
+ '
';
}).join('');
}
// Init history count on load
document.addEventListener('DOMContentLoaded', function() {
renderHistory();
});
// ── END GEÇMİŞ ────────────────────────────────────────────────────────────────
function buildReport() {
const report=results[11]||'';
const decision=results[8]||'';
const combined=report+' '+decision;
const v=parseVerdict(combined);
const score=parseScore(decision)||parseScore(report);
document.getElementById('rTitle').textContent=curInfo.name+' — Kapsamlı Analiz Raporu';
const prov=currentProvider==='claude'?'Claude ('+document.getElementById('modelSelect').value+')':'OpenAI ('+document.getElementById('modelSelect').value+')';
document.getElementById('rSub').textContent='MarketScope AI · '+prov+' · '+new Date().toLocaleString('tr-TR');
const vc=document.getElementById('rVerdict');vc.textContent=v.label;vc.className='vchip '+v.cls;
if(score){
document.getElementById('rScore').textContent=score;
const f=document.getElementById('rScoreFill');
f.className='score-fill sf-'+v.col;
setTimeout(()=>f.style.width=score+'%',200);
}
document.getElementById('mProd').textContent=curInfo.name;
document.getElementById('mMarket').textContent=curInfo.market;
document.getElementById('mBiz').textContent=curInfo.biz;
document.getElementById('mDate').textContent=new Date().toLocaleDateString('tr-TR');
// Parse section summaries from report agent
SECS.forEach(s=>{ sectionTexts[s.id]=extractSection(report,s.id); });
const container=document.getElementById('sectionsContainer');
container.innerHTML='';
// ── YÖNETİCİ ÖZETİ ──
const execCard = document.createElement('div');
execCard.className='scard open';
execCard.innerHTML=`
📊
'
+ ''
+ '
'
+ '' + (h.verdict || '—') + ' · ' + score + ''
+ ''
+ '' + (h.info.name || 'İsimsiz') + '
'
+ '' + d + ' · ' + (h.info.market || '') + ' · ' + (h.provider || 'claude') + '
'
+ 'ÖZ
Yönetici Özeti
Nihai karar · Kritik bulgular · Öncelikli aksiyonlar
▾
Nihai Karar
${v.label}
${score||'—'}/100
Ürün Bilgisi
${curInfo.name}
${curInfo.cat} · ${curInfo.market}
Alış: ${curInfo.buy||'?'} → Satış: ${curInfo.sell||'?'}
Model: ${curInfo.biz}
${curInfo.cat} · ${curInfo.market}
Alış: ${curInfo.buy||'?'} → Satış: ${curInfo.sell||'?'}
Model: ${curInfo.biz}
Analiz Bilgisi
${new Date().toLocaleString('tr-TR')}
${prov}
12 Ajan · 3 Faz
A-H Bölümleri
${prov}
12 Ajan · 3 Faz
A-H Bölümleri
${sectionTexts['H']||decision||'Karar bölümü hazırlanıyor...'}
${s.id}
${s.title}
${s.sub}
▾
${fullContent}
`;
container.appendChild(card);
});
// ── TARTIŞMA TUTANAĞI ──
const debateCard = document.createElement('div');
debateCard.className='scard';
debateCard.innerHTML=`
T
Tartışma Tutanağı
Savunucu argümanları · Eleştirmen karşı argümanları · Tam metin
▾
👍 SAVUNUCU — Portföye Al
${fullTexts[6]||results[6]||'—'}
👎 ELEŞTİRMEN — Portföye Alma
${fullTexts[7]||results[7]||'—'}
R
Risk Matrisi
Olasılık · Etki · Mitigasyon · Birleşik risk seviyesi
▾
${fullTexts[9]||results[9]||'—'}
H
Puanlama & Karar Detayı
8 kriterin ağırlıklı puanlaması · Karar eşikleri · Aksiyon planı
▾
${fullTexts[8]||results[8]||'—'}
BÖLÜM ÖZETİ
${summary}
DETAYLI ANALİZ
${rawOutput}
İçerik hazırlanıyor...
';
return summaryHtml + rawHtml;
}
function resetAll() {
uploadedFiles=[]; renderFileList();
results=Array(TOTAL).fill(''); fullTexts=Array(TOTAL).fill(''); sectionTexts={};
document.getElementById('reportWrap').classList.remove('show');
var wb=document.getElementById('wordBtn');if(wb){wb.disabled=true;wb.style.opacity='.4';wb.style.cursor='not-allowed';}
document.getElementById('pipelineWrap').classList.remove('show');
document.getElementById('emptyState').style.display='block';
document.getElementById('inputCard').style.cssText='';
setStep(1);
for(let i=0;i${s.id}${s.title}${s.sub}
${(sectionTexts[s.id]||'(İçerik mevcut değil)').replace(/\n/g,'
')}
')}
MarketScope AI · Ürün Analiz Platformu
${curInfo.name}
Çok-Agent Ürün Seçim Analiz Raporu
| Ürün Adı | ${curInfo.name} |
| Kategori | ${curInfo.cat} |
| Hedef Pazar | ${curInfo.market} |
| İş Modeli | ${curInfo.biz} |
| Alış / Satış | ${curInfo.buy||'?'} / ${curInfo.sell||'?'} |
| Analiz Tarihi | ${dt} |
| Ajan Sayısı | 12 Ajan · 3 Faz · A-H Bölümleri |
${v.label}
Ağırlıklı Puan: ${score} / 100
Risk Matrisi
${(results[9]||'Risk analizi mevcut değil').replace(/\n/g,'
')}
')}
MarketScope AI · Gizli Ticari Belge
${dt}
`;
}
async function downloadReport(type) {
const btn = document.getElementById(type === 'word' ? 'wordBtn' : 'pptxBtn');
const orig = btn.innerHTML;
btn.disabled = true; btn.innerHTML = '⏳ Hazırlanıyor...';
try {
if (type === 'word') {
await generateWordReport();
} else {
await generatePptxReport();
}
} catch(e) {
console.error(e);
toast('Hata: ' + e.message, 5000);
}
btn.innerHTML = orig;
btn.disabled = false;
}
async function generateWordReport() {
// Use server endpoint for Word generation
const v = parseVerdict(results[11] + results[8]);
const score = parseScore(results[8]) || parseScore(results[11]) || '—';
const payload = {
info: curInfo, results: [...results], fullTexts: [...fullTexts],
sectionTexts: {...sectionTexts}, verdict: v.label, verdictCol: v.col,
score: score, provider: currentProvider,
model: document.getElementById('modelSelect').value,
date: new Date().toLocaleString('tr-TR')
};
const resp = await fetch('/api/report/word', {
method: 'POST', headers: {'Content-Type': 'application/json'},
body: JSON.stringify(payload)
});
if (!resp.ok) {
// Fallback: generate rich HTML report if server fails
const err = await resp.text();
console.warn('Word server failed, using HTML fallback:', err);
generateHTMLReport();
return;
}
const blob = await resp.blob();
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = (curInfo.name || 'Rapor').replace(/[^a-zA-Z0-9 ]/g,'').trim().replace(/ +/g,'_') + '_Analiz_Raporu.docx';
document.body.appendChild(a); a.click(); document.body.removeChild(a);
URL.revokeObjectURL(url);
toast('✓ Word raporu indirildi');
}
async function generatePptxReport() {
const v = parseVerdict(results[11] + results[8]);
const score = parseScore(results[8]) || parseScore(results[11]) || '—';
const payload = {
info: curInfo, results: [...results], fullTexts: [...fullTexts],
sectionTexts: {...sectionTexts}, verdict: v.label, verdictCol: v.col,
score: score, provider: currentProvider,
model: document.getElementById('modelSelect').value,
date: new Date().toLocaleString('tr-TR')
};
const resp = await fetch('/api/report/pptx', {
method: 'POST', headers: {'Content-Type': 'application/json'},
body: JSON.stringify(payload)
});
if (!resp.ok) {
const err = await resp.json().catch(() => ({}));
throw new Error(err.error || 'HTTP ' + resp.status);
}
const blob = await resp.blob();
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
const fname = (curInfo.name || 'Rapor').replace(/[^a-zA-Z0-9 ]/g,'').trim().replace(/ +/g,'_') + '_Sunum.pptx';
a.download = fname;
document.body.appendChild(a); a.click(); document.body.removeChild(a);
URL.revokeObjectURL(url);
toast('✓ PowerPoint indirildi (15 slayt)');
}
function generateHTMLReport() {
// Rich HTML fallback for Word
exportHTML();
}
function exportWord(){
downloadReport('word');
}
function exportHTML(){
var v=parseVerdict(results[11]+results[8]);
var score=parseScore(results[8])||parseScore(results[11])||'—';
var dt=new Date().toLocaleString('tr-TR');
var prov=currentProvider==='claude'?'Claude':'OpenAI';
var model=document.getElementById('modelSelect').value;
var NL=''; var vc=v.col==='green'?'vg':v.col==='red'?'vr':'vy'; var vcHex=v.col==='green'?'#0E7A4E':v.col==='red'?'#B91C1C':'#C4620D'; var vbg=v.col==='green'?'#EDFAF4':v.col==='red'?'#FEF2F2':'#FFFBEB'; var vborder=v.col==='green'?'#059669':v.col==='red'?'#DC2626':'#D97706'; var sw=isNaN(parseInt(score))?50:parseInt(score); function clean(t){ if(!t) return ''; return t.replace(/\*\*(.+?)\*\*/g,'$1') .replace(/^#{1,3}\s*/gm,'') .split('\n').map(function(l){return l.trim();}) .filter(function(l){return l.length>0;}) .join('
'); } function sectionBlock(letter,title,sub,agIdx,summKey){ var summ=sectionTexts[summKey]||''; var raw=fullTexts[agIdx]||results[agIdx]||''; var colors={A:'#1B4FD8',B:'#1B4FD8',C:'#0F1F3D',D:'#0F1F3D',E:'#0E7A4E',F:'#C4620D',G:'#1B4FD8'}; var accent=colors[letter]||'#1B4FD8'; return '
'
+'':'')
+'
';
}
var sections=''
+sectionBlock('A','Pazar Analizi','TAM/SAM/SOM · CAGR · Segmentasyon · Büyüme katalizörleri · Hedef müşteri profili',0,'A')
+sectionBlock('B','Rekabet Analizi','Rakip fiyat haritası · Giriş engelleri · Farklılaşma matrisi · Segment boşluğu',1,'B')
+sectionBlock('C','Tedarikçi Analizi','Min. 3 OEM karşılaştırma · Factory audit · Sertifikasyon · Risk matrisi',2,'C')
+sectionBlock('D','Fiyatlandırma','FOB→raf tüm maliyet kalemleri · Kanal bazlı marj analizi · Eşik değerlendirmesi',4,'D')
+sectionBlock('E','Finansal Projeksiyon','5 yıl senaryo tablosu · ROI · Başabaş · Cash conversion cycle',5,'E')
+sectionBlock('F','Uyumluluk','CE/UKCA/MDR/AQAP sertifika durumu · GTİP/ithalat kontrolü · Dual-use',3,'F')
+sectionBlock('G','Stratejik Uyum','SWOT · Portföy sinerji değerlendirmesi · Ölçeklenme potansiyeli',10,'G');
var h=(fullTexts[8]||results[8]||'');
var doc='\n\n\n\n'
+''
+''
+'
'
+(summ?''+letter+'
'
+''+title+'
'+sub+'
BÖLÜM ÖZETİ
'+clean(summ)+'
DETAYLI ANALİZ — TAM AJAN ÇIKTISI
'
+''+clean(raw)+'
'
+'\n'
+'\n'
+'
\n'
// EXEC SUMMARY PAGE
+''+score+'
/ 100 Puan
MarketScope AI · EMEA Ürün Analiz Platformu
\n'
+''+curInfo.name+'
\n' +'Kapsamlı Ürün Seçim Analiz Raporu
\n' +''+v.label+'
\n'
+'\n'
+'
\n'
+'\n'
+'\n'
+'\n'
+'\n'
+'\n'
+'\n'
+'
\n'
+'Ürün Kategorisi
'+curInfo.cat+'
Hedef Pazar
'+curInfo.market+'
İş Modeli
'+curInfo.biz+'
Alış / Satış
'+(curInfo.buy||'?')+' / '+(curInfo.sell||'?')+'
Platform
'+prov+' ('+model+')
Analiz Tarihi
'+dt+'
Karar Eşikleri: ≥80 = Onayli · 65–79 = Koşullu Onay · 50–64 = Ertelendi · <50 = Reddedildi · 12 Ajan · 3 Faz · A-H Bölümleri
\n'
+'\n'
+''+l.replace(/^\d\.\s*/,'').replace(/\*\*/g,'')+'');
}
}
if(!acts.length) return '';
return '
\n'
// A-G SECTIONS
+sections
// DEBATE
+'Yönetici Özeti & Nihai Karar
\n'
+'\n'
+'\n'
+'
\n'
// Action plan
+(function(){
var lines=(h||'').split('\n');
var acts=[];
for(var i=0;i'+score+'
/ 100 Puan
'+v.label+'
'
+''
+'
'
+'
| Kriter | Ağırlık | Puan | Ağırlıklı | '+c[0]+' | ' +''+c[1]+' | ' +''+(sc!==null?sc+'/5':'—')+' | ' +''+(ws!==null?ws:'—')+' | '; }); rows+='
|---|---|---|---|
| TOPLAM | %100 | — | '+score+'/100 |
Aksiyon Planı
- '+acts.join('')+'
Karar Gerekçesi
'+m[1].trim().replace(/\n/g,' ')+'
';
})()
+'\n'
+'
\n'
// RISK
+'Tartışma Tutanağı
\n'
+'\n'
+'\n'
+'\n'
+'
👍 Savunucu — Portföye Al
'+clean(fullTexts[6]||results[6]||'')+'
👎 Eleştirmen — Portföye Alma
'+clean(fullTexts[7]||results[7]||'')+'
\n'
+'\n'
+'
\n'
// APPENDIX
+'🔺 Risk Matrisi
\n'
+''+clean(fullTexts[9]||results[9]||'')+'
\n'
+'
';
}
return out;
})()
+'Ek — Tüm Ajan Analizleri (Tam Metin)
\n'
+'Bu bölüm 12 ajanın ürettiği ham analiz çıktılarını eksiksiz olarak içermektedir.
\n' +(function(){ var names=['Ajan 0 — Pazar Araştırma','Ajan 1 — Rekabet Analizi', 'Ajan 2 — Tedarik Zinciri','Ajan 3 — Mevzuat & Uyumluluk', 'Ajan 4 — Fiyatlandırma','Ajan 5 — Finansal Projeksiyon', 'Ajan 6 — Savunucu','Ajan 7 — Eleştirmen', 'Ajan 8 — Karar (H)','Ajan 9 — Risk Analizi', 'Ajan 10 — Stratejik Uyum (G)','Ajan 11 — Rapor Sentezi']; var out=''; for(var i=0;i'+names[i]+'
'+clean(t)+'