Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redis Refactor #155

Merged
merged 7 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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",
christianhelp marked this conversation as resolved.
Show resolved Hide resolved
"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
Loading