From 678fdfe388e6192802f1333d6bad122d4b3ea6b9 Mon Sep 17 00:00:00 2001 From: Jennie Robinson Faber Date: Mon, 27 Apr 2026 11:24:58 +0100 Subject: [PATCH] refactor(payments): extract PAYMENT_METADATA_TYPE constants --- server/api/helcim/initialize-payment.post.js | 6 +++--- server/utils/paymentTypes.js | 15 +++++++++++++++ server/utils/schemas.js | 3 ++- tests/server/api/helcim-payment.test.js | 4 ++++ 4 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 server/utils/paymentTypes.js diff --git a/server/api/helcim/initialize-payment.post.js b/server/api/helcim/initialize-payment.post.js index 71996b1..053b63d 100644 --- a/server/api/helcim/initialize-payment.post.js +++ b/server/api/helcim/initialize-payment.post.js @@ -10,10 +10,10 @@ export default defineEventHandler(async (event) => { const body = await validateBody(event, helcimInitializePaymentSchema) const metaType = body.metadata?.type - const isEventTicket = metaType === 'event_ticket' - const isSeriesTicket = metaType === 'series_ticket' + const isEventTicket = metaType === PAYMENT_METADATA_TYPES.EVENT_TICKET + const isSeriesTicket = metaType === PAYMENT_METADATA_TYPES.SERIES_TICKET const isTicket = isEventTicket || isSeriesTicket - const isMembershipSignup = metaType === 'membership_signup' + const isMembershipSignup = metaType === PAYMENT_METADATA_TYPES.MEMBERSHIP_SIGNUP if (!isTicket) { if (isMembershipSignup) { diff --git a/server/utils/paymentTypes.js b/server/utils/paymentTypes.js new file mode 100644 index 0000000..3c833a8 --- /dev/null +++ b/server/utils/paymentTypes.js @@ -0,0 +1,15 @@ +// Metadata.type values accepted by /api/helcim/initialize-payment. +// Shared by the Zod schema (PAYMENT_METADATA_TYPE_VALUES in z.enum) and the +// route handler so server-side wire validation stays single-sourced. The client +// composable intentionally uses inline string literals — server-side z.enum +// rejects any drift as a 400. + +export const PAYMENT_METADATA_TYPES = { + EVENT_TICKET: 'event_ticket', + SERIES_TICKET: 'series_ticket', + SUBSCRIPTION: 'subscription', + CARD_VERIFY: 'card_verify', + MEMBERSHIP_SIGNUP: 'membership_signup' +} + +export const PAYMENT_METADATA_TYPE_VALUES = Object.values(PAYMENT_METADATA_TYPES) diff --git a/server/utils/schemas.js b/server/utils/schemas.js index c04a649..cb75944 100644 --- a/server/utils/schemas.js +++ b/server/utils/schemas.js @@ -1,5 +1,6 @@ import * as z from 'zod' import { ADMIN_ALERT_TYPES } from '../models/adminAlertDismissal.js' +import { PAYMENT_METADATA_TYPE_VALUES } from './paymentTypes.js' export const emailSchema = z.object({ email: z.string().trim().toLowerCase().email() @@ -71,7 +72,7 @@ export const helcimInitializePaymentSchema = z.object({ amount: z.number().min(0).optional(), customerCode: z.string().max(200).optional(), metadata: z.object({ - type: z.enum(['event_ticket', 'series_ticket', 'subscription', 'card_verify', 'membership_signup']).optional(), + type: z.enum(PAYMENT_METADATA_TYPE_VALUES).optional(), eventTitle: z.string().max(500).optional(), eventId: z.string().max(200).optional(), seriesId: z.string().max(200).optional(), diff --git a/tests/server/api/helcim-payment.test.js b/tests/server/api/helcim-payment.test.js index 1c8d724..ff21f93 100644 --- a/tests/server/api/helcim-payment.test.js +++ b/tests/server/api/helcim-payment.test.js @@ -3,6 +3,7 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' import { requireAuth, getOptionalMember } from '../../../server/utils/auth.js' import { validateBody as importedValidateBody } from '../../../server/utils/validateBody.js' import { loadPublicEvent } from '../../../server/utils/loadEvent.js' +import { PAYMENT_METADATA_TYPES } from '../../../server/utils/paymentTypes.js' import Member from '../../../server/models/member.js' import Series from '../../../server/models/series.js' import initPaymentHandler from '../../../server/api/helcim/initialize-payment.post.js' @@ -22,6 +23,9 @@ vi.mock('../../../server/models/series.js', () => ({ default: { findOne: vi.fn() // helcimInitializePaymentSchema is a Nitro auto-import used by validateBody vi.stubGlobal('helcimInitializePaymentSchema', {}) +// PAYMENT_METADATA_TYPES is a Nitro auto-import from server/utils/paymentTypes.js +vi.stubGlobal('PAYMENT_METADATA_TYPES', PAYMENT_METADATA_TYPES) + const mockFetch = vi.fn() vi.stubGlobal('fetch', mockFetch)