diff --git a/SETUP-GUIDE.md b/SETUP-GUIDE.md index 1ebff77e..72052931 100644 --- a/SETUP-GUIDE.md +++ b/SETUP-GUIDE.md @@ -1,81 +1,134 @@ -# Setup guide +# Self Hosting Guide + +This guide will help you set up your own instance of Supermemory. This is neccessary if you want to contribute to the project or if you want to self host the project. You can read more about the stack [here](https://github.com/supermemoryai/supermemory/?tab=readme-ov-file#-the-stack). ## Prerequisites - [bun](https://bun.sh/) - [turbo](https://turbo.build/repo/docs/installing) - [wrangler](https://developers.cloudflare.com/workers/cli-wrangler/install-update) +- [yarn](https://yarnpkg.com/getting-started/install): yarn is required to run scripts using turborepo. bun is not supported by turborepo yet vercel/turbo#4762 +- [Cloudflare Workers](https://developers.cloudflare.com/workers/platform/pricing/): You also need to have a paid Workers plan to use the vectorize feature which is needed run the AI backend. It is currently $5/mo + usage costs. +- [Cloudflare R2](https://developers.cloudflare.com/r2/): You need to enable R2 in the Cloudflare Dashboard for use in the web app. ## Steps 1. Clone the repo 2. Run `bun install` in the root directory -3. Create a `.dev.vars` file in `apps/web` with the following content: + +### web + +1. You need to create OAuth credentials for Google which is need for auth.js (nextauth). Visit https://developers.google.com/identity/protocols/oauth2 to learn more and https://console.cloud.google.com/apis/dashboard to create a new project and OAuth credentials. You need to set the redirect URL to `http://localhost:3000/api/auth/callback/google` for development. You can also set the redirect URL to your own domain if you are deploying the app. +2. Create a `.dev.vars` file in `apps/web` with the following content: ```bash -GOOGLE_CLIENT_ID="-" // required, visit https://developers.google.com/identity/protocols/oauth2 -GOOGLE_CLIENT_SECRET="-" // required -NEXTAUTH_SECRET='nextauthsecret' +GOOGLE_CLIENT_ID="" // required +GOOGLE_CLIENT_SECRET="" // required +NEXTAUTH_SECRET="" // generate by running `openssl rand -base64 32` DATABASE_URL='database.sqlite' NEXTAUTH_URL='http://localhost:3000' -BACKEND_SECURITY_KEY='veryrandomsecuritykey' -BACKEND_BASE_URL="where your backend is hosted" +BACKEND_SECURITY_KEY="" // used to authenticate with the backend. generate a random string using `openssl rand -base64 32` +BACKEND_BASE_URL="http://localhost:8686" ``` -4. Setup the database: +> [!NOTE] +> The `BACKEND_SECURITY_KEY` should be the same as the `SECURITY_KEY` in the `.dev.vars` file in `apps/cf-ai-backend`. -First, edit the `wrangler.toml` file in `apps/web` to point the d1 database to your account. +3. KV Namespaces -You can create a d1 database by running this command - -``` -bunx wrangler d1 create +```bash +bunx wrangler kv namespace create canvas-snaps ``` -And then replace database_name and database_id with the values +```bash +bunx wrangler kv namespace create recommendations +``` + +Do not change the binding value in the `wrangler.toml` but update the id for the namespaces with the values you get from the above commands. + +4. R2 Storage + +```bash +bunx wrangler r2 bucket create supermemory-r2 +``` + +Update bucket_name in the `wrangler.toml` file in `apps/web` to `supermemory-r2` + +5. D1 Database + +```bash +bunx wrangler d1 create supermemory-db-prod +``` + +Update the database_name and database_id in `[[env.production.d1_databases]]` with the values you get from the above command. + +```bash +bunx wrangler d1 create supermemory-db-preview +``` + +Update the database_name and database_id in `[[d1_databases]]` and `[[env.preview.d1_databases]]` with the values you get from the above command. > [!NOTE] > please don't change the binding value even if wrangler cli suggests you to do so. -``` +```bash [[d1_databases]] binding = "DATABASE" -database_name = "YOUR_DATABASE_NAME" +database_name = "supermemory-db-preview" database_id = "YOUR_DB_ID" ``` Simply run this command in `apps/web` -``` -bunx wrangler d1 migrations apply +```bash +bunx wrangler d1 migrations apply supermemory-db-preview ``` -If it runs, you can set up the cloud database as well by removing the `--local` flag, +If it runs, you can set up the cloud database as well by add the `--remote` flag, if you just want to contribute to frontend then just run `bun run dev` in the root of the project and done! (you won't be able to try ai stuff), otherwise continue... -5. You need to host your own worker for the `apps/cf-ai-backend` module. +### cf-ai-backend + +1. You need to host your own worker for the `apps/cf-ai-backend` module. To do this, first edit the `.dev.vars` file in `apps/cf-ai-backend` with the following content: ```bash -SECURITY_KEY="veryrandomsecuritykey" +SECURITY_KEY="veryrandomsecuritykey" // same as BACKEND_SECURITY_KEY in web // Why? to generate embeddings with 4000+ tokens OPENAI_API_KEY="sk-" ``` -6. Run this command to initialise vector database +2. Run this command to initialise vector database > Note: You need to use the workers paid plan to use vectorize for now. -``` -wrangler vectorize create --dimensions=1536 supermem-vector-1 --metric=cosine +```bash +bunx wrangler vectorize create --dimensions=1536 supermemory --metric=cosine ``` -7. Change the `wrangler.toml` file in `apps/cf-ai-backend` to point to your KV namespace +Update the index_name for `[[vectorize]]` in `wrangler.toml` file in `apps/cf-ai-backend` with the `supermemory` or the name you used in the above command. -8. Run `bun dev` in the root directory and Voila! You have your own supermemory instance running! +3. Create KV namespaces for the `cf-ai-backend` module -> Note: You need to replace the url `https://cf-ai-backend.dhr.wtf` everywhere with your own url for the cf-ai-backend module. +```bash +bunx wrangler kv namespace create prod +``` + +Update the id in `[[kv_namespaces]]` in the `wrangler.toml` file in `apps/cf-ai-backend` with the value you get from the above command. + +```bash +bunx wrangler kv namespace create preview +``` + +Update the preview_id in `[[kv_namespaces]]` in the `wrangler.toml` file in `apps/cf-ai-backend` with the value you get from the above command. + +## Local Development + +- Run `bun dev` in the root directory and Voila! You have your own supermemory instance running! + +> [!NOTE] +> It sometimes takes multiple tries to successfully run the `bun dev` command. If you encounter any issues, try running the command again. ## Deploying diff --git a/apps/extension/manifest.json b/apps/extension/manifest.json index 0edcd320..7f998412 100644 --- a/apps/extension/manifest.json +++ b/apps/extension/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "$schema": "https://json.schemastore.org/chrome-manifest", - "version": "2.63", + "version": "2.63.1", "name": "supermemory", "description": "An extension for https://supermemory.ai - an AI hub for all your bookmarks.", "background": { diff --git a/apps/web/app/(auth)/onboarding/page.tsx b/apps/web/app/(auth)/onboarding/page.tsx index 9728d107..b40042d1 100644 --- a/apps/web/app/(auth)/onboarding/page.tsx +++ b/apps/web/app/(auth)/onboarding/page.tsx @@ -1,10 +1,10 @@ "use client"; import { + ArrowUturnDownIcon, ChevronLeftIcon, ChevronRightIcon, QuestionMarkCircleIcon, - ArrowTurnDownLeftIcon, } from "@heroicons/react/24/solid"; import { CheckIcon, PlusCircleIcon } from "@heroicons/react/24/outline"; import { motion } from "framer-motion"; @@ -311,7 +311,7 @@ function StepThree({ currStep }: { currStep: number }) { type="submit" className="rounded-lg bg-[#369DFD1A] p-3 absolute bottom-4 right-2" > - + diff --git a/apps/web/app/(dash)/header/header.tsx b/apps/web/app/(dash)/header/header.tsx index 9c225bc6..eaade258 100644 --- a/apps/web/app/(dash)/header/header.tsx +++ b/apps/web/app/(dash)/header/header.tsx @@ -6,7 +6,13 @@ import Logo from "../../../public/logo.svg"; import { getChatHistory } from "../../actions/fetchers"; import NewChatButton from "./newChatButton"; import AutoBreadCrumbs from "./autoBreadCrumbs"; -import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@repo/ui/shadcn/dropdown-menu"; +import SignOutButton from "./signOutButton"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@repo/ui/shadcn/dropdown-menu"; import { CaretDownIcon } from "@radix-ui/react-icons"; async function Header() { @@ -36,9 +42,9 @@ async function Header() { - History - - + History + + {chatThreads.data.map((thread) => ( @@ -54,6 +60,8 @@ async function Header() { ))} + + diff --git a/apps/web/app/(dash)/header/signOutButton.tsx b/apps/web/app/(dash)/header/signOutButton.tsx new file mode 100644 index 00000000..3ef5fa2a --- /dev/null +++ b/apps/web/app/(dash)/header/signOutButton.tsx @@ -0,0 +1,17 @@ +import { signOut } from "@/server/auth"; +import { Button } from "@repo/ui/shadcn/button"; + +export default function SignOutButton() { + return ( +
{ + "use server" + await signOut() + }} + > + +
+ ); +} \ No newline at end of file diff --git a/apps/web/app/(dash)/home/history.tsx b/apps/web/app/(dash)/home/history.tsx index 307ef4e3..a4cd11d0 100644 --- a/apps/web/app/(dash)/home/history.tsx +++ b/apps/web/app/(dash)/home/history.tsx @@ -1,12 +1,8 @@ -import { getChatHistory } from "@repo/web/app/actions/fetchers"; import { ArrowLongRightIcon } from "@heroicons/react/24/outline"; import { Skeleton } from "@repo/ui/shadcn/skeleton"; -import Link from "next/link"; import { memo, useEffect, useState } from "react"; import { motion } from "framer-motion"; -import { chatThreads } from "@/server/db/schema"; import { getQuerySuggestions } from "@/app/actions/doers"; -import { Button } from "@repo/ui/shadcn/button"; const History = memo(({ setQuery }: { setQuery: (q: string) => void }) => { const [suggestions, setSuggestions] = useState(null); @@ -21,7 +17,12 @@ const History = memo(({ setQuery }: { setQuery: (q: string) => void }) => { } console.log(suggestions); if (typeof suggestions.data === "string") { - setSuggestions(JSON.parse(suggestions.data)); + const queries = suggestions.data.slice(1, -1).split(", "); + const parsedQueries = queries.map((query) => + query.replace(/^'|'$/g, ""), + ); + console.log(parsedQueries); + setSuggestions(parsedQueries); return; } setSuggestions(suggestions.data.reverse().slice(0, 3)); diff --git a/apps/web/app/actions/doers.ts b/apps/web/app/actions/doers.ts index 16d5542f..191d96e4 100644 --- a/apps/web/app/actions/doers.ts +++ b/apps/web/app/actions/doers.ts @@ -458,6 +458,7 @@ export const createChatObject = async ( answer: lastChat.answer.parts.map((part) => part.text).join(""), answerSources: JSON.stringify(lastChat.answer.sources), threadId, + createdAt: new Date(), }); if (!saved) { @@ -782,7 +783,7 @@ export async function getQuerySuggestions() { messages: [ { role: "system", - content: `You are a model that suggests questions based on the user's content. you MUST suggest atleast 1 question to ask. Create 3 suggestions at most.`, + content: `You are a model that suggests questions based on the user's content. you MUST suggest atleast 1 question to ask. AT MAX, create 3 suggestions. not more than that.`, }, { role: "user", diff --git a/apps/web/app/api/chat/route.ts b/apps/web/app/api/chat/route.ts index 3b8d971b..9127261c 100644 --- a/apps/web/app/api/chat/route.ts +++ b/apps/web/app/api/chat/route.ts @@ -7,6 +7,10 @@ import { } from "@repo/shared-types"; import { ensureAuth } from "../ensureAuth"; import { z } from "zod"; +import { db } from "@/server/db"; +import { chatHistory as chatHistoryDb, chatThreads } from "@/server/db/schema"; +import { and, eq, gt, sql } from "drizzle-orm"; +import { join } from "path"; export const runtime = "edge"; @@ -21,6 +25,49 @@ export async function POST(req: NextRequest) { return new Response("Missing BACKEND_SECURITY_KEY", { status: 500 }); } + const ip = req.headers.get("cf-connecting-ip"); + + if (ip) { + if (process.env.RATELIMITER) { + const { success } = await process.env.RATELIMITER.limit({ + key: `chat-${ip}`, + }); + + if (!success) { + console.error("rate limit exceeded"); + return new Response("Rate limit exceeded", { status: 429 }); + } + } else { + console.info("RATELIMITER not found in env"); + } + } else { + console.info("cf-connecting-ip not found in headers"); + } + + const lastHour = new Date(new Date().getTime() - 3600000); + + // Only allow 5 requests per hour for each user, something lke this but this one is bad because chathistory.userid doesnt exist, we have to do a join and get it from the threads table + const result = await db + .select({ + count: sql`count(*)`.mapWith(Number), + }) + .from(chatHistoryDb) + .innerJoin(chatThreads, eq(chatHistoryDb.threadId, chatThreads.id)) + .where( + and( + eq(chatThreads.userId, session.user.id), + gt(chatHistoryDb.createdAt, lastHour) + ) + ) + .execute(); + + if (result[0]?.count && result[0]?.count >= 5) { + // return new Response(`Too many requests ${result[0]?.count}`, { status: 429 }); + console.log(result[0]?.count) + } else { + console.log("count", result); + } + const url = new URL(req.url); const query = url.searchParams.get("q"); diff --git a/apps/web/app/api/store/route.ts b/apps/web/app/api/store/route.ts index f9ab7c01..da393d2e 100644 --- a/apps/web/app/api/store/route.ts +++ b/apps/web/app/api/store/route.ts @@ -4,7 +4,7 @@ import { ensureAuth } from "../ensureAuth"; import { z } from "zod"; import { db } from "@/server/db"; import { contentToSpace, space, storedContent } from "@/server/db/schema"; -import { and, eq, inArray } from "drizzle-orm"; +import { and, eq, gt, inArray, sql } from "drizzle-orm"; import { LIMITS } from "@/lib/constants"; import { limit } from "@/app/actions/doers"; @@ -22,6 +22,24 @@ const createMemoryFromAPI = async (input: { }; } + // Get number of items saved in the last 2 hours + const last2Hours = new Date(Date.now() - 2 * 60 * 60 * 1000); + + const numberOfItemsSavedInLast2Hours = await db + .select({ + count: sql`count(*)`.mapWith(Number), + }) + .from(storedContent) + .where(and(gt(storedContent.savedAt, last2Hours), eq(storedContent.userId, input.userId))) + + if (numberOfItemsSavedInLast2Hours[0]!.count >= 20) { + return { + success: false, + data: 0, + error: `You have exceeded the limit`, + }; + } + const vectorSaveResponse = await fetch( `${process.env.BACKEND_BASE_URL}/api/add`, { diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx index cf6e9b0f..94a538ed 100644 --- a/apps/web/app/layout.tsx +++ b/apps/web/app/layout.tsx @@ -66,9 +66,14 @@ export default function RootLayout({ }): JSX.Element { return ( - {/* - - */} + + {/* Cloudflare web analytics */} + + {/* TODO: when lightmode support is added, remove the 'dark' class from the body tag */} {success: boolean} + }; } } } diff --git a/apps/web/migrations/0000_setup.sql b/apps/web/migrations/0000_steep_moira_mactaggert.sql similarity index 97% rename from apps/web/migrations/0000_setup.sql rename to apps/web/migrations/0000_steep_moira_mactaggert.sql index 65a41795..5813639d 100644 --- a/apps/web/migrations/0000_setup.sql +++ b/apps/web/migrations/0000_steep_moira_mactaggert.sql @@ -43,6 +43,7 @@ CREATE TABLE `chatHistory` ( `answerParts` text, `answerSources` text, `answerJustification` text, + `createdAt` integer DEFAULT '"2024-07-25T22:31:50.848Z"' NOT NULL, FOREIGN KEY (`threadId`) REFERENCES `chatThread`(`id`) ON UPDATE no action ON DELETE cascade ); --> statement-breakpoint @@ -106,7 +107,8 @@ CREATE TABLE `user` ( `email` text NOT NULL, `emailVerified` integer, `image` text, - `telegramId` text + `telegramId` text, + `hasOnboarded` integer DEFAULT false ); --> statement-breakpoint CREATE TABLE `verificationToken` ( diff --git a/apps/web/migrations/0001_dear_sally_floyd.sql b/apps/web/migrations/0001_dear_sally_floyd.sql deleted file mode 100644 index 8fa112f7..00000000 --- a/apps/web/migrations/0001_dear_sally_floyd.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE `user` ADD `hasOnboarded` integer DEFAULT false; \ No newline at end of file diff --git a/apps/web/migrations/meta/0000_snapshot.json b/apps/web/migrations/meta/0000_snapshot.json index 7e502c8b..a7689010 100644 --- a/apps/web/migrations/meta/0000_snapshot.json +++ b/apps/web/migrations/meta/0000_snapshot.json @@ -1,895 +1,822 @@ { - "version": "6", - "dialect": "sqlite", - "id": "e8646bed-105d-4f69-b385-b8b6fee8a6a9", - "prevId": "00000000-0000-0000-0000-000000000000", - "tables": { - "account": { - "name": "account", - "columns": { - "userId": { - "name": "userId", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "providerAccountId": { - "name": "providerAccountId", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "refresh_token": { - "name": "refresh_token", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "access_token": { - "name": "access_token", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "expires_at": { - "name": "expires_at", - "type": "integer", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "token_type": { - "name": "token_type", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "scope": { - "name": "scope", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "id_token": { - "name": "id_token", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "session_state": { - "name": "session_state", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "account_userId_user_id_fk": { - "name": "account_userId_user_id_fk", - "tableFrom": "account", - "tableTo": "user", - "columnsFrom": [ - "userId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "account_provider_providerAccountId_pk": { - "columns": [ - "provider", - "providerAccountId" - ], - "name": "account_provider_providerAccountId_pk" - } - }, - "uniqueConstraints": {} - }, - "authenticator": { - "name": "authenticator", - "columns": { - "credentialID": { - "name": "credentialID", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "userId": { - "name": "userId", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "providerAccountId": { - "name": "providerAccountId", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "credentialPublicKey": { - "name": "credentialPublicKey", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "counter": { - "name": "counter", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "credentialDeviceType": { - "name": "credentialDeviceType", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "credentialBackedUp": { - "name": "credentialBackedUp", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "transports": { - "name": "transports", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": { - "authenticator_credentialID_unique": { - "name": "authenticator_credentialID_unique", - "columns": [ - "credentialID" - ], - "isUnique": true - } - }, - "foreignKeys": { - "authenticator_userId_user_id_fk": { - "name": "authenticator_userId_user_id_fk", - "tableFrom": "authenticator", - "tableTo": "user", - "columnsFrom": [ - "userId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "authenticator_userId_credentialID_pk": { - "columns": [ - "credentialID", - "userId" - ], - "name": "authenticator_userId_credentialID_pk" - } - }, - "uniqueConstraints": {} - }, - "canvas": { - "name": "canvas", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "title": { - "name": "title", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'Untitled'" - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'Untitled'" - }, - "url": { - "name": "url", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "''" - }, - "userId": { - "name": "userId", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "canvas_user_userId": { - "name": "canvas_user_userId", - "columns": [ - "userId" - ], - "isUnique": false - } - }, - "foreignKeys": { - "canvas_userId_user_id_fk": { - "name": "canvas_userId_user_id_fk", - "tableFrom": "canvas", - "tableTo": "user", - "columnsFrom": [ - "userId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "chatHistory": { - "name": "chatHistory", - "columns": { - "id": { - "name": "id", - "type": "integer", - "primaryKey": true, - "notNull": true, - "autoincrement": true - }, - "threadId": { - "name": "threadId", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "question": { - "name": "question", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "answerParts": { - "name": "answerParts", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "answerSources": { - "name": "answerSources", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "answerJustification": { - "name": "answerJustification", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": { - "chatHistory_thread_idx": { - "name": "chatHistory_thread_idx", - "columns": [ - "threadId" - ], - "isUnique": false - } - }, - "foreignKeys": { - "chatHistory_threadId_chatThread_id_fk": { - "name": "chatHistory_threadId_chatThread_id_fk", - "tableFrom": "chatHistory", - "tableTo": "chatThread", - "columnsFrom": [ - "threadId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "chatThread": { - "name": "chatThread", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "firstMessage": { - "name": "firstMessage", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "userId": { - "name": "userId", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "chatThread_user_idx": { - "name": "chatThread_user_idx", - "columns": [ - "userId" - ], - "isUnique": false - } - }, - "foreignKeys": { - "chatThread_userId_user_id_fk": { - "name": "chatThread_userId_user_id_fk", - "tableFrom": "chatThread", - "tableTo": "user", - "columnsFrom": [ - "userId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "contentToSpace": { - "name": "contentToSpace", - "columns": { - "contentId": { - "name": "contentId", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "spaceId": { - "name": "spaceId", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "contentToSpace_contentId_storedContent_id_fk": { - "name": "contentToSpace_contentId_storedContent_id_fk", - "tableFrom": "contentToSpace", - "tableTo": "storedContent", - "columnsFrom": [ - "contentId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "contentToSpace_spaceId_space_id_fk": { - "name": "contentToSpace_spaceId_space_id_fk", - "tableFrom": "contentToSpace", - "tableTo": "space", - "columnsFrom": [ - "spaceId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "contentToSpace_contentId_spaceId_pk": { - "columns": [ - "contentId", - "spaceId" - ], - "name": "contentToSpace_contentId_spaceId_pk" - } - }, - "uniqueConstraints": {} - }, - "session": { - "name": "session", - "columns": { - "sessionToken": { - "name": "sessionToken", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "userId": { - "name": "userId", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "expires": { - "name": "expires", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "session_userId_user_id_fk": { - "name": "session_userId_user_id_fk", - "tableFrom": "session", - "tableTo": "user", - "columnsFrom": [ - "userId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "space": { - "name": "space", - "columns": { - "id": { - "name": "id", - "type": "integer", - "primaryKey": true, - "notNull": true, - "autoincrement": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'none'" - }, - "user": { - "name": "user", - "type": "text(255)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "createdAt": { - "name": "createdAt", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "numItems": { - "name": "numItems", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": 0 - } - }, - "indexes": { - "space_name_unique": { - "name": "space_name_unique", - "columns": [ - "name" - ], - "isUnique": true - }, - "spaces_name_idx": { - "name": "spaces_name_idx", - "columns": [ - "name" - ], - "isUnique": false - }, - "spaces_user_idx": { - "name": "spaces_user_idx", - "columns": [ - "user" - ], - "isUnique": false - } - }, - "foreignKeys": { - "space_user_user_id_fk": { - "name": "space_user_user_id_fk", - "tableFrom": "space", - "tableTo": "user", - "columnsFrom": [ - "user" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "spacesAccess": { - "name": "spacesAccess", - "columns": { - "spaceId": { - "name": "spaceId", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "userEmail": { - "name": "userEmail", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "spacesAccess_spaceId_space_id_fk": { - "name": "spacesAccess_spaceId_space_id_fk", - "tableFrom": "spacesAccess", - "tableTo": "space", - "columnsFrom": [ - "spaceId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "spacesAccess_spaceId_userEmail_pk": { - "columns": [ - "spaceId", - "userEmail" - ], - "name": "spacesAccess_spaceId_userEmail_pk" - } - }, - "uniqueConstraints": {} - }, - "storedContent": { - "name": "storedContent", - "columns": { - "id": { - "name": "id", - "type": "integer", - "primaryKey": true, - "notNull": true, - "autoincrement": true - }, - "content": { - "name": "content", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "title": { - "name": "title", - "type": "text(255)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "description": { - "name": "description", - "type": "text(255)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "url": { - "name": "url", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "savedAt": { - "name": "savedAt", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "baseUrl": { - "name": "baseUrl", - "type": "text(255)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "ogImage": { - "name": "ogImage", - "type": "text(255)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false, - "default": "'page'" - }, - "image": { - "name": "image", - "type": "text(255)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "user": { - "name": "user", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "noteId": { - "name": "noteId", - "type": "integer", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": { - "storedContent_baseUrl_unique": { - "name": "storedContent_baseUrl_unique", - "columns": [ - "baseUrl" - ], - "isUnique": true - }, - "storedContent_url_idx": { - "name": "storedContent_url_idx", - "columns": [ - "url" - ], - "isUnique": false - }, - "storedContent_savedAt_idx": { - "name": "storedContent_savedAt_idx", - "columns": [ - "savedAt" - ], - "isUnique": false - }, - "storedContent_title_idx": { - "name": "storedContent_title_idx", - "columns": [ - "title" - ], - "isUnique": false - }, - "storedContent_user_idx": { - "name": "storedContent_user_idx", - "columns": [ - "user" - ], - "isUnique": false - } - }, - "foreignKeys": { - "storedContent_user_user_id_fk": { - "name": "storedContent_user_user_id_fk", - "tableFrom": "storedContent", - "tableTo": "user", - "columnsFrom": [ - "user" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "user": { - "name": "user", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "email": { - "name": "email", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "emailVerified": { - "name": "emailVerified", - "type": "integer", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "image": { - "name": "image", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "telegramId": { - "name": "telegramId", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": { - "users_email_idx": { - "name": "users_email_idx", - "columns": [ - "email" - ], - "isUnique": false - }, - "users_telegram_idx": { - "name": "users_telegram_idx", - "columns": [ - "telegramId" - ], - "isUnique": false - }, - "users_id_idx": { - "name": "users_id_idx", - "columns": [ - "id" - ], - "isUnique": false - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "verificationToken": { - "name": "verificationToken", - "columns": { - "identifier": { - "name": "identifier", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "token": { - "name": "token", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "expires": { - "name": "expires", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": { - "verificationToken_identifier_token_pk": { - "columns": [ - "identifier", - "token" - ], - "name": "verificationToken_identifier_token_pk" - } - }, - "uniqueConstraints": {} - } - }, - "enums": {}, - "_meta": { - "schemas": {}, - "tables": {}, - "columns": {} - } -} \ No newline at end of file + "version": "6", + "dialect": "sqlite", + "id": "8705302a-eae7-4fbf-9ce8-8ae23df228a2", + "prevId": "00000000-0000-0000-0000-000000000000", + "tables": { + "account": { + "name": "account", + "columns": { + "userId": { + "name": "userId", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "providerAccountId": { + "name": "providerAccountId", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "token_type": { + "name": "token_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "session_state": { + "name": "session_state", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "account_userId_user_id_fk": { + "name": "account_userId_user_id_fk", + "tableFrom": "account", + "tableTo": "user", + "columnsFrom": ["userId"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "account_provider_providerAccountId_pk": { + "columns": ["provider", "providerAccountId"], + "name": "account_provider_providerAccountId_pk" + } + }, + "uniqueConstraints": {} + }, + "authenticator": { + "name": "authenticator", + "columns": { + "credentialID": { + "name": "credentialID", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "userId": { + "name": "userId", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "providerAccountId": { + "name": "providerAccountId", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "credentialPublicKey": { + "name": "credentialPublicKey", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "counter": { + "name": "counter", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "credentialDeviceType": { + "name": "credentialDeviceType", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "credentialBackedUp": { + "name": "credentialBackedUp", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "transports": { + "name": "transports", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "authenticator_credentialID_unique": { + "name": "authenticator_credentialID_unique", + "columns": ["credentialID"], + "isUnique": true + } + }, + "foreignKeys": { + "authenticator_userId_user_id_fk": { + "name": "authenticator_userId_user_id_fk", + "tableFrom": "authenticator", + "tableTo": "user", + "columnsFrom": ["userId"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "authenticator_userId_credentialID_pk": { + "columns": ["credentialID", "userId"], + "name": "authenticator_userId_credentialID_pk" + } + }, + "uniqueConstraints": {} + }, + "canvas": { + "name": "canvas", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'Untitled'" + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'Untitled'" + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "''" + }, + "userId": { + "name": "userId", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "canvas_user_userId": { + "name": "canvas_user_userId", + "columns": ["userId"], + "isUnique": false + } + }, + "foreignKeys": { + "canvas_userId_user_id_fk": { + "name": "canvas_userId_user_id_fk", + "tableFrom": "canvas", + "tableTo": "user", + "columnsFrom": ["userId"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "chatHistory": { + "name": "chatHistory", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "threadId": { + "name": "threadId", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "question": { + "name": "question", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "answerParts": { + "name": "answerParts", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "answerSources": { + "name": "answerSources", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "answerJustification": { + "name": "answerJustification", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "createdAt": { + "name": "createdAt", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'\"2024-07-25T22:31:50.848Z\"'" + } + }, + "indexes": { + "chatHistory_thread_idx": { + "name": "chatHistory_thread_idx", + "columns": ["threadId"], + "isUnique": false + } + }, + "foreignKeys": { + "chatHistory_threadId_chatThread_id_fk": { + "name": "chatHistory_threadId_chatThread_id_fk", + "tableFrom": "chatHistory", + "tableTo": "chatThread", + "columnsFrom": ["threadId"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "chatThread": { + "name": "chatThread", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "firstMessage": { + "name": "firstMessage", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "userId": { + "name": "userId", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "chatThread_user_idx": { + "name": "chatThread_user_idx", + "columns": ["userId"], + "isUnique": false + } + }, + "foreignKeys": { + "chatThread_userId_user_id_fk": { + "name": "chatThread_userId_user_id_fk", + "tableFrom": "chatThread", + "tableTo": "user", + "columnsFrom": ["userId"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "contentToSpace": { + "name": "contentToSpace", + "columns": { + "contentId": { + "name": "contentId", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "spaceId": { + "name": "spaceId", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "contentToSpace_contentId_storedContent_id_fk": { + "name": "contentToSpace_contentId_storedContent_id_fk", + "tableFrom": "contentToSpace", + "tableTo": "storedContent", + "columnsFrom": ["contentId"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "contentToSpace_spaceId_space_id_fk": { + "name": "contentToSpace_spaceId_space_id_fk", + "tableFrom": "contentToSpace", + "tableTo": "space", + "columnsFrom": ["spaceId"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "contentToSpace_contentId_spaceId_pk": { + "columns": ["contentId", "spaceId"], + "name": "contentToSpace_contentId_spaceId_pk" + } + }, + "uniqueConstraints": {} + }, + "session": { + "name": "session", + "columns": { + "sessionToken": { + "name": "sessionToken", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "userId": { + "name": "userId", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires": { + "name": "expires", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "session_userId_user_id_fk": { + "name": "session_userId_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": ["userId"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "space": { + "name": "space", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'none'" + }, + "user": { + "name": "user", + "type": "text(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "createdAt": { + "name": "createdAt", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "numItems": { + "name": "numItems", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 0 + } + }, + "indexes": { + "space_name_unique": { + "name": "space_name_unique", + "columns": ["name"], + "isUnique": true + }, + "spaces_name_idx": { + "name": "spaces_name_idx", + "columns": ["name"], + "isUnique": false + }, + "spaces_user_idx": { + "name": "spaces_user_idx", + "columns": ["user"], + "isUnique": false + } + }, + "foreignKeys": { + "space_user_user_id_fk": { + "name": "space_user_user_id_fk", + "tableFrom": "space", + "tableTo": "user", + "columnsFrom": ["user"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "spacesAccess": { + "name": "spacesAccess", + "columns": { + "spaceId": { + "name": "spaceId", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "userEmail": { + "name": "userEmail", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "spacesAccess_spaceId_space_id_fk": { + "name": "spacesAccess_spaceId_space_id_fk", + "tableFrom": "spacesAccess", + "tableTo": "space", + "columnsFrom": ["spaceId"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "spacesAccess_spaceId_userEmail_pk": { + "columns": ["spaceId", "userEmail"], + "name": "spacesAccess_spaceId_userEmail_pk" + } + }, + "uniqueConstraints": {} + }, + "storedContent": { + "name": "storedContent", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "savedAt": { + "name": "savedAt", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "baseUrl": { + "name": "baseUrl", + "type": "text(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "ogImage": { + "name": "ogImage", + "type": "text(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "'page'" + }, + "image": { + "name": "image", + "type": "text(255)", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "user": { + "name": "user", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "noteId": { + "name": "noteId", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "storedContent_baseUrl_unique": { + "name": "storedContent_baseUrl_unique", + "columns": ["baseUrl"], + "isUnique": true + }, + "storedContent_url_idx": { + "name": "storedContent_url_idx", + "columns": ["url"], + "isUnique": false + }, + "storedContent_savedAt_idx": { + "name": "storedContent_savedAt_idx", + "columns": ["savedAt"], + "isUnique": false + }, + "storedContent_title_idx": { + "name": "storedContent_title_idx", + "columns": ["title"], + "isUnique": false + }, + "storedContent_user_idx": { + "name": "storedContent_user_idx", + "columns": ["user"], + "isUnique": false + } + }, + "foreignKeys": { + "storedContent_user_user_id_fk": { + "name": "storedContent_user_user_id_fk", + "tableFrom": "storedContent", + "tableTo": "user", + "columnsFrom": ["user"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "user": { + "name": "user", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "emailVerified": { + "name": "emailVerified", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "telegramId": { + "name": "telegramId", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "hasOnboarded": { + "name": "hasOnboarded", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + } + }, + "indexes": { + "users_email_idx": { + "name": "users_email_idx", + "columns": ["email"], + "isUnique": false + }, + "users_telegram_idx": { + "name": "users_telegram_idx", + "columns": ["telegramId"], + "isUnique": false + }, + "users_id_idx": { + "name": "users_id_idx", + "columns": ["id"], + "isUnique": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "verificationToken": { + "name": "verificationToken", + "columns": { + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expires": { + "name": "expires", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "verificationToken_identifier_token_pk": { + "columns": ["identifier", "token"], + "name": "verificationToken_identifier_token_pk" + } + }, + "uniqueConstraints": {} + } + }, + "enums": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + } +} diff --git a/apps/web/migrations/meta/0001_snapshot.json b/apps/web/migrations/meta/0001_snapshot.json deleted file mode 100644 index 461b3c72..00000000 --- a/apps/web/migrations/meta/0001_snapshot.json +++ /dev/null @@ -1,903 +0,0 @@ -{ - "version": "6", - "dialect": "sqlite", - "id": "1f43694b-f42b-4074-876e-8501fc18bf38", - "prevId": "e8646bed-105d-4f69-b385-b8b6fee8a6a9", - "tables": { - "account": { - "name": "account", - "columns": { - "userId": { - "name": "userId", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "provider": { - "name": "provider", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "providerAccountId": { - "name": "providerAccountId", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "refresh_token": { - "name": "refresh_token", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "access_token": { - "name": "access_token", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "expires_at": { - "name": "expires_at", - "type": "integer", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "token_type": { - "name": "token_type", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "scope": { - "name": "scope", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "id_token": { - "name": "id_token", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "session_state": { - "name": "session_state", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "account_userId_user_id_fk": { - "name": "account_userId_user_id_fk", - "tableFrom": "account", - "tableTo": "user", - "columnsFrom": [ - "userId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "account_provider_providerAccountId_pk": { - "columns": [ - "provider", - "providerAccountId" - ], - "name": "account_provider_providerAccountId_pk" - } - }, - "uniqueConstraints": {} - }, - "authenticator": { - "name": "authenticator", - "columns": { - "credentialID": { - "name": "credentialID", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "userId": { - "name": "userId", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "providerAccountId": { - "name": "providerAccountId", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "credentialPublicKey": { - "name": "credentialPublicKey", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "counter": { - "name": "counter", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "credentialDeviceType": { - "name": "credentialDeviceType", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "credentialBackedUp": { - "name": "credentialBackedUp", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "transports": { - "name": "transports", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": { - "authenticator_credentialID_unique": { - "name": "authenticator_credentialID_unique", - "columns": [ - "credentialID" - ], - "isUnique": true - } - }, - "foreignKeys": { - "authenticator_userId_user_id_fk": { - "name": "authenticator_userId_user_id_fk", - "tableFrom": "authenticator", - "tableTo": "user", - "columnsFrom": [ - "userId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "authenticator_userId_credentialID_pk": { - "columns": [ - "credentialID", - "userId" - ], - "name": "authenticator_userId_credentialID_pk" - } - }, - "uniqueConstraints": {} - }, - "canvas": { - "name": "canvas", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "title": { - "name": "title", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'Untitled'" - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'Untitled'" - }, - "url": { - "name": "url", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "''" - }, - "userId": { - "name": "userId", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "canvas_user_userId": { - "name": "canvas_user_userId", - "columns": [ - "userId" - ], - "isUnique": false - } - }, - "foreignKeys": { - "canvas_userId_user_id_fk": { - "name": "canvas_userId_user_id_fk", - "tableFrom": "canvas", - "tableTo": "user", - "columnsFrom": [ - "userId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "chatHistory": { - "name": "chatHistory", - "columns": { - "id": { - "name": "id", - "type": "integer", - "primaryKey": true, - "notNull": true, - "autoincrement": true - }, - "threadId": { - "name": "threadId", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "question": { - "name": "question", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "answerParts": { - "name": "answerParts", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "answerSources": { - "name": "answerSources", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "answerJustification": { - "name": "answerJustification", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": { - "chatHistory_thread_idx": { - "name": "chatHistory_thread_idx", - "columns": [ - "threadId" - ], - "isUnique": false - } - }, - "foreignKeys": { - "chatHistory_threadId_chatThread_id_fk": { - "name": "chatHistory_threadId_chatThread_id_fk", - "tableFrom": "chatHistory", - "tableTo": "chatThread", - "columnsFrom": [ - "threadId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "chatThread": { - "name": "chatThread", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "firstMessage": { - "name": "firstMessage", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "userId": { - "name": "userId", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": { - "chatThread_user_idx": { - "name": "chatThread_user_idx", - "columns": [ - "userId" - ], - "isUnique": false - } - }, - "foreignKeys": { - "chatThread_userId_user_id_fk": { - "name": "chatThread_userId_user_id_fk", - "tableFrom": "chatThread", - "tableTo": "user", - "columnsFrom": [ - "userId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "contentToSpace": { - "name": "contentToSpace", - "columns": { - "contentId": { - "name": "contentId", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "spaceId": { - "name": "spaceId", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "contentToSpace_contentId_storedContent_id_fk": { - "name": "contentToSpace_contentId_storedContent_id_fk", - "tableFrom": "contentToSpace", - "tableTo": "storedContent", - "columnsFrom": [ - "contentId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "contentToSpace_spaceId_space_id_fk": { - "name": "contentToSpace_spaceId_space_id_fk", - "tableFrom": "contentToSpace", - "tableTo": "space", - "columnsFrom": [ - "spaceId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "contentToSpace_contentId_spaceId_pk": { - "columns": [ - "contentId", - "spaceId" - ], - "name": "contentToSpace_contentId_spaceId_pk" - } - }, - "uniqueConstraints": {} - }, - "session": { - "name": "session", - "columns": { - "sessionToken": { - "name": "sessionToken", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "userId": { - "name": "userId", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "expires": { - "name": "expires", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "session_userId_user_id_fk": { - "name": "session_userId_user_id_fk", - "tableFrom": "session", - "tableTo": "user", - "columnsFrom": [ - "userId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "space": { - "name": "space", - "columns": { - "id": { - "name": "id", - "type": "integer", - "primaryKey": true, - "notNull": true, - "autoincrement": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'none'" - }, - "user": { - "name": "user", - "type": "text(255)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "createdAt": { - "name": "createdAt", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "numItems": { - "name": "numItems", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": 0 - } - }, - "indexes": { - "space_name_unique": { - "name": "space_name_unique", - "columns": [ - "name" - ], - "isUnique": true - }, - "spaces_name_idx": { - "name": "spaces_name_idx", - "columns": [ - "name" - ], - "isUnique": false - }, - "spaces_user_idx": { - "name": "spaces_user_idx", - "columns": [ - "user" - ], - "isUnique": false - } - }, - "foreignKeys": { - "space_user_user_id_fk": { - "name": "space_user_user_id_fk", - "tableFrom": "space", - "tableTo": "user", - "columnsFrom": [ - "user" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "spacesAccess": { - "name": "spacesAccess", - "columns": { - "spaceId": { - "name": "spaceId", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "userEmail": { - "name": "userEmail", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": { - "spacesAccess_spaceId_space_id_fk": { - "name": "spacesAccess_spaceId_space_id_fk", - "tableFrom": "spacesAccess", - "tableTo": "space", - "columnsFrom": [ - "spaceId" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "spacesAccess_spaceId_userEmail_pk": { - "columns": [ - "spaceId", - "userEmail" - ], - "name": "spacesAccess_spaceId_userEmail_pk" - } - }, - "uniqueConstraints": {} - }, - "storedContent": { - "name": "storedContent", - "columns": { - "id": { - "name": "id", - "type": "integer", - "primaryKey": true, - "notNull": true, - "autoincrement": true - }, - "content": { - "name": "content", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "title": { - "name": "title", - "type": "text(255)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "description": { - "name": "description", - "type": "text(255)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "url": { - "name": "url", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "savedAt": { - "name": "savedAt", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "baseUrl": { - "name": "baseUrl", - "type": "text(255)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "ogImage": { - "name": "ogImage", - "type": "text(255)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false, - "default": "'page'" - }, - "image": { - "name": "image", - "type": "text(255)", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "user": { - "name": "user", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "noteId": { - "name": "noteId", - "type": "integer", - "primaryKey": false, - "notNull": false, - "autoincrement": false - } - }, - "indexes": { - "storedContent_baseUrl_unique": { - "name": "storedContent_baseUrl_unique", - "columns": [ - "baseUrl" - ], - "isUnique": true - }, - "storedContent_url_idx": { - "name": "storedContent_url_idx", - "columns": [ - "url" - ], - "isUnique": false - }, - "storedContent_savedAt_idx": { - "name": "storedContent_savedAt_idx", - "columns": [ - "savedAt" - ], - "isUnique": false - }, - "storedContent_title_idx": { - "name": "storedContent_title_idx", - "columns": [ - "title" - ], - "isUnique": false - }, - "storedContent_user_idx": { - "name": "storedContent_user_idx", - "columns": [ - "user" - ], - "isUnique": false - } - }, - "foreignKeys": { - "storedContent_user_user_id_fk": { - "name": "storedContent_user_user_id_fk", - "tableFrom": "storedContent", - "tableTo": "user", - "columnsFrom": [ - "user" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "user": { - "name": "user", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true, - "autoincrement": false - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "email": { - "name": "email", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "emailVerified": { - "name": "emailVerified", - "type": "integer", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "image": { - "name": "image", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "telegramId": { - "name": "telegramId", - "type": "text", - "primaryKey": false, - "notNull": false, - "autoincrement": false - }, - "hasOnboarded": { - "name": "hasOnboarded", - "type": "integer", - "primaryKey": false, - "notNull": false, - "autoincrement": false, - "default": false - } - }, - "indexes": { - "users_email_idx": { - "name": "users_email_idx", - "columns": [ - "email" - ], - "isUnique": false - }, - "users_telegram_idx": { - "name": "users_telegram_idx", - "columns": [ - "telegramId" - ], - "isUnique": false - }, - "users_id_idx": { - "name": "users_id_idx", - "columns": [ - "id" - ], - "isUnique": false - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "verificationToken": { - "name": "verificationToken", - "columns": { - "identifier": { - "name": "identifier", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "token": { - "name": "token", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false - }, - "expires": { - "name": "expires", - "type": "integer", - "primaryKey": false, - "notNull": true, - "autoincrement": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": { - "verificationToken_identifier_token_pk": { - "columns": [ - "identifier", - "token" - ], - "name": "verificationToken_identifier_token_pk" - } - }, - "uniqueConstraints": {} - } - }, - "enums": {}, - "_meta": { - "schemas": {}, - "tables": {}, - "columns": {} - } -} \ No newline at end of file diff --git a/apps/web/migrations/meta/_journal.json b/apps/web/migrations/meta/_journal.json index ba09e752..d79e2607 100644 --- a/apps/web/migrations/meta/_journal.json +++ b/apps/web/migrations/meta/_journal.json @@ -1,20 +1,13 @@ { - "version": "6", - "dialect": "sqlite", - "entries": [ - { - "idx": 0, - "version": "6", - "when": 1721746132570, - "tag": "0000_silky_havok", - "breakpoints": true - }, - { - "idx": 1, - "version": "6", - "when": 1721775651258, - "tag": "0001_dear_sally_floyd", - "breakpoints": true - } - ] -} \ No newline at end of file + "version": "6", + "dialect": "sqlite", + "entries": [ + { + "idx": 0, + "version": "6", + "when": 1721946710900, + "tag": "0000_steep_moira_mactaggert", + "breakpoints": true + } + ] +} diff --git a/apps/web/server/db/schema.ts b/apps/web/server/db/schema.ts index 8486c788..35267eb8 100644 --- a/apps/web/server/db/schema.ts +++ b/apps/web/server/db/schema.ts @@ -1,3 +1,4 @@ +import { create } from "domain"; import { relations, sql } from "drizzle-orm"; import { index, @@ -211,6 +212,7 @@ export const chatHistory = createTable( answer: text("answerParts"), // Single answer part as string answerSources: text("answerSources"), // JSON stringified array of objects answerJustification: text("answerJustification"), + createdAt: int("createdAt", { mode: "timestamp" }).notNull().default(new Date()), }, (history) => ({ threadIdx: index("chatHistory_thread_idx").on(history.threadId),