diff --git a/internal/models/activity.go b/internal/models/activity.go index a34d2f58..cec69e26 100644 --- a/internal/models/activity.go +++ b/internal/models/activity.go @@ -16,6 +16,11 @@ type Activity struct { Source string `json:"source"` Metadata string `json:"metadata,omitempty"` // JSON CreatedAt time.Time `json:"created_at"` + + // Enrichment fields — populated by handlers, not stored in DB + ItemTitle string `json:"item_title,omitempty"` + ItemSlug string `json:"item_slug,omitempty"` + CollectionSlug string `json:"collection_slug,omitempty"` } type ActivityListParams struct { diff --git a/internal/server/handlers_activity.go b/internal/server/handlers_activity.go index 17a8ca10..3d100b74 100644 --- a/internal/server/handlers_activity.go +++ b/internal/server/handlers_activity.go @@ -39,6 +39,9 @@ func (s *Server) handleListWorkspaceActivity(w http.ResponseWriter, r *http.Requ activities = []models.Activity{} } + // Enrich activities with item titles and collection info + s.enrichActivities(activities) + writeJSON(w, http.StatusOK, activities) } @@ -73,5 +76,25 @@ func (s *Server) handleListDocumentActivity(w http.ResponseWriter, r *http.Reque activities = []models.Activity{} } + // Enrich activities with item titles and collection info + s.enrichActivities(activities) + writeJSON(w, http.StatusOK, activities) } + +// enrichActivities populates ItemTitle, ItemSlug, and CollectionSlug +// on each activity by looking up the referenced item. +func (s *Server) enrichActivities(activities []models.Activity) { + for i := range activities { + if activities[i].DocumentID == "" { + continue + } + item, err := s.store.GetItem(activities[i].DocumentID) + if err != nil || item == nil { + continue + } + activities[i].ItemTitle = item.Title + activities[i].ItemSlug = item.Slug + activities[i].CollectionSlug = item.CollectionSlug + } +} diff --git a/web/src/lib/types/index.ts b/web/src/lib/types/index.ts index 09090a91..ef1079e8 100644 --- a/web/src/lib/types/index.ts +++ b/web/src/lib/types/index.ts @@ -238,6 +238,9 @@ export interface Activity { source: string; metadata: string; created_at: string; + item_title?: string; + item_slug?: string; + collection_slug?: string; } // ─── Dashboard ─────────────────────────────────────────────────────────────── diff --git a/web/src/routes/[workspace]/activity/+page.svelte b/web/src/routes/[workspace]/activity/+page.svelte index 9de59f13..2d9ed68b 100644 --- a/web/src/routes/[workspace]/activity/+page.svelte +++ b/web/src/routes/[workspace]/activity/+page.svelte @@ -88,10 +88,11 @@ } } - // Client-side collection filter (metadata contains item_collection info) + // Client-side collection filter using enriched top-level field or metadata fallback let filteredActivities = $derived.by(() => { if (!filterCollection) return activities; return activities.filter((a) => { + if (a.collection_slug) return a.collection_slug === filterCollection; try { const meta = JSON.parse(a.metadata); return meta.collection_slug === filterCollection || meta.collection === filterCollection; @@ -299,6 +300,9 @@