Skip to content
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
64 changes: 48 additions & 16 deletions langsuit/app/api/lessons/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { type NextRequest, NextResponse } from "next/server";
import db from "@/db/drizzle";
import { lessons } from "@/db/schema";
import { getIsAdmin } from "@/lib/admin";
import { getCachedResponse } from "@/lib/cache";
import { invalidateCache } from "@/lib/cache-utils";

/**
* @swagger
Expand Down Expand Up @@ -59,27 +61,57 @@ import { getIsAdmin } from "@/lib/admin";
* description: Unauthorized - Admin access required
*/

export const GET = async () => {
const isAdmin = getIsAdmin();
if (!isAdmin) return new NextResponse("Unauthorized.", { status: 401 });
export async function GET() {
try {
const isAdmin = await getIsAdmin();
if (!isAdmin) {
return NextResponse.json(
{ error: "Unauthorized - Admin access required" },
{ status: 401 },
);
}

const data = await db.query.lessons.findMany();
const lessons = await getCachedResponse(
'lessons',
async () => {
const result = await db.query.lessons.findMany();
return result;
},
900 // 15 minutes cache
);

return NextResponse.json(data);
return NextResponse.json(lessons);
} catch (error) {
console.error("Error fetching lessons:", error);
return NextResponse.json(
{ error: "Failed to fetch lessons" },
{ status: 500 },
);
}
};

export const POST = async (req: NextRequest) => {
const isAdmin = getIsAdmin();
if (!isAdmin) return new NextResponse("Unauthorized.", { status: 401 });
export async function POST(req: NextRequest) {
try {
const isAdmin = await getIsAdmin();
if (!isAdmin) {
return NextResponse.json(
{ error: "Unauthorized - Admin access required" },
{ status: 401 },
);
}

const body = (await req.json()) as typeof lessons.$inferSelect;
const body = await req.json();
const lesson = await db.insert(lessons).values(body).returning().get();

const data = await db
.insert(lessons)
.values({
...body,
})
.returning();
// Invalidate cache for lessons
await invalidateCache('lessons');

return NextResponse.json(data[0]);
return NextResponse.json(lesson);
} catch (error) {
console.error("Error creating lesson:", error);
return NextResponse.json(
{ error: "Failed to create lesson" },
{ status: 500 },
);
}
};
27 changes: 22 additions & 5 deletions langsuit/app/api/units/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,35 @@
*/

import { type NextRequest, NextResponse } from "next/server";
import { getCachedResponse } from "@/lib/cache";
import { invalidateCache } from "@/lib/cache-utils";

import db from "@/db/drizzle";
import { units } from "@/db/schema";
import { getIsAdmin } from "@/lib/admin";

export const GET = async () => {
const isAdmin = getIsAdmin();
if (!isAdmin) return new NextResponse("Unauthorized.", { status: 401 });
export async function GET() {
try {
const isAdmin = getIsAdmin();
if (!isAdmin) return new NextResponse("Unauthorized.", { status: 401 });

const data = await db.query.units.findMany();
const units = await getCachedResponse(
'units',
async () => {
const result = await db.query.units.findMany();
return result;
},
900 // 15 minutes cache
);

return NextResponse.json(data);
return NextResponse.json(units);
} catch (error) {
console.error("Error fetching units:", error);
return NextResponse.json(
{ error: "Failed to fetch units" },
{ status: 500 },
);
}
};

export const POST = async (req: NextRequest) => {
Expand Down
26 changes: 26 additions & 0 deletions langsuit/lib/cache-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import redis from "./redis";

/**
* Invalidates cache for a specific resource
* @param type - The type of resource (e.g., 'courses', 'units', 'lessons')
* @param id - Optional ID for specific resource
*/
export async function invalidateCache(type: string, id?: string | number) {
try {
// Get all keys matching the pattern
const keys = await redis.keys(`${type}*`);

// Delete all matching keys
if (keys.length > 0) {
await redis.del(...keys);
}

// If specific ID is provided, invalidate that specific key
if (id) {
const specificKey = `${type}:${id}`;
await redis.del(specificKey);
}
} catch (error) {
console.error(`Error invalidating cache for ${type}:`, error);
}
}