From 7e6592fa2ee41080ea8a74ead5f4c980d803439f Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Sun, 9 Mar 2025 20:52:29 +0100 Subject: [PATCH] Implement routes in /shows --- api/src/controllers/staff.ts | 49 +++++++++++++++++++++++++++++----- api/src/controllers/studios.ts | 2 +- api/src/models/staff.ts | 4 +-- 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/api/src/controllers/staff.ts b/api/src/controllers/staff.ts index b43817ce..f7581545 100644 --- a/api/src/controllers/staff.ts +++ b/api/src/controllers/staff.ts @@ -1,12 +1,21 @@ -import { sql } from "drizzle-orm"; +import { and, eq, sql } from "drizzle-orm"; import Elysia, { t } from "elysia"; import { db } from "~/db"; import { staff } from "~/db/schema/staff"; import { KError } from "~/models/error"; import { Role, Staff } from "~/models/staff"; -import { Filter, Page, Sort } from "~/models/utils"; +import { + Page, + Sort, + createPage, + isUuid, + keysetPaginate, + sortToSql, +} from "~/models/utils"; import { desc } from "~/models/utils/descriptions"; +const staffSort = Sort(["slug", "name", "latinName"], { default: ["slug"] }); + export const staffH = new Elysia({ tags: ["staff"] }) .model({ staff: Staff, @@ -14,8 +23,19 @@ export const staffH = new Elysia({ tags: ["staff"] }) }) .get( "/staff/:id", - async ({ params: { id }, error, set }) => { - throw new Error(); + async ({ params: { id }, error }) => { + const [ret] = await db + .select() + .from(staff) + .where(isUuid(id) ? eq(staff.id, id) : eq(staff.slug, id)) + .limit(1); + if (!ret) { + return error(404, { + status: 404, + message: `No staff found with the id or slug: '${id}'`, + }); + } + return ret; }, { detail: { @@ -69,14 +89,31 @@ export const staffH = new Elysia({ tags: ["staff"] }) ) .get( "/staff", - async ({ query: { limit, after, query }, request: { url } }) => { - throw new Error(); + async ({ query: { limit, after, sort, query }, request: { url } }) => { + const items = await db + .select() + .from(staff) + .where( + and( + query ? sql`${staff.name} %> ${query}::text` : undefined, + keysetPaginate({ table: staff, after, sort }), + ), + ) + .orderBy( + ...(query + ? [sql`word_similarity(${query}::text, ${staff.name})`] + : sortToSql(sort, staff)), + staff.pk, + ) + .limit(limit); + return createPage(items, { url, sort, limit }); }, { detail: { description: "Get all staff members known by kyoo.", }, query: t.Object({ + sort: staffSort, query: t.Optional(t.String({ description: desc.query })), limit: t.Integer({ minimum: 1, diff --git a/api/src/controllers/studios.ts b/api/src/controllers/studios.ts index 66eb483b..8a9806bd 100644 --- a/api/src/controllers/studios.ts +++ b/api/src/controllers/studios.ts @@ -138,7 +138,7 @@ export const studiosH = new Elysia({ prefix: "/studios", tags: ["studios"] }) if (!ret) { return error(404, { status: 404, - message: `No studio with the id or slug: '${id}'`, + message: `No studio found with the id or slug: '${id}'`, }); } if (!ret.language) { diff --git a/api/src/models/staff.ts b/api/src/models/staff.ts index 62737f51..66d8a727 100644 --- a/api/src/models/staff.ts +++ b/api/src/models/staff.ts @@ -3,7 +3,7 @@ import { DbMetadata, ExternalId, Image, Resource } from "./utils"; export const Character = t.Object({ name: t.String(), - latinName: t.String(), + latinName: t.Nullable(t.String()), image: t.Nullable(Image), }); export type Character = typeof Character.static; @@ -25,7 +25,7 @@ export const Staff = t.Intersect([ Resource(), t.Object({ name: t.String(), - latinName: t.String(), + latinName: t.Nullable(t.String()), image: t.Nullable(Image), externalId: ExternalId(), }),