From 28159d0a4a659bd299b97bff203a0272558787d5 Mon Sep 17 00:00:00 2001 From: Anthony G <1@anthony.sh> Date: Mon, 10 Aug 2026 14:23:31 +0200 Subject: [PATCH] chore: add config, prisma schema and client (Prisma 7 adapter) --- config/app.config.ts | 8 +++ prisma.config.ts | 12 +++++ .../20260810122259_init/migration.sql | 39 +++++++++++++++ prisma/migrations/migration_lock.toml | 3 ++ prisma/schema.prisma | 49 +++++++++++++++++++ src/lib/prisma.ts | 16 ++++++ 6 files changed, 127 insertions(+) create mode 100644 config/app.config.ts create mode 100644 prisma.config.ts create mode 100644 prisma/migrations/20260810122259_init/migration.sql create mode 100644 prisma/migrations/migration_lock.toml create mode 100644 prisma/schema.prisma create mode 100644 src/lib/prisma.ts diff --git a/config/app.config.ts b/config/app.config.ts new file mode 100644 index 0000000..301ba69 --- /dev/null +++ b/config/app.config.ts @@ -0,0 +1,8 @@ +export const config = { + DOWNLOAD_LINK_TTL_HOURS: 24, + WORKER_CONCURRENCY: 3, + WORKER_POLL_INTERVAL_MS: 10_000, + STORAGE_PATH: process.env.STORAGE_PATH ?? '', + RATE_LIMIT_MAX: 5, + RATE_LIMIT_WINDOW_MS: 3_600_000, +} as const diff --git a/prisma.config.ts b/prisma.config.ts new file mode 100644 index 0000000..952ca5c --- /dev/null +++ b/prisma.config.ts @@ -0,0 +1,12 @@ +import 'dotenv/config' +import { defineConfig, env } from 'prisma/config' + +export default defineConfig({ + schema: 'prisma/schema.prisma', + migrations: { + path: 'prisma/migrations', + }, + datasource: { + url: env('DATABASE_URL'), + }, +}) diff --git a/prisma/migrations/20260810122259_init/migration.sql b/prisma/migrations/20260810122259_init/migration.sql new file mode 100644 index 0000000..1167afc --- /dev/null +++ b/prisma/migrations/20260810122259_init/migration.sql @@ -0,0 +1,39 @@ +-- CreateTable +CREATE TABLE `Download` ( + `id` VARCHAR(191) NOT NULL, + `uuid` VARCHAR(191) NOT NULL, + `url` TEXT NOT NULL, + `status` ENUM('PENDING', 'PROCESSING', 'DONE', 'FAILED', 'FILE_DELETED') NOT NULL DEFAULT 'PENDING', + `format` VARCHAR(191) NOT NULL, + `quality` VARCHAR(191) NOT NULL, + `subtitles` BOOLEAN NOT NULL DEFAULT false, + `extraArgs` TEXT NULL, + `filePath` TEXT NULL, + `fileName` VARCHAR(191) NULL, + `fileSize` BIGINT NULL, + `errorMsg` TEXT NULL, + `ipAddress` VARCHAR(191) NOT NULL, + `submittedAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + `startedAt` DATETIME(3) NULL, + `completedAt` DATETIME(3) NULL, + `deletedAt` DATETIME(3) NULL, + + UNIQUE INDEX `Download_uuid_key`(`uuid`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `DownloadToken` ( + `id` VARCHAR(191) NOT NULL, + `downloadId` VARCHAR(191) NOT NULL, + `token` VARCHAR(191) NOT NULL, + `expiresAt` DATETIME(3) NOT NULL, + `usedAt` DATETIME(3) NULL, + `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + + UNIQUE INDEX `DownloadToken_token_key`(`token`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- AddForeignKey +ALTER TABLE `DownloadToken` ADD CONSTRAINT `DownloadToken_downloadId_fkey` FOREIGN KEY (`downloadId`) REFERENCES `Download`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/migration_lock.toml b/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000..592fc0b --- /dev/null +++ b/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (e.g., Git) +provider = "mysql" diff --git a/prisma/schema.prisma b/prisma/schema.prisma new file mode 100644 index 0000000..3ba13f6 --- /dev/null +++ b/prisma/schema.prisma @@ -0,0 +1,49 @@ +generator client { + provider = "prisma-client-js" +} + +datasource db { + provider = "mysql" +} + +model Download { + id String @id @default(cuid()) + uuid String @unique @default(uuid()) + url String @db.Text + status Status @default(PENDING) + format String + quality String + subtitles Boolean @default(false) + extraArgs String? @db.Text + + filePath String? @db.Text + fileName String? + fileSize BigInt? + errorMsg String? @db.Text + + ipAddress String + submittedAt DateTime @default(now()) + startedAt DateTime? + completedAt DateTime? + deletedAt DateTime? + + tokens DownloadToken[] +} + +model DownloadToken { + id String @id @default(cuid()) + download Download @relation(fields: [downloadId], references: [id]) + downloadId String + token String @unique @default(uuid()) + expiresAt DateTime + usedAt DateTime? + createdAt DateTime @default(now()) +} + +enum Status { + PENDING + PROCESSING + DONE + FAILED + FILE_DELETED +} diff --git a/src/lib/prisma.ts b/src/lib/prisma.ts new file mode 100644 index 0000000..d512166 --- /dev/null +++ b/src/lib/prisma.ts @@ -0,0 +1,16 @@ +import 'dotenv/config' +import { PrismaClient } from '@prisma/client' +import { PrismaMariaDb } from '@prisma/adapter-mariadb' + +function createPrismaClient() { + const url = process.env.DATABASE_URL + if (!url) throw new Error('DATABASE_URL is not set') + const adapter = new PrismaMariaDb(url) + return new PrismaClient({ adapter }) +} + +const globalForPrisma = globalThis as unknown as { prisma: PrismaClient } + +export const prisma = globalForPrisma.prisma ?? createPrismaClient() + +if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma