From be4b4f016b6c996c7ddd3ec2a1ea7db2e9095269 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Thu, 5 Jun 2025 00:21:40 +0200 Subject: [PATCH] Add `isAvailable` filter for both entries & shows --- api/src/controllers/entries.ts | 1 + api/src/controllers/shows/logic.ts | 5 +++-- api/src/models/utils/filters/index.ts | 2 +- api/src/models/utils/filters/parser.ts | 3 ++- api/src/models/utils/filters/to-sql.ts | 12 ++++++++++++ 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/api/src/controllers/entries.ts b/api/src/controllers/entries.ts index b34fd1a4..b994b8c2 100644 --- a/api/src/controllers/entries.ts +++ b/api/src/controllers/entries.ts @@ -72,6 +72,7 @@ export const entryFilters: FilterDef = { runtime: { column: entries.runtime, type: "float" }, airDate: { column: entries.airDate, type: "date" }, playedDate: { column: entryProgressQ.playedDate, type: "date" }, + isAvailable: { column: isNotNull(entries.availableSince), type: "bool" }, }; const extraFilters: FilterDef = { diff --git a/api/src/controllers/shows/logic.ts b/api/src/controllers/shows/logic.ts index 26c2af66..e961127d 100644 --- a/api/src/controllers/shows/logic.ts +++ b/api/src/controllers/shows/logic.ts @@ -1,4 +1,4 @@ -import { type SQL, and, eq, exists, ne, sql } from "drizzle-orm"; +import { type SQL, and, eq, exists, gt, ne, sql } from "drizzle-orm"; import { db } from "~/db"; import { entries, @@ -60,7 +60,7 @@ export const showFilters: FilterDef = { runtime: { column: shows.runtime, type: "float" }, airDate: { column: shows.startAir, type: "date" }, startAir: { column: shows.startAir, type: "date" }, - endAir: { column: shows.startAir, type: "date" }, + endAir: { column: shows.endAir, type: "date" }, originalLanguage: { column: sql`${shows.original}->'language'`, type: "string", @@ -76,6 +76,7 @@ export const showFilters: FilterDef = { values: WatchlistStatus.enum, }, score: { column: watchStatusQ.score, type: "int" }, + isAvailable: { column: sql`(${shows.availableCount} > 0)`, type: "bool" }, }; export const showSort = Sort( { diff --git a/api/src/models/utils/filters/index.ts b/api/src/models/utils/filters/index.ts index 18fcdd77..1de7a1ce 100644 --- a/api/src/models/utils/filters/index.ts +++ b/api/src/models/utils/filters/index.ts @@ -9,7 +9,7 @@ export type FilterDef = { [key: string]: | { column: Column | SQLWrapper; - type: "int" | "float" | "date" | "string"; + type: "int" | "float" | "date" | "string" | "bool"; isArray?: boolean; } | { diff --git a/api/src/models/utils/filters/parser.ts b/api/src/models/utils/filters/parser.ts index 26db94c8..ab82ee40 100644 --- a/api/src/models/utils/filters/parser.ts +++ b/api/src/models/utils/filters/parser.ts @@ -29,7 +29,8 @@ export type Value = | { type: "float"; value: number } | { type: "date"; value: string } | { type: "string"; value: string } - | { type: "enum"; value: string }; + | { type: "enum"; value: string } + | { type: "bool"; value: boolean }; const operators = ["eq", "ne", "gt", "ge", "lt", "le", "has"] as const; export type Operator = (typeof operators)[number]; export type Expression = diff --git a/api/src/models/utils/filters/to-sql.ts b/api/src/models/utils/filters/to-sql.ts index dbcb686a..96600331 100644 --- a/api/src/models/utils/filters/to-sql.ts +++ b/api/src/models/utils/filters/to-sql.ts @@ -48,6 +48,18 @@ export const toDrizzle = (expr: Expression, config: FilterDef): SQL => { // but parser doesn't know if an enum should be a string expr.value = { type: "string", value: expr.value.value }; } + if (prop.type === "bool" && expr.value.type === "enum") { + if (expr.value.value !== "false" && expr.value.value !== "true") { + throw new KErrorT( + comment` + Invalid value for property ${expr.property}. + Get ${expr.value.value} but expected true or false. + `, + { in: where }, + ); + } + expr.value = { type: "bool", value: expr.value.value === "true" } + } if (prop.type !== expr.value.type) { throw new KErrorT( comment`