feat(client): agent activity history UI — "what Carol changed" #350
Labels
No labels
area:auth
area:ci
area:db
area:infra
area:native
area:pwa
area:service
epic
feature
foundation
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
james/carol#350
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Make the audit trail (#348,
GET /api/agent/audit) user-visible: api-client hooks + a paginated activity screen showing every change Carol made, newest first. Read-only for now — undo is a separate follow-up.Placement
The sidebar nav is a fixed union mirroring the design package, so this is not a new top-level nav item. It's a dedicated routable screen
apps/client/app/(app)/activity.tsx(likenotes.tsx— routable but out of the sidebar), reachable via a row/card in Settings (/account).Scope
@carol/api-client(hooks/audit.ts):useAuditLog()(first page) +useAuditLogInfinite()overGET /api/agent/audit, mirroringuseConversations/useConversationsInfiniteexactly (cursor envelope{ data, next_cursor }). Addkeys.auditLog. Barrel-export; thin structural test.apps/client/lib/activity/describeAuditEvent.ts):AuditEventDto -> { key, args }(an i18n key + interpolation args), NOT a hardcoded string. Derive from theaction(verb_nounper ADR-0030) +entityType: map the verb (created/updated/deleted/added/removed/…) to an i18n key and render the entity type, with a sensible fallback for an unknown verb. This is the tested core — unit tests for create/update/delete across a couple of entities + the fallback.activity.tsx: a paginated history screen mirroringnotes.tsx(DStheme.tokens.*, RN primitives,KeyboardAwareScrollVieworFlatList, loading/error/empty branches). Each event renders a one-line human description (via the helper +t()) + a relative/absolute timestamp; a "load more" affordance drivesuseAuditLogInfinite. Keep it thin — logic lives in the helper/hooks. (Before/after diff expansion is deferred polish.)account.tsx: a row/card ("Recent changes" / "What Carol changed") that navigates to/activity(expo-routerLink/useRouter).activitynamespace inpackages/i18n/messages/en.json(title, lede, empty/loading/error, load-more, the per-verb description keys, the account link label). Carol's voice: first person, sentence case, lead with the takeaway, no emoji. No hardcoded user-facing strings.es.jsonuntouched.Tests
describeAuditEventunit tests (the valuable core): the common verbs + an unknown-verb fallback, asserting the returned{ key, args }.keys.auditLogregistered), mirroringtests/contracts.test.ts.node-env — the visual screen is verified manually by the maintainer.Out of scope (follow-ups)
Part of epic #47; makes #348 visible.