diff --git a/docs/quality/qa-preparation-overview.json b/docs/quality/qa-preparation-overview.json
new file mode 100644
index 0000000..2c28550
--- /dev/null
+++ b/docs/quality/qa-preparation-overview.json
@@ -0,0 +1,18 @@
+{
+ "date": "2026-09-06",
+ "environment": "localhost:5182 five synthetic tenders, real UI/API save",
+ "checks": {
+ "fiveDossiers": true,
+ "allUnassignedVisible": true,
+ "directFieldFocus": true,
+ "savedFieldCleared": true,
+ "ownerUpdated": true,
+ "reloadPreserved": true
+ },
+ "limits": [
+ "Synthetic incomplete dossiers, not five official bid approvals",
+ "One direct field focus, saved edit and one owner assignment tested",
+ "Distinct owners and document revision errors covered by unit tests",
+ "Real PDF/official documents remain open"
+ ]
+}
diff --git a/docs/quality/uygulama-durumu.md b/docs/quality/uygulama-durumu.md
index 053f593..b60feac 100644
--- a/docs/quality/uygulama-durumu.md
+++ b/docs/quality/uygulama-durumu.md
@@ -874,3 +874,11 @@ Taslak türü seçicisine erişilebilir ad eklendi. Üretim derlemesi geçti. Ö
- Kayıt sırasında durum/atama/sürükleme kilitlenir; mevcut sunucu kayıt hatası panoda gösterilir. Durum iyimser olarak değiştirilmez, mevcut mutateTender kalıcılık akışı korunur.
- Yerel 5182 sentetik Giresun görevinde 5 kontrol geçti: sahte düğmenin kalkması, desteklenmeme açıklaması, durum seçimi, yenileme sonrası durumun korunması ve erişilebilir kontrol adları. Kanıt qa-kanban-controls.json. Derleme geçti. Önceki 197 test tekrar çalıştırılmadı; sunucu değişmedi.
- Bu tur atama mutasyonu, hata enjeksiyonu, yalnız klavyeyle tam gezinme veya beş dosyalı eksik/sorumlu/sonraki işlem özetinin kabulünü kanıtlamaz. D07'nin ortak hazırlık özeti açık.
+
+### D07 — Beş dosyalı hazırlık özeti — 6 Eylül 2026
+- Kanban'a Hazırlık dosyaları özeti eklendi. Aynı takip/sorumlu filtresindeki tüm ihaleler için sorumlu, kayıtlı taslaktaki kontrol sayısı, belge eksikleri ve sıradaki kontrol bir tabloda gösterilir. Kaydedilmemiş form değişiklikleri özetin dışında olduğu açıklanır; temiz özet başvuru onayı olarak sunulmaz.
+- preparationSummary mevcut kaynak/kalem/kısım, firma alanları, teklif türü/geçerliliği, fiyat, sağlık koşulları ve belge bağlantı/sürüm/süre kontrollerini kullanır. Zorunlu firma alanları ortak modüle taşındı. Belge deposu hata/yükleme durumları gösterilir; yenileme düğmesi vardır.
+- Özet bağlantıları detayın doğrudan hazırlık sekmesini açar ve ilgili firma/fiyat/kontrol alanına odak taşır. Belge ve ürün eksikleri ilgili kontrol bölümüne gider. Çıktı öncesi canlı belge doğrulamaları korunur.
+- 200 otomatik test ve derleme geçti. Beş ayrı sorumlu/belge içeren taslak özeti, eski belge sürümü/depo hatası ve geçmiş deadline önceliği test edildi.
+- 5182 yerel tarayıcıda beş sentetik görev tek tabloda görüldü; vergi alanına doğrudan odak, kaydedilen düzeltmenin özetten kalkması, sorumlu atamasının yansıması ve yenileme sonrası kalıcılık dahil 6 kontrol geçti (qa-preparation-overview.json).
+- Bu sentetik kabul gerçek beş resmi dosyanın uygunluğunu kanıtlamaz. Firma portföyü/ürün kapasitesi, tam mobil erişilebilirlik, her eksik belgeye ayrı alt-alan odağı ve resmi çıktılarla ilgili açık maddeler devam eder. Özet kontrolleri kayıtlı taslağa dayanır; yeni AI analizi veya kaydedilmemiş değişiklikler dosya ekranında ayrıca değerlendirilir.
diff --git a/src/components/BidPackageBuilder.jsx b/src/components/BidPackageBuilder.jsx
index 9e72e0a..dc70924 100644
--- a/src/components/BidPackageBuilder.jsx
+++ b/src/components/BidPackageBuilder.jsx
@@ -1,3 +1,4 @@
+import { bidFirmFields as ALANLAR } from '../services/bidFirmFields';
import { preparationAnalysisSource, preparationConditionSections, conditionText } from '../services/preparationAnalysis';
import { preparationDeadlineProblem } from '../services/preparationDeadline';
import { bidValidityForForm, bidTypeForForm } from '../services/bidTerms';
@@ -29,23 +30,13 @@ import {
* Firma bilgileri localStorage'da tutulur — her ihalede yeniden sorulmasın.
*/
-const ALANLAR = [
- { k: 'firmaUnvan', l: 'Firma ticaret unvanı', zorunlu: true, genis: true },
- { k: 'adres', l: 'Tebligata esas adres', zorunlu: true, genis: true },
- { k: 'vergiDairesi', l: 'Vergi dairesi', zorunlu: true },
- { k: 'vergiNo', l: 'Vergi numarası', zorunlu: true },
- { k: 'sicilNo', l: 'Ticaret sicil / MERSİS no', zorunlu: false },
- { k: 'yetkiliAd', l: 'Yetkili ad soyad', zorunlu: true },
- { k: 'yetkiliGorev', l: 'Yetkilinin görevi', zorunlu: true, ph: 'Örn. Genel Müdür' },
- { k: 'telefon', l: 'Telefon', zorunlu: true },
- { k: 'eposta', l: 'E-posta', zorunlu: true },
-];
+
const FIRMA_ANAHTAR = 'ihaleist_firma_bilgi';
const bosFirma = () => Object.fromEntries(ALANLAR.map((a) => [a.k, '']));
-export const BidPackageBuilder = ({ results, tender: selectedTender }) => {
+export const BidPackageBuilder = ({ results, tender: selectedTender, initialFocus }) => {
const { userProfile, mutateTender, savingCount, authUser, tenders } = useApp();
const tender = {...selectedTender, ...tenders.find(t => t.id === selectedTender?.id)};
const storedDraft = tender?.bidDraft || {};
@@ -67,6 +58,11 @@ export const BidPackageBuilder = ({ results, tender: selectedTender }) => {
target.scrollIntoView({block:'center'});
target.focus({preventScroll:true});
};
+ useEffect(()=>{
+ if(!initialFocus)return;
+ const frame=requestAnimationFrame(()=>goToMissing(initialFocus));
+ return ()=>cancelAnimationFrame(frame);
+ },[initialFocus]);
const [dirty, setDirty] = useState(false);
const [acik, setAcik] = useState(true);
const [hata, setHata] = useState(null);
diff --git a/src/components/KanbanBoard.jsx b/src/components/KanbanBoard.jsx
index 533cea1..3620e20 100644
--- a/src/components/KanbanBoard.jsx
+++ b/src/components/KanbanBoard.jsx
@@ -1,3 +1,4 @@
+import { PreparationOverview } from './PreparationOverview';
import { useDeadlineClock } from '../hooks/useDeadlineClock';
import { deadlineInfo } from '../services/tenderCalendar';
import React, { useState } from 'react';
@@ -91,6 +92,7 @@ export const KanbanBoard = () => {
{savingCount > 0 &&
Değişiklik kaydediliyor…
}
{saveError &&
{saveError}
}
+
{/* Kanban Columns Grid */}
{columns.map(col => {
diff --git a/src/components/PreparationOverview.jsx b/src/components/PreparationOverview.jsx
new file mode 100644
index 0000000..0b08538
--- /dev/null
+++ b/src/components/PreparationOverview.jsx
@@ -0,0 +1,46 @@
+import React,{useEffect,useState} from 'react';
+import {listDocuments} from '../services/account';
+import {preparationSummary} from '../services/preparationSummary';
+import {useApp} from '../context/AppContext';
+import {getToken} from '../services/auth';
+
+export function PreparationOverview({tenders,now}) {
+ const {authUser}=useApp();
+ return ;
+}
+function Overview({tenders,now}) {
+ const {setActiveTenderDetail}=useApp();
+ const [vault,setVault]=useState({loading:true,error:null,documents:[]}),[refresh,setRefresh]=useState(0);
+ useEffect(()=>{
+ let cancelled=false;
+ setVault({loading:true,error:null,documents:[]});
+ listDocuments().then(data=>{if(!cancelled)setVault({loading:false,error:null,documents:data.belgeler});})
+ .catch(error=>{if(!cancelled)setVault({loading:false,error:error.message,documents:[]});});
+ return()=>{cancelled=true;};
+ },[refresh]);
+ const open=(tender,target)=>setActiveTenderDetail({...tender,preparationTarget:target});
+ return
+
Hazırlık dosyaları · {tenders.length}
+
Panodaki ve sorumlu filtresindeki kayıtlı taslaklar gösterilir. Kaydetmediğiniz değişiklikler bu özete girmez. Eksik sayısı başvuru onayı değildir; çıktı sırasında belgeler yeniden kontrol edilir.
+
+ {vault.loading&&
Belge durumu kontrol ediliyor…
}
+ {vault.error&&
Belge durumu doğrulanamadı: {vault.error}
}
+ {!tenders.length ?
İhaleyi takibe alın veya hazırlık görevi açın; dosyası burada görünsün.