Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
12383a7
Add changeSummary API endpoint and UI components for description sour…
harshach Mar 17, 2026
f2b7b66
Fix checkstyle
harshach Mar 17, 2026
b77ce50
Integrate DescriptionSourceBadge into UI and address PR review comments
harshach Mar 21, 2026
3392ba8
Address PR review feedback: fix column FQN parsing, badge labels, bac…
harshach Mar 23, 2026
145d0b7
Improve change summary description layout
harshach Mar 23, 2026
a4aaabc
Expand change summary support across assets
harshach Mar 23, 2026
2511acc
Merge remote-tracking branch 'origin/main' into feature/change-summar…
pmbrull Mar 31, 2026
7db09ab
Fix changeSummary race condition and LLMModel entity type mismatch
pmbrull Apr 1, 2026
857a8ee
Fix Playwright strict mode violation and sync i18n translations
pmbrull Apr 1, 2026
2c4591e
fix
pmbrull Apr 2, 2026
71de2cb
Merge remote-tracking branch 'origin/main' into feature/change-summar…
pmbrull Apr 2, 2026
17a13a3
fix
pmbrull Apr 2, 2026
8d5e201
fix
pmbrull Apr 2, 2026
0f1f4ce
Merge branch 'main' into feature/change-summary-api
pmbrull Apr 2, 2026
1c4a1ea
implemented the new UI changes for AI description
Rohit0301 Apr 7, 2026
892495d
fixed the lint issues
Rohit0301 Apr 7, 2026
a18bfcb
addressed gitar comment
Rohit0301 Apr 7, 2026
48181a7
fixed the translations
Rohit0301 Apr 7, 2026
fd88967
fixed unit test
Rohit0301 Apr 7, 2026
b49dcdb
Merge branch 'main' into feature/change-summary-api
Rohit0301 Apr 8, 2026
bec52d6
addressed PR comment
Rohit0301 Apr 9, 2026
2da3ae0
fixed odcs playwright test
Rohit0301 Apr 9, 2026
532033e
Merge branch 'main' into feature/change-summary-api
harshach Apr 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties

.maestro
catalog-services/catalog-services.iml

# local docker volume
Expand Down Expand Up @@ -187,7 +187,9 @@ hive-mind-prompt-*.txt
.claude-flow/
memory
.claude/agents
.claude/hooks/
ingestion/.claude/agents
.claustre_session_id

# AI scaffold working documents — stay local, never committed
**/CONNECTOR_CONTEXT.md
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,7 @@ void test_paginationFetchesTagsAtBothEntityAndFieldLevels(TestNamespace ns) {
ListParams paramsTagsOnly = new ListParams();
paramsTagsOnly.setFields("tags");
paramsTagsOnly.setLimit(50);
paramsTagsOnly.addQueryParam("apiCollection", collection.getFullyQualifiedName());
ListResponse<APIEndpoint> listWithTagsOnly = client.apiEndpoints().list(paramsTagsOnly);
assertNotNull(listWithTagsOnly.getData());

Expand Down Expand Up @@ -594,6 +595,7 @@ void test_paginationFetchesTagsAtBothEntityAndFieldLevels(TestNamespace ns) {
ListParams paramsWithSchemas = new ListParams();
paramsWithSchemas.setFields("requestSchema,responseSchema,tags");
paramsWithSchemas.setLimit(50);
paramsWithSchemas.addQueryParam("apiCollection", collection.getFullyQualifiedName());
ListResponse<APIEndpoint> listWithSchemas = client.apiEndpoints().list(paramsWithSchemas);
assertNotNull(listWithSchemas.getData());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6240,4 +6240,168 @@ void test_listEntityHistoryByTimestamp_completePaginationCycle(TestNamespace ns)
}
}
}

// ===================================================================
// CHANGE SUMMARY TESTS
// ===================================================================

/**
* Test: Retrieve changeSummary by entity ID after updating the entity.
* The changeSummary API returns metadata about who changed each field,
* the source of the change, and when it was changed.
*/
@Test
void get_changeSummaryById_200(TestNamespace ns) throws Exception {
K createRequest = createMinimalRequest(ns);
T created = createEntity(createRequest);

created.setDescription("Updated description for changeSummary test");
T updated = patchEntity(created.getId().toString(), created);

OpenMetadataClient client = SdkClients.adminClient();
String response =
client
.getHttpClient()
.executeForString(
HttpMethod.GET,
"/v1/changeSummary/" + getEntityType() + "/" + updated.getId(),
null);
assertNotNull(response, "ChangeSummary response should not be null");
JsonNode result = MAPPER.readTree(response);
assertTrue(result.has("changeSummary"), "Response must contain changeSummary field");
assertTrue(result.has("totalEntries"), "Response must contain totalEntries field");
assertTrue(
result.get("totalEntries").asInt() > 0,
"totalEntries should be > 0 after patching description");
JsonNode changeSummaryNode = result.get("changeSummary");
assertTrue(
changeSummaryNode.isObject() && changeSummaryNode.size() > 0,
"changeSummary should contain at least one entry after patching description");
}
Comment on lines +6270 to +6280
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assertions only check for presence of changeSummary/totalEntries, which will still pass when the API returns an empty map. To validate behavior, assert that changeSummary contains the updated field (e.g., description) and that totalEntries is > 0 after the PATCH.

Copilot uses AI. Check for mistakes.

/**
* Test: Retrieve changeSummary by entity FQN after updating the entity.
*/
@Test
void get_changeSummaryByFqn_200(TestNamespace ns) throws Exception {
K createRequest = createMinimalRequest(ns);
T created = createEntity(createRequest);

created.setDescription("Updated description for changeSummary FQN test");
T updated = patchEntity(created.getId().toString(), created);

OpenMetadataClient client = SdkClients.adminClient();
String fqn = updated.getFullyQualifiedName();
String response =
client
.getHttpClient()
.executeForString(
HttpMethod.GET, "/v1/changeSummary/" + getEntityType() + "/name/" + fqn, null);
assertNotNull(response, "ChangeSummary response should not be null");
JsonNode result = MAPPER.readTree(response);
assertTrue(result.has("changeSummary"), "Response must contain changeSummary field");
assertTrue(result.has("totalEntries"), "Response must contain totalEntries field");
assertTrue(
result.get("totalEntries").asInt() > 0,
"totalEntries should be > 0 after patching description");
JsonNode changeSummaryNode = result.get("changeSummary");
assertTrue(
changeSummaryNode.isObject() && changeSummaryNode.size() > 0,
"changeSummary should contain at least one entry after patching description");
}

/**
* Test: Retrieve changeSummary with fieldPrefix filter.
* Verifies that the filtering parameter works correctly.
*/
@Test
void get_changeSummaryWithFieldPrefix_200(TestNamespace ns) throws Exception {
K createRequest = createMinimalRequest(ns);
T created = createEntity(createRequest);

created.setDescription("Updated for fieldPrefix test");
T updated = patchEntity(created.getId().toString(), created);

OpenMetadataClient client = SdkClients.adminClient();
String response =
client
.getHttpClient()
.executeForString(
HttpMethod.GET,
"/v1/changeSummary/"
+ getEntityType()
+ "/"
+ updated.getId()
+ "?fieldPrefix=description",
null);
assertNotNull(response, "ChangeSummary filtered response should not be null");
JsonNode result = MAPPER.readTree(response);
assertTrue(result.has("changeSummary"), "Response must contain changeSummary field");
assertTrue(result.has("totalEntries"), "Response must contain totalEntries field");

JsonNode changeSummary = result.get("changeSummary");
assertTrue(
changeSummary.isObject() && changeSummary.size() > 0,
"Filtered changeSummary should contain at least one entry matching 'description' prefix");
changeSummary
.fieldNames()
.forEachRemaining(
key ->
assertTrue(
key.startsWith("description"),
"All keys should start with 'description', but found: " + key));
}

/**
* Test: Retrieve changeSummary with pagination parameters.
*/
@Test
void get_changeSummaryWithPagination_200(TestNamespace ns) throws Exception {
K createRequest = createMinimalRequest(ns);
T created = createEntity(createRequest);

created.setDescription("Updated for pagination test");
patchEntity(created.getId().toString(), created);

OpenMetadataClient client = SdkClients.adminClient();
String response =
client
.getHttpClient()
.executeForString(
HttpMethod.GET,
"/v1/changeSummary/"
+ getEntityType()
+ "/"
+ created.getId()
+ "?limit=1&offset=0",
null);
assertNotNull(response, "ChangeSummary paginated response should not be null");
JsonNode result = MAPPER.readTree(response);
assertTrue(result.has("changeSummary"), "Response must contain changeSummary field");
assertTrue(result.has("totalEntries"), "Response must contain totalEntries field");
assertTrue(result.has("offset"), "Paginated response must contain offset field");
assertTrue(result.has("limit"), "Paginated response must contain limit field");
Comment thread
pmbrull marked this conversation as resolved.
}

/**
* Test: changeSummary returns 404 for non-existent entity.
*/
@Test
void get_changeSummaryNotFound_404(TestNamespace ns) {
OpenMetadataClient client = SdkClients.adminClient();
UUID randomId = UUID.randomUUID();
Exception thrown =
assertThrows(
Exception.class,
() ->
client
.getHttpClient()
.executeForString(
HttpMethod.GET,
"/v1/changeSummary/" + getEntityType() + "/" + randomId,
null));
assertTrue(
thrown.getMessage().contains("404") || thrown.getMessage().contains("not found"),
"Should get 404 for non-existent entity, got: " + thrown.getMessage());
}
}
Loading
Loading