[OPIK-6260] [BE] [FE] feat: display recent activity on project home page#6595
[OPIK-6260] [BE] [FE] feat: display recent activity on project home page#6595
Conversation
BE: New aggregated endpoint GET /v1/private/projects/{projectId}/recent-activity
that fetches the most recent items across 6 entity types (experiments,
optimizations, dataset/test suite versions, agent config blueprints, alert
events) in parallel, merges and returns the top N sorted by date.
Also enriches alert event logs with project_id in markers for project-scoped
filtering.
FE: Redesigned project home page with greeting, action buttons, and recent
activity feed. Split sidebar into Home + Ollie tabs. Added /ollie route for
full-page assistant (previous home behavior).
|
🔄 Test environment deployment process has started Phase 1: Deploying base version You can monitor the progress here. |
|
✅ Test environment is now available! To configure additional Environment variables for your environment, run [Deploy Opik AdHoc Environment workflow] (https://github.com/comet-ml/comet-deployment/actions/workflows/deploy_opik_adhoc_env.yaml) Access Information
The deployment has completed successfully and the version has been verified. |
|
🌙 Nightly cleanup: The test environment for this PR ( |
|
🔄 Test environment deployment process has started Phase 1: Deploying base version You can monitor the progress here. |
|
✅ Test environment is now available! To configure additional Environment variables for your environment, run [Deploy Opik AdHoc Environment workflow] (https://github.com/comet-ml/comet-deployment/actions/workflows/deploy_opik_adhoc_env.yaml) Access Information
The deployment has completed successfully and the version has been verified. |
- Fix import order in RecentActivitySection (external before internal) - Add @max(100) to size query param in RecentActivityResource - Pass size through to per-source queries instead of hardcoded limit - Use UserLog constants for marker keys and add null guard in fetchAlertEvents - Fix dataset/test suite links to navigate to /items directly
|
🔄 Test environment deployment process has started Phase 1: Deploying base version You can monitor the progress here. |
Tests cover: merge/sort across sources, size limiting, graceful degradation (partial + total failure), alert event null guard filtering, and empty project handling.
|
✅ Test environment is now available! To configure additional Environment variables for your environment, run [Deploy Opik AdHoc Environment workflow] (https://github.com/comet-ml/comet-deployment/actions/workflows/deploy_opik_adhoc_env.yaml) Access Information
The deployment has completed successfully and the version has been verified. |
Home should always be visible; only Ollie depends on the assistant plugin.
|
🔄 Test environment deployment process has started Phase 1: Deploying base version You can monitor the progress here. |
|
✅ Test environment is now available! To configure additional Environment variables for your environment, run [Deploy Opik AdHoc Environment workflow] (https://github.com/comet-ml/comet-deployment/actions/workflows/deploy_opik_adhoc_env.yaml) Access Information
The deployment has completed successfully and the version has been verified. |
aadereiko
left a comment
There was a problem hiding this comment.
In general, looks good! I've left a few comments how to make the code more semantically proper. Up to you if you want to fix it, good to go for the FE side.
andrescrz
left a comment
There was a problem hiding this comment.
Please check the BE feedback. Some comments were written once, but apply everywhere in the PR.
- Rename showHome → showOlliePage (only controls Ollie visibility now) - Replace Button+onClick with Link for nav buttons and activity items - Move formatRelativeDateTime to @/lib/date.ts alongside other date utils
|
🔄 Test environment deployment process has started Phase 1: Deploying base version You can monitor the progress here. |
|
✅ Test environment is now available! To configure additional Environment variables for your environment, run [Deploy Opik AdHoc Environment workflow] (https://github.com/comet-ml/comet-deployment/actions/workflows/deploy_opik_adhoc_env.yaml) Access Information
The deployment has completed successfully and the version has been verified. |
- Rename endpoint path to /activities (RESTful plural) - Add @consumes(JSON), @JSONVIEW, @apiresponse docs (200, 400, 500) - Add pagination (RecentActivityPage with page/size/total/projectId/content) - Add createdBy field to RecentActivityItem - Use @builder pattern for all DTOs and construction - Remove top-level onErrorResume (errors bubble as 500) - Add class-level javadoc documenting page-1 limitation - Parallelize JDBI sources (datasets + agent configs as separate Monos) - Merge dataset/test suite query into single call (drop type filter) - Add UUIDv7 30-day lookback filter for dataset query scan reduction - Import HashMap instead of inline java.util.HashMap - Update unit tests: @Injectmocks, Podam, precise mocks, full object assertions - Add resource-level black box tests with Testcontainers (all entity types, sort order, project isolation, permission enforcement)
…stamps - Hide "View dashboards" button when canViewDashboards is false - Guard future timestamps in formatRelativeDateTime to prevent "0 days ago"
|
🔄 Test environment deployment process has started Phase 1: Deploying base version You can monitor the progress here. |
|
✅ Test environment is now available! To configure additional Environment variables for your environment, run [Deploy Opik AdHoc Environment workflow] (https://github.com/comet-ml/comet-deployment/actions/workflows/deploy_opik_adhoc_env.yaml) Access Information
The deployment has completed successfully and the version has been verified. |
|
🌙 Nightly cleanup: The test environment for this PR ( |
|
🔄 Test environment deployment process has started Phase 1: Deploying base version You can monitor the progress here. |
|
✅ Test environment is now available! To configure additional Environment variables for your environment, run [Deploy Opik AdHoc Environment workflow] (https://github.com/comet-ml/comet-deployment/actions/workflows/deploy_opik_adhoc_env.yaml) Access Information
The deployment has completed successfully and the version has been verified. |
andrescrz
left a comment
There was a problem hiding this comment.
I left a bit more of feedback for stuff to check, but no blockers. Some of them are questions and others are things that can be followed-up in a separated PR. Please take a look at one comment from the previous review, not sure if you saw it.
| @JsonView(View.Public.class) int page, | ||
| @JsonView(View.Public.class) int size, | ||
| @JsonView(View.Public.class) long total, | ||
| @JsonView(View.Public.class) UUID projectId, |
There was a problem hiding this comment.
Minor: we generally keep the top level page free of content fields, such as projectId here. On the other hand, while this is inconsistent with the service conventions, we know the projectId is unique here, so the response is more optimal.
It's a matter of conventions vs optimising. I'm fine with this.
| @JsonView(View.Public.class) Instant createdAt, | ||
| @JsonView(View.Public.class) UUID resourceId, | ||
| @JsonView(View.Public.class) String createdBy) { |
There was a problem hiding this comment.
Very nit: we typically list together createdBy, createdAt as it's more readable.
| } | ||
|
|
||
| @Builder(toBuilder = true) | ||
| public record RecentDatasetVersion(UUID datasetId, String datasetName, String datasetType, Instant createdAt, |
There was a problem hiding this comment.
Minor: this record represents the DB row, feel free to add @NonNull validations to those fields where that's enforced on the DB.
| AND dv.created_at > d.created_at | ||
| AND dv.items_total > 0 | ||
| ) combined | ||
| ORDER BY created_at DESC |
There was a problem hiding this comment.
Related to similar questions: is this created_at sorting over the whole union performant? Do we lack or need index here?
| } | ||
|
|
||
| private Mono<List<RecentActivityItem>> fetchDatasetSources(String workspaceId, UUID projectId, int size) { | ||
| var minId = idGenerator.generateId(Instant.now().minus(LOOKBACK_DAYS, ChronoUnit.DAYS)); |
There was a problem hiding this comment.
I believe this generateId method doesn't properly set the random part of the UUID to all 0s or all F. There were some other methods available in the service, please double check. You might leave some records behind, which might be ok when no strong precision is required. Eventually, we need to clean up these duplications in our code base.
| wireMock.server().stop(); | ||
| } | ||
|
|
||
| private RecentActivity.RecentActivityPage getActivities(UUID projectId, String apiKey, String workspaceName) { |
There was a problem hiding this comment.
Minor: we generally create a separated client class to encapsulate and reuse all these.
|
|
||
| var result = getActivities(projectId, API_KEY, TEST_WORKSPACE_NAME); | ||
|
|
||
| assertThat(result.content()).isNotEmpty(); |
There was a problem hiding this comment.
Minor: I miss some assertions on the whole content (full object assertion).
Applies to all tests.
|
|
||
| private static final String WORKSPACE_ID = UUID.randomUUID().toString(); | ||
| private static final UUID PROJECT_ID = UUID.randomUUID(); | ||
| private static final PodamFactory PODAM = PodamFactoryUtils.newPodamFactory(); |
There was a problem hiding this comment.
Minor: podam is in theory not fully thread-safe, better not have it as static. We aren't running paralel tests now, that's why it works.
| }) | ||
| .onErrorResume(e -> { | ||
| log.error("Failed to fetch recent activity for project '{}'", projectId, e); | ||
| return Mono.just(new RecentActivity(List.of())); |
There was a problem hiding this comment.
Please double check this, I believe you left it behind.
|
🌙 Nightly cleanup: The test environment for this PR ( |
Details
Redesigns the project home page to display a unified "Recent Activity" feed showing the most recent items across 6 entity types.
Backend
GET /v1/private/projects/{projectId}/recent-activity?size=10endpointRecentActivityServiceorchestrates 6 parallel queries (experiments, optimizations, dataset/test suite creations + version updates, agent config blueprints, alert events), merges results, sorts by date, and returns the top Nproject_idin markers to enable project-scoped filtering (WebhookEvent, WebhookHttpClient, WebhookPublisher, AlertEventLogsDAO)Frontend
ProjectHomePagewith greeting ("Hi, {username}"), action buttons (View logs, View dashboards), and Recent Activity sectionRecentActivitySectioncomponent with loading skeletons, empty state (activity-cloud icon), and activity item listACTIVITY_CONFIGrecord/ollieroute preserving the old full-page AssistantSidebar experienceChange checklist
Issues
Testing
Documentation
N/A