Skip to content

Commit

Permalink
Redis Refactor (#155)
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuasilva414 authored Jan 3, 2025
1 parent b1d8b89 commit 74498e7
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 32 deletions.
13 changes: 5 additions & 8 deletions apps/web/src/actions/admin/modify-nav-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { z } from "zod";
import { adminAction } from "@/lib/safe-action";
import { kv } from "@vercel/kv";
import { redisSAdd, redisHSet, removeNavItem } from "@/lib/utils/server/redis";
import { revalidatePath } from "next/cache";

const metadataSchema = z.object({
Expand All @@ -16,8 +16,8 @@ const navAdminPage = "/admin/toggles/landing";
export const setItem = adminAction
.schema(metadataSchema)
.action(async ({ parsedInput: { name, url }, ctx: { user, userId } }) => {
await kv.sadd("config:navitemslist", encodeURIComponent(name));
await kv.hset(`config:navitems:${encodeURIComponent(name)}`, {
await redisSAdd("config:navitemslist", encodeURIComponent(name));
await redisHSet(`config:navitems:${encodeURIComponent(name)}`, {
url,
name,
enabled: true,
Expand All @@ -29,10 +29,7 @@ export const setItem = adminAction
export const removeItem = adminAction
.schema(z.string())
.action(async ({ parsedInput: name, ctx: { user, userId } }) => {
const pipe = kv.pipeline();
pipe.srem("config:navitemslist", encodeURIComponent(name));
pipe.del(`config:navitems:${encodeURIComponent(name)}`);
await pipe.exec();
await removeNavItem(name);
// await new Promise((resolve) => setTimeout(resolve, 1500));
revalidatePath(navAdminPage);
return { success: true };
Expand All @@ -45,7 +42,7 @@ export const toggleItem = adminAction
parsedInput: { name, statusToSet },
ctx: { user, userId },
}) => {
await kv.hset(`config:navitems:${encodeURIComponent(name)}`, {
await redisHSet(`config:navitems:${encodeURIComponent(name)}`, {
enabled: statusToSet,
});
revalidatePath(navAdminPage);
Expand Down
18 changes: 12 additions & 6 deletions apps/web/src/actions/admin/registration-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { z } from "zod";
import { adminAction } from "@/lib/safe-action";
import { kv } from "@vercel/kv";
import { redisSet } from "@/lib/utils/server/redis";
import { revalidatePath } from "next/cache";

const defaultRegistrationToggleSchema = z.object({
Expand All @@ -16,39 +16,45 @@ const defaultRSVPLimitSchema = z.object({
export const toggleRegistrationEnabled = adminAction
.schema(defaultRegistrationToggleSchema)
.action(async ({ parsedInput: { enabled }, ctx: { user, userId } }) => {
await kv.set("config:registration:registrationEnabled", enabled);
await redisSet("config:registration:registrationEnabled", enabled);
revalidatePath("/admin/toggles/registration");
return { success: true, statusSet: enabled };
});

export const toggleRegistrationMessageEnabled = adminAction
.schema(defaultRegistrationToggleSchema)
.action(async ({ parsedInput: { enabled }, ctx: { user, userId } }) => {
await kv.set("config:registration:registrationMessageEnabled", enabled);
await redisSet(
"config:registration:registrationMessageEnabled",
enabled,
);
revalidatePath("/admin/toggles/registration");
return { success: true, statusSet: enabled };
});

export const toggleSecretRegistrationEnabled = adminAction
.schema(defaultRegistrationToggleSchema)
.action(async ({ parsedInput: { enabled }, ctx: { user, userId } }) => {
await kv.set("config:registration:secretRegistrationEnabled", enabled);
await redisSet(
"config:registration:secretRegistrationEnabled",
enabled,
);
revalidatePath("/admin/toggles/registration");
return { success: true, statusSet: enabled };
});

export const toggleRSVPs = adminAction
.schema(defaultRegistrationToggleSchema)
.action(async ({ parsedInput: { enabled }, ctx: { user, userId } }) => {
await kv.set("config:registration:allowRSVPs", enabled);
await redisSet("config:registration:allowRSVPs", enabled);
revalidatePath("/admin/toggles/registration");
return { success: true, statusSet: enabled };
});

export const setRSVPLimit = adminAction
.schema(defaultRSVPLimitSchema)
.action(async ({ parsedInput: { rsvpLimit }, ctx: { user, userId } }) => {
await kv.set("config:registration:maxRSVPs", rsvpLimit);
await redisSet("config:registration:maxRSVPs", rsvpLimit);
revalidatePath("/admin/toggles/registration");
return { success: true, statusSet: rsvpLimit };
});
9 changes: 2 additions & 7 deletions apps/web/src/app/admin/toggles/registration/page.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
import { RegistrationToggles } from "@/components/admin/toggles/RegistrationSettings";
import { kv } from "@vercel/kv";
import { redisMGet } from "@/lib/utils/server/redis";
import { parseRedisBoolean, parseRedisNumber } from "@/lib/utils/server/redis";
import c from "config";

export default async function Page() {
const pipe = kv.pipeline();
pipe.get("config:registration:registrationEnabled");
pipe.get("config:registration:secretRegistrationEnabled");
// const result = await pipe.exec();

const [
defaultRegistrationEnabled,
defaultSecretRegistrationEnabled,
defaultRSVPsEnabled,
defaultRSVPLimit,
]: (string | null)[] = await kv.mget(
]: (string | null)[] = await redisMGet(
"config:registration:registrationEnabled",
"config:registration:secretRegistrationEnabled",
"config:registration:allowRSVPs",
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/app/register/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { auth, currentUser } from "@clerk/nextjs";
import { redirect } from "next/navigation";
import Navbar from "@/components/shared/Navbar";
import Link from "next/link";
import { kv } from "@vercel/kv";
import { redisMGet } from "@/lib/utils/server/redis";
import { parseRedisBoolean } from "@/lib/utils/server/redis";
import { Button } from "@/components/shadcn/ui/button";
import { getUser } from "db/functions";
Expand All @@ -22,7 +22,7 @@ export default async function Page() {
const [defaultRegistrationEnabled, defaultSecretRegistrationEnabled]: (
| string
| null
)[] = await kv.mget(
)[] = await redisMGet(
"config:registration:registrationEnabled",
"config:registration:secretRegistrationEnabled",
);
Expand Down
11 changes: 7 additions & 4 deletions apps/web/src/app/rsvp/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ import { eq } from "db/drizzle";
import { userCommonData } from "db/schema";
import ClientToast from "@/components/shared/ClientToast";
import { SignedOut, RedirectToSignIn } from "@clerk/nextjs";
import { kv } from "@vercel/kv";
import { parseRedisBoolean, parseRedisNumber } from "@/lib/utils/server/redis";
import {
parseRedisBoolean,
parseRedisNumber,
redisGet,
} from "@/lib/utils/server/redis";
import Link from "next/link";
import { Button } from "@/components/shadcn/ui/button";
import { getUser } from "db/functions";
Expand Down Expand Up @@ -41,7 +44,7 @@ export default async function RsvpPage({
}

const rsvpEnabled = parseRedisBoolean(
(await kv.get("config:registration:allowRSVPs")) as
(await redisGet("config:registration:allowRSVPs")) as
| string
| boolean
| null
Expand All @@ -53,7 +56,7 @@ export default async function RsvpPage({

if (rsvpEnabled === true) {
const rsvpLimit = parseRedisNumber(
await kv.get("config:registration:maxRSVPs"),
await redisGet("config:registration:maxRSVPs"),
c.rsvpDefaultLimit,
);

Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/app/sign-up/[[...sign-up]]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SignUp } from "@clerk/nextjs";
import { kv } from "@vercel/kv";
import { redisMGet } from "@/lib/utils/server/redis";
import { parseRedisBoolean } from "@/lib/utils/server/redis";
import c from "config";
import { Button } from "@/components/shadcn/ui/button";
Expand All @@ -9,7 +9,7 @@ export default async function Page() {
const [defaultRegistrationEnabled, defaultSecretRegistrationEnabled]: (
| string
| null
)[] = await kv.mget(
)[] = await redisMGet(
"config:registration:registrationEnabled",
"config:registration:secretRegistrationEnabled",
);
Expand Down
1 change: 1 addition & 0 deletions apps/web/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const env = createEnv({
AWS_SES_EMAIL_FROM: z.string().min(1),
INTERNAL_AUTH_KEY: z.string().min(64),
BOT_API_URL: z.string().min(1),
HK_ENV: z.string().min(1),
NODE_ENV: z
.enum(["development", "test", "production"])
.default("development"),
Expand Down
47 changes: 45 additions & 2 deletions apps/web/src/lib/utils/server/redis.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,40 @@
import { kv } from "@vercel/kv";
import type { NavItemToggleType } from "@/validators/shared/navitemtoggle";

export function includeEnvPrefix(key: string) {
return `${process.env.HK_ENV}_${key}`;
}

export async function redisSAdd(key: string, value: string): Promise<number> {
return kv.sadd(includeEnvPrefix(key), value);
}

export async function redisHSet<TData>(
key: string,
value: Record<string, TData>,
): Promise<number> {
return kv.hset(includeEnvPrefix(key), value);
}

export async function redisSet<TData>(
key: string,
value: TData,
): Promise<TData | "OK" | null> {
return kv.set<TData>(includeEnvPrefix(key), value);
}

export async function redisGet<TData>(key: string): Promise<TData | null> {
return kv.get<TData>(includeEnvPrefix(key));
}

export async function redisMGet<TData>(...keys: string[]): Promise<TData[]> {
return kv.mget<TData[]>(keys.map(includeEnvPrefix));
}

export async function getAllNavItems() {
const keys = await kv.smembers<string[]>("config:navitemslist");
const keys = await kv.smembers<string[]>(
includeEnvPrefix("config:navitemslist"),
);
if (!keys || keys.length < 1) {
return {
keys: [],
Expand All @@ -11,7 +43,7 @@ export async function getAllNavItems() {
}
const pipe = kv.pipeline();
for (const key of keys) {
pipe.hgetall(`config:navitems:${key}`);
pipe.hgetall(includeEnvPrefix(`config:navitems:${key}`));
}
const items = await pipe.exec<NavItemToggleType[]>();
return {
Expand All @@ -20,6 +52,17 @@ export async function getAllNavItems() {
};
}

export function removeNavItem(name: string) {
console.log("Removing: ", includeEnvPrefix("config:navitemslist"));
const pipe = kv.pipeline();
pipe.srem(
includeEnvPrefix("config:navitemslist"),
encodeURIComponent(name),
);
pipe.del(includeEnvPrefix(`config:navitems:${encodeURIComponent(name)}`));
return pipe.exec();
}

export function parseRedisBoolean(
value: string | boolean | undefined | null,
defaultValue?: boolean,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"prettier": "^3.3.3",
"turbo": "^2.0.9"
},
"packageManager": "[email protected]",
"packageManager": "[email protected]+sha512.d264f6640bf4f09de7cfcc547568515bcf0613cf485a03e8ff16616fa69c4172b6f9a0a2925ee44fb060df565c9c9a8eaf061749e77af318cb77f6684a7051f3",
"name": "hackkit",
"dependencies": {
"prettier-plugin-tailwindcss": "^0.6.5"
Expand Down
1 change: 1 addition & 0 deletions turbo.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"DISCORD_PROD_SERVER_ID",
"DISCORD_PROD_VERIFY_CHANNEL_ID",
"DISCORD_SECRET_TOKEN",
"HK_ENV",
"INTERNAL_AUTH_KEY",
"KV_REST_API_READ_ONLY_TOKEN",
"KV_REST_API_TOKEN",
Expand Down

0 comments on commit 74498e7

Please sign in to comment.