Skip to content

Commit f044469

Browse files
committed
prefs and websites optimization
1 parent 570f3e9 commit f044469

File tree

2 files changed

+56
-61
lines changed

2 files changed

+56
-61
lines changed
Lines changed: 31 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { userPreferences } from '@databuddy/db';
2-
import { TRPCError } from '@trpc/server';
32
import { eq } from 'drizzle-orm';
43
import { nanoid } from 'nanoid';
54
import { z } from 'zod';
@@ -11,26 +10,25 @@ const preferencesSchema = z.object({
1110
timeFormat: z.string().optional(),
1211
});
1312

13+
const defaultPreferences = {
14+
timezone: 'auto',
15+
dateFormat: 'MMM D, YYYY',
16+
timeFormat: 'h:mm a',
17+
} as const;
18+
1419
export const preferencesRouter = createTRPCRouter({
1520
getUserPreferences: protectedProcedure.query(async ({ ctx }) => {
16-
const user = ctx.user;
17-
if (!user) {
18-
throw new TRPCError({ code: 'UNAUTHORIZED' });
19-
}
20-
2121
let preferences = await ctx.db.query.userPreferences.findFirst({
22-
where: eq(userPreferences.userId, user.id),
22+
where: eq(userPreferences.userId, ctx.user.id),
2323
});
2424

2525
if (!preferences) {
2626
const inserted = await ctx.db
2727
.insert(userPreferences)
2828
.values({
2929
id: nanoid(),
30-
userId: user.id,
31-
timezone: 'auto',
32-
dateFormat: 'MMM D, YYYY',
33-
timeFormat: 'h:mm a',
30+
userId: ctx.user.id,
31+
...defaultPreferences,
3432
updatedAt: new Date().toISOString(),
3533
})
3634
.returning();
@@ -42,41 +40,29 @@ export const preferencesRouter = createTRPCRouter({
4240
updateUserPreferences: protectedProcedure
4341
.input(preferencesSchema)
4442
.mutation(async ({ ctx, input }) => {
45-
const user = ctx.user;
46-
if (!user) {
47-
throw new TRPCError({ code: 'UNAUTHORIZED' });
48-
}
43+
const now = new Date().toISOString();
4944

50-
let preferences = await ctx.db.query.userPreferences.findFirst({
51-
where: eq(userPreferences.userId, user.id),
52-
});
45+
const result = await ctx.db
46+
.insert(userPreferences)
47+
.values({
48+
id: nanoid(),
49+
userId: ctx.user.id,
50+
timezone: input.timezone ?? defaultPreferences.timezone,
51+
dateFormat: input.dateFormat ?? defaultPreferences.dateFormat,
52+
timeFormat: input.timeFormat ?? defaultPreferences.timeFormat,
53+
updatedAt: now,
54+
})
55+
.onConflictDoUpdate({
56+
target: userPreferences.userId,
57+
set: {
58+
timezone: input.timezone,
59+
dateFormat: input.dateFormat,
60+
timeFormat: input.timeFormat,
61+
updatedAt: now,
62+
},
63+
})
64+
.returning();
5365

54-
if (preferences) {
55-
const updated = await ctx.db
56-
.update(userPreferences)
57-
.set({
58-
timezone: input.timezone || preferences.timezone,
59-
dateFormat: input.dateFormat || preferences.dateFormat,
60-
timeFormat: input.timeFormat || preferences.timeFormat,
61-
updatedAt: new Date().toISOString(),
62-
})
63-
.where(eq(userPreferences.userId, user.id))
64-
.returning();
65-
preferences = updated[0];
66-
} else {
67-
const inserted = await ctx.db
68-
.insert(userPreferences)
69-
.values({
70-
id: nanoid(),
71-
userId: user.id,
72-
timezone: input.timezone || 'auto',
73-
dateFormat: input.dateFormat || 'MMM D, YYYY',
74-
timeFormat: input.timeFormat || 'h:mm a',
75-
updatedAt: new Date().toISOString(),
76-
})
77-
.returning();
78-
preferences = inserted[0];
79-
}
80-
return preferences;
66+
return result[0];
8167
}),
8268
});

packages/rpc/src/routers/websites.ts

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,19 @@ import {
2020

2121
const drizzleCache = createDrizzleCache({ redis, namespace: 'websites' });
2222

23+
const CACHE_TTL = 60;
24+
25+
const buildDomain = (domain: string, subdomain?: string) =>
26+
subdomain ? `${subdomain}.${domain}` : domain;
27+
2328
export const websitesRouter = createTRPCRouter({
2429
list: protectedProcedure
2530
.input(z.object({ organizationId: z.string().optional() }).default({}))
2631
.query(({ ctx, input }) => {
27-
const userId = ctx.user.id;
28-
const orgId = input.organizationId || '';
29-
const cacheKey = `list:${userId}:${orgId}`;
32+
const cacheKey = `list:${ctx.user.id}:${input.organizationId || ''}`;
3033
return drizzleCache.withCache({
3134
key: cacheKey,
32-
ttl: 60,
35+
ttl: CACHE_TTL,
3336
tables: ['websites'],
3437
queryFn: () => {
3538
const where = input.organizationId
@@ -52,7 +55,7 @@ export const websitesRouter = createTRPCRouter({
5255
const cacheKey = `getById:${input.id}`;
5356
return drizzleCache.withCache({
5457
key: cacheKey,
55-
ttl: 60,
58+
ttl: CACHE_TTL,
5659
tables: ['websites'],
5760
queryFn: () => authorizeWebsiteAccess(ctx, input.id, 'read'),
5861
});
@@ -83,9 +86,7 @@ export const websitesRouter = createTRPCRouter({
8386
throw new TRPCError({ code: 'BAD_REQUEST', message: limitCheck.error });
8487
}
8588

86-
const fullDomain = input.subdomain
87-
? `${input.subdomain}.${input.domain}`
88-
: input.domain;
89+
const fullDomain = buildDomain(input.domain, input.subdomain);
8990

9091
const existingWebsite = await ctx.db.query.websites.findFirst({
9192
where: and(
@@ -163,8 +164,10 @@ export const websitesRouter = createTRPCRouter({
163164
}
164165
);
165166

166-
await drizzleCache.invalidateByTables(['websites']);
167-
await drizzleCache.invalidateByKey(`getById:${input.id}`);
167+
await Promise.all([
168+
drizzleCache.invalidateByTables(['websites']),
169+
drizzleCache.invalidateByKey(`getById:${input.id}`),
170+
]);
168171

169172
return updatedWebsite;
170173
}),
@@ -178,8 +181,10 @@ export const websitesRouter = createTRPCRouter({
178181
website.organizationId
179182
);
180183

181-
await ctx.db.delete(websites).where(eq(websites.id, input.id));
182-
await trackWebsiteUsage(customerId, -1);
184+
await Promise.all([
185+
ctx.db.delete(websites).where(eq(websites.id, input.id)),
186+
trackWebsiteUsage(customerId, -1),
187+
]);
183188

184189
logger.warning(
185190
'Website Deleted',
@@ -192,8 +197,10 @@ export const websitesRouter = createTRPCRouter({
192197
}
193198
);
194199

195-
await drizzleCache.invalidateByTables(['websites']);
196-
await drizzleCache.invalidateByKey(`getById:${input.id}`);
200+
await Promise.all([
201+
drizzleCache.invalidateByTables(['websites']),
202+
drizzleCache.invalidateByKey(`getById:${input.id}`),
203+
]);
197204

198205
return { success: true };
199206
}),
@@ -239,8 +246,10 @@ export const websitesRouter = createTRPCRouter({
239246
}
240247
);
241248

242-
await drizzleCache.invalidateByTables(['websites']);
243-
await drizzleCache.invalidateByKey(`getById:${input.websiteId}`);
249+
await Promise.all([
250+
drizzleCache.invalidateByTables(['websites']),
251+
drizzleCache.invalidateByKey(`getById:${input.websiteId}`),
252+
]);
244253

245254
return updatedWebsite;
246255
}),

0 commit comments

Comments
 (0)