From 133503582ad460187ab03a30633e9b0fa8431b0b Mon Sep 17 00:00:00 2001 From: DecDuck Date: Mon, 10 Mar 2025 12:28:59 +1100 Subject: [PATCH] feat: client collection routes --- .../v1/client/collection/[id]/entry.delete.ts | 31 ++++++++++++++++++ .../v1/client/collection/[id]/entry.post.ts | 21 ++++++++++++ .../v1/client/collection/[id]/index.delete.ts | 32 +++++++++++++++++++ .../v1/client/collection/[id]/index.get.ts | 32 +++++++++++++++++++ .../client/collection/default/entry.delete.ts | 16 ++++++++++ .../client/collection/default/entry.post.ts | 16 ++++++++++ .../v1/client/collection/default/index.get.ts | 11 +++++++ server/api/v1/client/collection/index.get.ts | 10 ++++++ server/api/v1/client/collection/index.post.ts | 17 ++++++++++ 9 files changed, 186 insertions(+) create mode 100644 server/api/v1/client/collection/[id]/entry.delete.ts create mode 100644 server/api/v1/client/collection/[id]/entry.post.ts create mode 100644 server/api/v1/client/collection/[id]/index.delete.ts create mode 100644 server/api/v1/client/collection/[id]/index.get.ts create mode 100644 server/api/v1/client/collection/default/entry.delete.ts create mode 100644 server/api/v1/client/collection/default/entry.post.ts create mode 100644 server/api/v1/client/collection/default/index.get.ts create mode 100644 server/api/v1/client/collection/index.get.ts create mode 100644 server/api/v1/client/collection/index.post.ts diff --git a/server/api/v1/client/collection/[id]/entry.delete.ts b/server/api/v1/client/collection/[id]/entry.delete.ts new file mode 100644 index 0000000..61bcc42 --- /dev/null +++ b/server/api/v1/client/collection/[id]/entry.delete.ts @@ -0,0 +1,31 @@ +import aclManager from "~/server/internal/acls"; +import { defineClientEventHandler } from "~/server/internal/clients/event-handler"; +import userLibraryManager from "~/server/internal/userlibrary"; + +export default defineClientEventHandler(async (h3, { fetchUser }) => { + const user = await fetchUser(); + + const id = getRouterParam(h3, "id"); + if (!id) + throw createError({ + statusCode: 400, + statusMessage: "ID required in route params", + }); + + const body = await readBody(h3); + const gameId = body.id; + if (!gameId) + throw createError({ statusCode: 400, statusMessage: "Game ID required" }); + + const successful = await userLibraryManager.collectionRemove( + gameId, + id, + user.id + ); + if (!successful) + throw createError({ + statusCode: 404, + statusMessage: "Collection not found", + }); + return {}; +}); diff --git a/server/api/v1/client/collection/[id]/entry.post.ts b/server/api/v1/client/collection/[id]/entry.post.ts new file mode 100644 index 0000000..3674cac --- /dev/null +++ b/server/api/v1/client/collection/[id]/entry.post.ts @@ -0,0 +1,21 @@ +import aclManager from "~/server/internal/acls"; +import { defineClientEventHandler } from "~/server/internal/clients/event-handler"; +import userLibraryManager from "~/server/internal/userlibrary"; + +export default defineClientEventHandler(async (h3, { fetchUser }) => { + const user = await fetchUser(); + + const id = getRouterParam(h3, "id"); + if (!id) + throw createError({ + statusCode: 400, + statusMessage: "ID required in route params", + }); + + const body = await readBody(h3); + const gameId = body.id; + if (!gameId) + throw createError({ statusCode: 400, statusMessage: "Game ID required" }); + + return await userLibraryManager.collectionAdd(gameId, id, user.id); +}); diff --git a/server/api/v1/client/collection/[id]/index.delete.ts b/server/api/v1/client/collection/[id]/index.delete.ts new file mode 100644 index 0000000..12d0b0d --- /dev/null +++ b/server/api/v1/client/collection/[id]/index.delete.ts @@ -0,0 +1,32 @@ +import aclManager from "~/server/internal/acls"; +import { defineClientEventHandler } from "~/server/internal/clients/event-handler"; +import userLibraryManager from "~/server/internal/userlibrary"; + +export default defineClientEventHandler(async (h3, { fetchUser }) => { + const user = await fetchUser(); + + const id = getRouterParam(h3, "id"); + if (!id) + throw createError({ + statusCode: 400, + statusMessage: "ID required in route params", + }); + + // Verify collection exists and user owns it + // Will not return the default collection + const collection = await userLibraryManager.fetchCollection(id); + if (!collection) + throw createError({ + statusCode: 404, + statusMessage: "Collection not found", + }); + + if (collection.userId !== user.id) + throw createError({ + statusCode: 403, + statusMessage: "Not authorized to delete this collection", + }); + + await userLibraryManager.deleteCollection(id); + return { success: true }; +}); diff --git a/server/api/v1/client/collection/[id]/index.get.ts b/server/api/v1/client/collection/[id]/index.get.ts new file mode 100644 index 0000000..24a48ee --- /dev/null +++ b/server/api/v1/client/collection/[id]/index.get.ts @@ -0,0 +1,32 @@ +import aclManager from "~/server/internal/acls"; +import { defineClientEventHandler } from "~/server/internal/clients/event-handler"; +import userLibraryManager from "~/server/internal/userlibrary"; + +export default defineClientEventHandler(async (h3, { fetchUser }) => { + const user = await fetchUser(); + + const id = getRouterParam(h3, "id"); + if (!id) + throw createError({ + statusCode: 400, + statusMessage: "ID required in route params", + }); + + // Fetch specific collection + // Will not return the default collection + const collection = await userLibraryManager.fetchCollection(id); + if (!collection) + throw createError({ + statusCode: 404, + statusMessage: "Collection not found", + }); + + // Verify user owns this collection + if (collection.userId !== user.id) + throw createError({ + statusCode: 403, + statusMessage: "Not authorized to access this collection", + }); + + return collection; +}); diff --git a/server/api/v1/client/collection/default/entry.delete.ts b/server/api/v1/client/collection/default/entry.delete.ts new file mode 100644 index 0000000..ca4b3e1 --- /dev/null +++ b/server/api/v1/client/collection/default/entry.delete.ts @@ -0,0 +1,16 @@ +import aclManager from "~/server/internal/acls"; +import { defineClientEventHandler } from "~/server/internal/clients/event-handler"; +import userLibraryManager from "~/server/internal/userlibrary"; + +export default defineClientEventHandler(async (h3, { fetchUser }) => { + const user = await fetchUser(); + + const body = await readBody(h3); + + const gameId = body.id; + if (!gameId) + throw createError({ statusCode: 400, statusMessage: "Game ID required" }); + + await userLibraryManager.libraryRemove(gameId, user.id); + return {}; +}); diff --git a/server/api/v1/client/collection/default/entry.post.ts b/server/api/v1/client/collection/default/entry.post.ts new file mode 100644 index 0000000..65e51b2 --- /dev/null +++ b/server/api/v1/client/collection/default/entry.post.ts @@ -0,0 +1,16 @@ +import aclManager from "~/server/internal/acls"; +import { defineClientEventHandler } from "~/server/internal/clients/event-handler"; +import userLibraryManager from "~/server/internal/userlibrary"; + +export default defineClientEventHandler(async (h3, { fetchUser }) => { + const user = await fetchUser(); + + const body = await readBody(h3); + const gameId = body.id; + if (!gameId) + throw createError({ statusCode: 400, statusMessage: "Game ID required" }); + + // Add the game to the default collection + await userLibraryManager.libraryAdd(gameId, user.id); + return {}; +}); diff --git a/server/api/v1/client/collection/default/index.get.ts b/server/api/v1/client/collection/default/index.get.ts new file mode 100644 index 0000000..6b90218 --- /dev/null +++ b/server/api/v1/client/collection/default/index.get.ts @@ -0,0 +1,11 @@ +import aclManager from "~/server/internal/acls"; +import { defineClientEventHandler } from "~/server/internal/clients/event-handler"; +import userLibraryManager from "~/server/internal/userlibrary"; + +export default defineClientEventHandler(async (h3, { fetchUser }) => { + const user = await fetchUser(); + + const collection = await userLibraryManager.fetchLibrary(user.id); + + return collection; +}); diff --git a/server/api/v1/client/collection/index.get.ts b/server/api/v1/client/collection/index.get.ts new file mode 100644 index 0000000..9d4b259 --- /dev/null +++ b/server/api/v1/client/collection/index.get.ts @@ -0,0 +1,10 @@ +import aclManager from "~/server/internal/acls"; +import { defineClientEventHandler } from "~/server/internal/clients/event-handler"; +import userLibraryManager from "~/server/internal/userlibrary"; + +export default defineClientEventHandler(async (h3, { fetchUser }) => { + const user = await fetchUser(); + + const collections = await userLibraryManager.fetchCollections(user.id); + return collections; +}); diff --git a/server/api/v1/client/collection/index.post.ts b/server/api/v1/client/collection/index.post.ts new file mode 100644 index 0000000..e718e6c --- /dev/null +++ b/server/api/v1/client/collection/index.post.ts @@ -0,0 +1,17 @@ +import aclManager from "~/server/internal/acls"; +import { defineClientEventHandler } from "~/server/internal/clients/event-handler"; +import userLibraryManager from "~/server/internal/userlibrary"; + +export default defineClientEventHandler(async (h3, { fetchUser }) => { + const user = await fetchUser(); + + const body = await readBody(h3); + + const name = body.name; + if (!name) + throw createError({ statusCode: 400, statusMessage: "Requires name" }); + + // Create the collection using the manager + const newCollection = await userLibraryManager.collectionCreate(name, user.id); + return newCollection; +});