feat(logistics): departure-after-arrival validation + travel/visa CSV export
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m11s
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m11s
- upsertFlightDetail throws BAD_REQUEST when departureAt < arrivalAt - Travel tab: Download CSV button (project/attendee/email/flight fields/status/visa) - Visas tab: Download CSV button (project/attendee/nationality/status/dates/notes) - TDD: 2 new tests (rejects invalid, accepts valid); all 6 flight tests pass Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -174,6 +174,64 @@ describe('logistics flight detail procedures', () => {
|
||||
expect(count).toBe(1)
|
||||
})
|
||||
|
||||
it('upsertFlightDetail rejects when departureAt < arrivalAt', async () => {
|
||||
const admin = await createTestUser('SUPER_ADMIN')
|
||||
userIds.push(admin.id)
|
||||
const { program, lead, attendingMember } = await setupConfirmedFinalist(
|
||||
`flight-dep-before-arr-${uid()}`,
|
||||
)
|
||||
programIds.push(program.id)
|
||||
userIds.push(lead.id)
|
||||
|
||||
const caller = createCaller(logisticsRouter, {
|
||||
id: admin.id,
|
||||
email: admin.email,
|
||||
role: 'SUPER_ADMIN',
|
||||
})
|
||||
|
||||
const arrivalDate = new Date('2026-06-28T14:00:00Z')
|
||||
const departureBeforeArrival = new Date('2026-06-28T10:00:00Z') // 4 hours earlier
|
||||
|
||||
await expect(
|
||||
caller.upsertFlightDetail({
|
||||
attendingMemberId: attendingMember.id,
|
||||
arrivalAt: arrivalDate,
|
||||
departureAt: departureBeforeArrival,
|
||||
arrivalFlightNumber: 'AF7400',
|
||||
departureFlightNumber: 'AF7405',
|
||||
}),
|
||||
).rejects.toMatchObject({ code: 'BAD_REQUEST', message: 'Departure must be after arrival' })
|
||||
})
|
||||
|
||||
it('upsertFlightDetail succeeds when departureAt >= arrivalAt', async () => {
|
||||
const admin = await createTestUser('SUPER_ADMIN')
|
||||
userIds.push(admin.id)
|
||||
const { program, lead, attendingMember } = await setupConfirmedFinalist(
|
||||
`flight-dep-after-arr-${uid()}`,
|
||||
)
|
||||
programIds.push(program.id)
|
||||
userIds.push(lead.id)
|
||||
|
||||
const caller = createCaller(logisticsRouter, {
|
||||
id: admin.id,
|
||||
email: admin.email,
|
||||
role: 'SUPER_ADMIN',
|
||||
})
|
||||
|
||||
const arrivalDate = new Date('2026-06-28T10:00:00Z')
|
||||
const departureAfterArrival = new Date('2026-06-30T14:00:00Z') // 2 days later
|
||||
|
||||
const result = await caller.upsertFlightDetail({
|
||||
attendingMemberId: attendingMember.id,
|
||||
arrivalAt: arrivalDate,
|
||||
departureAt: departureAfterArrival,
|
||||
arrivalFlightNumber: 'AF7400',
|
||||
departureFlightNumber: 'AF7405',
|
||||
})
|
||||
expect(result.arrivalFlightNumber).toBe('AF7400')
|
||||
expect(result.departureFlightNumber).toBe('AF7405')
|
||||
})
|
||||
|
||||
it('setFlightStatus toggles PENDING ↔ CONFIRMED', async () => {
|
||||
const admin = await createTestUser('SUPER_ADMIN')
|
||||
userIds.push(admin.id)
|
||||
|
||||
Reference in New Issue
Block a user