feat: add watch history import from Trakt, Simkl, and Letterboxd (#13)

This commit is contained in:
2026-03-17 11:02:58 -04:00
committed by GitHub
parent 25736f684a
commit 710c43a01f
41 changed files with 10230 additions and 106 deletions
@@ -0,0 +1,25 @@
CREATE TABLE `importJobs` (
`id` text PRIMARY KEY,
`userId` text NOT NULL,
`source` text NOT NULL,
`status` text NOT NULL,
`payload` text NOT NULL,
`importWatches` integer NOT NULL,
`importWatchlist` integer NOT NULL,
`importRatings` integer NOT NULL,
`totalItems` integer DEFAULT 0 NOT NULL,
`processedItems` integer DEFAULT 0 NOT NULL,
`importedCount` integer DEFAULT 0 NOT NULL,
`skippedCount` integer DEFAULT 0 NOT NULL,
`failedCount` integer DEFAULT 0 NOT NULL,
`currentMessage` text,
`errors` text,
`warnings` text,
`createdAt` integer NOT NULL,
`startedAt` integer,
`finishedAt` integer,
CONSTRAINT `fk_importJobs_userId_user_id_fk` FOREIGN KEY (`userId`) REFERENCES `user`(`id`) ON DELETE CASCADE
);
--> statement-breakpoint
CREATE INDEX `importJobs_userId_createdAt` ON `importJobs` (`userId`,`createdAt`);--> statement-breakpoint
CREATE INDEX `importJobs_status` ON `importJobs` (`status`);
File diff suppressed because it is too large Load Diff
+37
View File
@@ -486,6 +486,43 @@ export const cronRuns = sqliteTable(
],
);
// ─── Import Jobs ────────────────────────────────────────────────────
export const importJobs = sqliteTable(
"importJobs",
{
id: uuidPk(),
userId: text("userId")
.notNull()
.references(() => user.id, { onDelete: "cascade" }),
source: text("source", {
enum: ["trakt", "simkl", "letterboxd"],
}).notNull(),
status: text("status", {
enum: ["pending", "running", "success", "error", "cancelled"],
}).notNull(),
payload: text("payload").notNull(),
importWatches: int("importWatches", { mode: "boolean" }).notNull(),
importWatchlist: int("importWatchlist", { mode: "boolean" }).notNull(),
importRatings: int("importRatings", { mode: "boolean" }).notNull(),
totalItems: int("totalItems").notNull().default(0),
processedItems: int("processedItems").notNull().default(0),
importedCount: int("importedCount").notNull().default(0),
skippedCount: int("skippedCount").notNull().default(0),
failedCount: int("failedCount").notNull().default(0),
currentMessage: text("currentMessage"),
errors: text("errors"),
warnings: text("warnings"),
createdAt: int("createdAt", { mode: "timestamp" }).notNull(),
startedAt: int("startedAt", { mode: "timestamp" }),
finishedAt: int("finishedAt", { mode: "timestamp" }),
},
(table) => [
index("importJobs_userId_createdAt").on(table.userId, table.createdAt),
index("importJobs_status").on(table.status),
],
);
// ─── App Settings ───────────────────────────────────────────────────
export const appSettings = sqliteTable("appSettings", {