import { requireAuth } from '../../utils/auth.js' import { validateBody } from '../../utils/validateBody.js' import { onboardingTrackSchema } from '../../utils/schemas.js' import Member from '../../models/member.js' import { logActivity } from '../../utils/activityLog.js' export default defineEventHandler(async (event) => { const member = await requireAuth(event) const { goal } = await validateBody(event, onboardingTrackSchema) // Already graduated — no-op if (member.onboarding?.completedAt) { return { success: true } } // Idempotent — already tracked if (member.onboarding?.[goal]) { return { success: true } } // Set the boolean await Member.findByIdAndUpdate(member._id, { $set: { [`onboarding.${goal}`]: true }, }) // Log the individual goal completion await logActivity(member._id, 'member_onboarding_goal_completed', { goal }, { visibility: 'admin' }) // Graduation check — atomic so concurrent requests can't double-graduate const graduated = await Member.findOneAndUpdate( { _id: member._id, 'onboarding.completedAt': null, 'onboarding.eventPageVisited': true, 'onboarding.ecologyPageVisited': true, 'onboarding.wikiClicked': true, 'craftTags.0': { $exists: true }, 'communityEcology.topics': { $elemMatch: { state: { $in: ['help', 'interested', 'seeking'] } }, }, }, { $set: { 'onboarding.completedAt': new Date() } }, { new: true } ) if (graduated) { await logActivity(member._id, 'member_onboarding_completed', {}, { visibility: 'admin' }) } return { success: true, graduated: !!graduated } })