fix: block preparation for unfinished analysis states
This commit is contained in:
@@ -1286,3 +1286,9 @@ Taslak türü seçicisine erişilebilir ad eklendi. Üretim derlemesi geçti. Ö
|
||||
|
||||
- Hazırlık özetindeki “Belge durumunu yenile” düğmesi belge deposu okunurken artık `aria-busy=true` bildiriyor. Görsel disabled durumu, mevcut yükleniyor mesajı ve hata sonrası yeniden deneme davranışı korunuyor.
|
||||
- 279 test ve build başarılı. Bu tek nitelik için ayrı ekran okuyucu kabulü yapılmadı; genel plan açık.
|
||||
|
||||
### 2026-09-06 — Analiz durumlarının hazırlığı engellemesi
|
||||
|
||||
- Hazırlık ekranı yalnız `partial` analizde değil; `error`, `processing` ve `pending` durumlarında da artık hazır olamıyor. Ortak `analysisStatusBlocksPreparation` yordamı bu dört tamamlanmamış durumu tek yerde tanımlıyor.
|
||||
- Kullanıcıya gösterilen uyarı artık gerçek durumu (`error`, `processing` gibi) yazıyor; eksik kaynak/OCR/kalem açıklaması korunuyor.
|
||||
- Dört engelli ve üç tamamlanmış durum için regresyon testi eklendi. 280 test ve build başarılı. Gerçek AI sağlayıcılarında hata/işleniyor ekranı kabulü henüz yapılmadı; genel plan açık.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { bidFirmFields as ALANLAR, bidFirmIssues } from '../services/bidFirmFields';
|
||||
import { preparationAnalysisSource, preparationConditionSections, conditionText } from '../services/preparationAnalysis';
|
||||
import { preparationAnalysisSource, preparationConditionSections, conditionText, analysisStatusBlocksPreparation } from '../services/preparationAnalysis';
|
||||
import { preparationDeadlineProblem } from '../services/preparationDeadline';
|
||||
import { bidValidityForForm, bidTypeForForm } from '../services/bidTerms';
|
||||
import { createBidWorkbook, downloadBidWorkbook } from '../services/bidWorkbook';
|
||||
@@ -139,7 +139,7 @@ export const BidPackageBuilder = ({ results, tender: selectedTender, initialFocu
|
||||
useEffect(() => {const timer=setInterval(()=>setDeadlineNow(new Date()),30000);return ()=>clearInterval(timer);},[]);
|
||||
const deadlineProblem = preparationDeadlineProblem(tender,deadlineNow);
|
||||
const kontrolEksikleri = preparationBlockers(lotSelection.rows, documents, checks, {...vault,healthPortfolio:userProfile.scrapedCapabilities?.healthPortfolio || [],deadlineDate:tenderDateKey(tender),tenderIkn:tender.ikn});
|
||||
const analizEksik = effectiveResults.sourceReview?.status === 'partial';
|
||||
const analizEksik = analysisStatusBlocksPreparation(effectiveResults.sourceReview?.status);
|
||||
const hazir = !deadlineProblem && eksikler.length === 0 && toplam > 0 && !kalemEksik && !turCeliskisi && !sureEksik && !kaynakKontrolGerekli && kontrolEksikleri.length === 0 && lotSelection.errors.length === 0 && !analizEksik && !sourceOptions.needsSelection;
|
||||
|
||||
const missingActions = [
|
||||
@@ -313,7 +313,7 @@ export const BidPackageBuilder = ({ results, tender: selectedTender, initialFocu
|
||||
Metin incelemesi: sürüm {effectiveResults.sourceReview.humanReview.revision} · {effectiveResults.sourceReview.humanReview.reviewedBy} · {effectiveResults.sourceReview.humanReview.reviewedAt}. Kullanıcı karşılaştırmasıdır; resmi onay değildir.
|
||||
</p>}
|
||||
{deadlineProblem && <p role="alert" className="text-xs text-red-700">{deadlineProblem}</p>}
|
||||
{analizEksik && <p ref={targetRef('analysis')} tabIndex={-1} role="alert" className="text-xs text-red-700">Analiz kısmi: kaynak, OCR veya kalem bilgisi kontrol gerektiriyor. {(effectiveResults.sourceReview.issues || []).join(' ')} Tam ve doğrulanabilir kaynakla analizi tamamlayın.</p>}
|
||||
{analizEksik && <p ref={targetRef('analysis')} tabIndex={-1} role="alert" className="text-xs text-red-700">Analiz tamamlanmadı ({effectiveResults.sourceReview?.status || 'durum bilinmiyor'}): kaynak, OCR veya kalem bilgisi kontrol gerektiriyor. {(effectiveResults.sourceReview?.issues || []).join(' ')} Tam ve doğrulanabilir kaynakla analizi tamamlayın.</p>}
|
||||
{/* Sizden beklenen bilgiler */}
|
||||
{eksikler.length > 0 && (
|
||||
<div className="bg-amber-50 border border-amber-300 rounded-xl p-3.5 flex gap-2.5">
|
||||
|
||||
@@ -15,6 +15,8 @@ export function preparationAnalysisSource(results = {}) {
|
||||
...['documentVersion','procurementTerms','sourceReview','sourceEvidence','citations','summary','scopeOfWork'].map(field=>[field,results[field] ?? null]),
|
||||
]);
|
||||
}
|
||||
export const analysisStatusBlocksPreparation = status =>
|
||||
['partial','error','processing','pending'].includes(String(status || '').trim().toLowerCase());
|
||||
export function conditionText(row) {
|
||||
if (typeof row === 'string') return row;
|
||||
return ['title','label','value','clause','text','detail','where','whyItMatters','note'].map(key=>row?.[key]).filter(Boolean).join(' — ');
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import {qualifyAnalysis} from '../server/analysis-quality.mjs';
|
||||
import {analysisStatusBlocksPreparation} from '../src/services/preparationAnalysis.js';
|
||||
test('all non-final analysis states block preparation',()=>{
|
||||
for(const status of ['partial','error','processing','pending'])assert.equal(analysisStatusBlocksPreparation(status),true);
|
||||
for(const status of ['complete','verified',''])assert.equal(analysisStatusBlocksPreparation(status),false);
|
||||
});
|
||||
test('malformed nested model fields cannot reach preparation screens',()=>{
|
||||
for(const result of [
|
||||
{itemsAndSpecs:[null]}, {itemsAndSpecs:[{name:{text:'Kit'}}]},
|
||||
|
||||
Reference in New Issue
Block a user