diff --git a/backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/personal/service/PersonalVectorStore.java b/backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/personal/service/PersonalVectorStore.java index e1cb5559..eb31a8bc 100644 --- a/backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/personal/service/PersonalVectorStore.java +++ b/backend/ruoyi-modules/ruoyi-aihr/src/main/java/org/dromara/aihr/personal/service/PersonalVectorStore.java @@ -93,6 +93,9 @@ public class PersonalVectorStore { if (point == null || point.spaceId() <= 0 || point.itemId() <= 0 || point.fragmentId() <= 0) { throw new IllegalArgumentException("PERSONAL_VECTOR_POINT_INVALID"); } + if (point.capturedAt() == null) { + throw new IllegalArgumentException("PERSONAL_VECTOR_CAPTURED_AT_REQUIRED"); + } ArrayNode vector = parseVector(vectorJson); setOrValidateDimension(vector.size()); @@ -103,9 +106,7 @@ public class PersonalVectorStore { payload.put("item_id", point.itemId()); payload.put("fragment_id", point.fragmentId()); payload.put("source", point.source() == null ? "" : point.source()); - if (point.capturedAt() != null) { - payload.put("captured_at", point.capturedAt().toString()); - } + payload.put("captured_at", point.capturedAt().toString()); ObjectNode qdrantPoint = objectMapper.createObjectNode(); qdrantPoint.put("id", point.fragmentId()); qdrantPoint.set("vector", vector); diff --git a/backend/ruoyi-modules/ruoyi-aihr/src/test/java/org/dromara/aihr/personal/PersonalVectorStoreTest.java b/backend/ruoyi-modules/ruoyi-aihr/src/test/java/org/dromara/aihr/personal/PersonalVectorStoreTest.java index 9a34e6b0..fc2f0340 100644 --- a/backend/ruoyi-modules/ruoyi-aihr/src/test/java/org/dromara/aihr/personal/PersonalVectorStoreTest.java +++ b/backend/ruoyi-modules/ruoyi-aihr/src/test/java/org/dromara/aihr/personal/PersonalVectorStoreTest.java @@ -56,9 +56,24 @@ class PersonalVectorStoreTest { assertEquals(11, point.path("payload").path("space_id").asLong()); assertEquals(12, point.path("payload").path("item_id").asLong()); assertEquals(13, point.path("payload").path("fragment_id").asLong()); + assertEquals("2026-07-01T09:00", point.path("payload").path("captured_at").asText()); assertFalse(point.path("payload").has("content")); } + @Test + void rejectsMissingCaptureMetadataBeforeHttp() { + List seen = new ArrayList<>(); + PersonalVectorStore store = fixture(seen, request -> ok("{}")); + PersonalOwner owner = new PersonalOwner("t", 1, null); + var point = new PersonalVectorStore.VectorPoint(1, 2, 3, "file", null); + + IllegalArgumentException error = assertThrows(IllegalArgumentException.class, + () -> store.upsert(owner, point, "[1,2]")); + + assertEquals("PERSONAL_VECTOR_CAPTURED_AT_REQUIRED", error.getMessage()); + assertTrue(seen.isEmpty()); + } + @Test void collectionCreationAndPayloadIndexesAreStable() throws Exception { List seen = new ArrayList<>();