feat(activity): enrich activities with iam User display names#193
Open
mattdjenkinson wants to merge 1 commit intomainfrom
Open
feat(activity): enrich activities with iam User display names#193mattdjenkinson wants to merge 1 commit intomainfrom
mattdjenkinson wants to merge 1 commit intomainfrom
Conversation
Resolve actors and User-typed link targets to human-readable
display names so the UI can show names instead of raw emails / UIDs.
- ActivityActor gets a new omitempty DisplayName field; ActivityLink
gets DisplayName + Email (populated only when the link's resource
is an iam User).
- New UserResolver interface in internal/processor/userlookup.go
with NoopUserResolver and a CachedUserResolver wrapper (TTL,
single-flight, negative caching).
- ResolveActorWithResolver populates the actor's DisplayName from
the iam User's spec.givenName + spec.familyName via the resolver.
- ActivityBuilder gains a UserResolver and rewrites the summary at
build time: substitutes actor.Name (typically email) with
actor.DisplayName, upgrades existing actor link() entries in
place (or appends a synthetic actor link), and hydrates User-typed
link targets via the resolver.
- *WithResolver overloads on Evaluate{Audit,Event}Rules and
EvaluateCompiledAuditRules let callers opt into enrichment without
changing the existing public API.
- IAMUserResolver in internal/activityprocessor uses a
controller-runtime client to fetch iam.miloapis.com/v1alpha1/User
CRs as Unstructured (no milo Go-types dependency).
- The processor wires NewCachedUserResolver(NewIAMUserResolver(...))
at startup; resolver errors are silently ignored, so the activity
is still emitted with raw values when lookup fails.
All new optional fields are backwards compatible: consumers that
don't know about DisplayName continue to work, and once they
recognise it they get richer data automatically.
Tests:
- internal/processor/userlookup_test.go: cache hit, neg-cache,
TTL expiry, single-flight collapse, error-not-cached, empty-key
short-circuit.
- internal/processor/enrichment_test.go: actor replacement, link
upgrade in place, actor-not-in-summary, user link hydration,
non-user link untouched, ResolveActorWithResolver paths.
This was referenced May 1, 2026
mattdjenkinson
added a commit
that referenced
this pull request
May 1, 2026
## Summary Rebuilds the activity UI to consume `@datum-cloud/datum-ui` as a peer dependency and converts the activity feed, events, and audit views to table + timeline layouts with manual pagination. This is the **UI half** of the work previously bundled in #192; the matching backend display-name enrichment ships in #193. ## What changes **Design system migration** - Promote `@datum-cloud/datum-ui` to a peer dependency - Replace local shadcn primitives with datum-ui exports where possible - Drop Tailwind/PostCSS configs and unused local components - Externalize peer deps in `rollup.config.mjs` - Update `Dockerfile` to drop postcss/tailwind copies **Layout refactor** - Convert `ActivityFeed`, `EventsFeed`, `AuditLogQueryComponent` to table/timeline views - Manual "Load more" pagination (replaces auto-scroll observer that was misfiring on tab switches) - Add `Timestamp` component using `Intl.DateTimeFormat` for timezone-aware rendering with a single tooltip - Add reusable details-panel primitives in `components/details.tsx`; apply across activity/audit/event expanded views - Truncation with tooltips on summary/notes columns - Tooltip shim renders Radix Tooltip directly (mirroring datum-ui styles) so flex truncation actually engages - Normalize toolbar styling, filter chips, and details-panel padding across feeds - Remove "unsaved changes" badge **Display name support** - Mirror `displayName` / `email` (both optional) on `Actor` and `ActivityLink` TS types - Render `actor.displayName ?? actor.name` with email/UID hover; user-typed link markers swap in `displayName` as visible text - Falls back cleanly when backend hasn't populated the new fields, so this PR can land independently of #193 ## Tooltip / truncation notes datum-ui's Tooltip wraps the trigger in a `relative inline-flex` span which broke parent flex truncation. To keep datum-ui's visual styling, the local Tooltip in `ui/tooltip.tsx` re-implements Radix Tooltip directly with the same class tokens — same look, no flex-chain breakage. <img width="1502" height="829" alt="Screenshot 2026-05-01 at 16 27 29" src="https://github.com/user-attachments/assets/57a564c5-dfd3-4d8c-91f8-3e5bc46367ba" /> <img width="1624" height="1061" alt="Screenshot 2026-05-01 at 13 55 32" src="https://github.com/user-attachments/assets/716e691e-3b80-4928-a139-54aafd2839fe" /> <img width="1624" height="1061" alt="Screenshot 2026-05-01 at 13 55 40" src="https://github.com/user-attachments/assets/53e7ff60-8132-4645-bb13-d4d989190e4f" /> <img width="1624" height="1061" alt="Screenshot 2026-05-01 at 13 55 54" src="https://github.com/user-attachments/assets/9c013a99-3e0a-4120-aa14-b69126510632" /> <img width="1624" height="1061" alt="Screenshot 2026-05-01 at 13 56 07" src="https://github.com/user-attachments/assets/38bed23d-40a1-4a05-949d-d9871cc39c1f" /> <img width="1624" height="1061" alt="Screenshot 2026-05-01 at 14 09 47" src="https://github.com/user-attachments/assets/a8f94d88-5038-4cfe-83b9-19ed75a14ab7" />
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Enriches activity records with display names looked up from iam User CRs, so the UI can render human names with email/UID available on hover. This is the backend half of the work previously bundled in #192; the matching UI changes ship in a separate PR.
What changes
UserResolverinterface ininternal/processorwith TTL + single-flightCachedUserResolverand aNoopUserResolverfor testsIAMUserResolverininternal/activityprocessorthat fetchesiam.miloapis.com/v1alpha1Users via controller-runtime + UnstructuredActivityActorgainsDisplayName(omitempty);ActivityLinkgainsDisplayNameandEmail(both omitempty)ResolveActorWithResolver(ctx, user, resolver)populates the actor'sDisplayNamefor human users (falls back to email when no User record found)link()evaluation, User-typed links are hydrated with display name + emailEvaluateAuditRulesWithResolver/EvaluateEventRulesWithResolveroverloads thread the resolver through; the existing non-resolver entrypoints remain backwards-compatibleprocessor.gowiresNewCachedUserResolver(NewIAMUserResolver(k8sClient), 0, 0)(defaults: 5m positive, 30s negative TTL)Tests
internal/processor/userlookup_test.gocovers cache hit, negative cache, TTL expiry, single-flight collapse, error not cached, empty-key short-circuitinternal/processor/enrichment_test.gocovers actor email replacement, link upgrade, and User-typed link hydrationNotes
ui/already declaredisplayName/emailas optional, so the UI PR can ship independently — fields stay undefined until this landsTest plan
spec.actor.displayNamepopulated and User-typed links carrydisplayName+emailgivenName/familyNamefalls back to email cleanly