Fix date handling (force iso on drizzle side)

This commit is contained in:
Zoe Roux 2025-06-23 01:36:18 +02:00
parent dfe0d52b1e
commit 985a13c1e4
No known key found for this signature in database
11 changed files with 74 additions and 54 deletions

View File

@ -8,11 +8,11 @@ import {
primaryKey,
real,
text,
timestamp,
unique,
uuid,
varchar,
} from "drizzle-orm/pg-core";
import { timestamp } from "../utils";
import { shows } from "./shows";
import { image, language, schema } from "./utils";
import { entryVideoJoin } from "./videos";
@ -67,14 +67,14 @@ export const entries = schema.table(
externalId: entry_extid(),
createdAt: timestamp({ withTimezone: true, mode: "string" })
createdAt: timestamp({ withTimezone: true, mode: "iso" })
.notNull()
.defaultNow(),
updatedAt: timestamp({ withTimezone: true, mode: "string" })
.default(sql`now()`),
updatedAt: timestamp({ withTimezone: true, mode: "iso" })
.notNull()
.$onUpdate(() => sql`now()`),
availableSince: timestamp({ withTimezone: true, mode: "string" }),
nextRefresh: timestamp({ withTimezone: true, mode: "string" }).notNull(),
availableSince: timestamp({ withTimezone: true, mode: "iso" }),
nextRefresh: timestamp({ withTimezone: true, mode: "iso" }).notNull(),
},
(t) => [
unique().on(t.showPk, t.seasonNumber, t.episodeNumber),

View File

@ -1,5 +1,6 @@
import { sql } from "drizzle-orm";
import { check, index, integer, timestamp } from "drizzle-orm/pg-core";
import { check, index, integer } from "drizzle-orm/pg-core";
import { timestamp } from "../utils";
import { entries } from "./entries";
import { profiles } from "./profiles";
import { schema } from "./utils";
@ -18,9 +19,9 @@ export const history = schema.table(
videoPk: integer().references(() => videos.pk, { onDelete: "set null" }),
percent: integer().notNull().default(0),
time: integer(),
playedDate: timestamp({ withTimezone: true, mode: "string" })
playedDate: timestamp({ withTimezone: true, mode: "iso" })
.notNull()
.defaultNow(),
.default(sql`now()`),
},
(t) => [
index("history_play_date").on(t.playedDate.desc()),

View File

@ -1,11 +1,6 @@
import {
index,
integer,
jsonb,
timestamp,
uuid,
varchar,
} from "drizzle-orm/pg-core";
import { sql } from "drizzle-orm";
import { index, integer, jsonb, uuid, varchar } from "drizzle-orm/pg-core";
import { timestamp } from "../utils";
import { schema } from "./utils";
export const mqueue = schema.table(
@ -15,9 +10,9 @@ export const mqueue = schema.table(
kind: varchar({ length: 255 }).notNull(),
message: jsonb().notNull(),
attempt: integer().notNull().default(0),
createdAt: timestamp({ withTimezone: true, mode: "string" })
createdAt: timestamp({ withTimezone: true, mode: "iso" })
.notNull()
.defaultNow(),
.default(sql`now()`),
},
(t) => [index("mqueue_created").on(t.createdAt)],
);

View File

@ -6,11 +6,11 @@ import {
jsonb,
primaryKey,
text,
timestamp,
unique,
uuid,
varchar,
} from "drizzle-orm/pg-core";
import { timestamp } from "../utils";
import { shows } from "./shows";
import { image, language, schema } from "./utils";
@ -42,13 +42,13 @@ export const seasons = schema.table(
externalId: season_extid(),
createdAt: timestamp({ withTimezone: true, mode: "string" })
createdAt: timestamp({ withTimezone: true, mode: "iso" })
.notNull()
.defaultNow(),
updatedAt: timestamp({ withTimezone: true, mode: "string" })
.default(sql`now()`),
updatedAt: timestamp({ withTimezone: true, mode: "iso" })
.notNull()
.$onUpdate(() => sql`now()`),
nextRefresh: timestamp({ withTimezone: true, mode: "string" }).notNull(),
nextRefresh: timestamp({ withTimezone: true, mode: "iso" }).notNull(),
},
(t) => [
unique().on(t.showPk, t.seasonNumber),

View File

@ -9,11 +9,11 @@ import {
primaryKey,
smallint,
text,
timestamp,
uuid,
varchar,
} from "drizzle-orm/pg-core";
import type { Image, Original } from "~/models/utils";
import { timestamp } from "../utils";
import { entries } from "./entries";
import { seasons } from "./seasons";
import { roles } from "./staff";
@ -87,13 +87,13 @@ export const shows = schema.table(
externalId: externalid(),
createdAt: timestamp({ withTimezone: true, mode: "string" })
createdAt: timestamp({ withTimezone: true, mode: "iso" })
.notNull()
.defaultNow(),
updatedAt: timestamp({ withTimezone: true, mode: "string" })
.default(sql`now()`),
updatedAt: timestamp({ withTimezone: true, mode: "iso" })
.notNull()
.$onUpdate(() => sql`now()`),
nextRefresh: timestamp({ withTimezone: true, mode: "string" }).notNull(),
nextRefresh: timestamp({ withTimezone: true, mode: "iso" }).notNull(),
},
(t) => [
check("rating_valid", sql`${t.rating} between 0 and 100`),

View File

@ -3,13 +3,12 @@ import {
index,
integer,
jsonb,
primaryKey,
text,
timestamp,
uuid,
varchar,
} from "drizzle-orm/pg-core";
import type { Character } from "~/models/staff";
import { timestamp } from "../utils";
import { shows } from "./shows";
import { externalid, image, schema } from "./utils";
@ -32,10 +31,10 @@ export const staff = schema.table("staff", {
image: image(),
externalId: externalid(),
createdAt: timestamp({ withTimezone: true, mode: "string" })
createdAt: timestamp({ withTimezone: true, mode: "iso" })
.notNull()
.defaultNow(),
updatedAt: timestamp({ withTimezone: true, mode: "string" })
.default(sql`now()`),
updatedAt: timestamp({ withTimezone: true, mode: "iso" })
.notNull()
.$onUpdate(() => sql`now()`),
});

View File

@ -4,10 +4,10 @@ import {
integer,
primaryKey,
text,
timestamp,
uuid,
varchar,
} from "drizzle-orm/pg-core";
import { timestamp } from "../utils";
import { shows } from "./shows";
import { externalid, image, language, schema } from "./utils";
@ -17,10 +17,10 @@ export const studios = schema.table("studios", {
slug: varchar({ length: 255 }).notNull().unique(),
externalId: externalid(),
createdAt: timestamp({ withTimezone: true, mode: "string" })
createdAt: timestamp({ withTimezone: true, mode: "iso" })
.notNull()
.defaultNow(),
updatedAt: timestamp({ withTimezone: true, mode: "string" })
.default(sql`now()`),
updatedAt: timestamp({ withTimezone: true, mode: "iso" })
.notNull()
.$onUpdate(() => sql`now()`),
});

View File

@ -5,12 +5,12 @@ import {
jsonb,
primaryKey,
text,
timestamp,
unique,
uuid,
varchar,
} from "drizzle-orm/pg-core";
import type { Guess } from "~/models/video";
import { timestamp } from "../utils";
import { entries } from "./entries";
import { schema } from "./utils";
@ -25,10 +25,10 @@ export const videos = schema.table(
version: integer().notNull().default(1),
guess: jsonb().$type<Guess>().notNull(),
createdAt: timestamp({ withTimezone: true, mode: "string" })
createdAt: timestamp({ withTimezone: true, mode: "iso" })
.notNull()
.defaultNow(),
updatedAt: timestamp({ withTimezone: true, mode: "string" })
.default(sql`now()`),
updatedAt: timestamp({ withTimezone: true, mode: "iso" })
.notNull()
.$onUpdate(() => sql`now()`),
},

View File

@ -1,5 +1,6 @@
import { sql } from "drizzle-orm";
import { check, integer, primaryKey, timestamp } from "drizzle-orm/pg-core";
import { check, integer, primaryKey } from "drizzle-orm/pg-core";
import { timestamp } from "../utils";
import { entries } from "./entries";
import { profiles } from "./profiles";
import { shows } from "./shows";
@ -29,14 +30,14 @@ export const watchlist = schema.table(
score: integer(),
startedAt: timestamp({ withTimezone: true, mode: "string" }),
lastPlayedAt: timestamp({ withTimezone: true, mode: "string" }),
completedAt: timestamp({ withTimezone: true, mode: "string" }),
startedAt: timestamp({ withTimezone: true, mode: "iso" }),
lastPlayedAt: timestamp({ withTimezone: true, mode: "iso" }),
completedAt: timestamp({ withTimezone: true, mode: "iso" }),
createdAt: timestamp({ withTimezone: true, mode: "string" })
createdAt: timestamp({ withTimezone: true, mode: "iso" })
.notNull()
.defaultNow(),
updatedAt: timestamp({ withTimezone: true, mode: "string" })
.default(sql`now()`),
updatedAt: timestamp({ withTimezone: true, mode: "iso" })
.notNull()
.$onUpdate(() => sql`now()`),
},

View File

@ -1,19 +1,23 @@
import {
type Column,
type ColumnsSelection,
getTableColumns,
is,
type SQL,
type SQLWrapper,
type Subquery,
sql,
Table,
View,
ViewBaseConfig,
getTableColumns,
is,
sql,
} from "drizzle-orm";
import type { CasingCache } from "drizzle-orm/casing";
import type { AnyMySqlSelect } from "drizzle-orm/mysql-core";
import type { AnyPgSelect, SelectedFieldsFlat } from "drizzle-orm/pg-core";
import {
type AnyPgSelect,
customType,
type SelectedFieldsFlat,
} from "drizzle-orm/pg-core";
import type { AnySQLiteSelect } from "drizzle-orm/sqlite-core";
import type { WithSubquery } from "drizzle-orm/subquery";
import { db } from "./index";
@ -148,3 +152,19 @@ export const isUniqueConstraint = (e: unknown): boolean => {
typeof e === "object" && e != null && "code" in e && e.code === "23505"
);
};
export const timestamp = customType<{
data: string;
driverData: string;
config: { withTimezone: boolean; precision?: number; mode: "iso" };
}>({
dataType(config) {
const precision = config?.precision ? ` (${config.precision})` : "";
return `timestamp${precision}${config?.withTimezone ? " with time zone" : ""}`;
},
fromDriver(value: string): string {
// postgres format: 2025-06-22 16:13:37.489301+00
// what we want: 2025-06-22T16:13:37Z
return `${value.substring(0, 10)}T${value.substring(11, 19)}Z`;
},
});

View File

@ -1,3 +1,7 @@
import { z } from "zod/v4";
export const zdate = z.coerce.date;
export const zdate = () =>
z.iso
.date()
.or(z.iso.datetime())
.transform((x) => new Date(x));