Skip to content

Commit d589b0c

Browse files
committed
refactor: enhance error handling and streamline data fetching in various routers and schemas
1 parent 863b386 commit d589b0c

14 files changed

Lines changed: 257 additions & 222 deletions

File tree

src/lib/signing/sanity.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { clientReadUncached } from '@/lib/sanity/client'
2+
3+
export interface SigningContractData {
4+
_id: string
5+
signatureStatus: string
6+
signatureId: string
7+
signerEmail: string
8+
contractStatus?: string
9+
contractSentAt?: string
10+
organizerSignedBy?: string
11+
organizerSignedAt?: string
12+
contractDocument?: {
13+
asset?: {
14+
url?: string
15+
}
16+
}
17+
sponsor?: {
18+
name?: string
19+
}
20+
tier?: {
21+
title?: string
22+
}
23+
conference?: {
24+
_id?: string
25+
title?: string
26+
startDate?: string
27+
city?: string
28+
organizer?: string
29+
sponsorEmail?: string
30+
domains?: string[]
31+
socialLinks?: string[]
32+
salesNotificationChannel?: string
33+
}
34+
contactPersons?: Array<{ name?: string; email?: string; isPrimary?: boolean }>
35+
contractValue?: number
36+
contractCurrency?: string
37+
}
38+
39+
const SIGNING_CONTRACT_QUERY = `*[_type == "sponsorForConference" && signatureId == $signingToken][0]{
40+
_id,
41+
signatureStatus,
42+
signatureId,
43+
signerEmail,
44+
contractStatus,
45+
contractSentAt,
46+
organizerSignedBy,
47+
organizerSignedAt,
48+
contractDocument{
49+
asset->{
50+
url
51+
}
52+
},
53+
"sponsor": sponsor->{ name },
54+
"tier": tier->{ title },
55+
"conference": conference->{ _id, title, startDate, city, organizer, sponsorEmail, domains, socialLinks, salesNotificationChannel },
56+
contactPersons[]{ name, email, isPrimary },
57+
contractValue,
58+
contractCurrency
59+
}`
60+
61+
export async function getSigningContract(
62+
token: string,
63+
): Promise<SigningContractData | null> {
64+
return clientReadUncached.fetch<SigningContractData | null>(
65+
SIGNING_CONTRACT_QUERY,
66+
{ signingToken: token },
67+
)
68+
}

src/lib/sponsor-crm/registration.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
import { getCurrentDateTime } from '@/lib/time'
77
import { prepareArrayWithKeys } from '@/lib/sanity/helpers'
88
import type { ContactPerson, BillingInfo } from '@/lib/sponsor/types'
9+
import type { Conference } from '@/lib/conference/types'
910

1011
export interface RegistrationSponsorInfo {
1112
_id: string
@@ -274,3 +275,79 @@ export async function completeRegistration(
274275
export function buildPortalUrl(baseUrl: string, token: string): string {
275276
return `${baseUrl}/sponsor/portal/${token}`
276277
}
278+
279+
export interface SfcNotificationData {
280+
sponsorName: string
281+
tierTitle: string | null
282+
contractValue: number | null
283+
contractCurrency: string | null
284+
conference: Conference | null
285+
}
286+
287+
export async function getSfcForNotification(
288+
sfcId: string,
289+
): Promise<SfcNotificationData | null> {
290+
return clientRead.fetch<SfcNotificationData | null>(
291+
`*[_type == "sponsorForConference" && _id == $id][0]{
292+
"sponsorName": sponsor->name,
293+
"tierTitle": tier->title,
294+
contractValue,
295+
contractCurrency,
296+
"conference": conference->{ ... }
297+
}`,
298+
{ id: sfcId },
299+
)
300+
}
301+
302+
export interface SfcPortalInviteData {
303+
_id: string
304+
status: string | null
305+
registrationToken: string | null
306+
registrationComplete: boolean
307+
contractStatus: string | null
308+
sponsor: { name: string } | null
309+
contactPersons: Array<{
310+
name: string
311+
email: string
312+
isPrimary?: boolean
313+
}> | null
314+
tier: { title: string } | null
315+
contractValue: number | null
316+
contractCurrency: string | null
317+
conference: {
318+
title: string
319+
city: string | null
320+
startDate: string | null
321+
organizer: string | null
322+
sponsorEmail: string | null
323+
socialLinks: string[] | null
324+
} | null
325+
}
326+
327+
export async function getSfcForPortalInvite(
328+
sfcId: string,
329+
): Promise<SfcPortalInviteData | null> {
330+
return clientRead.fetch<SfcPortalInviteData | null>(
331+
`*[_type == "sponsorForConference" && _id == $id][0]{
332+
_id,
333+
status,
334+
registrationToken,
335+
registrationComplete,
336+
contractStatus,
337+
sponsor->{ name },
338+
contactPersons[]{ name, email, isPrimary },
339+
tier->{ title },
340+
contractValue,
341+
contractCurrency,
342+
conference->{
343+
title,
344+
city,
345+
startDate,
346+
organizer,
347+
sponsorEmail,
348+
socialLinks
349+
}
350+
}`,
351+
{ id: sfcId },
352+
)
353+
}

src/lib/travel-support/sanity.ts

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ export async function getTravelSupport(
4545

4646
export async function getTravelSupportById(id: string): Promise<{
4747
travelSupport:
48-
| (TravelSupportWithSpeaker & { expenses: TravelExpense[] })
49-
| null
48+
| (TravelSupportWithSpeaker & { expenses: TravelExpense[] })
49+
| null
5050
error: Error | null
5151
}> {
5252
try {
@@ -382,14 +382,32 @@ export async function updateExpenseStatus(
382382
}
383383
}
384384

385+
export async function getTravelExpenseById(
386+
expenseId: string,
387+
): Promise<TravelExpense | null> {
388+
return clientRead.fetch<TravelExpense | null>(
389+
`*[_type == "travelExpense" && _id == $expenseId][0] {
390+
...,
391+
travelSupport
392+
}`,
393+
{ expenseId },
394+
)
395+
}
396+
397+
export async function getTravelExpenseRef(
398+
expenseId: string,
399+
): Promise<{ travelSupport: { _ref: string } } | null> {
400+
return clientRead.fetch<{ travelSupport: { _ref: string } } | null>(
401+
`*[_type == "travelExpense" && _id == $expenseId][0] { travelSupport }`,
402+
{ expenseId },
403+
)
404+
}
405+
385406
export async function deleteTravelExpense(
386407
expenseId: string,
387408
): Promise<{ success: boolean; error: Error | null }> {
388409
try {
389-
const expense = await clientRead.fetch<{ travelSupport: { _ref: string } }>(
390-
`*[_type == "travelExpense" && _id == $expenseId][0] { travelSupport }`,
391-
{ expenseId },
392-
)
410+
const expense = await getTravelExpenseRef(expenseId)
393411

394412
await clientWrite.delete(expenseId)
395413

src/server/routers/badge.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export const badgeRouter = router({
5252
const publicKeyHex = process.env.BADGE_ISSUER_PUBLIC_KEY
5353
if (!publicKeyHex) {
5454
throw new TRPCError({
55-
code: 'INTERNAL_SERVER_ERROR',
55+
code: 'PRECONDITION_FAILED',
5656
message: 'Public key not configured',
5757
})
5858
}

src/server/routers/featured.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export const featuredRouter = router({
4848

4949
throw new TRPCError({
5050
code: 'INTERNAL_SERVER_ERROR',
51-
message: 'Unexpected error getting featured speakers',
51+
message: 'Failed to get featured speakers',
5252
cause: error,
5353
})
5454
}
@@ -82,7 +82,7 @@ export const featuredRouter = router({
8282

8383
throw new TRPCError({
8484
code: 'INTERNAL_SERVER_ERROR',
85-
message: 'Unexpected error getting featured talks',
85+
message: 'Failed to get featured talks',
8686
cause: error,
8787
})
8888
}
@@ -124,7 +124,7 @@ export const featuredRouter = router({
124124

125125
throw new TRPCError({
126126
code: 'INTERNAL_SERVER_ERROR',
127-
message: 'Unexpected error adding featured speaker',
127+
message: 'Failed to add featured speaker',
128128
cause: error,
129129
})
130130
}
@@ -166,7 +166,7 @@ export const featuredRouter = router({
166166

167167
throw new TRPCError({
168168
code: 'INTERNAL_SERVER_ERROR',
169-
message: 'Unexpected error removing featured speaker',
169+
message: 'Failed to remove featured speaker',
170170
cause: error,
171171
})
172172
}
@@ -209,7 +209,7 @@ export const featuredRouter = router({
209209

210210
throw new TRPCError({
211211
code: 'INTERNAL_SERVER_ERROR',
212-
message: 'Unexpected error adding featured talk',
212+
message: 'Failed to add featured talk',
213213
cause: error,
214214
})
215215
}
@@ -252,7 +252,7 @@ export const featuredRouter = router({
252252

253253
throw new TRPCError({
254254
code: 'INTERNAL_SERVER_ERROR',
255-
message: 'Unexpected error removing featured talk',
255+
message: 'Failed to remove featured talk',
256256
cause: error,
257257
})
258258
}
@@ -285,7 +285,7 @@ export const featuredRouter = router({
285285

286286
throw new TRPCError({
287287
code: 'INTERNAL_SERVER_ERROR',
288-
message: 'Unexpected error getting featured content summary',
288+
message: 'Failed to get featured content summary',
289289
cause: error,
290290
})
291291
}

src/server/routers/registration.ts

Lines changed: 6 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,18 @@ import {
1212
completeRegistration,
1313
generateRegistrationToken,
1414
buildPortalUrl,
15+
getSfcForNotification,
16+
getSfcForPortalInvite,
1517
} from '@/lib/sponsor-crm/registration'
1618
import type { RegistrationSubmission } from '@/lib/sponsor-crm/registration'
1719
import {
1820
logRegistrationComplete,
1921
logEmailSent,
2022
logContractStatusChange,
2123
} from '@/lib/sponsor-crm/activity'
22-
import { clientReadUncached, clientWrite } from '@/lib/sanity/client'
24+
import { clientWrite } from '@/lib/sanity/client'
2325
import { getConferenceForCurrentDomain } from '@/lib/conference/sanity'
2426
import { notifySponsorRegistrationComplete } from '@/lib/slack/notify'
25-
import type { Conference } from '@/lib/conference/types'
2627

2728
export const registrationRouter = router({
2829
validate: publicProcedure
@@ -73,26 +74,7 @@ export const registrationRouter = router({
7374

7475
// Send Slack notification to sales channel
7576
try {
76-
const sfcData = await clientReadUncached.fetch<{
77-
sponsorName: string
78-
tierTitle: string | null
79-
contractValue: number | null
80-
contractCurrency: string | null
81-
conference: Conference | null
82-
}>(
83-
`*[_type == "sponsorForConference" && _id == $id][0]{
84-
"sponsorName": sponsor->name,
85-
"tierTitle": tier->title,
86-
contractValue,
87-
contractCurrency,
88-
"conference": conference->{
89-
_id, title, city, country, startDate, endDate,
90-
organizer, salesNotificationChannel, domains,
91-
socialLinks
92-
}
93-
}`,
94-
{ id: sponsorForConferenceId },
95-
)
77+
const sfcData = await getSfcForNotification(sponsorForConferenceId)
9678

9779
if (sfcData?.conference) {
9880
await notifySponsorRegistrationComplete(
@@ -120,7 +102,7 @@ export const registrationRouter = router({
120102

121103
if (error || !token) {
122104
throw new TRPCError({
123-
code: 'INTERNAL_SERVER_ERROR',
105+
code: 'PRECONDITION_FAILED',
124106
message: error?.message || 'Failed to generate registration token',
125107
})
126108
}
@@ -148,52 +130,7 @@ export const registrationRouter = router({
148130
)
149131
.mutation(async ({ input, ctx }) => {
150132
// Fetch full sponsor + conference data for the email
151-
const sfc = await clientReadUncached.fetch<{
152-
_id: string
153-
status: string | null
154-
registrationToken: string | null
155-
registrationComplete: boolean
156-
contractStatus: string | null
157-
sponsor: { name: string } | null
158-
contactPersons: Array<{
159-
name: string
160-
email: string
161-
isPrimary?: boolean
162-
}> | null
163-
tier: { title: string } | null
164-
contractValue: number | null
165-
contractCurrency: string | null
166-
conference: {
167-
title: string
168-
city: string | null
169-
startDate: string | null
170-
organizer: string | null
171-
sponsorEmail: string | null
172-
socialLinks: string[] | null
173-
} | null
174-
}>(
175-
`*[_type == "sponsorForConference" && _id == $id][0]{
176-
_id,
177-
status,
178-
registrationToken,
179-
registrationComplete,
180-
contractStatus,
181-
sponsor->{ name },
182-
contactPersons[]{ name, email, isPrimary },
183-
tier->{ title },
184-
contractValue,
185-
contractCurrency,
186-
conference->{
187-
title,
188-
city,
189-
startDate,
190-
organizer,
191-
sponsorEmail,
192-
socialLinks
193-
}
194-
}`,
195-
{ id: input.sponsorForConferenceId },
196-
)
133+
const sfc = await getSfcForPortalInvite(input.sponsorForConferenceId)
197134

198135
if (!sfc) {
199136
throw new TRPCError({

0 commit comments

Comments
 (0)