customer-activity-feedrun.md00_intake/stub.mdThe Value section's activity block (latestSummary, latestTime, entries[{event, detail, time, type, impactTag}]) and its "View all activity" link to /customer/activity are dummy. A real
per-lead audit log already exists — the activity model
(packages/services/src/db/models/activity.ts)
records changeType, message, performedBy, status transitions per leadId — but it is not mapped
into the customer-facing shape, and the /customer/activity page does not exist.
Activity entries and maps them to the customer view:
event, detail, time, type (start | delivery | update | …), impactTag (e.g. no-impact).type / impactTag derivation from
changeType + action./customer/activity full-feed page the "View all activity" link targets./customer/activity renders the full, paginated feed for the active project.changeType → customer type/impactTag is the design crux; agree the visible
event set and tag rules with the user.touches: packages/services/src/db/models/activity.ts (read/map),
packages/services/src/server, apps/web/components/dashboard/customer/value-section.tsx,
apps/web/app/(app)/customer/activity/ (new page).01_define/output/spec.mdThe customer dashboard's Value section shows a "Latest update" activity block
(latestSummary, latestTime, entries[{ event, detail, time, type, impactTag }]) and a
"View all activity" link to /customer/activity — but both are dummy, fed from
apps/web/lib/mock/customer.ts. A real per-lead audit log already exists: the Activity model
records changeType, message, performedBy, oldStatus/newStatus and timestamps per leadId.
It is simply never mapped into the customer-facing shape, and /customer/activity does not exist.
This is feature 6 of the customer-dashboard-data epic (Build the Bridge / Q2 2026 Objective 3 —
Validate Technical Infrastructure & Payout Flow): replacing the last mocked sections of the customer
delivery window with real, tenant- and project-scoped data so the customer can trust what they see.
@sustentus/services/server) that pulls the signed-in customer's active
project's Activity entries and maps them into the customer view shape
(event, detail, time, type, impactTag), newest first.STATUS_CHANGE and CREATE entries — status
transitions and creation events (project/milestone start, status reached). Exclude UPDATE,
DELETE, ASSIGNMENT, COMMENT, OTHER (internal field edits and chatter never reach the
customer view).type derivation (decided default): CREATE → start; STATUS_CHANGE → delivery when the
new status denotes a completion/delivery/go-live milestone, otherwise update. These three map to
the icons the ValueSection already renders (start/delivery/update, fallback update).impactTag derivation (decided): always no-impact for this feature. The audit log carries no
impact signal; go-live impact is the health-engine's job (a separate epic feature). The field is
kept so the badge renders, but it is constant for now.latestSummary + latestTime from the most recent customer-visible entry.ValueSection (via the dashboard page's server fetch, replacing
d.activity) and build the /customer/activity full-feed page the "View all activity" link
targets, paginated, scoped to the active project.STATUS_CHANGE + CREATE events for the
customer's active project, newest first, with derived type and impactTag of "No impact".UPDATE, DELETE, ASSIGNMENT, COMMENT and OTHER audit entries are excluded from the
customer view.latestSummary and latestTime reflect the most recent customer-visible event (no mock)./customer/activity renders the full, paginated feed for the active project.Activity entries — this consumes the existing audit log only.no-impact — real go-live impact is the health-engine feature.02_build/output/notes.mdpackages/services/src/db/services/activity/index.ts: added the customer-facing
mapping (CustomerActivityEntry/CustomerActivityType), the visible-event filter
(STATUS_CHANGE + CREATE only), the type/impactTag derivation, and a paginated
findCustomerVisibleByLead(tenantId, leadId, opts) read that filters at the query level so
totals stay accurate.packages/services/src/db/services/customer-project/index.ts: added CustomerActivityFeed
and getCustomerActivity(tenantId, customerUserId, opts) — resolves the signed-in customer's
active project lead (tenant + customer scoped), delegates to the activity read, and derives
latestSummary/latestTime from the newest entry. Returns null when there's no active project.packages/services/src/db/services/index.ts: exported the new types.apps/web/lib/dashboard-utils.ts: added formatRelativeTime (ISO → "2 hours ago" … short date).apps/web/app/(app)/customer/dashboard/page.tsx: resolves project + activity together, maps the
feed into the ValueSection shape (replacing d.activity mock), formatting times for display.apps/web/app/(app)/customer/activity/page.tsx: new full, paginated feed page the "View all
activity" link targets, with empty state and prev/next pagination.STATUS_CHANGE + CREATE events for the
customer's active project, newest first, with derived type and impactTag of "No impact" —
getCustomerActivity (limit 3) feeds ValueSection via toActivityView.UPDATE, DELETE, ASSIGNMENT, COMMENT and OTHER entries are excluded — filtered in
findCustomerVisibleByLead via changeType: { $in: ["CREATE","STATUS_CHANGE"] }.latestSummary/latestTime reflect the most recent customer-visible event — derived from the
newest entry in getCustomerActivity./customer/activity renders the full, paginated feed for the active project — new page, 25/page.tenantId + customer +
isActiveProject, reusing the foundation's scoping; activity reads are tenant + leadId scoped.impactTag is intentionally constant no-impact (per the approved spec) — real go-live impact is
the health-engine feature, not this one.type derivation: CREATE → start; STATUS_CHANGE → delivery when the new status/action name
matches a completion/go-live hint (deliver|complete|done|live|launch|closed|paid), else update.formatRelativeTime); the service returns ISO strings so
the data layer stays presentation-free.03_release/output/changelog.mdLive entry: apps/help/app/changelog/2026-06-22-customer-activity-feed/page.mdx
You can now see what is happening on your project as it happens. Your dashboard shows the latest updates — status changes and milestones reached — and a new activity page gives you the full history, newest first. Internal working notes stay private; you only see the events that matter to you.
03_release/output/investor-update.mdWho it's for: Customers What shipped: The customer dashboard's activity feed now shows real status and milestone events from the project audit log, plus a full activity page. Why it matters: Another customer dashboard section runs on live data, advancing Build the Bridge / Q2 objective 3, Validate Technical Infrastructure & Payout Flow.
Dig deeper: <merged-PR URL> · <changelog entry URL>