ghostguild-org/server/utils/activityLog.js
Jennie Robinson Faber 0b3896d984
Some checks failed
Test / vitest (push) Successful in 11m42s
Test / playwright (push) Failing after 9m27s
Test / visual (push) Failing after 9m53s
Test / Notify on failure (push) Successful in 2s
refactor(community): rename Community Connections → Community Ecology
Simplify the feature to pure discovery (filter by topic, see matching
members, copy Slack handle). Drop the connection request/confirm flow
entirely — Connection model, 7 API endpoints, useConnections composable,
and TagInput component deleted.

- Rename communityConnections → communityEcology in schema, API, pages
- Delete legacy fields: offering, lookingFor, peerSupport
- New /ecology page, /api/ecology/suggestions, community-ecology.patch
- Nav: "Connections" → "Ecology", remove pending-count badge
- Fix auth/member.get.js missing craftTags + communityEcology
- Add community_ecology_updated activity log type
- Expose slackHandle conditionally when offerPeerSupport is true
- Add migration script at scripts/migrate-to-ecology.js (run before deploy)
2026-04-09 09:07:15 +01:00

77 lines
2.6 KiB
JavaScript

import ActivityLog from '../models/activityLog.js'
export const ACTIVITY_TYPES = {
MEMBER_JOINED: 'member_joined',
EVENT_REGISTERED: 'event_registered',
EVENT_CANCELLED: 'event_cancelled',
EVENT_WAITLISTED: 'event_waitlisted',
CIRCLE_CHANGED: 'circle_changed',
CONTRIBUTION_CHANGED: 'contribution_changed',
EMAIL_CHANGED: 'email_changed',
PROFILE_UPDATED: 'profile_updated',
SUBSCRIPTION_CREATED: 'subscription_created',
SUBSCRIPTION_CANCELLED: 'subscription_cancelled',
STATUS_CHANGED: 'status_changed',
ROLE_CHANGED: 'role_changed',
ADMIN_PROFILE_UPDATE: 'admin_profile_update',
SLACK_INVITED: 'slack_invited',
EMAIL_SENT: 'email_sent',
COMMUNITY_CONNECTIONS_UPDATED: 'community_connections_updated',
COMMUNITY_ECOLOGY_UPDATED: 'community_ecology_updated',
CONNECTION_REQUESTED: 'connection_requested',
CONNECTION_CONFIRMED: 'connection_confirmed',
TAG_SUGGESTED: 'tag_suggested'
}
export const ACTIVITY_TYPE_DEFAULTS = {
member_joined: 'public',
event_registered: 'public',
event_cancelled: 'member',
event_waitlisted: 'member',
circle_changed: 'member',
contribution_changed: 'member',
email_changed: 'member',
profile_updated: 'member',
subscription_created: 'member',
subscription_cancelled: 'member',
status_changed: 'admin',
role_changed: 'admin',
admin_profile_update: 'admin',
slack_invited: 'admin',
email_sent: 'member',
community_connections_updated: 'member',
community_ecology_updated: 'member',
connection_requested: 'member',
connection_confirmed: 'member',
tag_suggested: 'member'
}
/**
* Log an activity for a member. Fire-and-forget — catches errors
* and logs to console without blocking the request.
*
* @param {string|ObjectId} memberId
* @param {string} type - one of ACTIVITY_TYPES values
* @param {object} [metadata={}]
* @param {object} [options]
* @param {string|ObjectId} [options.performedBy] - admin who initiated the action
* @param {string} [options.visibility] - override default visibility
* @param {Date} [options.timestamp] - override Date.now (for backfill)
*/
export async function logActivity(memberId, type, metadata = {}, options = {}) {
try {
const visibility = options.visibility || ACTIVITY_TYPE_DEFAULTS[type] || 'member'
const doc = {
member: memberId,
type,
visibility,
metadata
}
if (options.performedBy) doc.performedBy = options.performedBy
if (options.timestamp) doc.timestamp = options.timestamp
return await ActivityLog.create(doc)
} catch (err) {
console.error(`[activityLog] Failed to log ${type} for member ${memberId}:`, err)
}
}