22// (import orchestration) → delete → list to verify removal.
33import { mkdtempSync , writeFileSync } from "node:fs" ;
44import { tmpdir } from "node:os" ;
5- import { join } from "node:path" ;
5+ import { basename , join } from "node:path" ;
66import { describe , expect , test } from "vite-plus/test" ;
77import { isKbAdminE2EReady , parseStdoutJson , runCommandE2e } from "../helpers.ts" ;
88import { deleteKbWithRetry } from "./journeys/journey-helpers.ts" ;
@@ -132,7 +132,9 @@ describe.skipIf(!isKbAdminE2EReady())("e2e: knowledge kb 写链路 (live, 自清
132132
133133 // 2.7) Live coverage of the upload → import orchestration (doc upload --index-id --wait):
134134 // the journeys always upload bare files and import via kb create, so this is the
135- // only place the createImportJob step runs live
135+ // only place the createImportJob step runs live. Using --output json (not --quiet)
136+ // so we can assert final_status and ingestion_id — a regression in the job/create
137+ // request body (e.g. wrong field name) is caught by the server returning HTTP 400.
136138 const importFilePath = join ( fixtureDir , `chain-import-${ Date . now ( ) } .md` ) ;
137139 writeFileSync ( importFilePath , "# kb chain e2e import fixture\n" ) ;
138140 const importUploadRun = await runCommandE2e ( KNOWLEDGE_KB_DELETE_ROUTES , [
@@ -146,13 +148,47 @@ describe.skipIf(!isKbAdminE2EReady())("e2e: knowledge kb 写链路 (live, 自清
146148 "--wait" ,
147149 "--workspace-id" ,
148150 workspaceId ,
149- "--quiet" ,
151+ "--output" ,
152+ "json" ,
150153 ] ) ;
151154 expect ( importUploadRun . exitCode , importUploadRun . stderr ) . toBe ( 0 ) ;
152- const importedFileId = importUploadRun . stdout . trim ( ) ;
155+ const importData = parseStdoutJson < {
156+ files : Array < { fileId : string } > ;
157+ ingestion_id ?: string ;
158+ final_status ?: string ;
159+ } > ( importUploadRun . stdout ) ;
160+ // These assertions verify the full pipeline completed: ingestion_id proves the
161+ // job was created, and final_status COMPLETED proves parsing finished successfully.
162+ expect ( importData . ingestion_id ) . toBeTruthy ( ) ;
163+ expect ( importData . final_status ) . toBe ( "COMPLETED" ) ;
164+ const importedFileId = importData . files ?. [ 0 ] ?. fileId ;
153165 expect ( importedFileId ) . toMatch ( / ^ f i l e _ / ) ;
154166 fixtureFileIds . push ( importedFileId ) ;
155167
168+ // 2.8) Verify the imported file is actually visible in the KB — final_status
169+ // COMPLETED only proves the job finished; an independent doc list query
170+ // confirms the file was registered as a document in the index
171+ const importedFileName = basename ( importFilePath ) ;
172+ const docListRun = await runCommandE2e ( KNOWLEDGE_KB_DELETE_ROUTES , [
173+ "knowledge" ,
174+ "doc" ,
175+ "list" ,
176+ "--index-id" ,
177+ indexId ,
178+ "--workspace-id" ,
179+ workspaceId ,
180+ "--output" ,
181+ "json" ,
182+ ] ) ;
183+ expect ( docListRun . exitCode , docListRun . stderr ) . toBe ( 0 ) ;
184+ const docListData = parseStdoutJson < {
185+ data ?: { rows ?: Array < { doc_name ?: string ; status ?: string } > } ;
186+ } > ( docListRun . stdout ) ;
187+ const importedDoc = docListData . data ?. rows ?. find ( ( row ) =>
188+ row . doc_name ?. includes ( importedFileName ) ,
189+ ) ;
190+ expect ( importedDoc , `expected doc list to contain file "${ importedFileName } "` ) . toBeTruthy ( ) ;
191+
156192 // 3) Delete the base (--yes non-interactive; deleteKbWithRetry retries on
157193 // IndexStatusError: readiness can lag briefly even after the import completes)
158194 const deleteRun = await deleteKbWithRetry (
0 commit comments