feat: applicant.getMyVisaApplications gated by program toggle

Returns the caller's visa application rows when the program's
visaStatusVisibleToMembers toggle is on; returns null when it's off
(so the UI can hide the section entirely); returns an empty array
when the toggle is on but the caller has no needsVisa attendees.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matt
2026-04-28 19:33:40 +02:00
parent 0e104e0b6f
commit 7c86e42413
2 changed files with 195 additions and 0 deletions

View File

@@ -2774,4 +2774,53 @@ export const applicantRouter = router({
editableNow,
}
}),
/**
* Returns the caller's visa application rows (one per AttendingMember
* the caller owns) when their program has visaStatusVisibleToMembers=true.
* Returns null when the toggle is off so the UI can hide the section
* entirely. Returns an empty array when the toggle is on but the caller
* has no needsVisa attendees yet.
*/
getMyVisaApplications: protectedProcedure.query(async ({ ctx }) => {
const attendees = await ctx.prisma.attendingMember.findMany({
where: { userId: ctx.user.id },
include: {
confirmation: {
select: {
id: true,
project: {
select: {
id: true,
programId: true,
program: { select: { visaStatusVisibleToMembers: true } },
},
},
},
},
visaApplication: true,
},
})
const visibleAttendees = attendees.filter(
(a) => a.confirmation.project.program.visaStatusVisibleToMembers,
)
if (attendees.length > 0 && visibleAttendees.length === 0) {
return null
}
return visibleAttendees
.filter((a) => a.visaApplication !== null)
.map((a) => ({
id: a.visaApplication!.id,
attendingMemberId: a.id,
status: a.visaApplication!.status,
nationality: a.visaApplication!.nationality,
invitationSentAt: a.visaApplication!.invitationSentAt,
appointmentAt: a.visaApplication!.appointmentAt,
decisionAt: a.visaApplication!.decisionAt,
notes: a.visaApplication!.notes,
projectId: a.confirmation.project.id,
}))
}),
})