Skip to content

feat: general volunteer activity log (audit trail) for contact changes, opportunity transitions, availability #919

Description

@nadavosa

Description

The volunteer profile page (fe) has a placeholder "Activity Log" section (src/hooks/useVolunteerProfileSections.tsx) meant to show a chronological audit trail of things that happen to a volunteer's record: contact-detail changes, opportunity status transitions (suggested/matched/active/past), being marked available, and anything else that changes on the profile without a clear date/time record today. This needs a backend home, nothing like this exists yet.

Naming collision, read this first

There is already an entity/feature called ActivityLog in this codebase (src/data/entity/m2m/activity-log.entity.ts, routes in src/server/routes/activity-log.routes.ts / m2m/activity-log.routes.ts, fe's apiPathActivityLog). That's a completely unrelated feature, an hours-worked ledger per opportunity-volunteer pairing ({date, hours} rows with a running total). Do not confuse the two or try to repurpose that entity/routes for this. Whatever gets built here needs a clearly distinct name, e.g. VolunteerAuditLog or VolunteerActivityHistory.

What's confirmed as not tracked with a date today

  • Contact-detail edits and availability/engagement status changes (VolunteerStateEngagementType.AVAILABLE / TEMP_UNAVAILABLE) both go through the same generic PATCH /volunteer/:id. Neither is currently recorded anywhere with a timestamp.
  • Opportunity status transitions go through PATCH /opportunity-volunteer/:m2mId {status} (OpportunityVolunteerStatusType: PENDING = "opp-pending" — the closest existing value to "suggested", MATCHED, ACTIVE, PAST). Not currently recorded either.
  • There may be other profile fields that change without a timestamp, worth a quick audit during implementation rather than assuming the three above are exhaustive.

Ask

  1. New entity/table for the audit trail: at minimum {volunteerId, type, detail, occurredAt, actor/source}.
  2. Write hooks at the integration points above. PATCH /volunteer/:id handles two different loggable changes (contact vs. availability) through one generic handler, so this will need a field-diff check on what actually changed (or a TypeORM subscriber), not just "log on every PATCH". PATCH /opportunity-volunteer/:m2mId is a single, more straightforward hook-in point.
  3. A new read endpoint, e.g. GET /volunteer/:id/activity-log, returning entries newest-first for the fe list.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions