update global (texte + logo)

This commit is contained in:
2024-04-18 17:19:24 +02:00
parent f9d05a2fd3
commit 1c73080fe3
307 changed files with 28214 additions and 105 deletions

View File

@ -0,0 +1,176 @@
-- CreateTable
CREATE TABLE "Account" (
"id" TEXT NOT NULL,
"userId" INTEGER NOT NULL,
"type" TEXT NOT NULL,
"provider" TEXT NOT NULL,
"providerAccountId" TEXT NOT NULL,
"refresh_token" TEXT,
"access_token" TEXT,
"expires_at" INTEGER,
"token_type" TEXT,
"scope" TEXT,
"id_token" TEXT,
"session_state" TEXT,
CONSTRAINT "Account_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Session" (
"id" TEXT NOT NULL,
"sessionToken" TEXT NOT NULL,
"userId" INTEGER NOT NULL,
"expires" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Session_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "User" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
"username" TEXT,
"email" TEXT,
"emailVerified" TIMESTAMP(3),
"image" TEXT,
"password" TEXT NOT NULL,
"isPrivate" BOOLEAN NOT NULL DEFAULT false,
"whitelistedUsers" TEXT[] DEFAULT ARRAY[]::TEXT[],
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "VerificationToken" (
"identifier" TEXT NOT NULL,
"token" TEXT NOT NULL,
"expires" TIMESTAMP(3) NOT NULL
);
-- CreateTable
CREATE TABLE "Collection" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT NOT NULL DEFAULT '',
"color" TEXT NOT NULL DEFAULT '#0ea5e9',
"isPublic" BOOLEAN NOT NULL DEFAULT false,
"ownerId" INTEGER NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Collection_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "UsersAndCollections" (
"userId" INTEGER NOT NULL,
"collectionId" INTEGER NOT NULL,
"canCreate" BOOLEAN NOT NULL,
"canUpdate" BOOLEAN NOT NULL,
"canDelete" BOOLEAN NOT NULL,
CONSTRAINT "UsersAndCollections_pkey" PRIMARY KEY ("userId","collectionId")
);
-- CreateTable
CREATE TABLE "Link" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
"url" TEXT NOT NULL,
"description" TEXT NOT NULL DEFAULT '',
"collectionId" INTEGER NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Link_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Tag" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
"ownerId" INTEGER NOT NULL,
CONSTRAINT "Tag_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "_LinkToUser" (
"A" INTEGER NOT NULL,
"B" INTEGER NOT NULL
);
-- CreateTable
CREATE TABLE "_LinkToTag" (
"A" INTEGER NOT NULL,
"B" INTEGER NOT NULL
);
-- CreateIndex
CREATE UNIQUE INDEX "Account_provider_providerAccountId_key" ON "Account"("provider", "providerAccountId");
-- CreateIndex
CREATE UNIQUE INDEX "Session_sessionToken_key" ON "Session"("sessionToken");
-- CreateIndex
CREATE UNIQUE INDEX "User_username_key" ON "User"("username");
-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
-- CreateIndex
CREATE UNIQUE INDEX "VerificationToken_token_key" ON "VerificationToken"("token");
-- CreateIndex
CREATE UNIQUE INDEX "VerificationToken_identifier_token_key" ON "VerificationToken"("identifier", "token");
-- CreateIndex
CREATE UNIQUE INDEX "Collection_name_ownerId_key" ON "Collection"("name", "ownerId");
-- CreateIndex
CREATE UNIQUE INDEX "Tag_name_ownerId_key" ON "Tag"("name", "ownerId");
-- CreateIndex
CREATE UNIQUE INDEX "_LinkToUser_AB_unique" ON "_LinkToUser"("A", "B");
-- CreateIndex
CREATE INDEX "_LinkToUser_B_index" ON "_LinkToUser"("B");
-- CreateIndex
CREATE UNIQUE INDEX "_LinkToTag_AB_unique" ON "_LinkToTag"("A", "B");
-- CreateIndex
CREATE INDEX "_LinkToTag_B_index" ON "_LinkToTag"("B");
-- AddForeignKey
ALTER TABLE "Account" ADD CONSTRAINT "Account_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Session" ADD CONSTRAINT "Session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Collection" ADD CONSTRAINT "Collection_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "UsersAndCollections" ADD CONSTRAINT "UsersAndCollections_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "UsersAndCollections" ADD CONSTRAINT "UsersAndCollections_collectionId_fkey" FOREIGN KEY ("collectionId") REFERENCES "Collection"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Link" ADD CONSTRAINT "Link_collectionId_fkey" FOREIGN KEY ("collectionId") REFERENCES "Collection"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Tag" ADD CONSTRAINT "Tag_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_LinkToUser" ADD CONSTRAINT "_LinkToUser_A_fkey" FOREIGN KEY ("A") REFERENCES "Link"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_LinkToUser" ADD CONSTRAINT "_LinkToUser_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_LinkToTag" ADD CONSTRAINT "_LinkToTag_A_fkey" FOREIGN KEY ("A") REFERENCES "Link"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_LinkToTag" ADD CONSTRAINT "_LinkToTag_B_fkey" FOREIGN KEY ("B") REFERENCES "Tag"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -0,0 +1,20 @@
/*
Warnings:
- You are about to drop the column `whitelistedUsers` on the `User` table. All the data in the column will be lost.
*/
-- AlterTable
ALTER TABLE "User" DROP COLUMN "whitelistedUsers";
-- CreateTable
CREATE TABLE "WhitelistedUser" (
"id" SERIAL NOT NULL,
"username" TEXT NOT NULL DEFAULT '',
"userId" INTEGER,
CONSTRAINT "WhitelistedUser_pkey" PRIMARY KEY ("id")
);
-- AddForeignKey
ALTER TABLE "WhitelistedUser" ADD CONSTRAINT "WhitelistedUser_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;

View File

@ -0,0 +1,4 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "archiveAsPDF" BOOLEAN NOT NULL DEFAULT true,
ADD COLUMN "archiveAsScreenshot" BOOLEAN NOT NULL DEFAULT true,
ADD COLUMN "archiveAsWaybackMachine" BOOLEAN NOT NULL DEFAULT false;

View File

@ -0,0 +1,13 @@
/*
Warnings:
- You are about to drop the column `image` on the `User` table. All the data in the column will be lost.
*/
-- AlterTable
ALTER TABLE "Link" ADD COLUMN "pdfPath" TEXT,
ADD COLUMN "screenshotPath" TEXT;
-- AlterTable
ALTER TABLE "User" DROP COLUMN "image",
ADD COLUMN "imagePath" TEXT;

View File

@ -0,0 +1,24 @@
-- AlterTable
ALTER TABLE "Collection" ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE "Link" ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE "Tag" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE "User" ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE "UsersAndCollections" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE "VerificationToken" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
-- AlterTable
ALTER TABLE "WhitelistedUser" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;

View File

@ -0,0 +1,18 @@
/*
Warnings:
- You are about to drop the `Account` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `Session` table. If the table is not empty, all the data it contains will be lost.
*/
-- DropForeignKey
ALTER TABLE "Account" DROP CONSTRAINT "Account_userId_fkey";
-- DropForeignKey
ALTER TABLE "Session" DROP CONSTRAINT "Session_userId_fkey";
-- DropTable
DROP TABLE "Account";
-- DropTable
DROP TABLE "Session";

View File

@ -0,0 +1 @@
ALTER TABLE "User" RENAME COLUMN "imagePath" TO "image";

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Link" ADD COLUMN "readabilityPath" TEXT;

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Link" ADD COLUMN "lastPreserved" TIMESTAMP(3);

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Link" ADD COLUMN "textContent" TEXT;

View File

@ -0,0 +1,19 @@
-- CreateTable
CREATE TABLE "Subscription" (
"id" SERIAL NOT NULL,
"active" BOOLEAN NOT NULL,
"stripeSubscriptionId" TEXT NOT NULL,
"currentPeriodStart" TIMESTAMP(3) NOT NULL,
"currentPeriodEnd" TIMESTAMP(3) NOT NULL,
"userId" INTEGER NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Subscription_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "Subscription_stripeSubscriptionId_key" ON "Subscription"("stripeSubscriptionId");
-- AddForeignKey
ALTER TABLE "Subscription" ADD CONSTRAINT "Subscription_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@ -0,0 +1,8 @@
/*
Warnings:
- A unique constraint covering the columns `[userId]` on the table `Subscription` will be added. If there are existing duplicate values, this will fail.
*/
-- CreateIndex
CREATE UNIQUE INDEX "Subscription_userId_key" ON "Subscription"("userId");

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "User" ALTER COLUMN "password" DROP NOT NULL;

View File

@ -0,0 +1,23 @@
-- CreateTable
CREATE TABLE "Account" (
"id" TEXT NOT NULL,
"userId" INTEGER NOT NULL,
"type" TEXT NOT NULL,
"provider" TEXT NOT NULL,
"providerAccountId" TEXT NOT NULL,
"refresh_token" TEXT,
"access_token" TEXT,
"expires_at" INTEGER,
"token_type" TEXT,
"scope" TEXT,
"id_token" TEXT,
"session_state" TEXT,
CONSTRAINT "Account_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "Account_provider_providerAccountId_key" ON "Account"("provider", "providerAccountId");
-- AddForeignKey
ALTER TABLE "Account" ADD CONSTRAINT "Account_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "blurredFavicons" BOOLEAN NOT NULL DEFAULT true;

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "displayLinkIcons" BOOLEAN NOT NULL DEFAULT true;

View File

@ -0,0 +1,22 @@
-- CreateTable
CREATE TABLE "ApiKeys" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
"userId" INTEGER NOT NULL,
"token" TEXT NOT NULL,
"expires" TIMESTAMP(3) NOT NULL,
"lastUsedAt" TIMESTAMP(3),
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "ApiKeys_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "ApiKeys_token_key" ON "ApiKeys"("token");
-- CreateIndex
CREATE UNIQUE INDEX "ApiKeys_token_userId_key" ON "ApiKeys"("token", "userId");
-- AddForeignKey
ALTER TABLE "ApiKeys" ADD CONSTRAINT "ApiKeys_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@ -0,0 +1,34 @@
/*
Warnings:
- You are about to drop the `ApiKeys` table. If the table is not empty, all the data it contains will be lost.
*/
-- DropForeignKey
ALTER TABLE "ApiKeys" DROP CONSTRAINT "ApiKeys_userId_fkey";
-- DropTable
DROP TABLE "ApiKeys";
-- CreateTable
CREATE TABLE "ApiKey" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
"userId" INTEGER NOT NULL,
"token" TEXT NOT NULL,
"expires" TIMESTAMP(3) NOT NULL,
"lastUsedAt" TIMESTAMP(3),
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "ApiKey_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "ApiKey_token_key" ON "ApiKey"("token");
-- CreateIndex
CREATE UNIQUE INDEX "ApiKey_token_userId_key" ON "ApiKey"("token", "userId");
-- AddForeignKey
ALTER TABLE "ApiKey" ADD CONSTRAINT "ApiKey_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "User" ALTER COLUMN "blurredFavicons" SET DEFAULT false;

View File

@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "Link" ADD COLUMN "type" TEXT NOT NULL DEFAULT 'url',
ALTER COLUMN "url" DROP NOT NULL;

View File

@ -0,0 +1,10 @@
/*
Warnings:
- You are about to drop the column `blurredFavicons` on the `User` table. All the data in the column will be lost.
- You are about to drop the column `displayLinkIcons` on the `User` table. All the data in the column will be lost.
*/
-- AlterTable
ALTER TABLE "User" DROP COLUMN "blurredFavicons",
DROP COLUMN "displayLinkIcons";

View File

@ -0,0 +1,13 @@
/*
Warnings:
- You are about to drop the column `pdf` on the `Link` table. All the data in the column will be lost.
- You are about to drop the column `readable` on the `Link` table. All the data in the column will be lost.
- You are about to drop the column `screenshotPath` on the `Link` table. All the data in the column will be lost.
*/
-- AlterTable
ALTER TABLE "Link" RENAME COLUMN "screenshotPath" TO "image";
ALTER TABLE "Link" RENAME COLUMN "pdfPath" TO "pdf";
ALTER TABLE "Link" RENAME COLUMN "readabilityPath" TO "readable";
ALTER TABLE "Link" ADD COLUMN "preview" TEXT;

View File

@ -0,0 +1,8 @@
/*
Warnings:
- A unique constraint covering the columns `[name]` on the table `ApiKey` will be added. If there are existing duplicate values, this will fail.
*/
-- CreateIndex
CREATE UNIQUE INDEX "ApiKey_name_key" ON "ApiKey"("name");

View File

@ -0,0 +1,14 @@
/*
Warnings:
- A unique constraint covering the columns `[name,userId]` on the table `ApiKey` will be added. If there are existing duplicate values, this will fail.
*/
-- DropIndex
DROP INDEX "ApiKey_name_key";
-- DropIndex
DROP INDEX "ApiKey_token_userId_key";
-- CreateIndex
CREATE UNIQUE INDEX "ApiKey_name_userId_key" ON "ApiKey"("name", "userId");

View File

@ -0,0 +1,35 @@
/*
Warnings:
- You are about to drop the `ApiKey` table. If the table is not empty, all the data it contains will be lost.
*/
-- DropForeignKey
ALTER TABLE "ApiKey" DROP CONSTRAINT "ApiKey_userId_fkey";
-- DropTable
DROP TABLE "ApiKey";
-- CreateTable
CREATE TABLE "AccessToken" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
"userId" INTEGER NOT NULL,
"token" TEXT NOT NULL,
"revoked" BOOLEAN NOT NULL DEFAULT false,
"expires" TIMESTAMP(3) NOT NULL,
"lastUsedAt" TIMESTAMP(3),
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "AccessToken_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "AccessToken_token_key" ON "AccessToken"("token");
-- CreateIndex
CREATE UNIQUE INDEX "AccessToken_name_userId_key" ON "AccessToken"("name", "userId");
-- AddForeignKey
ALTER TABLE "AccessToken" ADD CONSTRAINT "AccessToken_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

View File

@ -0,0 +1,2 @@
-- DropIndex
DROP INDEX "AccessToken_name_userId_key";

View File

@ -0,0 +1,5 @@
-- AlterTable
ALTER TABLE "Collection" ADD COLUMN "parentId" INTEGER;
-- AddForeignKey
ALTER TABLE "Collection" ADD CONSTRAINT "Collection_parentId_fkey" FOREIGN KEY ("parentId") REFERENCES "Collection"("id") ON DELETE SET NULL ON UPDATE CASCADE;

View File

@ -0,0 +1,5 @@
-- CreateEnum
CREATE TYPE "LinksRouteTo" AS ENUM ('ORIGINAL', 'PDF', 'READABLE', 'SCREENSHOT');
-- AlterTable
ALTER TABLE "User" ADD COLUMN "linksRouteTo" "LinksRouteTo" NOT NULL DEFAULT 'ORIGINAL';

View File

@ -0,0 +1,2 @@
-- DropIndex
DROP INDEX "Collection_name_ownerId_key";

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "collectionOrder" INTEGER[] DEFAULT ARRAY[]::INTEGER[];

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "preventDuplicateLinks" BOOLEAN NOT NULL DEFAULT false;

View File

@ -0,0 +1,5 @@
-- CreateIndex
CREATE INDEX "Collection_ownerId_idx" ON "Collection"("ownerId");
-- CreateIndex
CREATE INDEX "UsersAndCollections_userId_idx" ON "UsersAndCollections"("userId");

View File

@ -0,0 +1,2 @@
-- CreateIndex
CREATE INDEX "Tag_ownerId_idx" ON "Tag"("ownerId");

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Link" ADD COLUMN "importDate" TIMESTAMP(3);

View File

@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"

View File

@ -0,0 +1,172 @@
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Account {
id String @id @default(cuid())
userId Int
type String
provider String
providerAccountId String
refresh_token String?
access_token String?
expires_at Int?
token_type String?
scope String?
id_token String?
session_state String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
}
model User {
id Int @id @default(autoincrement())
name String
username String? @unique
email String? @unique
emailVerified DateTime?
image String?
accounts Account[]
password String?
collections Collection[]
tags Tag[]
pinnedLinks Link[]
collectionsJoined UsersAndCollections[]
collectionOrder Int[] @default([])
whitelistedUsers WhitelistedUser[]
accessTokens AccessToken[]
subscriptions Subscription?
linksRouteTo LinksRouteTo @default(ORIGINAL)
preventDuplicateLinks Boolean @default(false)
archiveAsScreenshot Boolean @default(true)
archiveAsPDF Boolean @default(true)
archiveAsWaybackMachine Boolean @default(false)
isPrivate Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
}
enum LinksRouteTo {
ORIGINAL
PDF
READABLE
SCREENSHOT
}
model WhitelistedUser {
id Int @id @default(autoincrement())
username String @default("")
User User? @relation(fields: [userId], references: [id])
userId Int?
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
}
model VerificationToken {
identifier String
token String @unique
expires DateTime
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
@@unique([identifier, token])
}
model Collection {
id Int @id @default(autoincrement())
name String
description String @default("")
color String @default("#0ea5e9")
parentId Int?
parent Collection? @relation("SubCollections", fields: [parentId], references: [id])
subCollections Collection[] @relation("SubCollections")
isPublic Boolean @default(false)
owner User @relation(fields: [ownerId], references: [id])
ownerId Int
members UsersAndCollections[]
links Link[]
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
@@index([ownerId])
}
model UsersAndCollections {
user User @relation(fields: [userId], references: [id])
userId Int
collection Collection @relation(fields: [collectionId], references: [id])
collectionId Int
canCreate Boolean
canUpdate Boolean
canDelete Boolean
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
@@id([userId, collectionId])
@@index([userId])
}
model Link {
id Int @id @default(autoincrement())
name String
type String @default("url")
description String @default("")
pinnedBy User[]
collection Collection @relation(fields: [collectionId], references: [id])
collectionId Int
tags Tag[]
url String?
textContent String?
preview String?
image String?
pdf String?
readable String?
lastPreserved DateTime?
importDate DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
}
model Tag {
id Int @id @default(autoincrement())
name String
links Link[]
owner User @relation(fields: [ownerId], references: [id])
ownerId Int
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
@@unique([name, ownerId])
@@index([ownerId])
}
model Subscription {
id Int @id @default(autoincrement())
active Boolean
stripeSubscriptionId String @unique
currentPeriodStart DateTime
currentPeriodEnd DateTime
user User @relation(fields: [userId], references: [id])
userId Int @unique
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
}
model AccessToken {
id Int @id @default(autoincrement())
name String
user User @relation(fields: [userId], references: [id])
userId Int
token String @unique
revoked Boolean @default(false)
expires DateTime
lastUsedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
}

571
Linkwarden/prisma/seed.js Normal file
View File

@ -0,0 +1,571 @@
// A dirty script to seed the database with some data
const { PrismaClient } = require("@prisma/client");
const bcrypt = require("bcrypt");
const prisma = new PrismaClient();
async function main() {
const saltRounds = 10;
const defaultPassword = "11111111";
const hashedPassword = bcrypt.hashSync(defaultPassword, saltRounds);
// Subscription dates
const currentPeriodStart = new Date();
const currentPeriodEnd = new Date();
currentPeriodEnd.setFullYear(currentPeriodEnd.getFullYear() + 10);
// Operations to be executed within a transaction
const transaction = await prisma.$transaction(async (prisma) => {
// Create users with subscriptions
const user1 = await prisma.user.create({
data: {
name: "John Doe",
username: "user1",
email: "user1@example.com",
emailVerified: new Date(),
password: hashedPassword,
subscriptions: {
create: {
stripeSubscriptionId: "sub_4323",
active: true,
currentPeriodStart,
currentPeriodEnd,
},
},
},
});
const user2 = await prisma.user.create({
data: {
name: "Mary Smith",
username: "user2",
email: "user2@example.com",
emailVerified: new Date(),
password: hashedPassword,
subscriptions: {
create: {
stripeSubscriptionId: "sub_5435",
active: true,
currentPeriodStart,
currentPeriodEnd,
},
},
},
});
const user3 = await prisma.user.create({
data: {
name: "Linda Jones",
username: "user3",
email: "user3@example.com",
emailVerified: new Date(),
password: hashedPassword,
subscriptions: {
create: {
stripeSubscriptionId: "sub_6435",
active: true,
currentPeriodStart,
currentPeriodEnd,
},
},
},
});
const user4 = await prisma.user.create({
data: {
name: "Betty Sanchez",
username: "user4",
email: "user4@example.com",
emailVerified: new Date(),
password: hashedPassword,
subscriptions: {
create: {
stripeSubscriptionId: "sub_7868",
active: true,
currentPeriodStart,
currentPeriodEnd,
},
},
},
});
const user5 = await prisma.user.create({
data: {
name: "Jeffrey Edwards",
username: "user5",
email: "user5@example.com",
emailVerified: new Date(),
password: hashedPassword,
subscriptions: {
create: {
stripeSubscriptionId: "sub_5653",
active: true,
currentPeriodStart,
currentPeriodEnd,
},
},
},
});
// Define and create collections
const collectionsUser1 = [
{
name: "Health and Wellness",
description: "Latest articles on health and wellness.",
ownerId: user1.id,
color: "#ff1100",
},
{
name: "Research",
description: "Latest articles on research.",
ownerId: user1.id,
color: "#000dff",
},
{
name: "Technology",
description: "Latest articles on technology.",
ownerId: user1.id,
color: "#0080ff",
},
{
name: "Personal Finance",
description: "Latest articles on personal finance.",
ownerId: user1.id,
color: "#00ff40",
},
{
name: "Productivity",
description: "Latest articles on productivity.",
ownerId: user1.id,
color: "#ff00f7",
},
{
name: "Recipes",
description: "Latest recipes.",
ownerId: user1.id,
color: "#eeff00",
},
];
const collectionsUser2 = [
{
name: "Project Alpha",
description: "Articles for Project Alpha.",
ownerId: user2.id,
},
];
const user1Collections = await Promise.all(
collectionsUser1.map((c) => prisma.collection.create({ data: c }))
);
const user2Collections = await Promise.all(
collectionsUser2.map((c) => prisma.collection.create({ data: c }))
);
// Share one collection between users with permissions
await Promise.allSettled([
prisma.usersAndCollections.create({
data: {
userId: user1.id,
collectionId: user2Collections[0].id,
canCreate: true,
canUpdate: true,
canDelete: true,
},
}),
prisma.usersAndCollections.create({
data: {
userId: user2.id,
collectionId: user1Collections[1].id,
canCreate: true,
canUpdate: true,
canDelete: true,
},
}),
prisma.usersAndCollections.create({
data: {
userId: user3.id,
collectionId: user1Collections[1].id,
canCreate: true,
canUpdate: true,
canDelete: true,
},
}),
prisma.usersAndCollections.create({
data: {
userId: user4.id,
collectionId: user1Collections[1].id,
canCreate: true,
canUpdate: true,
canDelete: true,
},
}),
prisma.usersAndCollections.create({
data: {
userId: user5.id,
collectionId: user1Collections[1].id,
canCreate: true,
canUpdate: true,
canDelete: true,
},
}),
prisma.usersAndCollections.create({
data: {
userId: user2.id,
collectionId: user2Collections[0].id,
canCreate: true,
canUpdate: true,
canDelete: true,
},
}),
prisma.usersAndCollections.create({
data: {
userId: user3.id,
collectionId: user2Collections[0].id,
canCreate: true,
canUpdate: true,
canDelete: true,
},
}),
prisma.usersAndCollections.create({
data: {
userId: user2.id,
collectionId: user1Collections[0].id,
canCreate: true,
canUpdate: true,
canDelete: true,
},
}),
]);
let projectAlphaCollection = await prisma.collection.findFirst({
where: {
name: "Project Alpha",
ownerId: user2.id,
},
});
const projectAlphaLinks = [
{
name: "More than 10,000 research papers were retracted in 2023 — a new record",
url: "https://www.nature.com/articles/d41586-023-03974-8",
},
{
name: "Advances in Liver Cancer Research",
url: "https://www.cancer.gov/types/liver/research",
},
{
name: "NEW RESEARCH REVEALS TOP AI TOOLS UTILIZED BY MUSIC PRODUCERS",
url: "https://edm.com/gear-tech/top-ai-tools-music-producers",
},
{
name: "New Google research: What we now know about 'decoding' consumer decision-making",
url: "https://www.thinkwithgoogle.com/intl/en-emea/consumer-insights/consumer-journey/the-consumer-decision-making-process/",
},
{
name: "Drug Overdose Death Rates",
url: "https://nida.nih.gov/research-topics/trends-statistics/overdose-death-rates",
},
{
name: "Explore the latest research making an impact in your field",
url: "https://biologue.plos.org/2023/10/25/latest-biological-science-research/",
},
];
for (const link of projectAlphaLinks) {
await prisma.link.create({
data: {
name: link.name,
url: link.url,
collectionId: projectAlphaCollection.id,
},
});
}
for (const [collectionName, links] of Object.entries(linksAndCollections)) {
let collection = await prisma.collection.findFirst({
where: {
name: collectionName,
ownerId: user1.id,
},
});
if (!collection) {
collection = await prisma.collection.create({
data: {
name: collectionName,
ownerId: user1.id,
},
});
}
for (const link of links) {
await prisma.link.create({
data: {
name: link.name,
url: link.url,
collectionId: collection.id,
},
});
}
}
const tags = [
{ name: "technology", ownerId: user1.id },
{ name: "finance", ownerId: user1.id },
{ name: "future", ownerId: user1.id },
{ name: "health", ownerId: user1.id },
{ name: "hacks", ownerId: user1.id },
{ name: "lifestyle", ownerId: user1.id },
{ name: "routine", ownerId: user1.id },
{ name: "personal", ownerId: user1.id },
];
});
return transaction;
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});
const linksAndCollections = {
"Health and Wellness": [
{
name: "50 Wellness Gifts for Anyone Who Could Use Some Self-Care",
url: "https://www.self.com/gallery/healthy-gift-ideas-for-wellness-gurus",
},
{
name: "Hearing aids slow cognitive decline in people at high risk",
url: "https://www.nih.gov/news-events/nih-research-matters/hearing-aids-slow-cognitive-decline-people-high-risk",
},
{
name: "Why Are Healthy Habits Important at Work and Home?",
url: "https://info.totalwellnesshealth.com/blog/why-are-healthy-habits-important",
},
{
name: "Wellness Travel BC explores shifting travel trends as health and wellness take center stage for Canadians",
url: "https://www.vancouverisawesome.com/sponsored/wellness-travel-bc-explores-shifting-travel-trends-as-health-and-wellness-take-center-stage-for-canadians-8004505",
},
{
name: "50 Wellness Gifts for Anyone Who Could Use Some Self-Care",
url: "https://www.self.com/gallery/healthy-gift-ideas-for-wellness-gurus",
},
{
name: "Example",
url: "https://example.com",
},
{
name: "Example",
url: "https://example.com",
},
{
name: "Example",
url: "https://example.com",
},
{
name: "Example",
url: "https://example.com",
},
],
Research: [
{
name: "More than 10,000 research papers were retracted in 2023 — a new record",
url: "https://www.nature.com/articles/d41586-023-03974-8",
},
{
name: "Advances in Liver Cancer Research",
url: "https://www.cancer.gov/types/liver/research",
},
{
name: "NEW RESEARCH REVEALS TOP AI TOOLS UTILIZED BY MUSIC PRODUCERS",
url: "https://edm.com/gear-tech/top-ai-tools-music-producers",
},
{
name: "New Google research: What we now know about 'decoding' consumer decision-making",
url: "https://www.thinkwithgoogle.com/intl/en-emea/consumer-insights/consumer-journey/the-consumer-decision-making-process/",
},
{
name: "Drug Overdose Death Rates",
url: "https://nida.nih.gov/research-topics/trends-statistics/overdose-death-rates",
},
{
name: "Explore the latest research making an impact in your field",
url: "https://biologue.plos.org/2023/10/25/latest-biological-science-research/",
},
{
name: "Example",
url: "https://example.com",
},
],
Technology: [
{
name: "These six questions will dictate the future of generative AI",
url: "https://www.technologyreview.com/2023/12/19/1084505/generative-ai-artificial-intelligence-bias-jobs-copyright-misinformation/",
},
{
name: "Q&A: People will only use technology they trust, Microsoft expert says",
url: "https://www.euronews.com/next/2023/12/21/qa-people-will-only-use-technology-they-trust-microsoft-expert-says",
},
{
name: "How technology and economics can help save endangered species",
url: "https://news.osu.edu/how-technology-and-economics-can-help-save-endangered-species/",
},
{
name: "How technology can help save Indigenous forests and our planet",
url: "https://www.eco-business.com/opinion/how-technology-can-help-save-indigenous-forests-and-our-planet/",
},
{
name: "The most energy-efficient way to build homes",
url: "https://www.technologyreview.com/2023/12/22/1084532/passive-house-energy-efficient-harold-orr/",
},
{
name: "Using virtual reality to diagnose Alzheimer's disease",
url: "https://www.bbc.com/news/technology-67794645",
},
],
"Personal Finance": [
{
name: "Turn your homes empty bedroom into $875 in monthly rent",
url: "https://www.theglobeandmail.com/investing/personal-finance/household-finances/article-turn-your-homes-empty-bedroom-into-875-in-monthly-rent/",
},
{
name: "Dont let financial constraints slow down your gift-giving",
url: "https://www.thespec.com/life/personal-finance/don-t-let-financial-constraints-slow-down-your-gift-giving/article_e3c99ac5-912c-59a9-a815-654befcd4c9c.html",
},
{
name: "The worst retirement planning mistakes you should avoid, according to an expert",
url: "https://www.ctvnews.ca/business/the-worst-retirement-planning-mistakes-you-should-avoid-according-to-an-expert-1.6694093",
},
{
name: "What to Do About That Credit-Card Debt",
url: "https://www.thecut.com/2023/12/what-to-do-about-that-credit-card-debt.html",
},
{
name: "How to become rich: Nine golden personal finance rules that may help you make money",
url: "https://www.livemint.com/money/personal-finance/how-to-become-rich-nine-golden-personal-finance-rules-that-may-help-you-make-money-11703059139843.html",
},
{
name: "Saving Money: Smart Strategies for Keeping Your Financial New Years Resolutions",
url: "https://www.tipranks.com/news/personal-finance/saving-money-smart-strategies-for-keeping-your-financial-new-years-resolutions",
},
{
name: "Example",
url: "https://example.com",
},
{
name: "Example",
url: "https://example.com",
},
],
Productivity: [
{
name: "Efficiency Vs. Productivity At Work: How To Balance Both",
url: "https://www.forbes.com/sites/carolinecastrillon/2023/12/20/efficiency-vs-productivity-at-work-how-to-increase-both/?sh=4c7d486f1bee",
},
{
name: "Is it worth measuring software developer productivity? CIOs weigh in",
url: "https://www.cio.com/article/1255774/is-it-worth-measuring-software-developer-productivity-cios-weigh-in.html",
},
{
name: "Avoid These 10 Business Habits to Increase Workplace Productivity",
url: "https://www.entrepreneur.com/growing-a-business/10-bad-business-habits-that-destroy-productivity/466381",
},
{
name: "The value of productivity",
url: "https://www.tribuneindia.com/news/musings/the-value-of-productivity-573858",
},
{
name: "This new Canonical feature solves my biggest problem with online productivity apps",
url: "https://www.zdnet.com/article/canonical-will-soon-make-it-even-easier-to-work-with-google-workspace-and-office-365-online/",
},
{
name: "10 Practical Recommendations for Increasing Work Results and Value",
url: "https://www.inc.com/martin-zwilling/10-practical-recommendations-for-increasing-work-results-value.html",
},
{
name: "Example",
url: "https://example.com",
},
{
name: "Example",
url: "https://example.com",
},
{
name: "Example",
url: "https://example.com",
},
{
name: "Example",
url: "https://example.com",
},
{
name: "Example",
url: "https://example.com",
},
{
name: "Example",
url: "https://example.com",
},
],
Recipes: [
{
name: "Joe Woodhouses vegetarian standouts for Christmas day recipes",
url: "https://www.theguardian.com/food/2023/dec/22/joe-woodhouses-vegetarian-standouts-for-christmas-day-recipes",
},
{
name: "10 cookie recipes to bake for your holiday party",
url: "https://www.deseret.com/2023/12/21/24009656/best-holiday-cookie-recipes",
},
{
name: "The Best Potato Recipes for Holiday Season and Beyond, According to Eater Staff",
url: "https://www.eater.com/24003490/the-best-potato-recipes-for-holiday-season-and-beyond-according-to-eater-staff",
},
{
name: "The Most-Saved Recipes in the Epicurious App This Week",
url: "https://www.epicurious.com/recipes-menus/most-saved-recipes",
},
{
name: "11 Brand-New Recipes to Try This Month",
url: "https://www.tasteofhome.com/collection/new-recipes-to-try/",
},
{
name: "19 Baked Pasta Recipes for Golden, Gooey Comfort",
url: "https://www.bonappetit.com/gallery/baked-pasta-recipes",
},
{
name: "Example",
url: "https://example.com",
},
{
name: "Example",
url: "https://example.com",
},
{
name: "Example",
url: "https://example.com",
},
{
name: "Example",
url: "https://example.com",
},
{
name: "Example",
url: "https://example.com",
},
{
name: "Example",
url: "https://example.com",
},
{
name: "Example",
url: "https://example.com",
},
],
};