fix(forms): link by an email collected as a form field, not only submitter_email

Root cause: association only ever looked at the dedicated submitter_email
(public 'your email' box / auth email). A form that asks for email as an
ordinary field stored it in answers, so submitter_email stayed null and
nothing matched -- 'Re-link' reported 0 ('already linked') and the
submission never appeared under the member. New pure deriveSubmitterEmail
(explicit > email-type field answer > any email-looking answer; trimmed
lowercase) + 5 tests. submitForm now derives + persists submitter_email
from answers; relinkAllSubmissions re-derives per submission from its
form_snapshot and backfills member_id + submitter_email for existing
rows. Suite 469.
This commit is contained in:
Moheeb Zara
2026-05-17 00:31:33 -07:00
parent c2f8368634
commit 9f0ee189a6
3 changed files with 107 additions and 10 deletions
+24
View File
@@ -24,6 +24,7 @@ import {
deriveFieldKeys,
escapeLike,
pickMemberForEmail,
deriveSubmitterEmail,
} from '@/lib/forms-logic'
import { INVITE_ROLES, isInviteRole, canAssignInviteRole } from '@/lib/invite-logic'
import { createInviteSchema, updateInviteSchema } from '@/lib/validations'
@@ -561,3 +562,26 @@ describe('pickMemberForEmail', () => {
])).toBe('y')
})
})
describe('deriveSubmitterEmail', () => {
const fields = [
{ key: 'name', type: 'short_text' },
{ key: 'contact', type: 'email' },
]
it('prefers the explicit submitter email', () => {
expect(deriveSubmitterEmail(fields, { contact: '[email protected]' }, '[email protected]')).toBe('[email protected]')
})
it('falls back to an email-type field answer (the bug fix)', () => {
expect(deriveSubmitterEmail(fields, { name: 'Jo', contact: ' [email protected] ' }, null)).toBe('[email protected]')
})
it('falls back to any answer that is a valid email when no email field', () => {
expect(deriveSubmitterEmail([{ key: 'q1', type: 'short_text' }], { q1: '[email protected]' })).toBe('[email protected]')
})
it('returns null when nothing looks like an email', () => {
expect(deriveSubmitterEmail(fields, { name: 'Jo', contact: 'not-an-email' }, '')).toBeNull()
expect(deriveSubmitterEmail([], {}, null)).toBeNull()
})
it('ignores a non-email explicit value and still finds the field', () => {
expect(deriveSubmitterEmail(fields, { contact: '[email protected]' }, 'garbage')).toBe('[email protected]')
})
})