Add /series/:id/staff

This commit is contained in:
Zoe Roux 2025-03-09 21:47:36 +01:00
parent 18532b80b1
commit 039880d812
No known key found for this signature in database

View File

@ -1,4 +1,5 @@
import { and, eq, sql } from "drizzle-orm";
import type { StaticDecode } from "@sinclair/typebox";
import { type SQL, and, eq, sql } from "drizzle-orm";
import Elysia, { t } from "elysia";
import { db } from "~/db";
import { showTranslations, shows } from "~/db/schema";
@ -50,6 +51,42 @@ const roleShowFilters: FilterDef = {
...showFilters,
};
async function getStaffRoles({
after,
limit,
query,
sort,
filter,
}: {
after?: string;
limit: number;
query?: string;
sort?: StaticDecode<typeof staffRoleSort>;
filter?: SQL;
}) {
return await db
.select({
...getColumns(roles),
staff: getColumns(staff),
})
.from(roles)
.innerJoin(staff, eq(roles.staffPk, staff.pk))
.where(
and(
filter,
query ? sql`${staff.name} %> ${query}::text` : undefined,
keysetPaginate({ table: roles, sort, after }),
),
)
.orderBy(
...(query
? [sql`word_similarity(${query}::text, ${staff.name})`]
: sortToSql(sort, roles)),
shows.pk,
)
.limit(limit);
}
export const staffH = new Elysia({ tags: ["staff"] })
.model({
staff: Staff,
@ -282,7 +319,12 @@ export const staffH = new Elysia({ tags: ["staff"] })
const [movie] = await db
.select({ pk: shows.pk })
.from(shows)
.where(isUuid(id) ? eq(shows.id, id) : eq(shows.slug, id))
.where(
and(
eq(shows.kind, "movie"),
isUuid(id) ? eq(shows.id, id) : eq(shows.slug, id),
),
)
.limit(1);
if (!movie) {
@ -292,28 +334,13 @@ export const staffH = new Elysia({ tags: ["staff"] })
});
}
const items = await db
.select({
...getColumns(roles),
staff: getColumns(staff),
})
.from(roles)
.innerJoin(staff, eq(roles.staffPk, staff.pk))
.where(
and(
filter,
query ? sql`${staff.name} %> ${query}::text` : undefined,
keysetPaginate({ table: roles, sort, after }),
),
)
.orderBy(
...(query
? [sql`word_similarity(${query}::text, ${staff.name})`]
: sortToSql(sort, roles)),
shows.pk,
)
.limit(limit);
const items = await getStaffRoles({
limit,
after,
query,
sort,
filter: and(eq(shows.pk, roles.showPk), filter),
});
return createPage(items, { url, sort, limit });
},
{
@ -347,4 +374,71 @@ export const staffH = new Elysia({ tags: ["staff"] })
422: KError,
},
},
)
.get(
"/series/:id/staff",
async ({
params: { id },
query: { limit, after, query, sort, filter },
request: { url },
error,
}) => {
const [serie] = await db
.select({ pk: shows.pk })
.from(shows)
.where(
and(
eq(shows.kind, "serie"),
isUuid(id) ? eq(shows.id, id) : eq(shows.slug, id),
),
)
.limit(1);
if (!serie) {
return error(404, {
status: 404,
message: `No serie with the id or slug: '${id}'.`,
});
}
const items = await getStaffRoles({
limit,
after,
query,
sort,
filter: and(eq(shows.pk, roles.showPk), filter),
});
return createPage(items, { url, sort, limit });
},
{
detail: {
description: "Get all staff member who worked on this serie",
},
params: t.Object({
id: t.String({
description: "The id or slug of the serie.",
example: "made-in-abyss",
}),
}),
query: t.Object({
sort: staffRoleSort,
filter: t.Optional(Filter({ def: staffRoleFilter })),
query: t.Optional(t.String({ description: desc.query })),
limit: t.Integer({
minimum: 1,
maximum: 250,
default: 50,
description: "Max page size.",
}),
after: t.Optional(t.String({ description: desc.after })),
}),
response: {
200: Page(RoleWStaff),
404: {
...KError,
description: "No serie found with the given id or slug.",
},
422: KError,
},
},
);