feat(signup): community guidelines agreement and policies routes

Introduces /community-guidelines and /policies/{privacy,terms,[slug]} pages,
swaps the signup/invite checkbox from agreedToTerms to agreedToGuidelines,
adds Member.agreement.acceptedAt, and stamps the field when a Helcim
customer is created.
This commit is contained in:
Jennie Robinson Faber 2026-04-18 17:06:10 +01:00
parent e0d11e47f4
commit c5e901ed24
13 changed files with 1292 additions and 54 deletions

View file

@ -1,5 +1,4 @@
// Create a Helcim customer
import jwt from 'jsonwebtoken'
import Member from '../../models/member.js'
import { connectDB } from '../../utils/mongoose.js'
import { createHelcimCustomer } from '../../utils/helcim.js'
@ -7,7 +6,6 @@ import { createHelcimCustomer } from '../../utils/helcim.js'
export default defineEventHandler(async (event) => {
try {
await connectDB()
const config = useRuntimeConfig(event)
const body = await validateBody(event, helcimCustomerSchema)
// Check if member already exists
@ -33,34 +31,16 @@ export default defineEventHandler(async (event) => {
circle: body.circle,
contributionTier: body.contributionTier,
helcimCustomerId: customerData.id,
status: 'pending_payment'
status: 'pending_payment',
agreement: { acceptedAt: new Date() }
})
// Generate JWT token for the session
const token = jwt.sign(
{
memberId: member._id,
email: body.email,
helcimCustomerId: customerData.id
},
config.jwtSecret,
{ expiresIn: '7d' }
)
setAuthCookie(event, member)
// Set the session cookie server-side
setCookie(event, 'auth-token', token, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
maxAge: 60 * 60 * 24 * 7, // 7 days (matches verify.get.js and refresh.post.js)
path: '/',
domain: undefined // Let browser set domain automatically
})
return {
success: true,
customerId: customerData.id,
customerCode: customerData.customerCode,
token,
member: {
id: member._id,
email: member.email,

View file

@ -46,6 +46,7 @@ export default defineEventHandler(async (event) => {
contributionTier: body.contributionTier,
bio: body.motivation || undefined,
status: body.contributionTier === '0' ? 'active' : 'pending_payment',
agreement: { acceptedAt: new Date() },
})
await assignMemberNumber(member._id)