From 749b40a80223d52d1223f8a49dc2127dc12c44e7 Mon Sep 17 00:00:00 2001 From: Sundaram Kumar Jha Date: Tue, 27 Oct 2026 13:10:28 +0530 Subject: [PATCH] fix(validation): accept ISO sourceAddedAt in documents schema The API returns memoryEntries[].sourceAddedAt as an ISO-8601 string. z.date() rejected it, causing DocumentsWithMemoriesResponseSchema and $fetch("@post/documents/documents") to fail on live responses. Coerce the wire value to a Date and cover ISO/null sourceAddedAt values. Refs #1847 --- packages/validation/api.test.ts | 59 +++++++++++++++++++++++++++++++++ packages/validation/api.ts | 2 +- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/packages/validation/api.test.ts b/packages/validation/api.test.ts index fa52ed89..5a9f4119 100644 --- a/packages/validation/api.test.ts +++ b/packages/validation/api.test.ts @@ -3,6 +3,7 @@ import { readFileSync } from "node:fs" import { BulkDeleteMemoriesSchema, DocumentsWithMemoriesQuerySchema, + DocumentsWithMemoriesResponseSchema, ListMemoriesQuerySchema, SearchRequestSchema, Searchv4RequestSchema, @@ -175,3 +176,61 @@ describe("pagination query schemas", () => { expect(BulkDeleteMemoriesSchema.safeParse(ok).success).toBe(true) }) }) + +describe("DocumentsWithMemoriesResponseSchema", () => { + const document = { + id: "doc_123", + orgId: "org_123", + userId: "user_123", + createdAt: "2026-10-27T06:48:08.112Z", + updatedAt: "2026-10-27T06:48:13.638Z", + memoryEntries: [ + { + id: "mem_123", + memory: "Nora owns the billing pipeline.", + spaceId: "space_123", + orgId: "org_123", + createdAt: "2026-10-27T06:52:34.160Z", + updatedAt: "2026-10-27T06:52:34.160Z", + sourceAddedAt: "2026-10-27T06:52:34.160Z", + sourceRelevanceScore: 0.87, + sourceMetadata: null, + spaceContainerTag: "space_123", + }, + ], + } + + const pagination = { + currentPage: 1, + limit: 10, + totalItems: 1, + totalPages: 1, + } + + it("coerces sourceAddedAt ISO strings returned by the API", () => { + const parsed = DocumentsWithMemoriesResponseSchema.parse({ + documents: [document], + pagination, + }) + + const sourceAddedAt = parsed.documents[0]?.memoryEntries[0]?.sourceAddedAt + expect(sourceAddedAt).toBeInstanceOf(Date) + expect(sourceAddedAt?.toISOString()).toBe("2026-10-27T06:52:34.160Z") + }) + + it("accepts a null sourceAddedAt", () => { + const parsed = DocumentsWithMemoriesResponseSchema.parse({ + documents: [ + { + ...document, + memoryEntries: [ + { ...document.memoryEntries[0], sourceAddedAt: null }, + ], + }, + ], + pagination, + }) + + expect(parsed.documents[0]?.memoryEntries[0]?.sourceAddedAt).toBeNull() + }) +}) diff --git a/packages/validation/api.ts b/packages/validation/api.ts index ae6ac319..3527780c 100644 --- a/packages/validation/api.ts +++ b/packages/validation/api.ts @@ -1046,7 +1046,7 @@ export const AnalyticsMemoryResponseSchema = z.object({ }) export const MemoryEntryAPISchema = MemoryEntrySchema.extend({ - sourceAddedAt: z.date().nullable(), // From join relationship + sourceAddedAt: z.coerce.date().nullable(), // From join relationship; API returns ISO strings sourceRelevanceScore: z.number().nullable(), // From join relationship sourceMetadata: z.record(z.unknown()).nullable(), // From join relationship spaceContainerTag: z.string().nullable(), // From join relationship