diff --git a/.cursorrules b/.cursorrules
deleted file mode 100644
index 9c20c02a..00000000
--- a/.cursorrules
+++ /dev/null
@@ -1 +0,0 @@
-i am building an app called "supermemory"
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index f205702f..96fab4fe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,12 +1,8 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
-bun.lockb
-tests/
-new-api/
-packages/scripts/*
# Dependencies
-node_modules/
-/.pnp
+node_modules
+.pnp
.pnp.js
# Local env files
@@ -15,10 +11,9 @@ node_modules/
.env.development.local
.env.test.local
.env.production.local
-.env*.local
# Testing
-/coverage
+coverage
# Turbo
.turbo
@@ -27,10 +22,11 @@ node_modules/
.vercel
# Build Outputs
-/.next
+.next/
out/
build
-/dist
+dist
+
# Debug
npm-debug.log*
@@ -40,28 +36,3 @@ yarn-error.log*
# Misc
.DS_Store
*.pem
-
-# IDE specific files
-.idea/
-.vscode/
-*.swp
-*.swo
-
-# Sensitive data
-*.key
-**/credentials.*
-**/secrets.*
-config.private.*
-
-# Cache
-.cache/
-.npm
-.eslintcache
-
-# Local database files
-*.sqlite
-*.db
-
-# Personal notes/todos
-TODO.md
-NOTES.md
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index e69de29b..00000000
diff --git a/.npmrc b/.npmrc
index 145d3fa2..e69de29b 100644
--- a/.npmrc
+++ b/.npmrc
@@ -1,2 +0,0 @@
-save-exact=true
-engine-strict=true
diff --git a/.vscode/settings.json b/.vscode/settings.json
deleted file mode 100644
index 2e1683ca..00000000
--- a/.vscode/settings.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "editor.formatOnSave": true,
- "editor.defaultFormatter": "esbenp.prettier-vscode",
- "editor.codeActionsOnSave": {
- "source.fixAll.eslint": "always"
- },
- "sqltools.connections": [
- {
- "previewLimit": 50,
- "server": "localhost",
- "driver": "PostgreSQL",
- "name": "SupermemoryDB",
- "connectString": "postgresql://dhravya:DPOSTGRES99%40c22%23hLab27postgres@168.119.111.189/supermemory"
- }
- ],
- "millionLint.disableOutdatedVersionMessage": true
-}
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 00000000..16cadd13
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,119 @@
+# CLAUDE.md
+
+This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
+
+## Repository Structure
+
+This is a **Turbo monorepo** containing multiple applications and shared packages:
+
+### Applications (`apps/`)
+- **`web/`** - Next.js web application
+
+## Development Commands
+
+### Root Level (Monorepo)
+- `bun run dev` - Start all applications in development mode
+- `bun run build` - Build all applications
+- `bun run check-types` - Run TypeScript checks across all apps
+- `bun run format-lint` - Format and lint code using Biome
+
+### Web Application (`apps/web/`)
+- `bun run dev` - Start Next.js development server
+- `bun run build` - Build Next.js application
+- `bun run lint` - Run Next.js linting
+
+## Architecture Overview
+
+### Core Technology Stack
+- **Runtime**: Next.js (web)
+- **Framework**: Next.js (web)
+- **Language**: TypeScript throughout
+- **Package Manager**: Bun
+- **Monorepo**: Turbo
+- **Authentication**: Better Auth
+- **Monitoring**: Sentry
+
+### API Application (Primary Backend)
+The API serves as the core backend with these key features:
+
+**Key API Routes**
+- `/v3/memories` - CRUD operations for documents/memories
+- `/v3/search` - Semantic search across indexed content
+- `/v3/connections` - External service integrations (Google Drive, Notion, OneDrive)
+- `/v3/settings` - Organization and user settings
+- `/v3/analytics` - Usage analytics and reporting
+- `/api/auth/*` - Authentication endpoints
+
+### Web Application
+Next.js application providing user interface for:
+
+## Key Libraries & Dependencies
+
+### Shared Dependencies
+- `better-auth` - Authentication system with organization support
+- `drizzle-orm` - Database ORM
+- `zod` - Schema validation
+- `hono` - Web framework (API & MCP)
+- `@sentry/*` - Error monitoring
+- `turbo` - Monorepo build system
+
+### Web-Specific
+- `next` - React framework
+- `@radix-ui/*` - UI components
+- `@tanstack/react-query` - Data fetching
+- `recharts` - Analytics visualization
+
+## Development Workflow
+
+### Content Processing Pipeline
+All content goes through the `IngestContentWorkflow` which handles:
+- Content type detection and extraction
+- AI-powered summarization and automatic tagging
+- Vector embedding generation using Cloudflare AI
+- Chunking for semantic search optimization
+- Space relationship management
+
+### Environment Configuration
+- Uses `wrangler.jsonc` for Cloudflare Workers configuration
+- Supports staging and production environments
+- Requires Cloudflare bindings: Hyperdrive (DB), AI, KV storage, Workflows
+- Cron triggers every 4 hours for connection imports
+
+### Error Handling & Monitoring
+- HTTPException for consistent API error responses
+- Sentry integration with user and organization context
+- Custom logging that filters analytics noise
+
+## Code Quality & Standards
+
+### Linting & Formatting
+- **Biome** used for linting and formatting across the monorepo
+- Run `bun run format-lint` to format and lint all code
+- Configuration in `biome.json` at repository root
+
+### TypeScript
+- Strict TypeScript configuration with `@total-typescript/tsconfig`
+- Type checking with `bun run check-types`
+- Cloudflare Workers type generation with `cf-typegen`
+
+### Database Management
+- Drizzle ORM with schema located in shared packages
+- Database migrations handled through Drizzle Kit
+- Schema types automatically generated and shared
+
+## Security & Best Practices
+
+### Authentication
+- Better Auth handles user authentication and organization management
+- API key authentication for external access
+- Role-based access control within organizations
+
+### Data Handling
+- Content hashing to prevent duplicate processing
+- Secure handling of external service credentials
+- Automatic content type detection and validation
+
+### Deployment
+- Cloudflare Workers for scalable serverless deployment
+- Source map uploads to Sentry for production debugging
+- Environment-specific configuration management
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index ad38bd6e..00000000
--- a/Dockerfile
+++ /dev/null
@@ -1,37 +0,0 @@
-FROM postgres:17
-
-# Install build dependencies
-RUN apt-get update && apt-get install -y \
- build-essential \
- git \
- curl \
- pkg-config \
- libssl-dev \
- libclang-dev \
- llvm-dev \
- postgresql-server-dev-all \
- && rm -rf /var/lib/apt/lists/*
-
-# Install pgvector
-RUN git clone --branch v0.5.1 https://github.com/pgvector/pgvector.git \
- && cd pgvector \
- && make \
- && make install
-
-# Install Rust
-RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
-ENV PATH="/root/.cargo/bin:${PATH}"
-
-# Install and initialize pgrx
-RUN cargo install cargo-pgrx --version 0.12.5 --locked && \
- cargo pgrx init --pg17 pg_config
-
-# Clone and install pgvectorscale
-RUN cd /tmp && \
- git clone --branch 0.5.0 https://github.com/timescale/pgvectorscale && \
- cd pgvectorscale/pgvectorscale && \
- cargo pgrx install --release
-
-# Create initialization script to enable both extensions
-RUN echo 'CREATE EXTENSION IF NOT EXISTS vector;' > /docker-entrypoint-initdb.d/01-init-vector.sql && \
- echo 'CREATE EXTENSION IF NOT EXISTS vectorscale CASCADE;' > /docker-entrypoint-initdb.d/02-init-vectorscale.sql
\ No newline at end of file
diff --git a/README.md b/README.md
index 3f61f8da..afd2af2a 100644
--- a/README.md
+++ b/README.md
@@ -1,89 +1,99 @@
-
+
-
The Memory API for the AI era
-> [!WARNING]
-> This repo contains archived code for supermemory v1 and no longer receives updates or support.
+
+
+
-## π§ What is supermemory?
+## β¨ Features
-supermemory is a powerful, developer-friendly API that seamlessly integrates external knowledge into your AI applications. It serves as the perfect memory layer for your AI stack, providing semantic search and retrieval capabilities that enhance your models with relevant context.
+### Core Functionality
+- **Add Memories from Any Content**: Easily add memories from URLs, PDFs, and plain textβjust paste, upload, or link.
+- **Chat with Your Memories**: Converse with your stored content using natural language chat.
+- **Supermemory MCP Integration**: Seamlessly connect with all major AI tools (Claude, Cursor, etc.) via Supermemory MCP.
+- **Graph View for All Memories**: Visualize and explore your memories and their connections in an interactive graph mode.
-With supermemory, you can:
+## ποΈ Architecture
-- **Store and organize knowledge** in a searchable database that understands meaning, not just keywords
-- **Enhance AI responses** with accurate, up-to-date information from your data
-- **Eliminate hallucinations** by grounding AI outputs in your trusted content
-- **Connect to any source** with pre-built integrations for websites, PDFs, images, and more
+This is a **Turborepo monorepo**
-## β¨ Key Features
+### Technology Stack
+- **Frontend**: Next.js 15 with React 19
+- **Backend**: Hono API framework on Cloudflare Workers
+- **Database**: PostgreSQL with Drizzle ORM
+- **Authentication**: Better Auth with organization support
+- **Package Manager**: Bun
+- **Monorepo**: Turbo for build optimization
+- **Styling**: Tailwind CSS with Radix UI components
+- **Monitoring**: Sentry for error tracking and performance monitoring
-- **Universal Content Handling**: Automatically process and index content from URLs, PDFs, text, and more
-- **Semantic Search**: Find information based on meaning, not just keyword matching
-- **Advanced Filtering**: Organize and retrieve information using metadata, categories, and user partitioning
-- **Query Enhancement**: Rewriting and reranking for more relevant results
-- **Simple Integration**: Clean, consistent API with SDKs for TypeScript and Python
+### Project Structure
+```
+βββ apps/
+β βββ web/ # Next.js web application
+βββ packages/ # Shared packages and utilities
+βββ CLAUDE.md # Development guidelines for AI assistants
+βββ turbo.json # Turborepo configuration
+βββ package.json # Root package configuration
+```
## π Getting Started
-Getting started with supermemory takes just minutes:
+### Prerequisites
+- **Bun** package manager
-1. Sign up at [console.supermemory.ai](https://console.supermemory.ai)
-2. Create your API key
-3. Start adding and querying content
+### Installation
-```javascript
-// Install: npm install supermemory
-import { supermemory } from 'supermemory';
+1. **Clone the repository**
+ ```bash
+ git clone https://github.com/supermemoryai/supermemory-app.git
+ cd supermemory
+ ```
-const client = new supermemory({
- apiKey: 'YOUR_API_KEY',
-});
+2. **Install dependencies**
+ ```bash
+ bun install
+ ```
-// Add content to your knowledge base
-await client.memory.create({
- content: "https://en.wikipedia.org/wiki/Artificial_intelligence",
- metadata: {
- source: "wikipedia",
- category: "AI"
- }
-});
+3. **Environment Setup**
+
+ Create environment files for each app:
+ ```bash
+ # Copy environment templates
+ cp apps/web/.env.example apps/web/.env.local
+ ```
-// Query your knowledge base
-const results = await client.search.create({
- q: "What are the ethical considerations in AI development?",
- limit: 5
-});
+### Development
+
+#### Start all applications in development mode:
+```bash
+bun run dev
```
-## π Documentation
+This will start:
+- Web app at `http://localhost:3000`
+- API endpoints available through the web app
-We've created comprehensive documentation to help you get the most out of supermemory:
-- [Quick Start Guide](https://docs.supermemory.ai/quickstart/overview)
-- [API Reference](https://docs.supermemory.ai/api-reference)
-- [SDK Documentation](https://docs.supermemory.ai/sdks)
-- [Use Cases & Examples](https://docs.supermemory.ai/overview/use-cases)
+## π§ͺ Development Workflow
-## π Use Cases
+### Code Quality
+- **Linting & Formatting**: Uses Biome for consistent code style
+- **Type Safety**: Strict TypeScript configuration across all packages
-supermemory powers a wide range of AI-enhanced applications:
+## π€ Contributing
-- **RAG (Retrieval Augmented Generation)**: Enhance LLM outputs with accurate data
-- **Knowledge Bases & Documentation**: Create intelligent, searchable repositories
-- **Customer Support**: Build chatbots with access to your support documentation
-- **Research Assistants**: Query across papers, notes, and references
-- **Content Management**: Organize and retrieve multimedia content semantically
+### Development Guidelines
+- Follow the code style enforced by Biome
+- Write tests for new features
+- Update documentation when adding new functionality
+- Ensure all checks pass before submitting PRs
-## π¬ Support
-Have questions or feedback? We're here to help:
-- Email: [dhravya@supermemory.com](mailto:dhravya@supermemory.com)
-- Documentation: [docs.supermemory.ai](https://docs.supermemory.ai)
+## π¬ Support & Community
-## π Updates & Roadmap
+- **Issues**: [GitHub Issues](https://github.com/supermemoryai/supermemory-app/issues)
+- **Email**: [dhravya@supermemory.com](mailto:dhravya@supermemory.com)
+- **Twitter**: [@supermemoryai](https://x.com/supermemoryai)
-Stay up to date with the latest improvements:
-- [Changelog](https://docs.supermemory.ai/changelog/overview)
-- [X](https://x.com/supermemoryai)
diff --git a/SELF-HOSTING-GUIDE.md b/SELF-HOSTING-GUIDE.md
deleted file mode 100644
index 523369e2..00000000
--- a/SELF-HOSTING-GUIDE.md
+++ /dev/null
@@ -1,90 +0,0 @@
-# Supermemory self-hosting guide
-
-## Local Setup
-
-### 1. Database Setup
-
-To spin up the database locally, use Docker Compose:
-
-```bash
-docker-compose up -d
-```
-
-This will start a PostgreSQL database with pgvector extension at `localhost:5432`.
-
-### 2. Database Migrations
-
-To generate a migration:
-
-```bash
-bun run generate-migration
-```
-
-To apply migrations:
-
-```bash
-bun run migrate:local
-```
-
-> Note: You MUST use the drizzle-orm functions exported from `packages/db` for interacting with the database. Not using them will cause type errors that are hard to debug.
-
-### 3. Environment Variables
-
-#### Backend (`apps/backend/.env` and `apps/backend/.dev.vars`):
-
-```env
-WORKOS_API_KEY=your_workos_api_key
-WORKOS_CLIENT_ID=your_workos_client_id
-WORKOS_COOKIE_PASSWORD=your_cookie_password
-DATABASE_URL="postgresql://postgres:postgres@localhost:5432/supermemory"
-CONTENT_WORKFLOW=your_content_workflow
-GEMINI_API_KEY=your_gemini_api_key
-NODE_ENV=development
-OPEN_AI_API_KEY=your_openai_api_key
-BRAINTRUST_API_KEY=your_braintrust_api_key
-RESEND_API_KEY=your_resend_api_key
-TURNSTILE_SECRET_KEY=your_turnstile_secret_key
-```
-
-#### Web (`apps/web/.env` and `apps/web/.dev.vars`):
-
-```env
-WORKOS_CLIENT_ID=your_workos_client_id
-WORKOS_API_KEY=your_workos_api_key
-WORKOS_REDIRECT_URI="http://localhost:3000/callback"
-WORKOS_COOKIE_PASSWORD=your_cookie_password
-DATABASE_URL="postgresql://postgres:postgres@localhost:5432/supermemorydhravya"
-
-CLOUDFLARE_ACCOUNT_ID=your_cloudflare_account_id
-R2_ACCESS_KEY_ID=your_r2_access_key_id
-R2_SECRET_ACCESS_KEY=your_r2_secret_access_key
-
-BACKEND_URL=http://localhost:8787
-OPENAI_API_KEY=your_openai_api_key
-NOTION_CLIENT_ID=your_notion_client_id
-NOTION_CLIENT_SECRET=your_notion_client_secret
-
-NODE_ENV=development
-STRIPE_CHECKOUT_KEY=your_stripe_checkout_key
-STRIPE_WEBHOOK_SECRET=your_stripe_webhook_secret
-```
-
-You also need to update the Wrangler config for the web app and backend to your own account's resources on Cloudflare.
-
-### 4. Schema Changes
-
-To edit the database schema, modify the files in `packages/db/schema.ts`, and then repeat the steps in the [Database Migrations](#2-database-migrations) section.
-
-### 5. Running the Application
-
-1. Install dependencies:
-
-```bash
-bun install
-```
-
-2. Start the development servers:
-
-```bash
-bun run dev
-```
diff --git a/apps/backend/.gitignore b/apps/backend/.gitignore
deleted file mode 100644
index e4b00d87..00000000
--- a/apps/backend/.gitignore
+++ /dev/null
@@ -1,35 +0,0 @@
-# prod
-dist/
-.dev.vars
-*.vars
-
-# dev
-.yarn/
-!.yarn/releases
-.vscode/*
-!.vscode/launch.json
-!.vscode/*.code-snippets
-.idea/workspace.xml
-.idea/usage.statistics.xml
-.idea/shelf
-
-# deps
-node_modules/
-.wrangler
-
-# env
-.env
-.env.production
-.dev.vars
-
-# logs
-logs/
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-pnpm-debug.log*
-lerna-debug.log*
-
-# misc
-.DS_Store
diff --git a/apps/backend/README.md b/apps/backend/README.md
deleted file mode 100644
index cc58e962..00000000
--- a/apps/backend/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-```
-npm install
-npm run dev
-```
-
-```
-npm run deploy
-```
diff --git a/apps/backend/drizzle.config.prod.ts b/apps/backend/drizzle.config.prod.ts
deleted file mode 100644
index 4707bf25..00000000
--- a/apps/backend/drizzle.config.prod.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { defineConfig } from "drizzle-kit";
-
-export default defineConfig({
- dialect: "postgresql",
- schema: "../../packages/db",
- out: "./drizzle",
- dbCredentials: {
- url: process.env.PROD_DATABASE_URL!,
- },
-});
diff --git a/apps/backend/drizzle.config.ts b/apps/backend/drizzle.config.ts
deleted file mode 100644
index 3f198a9f..00000000
--- a/apps/backend/drizzle.config.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { config } from "dotenv";
-import { defineConfig } from "drizzle-kit";
-import process from "process";
-
-config();
-
-if (process.env.NODE_ENV !== "production" && !process.env.DATABASE_URL) {
- throw new Error("DATABASE_URL is not set");
-}
-
-export default defineConfig({
- dialect: "postgresql",
- schema: "../../packages/db",
- out: "./drizzle",
- dbCredentials: {
- url: process.env.DATABASE_URL!,
- },
-});
diff --git a/apps/backend/drizzle/0000_odd_impossible_man.sql b/apps/backend/drizzle/0000_odd_impossible_man.sql
deleted file mode 100644
index 0a4b660c..00000000
--- a/apps/backend/drizzle/0000_odd_impossible_man.sql
+++ /dev/null
@@ -1,189 +0,0 @@
-CREATE EXTENSION IF NOT EXISTS vectorscale CASCADE;
-
-CREATE TABLE IF NOT EXISTS "chat_threads" (
- "id" bigserial PRIMARY KEY NOT NULL,
- "uuid" varchar(36) NOT NULL,
- "firstMessage" text NOT NULL,
- "user_id" integer NOT NULL,
- "messages" jsonb NOT NULL,
- "created_at" timestamp with time zone DEFAULT now() NOT NULL,
- CONSTRAINT "chat_threads_uuid_unique" UNIQUE("uuid")
-);
---> statement-breakpoint
-CREATE TABLE IF NOT EXISTS "chunks" (
- "id" serial PRIMARY KEY NOT NULL,
- "document_id" integer NOT NULL,
- "text_content" text,
- "order_in_document" integer NOT NULL,
- "embeddings" vector(1536),
- "metadata" jsonb,
- "created_at" timestamp with time zone DEFAULT now() NOT NULL,
- "updated_at" timestamp with time zone DEFAULT now() NOT NULL
-);
---> statement-breakpoint
-CREATE TABLE IF NOT EXISTS "content_to_space" (
- "content_id" integer NOT NULL,
- "space_id" integer NOT NULL
-);
---> statement-breakpoint
-CREATE TABLE IF NOT EXISTS "document_type" (
- "type" text PRIMARY KEY NOT NULL
-);
---> statement-breakpoint
-CREATE TABLE IF NOT EXISTS "documents" (
- "id" bigserial PRIMARY KEY NOT NULL,
- "uuid" varchar(36) NOT NULL,
- "url" text,
- "created_at" timestamp with time zone DEFAULT now() NOT NULL,
- "updated_at" timestamp with time zone,
- "type" text NOT NULL,
- "title" text,
- "description" text,
- "og_image" text,
- "raw" text,
- "user_id" integer NOT NULL,
- "content" text,
- CONSTRAINT "documents_uuid_unique" UNIQUE("uuid")
-);
---> statement-breakpoint
-CREATE TABLE IF NOT EXISTS "job" (
- "id" serial PRIMARY KEY NOT NULL,
- "user_id" integer NOT NULL,
- "url" text NOT NULL,
- "status" text NOT NULL,
- "attempts" integer DEFAULT 0 NOT NULL,
- "lastAttemptAt" timestamp with time zone,
- "error" text,
- "created_at" timestamp with time zone,
- "updated_at" timestamp with time zone
-);
---> statement-breakpoint
-CREATE TABLE IF NOT EXISTS "space_access" (
- "space_id" integer,
- "user_email" varchar(512),
- "status" text
-);
---> statement-breakpoint
-CREATE TABLE IF NOT EXISTS "space_access_status" (
- "status" text PRIMARY KEY NOT NULL
-);
---> statement-breakpoint
-CREATE TABLE IF NOT EXISTS "space_members" (
- "spaceId" integer NOT NULL,
- "user_id" integer NOT NULL
-);
---> statement-breakpoint
-CREATE TABLE IF NOT EXISTS "spaces" (
- "id" bigserial PRIMARY KEY NOT NULL,
- "uuid" varchar(36) NOT NULL,
- "name" text NOT NULL,
- "created_at" timestamp DEFAULT now() NOT NULL,
- "updated_at" timestamp DEFAULT now() NOT NULL,
- "ownerId" integer NOT NULL,
- "is_public" boolean DEFAULT false NOT NULL,
- CONSTRAINT "spaces_uuid_unique" UNIQUE("uuid")
-);
---> statement-breakpoint
-CREATE TABLE IF NOT EXISTS "users" (
- "id" serial PRIMARY KEY NOT NULL,
- "uuid" varchar(36) NOT NULL,
- "email" text NOT NULL,
- "first_name" text,
- "last_name" text,
- "email_verified" boolean DEFAULT false NOT NULL,
- "profile_picture_url" text,
- "telegram_id" varchar(255),
- "has_onboarded" integer DEFAULT 0 NOT NULL,
- "created_at" timestamp DEFAULT now() NOT NULL,
- "updated_at" timestamp DEFAULT now() NOT NULL,
- CONSTRAINT "users_uuid_unique" UNIQUE("uuid"),
- CONSTRAINT "users_email_unique" UNIQUE("email")
-);
---> statement-breakpoint
-DO $$ BEGIN
- ALTER TABLE "chat_threads" ADD CONSTRAINT "chat_threads_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
-EXCEPTION
- WHEN duplicate_object THEN null;
-END $$;
---> statement-breakpoint
-DO $$ BEGIN
- ALTER TABLE "chunks" ADD CONSTRAINT "chunks_document_id_documents_id_fk" FOREIGN KEY ("document_id") REFERENCES "public"."documents"("id") ON DELETE cascade ON UPDATE no action;
-EXCEPTION
- WHEN duplicate_object THEN null;
-END $$;
---> statement-breakpoint
-DO $$ BEGIN
- ALTER TABLE "content_to_space" ADD CONSTRAINT "content_to_space_content_id_documents_id_fk" FOREIGN KEY ("content_id") REFERENCES "public"."documents"("id") ON DELETE cascade ON UPDATE no action;
-EXCEPTION
- WHEN duplicate_object THEN null;
-END $$;
---> statement-breakpoint
-DO $$ BEGIN
- ALTER TABLE "content_to_space" ADD CONSTRAINT "content_to_space_space_id_spaces_id_fk" FOREIGN KEY ("space_id") REFERENCES "public"."spaces"("id") ON DELETE cascade ON UPDATE no action;
-EXCEPTION
- WHEN duplicate_object THEN null;
-END $$;
---> statement-breakpoint
-DO $$ BEGIN
- ALTER TABLE "documents" ADD CONSTRAINT "documents_type_document_type_type_fk" FOREIGN KEY ("type") REFERENCES "public"."document_type"("type") ON DELETE no action ON UPDATE no action;
-EXCEPTION
- WHEN duplicate_object THEN null;
-END $$;
---> statement-breakpoint
-DO $$ BEGIN
- ALTER TABLE "documents" ADD CONSTRAINT "documents_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;
-EXCEPTION
- WHEN duplicate_object THEN null;
-END $$;
---> statement-breakpoint
-DO $$ BEGIN
- ALTER TABLE "job" ADD CONSTRAINT "job_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
-EXCEPTION
- WHEN duplicate_object THEN null;
-END $$;
---> statement-breakpoint
-DO $$ BEGIN
- ALTER TABLE "space_access" ADD CONSTRAINT "space_access_space_id_spaces_id_fk" FOREIGN KEY ("space_id") REFERENCES "public"."spaces"("id") ON DELETE cascade ON UPDATE no action;
-EXCEPTION
- WHEN duplicate_object THEN null;
-END $$;
---> statement-breakpoint
-DO $$ BEGIN
- ALTER TABLE "space_access" ADD CONSTRAINT "space_access_status_space_access_status_status_fk" FOREIGN KEY ("status") REFERENCES "public"."space_access_status"("status") ON DELETE no action ON UPDATE no action;
-EXCEPTION
- WHEN duplicate_object THEN null;
-END $$;
---> statement-breakpoint
-DO $$ BEGIN
- ALTER TABLE "space_members" ADD CONSTRAINT "space_members_spaceId_users_id_fk" FOREIGN KEY ("spaceId") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;
-EXCEPTION
- WHEN duplicate_object THEN null;
-END $$;
---> statement-breakpoint
-DO $$ BEGIN
- ALTER TABLE "space_members" ADD CONSTRAINT "space_members_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE restrict ON UPDATE no action;
-EXCEPTION
- WHEN duplicate_object THEN null;
-END $$;
---> statement-breakpoint
-CREATE INDEX IF NOT EXISTS "chat_threads_user_idx" ON "chat_threads" USING btree ("user_id");--> statement-breakpoint
-CREATE UNIQUE INDEX IF NOT EXISTS "chunk_id_idx" ON "chunks" USING btree ("id");--> statement-breakpoint
-CREATE INDEX IF NOT EXISTS "chunk_document_id_idx" ON "chunks" USING btree ("document_id");--> statement-breakpoint
-CREATE INDEX IF NOT EXISTS "embeddingIndex" ON "chunks" USING diskann ("embeddings" vector_cosine_ops);--> statement-breakpoint
-CREATE UNIQUE INDEX IF NOT EXISTS "content_id_space_id_unique" ON "content_to_space" USING btree ("content_id","space_id");--> statement-breakpoint
-CREATE UNIQUE INDEX IF NOT EXISTS "document_id_idx" ON "documents" USING btree ("id");--> statement-breakpoint
-CREATE UNIQUE INDEX IF NOT EXISTS "document_uuid_idx" ON "documents" USING btree ("uuid");--> statement-breakpoint
-CREATE INDEX IF NOT EXISTS "document_type_idx" ON "documents" USING btree ("type");--> statement-breakpoint
-CREATE UNIQUE INDEX IF NOT EXISTS "document_url_user_id_idx" ON "documents" USING btree ("url","user_id");--> statement-breakpoint
-CREATE UNIQUE INDEX IF NOT EXISTS "user_id_url_idx" ON "job" USING btree ("user_id","url");--> statement-breakpoint
-CREATE UNIQUE INDEX IF NOT EXISTS "space_id_user_email_idx" ON "space_access" USING btree ("space_id","user_email");--> statement-breakpoint
-CREATE UNIQUE INDEX IF NOT EXISTS "space_members_space_user_idx" ON "space_members" USING btree ("spaceId","user_id");--> statement-breakpoint
-CREATE UNIQUE INDEX IF NOT EXISTS "spaces_id_idx" ON "spaces" USING btree ("id");--> statement-breakpoint
-CREATE INDEX IF NOT EXISTS "spaces_owner_id_idx" ON "spaces" USING btree ("ownerId");--> statement-breakpoint
-CREATE INDEX IF NOT EXISTS "spaces_name_idx" ON "spaces" USING btree ("name");--> statement-breakpoint
-CREATE UNIQUE INDEX IF NOT EXISTS "users_id_idx" ON "users" USING btree ("id");--> statement-breakpoint
-CREATE UNIQUE INDEX IF NOT EXISTS "users_uuid_idx" ON "users" USING btree ("uuid");--> statement-breakpoint
-CREATE UNIQUE INDEX IF NOT EXISTS "users_email_idx" ON "users" USING btree ("email");--> statement-breakpoint
-CREATE INDEX IF NOT EXISTS "users_name_idx" ON "users" USING btree ("first_name","last_name");--> statement-breakpoint
-CREATE INDEX IF NOT EXISTS "users_created_at_idx" ON "users" USING btree ("created_at");--> statement-breakpoint
-CREATE UNIQUE INDEX IF NOT EXISTS "users_telegram_id_idx" ON "users" USING btree ("telegram_id");
\ No newline at end of file
diff --git a/apps/backend/drizzle/0001_seed-types.sql b/apps/backend/drizzle/0001_seed-types.sql
deleted file mode 100644
index 3c409b92..00000000
--- a/apps/backend/drizzle/0001_seed-types.sql
+++ /dev/null
@@ -1,3 +0,0 @@
--- Custom SQL migration file, put you code below! --
-INSERT INTO "document_type" (type) VALUES ('tweet'), ('page'), ('note') ON CONFLICT DO NOTHING;
-INSERT INTO "document_type" (type) VALUES ('document') ON CONFLICT DO NOTHING;
\ No newline at end of file
diff --git a/apps/backend/drizzle/0002_skinny_princess_powerful.sql b/apps/backend/drizzle/0002_skinny_princess_powerful.sql
deleted file mode 100644
index c826811f..00000000
--- a/apps/backend/drizzle/0002_skinny_princess_powerful.sql
+++ /dev/null
@@ -1,2 +0,0 @@
--- Active: 1732249624784@@_@5432@supermemorymain
-ALTER TABLE "documents" ADD COLUMN "is_successfully_processed" boolean DEFAULT false;
\ No newline at end of file
diff --git a/apps/backend/drizzle/0003_luxuriant_annihilus.sql b/apps/backend/drizzle/0003_luxuriant_annihilus.sql
deleted file mode 100644
index fef1b6b1..00000000
--- a/apps/backend/drizzle/0003_luxuriant_annihilus.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-ALTER TABLE "documents" ALTER COLUMN "is_successfully_processed" DROP NOT NULL;--> statement-breakpoint
-ALTER TABLE "space_access" ADD COLUMN "access_type" text DEFAULT 'read' NOT NULL;--> statement-breakpoint
-CREATE UNIQUE INDEX IF NOT EXISTS "document_raw_user_idx" ON "documents" USING btree ("raw","user_id");--> statement-breakpoint
\ No newline at end of file
diff --git a/apps/backend/drizzle/0004_early_rick_jones.sql b/apps/backend/drizzle/0004_early_rick_jones.sql
deleted file mode 100644
index b26c0ffc..00000000
--- a/apps/backend/drizzle/0004_early_rick_jones.sql
+++ /dev/null
@@ -1,19 +0,0 @@
-CREATE TABLE IF NOT EXISTS "saved_spaces" (
- "user_id" integer NOT NULL,
- "space_id" integer NOT NULL,
- "saved_at" timestamp DEFAULT now() NOT NULL
-);
---> statement-breakpoint
-DO $$ BEGIN
- ALTER TABLE "saved_spaces" ADD CONSTRAINT "saved_spaces_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
-EXCEPTION
- WHEN duplicate_object THEN null;
-END $$;
---> statement-breakpoint
-DO $$ BEGIN
- ALTER TABLE "saved_spaces" ADD CONSTRAINT "saved_spaces_space_id_spaces_id_fk" FOREIGN KEY ("space_id") REFERENCES "public"."spaces"("id") ON DELETE cascade ON UPDATE no action;
-EXCEPTION
- WHEN duplicate_object THEN null;
-END $$;
---> statement-breakpoint
-CREATE UNIQUE INDEX IF NOT EXISTS "saved_spaces_user_space_idx" ON "saved_spaces" USING btree ("user_id","space_id");
\ No newline at end of file
diff --git a/apps/backend/drizzle/0005_create-access-types.sql b/apps/backend/drizzle/0005_create-access-types.sql
deleted file mode 100644
index 29095454..00000000
--- a/apps/backend/drizzle/0005_create-access-types.sql
+++ /dev/null
@@ -1,2 +0,0 @@
--- Custom SQL migration file, put you code below! --
-INSERT INTO "space_access_status" (status) VALUES ('pending'), ('accepted'), ('rejected') ON CONFLICT DO NOTHING;
\ No newline at end of file
diff --git a/apps/backend/drizzle/0006_wandering_grandmaster.sql b/apps/backend/drizzle/0006_wandering_grandmaster.sql
deleted file mode 100644
index 0a0066d8..00000000
--- a/apps/backend/drizzle/0006_wandering_grandmaster.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-CREATE TABLE IF NOT EXISTS "waitlist" (
- "email" varchar(512) PRIMARY KEY NOT NULL
-);
diff --git a/apps/backend/drizzle/0007_fantastic_serpent_society.sql b/apps/backend/drizzle/0007_fantastic_serpent_society.sql
deleted file mode 100644
index c25c55a3..00000000
--- a/apps/backend/drizzle/0007_fantastic_serpent_society.sql
+++ /dev/null
@@ -1 +0,0 @@
-DROP INDEX IF EXISTS "document_url_user_id_idx";
\ No newline at end of file
diff --git a/apps/backend/drizzle/0008_add-notion.sql b/apps/backend/drizzle/0008_add-notion.sql
deleted file mode 100644
index 17cd0206..00000000
--- a/apps/backend/drizzle/0008_add-notion.sql
+++ /dev/null
@@ -1,2 +0,0 @@
--- Custom SQL migration file, put you code below! --
-INSERT INTO "document_type" (type) VALUES ('notion') ON CONFLICT DO NOTHING;
\ No newline at end of file
diff --git a/apps/backend/drizzle/0009_milky_sleepwalker.sql b/apps/backend/drizzle/0009_milky_sleepwalker.sql
deleted file mode 100644
index d32443c1..00000000
--- a/apps/backend/drizzle/0009_milky_sleepwalker.sql
+++ /dev/null
@@ -1 +0,0 @@
-ALTER TABLE "waitlist" ADD COLUMN "created_at" timestamp with time zone DEFAULT now() NOT NULL;
\ No newline at end of file
diff --git a/apps/backend/drizzle/0010_heavy_preak.sql b/apps/backend/drizzle/0010_heavy_preak.sql
deleted file mode 100644
index 003d62ae..00000000
--- a/apps/backend/drizzle/0010_heavy_preak.sql
+++ /dev/null
@@ -1,7 +0,0 @@
-ALTER TABLE "documents" DROP CONSTRAINT "documents_user_id_users_id_fk";
---> statement-breakpoint
-DO $$ BEGIN
- ALTER TABLE "documents" ADD CONSTRAINT "documents_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
-EXCEPTION
- WHEN duplicate_object THEN null;
-END $$;
diff --git a/apps/backend/drizzle/0011_new_liz_osborn.sql b/apps/backend/drizzle/0011_new_liz_osborn.sql
deleted file mode 100644
index b5679196..00000000
--- a/apps/backend/drizzle/0011_new_liz_osborn.sql
+++ /dev/null
@@ -1 +0,0 @@
-ALTER TABLE "documents" ADD COLUMN "error_message" text;
\ No newline at end of file
diff --git a/apps/backend/drizzle/0012_small_mystique.sql b/apps/backend/drizzle/0012_small_mystique.sql
deleted file mode 100644
index e89fb98a..00000000
--- a/apps/backend/drizzle/0012_small_mystique.sql
+++ /dev/null
@@ -1,2 +0,0 @@
--- Active: 1732308352274@@127.0.0.1@5432@supermemorydhravya
-ALTER TABLE "users" ADD COLUMN "last_api_key_generated_at" timestamp DEFAULT now();
\ No newline at end of file
diff --git a/apps/backend/drizzle/0013_sharp_hemingway.sql b/apps/backend/drizzle/0013_sharp_hemingway.sql
deleted file mode 100644
index 1f295677..00000000
--- a/apps/backend/drizzle/0013_sharp_hemingway.sql
+++ /dev/null
@@ -1 +0,0 @@
-ALTER TABLE "documents" ADD COLUMN "content_hash" text;
\ No newline at end of file
diff --git a/apps/backend/drizzle/0014_mighty_the_captain.sql b/apps/backend/drizzle/0014_mighty_the_captain.sql
deleted file mode 100644
index 40e7b1b8..00000000
--- a/apps/backend/drizzle/0014_mighty_the_captain.sql
+++ /dev/null
@@ -1,2 +0,0 @@
-ALTER TABLE "users" ADD COLUMN "stripe_customer_id" text;--> statement-breakpoint
-ALTER TABLE "users" ADD COLUMN "tier" text DEFAULT 'free' NOT NULL;
\ No newline at end of file
diff --git a/apps/backend/drizzle/0015_perpetual_mauler.sql b/apps/backend/drizzle/0015_perpetual_mauler.sql
deleted file mode 100644
index ec419523..00000000
--- a/apps/backend/drizzle/0015_perpetual_mauler.sql
+++ /dev/null
@@ -1 +0,0 @@
-ALTER TABLE "chunks" ALTER COLUMN "embeddings" SET DATA TYPE vector(768);
\ No newline at end of file
diff --git a/apps/backend/drizzle/0016_good_deathbird.sql b/apps/backend/drizzle/0016_good_deathbird.sql
deleted file mode 100644
index 7c6505de..00000000
--- a/apps/backend/drizzle/0016_good_deathbird.sql
+++ /dev/null
@@ -1,7 +0,0 @@
-ALTER TABLE "chunks" ALTER COLUMN "embeddings" SET DATA TYPE vector(768);--> statement-breakpoint
-CREATE INDEX IF NOT EXISTS "documents_search_idx" ON "documents" USING gin ((
- setweight(to_tsvector('english', coalesce("content", '')),'A') ||
- setweight(to_tsvector('english', coalesce("title", '')),'B') ||
- setweight(to_tsvector('english', coalesce("description", '')),'C') ||
- setweight(to_tsvector('english', coalesce("url", '')),'D')
- ));
\ No newline at end of file
diff --git a/apps/backend/drizzle/0018_past_inertia.sql b/apps/backend/drizzle/0018_past_inertia.sql
deleted file mode 100644
index a7d2e321..00000000
--- a/apps/backend/drizzle/0018_past_inertia.sql
+++ /dev/null
@@ -1,7 +0,0 @@
-DROP INDEX IF EXISTS "documents_search_idx";--> statement-breakpoint
-CREATE INDEX IF NOT EXISTS "documents_search_idx" ON "documents" USING gin ((
- setweight(to_tsvector('english', coalesce("content", '')),'A') ||
- setweight(to_tsvector('english', coalesce("title", '')),'B') ||
- setweight(to_tsvector('english', coalesce("description", '')),'C') ||
- setweight(to_tsvector('english', coalesce("url", '')),'D')
- ));
\ No newline at end of file
diff --git a/apps/backend/drizzle/0019_vengeful_marten_broadcloak.sql b/apps/backend/drizzle/0019_vengeful_marten_broadcloak.sql
deleted file mode 100644
index 7bed7a59..00000000
--- a/apps/backend/drizzle/0019_vengeful_marten_broadcloak.sql
+++ /dev/null
@@ -1 +0,0 @@
-ALTER TABLE "documents" ADD COLUMN "metadata" jsonb;
\ No newline at end of file
diff --git a/apps/backend/drizzle/0020_opposite_steel_serpent.sql b/apps/backend/drizzle/0020_opposite_steel_serpent.sql
deleted file mode 100644
index 3b0e2042..00000000
--- a/apps/backend/drizzle/0020_opposite_steel_serpent.sql
+++ /dev/null
@@ -1,2 +0,0 @@
--- Active: 1732308352274@@127.0.0.1@5432@supermemorydhravya
-DROP TABLE "job";
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/0000_snapshot.json b/apps/backend/drizzle/meta/0000_snapshot.json
deleted file mode 100644
index 4d7bf98d..00000000
--- a/apps/backend/drizzle/meta/0000_snapshot.json
+++ /dev/null
@@ -1,1060 +0,0 @@
-{
- "id": "a40bb20a-1c12-4e15-a7fc-cf46e9d4507f",
- "prevId": "00000000-0000-0000-0000-000000000000",
- "version": "7",
- "dialect": "postgresql",
- "tables": {
- "public.chat_threads": {
- "name": "chat_threads",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "firstMessage": {
- "name": "firstMessage",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "messages": {
- "name": "messages",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chat_threads_user_idx": {
- "name": "chat_threads_user_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "chat_threads_user_id_users_id_fk": {
- "name": "chat_threads_user_id_users_id_fk",
- "tableFrom": "chat_threads",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "chat_threads_uuid_unique": {
- "name": "chat_threads_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.chunks": {
- "name": "chunks",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "document_id": {
- "name": "document_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "text_content": {
- "name": "text_content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "order_in_document": {
- "name": "order_in_document",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "embeddings": {
- "name": "embeddings",
- "type": "vector(1536)",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chunk_id_idx": {
- "name": "chunk_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "chunk_document_id_idx": {
- "name": "chunk_document_id_idx",
- "columns": [
- {
- "expression": "document_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "embeddingIndex": {
- "name": "embeddingIndex",
- "columns": [
- {
- "expression": "embeddings",
- "isExpression": false,
- "asc": true,
- "nulls": "last",
- "opclass": "vector_cosine_ops"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "diskann",
- "with": {}
- }
- },
- "foreignKeys": {
- "chunks_document_id_documents_id_fk": {
- "name": "chunks_document_id_documents_id_fk",
- "tableFrom": "chunks",
- "tableTo": "documents",
- "columnsFrom": [
- "document_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.content_to_space": {
- "name": "content_to_space",
- "schema": "",
- "columns": {
- "content_id": {
- "name": "content_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "content_id_space_id_unique": {
- "name": "content_id_space_id_unique",
- "columns": [
- {
- "expression": "content_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "content_to_space_content_id_documents_id_fk": {
- "name": "content_to_space_content_id_documents_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "documents",
- "columnsFrom": [
- "content_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "content_to_space_space_id_spaces_id_fk": {
- "name": "content_to_space_space_id_spaces_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.document_type": {
- "name": "document_type",
- "schema": "",
- "columns": {
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.documents": {
- "name": "documents",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "title": {
- "name": "title",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "description": {
- "name": "description",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "og_image": {
- "name": "og_image",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "raw": {
- "name": "raw",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "content": {
- "name": "content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "document_id_idx": {
- "name": "document_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_uuid_idx": {
- "name": "document_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_type_idx": {
- "name": "document_type_idx",
- "columns": [
- {
- "expression": "type",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_url_user_id_idx": {
- "name": "document_url_user_id_idx",
- "columns": [
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "documents_type_document_type_type_fk": {
- "name": "documents_type_document_type_type_fk",
- "tableFrom": "documents",
- "tableTo": "document_type",
- "columnsFrom": [
- "type"
- ],
- "columnsTo": [
- "type"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- },
- "documents_user_id_users_id_fk": {
- "name": "documents_user_id_users_id_fk",
- "tableFrom": "documents",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "documents_uuid_unique": {
- "name": "documents_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.job": {
- "name": "job",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "attempts": {
- "name": "attempts",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "lastAttemptAt": {
- "name": "lastAttemptAt",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "error": {
- "name": "error",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "user_id_url_idx": {
- "name": "user_id_url_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "job_user_id_users_id_fk": {
- "name": "job_user_id_users_id_fk",
- "tableFrom": "job",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access": {
- "name": "space_access",
- "schema": "",
- "columns": {
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
- },
- "user_email": {
- "name": "user_email",
- "type": "varchar(512)",
- "primaryKey": false,
- "notNull": false
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "space_id_user_email_idx": {
- "name": "space_id_user_email_idx",
- "columns": [
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_access_space_id_spaces_id_fk": {
- "name": "space_access_space_id_spaces_id_fk",
- "tableFrom": "space_access",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "space_access_status_space_access_status_status_fk": {
- "name": "space_access_status_space_access_status_status_fk",
- "tableFrom": "space_access",
- "tableTo": "space_access_status",
- "columnsFrom": [
- "status"
- ],
- "columnsTo": [
- "status"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access_status": {
- "name": "space_access_status",
- "schema": "",
- "columns": {
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_members": {
- "name": "space_members",
- "schema": "",
- "columns": {
- "spaceId": {
- "name": "spaceId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "space_members_space_user_idx": {
- "name": "space_members_space_user_idx",
- "columns": [
- {
- "expression": "spaceId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_members_spaceId_users_id_fk": {
- "name": "space_members_spaceId_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "spaceId"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- },
- "space_members_user_id_users_id_fk": {
- "name": "space_members_user_id_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.spaces": {
- "name": "spaces",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "name": {
- "name": "name",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "ownerId": {
- "name": "ownerId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "is_public": {
- "name": "is_public",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "spaces_id_idx": {
- "name": "spaces_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_owner_id_idx": {
- "name": "spaces_owner_id_idx",
- "columns": [
- {
- "expression": "ownerId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_name_idx": {
- "name": "spaces_name_idx",
- "columns": [
- {
- "expression": "name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "spaces_uuid_unique": {
- "name": "spaces_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.users": {
- "name": "users",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "email": {
- "name": "email",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "first_name": {
- "name": "first_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "last_name": {
- "name": "last_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- },
- "profile_picture_url": {
- "name": "profile_picture_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "telegram_id": {
- "name": "telegram_id",
- "type": "varchar(255)",
- "primaryKey": false,
- "notNull": false
- },
- "has_onboarded": {
- "name": "has_onboarded",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "users_id_idx": {
- "name": "users_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_uuid_idx": {
- "name": "users_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_email_idx": {
- "name": "users_email_idx",
- "columns": [
- {
- "expression": "email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_name_idx": {
- "name": "users_name_idx",
- "columns": [
- {
- "expression": "first_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "last_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_created_at_idx": {
- "name": "users_created_at_idx",
- "columns": [
- {
- "expression": "created_at",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_telegram_id_idx": {
- "name": "users_telegram_id_idx",
- "columns": [
- {
- "expression": "telegram_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "users_uuid_unique": {
- "name": "users_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- },
- "users_email_unique": {
- "name": "users_email_unique",
- "nullsNotDistinct": false,
- "columns": [
- "email"
- ]
- }
- }
- }
- },
- "enums": {},
- "schemas": {},
- "sequences": {},
- "_meta": {
- "columns": {},
- "schemas": {},
- "tables": {}
- }
-}
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/0001_snapshot.json b/apps/backend/drizzle/meta/0001_snapshot.json
deleted file mode 100644
index 3c02b35d..00000000
--- a/apps/backend/drizzle/meta/0001_snapshot.json
+++ /dev/null
@@ -1,1060 +0,0 @@
-{
- "id": "67f177d5-9303-4ae0-ad66-e04d0624dab1",
- "prevId": "a40bb20a-1c12-4e15-a7fc-cf46e9d4507f",
- "version": "7",
- "dialect": "postgresql",
- "tables": {
- "public.chat_threads": {
- "name": "chat_threads",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "firstMessage": {
- "name": "firstMessage",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "messages": {
- "name": "messages",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chat_threads_user_idx": {
- "name": "chat_threads_user_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "chat_threads_user_id_users_id_fk": {
- "name": "chat_threads_user_id_users_id_fk",
- "tableFrom": "chat_threads",
- "columnsFrom": [
- "user_id"
- ],
- "tableTo": "users",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "chat_threads_uuid_unique": {
- "name": "chat_threads_uuid_unique",
- "columns": [
- "uuid"
- ],
- "nullsNotDistinct": false
- }
- }
- },
- "public.chunks": {
- "name": "chunks",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "document_id": {
- "name": "document_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "text_content": {
- "name": "text_content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "order_in_document": {
- "name": "order_in_document",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "embeddings": {
- "name": "embeddings",
- "type": "vector(1536)",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chunk_id_idx": {
- "name": "chunk_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "chunk_document_id_idx": {
- "name": "chunk_document_id_idx",
- "columns": [
- {
- "expression": "document_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "embeddingIndex": {
- "name": "embeddingIndex",
- "columns": [
- {
- "expression": "embeddings",
- "isExpression": false,
- "asc": true,
- "nulls": "last",
- "opclass": "vector_cosine_ops"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "diskann",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "chunks_document_id_documents_id_fk": {
- "name": "chunks_document_id_documents_id_fk",
- "tableFrom": "chunks",
- "columnsFrom": [
- "document_id"
- ],
- "tableTo": "documents",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.content_to_space": {
- "name": "content_to_space",
- "schema": "",
- "columns": {
- "content_id": {
- "name": "content_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "content_id_space_id_unique": {
- "name": "content_id_space_id_unique",
- "columns": [
- {
- "expression": "content_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "content_to_space_content_id_documents_id_fk": {
- "name": "content_to_space_content_id_documents_id_fk",
- "tableFrom": "content_to_space",
- "columnsFrom": [
- "content_id"
- ],
- "tableTo": "documents",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- },
- "content_to_space_space_id_spaces_id_fk": {
- "name": "content_to_space_space_id_spaces_id_fk",
- "tableFrom": "content_to_space",
- "columnsFrom": [
- "space_id"
- ],
- "tableTo": "spaces",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.document_type": {
- "name": "document_type",
- "schema": "",
- "columns": {
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.documents": {
- "name": "documents",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "title": {
- "name": "title",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "description": {
- "name": "description",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "og_image": {
- "name": "og_image",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "raw": {
- "name": "raw",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "content": {
- "name": "content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "document_id_idx": {
- "name": "document_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "document_uuid_idx": {
- "name": "document_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "document_type_idx": {
- "name": "document_type_idx",
- "columns": [
- {
- "expression": "type",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "document_url_user_id_idx": {
- "name": "document_url_user_id_idx",
- "columns": [
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "documents_type_document_type_type_fk": {
- "name": "documents_type_document_type_type_fk",
- "tableFrom": "documents",
- "columnsFrom": [
- "type"
- ],
- "tableTo": "document_type",
- "columnsTo": [
- "type"
- ],
- "onUpdate": "no action",
- "onDelete": "no action"
- },
- "documents_user_id_users_id_fk": {
- "name": "documents_user_id_users_id_fk",
- "tableFrom": "documents",
- "columnsFrom": [
- "user_id"
- ],
- "tableTo": "users",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "restrict"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "documents_uuid_unique": {
- "name": "documents_uuid_unique",
- "columns": [
- "uuid"
- ],
- "nullsNotDistinct": false
- }
- }
- },
- "public.job": {
- "name": "job",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "attempts": {
- "name": "attempts",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "lastAttemptAt": {
- "name": "lastAttemptAt",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "error": {
- "name": "error",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "user_id_url_idx": {
- "name": "user_id_url_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "job_user_id_users_id_fk": {
- "name": "job_user_id_users_id_fk",
- "tableFrom": "job",
- "columnsFrom": [
- "user_id"
- ],
- "tableTo": "users",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access": {
- "name": "space_access",
- "schema": "",
- "columns": {
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
- },
- "user_email": {
- "name": "user_email",
- "type": "varchar(512)",
- "primaryKey": false,
- "notNull": false
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "space_id_user_email_idx": {
- "name": "space_id_user_email_idx",
- "columns": [
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "space_access_space_id_spaces_id_fk": {
- "name": "space_access_space_id_spaces_id_fk",
- "tableFrom": "space_access",
- "columnsFrom": [
- "space_id"
- ],
- "tableTo": "spaces",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- },
- "space_access_status_space_access_status_status_fk": {
- "name": "space_access_status_space_access_status_status_fk",
- "tableFrom": "space_access",
- "columnsFrom": [
- "status"
- ],
- "tableTo": "space_access_status",
- "columnsTo": [
- "status"
- ],
- "onUpdate": "no action",
- "onDelete": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access_status": {
- "name": "space_access_status",
- "schema": "",
- "columns": {
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_members": {
- "name": "space_members",
- "schema": "",
- "columns": {
- "spaceId": {
- "name": "spaceId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "space_members_space_user_idx": {
- "name": "space_members_space_user_idx",
- "columns": [
- {
- "expression": "spaceId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "space_members_spaceId_users_id_fk": {
- "name": "space_members_spaceId_users_id_fk",
- "tableFrom": "space_members",
- "columnsFrom": [
- "spaceId"
- ],
- "tableTo": "users",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "restrict"
- },
- "space_members_user_id_users_id_fk": {
- "name": "space_members_user_id_users_id_fk",
- "tableFrom": "space_members",
- "columnsFrom": [
- "user_id"
- ],
- "tableTo": "users",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "restrict"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.spaces": {
- "name": "spaces",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "name": {
- "name": "name",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "ownerId": {
- "name": "ownerId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "is_public": {
- "name": "is_public",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "spaces_id_idx": {
- "name": "spaces_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "spaces_owner_id_idx": {
- "name": "spaces_owner_id_idx",
- "columns": [
- {
- "expression": "ownerId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "spaces_name_idx": {
- "name": "spaces_name_idx",
- "columns": [
- {
- "expression": "name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "spaces_uuid_unique": {
- "name": "spaces_uuid_unique",
- "columns": [
- "uuid"
- ],
- "nullsNotDistinct": false
- }
- }
- },
- "public.users": {
- "name": "users",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "email": {
- "name": "email",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "first_name": {
- "name": "first_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "last_name": {
- "name": "last_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- },
- "profile_picture_url": {
- "name": "profile_picture_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "telegram_id": {
- "name": "telegram_id",
- "type": "varchar(255)",
- "primaryKey": false,
- "notNull": false
- },
- "has_onboarded": {
- "name": "has_onboarded",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "users_id_idx": {
- "name": "users_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "users_uuid_idx": {
- "name": "users_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "users_email_idx": {
- "name": "users_email_idx",
- "columns": [
- {
- "expression": "email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "users_name_idx": {
- "name": "users_name_idx",
- "columns": [
- {
- "expression": "first_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "last_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "users_created_at_idx": {
- "name": "users_created_at_idx",
- "columns": [
- {
- "expression": "created_at",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "users_telegram_id_idx": {
- "name": "users_telegram_id_idx",
- "columns": [
- {
- "expression": "telegram_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "users_uuid_unique": {
- "name": "users_uuid_unique",
- "columns": [
- "uuid"
- ],
- "nullsNotDistinct": false
- },
- "users_email_unique": {
- "name": "users_email_unique",
- "columns": [
- "email"
- ],
- "nullsNotDistinct": false
- }
- }
- }
- },
- "enums": {},
- "schemas": {},
- "sequences": {},
- "_meta": {
- "columns": {},
- "schemas": {},
- "tables": {}
- }
-}
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/0002_snapshot.json b/apps/backend/drizzle/meta/0002_snapshot.json
deleted file mode 100644
index c36c66eb..00000000
--- a/apps/backend/drizzle/meta/0002_snapshot.json
+++ /dev/null
@@ -1,1067 +0,0 @@
-{
- "id": "be517863-31ba-4bf3-9a57-208d29723161",
- "prevId": "67f177d5-9303-4ae0-ad66-e04d0624dab1",
- "version": "7",
- "dialect": "postgresql",
- "tables": {
- "public.chat_threads": {
- "name": "chat_threads",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "firstMessage": {
- "name": "firstMessage",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "messages": {
- "name": "messages",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chat_threads_user_idx": {
- "name": "chat_threads_user_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "chat_threads_user_id_users_id_fk": {
- "name": "chat_threads_user_id_users_id_fk",
- "tableFrom": "chat_threads",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "chat_threads_uuid_unique": {
- "name": "chat_threads_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.chunks": {
- "name": "chunks",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "document_id": {
- "name": "document_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "text_content": {
- "name": "text_content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "order_in_document": {
- "name": "order_in_document",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "embeddings": {
- "name": "embeddings",
- "type": "vector(1536)",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chunk_id_idx": {
- "name": "chunk_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "chunk_document_id_idx": {
- "name": "chunk_document_id_idx",
- "columns": [
- {
- "expression": "document_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "embeddingIndex": {
- "name": "embeddingIndex",
- "columns": [
- {
- "expression": "embeddings",
- "isExpression": false,
- "asc": true,
- "nulls": "last",
- "opclass": "vector_cosine_ops"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "diskann",
- "with": {}
- }
- },
- "foreignKeys": {
- "chunks_document_id_documents_id_fk": {
- "name": "chunks_document_id_documents_id_fk",
- "tableFrom": "chunks",
- "tableTo": "documents",
- "columnsFrom": [
- "document_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.content_to_space": {
- "name": "content_to_space",
- "schema": "",
- "columns": {
- "content_id": {
- "name": "content_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "content_id_space_id_unique": {
- "name": "content_id_space_id_unique",
- "columns": [
- {
- "expression": "content_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "content_to_space_content_id_documents_id_fk": {
- "name": "content_to_space_content_id_documents_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "documents",
- "columnsFrom": [
- "content_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "content_to_space_space_id_spaces_id_fk": {
- "name": "content_to_space_space_id_spaces_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.document_type": {
- "name": "document_type",
- "schema": "",
- "columns": {
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.documents": {
- "name": "documents",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "title": {
- "name": "title",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "description": {
- "name": "description",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "og_image": {
- "name": "og_image",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "raw": {
- "name": "raw",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "content": {
- "name": "content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "is_successfully_processed": {
- "name": "is_successfully_processed",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "document_id_idx": {
- "name": "document_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_uuid_idx": {
- "name": "document_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_type_idx": {
- "name": "document_type_idx",
- "columns": [
- {
- "expression": "type",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_url_user_id_idx": {
- "name": "document_url_user_id_idx",
- "columns": [
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "documents_type_document_type_type_fk": {
- "name": "documents_type_document_type_type_fk",
- "tableFrom": "documents",
- "tableTo": "document_type",
- "columnsFrom": [
- "type"
- ],
- "columnsTo": [
- "type"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- },
- "documents_user_id_users_id_fk": {
- "name": "documents_user_id_users_id_fk",
- "tableFrom": "documents",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "documents_uuid_unique": {
- "name": "documents_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.job": {
- "name": "job",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "attempts": {
- "name": "attempts",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "lastAttemptAt": {
- "name": "lastAttemptAt",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "error": {
- "name": "error",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "user_id_url_idx": {
- "name": "user_id_url_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "job_user_id_users_id_fk": {
- "name": "job_user_id_users_id_fk",
- "tableFrom": "job",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access": {
- "name": "space_access",
- "schema": "",
- "columns": {
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
- },
- "user_email": {
- "name": "user_email",
- "type": "varchar(512)",
- "primaryKey": false,
- "notNull": false
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "space_id_user_email_idx": {
- "name": "space_id_user_email_idx",
- "columns": [
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_access_space_id_spaces_id_fk": {
- "name": "space_access_space_id_spaces_id_fk",
- "tableFrom": "space_access",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "space_access_status_space_access_status_status_fk": {
- "name": "space_access_status_space_access_status_status_fk",
- "tableFrom": "space_access",
- "tableTo": "space_access_status",
- "columnsFrom": [
- "status"
- ],
- "columnsTo": [
- "status"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access_status": {
- "name": "space_access_status",
- "schema": "",
- "columns": {
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_members": {
- "name": "space_members",
- "schema": "",
- "columns": {
- "spaceId": {
- "name": "spaceId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "space_members_space_user_idx": {
- "name": "space_members_space_user_idx",
- "columns": [
- {
- "expression": "spaceId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_members_spaceId_users_id_fk": {
- "name": "space_members_spaceId_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "spaceId"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- },
- "space_members_user_id_users_id_fk": {
- "name": "space_members_user_id_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.spaces": {
- "name": "spaces",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "name": {
- "name": "name",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "ownerId": {
- "name": "ownerId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "is_public": {
- "name": "is_public",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "spaces_id_idx": {
- "name": "spaces_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_owner_id_idx": {
- "name": "spaces_owner_id_idx",
- "columns": [
- {
- "expression": "ownerId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_name_idx": {
- "name": "spaces_name_idx",
- "columns": [
- {
- "expression": "name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "spaces_uuid_unique": {
- "name": "spaces_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.users": {
- "name": "users",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "email": {
- "name": "email",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "first_name": {
- "name": "first_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "last_name": {
- "name": "last_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- },
- "profile_picture_url": {
- "name": "profile_picture_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "telegram_id": {
- "name": "telegram_id",
- "type": "varchar(255)",
- "primaryKey": false,
- "notNull": false
- },
- "has_onboarded": {
- "name": "has_onboarded",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "users_id_idx": {
- "name": "users_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_uuid_idx": {
- "name": "users_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_email_idx": {
- "name": "users_email_idx",
- "columns": [
- {
- "expression": "email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_name_idx": {
- "name": "users_name_idx",
- "columns": [
- {
- "expression": "first_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "last_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_created_at_idx": {
- "name": "users_created_at_idx",
- "columns": [
- {
- "expression": "created_at",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_telegram_id_idx": {
- "name": "users_telegram_id_idx",
- "columns": [
- {
- "expression": "telegram_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "users_uuid_unique": {
- "name": "users_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- },
- "users_email_unique": {
- "name": "users_email_unique",
- "nullsNotDistinct": false,
- "columns": [
- "email"
- ]
- }
- }
- }
- },
- "enums": {},
- "schemas": {},
- "sequences": {},
- "_meta": {
- "columns": {},
- "schemas": {},
- "tables": {}
- }
-}
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/0003_snapshot.json b/apps/backend/drizzle/meta/0003_snapshot.json
deleted file mode 100644
index a1730bb5..00000000
--- a/apps/backend/drizzle/meta/0003_snapshot.json
+++ /dev/null
@@ -1,1095 +0,0 @@
-{
- "id": "bce9d9c5-68a2-417c-a9f8-454734bf47fa",
- "prevId": "be517863-31ba-4bf3-9a57-208d29723161",
- "version": "7",
- "dialect": "postgresql",
- "tables": {
- "public.chat_threads": {
- "name": "chat_threads",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "firstMessage": {
- "name": "firstMessage",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "messages": {
- "name": "messages",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chat_threads_user_idx": {
- "name": "chat_threads_user_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "chat_threads_user_id_users_id_fk": {
- "name": "chat_threads_user_id_users_id_fk",
- "tableFrom": "chat_threads",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "chat_threads_uuid_unique": {
- "name": "chat_threads_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.chunks": {
- "name": "chunks",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "document_id": {
- "name": "document_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "text_content": {
- "name": "text_content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "order_in_document": {
- "name": "order_in_document",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "embeddings": {
- "name": "embeddings",
- "type": "vector(1536)",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chunk_id_idx": {
- "name": "chunk_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "chunk_document_id_idx": {
- "name": "chunk_document_id_idx",
- "columns": [
- {
- "expression": "document_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "embeddingIndex": {
- "name": "embeddingIndex",
- "columns": [
- {
- "expression": "embeddings",
- "isExpression": false,
- "asc": true,
- "nulls": "last",
- "opclass": "vector_cosine_ops"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "hnsw",
- "with": {}
- }
- },
- "foreignKeys": {
- "chunks_document_id_documents_id_fk": {
- "name": "chunks_document_id_documents_id_fk",
- "tableFrom": "chunks",
- "tableTo": "documents",
- "columnsFrom": [
- "document_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.content_to_space": {
- "name": "content_to_space",
- "schema": "",
- "columns": {
- "content_id": {
- "name": "content_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "content_id_space_id_unique": {
- "name": "content_id_space_id_unique",
- "columns": [
- {
- "expression": "content_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "content_to_space_content_id_documents_id_fk": {
- "name": "content_to_space_content_id_documents_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "documents",
- "columnsFrom": [
- "content_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "content_to_space_space_id_spaces_id_fk": {
- "name": "content_to_space_space_id_spaces_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.document_type": {
- "name": "document_type",
- "schema": "",
- "columns": {
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.documents": {
- "name": "documents",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "title": {
- "name": "title",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "description": {
- "name": "description",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "og_image": {
- "name": "og_image",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "raw": {
- "name": "raw",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "content": {
- "name": "content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "is_successfully_processed": {
- "name": "is_successfully_processed",
- "type": "boolean",
- "primaryKey": false,
- "notNull": false,
- "default": false
- }
- },
- "indexes": {
- "document_id_idx": {
- "name": "document_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_uuid_idx": {
- "name": "document_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_type_idx": {
- "name": "document_type_idx",
- "columns": [
- {
- "expression": "type",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_url_user_id_idx": {
- "name": "document_url_user_id_idx",
- "columns": [
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_raw_user_idx": {
- "name": "document_raw_user_idx",
- "columns": [
- {
- "expression": "raw",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "documents_type_document_type_type_fk": {
- "name": "documents_type_document_type_type_fk",
- "tableFrom": "documents",
- "tableTo": "document_type",
- "columnsFrom": [
- "type"
- ],
- "columnsTo": [
- "type"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- },
- "documents_user_id_users_id_fk": {
- "name": "documents_user_id_users_id_fk",
- "tableFrom": "documents",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "documents_uuid_unique": {
- "name": "documents_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.job": {
- "name": "job",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "attempts": {
- "name": "attempts",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "lastAttemptAt": {
- "name": "lastAttemptAt",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "error": {
- "name": "error",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "user_id_url_idx": {
- "name": "user_id_url_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "job_user_id_users_id_fk": {
- "name": "job_user_id_users_id_fk",
- "tableFrom": "job",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access": {
- "name": "space_access",
- "schema": "",
- "columns": {
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
- },
- "user_email": {
- "name": "user_email",
- "type": "varchar(512)",
- "primaryKey": false,
- "notNull": false
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "access_type": {
- "name": "access_type",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'read'"
- }
- },
- "indexes": {
- "space_id_user_email_idx": {
- "name": "space_id_user_email_idx",
- "columns": [
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_access_space_id_spaces_id_fk": {
- "name": "space_access_space_id_spaces_id_fk",
- "tableFrom": "space_access",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "space_access_status_space_access_status_status_fk": {
- "name": "space_access_status_space_access_status_status_fk",
- "tableFrom": "space_access",
- "tableTo": "space_access_status",
- "columnsFrom": [
- "status"
- ],
- "columnsTo": [
- "status"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access_status": {
- "name": "space_access_status",
- "schema": "",
- "columns": {
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_members": {
- "name": "space_members",
- "schema": "",
- "columns": {
- "spaceId": {
- "name": "spaceId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "space_members_space_user_idx": {
- "name": "space_members_space_user_idx",
- "columns": [
- {
- "expression": "spaceId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_members_spaceId_users_id_fk": {
- "name": "space_members_spaceId_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "spaceId"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- },
- "space_members_user_id_users_id_fk": {
- "name": "space_members_user_id_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.spaces": {
- "name": "spaces",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "name": {
- "name": "name",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "ownerId": {
- "name": "ownerId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "is_public": {
- "name": "is_public",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "spaces_id_idx": {
- "name": "spaces_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_owner_id_idx": {
- "name": "spaces_owner_id_idx",
- "columns": [
- {
- "expression": "ownerId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_name_idx": {
- "name": "spaces_name_idx",
- "columns": [
- {
- "expression": "name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "spaces_uuid_unique": {
- "name": "spaces_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.users": {
- "name": "users",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "email": {
- "name": "email",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "first_name": {
- "name": "first_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "last_name": {
- "name": "last_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- },
- "profile_picture_url": {
- "name": "profile_picture_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "telegram_id": {
- "name": "telegram_id",
- "type": "varchar(255)",
- "primaryKey": false,
- "notNull": false
- },
- "has_onboarded": {
- "name": "has_onboarded",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "users_id_idx": {
- "name": "users_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_uuid_idx": {
- "name": "users_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_email_idx": {
- "name": "users_email_idx",
- "columns": [
- {
- "expression": "email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_name_idx": {
- "name": "users_name_idx",
- "columns": [
- {
- "expression": "first_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "last_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_created_at_idx": {
- "name": "users_created_at_idx",
- "columns": [
- {
- "expression": "created_at",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_telegram_id_idx": {
- "name": "users_telegram_id_idx",
- "columns": [
- {
- "expression": "telegram_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "users_uuid_unique": {
- "name": "users_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- },
- "users_email_unique": {
- "name": "users_email_unique",
- "nullsNotDistinct": false,
- "columns": [
- "email"
- ]
- }
- }
- }
- },
- "enums": {},
- "schemas": {},
- "sequences": {},
- "_meta": {
- "columns": {},
- "schemas": {},
- "tables": {}
- }
-}
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/0004_snapshot.json b/apps/backend/drizzle/meta/0004_snapshot.json
deleted file mode 100644
index acc4663d..00000000
--- a/apps/backend/drizzle/meta/0004_snapshot.json
+++ /dev/null
@@ -1,1173 +0,0 @@
-{
- "id": "6f9ba02f-28e8-4a11-8606-847dbc2ad43f",
- "prevId": "bce9d9c5-68a2-417c-a9f8-454734bf47fa",
- "version": "7",
- "dialect": "postgresql",
- "tables": {
- "public.chat_threads": {
- "name": "chat_threads",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "firstMessage": {
- "name": "firstMessage",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "messages": {
- "name": "messages",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chat_threads_user_idx": {
- "name": "chat_threads_user_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "chat_threads_user_id_users_id_fk": {
- "name": "chat_threads_user_id_users_id_fk",
- "tableFrom": "chat_threads",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "chat_threads_uuid_unique": {
- "name": "chat_threads_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.chunks": {
- "name": "chunks",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "document_id": {
- "name": "document_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "text_content": {
- "name": "text_content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "order_in_document": {
- "name": "order_in_document",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "embeddings": {
- "name": "embeddings",
- "type": "vector(1536)",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chunk_id_idx": {
- "name": "chunk_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "chunk_document_id_idx": {
- "name": "chunk_document_id_idx",
- "columns": [
- {
- "expression": "document_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "embeddingIndex": {
- "name": "embeddingIndex",
- "columns": [
- {
- "expression": "embeddings",
- "isExpression": false,
- "asc": true,
- "nulls": "last",
- "opclass": "vector_cosine_ops"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "hnsw",
- "with": {}
- }
- },
- "foreignKeys": {
- "chunks_document_id_documents_id_fk": {
- "name": "chunks_document_id_documents_id_fk",
- "tableFrom": "chunks",
- "tableTo": "documents",
- "columnsFrom": [
- "document_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.content_to_space": {
- "name": "content_to_space",
- "schema": "",
- "columns": {
- "content_id": {
- "name": "content_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "content_id_space_id_unique": {
- "name": "content_id_space_id_unique",
- "columns": [
- {
- "expression": "content_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "content_to_space_content_id_documents_id_fk": {
- "name": "content_to_space_content_id_documents_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "documents",
- "columnsFrom": [
- "content_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "content_to_space_space_id_spaces_id_fk": {
- "name": "content_to_space_space_id_spaces_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.document_type": {
- "name": "document_type",
- "schema": "",
- "columns": {
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.documents": {
- "name": "documents",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "title": {
- "name": "title",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "description": {
- "name": "description",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "og_image": {
- "name": "og_image",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "raw": {
- "name": "raw",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "content": {
- "name": "content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "is_successfully_processed": {
- "name": "is_successfully_processed",
- "type": "boolean",
- "primaryKey": false,
- "notNull": false,
- "default": false
- }
- },
- "indexes": {
- "document_id_idx": {
- "name": "document_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_uuid_idx": {
- "name": "document_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_type_idx": {
- "name": "document_type_idx",
- "columns": [
- {
- "expression": "type",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_url_user_id_idx": {
- "name": "document_url_user_id_idx",
- "columns": [
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_raw_user_idx": {
- "name": "document_raw_user_idx",
- "columns": [
- {
- "expression": "raw",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "documents_type_document_type_type_fk": {
- "name": "documents_type_document_type_type_fk",
- "tableFrom": "documents",
- "tableTo": "document_type",
- "columnsFrom": [
- "type"
- ],
- "columnsTo": [
- "type"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- },
- "documents_user_id_users_id_fk": {
- "name": "documents_user_id_users_id_fk",
- "tableFrom": "documents",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "documents_uuid_unique": {
- "name": "documents_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.job": {
- "name": "job",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "attempts": {
- "name": "attempts",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "lastAttemptAt": {
- "name": "lastAttemptAt",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "error": {
- "name": "error",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "user_id_url_idx": {
- "name": "user_id_url_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "job_user_id_users_id_fk": {
- "name": "job_user_id_users_id_fk",
- "tableFrom": "job",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.saved_spaces": {
- "name": "saved_spaces",
- "schema": "",
- "columns": {
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "saved_at": {
- "name": "saved_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "saved_spaces_user_space_idx": {
- "name": "saved_spaces_user_space_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "saved_spaces_user_id_users_id_fk": {
- "name": "saved_spaces_user_id_users_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "saved_spaces_space_id_spaces_id_fk": {
- "name": "saved_spaces_space_id_spaces_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access": {
- "name": "space_access",
- "schema": "",
- "columns": {
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
- },
- "user_email": {
- "name": "user_email",
- "type": "varchar(512)",
- "primaryKey": false,
- "notNull": false
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "access_type": {
- "name": "access_type",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'read'"
- }
- },
- "indexes": {
- "space_id_user_email_idx": {
- "name": "space_id_user_email_idx",
- "columns": [
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_access_space_id_spaces_id_fk": {
- "name": "space_access_space_id_spaces_id_fk",
- "tableFrom": "space_access",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "space_access_status_space_access_status_status_fk": {
- "name": "space_access_status_space_access_status_status_fk",
- "tableFrom": "space_access",
- "tableTo": "space_access_status",
- "columnsFrom": [
- "status"
- ],
- "columnsTo": [
- "status"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access_status": {
- "name": "space_access_status",
- "schema": "",
- "columns": {
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_members": {
- "name": "space_members",
- "schema": "",
- "columns": {
- "spaceId": {
- "name": "spaceId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "space_members_space_user_idx": {
- "name": "space_members_space_user_idx",
- "columns": [
- {
- "expression": "spaceId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_members_spaceId_users_id_fk": {
- "name": "space_members_spaceId_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "spaceId"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- },
- "space_members_user_id_users_id_fk": {
- "name": "space_members_user_id_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.spaces": {
- "name": "spaces",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "name": {
- "name": "name",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "ownerId": {
- "name": "ownerId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "is_public": {
- "name": "is_public",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "spaces_id_idx": {
- "name": "spaces_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_owner_id_idx": {
- "name": "spaces_owner_id_idx",
- "columns": [
- {
- "expression": "ownerId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_name_idx": {
- "name": "spaces_name_idx",
- "columns": [
- {
- "expression": "name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "spaces_uuid_unique": {
- "name": "spaces_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.users": {
- "name": "users",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "email": {
- "name": "email",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "first_name": {
- "name": "first_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "last_name": {
- "name": "last_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- },
- "profile_picture_url": {
- "name": "profile_picture_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "telegram_id": {
- "name": "telegram_id",
- "type": "varchar(255)",
- "primaryKey": false,
- "notNull": false
- },
- "has_onboarded": {
- "name": "has_onboarded",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "users_id_idx": {
- "name": "users_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_uuid_idx": {
- "name": "users_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_email_idx": {
- "name": "users_email_idx",
- "columns": [
- {
- "expression": "email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_name_idx": {
- "name": "users_name_idx",
- "columns": [
- {
- "expression": "first_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "last_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_created_at_idx": {
- "name": "users_created_at_idx",
- "columns": [
- {
- "expression": "created_at",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_telegram_id_idx": {
- "name": "users_telegram_id_idx",
- "columns": [
- {
- "expression": "telegram_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "users_uuid_unique": {
- "name": "users_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- },
- "users_email_unique": {
- "name": "users_email_unique",
- "nullsNotDistinct": false,
- "columns": [
- "email"
- ]
- }
- }
- }
- },
- "enums": {},
- "schemas": {},
- "sequences": {},
- "_meta": {
- "columns": {},
- "schemas": {},
- "tables": {}
- }
-}
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/0005_snapshot.json b/apps/backend/drizzle/meta/0005_snapshot.json
deleted file mode 100644
index 72fa7e54..00000000
--- a/apps/backend/drizzle/meta/0005_snapshot.json
+++ /dev/null
@@ -1,1173 +0,0 @@
-{
- "id": "5410ff1a-d1d0-4f47-b84e-a3507bd3f148",
- "prevId": "6f9ba02f-28e8-4a11-8606-847dbc2ad43f",
- "version": "7",
- "dialect": "postgresql",
- "tables": {
- "public.chat_threads": {
- "name": "chat_threads",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "firstMessage": {
- "name": "firstMessage",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "messages": {
- "name": "messages",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chat_threads_user_idx": {
- "name": "chat_threads_user_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "chat_threads_user_id_users_id_fk": {
- "name": "chat_threads_user_id_users_id_fk",
- "tableFrom": "chat_threads",
- "columnsFrom": [
- "user_id"
- ],
- "tableTo": "users",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "chat_threads_uuid_unique": {
- "name": "chat_threads_uuid_unique",
- "columns": [
- "uuid"
- ],
- "nullsNotDistinct": false
- }
- }
- },
- "public.chunks": {
- "name": "chunks",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "document_id": {
- "name": "document_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "text_content": {
- "name": "text_content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "order_in_document": {
- "name": "order_in_document",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "embeddings": {
- "name": "embeddings",
- "type": "vector(1536)",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chunk_id_idx": {
- "name": "chunk_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "chunk_document_id_idx": {
- "name": "chunk_document_id_idx",
- "columns": [
- {
- "expression": "document_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "embeddingIndex": {
- "name": "embeddingIndex",
- "columns": [
- {
- "expression": "embeddings",
- "isExpression": false,
- "asc": true,
- "nulls": "last",
- "opclass": "vector_cosine_ops"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "hnsw",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "chunks_document_id_documents_id_fk": {
- "name": "chunks_document_id_documents_id_fk",
- "tableFrom": "chunks",
- "columnsFrom": [
- "document_id"
- ],
- "tableTo": "documents",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.content_to_space": {
- "name": "content_to_space",
- "schema": "",
- "columns": {
- "content_id": {
- "name": "content_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "content_id_space_id_unique": {
- "name": "content_id_space_id_unique",
- "columns": [
- {
- "expression": "content_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "content_to_space_content_id_documents_id_fk": {
- "name": "content_to_space_content_id_documents_id_fk",
- "tableFrom": "content_to_space",
- "columnsFrom": [
- "content_id"
- ],
- "tableTo": "documents",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- },
- "content_to_space_space_id_spaces_id_fk": {
- "name": "content_to_space_space_id_spaces_id_fk",
- "tableFrom": "content_to_space",
- "columnsFrom": [
- "space_id"
- ],
- "tableTo": "spaces",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.document_type": {
- "name": "document_type",
- "schema": "",
- "columns": {
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.documents": {
- "name": "documents",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "title": {
- "name": "title",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "description": {
- "name": "description",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "og_image": {
- "name": "og_image",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "raw": {
- "name": "raw",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "content": {
- "name": "content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "is_successfully_processed": {
- "name": "is_successfully_processed",
- "type": "boolean",
- "primaryKey": false,
- "notNull": false,
- "default": false
- }
- },
- "indexes": {
- "document_id_idx": {
- "name": "document_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "document_uuid_idx": {
- "name": "document_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "document_type_idx": {
- "name": "document_type_idx",
- "columns": [
- {
- "expression": "type",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "document_url_user_id_idx": {
- "name": "document_url_user_id_idx",
- "columns": [
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "document_raw_user_idx": {
- "name": "document_raw_user_idx",
- "columns": [
- {
- "expression": "raw",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "documents_type_document_type_type_fk": {
- "name": "documents_type_document_type_type_fk",
- "tableFrom": "documents",
- "columnsFrom": [
- "type"
- ],
- "tableTo": "document_type",
- "columnsTo": [
- "type"
- ],
- "onUpdate": "no action",
- "onDelete": "no action"
- },
- "documents_user_id_users_id_fk": {
- "name": "documents_user_id_users_id_fk",
- "tableFrom": "documents",
- "columnsFrom": [
- "user_id"
- ],
- "tableTo": "users",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "restrict"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "documents_uuid_unique": {
- "name": "documents_uuid_unique",
- "columns": [
- "uuid"
- ],
- "nullsNotDistinct": false
- }
- }
- },
- "public.job": {
- "name": "job",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "attempts": {
- "name": "attempts",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "lastAttemptAt": {
- "name": "lastAttemptAt",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "error": {
- "name": "error",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "user_id_url_idx": {
- "name": "user_id_url_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "job_user_id_users_id_fk": {
- "name": "job_user_id_users_id_fk",
- "tableFrom": "job",
- "columnsFrom": [
- "user_id"
- ],
- "tableTo": "users",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.saved_spaces": {
- "name": "saved_spaces",
- "schema": "",
- "columns": {
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "saved_at": {
- "name": "saved_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "saved_spaces_user_space_idx": {
- "name": "saved_spaces_user_space_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "saved_spaces_user_id_users_id_fk": {
- "name": "saved_spaces_user_id_users_id_fk",
- "tableFrom": "saved_spaces",
- "columnsFrom": [
- "user_id"
- ],
- "tableTo": "users",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- },
- "saved_spaces_space_id_spaces_id_fk": {
- "name": "saved_spaces_space_id_spaces_id_fk",
- "tableFrom": "saved_spaces",
- "columnsFrom": [
- "space_id"
- ],
- "tableTo": "spaces",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access": {
- "name": "space_access",
- "schema": "",
- "columns": {
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
- },
- "user_email": {
- "name": "user_email",
- "type": "varchar(512)",
- "primaryKey": false,
- "notNull": false
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "access_type": {
- "name": "access_type",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'read'"
- }
- },
- "indexes": {
- "space_id_user_email_idx": {
- "name": "space_id_user_email_idx",
- "columns": [
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "space_access_space_id_spaces_id_fk": {
- "name": "space_access_space_id_spaces_id_fk",
- "tableFrom": "space_access",
- "columnsFrom": [
- "space_id"
- ],
- "tableTo": "spaces",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- },
- "space_access_status_space_access_status_status_fk": {
- "name": "space_access_status_space_access_status_status_fk",
- "tableFrom": "space_access",
- "columnsFrom": [
- "status"
- ],
- "tableTo": "space_access_status",
- "columnsTo": [
- "status"
- ],
- "onUpdate": "no action",
- "onDelete": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access_status": {
- "name": "space_access_status",
- "schema": "",
- "columns": {
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_members": {
- "name": "space_members",
- "schema": "",
- "columns": {
- "spaceId": {
- "name": "spaceId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "space_members_space_user_idx": {
- "name": "space_members_space_user_idx",
- "columns": [
- {
- "expression": "spaceId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "space_members_spaceId_users_id_fk": {
- "name": "space_members_spaceId_users_id_fk",
- "tableFrom": "space_members",
- "columnsFrom": [
- "spaceId"
- ],
- "tableTo": "users",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "restrict"
- },
- "space_members_user_id_users_id_fk": {
- "name": "space_members_user_id_users_id_fk",
- "tableFrom": "space_members",
- "columnsFrom": [
- "user_id"
- ],
- "tableTo": "users",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "restrict"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.spaces": {
- "name": "spaces",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "name": {
- "name": "name",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "ownerId": {
- "name": "ownerId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "is_public": {
- "name": "is_public",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "spaces_id_idx": {
- "name": "spaces_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "spaces_owner_id_idx": {
- "name": "spaces_owner_id_idx",
- "columns": [
- {
- "expression": "ownerId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "spaces_name_idx": {
- "name": "spaces_name_idx",
- "columns": [
- {
- "expression": "name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "spaces_uuid_unique": {
- "name": "spaces_uuid_unique",
- "columns": [
- "uuid"
- ],
- "nullsNotDistinct": false
- }
- }
- },
- "public.users": {
- "name": "users",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "email": {
- "name": "email",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "first_name": {
- "name": "first_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "last_name": {
- "name": "last_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- },
- "profile_picture_url": {
- "name": "profile_picture_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "telegram_id": {
- "name": "telegram_id",
- "type": "varchar(255)",
- "primaryKey": false,
- "notNull": false
- },
- "has_onboarded": {
- "name": "has_onboarded",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "users_id_idx": {
- "name": "users_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "users_uuid_idx": {
- "name": "users_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "users_email_idx": {
- "name": "users_email_idx",
- "columns": [
- {
- "expression": "email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "users_name_idx": {
- "name": "users_name_idx",
- "columns": [
- {
- "expression": "first_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "last_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "users_created_at_idx": {
- "name": "users_created_at_idx",
- "columns": [
- {
- "expression": "created_at",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "users_telegram_id_idx": {
- "name": "users_telegram_id_idx",
- "columns": [
- {
- "expression": "telegram_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "users_uuid_unique": {
- "name": "users_uuid_unique",
- "columns": [
- "uuid"
- ],
- "nullsNotDistinct": false
- },
- "users_email_unique": {
- "name": "users_email_unique",
- "columns": [
- "email"
- ],
- "nullsNotDistinct": false
- }
- }
- }
- },
- "enums": {},
- "schemas": {},
- "sequences": {},
- "_meta": {
- "columns": {},
- "schemas": {},
- "tables": {}
- }
-}
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/0006_snapshot.json b/apps/backend/drizzle/meta/0006_snapshot.json
deleted file mode 100644
index e69b69cb..00000000
--- a/apps/backend/drizzle/meta/0006_snapshot.json
+++ /dev/null
@@ -1,1189 +0,0 @@
-{
- "id": "d1518064-adca-451e-a41f-f6902c26f3aa",
- "prevId": "5410ff1a-d1d0-4f47-b84e-a3507bd3f148",
- "version": "7",
- "dialect": "postgresql",
- "tables": {
- "public.chat_threads": {
- "name": "chat_threads",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "firstMessage": {
- "name": "firstMessage",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "messages": {
- "name": "messages",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chat_threads_user_idx": {
- "name": "chat_threads_user_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "chat_threads_user_id_users_id_fk": {
- "name": "chat_threads_user_id_users_id_fk",
- "tableFrom": "chat_threads",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "chat_threads_uuid_unique": {
- "name": "chat_threads_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.chunks": {
- "name": "chunks",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "document_id": {
- "name": "document_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "text_content": {
- "name": "text_content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "order_in_document": {
- "name": "order_in_document",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "embeddings": {
- "name": "embeddings",
- "type": "vector(1536)",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chunk_id_idx": {
- "name": "chunk_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "chunk_document_id_idx": {
- "name": "chunk_document_id_idx",
- "columns": [
- {
- "expression": "document_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "embeddingIndex": {
- "name": "embeddingIndex",
- "columns": [
- {
- "expression": "embeddings",
- "isExpression": false,
- "asc": true,
- "nulls": "last",
- "opclass": "vector_cosine_ops"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "hnsw",
- "with": {}
- }
- },
- "foreignKeys": {
- "chunks_document_id_documents_id_fk": {
- "name": "chunks_document_id_documents_id_fk",
- "tableFrom": "chunks",
- "tableTo": "documents",
- "columnsFrom": [
- "document_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.content_to_space": {
- "name": "content_to_space",
- "schema": "",
- "columns": {
- "content_id": {
- "name": "content_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "content_id_space_id_unique": {
- "name": "content_id_space_id_unique",
- "columns": [
- {
- "expression": "content_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "content_to_space_content_id_documents_id_fk": {
- "name": "content_to_space_content_id_documents_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "documents",
- "columnsFrom": [
- "content_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "content_to_space_space_id_spaces_id_fk": {
- "name": "content_to_space_space_id_spaces_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.document_type": {
- "name": "document_type",
- "schema": "",
- "columns": {
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.documents": {
- "name": "documents",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "title": {
- "name": "title",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "description": {
- "name": "description",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "og_image": {
- "name": "og_image",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "raw": {
- "name": "raw",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "content": {
- "name": "content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "is_successfully_processed": {
- "name": "is_successfully_processed",
- "type": "boolean",
- "primaryKey": false,
- "notNull": false,
- "default": false
- }
- },
- "indexes": {
- "document_id_idx": {
- "name": "document_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_uuid_idx": {
- "name": "document_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_type_idx": {
- "name": "document_type_idx",
- "columns": [
- {
- "expression": "type",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_url_user_id_idx": {
- "name": "document_url_user_id_idx",
- "columns": [
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_raw_user_idx": {
- "name": "document_raw_user_idx",
- "columns": [
- {
- "expression": "raw",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "documents_type_document_type_type_fk": {
- "name": "documents_type_document_type_type_fk",
- "tableFrom": "documents",
- "tableTo": "document_type",
- "columnsFrom": [
- "type"
- ],
- "columnsTo": [
- "type"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- },
- "documents_user_id_users_id_fk": {
- "name": "documents_user_id_users_id_fk",
- "tableFrom": "documents",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "documents_uuid_unique": {
- "name": "documents_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.job": {
- "name": "job",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "attempts": {
- "name": "attempts",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "lastAttemptAt": {
- "name": "lastAttemptAt",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "error": {
- "name": "error",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "user_id_url_idx": {
- "name": "user_id_url_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "job_user_id_users_id_fk": {
- "name": "job_user_id_users_id_fk",
- "tableFrom": "job",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.saved_spaces": {
- "name": "saved_spaces",
- "schema": "",
- "columns": {
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "saved_at": {
- "name": "saved_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "saved_spaces_user_space_idx": {
- "name": "saved_spaces_user_space_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "saved_spaces_user_id_users_id_fk": {
- "name": "saved_spaces_user_id_users_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "saved_spaces_space_id_spaces_id_fk": {
- "name": "saved_spaces_space_id_spaces_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access": {
- "name": "space_access",
- "schema": "",
- "columns": {
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
- },
- "user_email": {
- "name": "user_email",
- "type": "varchar(512)",
- "primaryKey": false,
- "notNull": false
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "access_type": {
- "name": "access_type",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'read'"
- }
- },
- "indexes": {
- "space_id_user_email_idx": {
- "name": "space_id_user_email_idx",
- "columns": [
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_access_space_id_spaces_id_fk": {
- "name": "space_access_space_id_spaces_id_fk",
- "tableFrom": "space_access",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "space_access_status_space_access_status_status_fk": {
- "name": "space_access_status_space_access_status_status_fk",
- "tableFrom": "space_access",
- "tableTo": "space_access_status",
- "columnsFrom": [
- "status"
- ],
- "columnsTo": [
- "status"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access_status": {
- "name": "space_access_status",
- "schema": "",
- "columns": {
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_members": {
- "name": "space_members",
- "schema": "",
- "columns": {
- "spaceId": {
- "name": "spaceId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "space_members_space_user_idx": {
- "name": "space_members_space_user_idx",
- "columns": [
- {
- "expression": "spaceId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_members_spaceId_users_id_fk": {
- "name": "space_members_spaceId_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "spaceId"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- },
- "space_members_user_id_users_id_fk": {
- "name": "space_members_user_id_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.spaces": {
- "name": "spaces",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "name": {
- "name": "name",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "ownerId": {
- "name": "ownerId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "is_public": {
- "name": "is_public",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "spaces_id_idx": {
- "name": "spaces_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_owner_id_idx": {
- "name": "spaces_owner_id_idx",
- "columns": [
- {
- "expression": "ownerId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_name_idx": {
- "name": "spaces_name_idx",
- "columns": [
- {
- "expression": "name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "spaces_uuid_unique": {
- "name": "spaces_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.users": {
- "name": "users",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "email": {
- "name": "email",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "first_name": {
- "name": "first_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "last_name": {
- "name": "last_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- },
- "profile_picture_url": {
- "name": "profile_picture_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "telegram_id": {
- "name": "telegram_id",
- "type": "varchar(255)",
- "primaryKey": false,
- "notNull": false
- },
- "has_onboarded": {
- "name": "has_onboarded",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "users_id_idx": {
- "name": "users_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_uuid_idx": {
- "name": "users_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_email_idx": {
- "name": "users_email_idx",
- "columns": [
- {
- "expression": "email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_name_idx": {
- "name": "users_name_idx",
- "columns": [
- {
- "expression": "first_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "last_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_created_at_idx": {
- "name": "users_created_at_idx",
- "columns": [
- {
- "expression": "created_at",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_telegram_id_idx": {
- "name": "users_telegram_id_idx",
- "columns": [
- {
- "expression": "telegram_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "users_uuid_unique": {
- "name": "users_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- },
- "users_email_unique": {
- "name": "users_email_unique",
- "nullsNotDistinct": false,
- "columns": [
- "email"
- ]
- }
- }
- },
- "public.waitlist": {
- "name": "waitlist",
- "schema": "",
- "columns": {
- "email": {
- "name": "email",
- "type": "varchar(512)",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- }
- },
- "enums": {},
- "schemas": {},
- "sequences": {},
- "_meta": {
- "columns": {},
- "schemas": {},
- "tables": {}
- }
-}
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/0007_snapshot.json b/apps/backend/drizzle/meta/0007_snapshot.json
deleted file mode 100644
index e91f60a8..00000000
--- a/apps/backend/drizzle/meta/0007_snapshot.json
+++ /dev/null
@@ -1,1168 +0,0 @@
-{
- "id": "912b42e8-2827-4572-a698-577ba751461e",
- "prevId": "d1518064-adca-451e-a41f-f6902c26f3aa",
- "version": "7",
- "dialect": "postgresql",
- "tables": {
- "public.chat_threads": {
- "name": "chat_threads",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "firstMessage": {
- "name": "firstMessage",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "messages": {
- "name": "messages",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chat_threads_user_idx": {
- "name": "chat_threads_user_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "chat_threads_user_id_users_id_fk": {
- "name": "chat_threads_user_id_users_id_fk",
- "tableFrom": "chat_threads",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "chat_threads_uuid_unique": {
- "name": "chat_threads_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.chunks": {
- "name": "chunks",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "document_id": {
- "name": "document_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "text_content": {
- "name": "text_content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "order_in_document": {
- "name": "order_in_document",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "embeddings": {
- "name": "embeddings",
- "type": "vector(1536)",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chunk_id_idx": {
- "name": "chunk_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "chunk_document_id_idx": {
- "name": "chunk_document_id_idx",
- "columns": [
- {
- "expression": "document_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "embeddingIndex": {
- "name": "embeddingIndex",
- "columns": [
- {
- "expression": "embeddings",
- "isExpression": false,
- "asc": true,
- "nulls": "last",
- "opclass": "vector_cosine_ops"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "hnsw",
- "with": {}
- }
- },
- "foreignKeys": {
- "chunks_document_id_documents_id_fk": {
- "name": "chunks_document_id_documents_id_fk",
- "tableFrom": "chunks",
- "tableTo": "documents",
- "columnsFrom": [
- "document_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.content_to_space": {
- "name": "content_to_space",
- "schema": "",
- "columns": {
- "content_id": {
- "name": "content_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "content_id_space_id_unique": {
- "name": "content_id_space_id_unique",
- "columns": [
- {
- "expression": "content_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "content_to_space_content_id_documents_id_fk": {
- "name": "content_to_space_content_id_documents_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "documents",
- "columnsFrom": [
- "content_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "content_to_space_space_id_spaces_id_fk": {
- "name": "content_to_space_space_id_spaces_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.document_type": {
- "name": "document_type",
- "schema": "",
- "columns": {
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.documents": {
- "name": "documents",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "title": {
- "name": "title",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "description": {
- "name": "description",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "og_image": {
- "name": "og_image",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "raw": {
- "name": "raw",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "content": {
- "name": "content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "is_successfully_processed": {
- "name": "is_successfully_processed",
- "type": "boolean",
- "primaryKey": false,
- "notNull": false,
- "default": false
- }
- },
- "indexes": {
- "document_id_idx": {
- "name": "document_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_uuid_idx": {
- "name": "document_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_type_idx": {
- "name": "document_type_idx",
- "columns": [
- {
- "expression": "type",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_raw_user_idx": {
- "name": "document_raw_user_idx",
- "columns": [
- {
- "expression": "raw",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "documents_type_document_type_type_fk": {
- "name": "documents_type_document_type_type_fk",
- "tableFrom": "documents",
- "tableTo": "document_type",
- "columnsFrom": [
- "type"
- ],
- "columnsTo": [
- "type"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- },
- "documents_user_id_users_id_fk": {
- "name": "documents_user_id_users_id_fk",
- "tableFrom": "documents",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "documents_uuid_unique": {
- "name": "documents_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.job": {
- "name": "job",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "attempts": {
- "name": "attempts",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "lastAttemptAt": {
- "name": "lastAttemptAt",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "error": {
- "name": "error",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "user_id_url_idx": {
- "name": "user_id_url_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "job_user_id_users_id_fk": {
- "name": "job_user_id_users_id_fk",
- "tableFrom": "job",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.saved_spaces": {
- "name": "saved_spaces",
- "schema": "",
- "columns": {
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "saved_at": {
- "name": "saved_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "saved_spaces_user_space_idx": {
- "name": "saved_spaces_user_space_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "saved_spaces_user_id_users_id_fk": {
- "name": "saved_spaces_user_id_users_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "saved_spaces_space_id_spaces_id_fk": {
- "name": "saved_spaces_space_id_spaces_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access": {
- "name": "space_access",
- "schema": "",
- "columns": {
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
- },
- "user_email": {
- "name": "user_email",
- "type": "varchar(512)",
- "primaryKey": false,
- "notNull": false
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "access_type": {
- "name": "access_type",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'read'"
- }
- },
- "indexes": {
- "space_id_user_email_idx": {
- "name": "space_id_user_email_idx",
- "columns": [
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_access_space_id_spaces_id_fk": {
- "name": "space_access_space_id_spaces_id_fk",
- "tableFrom": "space_access",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "space_access_status_space_access_status_status_fk": {
- "name": "space_access_status_space_access_status_status_fk",
- "tableFrom": "space_access",
- "tableTo": "space_access_status",
- "columnsFrom": [
- "status"
- ],
- "columnsTo": [
- "status"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access_status": {
- "name": "space_access_status",
- "schema": "",
- "columns": {
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_members": {
- "name": "space_members",
- "schema": "",
- "columns": {
- "spaceId": {
- "name": "spaceId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "space_members_space_user_idx": {
- "name": "space_members_space_user_idx",
- "columns": [
- {
- "expression": "spaceId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_members_spaceId_users_id_fk": {
- "name": "space_members_spaceId_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "spaceId"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- },
- "space_members_user_id_users_id_fk": {
- "name": "space_members_user_id_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.spaces": {
- "name": "spaces",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "name": {
- "name": "name",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "ownerId": {
- "name": "ownerId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "is_public": {
- "name": "is_public",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "spaces_id_idx": {
- "name": "spaces_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_owner_id_idx": {
- "name": "spaces_owner_id_idx",
- "columns": [
- {
- "expression": "ownerId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_name_idx": {
- "name": "spaces_name_idx",
- "columns": [
- {
- "expression": "name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "spaces_uuid_unique": {
- "name": "spaces_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.users": {
- "name": "users",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "email": {
- "name": "email",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "first_name": {
- "name": "first_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "last_name": {
- "name": "last_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- },
- "profile_picture_url": {
- "name": "profile_picture_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "telegram_id": {
- "name": "telegram_id",
- "type": "varchar(255)",
- "primaryKey": false,
- "notNull": false
- },
- "has_onboarded": {
- "name": "has_onboarded",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "users_id_idx": {
- "name": "users_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_uuid_idx": {
- "name": "users_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_email_idx": {
- "name": "users_email_idx",
- "columns": [
- {
- "expression": "email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_name_idx": {
- "name": "users_name_idx",
- "columns": [
- {
- "expression": "first_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "last_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_created_at_idx": {
- "name": "users_created_at_idx",
- "columns": [
- {
- "expression": "created_at",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_telegram_id_idx": {
- "name": "users_telegram_id_idx",
- "columns": [
- {
- "expression": "telegram_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "users_uuid_unique": {
- "name": "users_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- },
- "users_email_unique": {
- "name": "users_email_unique",
- "nullsNotDistinct": false,
- "columns": [
- "email"
- ]
- }
- }
- },
- "public.waitlist": {
- "name": "waitlist",
- "schema": "",
- "columns": {
- "email": {
- "name": "email",
- "type": "varchar(512)",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- }
- },
- "enums": {},
- "schemas": {},
- "sequences": {},
- "_meta": {
- "columns": {},
- "schemas": {},
- "tables": {}
- }
-}
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/0008_snapshot.json b/apps/backend/drizzle/meta/0008_snapshot.json
deleted file mode 100644
index b4cdeb49..00000000
--- a/apps/backend/drizzle/meta/0008_snapshot.json
+++ /dev/null
@@ -1,1168 +0,0 @@
-{
- "id": "6f307490-3b7f-4c61-aec9-f51b65aae436",
- "prevId": "912b42e8-2827-4572-a698-577ba751461e",
- "version": "7",
- "dialect": "postgresql",
- "tables": {
- "public.chat_threads": {
- "name": "chat_threads",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "firstMessage": {
- "name": "firstMessage",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "messages": {
- "name": "messages",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chat_threads_user_idx": {
- "name": "chat_threads_user_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "chat_threads_user_id_users_id_fk": {
- "name": "chat_threads_user_id_users_id_fk",
- "tableFrom": "chat_threads",
- "columnsFrom": [
- "user_id"
- ],
- "tableTo": "users",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "chat_threads_uuid_unique": {
- "name": "chat_threads_uuid_unique",
- "columns": [
- "uuid"
- ],
- "nullsNotDistinct": false
- }
- }
- },
- "public.chunks": {
- "name": "chunks",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "document_id": {
- "name": "document_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "text_content": {
- "name": "text_content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "order_in_document": {
- "name": "order_in_document",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "embeddings": {
- "name": "embeddings",
- "type": "vector(1536)",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chunk_id_idx": {
- "name": "chunk_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "chunk_document_id_idx": {
- "name": "chunk_document_id_idx",
- "columns": [
- {
- "expression": "document_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "embeddingIndex": {
- "name": "embeddingIndex",
- "columns": [
- {
- "expression": "embeddings",
- "isExpression": false,
- "asc": true,
- "nulls": "last",
- "opclass": "vector_cosine_ops"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "hnsw",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "chunks_document_id_documents_id_fk": {
- "name": "chunks_document_id_documents_id_fk",
- "tableFrom": "chunks",
- "columnsFrom": [
- "document_id"
- ],
- "tableTo": "documents",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.content_to_space": {
- "name": "content_to_space",
- "schema": "",
- "columns": {
- "content_id": {
- "name": "content_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "content_id_space_id_unique": {
- "name": "content_id_space_id_unique",
- "columns": [
- {
- "expression": "content_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "content_to_space_content_id_documents_id_fk": {
- "name": "content_to_space_content_id_documents_id_fk",
- "tableFrom": "content_to_space",
- "columnsFrom": [
- "content_id"
- ],
- "tableTo": "documents",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- },
- "content_to_space_space_id_spaces_id_fk": {
- "name": "content_to_space_space_id_spaces_id_fk",
- "tableFrom": "content_to_space",
- "columnsFrom": [
- "space_id"
- ],
- "tableTo": "spaces",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.document_type": {
- "name": "document_type",
- "schema": "",
- "columns": {
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.documents": {
- "name": "documents",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "title": {
- "name": "title",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "description": {
- "name": "description",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "og_image": {
- "name": "og_image",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "raw": {
- "name": "raw",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "content": {
- "name": "content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "is_successfully_processed": {
- "name": "is_successfully_processed",
- "type": "boolean",
- "primaryKey": false,
- "notNull": false,
- "default": false
- }
- },
- "indexes": {
- "document_id_idx": {
- "name": "document_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "document_uuid_idx": {
- "name": "document_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "document_type_idx": {
- "name": "document_type_idx",
- "columns": [
- {
- "expression": "type",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "document_raw_user_idx": {
- "name": "document_raw_user_idx",
- "columns": [
- {
- "expression": "raw",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "documents_type_document_type_type_fk": {
- "name": "documents_type_document_type_type_fk",
- "tableFrom": "documents",
- "columnsFrom": [
- "type"
- ],
- "tableTo": "document_type",
- "columnsTo": [
- "type"
- ],
- "onUpdate": "no action",
- "onDelete": "no action"
- },
- "documents_user_id_users_id_fk": {
- "name": "documents_user_id_users_id_fk",
- "tableFrom": "documents",
- "columnsFrom": [
- "user_id"
- ],
- "tableTo": "users",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "restrict"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "documents_uuid_unique": {
- "name": "documents_uuid_unique",
- "columns": [
- "uuid"
- ],
- "nullsNotDistinct": false
- }
- }
- },
- "public.job": {
- "name": "job",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "attempts": {
- "name": "attempts",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "lastAttemptAt": {
- "name": "lastAttemptAt",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "error": {
- "name": "error",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "user_id_url_idx": {
- "name": "user_id_url_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "job_user_id_users_id_fk": {
- "name": "job_user_id_users_id_fk",
- "tableFrom": "job",
- "columnsFrom": [
- "user_id"
- ],
- "tableTo": "users",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.saved_spaces": {
- "name": "saved_spaces",
- "schema": "",
- "columns": {
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "saved_at": {
- "name": "saved_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "saved_spaces_user_space_idx": {
- "name": "saved_spaces_user_space_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "saved_spaces_user_id_users_id_fk": {
- "name": "saved_spaces_user_id_users_id_fk",
- "tableFrom": "saved_spaces",
- "columnsFrom": [
- "user_id"
- ],
- "tableTo": "users",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- },
- "saved_spaces_space_id_spaces_id_fk": {
- "name": "saved_spaces_space_id_spaces_id_fk",
- "tableFrom": "saved_spaces",
- "columnsFrom": [
- "space_id"
- ],
- "tableTo": "spaces",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access": {
- "name": "space_access",
- "schema": "",
- "columns": {
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
- },
- "user_email": {
- "name": "user_email",
- "type": "varchar(512)",
- "primaryKey": false,
- "notNull": false
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "access_type": {
- "name": "access_type",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'read'"
- }
- },
- "indexes": {
- "space_id_user_email_idx": {
- "name": "space_id_user_email_idx",
- "columns": [
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "space_access_space_id_spaces_id_fk": {
- "name": "space_access_space_id_spaces_id_fk",
- "tableFrom": "space_access",
- "columnsFrom": [
- "space_id"
- ],
- "tableTo": "spaces",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "cascade"
- },
- "space_access_status_space_access_status_status_fk": {
- "name": "space_access_status_space_access_status_status_fk",
- "tableFrom": "space_access",
- "columnsFrom": [
- "status"
- ],
- "tableTo": "space_access_status",
- "columnsTo": [
- "status"
- ],
- "onUpdate": "no action",
- "onDelete": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access_status": {
- "name": "space_access_status",
- "schema": "",
- "columns": {
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_members": {
- "name": "space_members",
- "schema": "",
- "columns": {
- "spaceId": {
- "name": "spaceId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "space_members_space_user_idx": {
- "name": "space_members_space_user_idx",
- "columns": [
- {
- "expression": "spaceId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {
- "space_members_spaceId_users_id_fk": {
- "name": "space_members_spaceId_users_id_fk",
- "tableFrom": "space_members",
- "columnsFrom": [
- "spaceId"
- ],
- "tableTo": "users",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "restrict"
- },
- "space_members_user_id_users_id_fk": {
- "name": "space_members_user_id_users_id_fk",
- "tableFrom": "space_members",
- "columnsFrom": [
- "user_id"
- ],
- "tableTo": "users",
- "columnsTo": [
- "id"
- ],
- "onUpdate": "no action",
- "onDelete": "restrict"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.spaces": {
- "name": "spaces",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "name": {
- "name": "name",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "ownerId": {
- "name": "ownerId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "is_public": {
- "name": "is_public",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "spaces_id_idx": {
- "name": "spaces_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "spaces_owner_id_idx": {
- "name": "spaces_owner_id_idx",
- "columns": [
- {
- "expression": "ownerId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "spaces_name_idx": {
- "name": "spaces_name_idx",
- "columns": [
- {
- "expression": "name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "spaces_uuid_unique": {
- "name": "spaces_uuid_unique",
- "columns": [
- "uuid"
- ],
- "nullsNotDistinct": false
- }
- }
- },
- "public.users": {
- "name": "users",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "email": {
- "name": "email",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "first_name": {
- "name": "first_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "last_name": {
- "name": "last_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- },
- "profile_picture_url": {
- "name": "profile_picture_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "telegram_id": {
- "name": "telegram_id",
- "type": "varchar(255)",
- "primaryKey": false,
- "notNull": false
- },
- "has_onboarded": {
- "name": "has_onboarded",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "users_id_idx": {
- "name": "users_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "users_uuid_idx": {
- "name": "users_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "users_email_idx": {
- "name": "users_email_idx",
- "columns": [
- {
- "expression": "email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "users_name_idx": {
- "name": "users_name_idx",
- "columns": [
- {
- "expression": "first_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "last_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "users_created_at_idx": {
- "name": "users_created_at_idx",
- "columns": [
- {
- "expression": "created_at",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "with": {},
- "method": "btree",
- "concurrently": false
- },
- "users_telegram_id_idx": {
- "name": "users_telegram_id_idx",
- "columns": [
- {
- "expression": "telegram_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "with": {},
- "method": "btree",
- "concurrently": false
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "users_uuid_unique": {
- "name": "users_uuid_unique",
- "columns": [
- "uuid"
- ],
- "nullsNotDistinct": false
- },
- "users_email_unique": {
- "name": "users_email_unique",
- "columns": [
- "email"
- ],
- "nullsNotDistinct": false
- }
- }
- },
- "public.waitlist": {
- "name": "waitlist",
- "schema": "",
- "columns": {
- "email": {
- "name": "email",
- "type": "varchar(512)",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- }
- },
- "enums": {},
- "schemas": {},
- "sequences": {},
- "_meta": {
- "columns": {},
- "schemas": {},
- "tables": {}
- }
-}
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/0009_snapshot.json b/apps/backend/drizzle/meta/0009_snapshot.json
deleted file mode 100644
index 33f2bbb5..00000000
--- a/apps/backend/drizzle/meta/0009_snapshot.json
+++ /dev/null
@@ -1,1175 +0,0 @@
-{
- "id": "b661c516-b919-46cf-81f3-6d7743acaf2f",
- "prevId": "6f307490-3b7f-4c61-aec9-f51b65aae436",
- "version": "7",
- "dialect": "postgresql",
- "tables": {
- "public.chat_threads": {
- "name": "chat_threads",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "firstMessage": {
- "name": "firstMessage",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "messages": {
- "name": "messages",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chat_threads_user_idx": {
- "name": "chat_threads_user_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "chat_threads_user_id_users_id_fk": {
- "name": "chat_threads_user_id_users_id_fk",
- "tableFrom": "chat_threads",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "chat_threads_uuid_unique": {
- "name": "chat_threads_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.chunks": {
- "name": "chunks",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "document_id": {
- "name": "document_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "text_content": {
- "name": "text_content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "order_in_document": {
- "name": "order_in_document",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "embeddings": {
- "name": "embeddings",
- "type": "vector(1536)",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chunk_id_idx": {
- "name": "chunk_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "chunk_document_id_idx": {
- "name": "chunk_document_id_idx",
- "columns": [
- {
- "expression": "document_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "embeddingIndex": {
- "name": "embeddingIndex",
- "columns": [
- {
- "expression": "embeddings",
- "isExpression": false,
- "asc": true,
- "nulls": "last",
- "opclass": "vector_cosine_ops"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "hnsw",
- "with": {}
- }
- },
- "foreignKeys": {
- "chunks_document_id_documents_id_fk": {
- "name": "chunks_document_id_documents_id_fk",
- "tableFrom": "chunks",
- "tableTo": "documents",
- "columnsFrom": [
- "document_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.content_to_space": {
- "name": "content_to_space",
- "schema": "",
- "columns": {
- "content_id": {
- "name": "content_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "content_id_space_id_unique": {
- "name": "content_id_space_id_unique",
- "columns": [
- {
- "expression": "content_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "content_to_space_content_id_documents_id_fk": {
- "name": "content_to_space_content_id_documents_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "documents",
- "columnsFrom": [
- "content_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "content_to_space_space_id_spaces_id_fk": {
- "name": "content_to_space_space_id_spaces_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.document_type": {
- "name": "document_type",
- "schema": "",
- "columns": {
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.documents": {
- "name": "documents",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "title": {
- "name": "title",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "description": {
- "name": "description",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "og_image": {
- "name": "og_image",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "raw": {
- "name": "raw",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "content": {
- "name": "content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "is_successfully_processed": {
- "name": "is_successfully_processed",
- "type": "boolean",
- "primaryKey": false,
- "notNull": false,
- "default": false
- }
- },
- "indexes": {
- "document_id_idx": {
- "name": "document_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_uuid_idx": {
- "name": "document_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_type_idx": {
- "name": "document_type_idx",
- "columns": [
- {
- "expression": "type",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_raw_user_idx": {
- "name": "document_raw_user_idx",
- "columns": [
- {
- "expression": "raw",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "documents_type_document_type_type_fk": {
- "name": "documents_type_document_type_type_fk",
- "tableFrom": "documents",
- "tableTo": "document_type",
- "columnsFrom": [
- "type"
- ],
- "columnsTo": [
- "type"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- },
- "documents_user_id_users_id_fk": {
- "name": "documents_user_id_users_id_fk",
- "tableFrom": "documents",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "documents_uuid_unique": {
- "name": "documents_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.job": {
- "name": "job",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "attempts": {
- "name": "attempts",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "lastAttemptAt": {
- "name": "lastAttemptAt",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "error": {
- "name": "error",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "user_id_url_idx": {
- "name": "user_id_url_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "job_user_id_users_id_fk": {
- "name": "job_user_id_users_id_fk",
- "tableFrom": "job",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.saved_spaces": {
- "name": "saved_spaces",
- "schema": "",
- "columns": {
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "saved_at": {
- "name": "saved_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "saved_spaces_user_space_idx": {
- "name": "saved_spaces_user_space_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "saved_spaces_user_id_users_id_fk": {
- "name": "saved_spaces_user_id_users_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "saved_spaces_space_id_spaces_id_fk": {
- "name": "saved_spaces_space_id_spaces_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access": {
- "name": "space_access",
- "schema": "",
- "columns": {
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
- },
- "user_email": {
- "name": "user_email",
- "type": "varchar(512)",
- "primaryKey": false,
- "notNull": false
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "access_type": {
- "name": "access_type",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'read'"
- }
- },
- "indexes": {
- "space_id_user_email_idx": {
- "name": "space_id_user_email_idx",
- "columns": [
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_access_space_id_spaces_id_fk": {
- "name": "space_access_space_id_spaces_id_fk",
- "tableFrom": "space_access",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "space_access_status_space_access_status_status_fk": {
- "name": "space_access_status_space_access_status_status_fk",
- "tableFrom": "space_access",
- "tableTo": "space_access_status",
- "columnsFrom": [
- "status"
- ],
- "columnsTo": [
- "status"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access_status": {
- "name": "space_access_status",
- "schema": "",
- "columns": {
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_members": {
- "name": "space_members",
- "schema": "",
- "columns": {
- "spaceId": {
- "name": "spaceId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "space_members_space_user_idx": {
- "name": "space_members_space_user_idx",
- "columns": [
- {
- "expression": "spaceId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_members_spaceId_users_id_fk": {
- "name": "space_members_spaceId_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "spaceId"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- },
- "space_members_user_id_users_id_fk": {
- "name": "space_members_user_id_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.spaces": {
- "name": "spaces",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "name": {
- "name": "name",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "ownerId": {
- "name": "ownerId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "is_public": {
- "name": "is_public",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "spaces_id_idx": {
- "name": "spaces_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_owner_id_idx": {
- "name": "spaces_owner_id_idx",
- "columns": [
- {
- "expression": "ownerId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_name_idx": {
- "name": "spaces_name_idx",
- "columns": [
- {
- "expression": "name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "spaces_uuid_unique": {
- "name": "spaces_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.users": {
- "name": "users",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "email": {
- "name": "email",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "first_name": {
- "name": "first_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "last_name": {
- "name": "last_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- },
- "profile_picture_url": {
- "name": "profile_picture_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "telegram_id": {
- "name": "telegram_id",
- "type": "varchar(255)",
- "primaryKey": false,
- "notNull": false
- },
- "has_onboarded": {
- "name": "has_onboarded",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "users_id_idx": {
- "name": "users_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_uuid_idx": {
- "name": "users_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_email_idx": {
- "name": "users_email_idx",
- "columns": [
- {
- "expression": "email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_name_idx": {
- "name": "users_name_idx",
- "columns": [
- {
- "expression": "first_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "last_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_created_at_idx": {
- "name": "users_created_at_idx",
- "columns": [
- {
- "expression": "created_at",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_telegram_id_idx": {
- "name": "users_telegram_id_idx",
- "columns": [
- {
- "expression": "telegram_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "users_uuid_unique": {
- "name": "users_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- },
- "users_email_unique": {
- "name": "users_email_unique",
- "nullsNotDistinct": false,
- "columns": [
- "email"
- ]
- }
- }
- },
- "public.waitlist": {
- "name": "waitlist",
- "schema": "",
- "columns": {
- "email": {
- "name": "email",
- "type": "varchar(512)",
- "primaryKey": true,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- }
- },
- "enums": {},
- "schemas": {},
- "sequences": {},
- "_meta": {
- "columns": {},
- "schemas": {},
- "tables": {}
- }
-}
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/0010_snapshot.json b/apps/backend/drizzle/meta/0010_snapshot.json
deleted file mode 100644
index 3cb3360c..00000000
--- a/apps/backend/drizzle/meta/0010_snapshot.json
+++ /dev/null
@@ -1,1175 +0,0 @@
-{
- "id": "6fcd94f9-4308-4619-bc19-ec851edf8964",
- "prevId": "b661c516-b919-46cf-81f3-6d7743acaf2f",
- "version": "7",
- "dialect": "postgresql",
- "tables": {
- "public.chat_threads": {
- "name": "chat_threads",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "firstMessage": {
- "name": "firstMessage",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "messages": {
- "name": "messages",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chat_threads_user_idx": {
- "name": "chat_threads_user_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "chat_threads_user_id_users_id_fk": {
- "name": "chat_threads_user_id_users_id_fk",
- "tableFrom": "chat_threads",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "chat_threads_uuid_unique": {
- "name": "chat_threads_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.chunks": {
- "name": "chunks",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "document_id": {
- "name": "document_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "text_content": {
- "name": "text_content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "order_in_document": {
- "name": "order_in_document",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "embeddings": {
- "name": "embeddings",
- "type": "vector(1536)",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chunk_id_idx": {
- "name": "chunk_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "chunk_document_id_idx": {
- "name": "chunk_document_id_idx",
- "columns": [
- {
- "expression": "document_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "embeddingIndex": {
- "name": "embeddingIndex",
- "columns": [
- {
- "expression": "embeddings",
- "isExpression": false,
- "asc": true,
- "nulls": "last",
- "opclass": "vector_cosine_ops"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "hnsw",
- "with": {}
- }
- },
- "foreignKeys": {
- "chunks_document_id_documents_id_fk": {
- "name": "chunks_document_id_documents_id_fk",
- "tableFrom": "chunks",
- "tableTo": "documents",
- "columnsFrom": [
- "document_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.content_to_space": {
- "name": "content_to_space",
- "schema": "",
- "columns": {
- "content_id": {
- "name": "content_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "content_id_space_id_unique": {
- "name": "content_id_space_id_unique",
- "columns": [
- {
- "expression": "content_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "content_to_space_content_id_documents_id_fk": {
- "name": "content_to_space_content_id_documents_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "documents",
- "columnsFrom": [
- "content_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "content_to_space_space_id_spaces_id_fk": {
- "name": "content_to_space_space_id_spaces_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.document_type": {
- "name": "document_type",
- "schema": "",
- "columns": {
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.documents": {
- "name": "documents",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "title": {
- "name": "title",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "description": {
- "name": "description",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "og_image": {
- "name": "og_image",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "raw": {
- "name": "raw",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "content": {
- "name": "content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "is_successfully_processed": {
- "name": "is_successfully_processed",
- "type": "boolean",
- "primaryKey": false,
- "notNull": false,
- "default": false
- }
- },
- "indexes": {
- "document_id_idx": {
- "name": "document_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_uuid_idx": {
- "name": "document_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_type_idx": {
- "name": "document_type_idx",
- "columns": [
- {
- "expression": "type",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_raw_user_idx": {
- "name": "document_raw_user_idx",
- "columns": [
- {
- "expression": "raw",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "documents_type_document_type_type_fk": {
- "name": "documents_type_document_type_type_fk",
- "tableFrom": "documents",
- "tableTo": "document_type",
- "columnsFrom": [
- "type"
- ],
- "columnsTo": [
- "type"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- },
- "documents_user_id_users_id_fk": {
- "name": "documents_user_id_users_id_fk",
- "tableFrom": "documents",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "documents_uuid_unique": {
- "name": "documents_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.job": {
- "name": "job",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "attempts": {
- "name": "attempts",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "lastAttemptAt": {
- "name": "lastAttemptAt",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "error": {
- "name": "error",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "user_id_url_idx": {
- "name": "user_id_url_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "job_user_id_users_id_fk": {
- "name": "job_user_id_users_id_fk",
- "tableFrom": "job",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.saved_spaces": {
- "name": "saved_spaces",
- "schema": "",
- "columns": {
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "saved_at": {
- "name": "saved_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "saved_spaces_user_space_idx": {
- "name": "saved_spaces_user_space_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "saved_spaces_user_id_users_id_fk": {
- "name": "saved_spaces_user_id_users_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "saved_spaces_space_id_spaces_id_fk": {
- "name": "saved_spaces_space_id_spaces_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access": {
- "name": "space_access",
- "schema": "",
- "columns": {
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
- },
- "user_email": {
- "name": "user_email",
- "type": "varchar(512)",
- "primaryKey": false,
- "notNull": false
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "access_type": {
- "name": "access_type",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'read'"
- }
- },
- "indexes": {
- "space_id_user_email_idx": {
- "name": "space_id_user_email_idx",
- "columns": [
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_access_space_id_spaces_id_fk": {
- "name": "space_access_space_id_spaces_id_fk",
- "tableFrom": "space_access",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "space_access_status_space_access_status_status_fk": {
- "name": "space_access_status_space_access_status_status_fk",
- "tableFrom": "space_access",
- "tableTo": "space_access_status",
- "columnsFrom": [
- "status"
- ],
- "columnsTo": [
- "status"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access_status": {
- "name": "space_access_status",
- "schema": "",
- "columns": {
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_members": {
- "name": "space_members",
- "schema": "",
- "columns": {
- "spaceId": {
- "name": "spaceId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "space_members_space_user_idx": {
- "name": "space_members_space_user_idx",
- "columns": [
- {
- "expression": "spaceId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_members_spaceId_users_id_fk": {
- "name": "space_members_spaceId_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "spaceId"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- },
- "space_members_user_id_users_id_fk": {
- "name": "space_members_user_id_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.spaces": {
- "name": "spaces",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "name": {
- "name": "name",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "ownerId": {
- "name": "ownerId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "is_public": {
- "name": "is_public",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "spaces_id_idx": {
- "name": "spaces_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_owner_id_idx": {
- "name": "spaces_owner_id_idx",
- "columns": [
- {
- "expression": "ownerId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_name_idx": {
- "name": "spaces_name_idx",
- "columns": [
- {
- "expression": "name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "spaces_uuid_unique": {
- "name": "spaces_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.users": {
- "name": "users",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "email": {
- "name": "email",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "first_name": {
- "name": "first_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "last_name": {
- "name": "last_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- },
- "profile_picture_url": {
- "name": "profile_picture_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "telegram_id": {
- "name": "telegram_id",
- "type": "varchar(255)",
- "primaryKey": false,
- "notNull": false
- },
- "has_onboarded": {
- "name": "has_onboarded",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "users_id_idx": {
- "name": "users_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_uuid_idx": {
- "name": "users_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_email_idx": {
- "name": "users_email_idx",
- "columns": [
- {
- "expression": "email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_name_idx": {
- "name": "users_name_idx",
- "columns": [
- {
- "expression": "first_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "last_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_created_at_idx": {
- "name": "users_created_at_idx",
- "columns": [
- {
- "expression": "created_at",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_telegram_id_idx": {
- "name": "users_telegram_id_idx",
- "columns": [
- {
- "expression": "telegram_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "users_uuid_unique": {
- "name": "users_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- },
- "users_email_unique": {
- "name": "users_email_unique",
- "nullsNotDistinct": false,
- "columns": [
- "email"
- ]
- }
- }
- },
- "public.waitlist": {
- "name": "waitlist",
- "schema": "",
- "columns": {
- "email": {
- "name": "email",
- "type": "varchar(512)",
- "primaryKey": true,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- }
- },
- "enums": {},
- "schemas": {},
- "sequences": {},
- "_meta": {
- "columns": {},
- "schemas": {},
- "tables": {}
- }
-}
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/0011_snapshot.json b/apps/backend/drizzle/meta/0011_snapshot.json
deleted file mode 100644
index b97e0826..00000000
--- a/apps/backend/drizzle/meta/0011_snapshot.json
+++ /dev/null
@@ -1,1181 +0,0 @@
-{
- "id": "e8a080b4-de5d-4015-945e-7bf5f461f16f",
- "prevId": "6fcd94f9-4308-4619-bc19-ec851edf8964",
- "version": "7",
- "dialect": "postgresql",
- "tables": {
- "public.chat_threads": {
- "name": "chat_threads",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "firstMessage": {
- "name": "firstMessage",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "messages": {
- "name": "messages",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chat_threads_user_idx": {
- "name": "chat_threads_user_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "chat_threads_user_id_users_id_fk": {
- "name": "chat_threads_user_id_users_id_fk",
- "tableFrom": "chat_threads",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "chat_threads_uuid_unique": {
- "name": "chat_threads_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.chunks": {
- "name": "chunks",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "document_id": {
- "name": "document_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "text_content": {
- "name": "text_content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "order_in_document": {
- "name": "order_in_document",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "embeddings": {
- "name": "embeddings",
- "type": "vector(1536)",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chunk_id_idx": {
- "name": "chunk_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "chunk_document_id_idx": {
- "name": "chunk_document_id_idx",
- "columns": [
- {
- "expression": "document_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "embeddingIndex": {
- "name": "embeddingIndex",
- "columns": [
- {
- "expression": "embeddings",
- "isExpression": false,
- "asc": true,
- "nulls": "last",
- "opclass": "vector_cosine_ops"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "hnsw",
- "with": {}
- }
- },
- "foreignKeys": {
- "chunks_document_id_documents_id_fk": {
- "name": "chunks_document_id_documents_id_fk",
- "tableFrom": "chunks",
- "tableTo": "documents",
- "columnsFrom": [
- "document_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.content_to_space": {
- "name": "content_to_space",
- "schema": "",
- "columns": {
- "content_id": {
- "name": "content_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "content_id_space_id_unique": {
- "name": "content_id_space_id_unique",
- "columns": [
- {
- "expression": "content_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "content_to_space_content_id_documents_id_fk": {
- "name": "content_to_space_content_id_documents_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "documents",
- "columnsFrom": [
- "content_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "content_to_space_space_id_spaces_id_fk": {
- "name": "content_to_space_space_id_spaces_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.document_type": {
- "name": "document_type",
- "schema": "",
- "columns": {
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.documents": {
- "name": "documents",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "title": {
- "name": "title",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "description": {
- "name": "description",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "og_image": {
- "name": "og_image",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "raw": {
- "name": "raw",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "content": {
- "name": "content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "is_successfully_processed": {
- "name": "is_successfully_processed",
- "type": "boolean",
- "primaryKey": false,
- "notNull": false,
- "default": false
- },
- "error_message": {
- "name": "error_message",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "document_id_idx": {
- "name": "document_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_uuid_idx": {
- "name": "document_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_type_idx": {
- "name": "document_type_idx",
- "columns": [
- {
- "expression": "type",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_raw_user_idx": {
- "name": "document_raw_user_idx",
- "columns": [
- {
- "expression": "raw",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "documents_type_document_type_type_fk": {
- "name": "documents_type_document_type_type_fk",
- "tableFrom": "documents",
- "tableTo": "document_type",
- "columnsFrom": [
- "type"
- ],
- "columnsTo": [
- "type"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- },
- "documents_user_id_users_id_fk": {
- "name": "documents_user_id_users_id_fk",
- "tableFrom": "documents",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "documents_uuid_unique": {
- "name": "documents_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.job": {
- "name": "job",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "attempts": {
- "name": "attempts",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "lastAttemptAt": {
- "name": "lastAttemptAt",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "error": {
- "name": "error",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "user_id_url_idx": {
- "name": "user_id_url_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "job_user_id_users_id_fk": {
- "name": "job_user_id_users_id_fk",
- "tableFrom": "job",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.saved_spaces": {
- "name": "saved_spaces",
- "schema": "",
- "columns": {
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "saved_at": {
- "name": "saved_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "saved_spaces_user_space_idx": {
- "name": "saved_spaces_user_space_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "saved_spaces_user_id_users_id_fk": {
- "name": "saved_spaces_user_id_users_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "saved_spaces_space_id_spaces_id_fk": {
- "name": "saved_spaces_space_id_spaces_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access": {
- "name": "space_access",
- "schema": "",
- "columns": {
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
- },
- "user_email": {
- "name": "user_email",
- "type": "varchar(512)",
- "primaryKey": false,
- "notNull": false
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "access_type": {
- "name": "access_type",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'read'"
- }
- },
- "indexes": {
- "space_id_user_email_idx": {
- "name": "space_id_user_email_idx",
- "columns": [
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_access_space_id_spaces_id_fk": {
- "name": "space_access_space_id_spaces_id_fk",
- "tableFrom": "space_access",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "space_access_status_space_access_status_status_fk": {
- "name": "space_access_status_space_access_status_status_fk",
- "tableFrom": "space_access",
- "tableTo": "space_access_status",
- "columnsFrom": [
- "status"
- ],
- "columnsTo": [
- "status"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access_status": {
- "name": "space_access_status",
- "schema": "",
- "columns": {
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_members": {
- "name": "space_members",
- "schema": "",
- "columns": {
- "spaceId": {
- "name": "spaceId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "space_members_space_user_idx": {
- "name": "space_members_space_user_idx",
- "columns": [
- {
- "expression": "spaceId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_members_spaceId_users_id_fk": {
- "name": "space_members_spaceId_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "spaceId"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- },
- "space_members_user_id_users_id_fk": {
- "name": "space_members_user_id_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.spaces": {
- "name": "spaces",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "name": {
- "name": "name",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "ownerId": {
- "name": "ownerId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "is_public": {
- "name": "is_public",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "spaces_id_idx": {
- "name": "spaces_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_owner_id_idx": {
- "name": "spaces_owner_id_idx",
- "columns": [
- {
- "expression": "ownerId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_name_idx": {
- "name": "spaces_name_idx",
- "columns": [
- {
- "expression": "name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "spaces_uuid_unique": {
- "name": "spaces_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.users": {
- "name": "users",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "email": {
- "name": "email",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "first_name": {
- "name": "first_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "last_name": {
- "name": "last_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- },
- "profile_picture_url": {
- "name": "profile_picture_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "telegram_id": {
- "name": "telegram_id",
- "type": "varchar(255)",
- "primaryKey": false,
- "notNull": false
- },
- "has_onboarded": {
- "name": "has_onboarded",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "users_id_idx": {
- "name": "users_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_uuid_idx": {
- "name": "users_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_email_idx": {
- "name": "users_email_idx",
- "columns": [
- {
- "expression": "email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_name_idx": {
- "name": "users_name_idx",
- "columns": [
- {
- "expression": "first_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "last_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_created_at_idx": {
- "name": "users_created_at_idx",
- "columns": [
- {
- "expression": "created_at",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_telegram_id_idx": {
- "name": "users_telegram_id_idx",
- "columns": [
- {
- "expression": "telegram_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "users_uuid_unique": {
- "name": "users_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- },
- "users_email_unique": {
- "name": "users_email_unique",
- "nullsNotDistinct": false,
- "columns": [
- "email"
- ]
- }
- }
- },
- "public.waitlist": {
- "name": "waitlist",
- "schema": "",
- "columns": {
- "email": {
- "name": "email",
- "type": "varchar(512)",
- "primaryKey": true,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- }
- },
- "enums": {},
- "schemas": {},
- "sequences": {},
- "_meta": {
- "columns": {},
- "schemas": {},
- "tables": {}
- }
-}
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/0012_snapshot.json b/apps/backend/drizzle/meta/0012_snapshot.json
deleted file mode 100644
index 829368fe..00000000
--- a/apps/backend/drizzle/meta/0012_snapshot.json
+++ /dev/null
@@ -1,1188 +0,0 @@
-{
- "id": "15bb0365-73b0-4c03-9aa8-6249e89a4afd",
- "prevId": "e8a080b4-de5d-4015-945e-7bf5f461f16f",
- "version": "7",
- "dialect": "postgresql",
- "tables": {
- "public.chat_threads": {
- "name": "chat_threads",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "firstMessage": {
- "name": "firstMessage",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "messages": {
- "name": "messages",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chat_threads_user_idx": {
- "name": "chat_threads_user_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "chat_threads_user_id_users_id_fk": {
- "name": "chat_threads_user_id_users_id_fk",
- "tableFrom": "chat_threads",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "chat_threads_uuid_unique": {
- "name": "chat_threads_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.chunks": {
- "name": "chunks",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "document_id": {
- "name": "document_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "text_content": {
- "name": "text_content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "order_in_document": {
- "name": "order_in_document",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "embeddings": {
- "name": "embeddings",
- "type": "vector(1536)",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chunk_id_idx": {
- "name": "chunk_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "chunk_document_id_idx": {
- "name": "chunk_document_id_idx",
- "columns": [
- {
- "expression": "document_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "embeddingIndex": {
- "name": "embeddingIndex",
- "columns": [
- {
- "expression": "embeddings",
- "isExpression": false,
- "asc": true,
- "nulls": "last",
- "opclass": "vector_cosine_ops"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "hnsw",
- "with": {}
- }
- },
- "foreignKeys": {
- "chunks_document_id_documents_id_fk": {
- "name": "chunks_document_id_documents_id_fk",
- "tableFrom": "chunks",
- "tableTo": "documents",
- "columnsFrom": [
- "document_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.content_to_space": {
- "name": "content_to_space",
- "schema": "",
- "columns": {
- "content_id": {
- "name": "content_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "content_id_space_id_unique": {
- "name": "content_id_space_id_unique",
- "columns": [
- {
- "expression": "content_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "content_to_space_content_id_documents_id_fk": {
- "name": "content_to_space_content_id_documents_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "documents",
- "columnsFrom": [
- "content_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "content_to_space_space_id_spaces_id_fk": {
- "name": "content_to_space_space_id_spaces_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.document_type": {
- "name": "document_type",
- "schema": "",
- "columns": {
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.documents": {
- "name": "documents",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "title": {
- "name": "title",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "description": {
- "name": "description",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "og_image": {
- "name": "og_image",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "raw": {
- "name": "raw",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "content": {
- "name": "content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "is_successfully_processed": {
- "name": "is_successfully_processed",
- "type": "boolean",
- "primaryKey": false,
- "notNull": false,
- "default": false
- },
- "error_message": {
- "name": "error_message",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "document_id_idx": {
- "name": "document_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_uuid_idx": {
- "name": "document_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_type_idx": {
- "name": "document_type_idx",
- "columns": [
- {
- "expression": "type",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_raw_user_idx": {
- "name": "document_raw_user_idx",
- "columns": [
- {
- "expression": "raw",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "documents_type_document_type_type_fk": {
- "name": "documents_type_document_type_type_fk",
- "tableFrom": "documents",
- "tableTo": "document_type",
- "columnsFrom": [
- "type"
- ],
- "columnsTo": [
- "type"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- },
- "documents_user_id_users_id_fk": {
- "name": "documents_user_id_users_id_fk",
- "tableFrom": "documents",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "documents_uuid_unique": {
- "name": "documents_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.job": {
- "name": "job",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "attempts": {
- "name": "attempts",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "lastAttemptAt": {
- "name": "lastAttemptAt",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "error": {
- "name": "error",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "user_id_url_idx": {
- "name": "user_id_url_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "job_user_id_users_id_fk": {
- "name": "job_user_id_users_id_fk",
- "tableFrom": "job",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.saved_spaces": {
- "name": "saved_spaces",
- "schema": "",
- "columns": {
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "saved_at": {
- "name": "saved_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "saved_spaces_user_space_idx": {
- "name": "saved_spaces_user_space_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "saved_spaces_user_id_users_id_fk": {
- "name": "saved_spaces_user_id_users_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "saved_spaces_space_id_spaces_id_fk": {
- "name": "saved_spaces_space_id_spaces_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access": {
- "name": "space_access",
- "schema": "",
- "columns": {
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
- },
- "user_email": {
- "name": "user_email",
- "type": "varchar(512)",
- "primaryKey": false,
- "notNull": false
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "access_type": {
- "name": "access_type",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'read'"
- }
- },
- "indexes": {
- "space_id_user_email_idx": {
- "name": "space_id_user_email_idx",
- "columns": [
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_access_space_id_spaces_id_fk": {
- "name": "space_access_space_id_spaces_id_fk",
- "tableFrom": "space_access",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "space_access_status_space_access_status_status_fk": {
- "name": "space_access_status_space_access_status_status_fk",
- "tableFrom": "space_access",
- "tableTo": "space_access_status",
- "columnsFrom": [
- "status"
- ],
- "columnsTo": [
- "status"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access_status": {
- "name": "space_access_status",
- "schema": "",
- "columns": {
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_members": {
- "name": "space_members",
- "schema": "",
- "columns": {
- "spaceId": {
- "name": "spaceId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "space_members_space_user_idx": {
- "name": "space_members_space_user_idx",
- "columns": [
- {
- "expression": "spaceId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_members_spaceId_users_id_fk": {
- "name": "space_members_spaceId_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "spaceId"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- },
- "space_members_user_id_users_id_fk": {
- "name": "space_members_user_id_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.spaces": {
- "name": "spaces",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "name": {
- "name": "name",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "ownerId": {
- "name": "ownerId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "is_public": {
- "name": "is_public",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "spaces_id_idx": {
- "name": "spaces_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_owner_id_idx": {
- "name": "spaces_owner_id_idx",
- "columns": [
- {
- "expression": "ownerId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_name_idx": {
- "name": "spaces_name_idx",
- "columns": [
- {
- "expression": "name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "spaces_uuid_unique": {
- "name": "spaces_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.users": {
- "name": "users",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "email": {
- "name": "email",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "first_name": {
- "name": "first_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "last_name": {
- "name": "last_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- },
- "profile_picture_url": {
- "name": "profile_picture_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "telegram_id": {
- "name": "telegram_id",
- "type": "varchar(255)",
- "primaryKey": false,
- "notNull": false
- },
- "has_onboarded": {
- "name": "has_onboarded",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "last_api_key_generated_at": {
- "name": "last_api_key_generated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": false,
- "default": "now()"
- }
- },
- "indexes": {
- "users_id_idx": {
- "name": "users_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_uuid_idx": {
- "name": "users_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_email_idx": {
- "name": "users_email_idx",
- "columns": [
- {
- "expression": "email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_name_idx": {
- "name": "users_name_idx",
- "columns": [
- {
- "expression": "first_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "last_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_created_at_idx": {
- "name": "users_created_at_idx",
- "columns": [
- {
- "expression": "created_at",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_telegram_id_idx": {
- "name": "users_telegram_id_idx",
- "columns": [
- {
- "expression": "telegram_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "users_uuid_unique": {
- "name": "users_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- },
- "users_email_unique": {
- "name": "users_email_unique",
- "nullsNotDistinct": false,
- "columns": [
- "email"
- ]
- }
- }
- },
- "public.waitlist": {
- "name": "waitlist",
- "schema": "",
- "columns": {
- "email": {
- "name": "email",
- "type": "varchar(512)",
- "primaryKey": true,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- }
- },
- "enums": {},
- "schemas": {},
- "sequences": {},
- "_meta": {
- "columns": {},
- "schemas": {},
- "tables": {}
- }
-}
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/0013_snapshot.json b/apps/backend/drizzle/meta/0013_snapshot.json
deleted file mode 100644
index 686ad86a..00000000
--- a/apps/backend/drizzle/meta/0013_snapshot.json
+++ /dev/null
@@ -1,1194 +0,0 @@
-{
- "id": "8204e351-f30b-41a5-b071-c50bad426920",
- "prevId": "15bb0365-73b0-4c03-9aa8-6249e89a4afd",
- "version": "7",
- "dialect": "postgresql",
- "tables": {
- "public.chat_threads": {
- "name": "chat_threads",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "firstMessage": {
- "name": "firstMessage",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "messages": {
- "name": "messages",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chat_threads_user_idx": {
- "name": "chat_threads_user_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "chat_threads_user_id_users_id_fk": {
- "name": "chat_threads_user_id_users_id_fk",
- "tableFrom": "chat_threads",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "chat_threads_uuid_unique": {
- "name": "chat_threads_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.chunks": {
- "name": "chunks",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "document_id": {
- "name": "document_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "text_content": {
- "name": "text_content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "order_in_document": {
- "name": "order_in_document",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "embeddings": {
- "name": "embeddings",
- "type": "vector(1536)",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chunk_id_idx": {
- "name": "chunk_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "chunk_document_id_idx": {
- "name": "chunk_document_id_idx",
- "columns": [
- {
- "expression": "document_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "embeddingIndex": {
- "name": "embeddingIndex",
- "columns": [
- {
- "expression": "embeddings",
- "isExpression": false,
- "asc": true,
- "nulls": "last",
- "opclass": "vector_cosine_ops"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "hnsw",
- "with": {}
- }
- },
- "foreignKeys": {
- "chunks_document_id_documents_id_fk": {
- "name": "chunks_document_id_documents_id_fk",
- "tableFrom": "chunks",
- "tableTo": "documents",
- "columnsFrom": [
- "document_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.content_to_space": {
- "name": "content_to_space",
- "schema": "",
- "columns": {
- "content_id": {
- "name": "content_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "content_id_space_id_unique": {
- "name": "content_id_space_id_unique",
- "columns": [
- {
- "expression": "content_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "content_to_space_content_id_documents_id_fk": {
- "name": "content_to_space_content_id_documents_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "documents",
- "columnsFrom": [
- "content_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "content_to_space_space_id_spaces_id_fk": {
- "name": "content_to_space_space_id_spaces_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.document_type": {
- "name": "document_type",
- "schema": "",
- "columns": {
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.documents": {
- "name": "documents",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "title": {
- "name": "title",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "description": {
- "name": "description",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "og_image": {
- "name": "og_image",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "raw": {
- "name": "raw",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "content": {
- "name": "content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "is_successfully_processed": {
- "name": "is_successfully_processed",
- "type": "boolean",
- "primaryKey": false,
- "notNull": false,
- "default": false
- },
- "error_message": {
- "name": "error_message",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "content_hash": {
- "name": "content_hash",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "document_id_idx": {
- "name": "document_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_uuid_idx": {
- "name": "document_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_type_idx": {
- "name": "document_type_idx",
- "columns": [
- {
- "expression": "type",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_raw_user_idx": {
- "name": "document_raw_user_idx",
- "columns": [
- {
- "expression": "raw",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "documents_type_document_type_type_fk": {
- "name": "documents_type_document_type_type_fk",
- "tableFrom": "documents",
- "tableTo": "document_type",
- "columnsFrom": [
- "type"
- ],
- "columnsTo": [
- "type"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- },
- "documents_user_id_users_id_fk": {
- "name": "documents_user_id_users_id_fk",
- "tableFrom": "documents",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "documents_uuid_unique": {
- "name": "documents_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.job": {
- "name": "job",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "attempts": {
- "name": "attempts",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "lastAttemptAt": {
- "name": "lastAttemptAt",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "error": {
- "name": "error",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "user_id_url_idx": {
- "name": "user_id_url_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "job_user_id_users_id_fk": {
- "name": "job_user_id_users_id_fk",
- "tableFrom": "job",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.saved_spaces": {
- "name": "saved_spaces",
- "schema": "",
- "columns": {
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "saved_at": {
- "name": "saved_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "saved_spaces_user_space_idx": {
- "name": "saved_spaces_user_space_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "saved_spaces_user_id_users_id_fk": {
- "name": "saved_spaces_user_id_users_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "saved_spaces_space_id_spaces_id_fk": {
- "name": "saved_spaces_space_id_spaces_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access": {
- "name": "space_access",
- "schema": "",
- "columns": {
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
- },
- "user_email": {
- "name": "user_email",
- "type": "varchar(512)",
- "primaryKey": false,
- "notNull": false
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "access_type": {
- "name": "access_type",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'read'"
- }
- },
- "indexes": {
- "space_id_user_email_idx": {
- "name": "space_id_user_email_idx",
- "columns": [
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_access_space_id_spaces_id_fk": {
- "name": "space_access_space_id_spaces_id_fk",
- "tableFrom": "space_access",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "space_access_status_space_access_status_status_fk": {
- "name": "space_access_status_space_access_status_status_fk",
- "tableFrom": "space_access",
- "tableTo": "space_access_status",
- "columnsFrom": [
- "status"
- ],
- "columnsTo": [
- "status"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access_status": {
- "name": "space_access_status",
- "schema": "",
- "columns": {
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_members": {
- "name": "space_members",
- "schema": "",
- "columns": {
- "spaceId": {
- "name": "spaceId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "space_members_space_user_idx": {
- "name": "space_members_space_user_idx",
- "columns": [
- {
- "expression": "spaceId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_members_spaceId_users_id_fk": {
- "name": "space_members_spaceId_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "spaceId"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- },
- "space_members_user_id_users_id_fk": {
- "name": "space_members_user_id_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.spaces": {
- "name": "spaces",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "name": {
- "name": "name",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "ownerId": {
- "name": "ownerId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "is_public": {
- "name": "is_public",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "spaces_id_idx": {
- "name": "spaces_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_owner_id_idx": {
- "name": "spaces_owner_id_idx",
- "columns": [
- {
- "expression": "ownerId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_name_idx": {
- "name": "spaces_name_idx",
- "columns": [
- {
- "expression": "name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "spaces_uuid_unique": {
- "name": "spaces_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.users": {
- "name": "users",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "email": {
- "name": "email",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "first_name": {
- "name": "first_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "last_name": {
- "name": "last_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- },
- "profile_picture_url": {
- "name": "profile_picture_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "telegram_id": {
- "name": "telegram_id",
- "type": "varchar(255)",
- "primaryKey": false,
- "notNull": false
- },
- "has_onboarded": {
- "name": "has_onboarded",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "last_api_key_generated_at": {
- "name": "last_api_key_generated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": false,
- "default": "now()"
- }
- },
- "indexes": {
- "users_id_idx": {
- "name": "users_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_uuid_idx": {
- "name": "users_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_email_idx": {
- "name": "users_email_idx",
- "columns": [
- {
- "expression": "email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_name_idx": {
- "name": "users_name_idx",
- "columns": [
- {
- "expression": "first_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "last_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_created_at_idx": {
- "name": "users_created_at_idx",
- "columns": [
- {
- "expression": "created_at",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_telegram_id_idx": {
- "name": "users_telegram_id_idx",
- "columns": [
- {
- "expression": "telegram_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "users_uuid_unique": {
- "name": "users_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- },
- "users_email_unique": {
- "name": "users_email_unique",
- "nullsNotDistinct": false,
- "columns": [
- "email"
- ]
- }
- }
- },
- "public.waitlist": {
- "name": "waitlist",
- "schema": "",
- "columns": {
- "email": {
- "name": "email",
- "type": "varchar(512)",
- "primaryKey": true,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- }
- },
- "enums": {},
- "schemas": {},
- "sequences": {},
- "_meta": {
- "columns": {},
- "schemas": {},
- "tables": {}
- }
-}
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/0014_snapshot.json b/apps/backend/drizzle/meta/0014_snapshot.json
deleted file mode 100644
index 6391612e..00000000
--- a/apps/backend/drizzle/meta/0014_snapshot.json
+++ /dev/null
@@ -1,1207 +0,0 @@
-{
- "id": "f5cef50a-50ec-4b49-99c2-4da3a0f6a098",
- "prevId": "8204e351-f30b-41a5-b071-c50bad426920",
- "version": "7",
- "dialect": "postgresql",
- "tables": {
- "public.chat_threads": {
- "name": "chat_threads",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "firstMessage": {
- "name": "firstMessage",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "messages": {
- "name": "messages",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chat_threads_user_idx": {
- "name": "chat_threads_user_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "chat_threads_user_id_users_id_fk": {
- "name": "chat_threads_user_id_users_id_fk",
- "tableFrom": "chat_threads",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "chat_threads_uuid_unique": {
- "name": "chat_threads_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.chunks": {
- "name": "chunks",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "document_id": {
- "name": "document_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "text_content": {
- "name": "text_content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "order_in_document": {
- "name": "order_in_document",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "embeddings": {
- "name": "embeddings",
- "type": "vector(1536)",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chunk_id_idx": {
- "name": "chunk_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "chunk_document_id_idx": {
- "name": "chunk_document_id_idx",
- "columns": [
- {
- "expression": "document_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "embeddingIndex": {
- "name": "embeddingIndex",
- "columns": [
- {
- "expression": "embeddings",
- "isExpression": false,
- "asc": true,
- "nulls": "last",
- "opclass": "vector_cosine_ops"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "hnsw",
- "with": {}
- }
- },
- "foreignKeys": {
- "chunks_document_id_documents_id_fk": {
- "name": "chunks_document_id_documents_id_fk",
- "tableFrom": "chunks",
- "tableTo": "documents",
- "columnsFrom": [
- "document_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.content_to_space": {
- "name": "content_to_space",
- "schema": "",
- "columns": {
- "content_id": {
- "name": "content_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "content_id_space_id_unique": {
- "name": "content_id_space_id_unique",
- "columns": [
- {
- "expression": "content_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "content_to_space_content_id_documents_id_fk": {
- "name": "content_to_space_content_id_documents_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "documents",
- "columnsFrom": [
- "content_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "content_to_space_space_id_spaces_id_fk": {
- "name": "content_to_space_space_id_spaces_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.document_type": {
- "name": "document_type",
- "schema": "",
- "columns": {
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.documents": {
- "name": "documents",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "title": {
- "name": "title",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "description": {
- "name": "description",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "og_image": {
- "name": "og_image",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "raw": {
- "name": "raw",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "content": {
- "name": "content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "is_successfully_processed": {
- "name": "is_successfully_processed",
- "type": "boolean",
- "primaryKey": false,
- "notNull": false,
- "default": false
- },
- "error_message": {
- "name": "error_message",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "content_hash": {
- "name": "content_hash",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "document_id_idx": {
- "name": "document_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_uuid_idx": {
- "name": "document_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_type_idx": {
- "name": "document_type_idx",
- "columns": [
- {
- "expression": "type",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_raw_user_idx": {
- "name": "document_raw_user_idx",
- "columns": [
- {
- "expression": "raw",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "documents_type_document_type_type_fk": {
- "name": "documents_type_document_type_type_fk",
- "tableFrom": "documents",
- "tableTo": "document_type",
- "columnsFrom": [
- "type"
- ],
- "columnsTo": [
- "type"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- },
- "documents_user_id_users_id_fk": {
- "name": "documents_user_id_users_id_fk",
- "tableFrom": "documents",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "documents_uuid_unique": {
- "name": "documents_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.job": {
- "name": "job",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "attempts": {
- "name": "attempts",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "lastAttemptAt": {
- "name": "lastAttemptAt",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "error": {
- "name": "error",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "user_id_url_idx": {
- "name": "user_id_url_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "job_user_id_users_id_fk": {
- "name": "job_user_id_users_id_fk",
- "tableFrom": "job",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.saved_spaces": {
- "name": "saved_spaces",
- "schema": "",
- "columns": {
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "saved_at": {
- "name": "saved_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "saved_spaces_user_space_idx": {
- "name": "saved_spaces_user_space_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "saved_spaces_user_id_users_id_fk": {
- "name": "saved_spaces_user_id_users_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "saved_spaces_space_id_spaces_id_fk": {
- "name": "saved_spaces_space_id_spaces_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access": {
- "name": "space_access",
- "schema": "",
- "columns": {
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
- },
- "user_email": {
- "name": "user_email",
- "type": "varchar(512)",
- "primaryKey": false,
- "notNull": false
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "access_type": {
- "name": "access_type",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'read'"
- }
- },
- "indexes": {
- "space_id_user_email_idx": {
- "name": "space_id_user_email_idx",
- "columns": [
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_access_space_id_spaces_id_fk": {
- "name": "space_access_space_id_spaces_id_fk",
- "tableFrom": "space_access",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "space_access_status_space_access_status_status_fk": {
- "name": "space_access_status_space_access_status_status_fk",
- "tableFrom": "space_access",
- "tableTo": "space_access_status",
- "columnsFrom": [
- "status"
- ],
- "columnsTo": [
- "status"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access_status": {
- "name": "space_access_status",
- "schema": "",
- "columns": {
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_members": {
- "name": "space_members",
- "schema": "",
- "columns": {
- "spaceId": {
- "name": "spaceId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "space_members_space_user_idx": {
- "name": "space_members_space_user_idx",
- "columns": [
- {
- "expression": "spaceId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_members_spaceId_users_id_fk": {
- "name": "space_members_spaceId_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "spaceId"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- },
- "space_members_user_id_users_id_fk": {
- "name": "space_members_user_id_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.spaces": {
- "name": "spaces",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "name": {
- "name": "name",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "ownerId": {
- "name": "ownerId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "is_public": {
- "name": "is_public",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "spaces_id_idx": {
- "name": "spaces_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_owner_id_idx": {
- "name": "spaces_owner_id_idx",
- "columns": [
- {
- "expression": "ownerId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_name_idx": {
- "name": "spaces_name_idx",
- "columns": [
- {
- "expression": "name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "spaces_uuid_unique": {
- "name": "spaces_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.users": {
- "name": "users",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "email": {
- "name": "email",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "first_name": {
- "name": "first_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "last_name": {
- "name": "last_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- },
- "profile_picture_url": {
- "name": "profile_picture_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "telegram_id": {
- "name": "telegram_id",
- "type": "varchar(255)",
- "primaryKey": false,
- "notNull": false
- },
- "has_onboarded": {
- "name": "has_onboarded",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "last_api_key_generated_at": {
- "name": "last_api_key_generated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": false,
- "default": "now()"
- },
- "stripe_customer_id": {
- "name": "stripe_customer_id",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "tier": {
- "name": "tier",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'free'"
- }
- },
- "indexes": {
- "users_id_idx": {
- "name": "users_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_uuid_idx": {
- "name": "users_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_email_idx": {
- "name": "users_email_idx",
- "columns": [
- {
- "expression": "email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_name_idx": {
- "name": "users_name_idx",
- "columns": [
- {
- "expression": "first_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "last_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_created_at_idx": {
- "name": "users_created_at_idx",
- "columns": [
- {
- "expression": "created_at",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_telegram_id_idx": {
- "name": "users_telegram_id_idx",
- "columns": [
- {
- "expression": "telegram_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "users_uuid_unique": {
- "name": "users_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- },
- "users_email_unique": {
- "name": "users_email_unique",
- "nullsNotDistinct": false,
- "columns": [
- "email"
- ]
- }
- }
- },
- "public.waitlist": {
- "name": "waitlist",
- "schema": "",
- "columns": {
- "email": {
- "name": "email",
- "type": "varchar(512)",
- "primaryKey": true,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- }
- },
- "enums": {},
- "schemas": {},
- "sequences": {},
- "_meta": {
- "columns": {},
- "schemas": {},
- "tables": {}
- }
-}
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/0015_snapshot.json b/apps/backend/drizzle/meta/0015_snapshot.json
deleted file mode 100644
index d19dbfbb..00000000
--- a/apps/backend/drizzle/meta/0015_snapshot.json
+++ /dev/null
@@ -1,1207 +0,0 @@
-{
- "id": "8529db1b-2d33-49e0-a413-f517eae7e4e4",
- "prevId": "f5cef50a-50ec-4b49-99c2-4da3a0f6a098",
- "version": "7",
- "dialect": "postgresql",
- "tables": {
- "public.chat_threads": {
- "name": "chat_threads",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "firstMessage": {
- "name": "firstMessage",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "messages": {
- "name": "messages",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chat_threads_user_idx": {
- "name": "chat_threads_user_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "chat_threads_user_id_users_id_fk": {
- "name": "chat_threads_user_id_users_id_fk",
- "tableFrom": "chat_threads",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "chat_threads_uuid_unique": {
- "name": "chat_threads_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.chunks": {
- "name": "chunks",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "document_id": {
- "name": "document_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "text_content": {
- "name": "text_content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "order_in_document": {
- "name": "order_in_document",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "embeddings": {
- "name": "embeddings",
- "type": "vector(7)",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chunk_id_idx": {
- "name": "chunk_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "chunk_document_id_idx": {
- "name": "chunk_document_id_idx",
- "columns": [
- {
- "expression": "document_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "embeddingIndex": {
- "name": "embeddingIndex",
- "columns": [
- {
- "expression": "embeddings",
- "isExpression": false,
- "asc": true,
- "nulls": "last",
- "opclass": "vector_cosine_ops"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "hnsw",
- "with": {}
- }
- },
- "foreignKeys": {
- "chunks_document_id_documents_id_fk": {
- "name": "chunks_document_id_documents_id_fk",
- "tableFrom": "chunks",
- "tableTo": "documents",
- "columnsFrom": [
- "document_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.content_to_space": {
- "name": "content_to_space",
- "schema": "",
- "columns": {
- "content_id": {
- "name": "content_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "content_id_space_id_unique": {
- "name": "content_id_space_id_unique",
- "columns": [
- {
- "expression": "content_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "content_to_space_content_id_documents_id_fk": {
- "name": "content_to_space_content_id_documents_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "documents",
- "columnsFrom": [
- "content_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "content_to_space_space_id_spaces_id_fk": {
- "name": "content_to_space_space_id_spaces_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.document_type": {
- "name": "document_type",
- "schema": "",
- "columns": {
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.documents": {
- "name": "documents",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "title": {
- "name": "title",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "description": {
- "name": "description",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "og_image": {
- "name": "og_image",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "raw": {
- "name": "raw",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "content": {
- "name": "content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "is_successfully_processed": {
- "name": "is_successfully_processed",
- "type": "boolean",
- "primaryKey": false,
- "notNull": false,
- "default": false
- },
- "error_message": {
- "name": "error_message",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "content_hash": {
- "name": "content_hash",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "document_id_idx": {
- "name": "document_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_uuid_idx": {
- "name": "document_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_type_idx": {
- "name": "document_type_idx",
- "columns": [
- {
- "expression": "type",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_raw_user_idx": {
- "name": "document_raw_user_idx",
- "columns": [
- {
- "expression": "raw",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "documents_type_document_type_type_fk": {
- "name": "documents_type_document_type_type_fk",
- "tableFrom": "documents",
- "tableTo": "document_type",
- "columnsFrom": [
- "type"
- ],
- "columnsTo": [
- "type"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- },
- "documents_user_id_users_id_fk": {
- "name": "documents_user_id_users_id_fk",
- "tableFrom": "documents",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "documents_uuid_unique": {
- "name": "documents_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.job": {
- "name": "job",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "attempts": {
- "name": "attempts",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "lastAttemptAt": {
- "name": "lastAttemptAt",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "error": {
- "name": "error",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "user_id_url_idx": {
- "name": "user_id_url_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "job_user_id_users_id_fk": {
- "name": "job_user_id_users_id_fk",
- "tableFrom": "job",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.saved_spaces": {
- "name": "saved_spaces",
- "schema": "",
- "columns": {
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "saved_at": {
- "name": "saved_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "saved_spaces_user_space_idx": {
- "name": "saved_spaces_user_space_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "saved_spaces_user_id_users_id_fk": {
- "name": "saved_spaces_user_id_users_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "saved_spaces_space_id_spaces_id_fk": {
- "name": "saved_spaces_space_id_spaces_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access": {
- "name": "space_access",
- "schema": "",
- "columns": {
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
- },
- "user_email": {
- "name": "user_email",
- "type": "varchar(512)",
- "primaryKey": false,
- "notNull": false
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "access_type": {
- "name": "access_type",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'read'"
- }
- },
- "indexes": {
- "space_id_user_email_idx": {
- "name": "space_id_user_email_idx",
- "columns": [
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_access_space_id_spaces_id_fk": {
- "name": "space_access_space_id_spaces_id_fk",
- "tableFrom": "space_access",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "space_access_status_space_access_status_status_fk": {
- "name": "space_access_status_space_access_status_status_fk",
- "tableFrom": "space_access",
- "tableTo": "space_access_status",
- "columnsFrom": [
- "status"
- ],
- "columnsTo": [
- "status"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access_status": {
- "name": "space_access_status",
- "schema": "",
- "columns": {
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_members": {
- "name": "space_members",
- "schema": "",
- "columns": {
- "spaceId": {
- "name": "spaceId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "space_members_space_user_idx": {
- "name": "space_members_space_user_idx",
- "columns": [
- {
- "expression": "spaceId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_members_spaceId_users_id_fk": {
- "name": "space_members_spaceId_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "spaceId"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- },
- "space_members_user_id_users_id_fk": {
- "name": "space_members_user_id_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.spaces": {
- "name": "spaces",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "name": {
- "name": "name",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "ownerId": {
- "name": "ownerId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "is_public": {
- "name": "is_public",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "spaces_id_idx": {
- "name": "spaces_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_owner_id_idx": {
- "name": "spaces_owner_id_idx",
- "columns": [
- {
- "expression": "ownerId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_name_idx": {
- "name": "spaces_name_idx",
- "columns": [
- {
- "expression": "name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "spaces_uuid_unique": {
- "name": "spaces_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.users": {
- "name": "users",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "email": {
- "name": "email",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "first_name": {
- "name": "first_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "last_name": {
- "name": "last_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- },
- "profile_picture_url": {
- "name": "profile_picture_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "telegram_id": {
- "name": "telegram_id",
- "type": "varchar(255)",
- "primaryKey": false,
- "notNull": false
- },
- "has_onboarded": {
- "name": "has_onboarded",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "last_api_key_generated_at": {
- "name": "last_api_key_generated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": false,
- "default": "now()"
- },
- "stripe_customer_id": {
- "name": "stripe_customer_id",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "tier": {
- "name": "tier",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'free'"
- }
- },
- "indexes": {
- "users_id_idx": {
- "name": "users_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_uuid_idx": {
- "name": "users_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_email_idx": {
- "name": "users_email_idx",
- "columns": [
- {
- "expression": "email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_name_idx": {
- "name": "users_name_idx",
- "columns": [
- {
- "expression": "first_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "last_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_created_at_idx": {
- "name": "users_created_at_idx",
- "columns": [
- {
- "expression": "created_at",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_telegram_id_idx": {
- "name": "users_telegram_id_idx",
- "columns": [
- {
- "expression": "telegram_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "users_uuid_unique": {
- "name": "users_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- },
- "users_email_unique": {
- "name": "users_email_unique",
- "nullsNotDistinct": false,
- "columns": [
- "email"
- ]
- }
- }
- },
- "public.waitlist": {
- "name": "waitlist",
- "schema": "",
- "columns": {
- "email": {
- "name": "email",
- "type": "varchar(512)",
- "primaryKey": true,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- }
- },
- "enums": {},
- "schemas": {},
- "sequences": {},
- "_meta": {
- "columns": {},
- "schemas": {},
- "tables": {}
- }
-}
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/0016_snapshot.json b/apps/backend/drizzle/meta/0016_snapshot.json
deleted file mode 100644
index 2020c691..00000000
--- a/apps/backend/drizzle/meta/0016_snapshot.json
+++ /dev/null
@@ -1,1222 +0,0 @@
-{
- "id": "23a39e70-a9c2-44cd-a3fb-22b19efef79e",
- "prevId": "8529db1b-2d33-49e0-a413-f517eae7e4e4",
- "version": "7",
- "dialect": "postgresql",
- "tables": {
- "public.chat_threads": {
- "name": "chat_threads",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "firstMessage": {
- "name": "firstMessage",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "messages": {
- "name": "messages",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chat_threads_user_idx": {
- "name": "chat_threads_user_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "chat_threads_user_id_users_id_fk": {
- "name": "chat_threads_user_id_users_id_fk",
- "tableFrom": "chat_threads",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "chat_threads_uuid_unique": {
- "name": "chat_threads_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.chunks": {
- "name": "chunks",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "document_id": {
- "name": "document_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "text_content": {
- "name": "text_content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "order_in_document": {
- "name": "order_in_document",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "embeddings": {
- "name": "embeddings",
- "type": "vector(768)",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chunk_id_idx": {
- "name": "chunk_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "chunk_document_id_idx": {
- "name": "chunk_document_id_idx",
- "columns": [
- {
- "expression": "document_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "embeddingIndex": {
- "name": "embeddingIndex",
- "columns": [
- {
- "expression": "embeddings",
- "isExpression": false,
- "asc": true,
- "nulls": "last",
- "opclass": "vector_cosine_ops"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "hnsw",
- "with": {}
- }
- },
- "foreignKeys": {
- "chunks_document_id_documents_id_fk": {
- "name": "chunks_document_id_documents_id_fk",
- "tableFrom": "chunks",
- "tableTo": "documents",
- "columnsFrom": [
- "document_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.content_to_space": {
- "name": "content_to_space",
- "schema": "",
- "columns": {
- "content_id": {
- "name": "content_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "content_id_space_id_unique": {
- "name": "content_id_space_id_unique",
- "columns": [
- {
- "expression": "content_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "content_to_space_content_id_documents_id_fk": {
- "name": "content_to_space_content_id_documents_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "documents",
- "columnsFrom": [
- "content_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "content_to_space_space_id_spaces_id_fk": {
- "name": "content_to_space_space_id_spaces_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.document_type": {
- "name": "document_type",
- "schema": "",
- "columns": {
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.documents": {
- "name": "documents",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "title": {
- "name": "title",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "description": {
- "name": "description",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "og_image": {
- "name": "og_image",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "raw": {
- "name": "raw",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "content": {
- "name": "content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "is_successfully_processed": {
- "name": "is_successfully_processed",
- "type": "boolean",
- "primaryKey": false,
- "notNull": false,
- "default": false
- },
- "error_message": {
- "name": "error_message",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "content_hash": {
- "name": "content_hash",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "document_id_idx": {
- "name": "document_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_uuid_idx": {
- "name": "document_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_type_idx": {
- "name": "document_type_idx",
- "columns": [
- {
- "expression": "type",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_raw_user_idx": {
- "name": "document_raw_user_idx",
- "columns": [
- {
- "expression": "raw",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "documents_search_idx": {
- "name": "documents_search_idx",
- "columns": [
- {
- "expression": "(\n setweight(to_tsvector('english', coalesce(\"content\", '')),'A') ||\n setweight(to_tsvector('english', coalesce(\"title\", '')),'B') ||\n setweight(to_tsvector('english', coalesce(\"description\", '')),'C') ||\n setweight(to_tsvector('english', coalesce(\"url\", '')),'D')\n )",
- "asc": true,
- "isExpression": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "gin",
- "with": {}
- }
- },
- "foreignKeys": {
- "documents_type_document_type_type_fk": {
- "name": "documents_type_document_type_type_fk",
- "tableFrom": "documents",
- "tableTo": "document_type",
- "columnsFrom": [
- "type"
- ],
- "columnsTo": [
- "type"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- },
- "documents_user_id_users_id_fk": {
- "name": "documents_user_id_users_id_fk",
- "tableFrom": "documents",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "documents_uuid_unique": {
- "name": "documents_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.job": {
- "name": "job",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "attempts": {
- "name": "attempts",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "lastAttemptAt": {
- "name": "lastAttemptAt",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "error": {
- "name": "error",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "user_id_url_idx": {
- "name": "user_id_url_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "job_user_id_users_id_fk": {
- "name": "job_user_id_users_id_fk",
- "tableFrom": "job",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.saved_spaces": {
- "name": "saved_spaces",
- "schema": "",
- "columns": {
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "saved_at": {
- "name": "saved_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "saved_spaces_user_space_idx": {
- "name": "saved_spaces_user_space_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "saved_spaces_user_id_users_id_fk": {
- "name": "saved_spaces_user_id_users_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "saved_spaces_space_id_spaces_id_fk": {
- "name": "saved_spaces_space_id_spaces_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access": {
- "name": "space_access",
- "schema": "",
- "columns": {
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
- },
- "user_email": {
- "name": "user_email",
- "type": "varchar(512)",
- "primaryKey": false,
- "notNull": false
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "access_type": {
- "name": "access_type",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'read'"
- }
- },
- "indexes": {
- "space_id_user_email_idx": {
- "name": "space_id_user_email_idx",
- "columns": [
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_access_space_id_spaces_id_fk": {
- "name": "space_access_space_id_spaces_id_fk",
- "tableFrom": "space_access",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "space_access_status_space_access_status_status_fk": {
- "name": "space_access_status_space_access_status_status_fk",
- "tableFrom": "space_access",
- "tableTo": "space_access_status",
- "columnsFrom": [
- "status"
- ],
- "columnsTo": [
- "status"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access_status": {
- "name": "space_access_status",
- "schema": "",
- "columns": {
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_members": {
- "name": "space_members",
- "schema": "",
- "columns": {
- "spaceId": {
- "name": "spaceId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "space_members_space_user_idx": {
- "name": "space_members_space_user_idx",
- "columns": [
- {
- "expression": "spaceId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_members_spaceId_users_id_fk": {
- "name": "space_members_spaceId_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "spaceId"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- },
- "space_members_user_id_users_id_fk": {
- "name": "space_members_user_id_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.spaces": {
- "name": "spaces",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "name": {
- "name": "name",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "ownerId": {
- "name": "ownerId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "is_public": {
- "name": "is_public",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "spaces_id_idx": {
- "name": "spaces_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_owner_id_idx": {
- "name": "spaces_owner_id_idx",
- "columns": [
- {
- "expression": "ownerId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_name_idx": {
- "name": "spaces_name_idx",
- "columns": [
- {
- "expression": "name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "spaces_uuid_unique": {
- "name": "spaces_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.users": {
- "name": "users",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "email": {
- "name": "email",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "first_name": {
- "name": "first_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "last_name": {
- "name": "last_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- },
- "profile_picture_url": {
- "name": "profile_picture_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "telegram_id": {
- "name": "telegram_id",
- "type": "varchar(255)",
- "primaryKey": false,
- "notNull": false
- },
- "has_onboarded": {
- "name": "has_onboarded",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "last_api_key_generated_at": {
- "name": "last_api_key_generated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": false,
- "default": "now()"
- },
- "stripe_customer_id": {
- "name": "stripe_customer_id",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "tier": {
- "name": "tier",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'free'"
- }
- },
- "indexes": {
- "users_id_idx": {
- "name": "users_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_uuid_idx": {
- "name": "users_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_email_idx": {
- "name": "users_email_idx",
- "columns": [
- {
- "expression": "email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_name_idx": {
- "name": "users_name_idx",
- "columns": [
- {
- "expression": "first_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "last_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_created_at_idx": {
- "name": "users_created_at_idx",
- "columns": [
- {
- "expression": "created_at",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_telegram_id_idx": {
- "name": "users_telegram_id_idx",
- "columns": [
- {
- "expression": "telegram_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "users_uuid_unique": {
- "name": "users_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- },
- "users_email_unique": {
- "name": "users_email_unique",
- "nullsNotDistinct": false,
- "columns": [
- "email"
- ]
- }
- }
- },
- "public.waitlist": {
- "name": "waitlist",
- "schema": "",
- "columns": {
- "email": {
- "name": "email",
- "type": "varchar(512)",
- "primaryKey": true,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- }
- },
- "enums": {},
- "schemas": {},
- "sequences": {},
- "_meta": {
- "columns": {},
- "schemas": {},
- "tables": {}
- }
-}
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/0017_snapshot.json b/apps/backend/drizzle/meta/0017_snapshot.json
deleted file mode 100644
index efd17477..00000000
--- a/apps/backend/drizzle/meta/0017_snapshot.json
+++ /dev/null
@@ -1,1222 +0,0 @@
-{
- "id": "f8d9da82-e3be-46a9-b52e-a70dc2d24505",
- "prevId": "23a39e70-a9c2-44cd-a3fb-22b19efef79e",
- "version": "7",
- "dialect": "postgresql",
- "tables": {
- "public.chat_threads": {
- "name": "chat_threads",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "firstMessage": {
- "name": "firstMessage",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "messages": {
- "name": "messages",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chat_threads_user_idx": {
- "name": "chat_threads_user_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "chat_threads_user_id_users_id_fk": {
- "name": "chat_threads_user_id_users_id_fk",
- "tableFrom": "chat_threads",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "chat_threads_uuid_unique": {
- "name": "chat_threads_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.chunks": {
- "name": "chunks",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "document_id": {
- "name": "document_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "text_content": {
- "name": "text_content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "order_in_document": {
- "name": "order_in_document",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "embeddings": {
- "name": "embeddings",
- "type": "vector(768)",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chunk_id_idx": {
- "name": "chunk_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "chunk_document_id_idx": {
- "name": "chunk_document_id_idx",
- "columns": [
- {
- "expression": "document_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "embeddingIndex": {
- "name": "embeddingIndex",
- "columns": [
- {
- "expression": "embeddings",
- "isExpression": false,
- "asc": true,
- "nulls": "last",
- "opclass": "vector_cosine_ops"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "hnsw",
- "with": {}
- }
- },
- "foreignKeys": {
- "chunks_document_id_documents_id_fk": {
- "name": "chunks_document_id_documents_id_fk",
- "tableFrom": "chunks",
- "tableTo": "documents",
- "columnsFrom": [
- "document_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.content_to_space": {
- "name": "content_to_space",
- "schema": "",
- "columns": {
- "content_id": {
- "name": "content_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "content_id_space_id_unique": {
- "name": "content_id_space_id_unique",
- "columns": [
- {
- "expression": "content_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "content_to_space_content_id_documents_id_fk": {
- "name": "content_to_space_content_id_documents_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "documents",
- "columnsFrom": [
- "content_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "content_to_space_space_id_spaces_id_fk": {
- "name": "content_to_space_space_id_spaces_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.document_type": {
- "name": "document_type",
- "schema": "",
- "columns": {
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.documents": {
- "name": "documents",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "title": {
- "name": "title",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "description": {
- "name": "description",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "og_image": {
- "name": "og_image",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "raw": {
- "name": "raw",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "content": {
- "name": "content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "is_successfully_processed": {
- "name": "is_successfully_processed",
- "type": "boolean",
- "primaryKey": false,
- "notNull": false,
- "default": false
- },
- "error_message": {
- "name": "error_message",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "content_hash": {
- "name": "content_hash",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "document_id_idx": {
- "name": "document_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_uuid_idx": {
- "name": "document_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_type_idx": {
- "name": "document_type_idx",
- "columns": [
- {
- "expression": "type",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_raw_user_idx": {
- "name": "document_raw_user_idx",
- "columns": [
- {
- "expression": "raw",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "documents_search_idx": {
- "name": "documents_search_idx",
- "columns": [
- {
- "expression": "(\n setweight(to_tsvector('english', coalesce(preprocess_for_text_search(\"content\"), '')),'A') ||\n setweight(to_tsvector('english', coalesce(preprocess_for_text_search(\"title\"), '')),'B') ||\n setweight(to_tsvector('english', coalesce(preprocess_for_text_search(\"description\"), '')),'C') ||\n setweight(to_tsvector('english', coalesce(preprocess_for_text_search(\"url\"), '')),'D')\n )",
- "asc": true,
- "isExpression": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "gin",
- "with": {}
- }
- },
- "foreignKeys": {
- "documents_type_document_type_type_fk": {
- "name": "documents_type_document_type_type_fk",
- "tableFrom": "documents",
- "tableTo": "document_type",
- "columnsFrom": [
- "type"
- ],
- "columnsTo": [
- "type"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- },
- "documents_user_id_users_id_fk": {
- "name": "documents_user_id_users_id_fk",
- "tableFrom": "documents",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "documents_uuid_unique": {
- "name": "documents_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.job": {
- "name": "job",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "attempts": {
- "name": "attempts",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "lastAttemptAt": {
- "name": "lastAttemptAt",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "error": {
- "name": "error",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "user_id_url_idx": {
- "name": "user_id_url_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "job_user_id_users_id_fk": {
- "name": "job_user_id_users_id_fk",
- "tableFrom": "job",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.saved_spaces": {
- "name": "saved_spaces",
- "schema": "",
- "columns": {
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "saved_at": {
- "name": "saved_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "saved_spaces_user_space_idx": {
- "name": "saved_spaces_user_space_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "saved_spaces_user_id_users_id_fk": {
- "name": "saved_spaces_user_id_users_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "saved_spaces_space_id_spaces_id_fk": {
- "name": "saved_spaces_space_id_spaces_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access": {
- "name": "space_access",
- "schema": "",
- "columns": {
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
- },
- "user_email": {
- "name": "user_email",
- "type": "varchar(512)",
- "primaryKey": false,
- "notNull": false
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "access_type": {
- "name": "access_type",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'read'"
- }
- },
- "indexes": {
- "space_id_user_email_idx": {
- "name": "space_id_user_email_idx",
- "columns": [
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_access_space_id_spaces_id_fk": {
- "name": "space_access_space_id_spaces_id_fk",
- "tableFrom": "space_access",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "space_access_status_space_access_status_status_fk": {
- "name": "space_access_status_space_access_status_status_fk",
- "tableFrom": "space_access",
- "tableTo": "space_access_status",
- "columnsFrom": [
- "status"
- ],
- "columnsTo": [
- "status"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access_status": {
- "name": "space_access_status",
- "schema": "",
- "columns": {
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_members": {
- "name": "space_members",
- "schema": "",
- "columns": {
- "spaceId": {
- "name": "spaceId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "space_members_space_user_idx": {
- "name": "space_members_space_user_idx",
- "columns": [
- {
- "expression": "spaceId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_members_spaceId_users_id_fk": {
- "name": "space_members_spaceId_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "spaceId"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- },
- "space_members_user_id_users_id_fk": {
- "name": "space_members_user_id_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.spaces": {
- "name": "spaces",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "name": {
- "name": "name",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "ownerId": {
- "name": "ownerId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "is_public": {
- "name": "is_public",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "spaces_id_idx": {
- "name": "spaces_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_owner_id_idx": {
- "name": "spaces_owner_id_idx",
- "columns": [
- {
- "expression": "ownerId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_name_idx": {
- "name": "spaces_name_idx",
- "columns": [
- {
- "expression": "name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "spaces_uuid_unique": {
- "name": "spaces_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.users": {
- "name": "users",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "email": {
- "name": "email",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "first_name": {
- "name": "first_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "last_name": {
- "name": "last_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- },
- "profile_picture_url": {
- "name": "profile_picture_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "telegram_id": {
- "name": "telegram_id",
- "type": "varchar(255)",
- "primaryKey": false,
- "notNull": false
- },
- "has_onboarded": {
- "name": "has_onboarded",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "last_api_key_generated_at": {
- "name": "last_api_key_generated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": false,
- "default": "now()"
- },
- "stripe_customer_id": {
- "name": "stripe_customer_id",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "tier": {
- "name": "tier",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'free'"
- }
- },
- "indexes": {
- "users_id_idx": {
- "name": "users_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_uuid_idx": {
- "name": "users_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_email_idx": {
- "name": "users_email_idx",
- "columns": [
- {
- "expression": "email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_name_idx": {
- "name": "users_name_idx",
- "columns": [
- {
- "expression": "first_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "last_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_created_at_idx": {
- "name": "users_created_at_idx",
- "columns": [
- {
- "expression": "created_at",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_telegram_id_idx": {
- "name": "users_telegram_id_idx",
- "columns": [
- {
- "expression": "telegram_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "users_uuid_unique": {
- "name": "users_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- },
- "users_email_unique": {
- "name": "users_email_unique",
- "nullsNotDistinct": false,
- "columns": [
- "email"
- ]
- }
- }
- },
- "public.waitlist": {
- "name": "waitlist",
- "schema": "",
- "columns": {
- "email": {
- "name": "email",
- "type": "varchar(512)",
- "primaryKey": true,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- }
- },
- "enums": {},
- "schemas": {},
- "sequences": {},
- "_meta": {
- "columns": {},
- "schemas": {},
- "tables": {}
- }
-}
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/0018_snapshot.json b/apps/backend/drizzle/meta/0018_snapshot.json
deleted file mode 100644
index 6b11027b..00000000
--- a/apps/backend/drizzle/meta/0018_snapshot.json
+++ /dev/null
@@ -1,1222 +0,0 @@
-{
- "id": "af318033-5cb6-41bf-9f68-2ebd75bd0a47",
- "prevId": "f8d9da82-e3be-46a9-b52e-a70dc2d24505",
- "version": "7",
- "dialect": "postgresql",
- "tables": {
- "public.chat_threads": {
- "name": "chat_threads",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "firstMessage": {
- "name": "firstMessage",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "messages": {
- "name": "messages",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chat_threads_user_idx": {
- "name": "chat_threads_user_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "chat_threads_user_id_users_id_fk": {
- "name": "chat_threads_user_id_users_id_fk",
- "tableFrom": "chat_threads",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "chat_threads_uuid_unique": {
- "name": "chat_threads_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.chunks": {
- "name": "chunks",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "document_id": {
- "name": "document_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "text_content": {
- "name": "text_content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "order_in_document": {
- "name": "order_in_document",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "embeddings": {
- "name": "embeddings",
- "type": "vector(768)",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chunk_id_idx": {
- "name": "chunk_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "chunk_document_id_idx": {
- "name": "chunk_document_id_idx",
- "columns": [
- {
- "expression": "document_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "embeddingIndex": {
- "name": "embeddingIndex",
- "columns": [
- {
- "expression": "embeddings",
- "isExpression": false,
- "asc": true,
- "nulls": "last",
- "opclass": "vector_cosine_ops"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "hnsw",
- "with": {}
- }
- },
- "foreignKeys": {
- "chunks_document_id_documents_id_fk": {
- "name": "chunks_document_id_documents_id_fk",
- "tableFrom": "chunks",
- "tableTo": "documents",
- "columnsFrom": [
- "document_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.content_to_space": {
- "name": "content_to_space",
- "schema": "",
- "columns": {
- "content_id": {
- "name": "content_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "content_id_space_id_unique": {
- "name": "content_id_space_id_unique",
- "columns": [
- {
- "expression": "content_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "content_to_space_content_id_documents_id_fk": {
- "name": "content_to_space_content_id_documents_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "documents",
- "columnsFrom": [
- "content_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "content_to_space_space_id_spaces_id_fk": {
- "name": "content_to_space_space_id_spaces_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.document_type": {
- "name": "document_type",
- "schema": "",
- "columns": {
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.documents": {
- "name": "documents",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "title": {
- "name": "title",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "description": {
- "name": "description",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "og_image": {
- "name": "og_image",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "raw": {
- "name": "raw",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "content": {
- "name": "content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "is_successfully_processed": {
- "name": "is_successfully_processed",
- "type": "boolean",
- "primaryKey": false,
- "notNull": false,
- "default": false
- },
- "error_message": {
- "name": "error_message",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "content_hash": {
- "name": "content_hash",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "document_id_idx": {
- "name": "document_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_uuid_idx": {
- "name": "document_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_type_idx": {
- "name": "document_type_idx",
- "columns": [
- {
- "expression": "type",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_raw_user_idx": {
- "name": "document_raw_user_idx",
- "columns": [
- {
- "expression": "raw",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "documents_search_idx": {
- "name": "documents_search_idx",
- "columns": [
- {
- "expression": "(\n setweight(to_tsvector('english', coalesce(\"content\", '')),'A') ||\n setweight(to_tsvector('english', coalesce(\"title\", '')),'B') ||\n setweight(to_tsvector('english', coalesce(\"description\", '')),'C') ||\n setweight(to_tsvector('english', coalesce(\"url\", '')),'D')\n )",
- "asc": true,
- "isExpression": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "gin",
- "with": {}
- }
- },
- "foreignKeys": {
- "documents_type_document_type_type_fk": {
- "name": "documents_type_document_type_type_fk",
- "tableFrom": "documents",
- "tableTo": "document_type",
- "columnsFrom": [
- "type"
- ],
- "columnsTo": [
- "type"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- },
- "documents_user_id_users_id_fk": {
- "name": "documents_user_id_users_id_fk",
- "tableFrom": "documents",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "documents_uuid_unique": {
- "name": "documents_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.job": {
- "name": "job",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "attempts": {
- "name": "attempts",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "lastAttemptAt": {
- "name": "lastAttemptAt",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "error": {
- "name": "error",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "user_id_url_idx": {
- "name": "user_id_url_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "job_user_id_users_id_fk": {
- "name": "job_user_id_users_id_fk",
- "tableFrom": "job",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.saved_spaces": {
- "name": "saved_spaces",
- "schema": "",
- "columns": {
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "saved_at": {
- "name": "saved_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "saved_spaces_user_space_idx": {
- "name": "saved_spaces_user_space_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "saved_spaces_user_id_users_id_fk": {
- "name": "saved_spaces_user_id_users_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "saved_spaces_space_id_spaces_id_fk": {
- "name": "saved_spaces_space_id_spaces_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access": {
- "name": "space_access",
- "schema": "",
- "columns": {
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
- },
- "user_email": {
- "name": "user_email",
- "type": "varchar(512)",
- "primaryKey": false,
- "notNull": false
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "access_type": {
- "name": "access_type",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'read'"
- }
- },
- "indexes": {
- "space_id_user_email_idx": {
- "name": "space_id_user_email_idx",
- "columns": [
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_access_space_id_spaces_id_fk": {
- "name": "space_access_space_id_spaces_id_fk",
- "tableFrom": "space_access",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "space_access_status_space_access_status_status_fk": {
- "name": "space_access_status_space_access_status_status_fk",
- "tableFrom": "space_access",
- "tableTo": "space_access_status",
- "columnsFrom": [
- "status"
- ],
- "columnsTo": [
- "status"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access_status": {
- "name": "space_access_status",
- "schema": "",
- "columns": {
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_members": {
- "name": "space_members",
- "schema": "",
- "columns": {
- "spaceId": {
- "name": "spaceId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "space_members_space_user_idx": {
- "name": "space_members_space_user_idx",
- "columns": [
- {
- "expression": "spaceId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_members_spaceId_users_id_fk": {
- "name": "space_members_spaceId_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "spaceId"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- },
- "space_members_user_id_users_id_fk": {
- "name": "space_members_user_id_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.spaces": {
- "name": "spaces",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "name": {
- "name": "name",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "ownerId": {
- "name": "ownerId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "is_public": {
- "name": "is_public",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "spaces_id_idx": {
- "name": "spaces_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_owner_id_idx": {
- "name": "spaces_owner_id_idx",
- "columns": [
- {
- "expression": "ownerId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_name_idx": {
- "name": "spaces_name_idx",
- "columns": [
- {
- "expression": "name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "spaces_uuid_unique": {
- "name": "spaces_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.users": {
- "name": "users",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "email": {
- "name": "email",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "first_name": {
- "name": "first_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "last_name": {
- "name": "last_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- },
- "profile_picture_url": {
- "name": "profile_picture_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "telegram_id": {
- "name": "telegram_id",
- "type": "varchar(255)",
- "primaryKey": false,
- "notNull": false
- },
- "has_onboarded": {
- "name": "has_onboarded",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "last_api_key_generated_at": {
- "name": "last_api_key_generated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": false,
- "default": "now()"
- },
- "stripe_customer_id": {
- "name": "stripe_customer_id",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "tier": {
- "name": "tier",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'free'"
- }
- },
- "indexes": {
- "users_id_idx": {
- "name": "users_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_uuid_idx": {
- "name": "users_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_email_idx": {
- "name": "users_email_idx",
- "columns": [
- {
- "expression": "email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_name_idx": {
- "name": "users_name_idx",
- "columns": [
- {
- "expression": "first_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "last_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_created_at_idx": {
- "name": "users_created_at_idx",
- "columns": [
- {
- "expression": "created_at",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_telegram_id_idx": {
- "name": "users_telegram_id_idx",
- "columns": [
- {
- "expression": "telegram_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "users_uuid_unique": {
- "name": "users_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- },
- "users_email_unique": {
- "name": "users_email_unique",
- "nullsNotDistinct": false,
- "columns": [
- "email"
- ]
- }
- }
- },
- "public.waitlist": {
- "name": "waitlist",
- "schema": "",
- "columns": {
- "email": {
- "name": "email",
- "type": "varchar(512)",
- "primaryKey": true,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- }
- },
- "enums": {},
- "schemas": {},
- "sequences": {},
- "_meta": {
- "columns": {},
- "schemas": {},
- "tables": {}
- }
-}
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/0019_snapshot.json b/apps/backend/drizzle/meta/0019_snapshot.json
deleted file mode 100644
index 7c75753c..00000000
--- a/apps/backend/drizzle/meta/0019_snapshot.json
+++ /dev/null
@@ -1,1228 +0,0 @@
-{
- "id": "0f7b4e6d-295d-481f-84be-6b31178aa1b6",
- "prevId": "af318033-5cb6-41bf-9f68-2ebd75bd0a47",
- "version": "7",
- "dialect": "postgresql",
- "tables": {
- "public.chat_threads": {
- "name": "chat_threads",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "firstMessage": {
- "name": "firstMessage",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "messages": {
- "name": "messages",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chat_threads_user_idx": {
- "name": "chat_threads_user_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "chat_threads_user_id_users_id_fk": {
- "name": "chat_threads_user_id_users_id_fk",
- "tableFrom": "chat_threads",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "chat_threads_uuid_unique": {
- "name": "chat_threads_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.chunks": {
- "name": "chunks",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "document_id": {
- "name": "document_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "text_content": {
- "name": "text_content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "order_in_document": {
- "name": "order_in_document",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "embeddings": {
- "name": "embeddings",
- "type": "vector(768)",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chunk_id_idx": {
- "name": "chunk_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "chunk_document_id_idx": {
- "name": "chunk_document_id_idx",
- "columns": [
- {
- "expression": "document_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "embeddingIndex": {
- "name": "embeddingIndex",
- "columns": [
- {
- "expression": "embeddings",
- "isExpression": false,
- "asc": true,
- "nulls": "last",
- "opclass": "vector_cosine_ops"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "hnsw",
- "with": {}
- }
- },
- "foreignKeys": {
- "chunks_document_id_documents_id_fk": {
- "name": "chunks_document_id_documents_id_fk",
- "tableFrom": "chunks",
- "tableTo": "documents",
- "columnsFrom": [
- "document_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.content_to_space": {
- "name": "content_to_space",
- "schema": "",
- "columns": {
- "content_id": {
- "name": "content_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "content_id_space_id_unique": {
- "name": "content_id_space_id_unique",
- "columns": [
- {
- "expression": "content_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "content_to_space_content_id_documents_id_fk": {
- "name": "content_to_space_content_id_documents_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "documents",
- "columnsFrom": [
- "content_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "content_to_space_space_id_spaces_id_fk": {
- "name": "content_to_space_space_id_spaces_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.document_type": {
- "name": "document_type",
- "schema": "",
- "columns": {
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.documents": {
- "name": "documents",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "title": {
- "name": "title",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "description": {
- "name": "description",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "og_image": {
- "name": "og_image",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "raw": {
- "name": "raw",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "content": {
- "name": "content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "is_successfully_processed": {
- "name": "is_successfully_processed",
- "type": "boolean",
- "primaryKey": false,
- "notNull": false,
- "default": false
- },
- "error_message": {
- "name": "error_message",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "content_hash": {
- "name": "content_hash",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "document_id_idx": {
- "name": "document_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_uuid_idx": {
- "name": "document_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_type_idx": {
- "name": "document_type_idx",
- "columns": [
- {
- "expression": "type",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_raw_user_idx": {
- "name": "document_raw_user_idx",
- "columns": [
- {
- "expression": "raw",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "documents_search_idx": {
- "name": "documents_search_idx",
- "columns": [
- {
- "expression": "(\n setweight(to_tsvector('english', coalesce(\"content\", '')),'A') ||\n setweight(to_tsvector('english', coalesce(\"title\", '')),'B') ||\n setweight(to_tsvector('english', coalesce(\"description\", '')),'C') ||\n setweight(to_tsvector('english', coalesce(\"url\", '')),'D')\n )",
- "asc": true,
- "isExpression": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "gin",
- "with": {}
- }
- },
- "foreignKeys": {
- "documents_type_document_type_type_fk": {
- "name": "documents_type_document_type_type_fk",
- "tableFrom": "documents",
- "tableTo": "document_type",
- "columnsFrom": [
- "type"
- ],
- "columnsTo": [
- "type"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- },
- "documents_user_id_users_id_fk": {
- "name": "documents_user_id_users_id_fk",
- "tableFrom": "documents",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "documents_uuid_unique": {
- "name": "documents_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.job": {
- "name": "job",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "attempts": {
- "name": "attempts",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "lastAttemptAt": {
- "name": "lastAttemptAt",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "error": {
- "name": "error",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "user_id_url_idx": {
- "name": "user_id_url_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "url",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "job_user_id_users_id_fk": {
- "name": "job_user_id_users_id_fk",
- "tableFrom": "job",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.saved_spaces": {
- "name": "saved_spaces",
- "schema": "",
- "columns": {
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "saved_at": {
- "name": "saved_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "saved_spaces_user_space_idx": {
- "name": "saved_spaces_user_space_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "saved_spaces_user_id_users_id_fk": {
- "name": "saved_spaces_user_id_users_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "saved_spaces_space_id_spaces_id_fk": {
- "name": "saved_spaces_space_id_spaces_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access": {
- "name": "space_access",
- "schema": "",
- "columns": {
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
- },
- "user_email": {
- "name": "user_email",
- "type": "varchar(512)",
- "primaryKey": false,
- "notNull": false
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "access_type": {
- "name": "access_type",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'read'"
- }
- },
- "indexes": {
- "space_id_user_email_idx": {
- "name": "space_id_user_email_idx",
- "columns": [
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_access_space_id_spaces_id_fk": {
- "name": "space_access_space_id_spaces_id_fk",
- "tableFrom": "space_access",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "space_access_status_space_access_status_status_fk": {
- "name": "space_access_status_space_access_status_status_fk",
- "tableFrom": "space_access",
- "tableTo": "space_access_status",
- "columnsFrom": [
- "status"
- ],
- "columnsTo": [
- "status"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access_status": {
- "name": "space_access_status",
- "schema": "",
- "columns": {
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_members": {
- "name": "space_members",
- "schema": "",
- "columns": {
- "spaceId": {
- "name": "spaceId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "space_members_space_user_idx": {
- "name": "space_members_space_user_idx",
- "columns": [
- {
- "expression": "spaceId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_members_spaceId_users_id_fk": {
- "name": "space_members_spaceId_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "spaceId"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- },
- "space_members_user_id_users_id_fk": {
- "name": "space_members_user_id_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.spaces": {
- "name": "spaces",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "name": {
- "name": "name",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "ownerId": {
- "name": "ownerId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "is_public": {
- "name": "is_public",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "spaces_id_idx": {
- "name": "spaces_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_owner_id_idx": {
- "name": "spaces_owner_id_idx",
- "columns": [
- {
- "expression": "ownerId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_name_idx": {
- "name": "spaces_name_idx",
- "columns": [
- {
- "expression": "name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "spaces_uuid_unique": {
- "name": "spaces_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.users": {
- "name": "users",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "email": {
- "name": "email",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "first_name": {
- "name": "first_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "last_name": {
- "name": "last_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- },
- "profile_picture_url": {
- "name": "profile_picture_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "telegram_id": {
- "name": "telegram_id",
- "type": "varchar(255)",
- "primaryKey": false,
- "notNull": false
- },
- "has_onboarded": {
- "name": "has_onboarded",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "last_api_key_generated_at": {
- "name": "last_api_key_generated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": false,
- "default": "now()"
- },
- "stripe_customer_id": {
- "name": "stripe_customer_id",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "tier": {
- "name": "tier",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'free'"
- }
- },
- "indexes": {
- "users_id_idx": {
- "name": "users_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_uuid_idx": {
- "name": "users_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_email_idx": {
- "name": "users_email_idx",
- "columns": [
- {
- "expression": "email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_name_idx": {
- "name": "users_name_idx",
- "columns": [
- {
- "expression": "first_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "last_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_created_at_idx": {
- "name": "users_created_at_idx",
- "columns": [
- {
- "expression": "created_at",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_telegram_id_idx": {
- "name": "users_telegram_id_idx",
- "columns": [
- {
- "expression": "telegram_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "users_uuid_unique": {
- "name": "users_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- },
- "users_email_unique": {
- "name": "users_email_unique",
- "nullsNotDistinct": false,
- "columns": [
- "email"
- ]
- }
- }
- },
- "public.waitlist": {
- "name": "waitlist",
- "schema": "",
- "columns": {
- "email": {
- "name": "email",
- "type": "varchar(512)",
- "primaryKey": true,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- }
- },
- "enums": {},
- "schemas": {},
- "sequences": {},
- "_meta": {
- "columns": {},
- "schemas": {},
- "tables": {}
- }
-}
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/0020_snapshot.json b/apps/backend/drizzle/meta/0020_snapshot.json
deleted file mode 100644
index a6d491d4..00000000
--- a/apps/backend/drizzle/meta/0020_snapshot.json
+++ /dev/null
@@ -1,1127 +0,0 @@
-{
- "id": "d76a6f6e-ff3d-49d8-b8fe-a5d3f48924da",
- "prevId": "0f7b4e6d-295d-481f-84be-6b31178aa1b6",
- "version": "7",
- "dialect": "postgresql",
- "tables": {
- "public.chat_threads": {
- "name": "chat_threads",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "firstMessage": {
- "name": "firstMessage",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "messages": {
- "name": "messages",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chat_threads_user_idx": {
- "name": "chat_threads_user_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "chat_threads_user_id_users_id_fk": {
- "name": "chat_threads_user_id_users_id_fk",
- "tableFrom": "chat_threads",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "chat_threads_uuid_unique": {
- "name": "chat_threads_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.chunks": {
- "name": "chunks",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "document_id": {
- "name": "document_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "text_content": {
- "name": "text_content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "order_in_document": {
- "name": "order_in_document",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "embeddings": {
- "name": "embeddings",
- "type": "vector(768)",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "chunk_id_idx": {
- "name": "chunk_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "chunk_document_id_idx": {
- "name": "chunk_document_id_idx",
- "columns": [
- {
- "expression": "document_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "embeddingIndex": {
- "name": "embeddingIndex",
- "columns": [
- {
- "expression": "embeddings",
- "isExpression": false,
- "asc": true,
- "nulls": "last",
- "opclass": "vector_cosine_ops"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "hnsw",
- "with": {}
- }
- },
- "foreignKeys": {
- "chunks_document_id_documents_id_fk": {
- "name": "chunks_document_id_documents_id_fk",
- "tableFrom": "chunks",
- "tableTo": "documents",
- "columnsFrom": [
- "document_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.content_to_space": {
- "name": "content_to_space",
- "schema": "",
- "columns": {
- "content_id": {
- "name": "content_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "content_id_space_id_unique": {
- "name": "content_id_space_id_unique",
- "columns": [
- {
- "expression": "content_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "content_to_space_content_id_documents_id_fk": {
- "name": "content_to_space_content_id_documents_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "documents",
- "columnsFrom": [
- "content_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "content_to_space_space_id_spaces_id_fk": {
- "name": "content_to_space_space_id_spaces_id_fk",
- "tableFrom": "content_to_space",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.document_type": {
- "name": "document_type",
- "schema": "",
- "columns": {
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.documents": {
- "name": "documents",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "url": {
- "name": "url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": false
- },
- "type": {
- "name": "type",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "title": {
- "name": "title",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "description": {
- "name": "description",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "og_image": {
- "name": "og_image",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "raw": {
- "name": "raw",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "content": {
- "name": "content",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "is_successfully_processed": {
- "name": "is_successfully_processed",
- "type": "boolean",
- "primaryKey": false,
- "notNull": false,
- "default": false
- },
- "error_message": {
- "name": "error_message",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "content_hash": {
- "name": "content_hash",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "metadata": {
- "name": "metadata",
- "type": "jsonb",
- "primaryKey": false,
- "notNull": false
- }
- },
- "indexes": {
- "document_id_idx": {
- "name": "document_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_uuid_idx": {
- "name": "document_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_type_idx": {
- "name": "document_type_idx",
- "columns": [
- {
- "expression": "type",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "document_raw_user_idx": {
- "name": "document_raw_user_idx",
- "columns": [
- {
- "expression": "raw",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "documents_search_idx": {
- "name": "documents_search_idx",
- "columns": [
- {
- "expression": "(\n setweight(to_tsvector('english', coalesce(\"content\", '')),'A') ||\n setweight(to_tsvector('english', coalesce(\"title\", '')),'B') ||\n setweight(to_tsvector('english', coalesce(\"description\", '')),'C') ||\n setweight(to_tsvector('english', coalesce(\"url\", '')),'D')\n )",
- "asc": true,
- "isExpression": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "gin",
- "with": {}
- }
- },
- "foreignKeys": {
- "documents_type_document_type_type_fk": {
- "name": "documents_type_document_type_type_fk",
- "tableFrom": "documents",
- "tableTo": "document_type",
- "columnsFrom": [
- "type"
- ],
- "columnsTo": [
- "type"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- },
- "documents_user_id_users_id_fk": {
- "name": "documents_user_id_users_id_fk",
- "tableFrom": "documents",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "documents_uuid_unique": {
- "name": "documents_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.saved_spaces": {
- "name": "saved_spaces",
- "schema": "",
- "columns": {
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "saved_at": {
- "name": "saved_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {
- "saved_spaces_user_space_idx": {
- "name": "saved_spaces_user_space_idx",
- "columns": [
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "saved_spaces_user_id_users_id_fk": {
- "name": "saved_spaces_user_id_users_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "saved_spaces_space_id_spaces_id_fk": {
- "name": "saved_spaces_space_id_spaces_id_fk",
- "tableFrom": "saved_spaces",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access": {
- "name": "space_access",
- "schema": "",
- "columns": {
- "space_id": {
- "name": "space_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": false
- },
- "user_email": {
- "name": "user_email",
- "type": "varchar(512)",
- "primaryKey": false,
- "notNull": false
- },
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "access_type": {
- "name": "access_type",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'read'"
- }
- },
- "indexes": {
- "space_id_user_email_idx": {
- "name": "space_id_user_email_idx",
- "columns": [
- {
- "expression": "space_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_access_space_id_spaces_id_fk": {
- "name": "space_access_space_id_spaces_id_fk",
- "tableFrom": "space_access",
- "tableTo": "spaces",
- "columnsFrom": [
- "space_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "cascade",
- "onUpdate": "no action"
- },
- "space_access_status_space_access_status_status_fk": {
- "name": "space_access_status_space_access_status_status_fk",
- "tableFrom": "space_access",
- "tableTo": "space_access_status",
- "columnsFrom": [
- "status"
- ],
- "columnsTo": [
- "status"
- ],
- "onDelete": "no action",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_access_status": {
- "name": "space_access_status",
- "schema": "",
- "columns": {
- "status": {
- "name": "status",
- "type": "text",
- "primaryKey": true,
- "notNull": true
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.space_members": {
- "name": "space_members",
- "schema": "",
- "columns": {
- "spaceId": {
- "name": "spaceId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "user_id": {
- "name": "user_id",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- }
- },
- "indexes": {
- "space_members_space_user_idx": {
- "name": "space_members_space_user_idx",
- "columns": [
- {
- "expression": "spaceId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "user_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {
- "space_members_spaceId_users_id_fk": {
- "name": "space_members_spaceId_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "spaceId"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- },
- "space_members_user_id_users_id_fk": {
- "name": "space_members_user_id_users_id_fk",
- "tableFrom": "space_members",
- "tableTo": "users",
- "columnsFrom": [
- "user_id"
- ],
- "columnsTo": [
- "id"
- ],
- "onDelete": "restrict",
- "onUpdate": "no action"
- }
- },
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- },
- "public.spaces": {
- "name": "spaces",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "bigserial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "name": {
- "name": "name",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "ownerId": {
- "name": "ownerId",
- "type": "integer",
- "primaryKey": false,
- "notNull": true
- },
- "is_public": {
- "name": "is_public",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- }
- },
- "indexes": {
- "spaces_id_idx": {
- "name": "spaces_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_owner_id_idx": {
- "name": "spaces_owner_id_idx",
- "columns": [
- {
- "expression": "ownerId",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "spaces_name_idx": {
- "name": "spaces_name_idx",
- "columns": [
- {
- "expression": "name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "spaces_uuid_unique": {
- "name": "spaces_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- }
- }
- },
- "public.users": {
- "name": "users",
- "schema": "",
- "columns": {
- "id": {
- "name": "id",
- "type": "serial",
- "primaryKey": true,
- "notNull": true
- },
- "uuid": {
- "name": "uuid",
- "type": "varchar(36)",
- "primaryKey": false,
- "notNull": true
- },
- "email": {
- "name": "email",
- "type": "text",
- "primaryKey": false,
- "notNull": true
- },
- "first_name": {
- "name": "first_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "last_name": {
- "name": "last_name",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "email_verified": {
- "name": "email_verified",
- "type": "boolean",
- "primaryKey": false,
- "notNull": true,
- "default": false
- },
- "profile_picture_url": {
- "name": "profile_picture_url",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "telegram_id": {
- "name": "telegram_id",
- "type": "varchar(255)",
- "primaryKey": false,
- "notNull": false
- },
- "has_onboarded": {
- "name": "has_onboarded",
- "type": "integer",
- "primaryKey": false,
- "notNull": true,
- "default": 0
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "updated_at": {
- "name": "updated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- },
- "last_api_key_generated_at": {
- "name": "last_api_key_generated_at",
- "type": "timestamp",
- "primaryKey": false,
- "notNull": false,
- "default": "now()"
- },
- "stripe_customer_id": {
- "name": "stripe_customer_id",
- "type": "text",
- "primaryKey": false,
- "notNull": false
- },
- "tier": {
- "name": "tier",
- "type": "text",
- "primaryKey": false,
- "notNull": true,
- "default": "'free'"
- }
- },
- "indexes": {
- "users_id_idx": {
- "name": "users_id_idx",
- "columns": [
- {
- "expression": "id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_uuid_idx": {
- "name": "users_uuid_idx",
- "columns": [
- {
- "expression": "uuid",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_email_idx": {
- "name": "users_email_idx",
- "columns": [
- {
- "expression": "email",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_name_idx": {
- "name": "users_name_idx",
- "columns": [
- {
- "expression": "first_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- },
- {
- "expression": "last_name",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_created_at_idx": {
- "name": "users_created_at_idx",
- "columns": [
- {
- "expression": "created_at",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": false,
- "concurrently": false,
- "method": "btree",
- "with": {}
- },
- "users_telegram_id_idx": {
- "name": "users_telegram_id_idx",
- "columns": [
- {
- "expression": "telegram_id",
- "isExpression": false,
- "asc": true,
- "nulls": "last"
- }
- ],
- "isUnique": true,
- "concurrently": false,
- "method": "btree",
- "with": {}
- }
- },
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {
- "users_uuid_unique": {
- "name": "users_uuid_unique",
- "nullsNotDistinct": false,
- "columns": [
- "uuid"
- ]
- },
- "users_email_unique": {
- "name": "users_email_unique",
- "nullsNotDistinct": false,
- "columns": [
- "email"
- ]
- }
- }
- },
- "public.waitlist": {
- "name": "waitlist",
- "schema": "",
- "columns": {
- "email": {
- "name": "email",
- "type": "varchar(512)",
- "primaryKey": true,
- "notNull": true
- },
- "created_at": {
- "name": "created_at",
- "type": "timestamp with time zone",
- "primaryKey": false,
- "notNull": true,
- "default": "now()"
- }
- },
- "indexes": {},
- "foreignKeys": {},
- "compositePrimaryKeys": {},
- "uniqueConstraints": {}
- }
- },
- "enums": {},
- "schemas": {},
- "sequences": {},
- "_meta": {
- "columns": {},
- "schemas": {},
- "tables": {}
- }
-}
\ No newline at end of file
diff --git a/apps/backend/drizzle/meta/_journal.json b/apps/backend/drizzle/meta/_journal.json
deleted file mode 100644
index ebd7e43a..00000000
--- a/apps/backend/drizzle/meta/_journal.json
+++ /dev/null
@@ -1,146 +0,0 @@
-{
- "version": "7",
- "dialect": "postgresql",
- "entries": [
- {
- "idx": 0,
- "version": "7",
- "when": 1731880515136,
- "tag": "0000_odd_impossible_man",
- "breakpoints": true
- },
- {
- "idx": 1,
- "version": "7",
- "when": 1731880538346,
- "tag": "0001_seed-types",
- "breakpoints": true
- },
- {
- "idx": 2,
- "version": "7",
- "when": 1731970096987,
- "tag": "0002_skinny_princess_powerful",
- "breakpoints": true
- },
- {
- "idx": 3,
- "version": "7",
- "when": 1732290500234,
- "tag": "0003_luxuriant_annihilus",
- "breakpoints": true
- },
- {
- "idx": 4,
- "version": "7",
- "when": 1732291518161,
- "tag": "0004_early_rick_jones",
- "breakpoints": true
- },
- {
- "idx": 5,
- "version": "7",
- "when": 1732292492979,
- "tag": "0005_create-access-types",
- "breakpoints": true
- },
- {
- "idx": 6,
- "version": "7",
- "when": 1732308308233,
- "tag": "0006_wandering_grandmaster",
- "breakpoints": true
- },
- {
- "idx": 7,
- "version": "7",
- "when": 1732476625236,
- "tag": "0007_fantastic_serpent_society",
- "breakpoints": true
- },
- {
- "idx": 8,
- "version": "7",
- "when": 1732575691923,
- "tag": "0008_add-notion",
- "breakpoints": true
- },
- {
- "idx": 9,
- "version": "7",
- "when": 1732693411536,
- "tag": "0009_milky_sleepwalker",
- "breakpoints": true
- },
- {
- "idx": 10,
- "version": "7",
- "when": 1733037679877,
- "tag": "0010_heavy_preak",
- "breakpoints": true
- },
- {
- "idx": 11,
- "version": "7",
- "when": 1733177542412,
- "tag": "0011_new_liz_osborn",
- "breakpoints": true
- },
- {
- "idx": 12,
- "version": "7",
- "when": 1735033070115,
- "tag": "0012_small_mystique",
- "breakpoints": true
- },
- {
- "idx": 13,
- "version": "7",
- "when": 1736500817155,
- "tag": "0013_sharp_hemingway",
- "breakpoints": true
- },
- {
- "idx": 14,
- "version": "7",
- "when": 1736852938881,
- "tag": "0014_mighty_the_captain",
- "breakpoints": true
- },
- {
- "idx": 15,
- "version": "7",
- "when": 1737920848112,
- "tag": "0015_perpetual_mauler",
- "breakpoints": true
- },
- {
- "idx": 16,
- "version": "7",
- "when": 1739937938319,
- "tag": "0016_good_deathbird",
- "breakpoints": true
- },
- {
- "idx": 18,
- "version": "7",
- "when": 1739939254444,
- "tag": "0018_past_inertia",
- "breakpoints": true
- },
- {
- "idx": 19,
- "version": "7",
- "when": 1741025619581,
- "tag": "0019_vengeful_marten_broadcloak",
- "breakpoints": true
- },
- {
- "idx": 20,
- "version": "7",
- "when": 1741026944027,
- "tag": "0020_opposite_steel_serpent",
- "breakpoints": true
- }
- ]
-}
\ No newline at end of file
diff --git a/apps/backend/package.json b/apps/backend/package.json
deleted file mode 100644
index 664b501d..00000000
--- a/apps/backend/package.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "name": "supermemory-backend",
- "scripts": {
- "dev": "bunx wrangler -v && wrangler dev",
- "deploy": "bunx wrangler deploy --minify",
- "generate-migration": "dotenv -- npx drizzle-kit generate",
- "migrate:local": "bun run ./scripts/migrate.ts",
- "migrate:prod": "NODE_ENV=production bun run ./scripts/migrate.ts",
- "tail": "bunx wrangler tail"
- },
- "dependencies": {
- "@ai-sdk/google": "^0.0.51",
- "@ai-sdk/openai": "^0.0.70",
- "@hono/swagger-ui": "^0.5.0",
- "@hono/zod-openapi": "^0.18.3",
- "@hono/zod-validator": "^0.4.1",
- "@supermemory/db": "workspace:*",
- "ai": "4.0.16",
- "compromise": "^14.14.2",
- "dotenv": "^16.4.5",
- "drizzle-kit": "^0.25.0",
- "drizzle-orm": "^0.34.1",
- "hono": "^4.6.4",
- "openai": "^4.68.4",
- "postgres": "^3.4.4",
- "uuid": "^11.0.1",
- "wrangler": "^3.111.0",
- "zod": "^3.23.8"
- },
- "devDependencies": {
- "@cloudflare/workers-types": "^4.20250124.3"
- },
- "overrides": {
- "iron-webcrypto": "^1.2.1"
- }
-}
diff --git a/apps/backend/public/favicon.ico b/apps/backend/public/favicon.ico
deleted file mode 100644
index 90d7aafc..00000000
Binary files a/apps/backend/public/favicon.ico and /dev/null differ
diff --git a/apps/backend/public/output.css b/apps/backend/public/output.css
deleted file mode 100644
index 925ff374..00000000
--- a/apps/backend/public/output.css
+++ /dev/null
@@ -1,853 +0,0 @@
-*, ::before, ::after {
- --tw-border-spacing-x: 0;
- --tw-border-spacing-y: 0;
- --tw-translate-x: 0;
- --tw-translate-y: 0;
- --tw-rotate: 0;
- --tw-skew-x: 0;
- --tw-skew-y: 0;
- --tw-scale-x: 1;
- --tw-scale-y: 1;
- --tw-pan-x: ;
- --tw-pan-y: ;
- --tw-pinch-zoom: ;
- --tw-scroll-snap-strictness: proximity;
- --tw-gradient-from-position: ;
- --tw-gradient-via-position: ;
- --tw-gradient-to-position: ;
- --tw-ordinal: ;
- --tw-slashed-zero: ;
- --tw-numeric-figure: ;
- --tw-numeric-spacing: ;
- --tw-numeric-fraction: ;
- --tw-ring-inset: ;
- --tw-ring-offset-width: 0px;
- --tw-ring-offset-color: #fff;
- --tw-ring-color: rgb(59 130 246 / 0.5);
- --tw-ring-offset-shadow: 0 0 #0000;
- --tw-ring-shadow: 0 0 #0000;
- --tw-shadow: 0 0 #0000;
- --tw-shadow-colored: 0 0 #0000;
- --tw-blur: ;
- --tw-brightness: ;
- --tw-contrast: ;
- --tw-grayscale: ;
- --tw-hue-rotate: ;
- --tw-invert: ;
- --tw-saturate: ;
- --tw-sepia: ;
- --tw-drop-shadow: ;
- --tw-backdrop-blur: ;
- --tw-backdrop-brightness: ;
- --tw-backdrop-contrast: ;
- --tw-backdrop-grayscale: ;
- --tw-backdrop-hue-rotate: ;
- --tw-backdrop-invert: ;
- --tw-backdrop-opacity: ;
- --tw-backdrop-saturate: ;
- --tw-backdrop-sepia: ;
- --tw-contain-size: ;
- --tw-contain-layout: ;
- --tw-contain-paint: ;
- --tw-contain-style: ;
-}
-
-::backdrop {
- --tw-border-spacing-x: 0;
- --tw-border-spacing-y: 0;
- --tw-translate-x: 0;
- --tw-translate-y: 0;
- --tw-rotate: 0;
- --tw-skew-x: 0;
- --tw-skew-y: 0;
- --tw-scale-x: 1;
- --tw-scale-y: 1;
- --tw-pan-x: ;
- --tw-pan-y: ;
- --tw-pinch-zoom: ;
- --tw-scroll-snap-strictness: proximity;
- --tw-gradient-from-position: ;
- --tw-gradient-via-position: ;
- --tw-gradient-to-position: ;
- --tw-ordinal: ;
- --tw-slashed-zero: ;
- --tw-numeric-figure: ;
- --tw-numeric-spacing: ;
- --tw-numeric-fraction: ;
- --tw-ring-inset: ;
- --tw-ring-offset-width: 0px;
- --tw-ring-offset-color: #fff;
- --tw-ring-color: rgb(59 130 246 / 0.5);
- --tw-ring-offset-shadow: 0 0 #0000;
- --tw-ring-shadow: 0 0 #0000;
- --tw-shadow: 0 0 #0000;
- --tw-shadow-colored: 0 0 #0000;
- --tw-blur: ;
- --tw-brightness: ;
- --tw-contrast: ;
- --tw-grayscale: ;
- --tw-hue-rotate: ;
- --tw-invert: ;
- --tw-saturate: ;
- --tw-sepia: ;
- --tw-drop-shadow: ;
- --tw-backdrop-blur: ;
- --tw-backdrop-brightness: ;
- --tw-backdrop-contrast: ;
- --tw-backdrop-grayscale: ;
- --tw-backdrop-hue-rotate: ;
- --tw-backdrop-invert: ;
- --tw-backdrop-opacity: ;
- --tw-backdrop-saturate: ;
- --tw-backdrop-sepia: ;
- --tw-contain-size: ;
- --tw-contain-layout: ;
- --tw-contain-paint: ;
- --tw-contain-style: ;
-}
-
-/*
-! tailwindcss v3.4.15 | MIT License | https://tailwindcss.com
-*/
-
-/*
-1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
-2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
-*/
-
-*,
-::before,
-::after {
- box-sizing: border-box;
- /* 1 */
- border-width: 0;
- /* 2 */
- border-style: solid;
- /* 2 */
- border-color: #e5e7eb;
- /* 2 */
-}
-
-::before,
-::after {
- --tw-content: '';
-}
-
-/*
-1. Use a consistent sensible line-height in all browsers.
-2. Prevent adjustments of font size after orientation changes in iOS.
-3. Use a more readable tab size.
-4. Use the user's configured `sans` font-family by default.
-5. Use the user's configured `sans` font-feature-settings by default.
-6. Use the user's configured `sans` font-variation-settings by default.
-7. Disable tap highlights on iOS
-*/
-
-html,
-:host {
- line-height: 1.5;
- /* 1 */
- -webkit-text-size-adjust: 100%;
- /* 2 */
- -moz-tab-size: 4;
- /* 3 */
- -o-tab-size: 4;
- tab-size: 4;
- /* 3 */
- font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
- /* 4 */
- font-feature-settings: normal;
- /* 5 */
- font-variation-settings: normal;
- /* 6 */
- -webkit-tap-highlight-color: transparent;
- /* 7 */
-}
-
-/*
-1. Remove the margin in all browsers.
-2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
-*/
-
-body {
- margin: 0;
- /* 1 */
- line-height: inherit;
- /* 2 */
-}
-
-/*
-1. Add the correct height in Firefox.
-2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
-3. Ensure horizontal rules are visible by default.
-*/
-
-hr {
- height: 0;
- /* 1 */
- color: inherit;
- /* 2 */
- border-top-width: 1px;
- /* 3 */
-}
-
-/*
-Add the correct text decoration in Chrome, Edge, and Safari.
-*/
-
-abbr:where([title]) {
- -webkit-text-decoration: underline dotted;
- text-decoration: underline dotted;
-}
-
-/*
-Remove the default font size and weight for headings.
-*/
-
-h1,
-h2,
-h3,
-h4,
-h5,
-h6 {
- font-size: inherit;
- font-weight: inherit;
-}
-
-/*
-Reset links to optimize for opt-in styling instead of opt-out.
-*/
-
-a {
- color: inherit;
- text-decoration: inherit;
-}
-
-/*
-Add the correct font weight in Edge and Safari.
-*/
-
-b,
-strong {
- font-weight: bolder;
-}
-
-/*
-1. Use the user's configured `mono` font-family by default.
-2. Use the user's configured `mono` font-feature-settings by default.
-3. Use the user's configured `mono` font-variation-settings by default.
-4. Correct the odd `em` font sizing in all browsers.
-*/
-
-code,
-kbd,
-samp,
-pre {
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
- /* 1 */
- font-feature-settings: normal;
- /* 2 */
- font-variation-settings: normal;
- /* 3 */
- font-size: 1em;
- /* 4 */
-}
-
-/*
-Add the correct font size in all browsers.
-*/
-
-small {
- font-size: 80%;
-}
-
-/*
-Prevent `sub` and `sup` elements from affecting the line height in all browsers.
-*/
-
-sub,
-sup {
- font-size: 75%;
- line-height: 0;
- position: relative;
- vertical-align: baseline;
-}
-
-sub {
- bottom: -0.25em;
-}
-
-sup {
- top: -0.5em;
-}
-
-/*
-1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
-2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
-3. Remove gaps between table borders by default.
-*/
-
-table {
- text-indent: 0;
- /* 1 */
- border-color: inherit;
- /* 2 */
- border-collapse: collapse;
- /* 3 */
-}
-
-/*
-1. Change the font styles in all browsers.
-2. Remove the margin in Firefox and Safari.
-3. Remove default padding in all browsers.
-*/
-
-button,
-input,
-optgroup,
-select,
-textarea {
- font-family: inherit;
- /* 1 */
- font-feature-settings: inherit;
- /* 1 */
- font-variation-settings: inherit;
- /* 1 */
- font-size: 100%;
- /* 1 */
- font-weight: inherit;
- /* 1 */
- line-height: inherit;
- /* 1 */
- letter-spacing: inherit;
- /* 1 */
- color: inherit;
- /* 1 */
- margin: 0;
- /* 2 */
- padding: 0;
- /* 3 */
-}
-
-/*
-Remove the inheritance of text transform in Edge and Firefox.
-*/
-
-button,
-select {
- text-transform: none;
-}
-
-/*
-1. Correct the inability to style clickable types in iOS and Safari.
-2. Remove default button styles.
-*/
-
-button,
-input:where([type='button']),
-input:where([type='reset']),
-input:where([type='submit']) {
- -webkit-appearance: button;
- /* 1 */
- background-color: transparent;
- /* 2 */
- background-image: none;
- /* 2 */
-}
-
-/*
-Use the modern Firefox focus style for all focusable elements.
-*/
-
-:-moz-focusring {
- outline: auto;
-}
-
-/*
-Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
-*/
-
-:-moz-ui-invalid {
- box-shadow: none;
-}
-
-/*
-Add the correct vertical alignment in Chrome and Firefox.
-*/
-
-progress {
- vertical-align: baseline;
-}
-
-/*
-Correct the cursor style of increment and decrement buttons in Safari.
-*/
-
-::-webkit-inner-spin-button,
-::-webkit-outer-spin-button {
- height: auto;
-}
-
-/*
-1. Correct the odd appearance in Chrome and Safari.
-2. Correct the outline style in Safari.
-*/
-
-[type='search'] {
- -webkit-appearance: textfield;
- /* 1 */
- outline-offset: -2px;
- /* 2 */
-}
-
-/*
-Remove the inner padding in Chrome and Safari on macOS.
-*/
-
-::-webkit-search-decoration {
- -webkit-appearance: none;
-}
-
-/*
-1. Correct the inability to style clickable types in iOS and Safari.
-2. Change font properties to `inherit` in Safari.
-*/
-
-::-webkit-file-upload-button {
- -webkit-appearance: button;
- /* 1 */
- font: inherit;
- /* 2 */
-}
-
-/*
-Add the correct display in Chrome and Safari.
-*/
-
-summary {
- display: list-item;
-}
-
-/*
-Removes the default spacing and border for appropriate elements.
-*/
-
-blockquote,
-dl,
-dd,
-h1,
-h2,
-h3,
-h4,
-h5,
-h6,
-hr,
-figure,
-p,
-pre {
- margin: 0;
-}
-
-fieldset {
- margin: 0;
- padding: 0;
-}
-
-legend {
- padding: 0;
-}
-
-ol,
-ul,
-menu {
- list-style: none;
- margin: 0;
- padding: 0;
-}
-
-/*
-Reset default styling for dialogs.
-*/
-
-dialog {
- padding: 0;
-}
-
-/*
-Prevent resizing textareas horizontally by default.
-*/
-
-textarea {
- resize: vertical;
-}
-
-/*
-1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
-2. Set the default placeholder color to the user's configured gray 400 color.
-*/
-
-input::-moz-placeholder, textarea::-moz-placeholder {
- opacity: 1;
- /* 1 */
- color: #9ca3af;
- /* 2 */
-}
-
-input::placeholder,
-textarea::placeholder {
- opacity: 1;
- /* 1 */
- color: #9ca3af;
- /* 2 */
-}
-
-/*
-Set the default cursor for buttons.
-*/
-
-button,
-[role="button"] {
- cursor: pointer;
-}
-
-/*
-Make sure disabled buttons don't get the pointer cursor.
-*/
-
-:disabled {
- cursor: default;
-}
-
-/*
-1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
-2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
- This can trigger a poorly considered lint error in some tools but is included by design.
-*/
-
-img,
-svg,
-video,
-canvas,
-audio,
-iframe,
-embed,
-object {
- display: block;
- /* 1 */
- vertical-align: middle;
- /* 2 */
-}
-
-/*
-Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
-*/
-
-img,
-video {
- max-width: 100%;
- height: auto;
-}
-
-/* Make elements with the HTML hidden attribute stay hidden by default */
-
-[hidden]:where(:not([hidden="until-found"])) {
- display: none;
-}
-
-.container {
- width: 100%;
-}
-
-@media (min-width: 640px) {
- .container {
- max-width: 640px;
- }
-}
-
-@media (min-width: 768px) {
- .container {
- max-width: 768px;
- }
-}
-
-@media (min-width: 1024px) {
- .container {
- max-width: 1024px;
- }
-}
-
-@media (min-width: 1280px) {
- .container {
- max-width: 1280px;
- }
-}
-
-@media (min-width: 1536px) {
- .container {
- max-width: 1536px;
- }
-}
-
-.mx-auto {
- margin-left: auto;
- margin-right: auto;
-}
-
-.mb-12 {
- margin-bottom: 3rem;
-}
-
-.mb-4 {
- margin-bottom: 1rem;
-}
-
-.mb-8 {
- margin-bottom: 2rem;
-}
-
-.mt-8 {
- margin-top: 2rem;
-}
-
-.block {
- display: block;
-}
-
-.flex {
- display: flex;
-}
-
-.table {
- display: table;
-}
-
-.grid {
- display: grid;
-}
-
-.hidden {
- display: none;
-}
-
-.transform {
- transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
-}
-
-.items-center {
- align-items: center;
-}
-
-.justify-center {
- justify-content: center;
-}
-
-.justify-between {
- justify-content: space-between;
-}
-
-.gap-8 {
- gap: 2rem;
-}
-
-.space-x-4 > :not([hidden]) ~ :not([hidden]) {
- --tw-space-x-reverse: 0;
- margin-right: calc(1rem * var(--tw-space-x-reverse));
- margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse)));
-}
-
-.space-x-8 > :not([hidden]) ~ :not([hidden]) {
- --tw-space-x-reverse: 0;
- margin-right: calc(2rem * var(--tw-space-x-reverse));
- margin-left: calc(2rem * calc(1 - var(--tw-space-x-reverse)));
-}
-
-.space-y-2 > :not([hidden]) ~ :not([hidden]) {
- --tw-space-y-reverse: 0;
- margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
- margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
-}
-
-.rounded-lg {
- border-radius: 0.5rem;
-}
-
-.border {
- border-width: 1px;
-}
-
-.border-t {
- border-top-width: 1px;
-}
-
-.border-gray-600 {
- --tw-border-opacity: 1;
- border-color: rgb(75 85 99 / var(--tw-border-opacity, 1));
-}
-
-.border-gray-800 {
- --tw-border-opacity: 1;
- border-color: rgb(31 41 55 / var(--tw-border-opacity, 1));
-}
-
-.bg-black\/50 {
- background-color: rgb(0 0 0 / 0.5);
-}
-
-.bg-blue-600 {
- --tw-bg-opacity: 1;
- background-color: rgb(37 99 235 / var(--tw-bg-opacity, 1));
-}
-
-.bg-gray-900 {
- --tw-bg-opacity: 1;
- background-color: rgb(17 24 39 / var(--tw-bg-opacity, 1));
-}
-
-.bg-gray-900\/50 {
- background-color: rgb(17 24 39 / 0.5);
-}
-
-.p-6 {
- padding: 1.5rem;
-}
-
-.px-6 {
- padding-left: 1.5rem;
- padding-right: 1.5rem;
-}
-
-.px-8 {
- padding-left: 2rem;
- padding-right: 2rem;
-}
-
-.py-16 {
- padding-top: 4rem;
- padding-bottom: 4rem;
-}
-
-.py-2 {
- padding-top: 0.5rem;
- padding-bottom: 0.5rem;
-}
-
-.py-20 {
- padding-top: 5rem;
- padding-bottom: 5rem;
-}
-
-.py-3 {
- padding-top: 0.75rem;
- padding-bottom: 0.75rem;
-}
-
-.py-4 {
- padding-top: 1rem;
- padding-bottom: 1rem;
-}
-
-.pt-8 {
- padding-top: 2rem;
-}
-
-.text-center {
- text-align: center;
-}
-
-.text-2xl {
- font-size: 1.5rem;
- line-height: 2rem;
-}
-
-.text-3xl {
- font-size: 1.875rem;
- line-height: 2.25rem;
-}
-
-.text-4xl {
- font-size: 2.25rem;
- line-height: 2.5rem;
-}
-
-.text-lg {
- font-size: 1.125rem;
- line-height: 1.75rem;
-}
-
-.text-xl {
- font-size: 1.25rem;
- line-height: 1.75rem;
-}
-
-.font-bold {
- font-weight: 700;
-}
-
-.font-semibold {
- font-weight: 600;
-}
-
-.text-gray-300 {
- --tw-text-opacity: 1;
- color: rgb(209 213 219 / var(--tw-text-opacity, 1));
-}
-
-.text-gray-400 {
- --tw-text-opacity: 1;
- color: rgb(156 163 175 / var(--tw-text-opacity, 1));
-}
-
-.text-white {
- --tw-text-opacity: 1;
- color: rgb(255 255 255 / var(--tw-text-opacity, 1));
-}
-
-.filter {
- filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
-}
-
-.transition {
- transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter;
- transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
- transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter;
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
- transition-duration: 150ms;
-}
-
-.duration-300 {
- transition-duration: 300ms;
-}
-
-.hover\:bg-blue-700:hover {
- --tw-bg-opacity: 1;
- background-color: rgb(29 78 216 / var(--tw-bg-opacity, 1));
-}
-
-.hover\:bg-gray-700:hover {
- --tw-bg-opacity: 1;
- background-color: rgb(55 65 81 / var(--tw-bg-opacity, 1));
-}
-
-.hover\:bg-gray-800:hover {
- --tw-bg-opacity: 1;
- background-color: rgb(31 41 55 / var(--tw-bg-opacity, 1));
-}
-
-.hover\:text-white:hover {
- --tw-text-opacity: 1;
- color: rgb(255 255 255 / var(--tw-text-opacity, 1));
-}
-
-@media (min-width: 768px) {
- .md\:flex {
- display: flex;
- }
-
- .md\:grid-cols-3 {
- grid-template-columns: repeat(3, minmax(0, 1fr));
- }
-
- .md\:grid-cols-4 {
- grid-template-columns: repeat(4, minmax(0, 1fr));
- }
-}
diff --git a/apps/backend/scripts/migrate.ts b/apps/backend/scripts/migrate.ts
deleted file mode 100644
index bb8bdcf8..00000000
--- a/apps/backend/scripts/migrate.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { config } from "dotenv";
-import { drizzle } from "drizzle-orm/postgres-js";
-import { migrate } from "drizzle-orm/postgres-js/migrator";
-import process from "node:process";
-import postgres from "postgres";
-
-config();
-
-const isProd = process.env.NODE_ENV === "production";
-const connectionString = isProd ? process.env.PROD_DATABASE_URL : process.env.DATABASE_URL;
-
-if (!connectionString) {
- throw new Error(`${isProd ? "PROD_DATABASE_URL" : "DATABASE_URL"} is not set`);
-}
-
-console.log("Connecting to:", connectionString.replace(/:[^:@]+@/, ":****@")); // Log sanitized connection string
-
-const migrationClient = postgres(connectionString, { max: 1 });
-
-async function main() {
- console.log("Running migrations...");
-
- try {
- const db = drizzle(migrationClient);
- await migrate(db, { migrationsFolder: "./drizzle" });
- console.log("Migrations completed!");
- } catch (error) {
- console.error("Migration failed:", error);
- } finally {
- await migrationClient.end();
- }
-}
-
-main().catch((err) => {
- console.error("Unexpected error:", err);
- process.exit(1);
-});
diff --git a/apps/backend/src/auth.ts b/apps/backend/src/auth.ts
deleted file mode 100644
index 0ceeb0c1..00000000
--- a/apps/backend/src/auth.ts
+++ /dev/null
@@ -1,151 +0,0 @@
-import { Context, Next } from "hono";
-import { getSessionFromRequest } from "@supermemory/authkit-remix-cloudflare/src/session";
-import { and, database, eq, sql } from "@supermemory/db";
-import { User, users } from "@supermemory/db/schema";
-import { Env, Variables } from "./types";
-import { encrypt, decrypt } from "./utils/cipher";
-
-interface EncryptedData {
- userId: string;
- lastApiKeyGeneratedAt: string;
-}
-
-export const getApiKey = async (
- userId: string,
- lastApiKeyGeneratedAt: string,
- c: Context<{ Variables: Variables; Bindings: Env }>
-) => {
- const data = `${userId}-${lastApiKeyGeneratedAt}`;
- return "sm_" + (await encrypt(data, c.env.WORKOS_COOKIE_PASSWORD));
-};
-
-export const decryptApiKey = async (
- encryptedKey: string,
- c: Context<{ Variables: Variables; Bindings: Env }>
-): Promise
=> {
- const ourKey = encryptedKey.slice(3);
- const decrypted = await decrypt(ourKey, c.env.WORKOS_COOKIE_PASSWORD);
- const [userId, lastApiKeyGeneratedAt] = decrypted.split("-");
-
- return {
- userId,
- lastApiKeyGeneratedAt,
- };
-};
-
-export const auth = async (
- c: Context<{ Variables: Variables; Bindings: Env }>,
- next: Next
-) => {
- // Handle CORS preflight requests
- if (c.req.method === "OPTIONS") {
- return next()
- }
-
- // Set cache control headers
- c.header("Cache-Control", "private, no-cache, no-store, must-revalidate");
- c.header("Pragma", "no-cache");
- c.header("Expires", "0");
-
- let user: User | User[] | undefined;
-
- // Check for API key authentication first
- const authHeader = c.req.raw.headers.get("Authorization");
- if (authHeader?.startsWith("Bearer ")) {
- const apiKey = authHeader.slice(7);
- try {
- const { userId, lastApiKeyGeneratedAt } = await decryptApiKey(apiKey, c);
-
- // Look up user with matching id and lastApiKeyGeneratedAt
- user = await database(c.env.HYPERDRIVE.connectionString)
- .select()
- .from(users)
- .where(
- and(
- eq(users.uuid, userId)
- )
- )
- .limit(1);
-
- if (user && Array.isArray(user)) {
- user = user[0];
- if (user && user.lastApiKeyGeneratedAt?.getTime() === Number(lastApiKeyGeneratedAt)) {
- c.set("user", user);
- } else {
- return c.json({ error: "Invalid API key - user not found" }, 401);
- }
- }
- } catch (err) {
- console.error("API key authentication failed:", err);
- return c.json({ error: "Invalid API key format" }, 401);
- }
- }
-
- // If no user found via API key, try cookie authentication
- if (!user) {
- const cookies = c.req.raw.headers.get("Cookie");
- if (cookies) {
- // Fake remix context object. this just works.
- const context = {
- cloudflare: {
- env: c.env,
- },
- };
-
- const session = await getSessionFromRequest(c.req.raw, context);
- console.log("Session", session);
- c.set("session", session);
-
- if (session?.user?.id) {
- user = await database(c.env.HYPERDRIVE.connectionString)
- .select()
- .from(users)
- .where(eq(users.uuid, session.user.id))
- .limit(1);
-
- if ((!user || user.length === 0) && session?.user?.id) {
- const newUser = await database(c.env.HYPERDRIVE.connectionString)
- .insert(users)
- .values({
- uuid: session.user?.id,
- email: session.user?.email,
- firstName: session.user?.firstName,
- lastName: session.user?.lastName,
- createdAt: new Date(),
- updatedAt: new Date(),
- emailVerified: false,
- profilePictureUrl: session.user?.profilePictureUrl ?? "",
- })
- .returning()
- .onConflictDoUpdate({
- target: [users.email],
- set: {
- uuid: session.user.id,
- },
- });
-
- user = newUser[0];
- }
-
- user = Array.isArray(user) ? user[0] : user;
- c.set("user", user);
- console.log("User", user);
- }
- }
- }
-
- // Check if request requires authentication
- const isPublicSpaceRequest =
- c.req.url.includes("/v1/spaces/") || c.req.url.includes("/v1/memories");
-
- if (!isPublicSpaceRequest && !c.get("user")) {
- console.log("Unauthorized access to", c.req.url);
- if (authHeader) {
- return c.json({ error: "Invalid authentication credentials" }, 401);
- } else {
- return c.json({ error: "Authentication required" }, 401);
- }
- }
-
- return next();
-};
diff --git a/apps/backend/src/components/landing.tsx b/apps/backend/src/components/landing.tsx
deleted file mode 100644
index 87bbdb69..00000000
--- a/apps/backend/src/components/landing.tsx
+++ /dev/null
@@ -1,234 +0,0 @@
-import { html } from "hono/html";
-
-export function LandingPage() {
- return (
-
-
-
-
-
- Supermemory API
-
-
-
-
-
-
-
-
- Key Features
-
-
-
-
- Battle-Tested RAG Stack
-
-
- Production-ready retrieval augmented generation architecture
- for reliable and scalable information retrieval.
-
-
-
-
- Flexible LLM Integration
-
-
- Use any LLM of your choice or operate in search-only mode
- for maximum flexibility and control.
-
-
-
-
- Advanced Access Control
-
-
- Comprehensive collection filtering and permission management
- for secure data access.
-
-
-
-
- Seamless Data Import
-
-
- Magic link import and platform synchronization for
- effortless data integration.
-
-
-
-
- Real-time Monitoring
-
-
- Track and analyze memory usage patterns in real-time with
- detailed metrics.
-
-
-
-
- Easy Integration
-
-
- Simple API endpoints that integrate seamlessly with your
- existing infrastructure.
-
-
-
-
-
-
-
-
-
-
-
- Supermemory API
-
-
- Making memory management simple and efficient for developers
- worldwide.
-
-
-
-
-
-
-
© 2024 Supermemory API. All rights reserved.
-
-
-
-
-
-
-
-
- );
-}
diff --git a/apps/backend/src/errors/baseError.ts b/apps/backend/src/errors/baseError.ts
deleted file mode 100644
index bccc54df..00000000
--- a/apps/backend/src/errors/baseError.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-export class BaseHttpError extends Error {
- public status: number;
- public message: string;
-
- constructor(status: number, message: string) {
- super(message);
- this.status = status;
- this.message = message;
- Object.setPrototypeOf(this, new.target.prototype); // Restore prototype chain
- }
- }
-
-
- export class BaseError extends Error {
- type: string;
- message: string;
- source: string;
- ignoreLog: boolean;
-
- constructor(
- type: string,
- message?: string,
- source?: string,
- ignoreLog = false
- ) {
- super();
-
- Object.setPrototypeOf(this, new.target.prototype);
-
- this.type = type;
- this.message =
- message ??
- "An unknown error occurred. If this persists, please contact us.";
- this.source = source ?? "unspecified";
- this.ignoreLog = ignoreLog;
- }
-
- toJSON(): Record {
- return {
- type: this.type,
- message: this.message,
- source: this.source,
- };
- }
- }
\ No newline at end of file
diff --git a/apps/backend/src/errors/results.ts b/apps/backend/src/errors/results.ts
deleted file mode 100644
index c5ab115b..00000000
--- a/apps/backend/src/errors/results.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { BaseError } from "./baseError";
-
-export type Result =
- | { ok: true; value: T }
- | { ok: false; error: E };
-
-export const Ok = (data: T): Result => {
- return { ok: true, value: data };
-};
-
-export const Err = (error: E): Result => {
- return { ok: false, error };
-};
-
-export async function wrap(
- p: Promise,
- errorFactory: (err: Error, source: string) => E,
- source: string = "unspecified"
- ): Promise> {
- try {
- return Ok(await p);
- } catch (e) {
- return Err(errorFactory(e as Error, source));
- }
- }
-
-export function isErr(
- result: Result,
-): result is { ok: false; error: E } {
- return !result.ok;
-}
\ No newline at end of file
diff --git a/apps/backend/src/globals.css b/apps/backend/src/globals.css
deleted file mode 100644
index b5c61c95..00000000
--- a/apps/backend/src/globals.css
+++ /dev/null
@@ -1,3 +0,0 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
diff --git a/apps/backend/src/index.tsx b/apps/backend/src/index.tsx
deleted file mode 100644
index 4ccbb4c0..00000000
--- a/apps/backend/src/index.tsx
+++ /dev/null
@@ -1,255 +0,0 @@
-import { z } from "zod";
-import { type Context, Hono } from "hono";
-import { auth } from "./auth";
-import { logger } from "hono/logger";
-import { timing } from "hono/timing";
-import type { Env, Variables } from "./types";
-import { zValidator } from "@hono/zod-validator";
-import { database } from "@supermemory/db";
-import { waitlist } from "@supermemory/db/schema";
-import { cors } from "hono/cors";
-import { ContentWorkflow } from "./workflow";
-import { Resend } from "resend";
-import { LandingPage } from "./components/landing";
-import user from "./routes/user";
-import spacesRoute from "./routes/spaces";
-import actions from "./routes/actions";
-import memories from "./routes/memories";
-import integrations from "./routes/integrations";
-import { fromHono } from "chanfana";
-import {
- DurableObjectRateLimiter,
- DurableObjectStore,
-} from "@hono-rate-limiter/cloudflare";
-import type { ConfigType, GeneralConfigType, rateLimiter } from "hono-rate-limiter";
-
-// Create base Hono app first
-const honoApp = new Hono<{ Variables: Variables; Bindings: Env }>();
-
-const app = fromHono(honoApp);
-
-// Add all middleware and routes
-app.use("*", timing());
-app.use("*", logger());
-app.use(
- "*",
- cors({
- origin: [
- "http://localhost:3000",
- "https://supermemory.ai",
- "https://*.supermemory.ai",
- "https://*.supermemory.com",
- "https://supermemory.com",
- "chrome-extension://*",
- ],
- allowHeaders: ["*"],
- allowMethods: ["*"],
- credentials: true,
- exposeHeaders: ["*"],
- })
-);
-
-app.use("/v1/*", auth);
-app.use("/v1/*", (c, next) => {
- const user = c.get("user");
-
- if (c.env.NODE_ENV === "development") {
- return next();
- }
-
- // RATELIMITS
- const rateLimitConfig = {
- // Endpoints that bypass rate limiting
- excludedPaths: [
- "/v1/add",
- "/v1/chat",
- "/v1/suggested-learnings",
- "/v1/recommended-questions",
- ] as (string | RegExp)[],
-
- // Custom rate limits for specific endpoints
- customLimits: {
- notionImport: {
- paths: ["/v1/integrations/notion/import", "/v1/integrations/notion"],
- windowMs: 10 * 60 * 1000, // 10 minutes
- limit: 5, // 5 requests per 10 minutes
- },
- inviteSpace: {
- paths: [/^\v1\/spaces\/[^/]+\/invite$/],
- windowMs: 60 * 1000, // 1 minute
- limit: 5, // 5 requests per minute
- },
- } as Record<
- string,
- { paths: (string | RegExp)[]; windowMs: number; limit: number }
- >,
-
- default: {
- windowMs: 60 * 1000, // 1 minute
- limit: 100, // 100 requests per minute
- },
-
- common: {
- standardHeaders: "draft-6",
- keyGenerator: (c: Context) =>
- `${user?.uuid ?? c.req.header("cf-connecting-ip")}-${new Date().getDate()}`, // day so that limit gets reset every day
- store: new DurableObjectStore({ namespace: c.env.RATE_LIMITER }),
- } as GeneralConfigType,
- };
-
- if (
- c.req.path &&
- rateLimitConfig.excludedPaths.some((path) =>
- typeof path === "string" ? c.req.path === path : path.test(c.req.path)
- )
- ) {
- return next();
- }
-
- // Check for custom rate limits
- for (const [_, config] of Object.entries(rateLimitConfig.customLimits)) {
- if (
- config.paths.some((path) =>
- typeof path === "string" ? c.req.path === path : path.test(c.req.path)
- )
- ) {
- return rateLimiter({
- windowMs: config.windowMs,
- limit: config.limit,
- ...rateLimitConfig.common,
- })(c as any, next);
- }
- }
-
- // Apply default rate limit
- return rateLimiter({
- windowMs: rateLimitConfig.default.windowMs,
- limit: rateLimitConfig.default.limit,
- ...rateLimitConfig.common,
- })(c as any, next);
-});
-
-app.get("/", (c) => {
- return c.html( );
-});
-
-// TEMPORARY REDIRECT
-app.all("/api/*", async (c) => {
- // Get the full URL and path
- const url = new URL(c.req.url);
- const path = url.pathname;
- const newPath = path.replace("/api", "/v1");
-
- // Preserve query parameters and build target URL
- const redirectUrl = `https://api.supermemory.ai${newPath}${url.search}`;
-
- // Use c.redirect() for a proper redirect
- return c.redirect(redirectUrl);
-});
-
-app.route("/v1/user", user);
-app.route("/v1/spaces", spacesRoute);
-app.route("/v1", actions);
-app.route("/v1/integrations", integrations);
-app.route("/v1/memories", memories);
-
-app.get("/v1/session", (c) => {
- const user = c.get("user");
-
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- return c.json({
- user,
- });
-});
-
-app.post(
- "/waitlist",
- zValidator(
- "json",
- z.object({ email: z.string().email(), token: z.string() })
- ),
- async (c) => {
- const { email, token } = c.req.valid("json");
-
- const address = c.req.raw.headers.get("CF-Connecting-IP");
-
- const idempotencyKey = crypto.randomUUID();
- const url = "https://challenges.cloudflare.com/turnstile/v0/siteverify";
- const firstResult = await fetch(url, {
- body: JSON.stringify({
- secret: c.env.TURNSTILE_SECRET_KEY,
- response: token,
- remoteip: address,
- idempotency_key: idempotencyKey,
- }),
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- });
-
- const firstOutcome = (await firstResult.json()) as { success: boolean };
-
- if (!firstOutcome.success) {
- console.info("Turnstile verification failed", firstOutcome);
- return c.json(
- { error: "Turnstile verification failed" },
- 439 as StatusCode
- );
- }
-
- const resend = new Resend(c.env.RESEND_API_KEY);
-
- const db = database(c.env.HYPERDRIVE.connectionString);
-
- const ip =
- c.req.header("cf-connecting-ip") ||
- `${c.req.raw.cf?.asn}-${c.req.raw.cf?.country}-${c.req.raw.cf?.city}-${c.req.raw.cf?.region}-${c.req.raw.cf?.postalCode}`;
-
- const { success } = await c.env.EMAIL_LIMITER.limit({ key: ip });
-
- if (!success) {
- return c.json({ error: "Rate limit exceeded" }, 429);
- }
-
- const message = `Supermemory started as a side project a few months ago when I built it as a hackathon project.
-
- you guys loved it too much. like wayy too much. it was embarrassing, because this was not it - it was nothing but a hackathon project.
-
- I launched on github too. https://github.com/supermemoryai/supermemory , and we were somehow one of the fastest growing open source repositories in Q3 2024.
-
- So, it's time to make this good. My vision is to make supermemory the best memory tool on the internet.
- `;
-
- try {
- await db.insert(waitlist).values({ email });
- await resend.emails.send({
- from: "Dhravya From Supermemory ",
- to: email,
- subject: "You're in the waitlist - A personal note from Dhravya",
- html: `Hi. I'm Dhravya. I'm building Supermemory to help people remember everything. ${message} I'll be in touch when we launch! Till then, just reply to this email if you wanna talk :) If you want to follow me on X, here's my handle: @dhravyashah - Dhravya
`,
- });
- } catch (e) {
- console.error(e);
- return c.json({ error: "Failed to add to waitlist" }, 400);
- }
-
- return c.json({ success: true });
- }
-);
-
-app.onError((err, c) => {
- console.error(err);
- return c.json({ error: "Internal server error" }, 500);
-});
-
-export default {
- fetch: app.fetch,
-};
-
-export { ContentWorkflow, DurableObjectRateLimiter };
-
-export type AppType = typeof app;
diff --git a/apps/backend/src/providers.ts b/apps/backend/src/providers.ts
deleted file mode 100644
index ed9644a3..00000000
--- a/apps/backend/src/providers.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { createOpenAI, OpenAIProvider } from "@ai-sdk/openai";
-import { createGoogleGenerativeAI } from "@ai-sdk/google";
-import { Env } from "./types";
-
-export function openai(
- env: Env,
- apiKey?: string
-): ReturnType {
- return createOpenAI({
- apiKey: apiKey || env.OPEN_AI_API_KEY,
- baseURL: "https://gateway.ai.cloudflare.com/v1/47c2b4d598af9d423c06fc9f936226d5/supermemory/openai"
- });
-}
-
-export function google(securityKey: string) {
- return createGoogleGenerativeAI({
- apiKey: securityKey,
- });
-}
diff --git a/apps/backend/src/routes/actions.ts b/apps/backend/src/routes/actions.ts
deleted file mode 100644
index 581e7787..00000000
--- a/apps/backend/src/routes/actions.ts
+++ /dev/null
@@ -1,1171 +0,0 @@
-import { Hono } from "hono";
-import { Variables, Env, recommendedQuestionsSchema } from "../types";
-import { zValidator } from "@hono/zod-validator";
-import { z } from "zod";
-import {
- AISDKError,
- convertToCoreMessages,
- embed,
- generateObject,
- InvalidPromptError,
- Message,
- smoothStream,
- StreamData,
- streamText,
- TextPart,
-} from "ai";
-import {
- chatThreads,
- documents,
- chunk,
- spaces as spaceInDb,
- spaceAccess,
- type Space,
- contentToSpace,
-} from "@supermemory/db/schema";
-import { google, openai } from "../providers";
-import { randomId } from "@supermemory/shared";
-import {
- and,
- cosineDistance,
- database,
- desc,
- eq,
- exists,
- inArray,
- or,
- sql,
-} from "@supermemory/db";
-import { typeDecider } from "../utils/typeDecider";
-import { isErr, Ok } from "../errors/results";
-import { fromHono } from "chanfana";
-
-const actions = fromHono(new Hono<{ Variables: Variables; Bindings: Env }>())
- .post(
- "/chat",
- zValidator(
- "json",
- z.object({
- messages: z.array(z.any()).min(1, "At least one message is required"),
- threadId: z.string().optional(),
- })
- ),
- async (c) => {
- const user = c.get("user");
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const { messages, threadId } = await c.req.valid("json");
-
- const unfilteredCoreMessages = convertToCoreMessages(
- (messages as Message[])
- .filter((m) => m.content.length > 0)
- .map((m) => ({
- ...m,
- content:
- m.content +
- (m.annotations
- ? `${JSON.stringify(m.annotations)} `
- : ""),
- experimental_attachments:
- m.experimental_attachments?.length &&
- m.experimental_attachments?.length > 0
- ? m.experimental_attachments
- : (m.data as { files: [] })?.files,
- }))
- );
-
- const coreMessages = unfilteredCoreMessages.filter(
- (message) => message.content.length > 0
- );
-
- const db = database(c.env.HYPERDRIVE.connectionString);
- const { initLogger, wrapAISDKModel } = await import("braintrust");
-
- // Initialize clients and loggers
- const logger = initLogger({
- projectName: "supermemory",
- apiKey: c.env.BRAINTRUST_API_KEY,
- });
-
- const googleClient = wrapAISDKModel(
- openai(c.env).chat("gpt-4o-mini-2024-07-18")
- );
-
- // Get last user message and generate embedding in parallel with thread creation
- let lastUserMessage = coreMessages.findLast((i) => i.role === "user");
- const queryText =
- typeof lastUserMessage?.content === "string"
- ? lastUserMessage.content
- : lastUserMessage?.content.map((c) => (c as TextPart).text).join("");
-
- if (!queryText || queryText.length === 0) {
- return c.json({ error: "Empty query" }, 400);
- }
-
- // Run embedding generation and thread creation in parallel
- const [{ data: embedding }, thread] = await Promise.all([
- c.env.AI.run("@cf/baai/bge-base-en-v1.5", { text: queryText }),
- !threadId
- ? db
- .insert(chatThreads)
- .values({
- firstMessage: messages[0].content,
- userId: user.id,
- uuid: randomId(),
- messages: coreMessages,
- })
- .returning()
- : null,
- ]);
-
- const threadUuid = threadId || thread?.[0].uuid;
-
- if (!embedding) {
- return c.json({ error: "Failed to generate embedding" }, 500);
- }
-
- try {
- const data = new StreamData();
-
- // Pre-compute the vector similarity expression
- const vectorSimilarity = sql`1 - (embeddings <=> ${JSON.stringify(embedding[0])}::vector)`;
-
- // Get matching chunks with document info
- const matchingChunks = await db
- .select({
- chunkId: chunk.id,
- documentId: chunk.documentId,
- textContent: chunk.textContent,
- orderInDocument: chunk.orderInDocument,
- metadata: chunk.metadata,
- similarity: vectorSimilarity,
- // Document fields
- docId: documents.id,
- docUuid: documents.uuid,
- docContent: documents.content,
- docType: documents.type,
- docUrl: documents.url,
- docTitle: documents.title,
- docDescription: documents.description,
- docOgImage: documents.ogImage,
- })
- .from(chunk)
- .innerJoin(documents, eq(chunk.documentId, documents.id))
- .where(
- and(eq(documents.userId, user.id), sql`${vectorSimilarity} > 0.3`)
- )
- .orderBy(desc(vectorSimilarity))
- .limit(25);
-
- // Get unique document IDs from matching chunks
- const uniqueDocIds = [
- ...new Set(matchingChunks.map((c) => c.documentId)),
- ];
-
- // Fetch all chunks for these documents to get context
- const contextChunks = await db
- .select({
- id: chunk.id,
- documentId: chunk.documentId,
- textContent: chunk.textContent,
- orderInDocument: chunk.orderInDocument,
- metadata: chunk.metadata,
- })
- .from(chunk)
- .where(inArray(chunk.documentId, uniqueDocIds))
- .orderBy(chunk.documentId, chunk.orderInDocument);
-
- // Group chunks by document
- const chunksByDocument = new Map();
- for (const chunk of contextChunks) {
- const docChunks = chunksByDocument.get(chunk.documentId) || [];
- docChunks.push(chunk);
- chunksByDocument.set(chunk.documentId, docChunks);
- }
-
- // Create context with surrounding chunks
- const contextualResults = matchingChunks.map((match) => {
- const docChunks = chunksByDocument.get(match.documentId) || [];
- const matchIndex = docChunks.findIndex((c) => c.id === match.chunkId);
-
- // Get surrounding chunks (2 before and 2 after for more context)
- const start = Math.max(0, matchIndex - 2);
- const end = Math.min(docChunks.length, matchIndex + 3);
- const relevantChunks = docChunks.slice(start, end);
-
- return {
- id: match.docId,
- title: match.docTitle,
- description: match.docDescription,
- url: match.docUrl,
- type: match.docType,
- content: relevantChunks.map((c) => c.textContent).join("\n"),
- similarity: Number(match.similarity.toFixed(4)),
- chunks: relevantChunks.map((c) => ({
- id: c.id,
- content: c.textContent,
- orderInDocument: c.orderInDocument,
- metadata: c.metadata,
- isMatch: c.id === match.chunkId,
- })),
- };
- });
-
- // Sort by similarity and take top results
- const topResults = contextualResults
- .sort((a, b) => b.similarity - a.similarity)
- .slice(0, 10);
-
- data.appendMessageAnnotation(topResults);
-
- if (lastUserMessage) {
- lastUserMessage.content =
- typeof lastUserMessage.content === "string"
- ? lastUserMessage.content +
- `${JSON.stringify(topResults)} `
- : [
- ...lastUserMessage.content,
- {
- type: "text",
- text: `${JSON.stringify(topResults)} `,
- },
- ];
- coreMessages[coreMessages.length - 1] = lastUserMessage;
- }
-
- const result = await streamText({
- model: googleClient,
- experimental_providerMetadata: {
- metadata: { userId: user.id, chatThreadId: threadUuid ?? "" },
- },
- experimental_transform: smoothStream(),
- messages: [
- {
- role: "system",
- content: `You are a knowledgeable and helpful AI assistant for Supermemory, a personal knowledge management app. Your goal is to help users explore and understand their saved content.
-
- Key guidelines:
- - Maintain natural, engaging conversation while seamlessly incorporating relevant information from the user's knowledge base
- - Build on previous messages in the conversation to provide coherent, contextual responses
- - Be concise but thorough, focusing on the most relevant details
- - When appropriate, make connections between different pieces of information
- - If you're not sure about something, be honest and say so
- - Feel free to ask clarifying questions if needed
- - Make it easy to read for the user!
- - Use markdown to format your responses but dont make your answers TOO long include any and all information related to context in the response if possible.
- - only talk about the context if the right answer is in the context.
- - You are Supermemory - a personal knowledge management app.
- - You are built by Dhravya Shah (https://dhravya.dev). And the supermemory team (https://supermemory.ai).
-
- The user's saved content is provided in tags. Use this information naturally without explicitly referencing it.`,
- },
- ...coreMessages,
- ],
- async onFinish(completion) {
- try {
- if (lastUserMessage) {
- lastUserMessage.content =
- typeof lastUserMessage.content === "string"
- ? lastUserMessage.content.replace(
- /[\s\S]*?<\/context>/g,
- ""
- )
- : lastUserMessage.content.filter(
- (part) =>
- !(
- part.type === "text" &&
- part.text.startsWith("")
- )
- );
- coreMessages[coreMessages.length - 1] = lastUserMessage;
- }
-
- const newMessages = [
- ...coreMessages,
- {
- role: "assistant",
- content:
- completion.text +
- `[${JSON.stringify(topResults)}] `,
- },
- ];
-
- if (threadUuid) {
- await db
- .update(chatThreads)
- .set({ messages: newMessages })
- .where(eq(chatThreads.uuid, threadUuid));
- }
- } catch (error) {
- console.error("Failed to update thread:", error);
- } finally {
- await data.close();
- }
- },
- });
-
- return result.toDataStreamResponse({
- headers: {
- "Supermemory-Thread-Uuid": threadUuid ?? "",
- "Content-Type": "text/x-unknown",
- "content-encoding": "identity",
- "transfer-encoding": "chunked",
- },
- data,
- });
- } catch (error) {
- console.error("Chat error:", error);
-
- if (error instanceof InvalidPromptError) {
- return c.json(
- { error: "Invalid prompt - please rephrase your message" },
- 400
- );
- }
-
- if ((error as AISDKError).cause === "ECONNREFUSED") {
- return c.json({ error: "Database connection failed" }, 503);
- }
-
- return c.json(
- {
- error: "An unexpected error occurred",
- details:
- c.env.NODE_ENV === "development"
- ? (error as Error).message
- : undefined,
- },
- 500
- );
- }
- }
- )
- .get(
- "/chat/:threadUuid",
- zValidator(
- "param",
- z.object({
- threadUuid: z.string(),
- })
- ),
- async (c) => {
- const user = c.get("user");
- const threadUuid = c.req.valid("param").threadUuid;
-
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const chatHistory = await database(c.env.HYPERDRIVE.connectionString)
- .select()
- .from(chatThreads)
- .where(
- and(eq(chatThreads.userId, user.id), eq(chatThreads.uuid, threadUuid))
- );
-
- if (!chatHistory) {
- return c.json({ error: "Chat history not found" }, 404);
- }
-
- return c.json({ chatHistory: chatHistory[0].messages });
- }
- )
- .get("/recommended-questions", async (c) => {
- const user = c.get("user");
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const db = database(c.env.HYPERDRIVE.connectionString);
- const recentDocuments = await db
- .select()
- .from(documents)
- .where(eq(documents.userId, user.id))
- .orderBy(sql`RANDOM()`)
- .limit(3);
-
- if (recentDocuments.length === 0) {
- return c.json({ questions: [] });
- }
-
- const cachedQuestions = await c.env.MD_CACHE.get(`rq:${user.id}`);
- if (cachedQuestions) {
- const randomQuestions = JSON.parse(cachedQuestions)
- .questions.sort(() => Math.random() - 0.5)
- .slice(0, 3);
- return c.json({ questions: randomQuestions });
- }
-
- const { initLogger, wrapAISDKModel } = await import("braintrust");
-
- const logger = initLogger({
- projectName: "supermemory",
- apiKey: c.env.BRAINTRUST_API_KEY,
- });
-
- const model = wrapAISDKModel(openai(c.env).chat("gpt-4o-mini-2024-07-18"));
-
- const aiResponse = await generateObject({
- schema: z.object({
- questions: recommendedQuestionsSchema,
- }),
- model,
- prompt: `You are helping generate search suggestions for a user's personal knowledge base.
-
- Generate 10 specific, focused questions based on the following documents. The questions should:
- - Be highly specific and reference concrete details from the documents
- - Focus on key insights, important facts, or interesting relationships
- - Be phrased naturally, as if the user is trying to recall something they learned
- - Be 2-8 words long
- - Not include generic questions that could apply to any document
-
- Documents:
- ${recentDocuments.map((d) => d.content).join("\n\n")}`,
- });
-
- await c.env.MD_CACHE.put(
- `rq:${user.id}`,
- JSON.stringify(aiResponse.object),
- {
- // 3 hours
- expirationTtl: 10800,
- }
- );
-
- const questions = aiResponse.object.questions;
- const randomQuestions = questions
- .sort(() => Math.random() - 0.5)
- .slice(0, 3);
- return c.json({ questions: randomQuestions });
- })
- .get("/suggested-learnings", async (c) => {
- const user = await c.get("user");
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const db = database(c.env.HYPERDRIVE.connectionString);
-
- // Try to get from cache first
- const cacheKey = `sl:${user.id}`;
- const cached = await c.env.MD_CACHE.get(cacheKey);
- if (cached) {
- return c.json({
- suggestedLearnings: JSON.parse(cached) as { [x: string]: string },
- });
- }
-
- // Get random sample of user's documents that are well-distributed
- const recentLearnings = await db
- .select()
- .from(documents)
- .where(eq(documents.userId, user.id))
- // Use random() to get distributed sample
- .orderBy(sql`RANDOM()`)
- .limit(7);
-
- if (recentLearnings.length === 0 || recentLearnings.length < 3) {
- return c.json({ suggestedLearnings: [] });
- }
-
- // for each document, i want to generate a list of
- // small markdown tweet-like things that the user might want to remember about
- const suggestedLearnings = await Promise.all(
- recentLearnings.map(async (document) => {
- const model = openai(c.env).chat("gpt-4o-mini-2024-07-18");
- const prompt = `Generate a concise topic recall card for this document. The card should:
- - Have a clear title that captures the main topic
- - based on when the document was saved, include a brief "Last (week/month/...), you saved notes on..." intro (do something different every time.)
- - List 2-3 key points from the content in simple bullet points
- - Keep the total length under 280 characters
- - Focus on the core concepts worth remembering
- - Be in markdown format
- - if you don't have a good suggestions, just skip that document.
-
- Here's the document content: ${document.content}, Document saved at: ${document.updatedAt}, Today's date: ${new Date().toLocaleDateString()}`;
- const response = await generateObject({
- schema: z.object({
- [document.uuid]: z.string(),
- }),
- // @ts-ignore
- model,
- prompt,
- });
- return response.object;
- })
- );
-
- // Cache the results
- await c.env.MD_CACHE.put(cacheKey, JSON.stringify(suggestedLearnings), {
- expirationTtl: 60 * 60 * 3, // 3 hours
- });
-
- return c.json({ suggestedLearnings });
- })
- .post(
- "/search",
- zValidator(
- "json",
- z.object({
- query: z.string().min(1, "Search query cannot be empty"),
- limit: z.number().min(1).max(50).default(10),
- threshold: z.number().min(0).max(1).default(0),
- spaces: z.array(z.string()).optional(),
- })
- ),
- async (c) => {
- const { query, limit, threshold, spaces } = c.req.valid("json");
- const user = c.get("user");
-
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const db = database(c.env.HYPERDRIVE.connectionString);
-
- if (spaces && spaces.length > 0) {
- const spaceDetails = await Promise.all(
- spaces.map(async (spaceId) => {
- const space = await db
- .select()
- .from(spaceInDb)
- .where(eq(spaceInDb.uuid, spaceId))
- .limit(1);
-
- if (space.length === 0) return null;
- return {
- id: space[0].id,
- ownerId: space[0].ownerId,
- uuid: space[0].uuid,
- };
- })
- );
-
- // Filter out any null values and check permissions
- const validSpaces = spaceDetails.filter(
- (s): s is NonNullable => s !== null
- );
- const unauthorized = validSpaces.filter((s) => s.ownerId !== user.id);
-
- if (unauthorized.length > 0) {
- return c.json(
- {
- error: "Space permission denied",
- details: unauthorized.map((s) => s.uuid).join(", "),
- },
- 403
- );
- }
-
- // Replace UUIDs with IDs for the database query
- spaces.splice(
- 0,
- spaces.length,
- ...validSpaces.map((s) => s.id.toString())
- );
- }
-
- try {
- // Generate embedding for the search query
- const embeddings = await c.env.AI.run("@cf/baai/bge-base-en-v1.5", {
- text: query,
- });
-
- if (!embeddings.data) {
- return c.json(
- { error: "Failed to generate embedding for query" },
- 500
- );
- }
-
- // Pre-compute the vector similarity expression
- const vectorSimilarity = sql`1 - (embeddings <=> ${JSON.stringify(embeddings.data[0])}::vector)`;
-
- // Get matching chunks
- const results = await db
- .select({
- chunkId: chunk.id,
- documentId: chunk.documentId,
- textContent: chunk.textContent,
- orderInDocument: chunk.orderInDocument,
- metadata: chunk.metadata,
- similarity: vectorSimilarity,
- // Document fields
- docUuid: documents.uuid,
- docContent: documents.content,
- docType: documents.type,
- docUrl: documents.url,
- docTitle: documents.title,
- docCreatedAt: documents.createdAt,
- docUpdatedAt: documents.updatedAt,
- docUserId: documents.userId,
- docDescription: documents.description,
- docOgImage: documents.ogImage,
- })
- .from(chunk)
- .innerJoin(documents, eq(chunk.documentId, documents.id))
- .where(
- and(
- eq(documents.userId, user.id),
- sql`${vectorSimilarity} > ${threshold}`,
- ...(spaces && spaces.length > 0
- ? [
- exists(
- db
- .select()
- .from(contentToSpace)
- .where(
- and(
- eq(contentToSpace.contentId, documents.id),
- inArray(
- contentToSpace.spaceId,
- spaces.map((spaceId) => Number(spaceId))
- )
- )
- )
- ),
- ]
- : [])
- )
- )
- .orderBy(desc(vectorSimilarity))
- .limit(limit);
-
- // Group results by document and take the best matching chunk
- const documentResults = new Map();
- for (const result of results) {
- const existingResult = documentResults.get(result.documentId);
- if (
- !existingResult ||
- result.similarity > existingResult.similarity
- ) {
- documentResults.set(result.documentId, result);
- }
- }
-
- // Convert back to array and format response
- const finalResults = Array.from(documentResults.values())
- .sort((a, b) => b.similarity - a.similarity)
- .map((r) => ({
- id: r.documentId,
- uuid: r.docUuid,
- content: r.docContent,
- type: r.docType,
- url: r.docUrl,
- title: r.docTitle,
- createdAt: r.docCreatedAt,
- updatedAt: r.docUpdatedAt,
- userId: r.docUserId,
- description: r.docDescription,
- ogImage: r.docOgImage,
- similarity: Number(r.similarity.toFixed(4)),
- matchingChunk: {
- id: r.chunkId,
- content: r.textContent,
- orderInDocument: r.orderInDocument,
- metadata: r.metadata,
- },
- }));
-
- return c.json({ results: finalResults });
- } catch (error) {
- console.error("[Search Error]", error);
- return c.json(
- {
- error: "Search failed",
- details:
- c.env.NODE_ENV === "development"
- ? (error as Error).message
- : undefined,
- },
- 500
- );
- }
- }
- )
- .post(
- "/add",
- zValidator(
- "json",
- z.object({
- content: z.string().min(1, "Content cannot be empty"),
- spaces: z.array(z.string()).max(5).optional(),
- id: z.string().optional(),
- // any type of metadata. must be json serializable.
- metadata: z.any().optional(),
- images: z.array(z.string()).optional(),
- prefetched: z
- .object({
- contentToVectorize: z.string(),
- contentToSave: z.string(),
- title: z.string(),
- type: z.string(),
- description: z.string().optional(),
- ogImage: z.string().optional(),
- })
- .optional(),
- })
- ),
- async (c) => {
- const body = c.req.valid("json");
-
- const user = c.get("user");
-
- if (!user) {
- return c.json({ error: "You must be logged in to add content" }, 401);
- }
-
- // Do not perform seperate check for prefetched type, breaks tweet addition from extension
- const type = typeDecider(body.content);
-
- if (isErr(type)) {
- return c.json(
- {
- error: "Could not determine content type",
- details: type.error.message,
- },
- 400
- );
- }
-
- if (type.value === "page" && !body.content.startsWith("http")) {
- body.content = `https://${body.content}`;
- }
-
- const uuid = body.id ?? randomId();
- const contentId = `add-${user.id}-${uuid}`;
-
- const db = database(c.env.HYPERDRIVE.connectionString);
-
- // Calculate document hash early to enable faster duplicate detection
- const content = body.prefetched?.contentToVectorize || body.content;
- const encoder = new TextEncoder();
- const data = encoder.encode(content);
- const hashBuffer = await crypto.subtle.digest("SHA-256", data);
- const hashArray = Array.from(new Uint8Array(hashBuffer));
- const documentHash = hashArray
- .map((b) => b.toString(16).padStart(2, "0"))
- .join("");
-
- // Check for duplicates using hash
- const existingDocs = await db
- .select()
- .from(documents)
- .where(
- and(
- eq(documents.userId, user.id),
- or(
- eq(documents.contentHash, documentHash),
- and(
- eq(documents.type, type.value),
- or(eq(documents.url, body.content), eq(documents.raw, content))
- )
- )
- )
- );
-
- if (existingDocs.length > 0) {
- return c.json(
- { error: `That ${type.value} already exists in your memories` },
- 409
- );
- }
-
- // Check space permissions if spaces are specified
- if (body.spaces && body.spaces.length > 0) {
- const spacePermissions = await Promise.all(
- body.spaces.map(async (spaceId) => {
- const space = await db
- .select()
- .from(spaceInDb)
- .where(eq(spaceInDb.uuid, spaceId))
- .limit(1);
-
- if (!space[0]) {
- // create a new space for the user with the given id
- const newSpace = await db
- .insert(spaceInDb)
- .values({
- uuid: spaceId,
- name: spaceId,
- isPublic: false,
- ownerId: user.id,
- createdAt: new Date(),
- updatedAt: new Date(),
- })
- .returning();
-
- return {
- spaceId: newSpace[0].id,
- allowed: true,
- error: null,
- };
- }
-
- const spaceData = space[0] as Space;
-
- // If public space, only owner can add content
- if (spaceData.isPublic) {
- return {
- spaceId,
- allowed: spaceData.ownerId === user.id,
- error:
- spaceData.ownerId !== user.id
- ? "Only space owner can add to public spaces"
- : null,
- };
- }
-
- // For private spaces, check if user is owner or in allowlist
- const spaceAccessCheck = await db
- .select()
- .from(spaceAccess)
- .where(
- and(
- eq(spaceAccess.spaceId, spaceData.id),
- eq(spaceAccess.userEmail, user.email),
- eq(spaceAccess.status, "accepted")
- )
- )
- .limit(1);
-
- return {
- spaceId,
- allowed:
- spaceData.ownerId === user.id || spaceAccessCheck.length > 0,
- error:
- spaceData.ownerId !== user.id && !spaceAccessCheck.length
- ? "Not authorized to add to this space"
- : null,
- };
- })
- );
-
- const unauthorized = spacePermissions.filter((p) => !p.allowed);
- if (unauthorized.length > 0) {
- return c.json(
- {
- error: "Space permission denied",
- details: unauthorized
- .map((u) => `${u.spaceId}: ${u.error}`)
- .join(", "),
- },
- 403
- );
- }
- }
-
- const isExternalContent = [
- "page",
- "tweet",
- "document",
- "notion",
- ].includes(type.value);
- const indexedUrl = isExternalContent
- ? body.content
- : `https://supermemory.ai/content/${contentId}`;
-
- // Insert into documents table with hash
- try {
- await db.insert(documents).values({
- uuid: contentId,
- userId: user.id,
- type: type.value,
- url: indexedUrl,
- title: body.prefetched?.title,
- description: body.prefetched?.description,
- ogImage: body.prefetched?.ogImage,
- contentHash: documentHash,
- raw:
- (body.prefetched ?? body.content) + "\n\n" + body.spaces?.join(" "),
- metadata: body.metadata,
- });
-
- await c.env.CONTENT_WORKFLOW.create({
- params: {
- userId: user.id,
- content: body.content,
- spaces: body.spaces,
- type: type.value,
- uuid: contentId,
- url: indexedUrl,
- prefetched: body.prefetched,
- },
- id: contentId,
- });
-
- return c.json({
- message: "Content added successfully",
- id: contentId,
- type: type.value,
- });
- } catch (error) {
- console.error("[Add Content Error]", error);
- return c.json({ error: "Failed to process content" }, 500);
- }
- }
- )
- .post(
- "/batch-add",
- zValidator(
- "json",
- z
- .object({
- urls: z
- .array(z.string())
- .min(1, "At least one URL is required")
- .optional(),
- contents: z
- .array(
- z.object({
- content: z.string(),
- title: z.string(),
- type: z.string(),
- })
- )
- .optional(),
- spaces: z.array(z.string()).max(5).optional(),
- })
- .refine((data) => data.urls || data.contents, {
- message: "Either urls or contents must be provided",
- })
- ),
- async (c) => {
- const user = c.get("user");
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const { urls, contents, spaces } = await c.req.valid("json");
-
- // Check space permissions if spaces are specified
- if (spaces && spaces.length > 0) {
- const db = database(c.env.HYPERDRIVE.connectionString);
- const spacePermissions = await Promise.all(
- spaces.map(async (spaceId) => {
- const space = await db
- .select()
- .from(spaceInDb)
- .where(eq(spaceInDb.uuid, spaceId))
- .limit(1);
-
- if (!space[0]) {
- return { spaceId, allowed: false, error: "Space not found" };
- }
-
- const spaceData = space[0] as Space;
-
- // If public space, only owner can add content
- if (spaceData.isPublic) {
- return {
- spaceId,
- allowed: spaceData.ownerId === user.id,
- error:
- spaceData.ownerId !== user.id
- ? "Only space owner can add to public spaces"
- : null,
- };
- }
-
- // For private spaces, check if user is owner or in allowlist
- const spaceAccessCheck = await db
- .select()
- .from(spaceAccess)
- .where(
- and(
- eq(spaceAccess.spaceId, spaceData.id),
- eq(spaceAccess.userEmail, user.email),
- eq(spaceAccess.status, "accepted")
- )
- )
- .limit(1);
-
- return {
- spaceId,
- allowed:
- spaceData.ownerId === user.id || spaceAccessCheck.length > 0,
- error:
- spaceData.ownerId !== user.id && !spaceAccessCheck.length
- ? "Not authorized to add to this space"
- : null,
- };
- })
- );
-
- const unauthorized = spacePermissions.filter((p) => !p.allowed);
- if (unauthorized.length > 0) {
- return c.json(
- {
- error: "Space permission denied",
- details: unauthorized
- .map((u) => `${u.spaceId}: ${u.error}`)
- .join(", "),
- },
- 403
- );
- }
- }
-
- // Create a new ReadableStream for progress updates
- const encoder = new TextEncoder();
- const stream = new ReadableStream({
- async start(controller) {
- const db = database(c.env.HYPERDRIVE.connectionString);
- const items = urls || contents || [];
- const total = items.length;
- let processed = 0;
- let failed = 0;
- let succeeded = 0;
-
- const sendMessage = (data: any) => {
- const message = encoder.encode(`data: ${JSON.stringify(data)}\n\n`);
- controller.enqueue(message);
- };
-
- for (const item of items) {
- try {
- processed++;
-
- // Handle both URL and markdown content
- const content = typeof item === "string" ? item : item.content;
- const title = typeof item === "string" ? null : item.title;
- const type =
- typeof item === "string" ? typeDecider(item) : Ok(item.type);
-
- if (isErr(type)) {
- failed++;
- sendMessage({
- progress: Math.round((processed / total) * 100),
- status: "error",
- url: typeof item === "string" ? item : item.title,
- error: type.error.message,
- processed,
- total,
- succeeded,
- failed,
- });
- continue;
- }
-
- // Calculate document hash
- const encoder = new TextEncoder();
- const data = encoder.encode(content);
- const hashBuffer = await crypto.subtle.digest("SHA-256", data);
- const hashArray = Array.from(new Uint8Array(hashBuffer));
- const documentHash = hashArray
- .map((b) => b.toString(16).padStart(2, "0"))
- .join("");
-
- // Check for duplicates
- const existingDocs = await db
- .select()
- .from(documents)
- .where(
- and(
- eq(documents.userId, user.id),
- or(
- eq(documents.contentHash, documentHash),
- eq(documents.raw, content)
- )
- )
- );
-
- if (existingDocs.length > 0) {
- failed++;
- sendMessage({
- progress: Math.round((processed / total) * 100),
- status: "duplicate",
- title: typeof item === "string" ? item : item.title,
- processed,
- total,
- succeeded,
- failed,
- });
- continue;
- }
-
- const contentId = `add-${user.id}-${randomId()}`;
- const isExternalContent =
- typeof item === "string" &&
- ["page", "tweet", "document", "notion"].includes(type.value);
- const url = isExternalContent
- ? content
- : `https://supermemory.ai/content/${contentId}`;
-
- // Insert into documents table
- await db.insert(documents).values({
- uuid: contentId,
- userId: user.id,
- type: type.value,
- url,
- title,
- contentHash: documentHash,
- raw: content + "\n\n" + spaces?.join(" "),
- });
-
- // Create workflow for processing
- await c.env.CONTENT_WORKFLOW.create({
- params: {
- userId: user.id,
- content,
- spaces,
- type: type.value,
- uuid: contentId,
- url,
- },
- id: contentId,
- });
-
- succeeded++;
- sendMessage({
- progress: Math.round((processed / total) * 100),
- status: "success",
- title: typeof item === "string" ? item : item.title,
- processed,
- total,
- succeeded,
- failed,
- });
-
- // Add a small delay between requests
- await new Promise((resolve) => setTimeout(resolve, 100));
- } catch (error) {
- failed++;
- sendMessage({
- progress: Math.round((processed / total) * 100),
- status: "error",
- title: typeof item === "string" ? item : item.title,
- error: error instanceof Error ? error.message : "Unknown error",
- processed,
- total,
- succeeded,
- failed,
- });
- }
- }
-
- sendMessage({
- progress: 100,
- status: "complete",
- processed,
- total,
- succeeded,
- failed,
- });
- controller.close();
- },
- });
-
- return new Response(stream, {
- headers: {
- "Content-Type": "text/event-stream",
- "Cache-Control": "no-cache",
- Connection: "keep-alive",
- },
- });
- }
- );
-
-export default actions;
diff --git a/apps/backend/src/routes/integrations.ts b/apps/backend/src/routes/integrations.ts
deleted file mode 100644
index 9aa369ea..00000000
--- a/apps/backend/src/routes/integrations.ts
+++ /dev/null
@@ -1,180 +0,0 @@
-import { Hono } from "hono";
-import type { Env, Variables } from "../types";
-import { getDecryptedKV } from "encrypt-workers-kv";
-import { getAllNotionPageContents } from "../utils/notion";
-import { and, eq, or } from "@supermemory/db";
-import { documents } from "@supermemory/db/schema";
-import { database } from "@supermemory/db";
-import { fromHono } from "chanfana";
-
-const integrations = fromHono(
- new Hono<{ Variables: Variables; Bindings: Env }>()).get("/notion/import", async (c) => {
- const user = c.get("user");
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- // Create SSE stream
- const stream = new TransformStream();
- const writer = stream.writable.getWriter();
- const encoder = new TextEncoder();
-
- // Create response first so client gets headers immediately
- const response = new Response(stream.readable, {
- headers: {
- "Content-Type": "text/event-stream",
- "Cache-Control": "no-cache",
- Connection: "keep-alive",
- // Required CORS headers for SSE
- "Access-Control-Allow-Origin": "*",
- "Access-Control-Allow-Credentials": "true",
- },
- });
-
- const sendMessage = async (data: Record) => {
- // Proper SSE format requires "data: " prefix and double newline
- const formattedData = `data: ${JSON.stringify(data)}\n\n`;
- await writer.write(encoder.encode(formattedData));
- };
-
- // Start processing in background
- c.executionCtx.waitUntil(
- (async () => {
- try {
- // Send initial heartbeat
- await sendMessage({ type: "connected" });
-
- const token = await getDecryptedKV(
- c.env.ENCRYPTED_TOKENS,
- `${user.uuid}-notion`,
- `${c.env.WORKOS_COOKIE_PASSWORD}-${user.uuid}`
- );
-
- const stringToken = new TextDecoder().decode(token);
- if (!stringToken) {
- await sendMessage({ type: "error", error: "No token found" });
- await writer.close();
- return;
- }
-
- await sendMessage({ type: "progress", progress: 5 });
-
- // Fetch pages with progress updates
- const pages = await getAllNotionPageContents(
- stringToken,
- async (progress) => {
- // Map progress from 0-100 to 5-40 range
- const scaledProgress = Math.floor(5 + (progress * 35) / 100);
- await sendMessage({ type: "progress", progress: scaledProgress });
- }
- );
-
- await sendMessage({ type: "progress", progress: 40 });
-
- let processed = 0;
- const totalPages = pages.length;
-
- const db = database(c.env.HYPERDRIVE.connectionString);
-
- for (const page of pages) {
- // Calculate document hash for duplicate detection
- const encoder = new TextEncoder();
- const data = encoder.encode(page.content);
- const hashBuffer = await crypto.subtle.digest("SHA-256", data);
- const hashArray = Array.from(new Uint8Array(hashBuffer));
- const documentHash = hashArray
- .map((b) => b.toString(16).padStart(2, "0"))
- .join("");
-
- // Check for duplicates using hash
- const existingDocs = await db
- .select()
- .from(documents)
- .where(
- and(
- eq(documents.userId, user.id),
- or(
- eq(documents.contentHash, documentHash),
- and(
- eq(documents.type, "notion"),
- or(
- eq(documents.url, page.url),
- eq(documents.raw, page.content)
- )
- )
- )
- )
- );
-
- if (existingDocs.length > 0) {
- await sendMessage({
- type: "warning",
- message: `Skipping duplicate page: ${page.title}`,
- });
- processed++;
- continue;
- }
-
- // Insert into documents table first
- try {
- await db.insert(documents).values({
- uuid: page.id,
- userId: user.id,
- type: "notion",
- url: page.url,
- title: page.title,
- contentHash: documentHash,
- raw: page.content,
- });
-
- await c.env.CONTENT_WORKFLOW.create({
- params: {
- userId: user.id,
- content: page.url,
- spaces: [],
- type: "notion",
- uuid: page.id,
- url: page.url,
- prefetched: {
- contentToVectorize: page.content,
- contentToSave: page.content,
- title: page.title,
- type: "notion",
- },
- createdAt: page.createdAt,
- },
- id: `${user.id}-${page.id}-${new Date().getTime()}`,
- });
-
- processed++;
- const progress = 50 + Math.floor((processed / totalPages) * 50);
- await sendMessage({ type: "progress", progress, page: page.title });
- } catch (error) {
- console.error(`Failed to process page ${page.title}:`, error);
- await sendMessage({
- type: "warning",
- message: `Failed to process page: ${page.title}`,
- error: error instanceof Error ? error.message : "Unknown error",
- });
- processed++;
- continue;
- }
- }
-
- await sendMessage({ type: "complete", progress: 100 });
- await writer.close();
- } catch (error) {
- console.error("Import error:", error);
- await sendMessage({
- type: "error",
- error: error instanceof Error ? error.message : "Import failed",
- });
- await writer.close();
- }
- })()
- );
-
- return response;
-});
-
-export default integrations;
diff --git a/apps/backend/src/routes/memories.ts b/apps/backend/src/routes/memories.ts
deleted file mode 100644
index f79da8ce..00000000
--- a/apps/backend/src/routes/memories.ts
+++ /dev/null
@@ -1,293 +0,0 @@
-import { Hono } from "hono";
-import { Variables, Env } from "../types";
-import { zValidator } from "@hono/zod-validator";
-import { z } from "zod";
-import {
- documents,
- spaces,
- spaceAccess,
- contentToSpace,
-} from "@supermemory/db/schema";
-import { and, database, desc, eq, or, sql, isNull } from "@supermemory/db";
-import { fromHono } from "chanfana";
-
-const memories = fromHono(new Hono<{ Variables: Variables; Bindings: Env }>())
- .get(
- "/",
- zValidator(
- "query",
- z.object({
- start: z.string().default("0").transform(Number),
- count: z.string().default("10").transform(Number),
- spaceId: z.string().optional(),
- })
- ),
- async (c) => {
- const { start, count, spaceId } = c.req.valid("query");
- const user = c.get("user");
- const db = database(c.env.HYPERDRIVE.connectionString);
-
- console.log("Fetching memories with spaceId", spaceId);
- console.log(c.req.url);
- // If spaceId provided, verify access
- if (spaceId) {
- console.log("SpaceID provided", spaceId);
- const space = await db
- .select()
- .from(spaces)
- .where(eq(spaces.uuid, spaceId.split("---")[0]))
- .limit(1);
-
- if (!space[0]) {
- return c.json({ error: "Space not found" }, 404);
- }
-
- // Check access - allow if public, user owns the space, or has access through spaceAccess
- if (!space[0].isPublic && !user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- if (!space[0].isPublic && space[0].ownerId !== user?.id) {
- const access = await db
- .select()
- .from(spaceAccess)
- .where(
- and(
- eq(spaceAccess.spaceId, space[0].id),
- eq(spaceAccess.userEmail, user?.email ?? ""),
- eq(spaceAccess.status, "accepted")
- )
- )
- .limit(1);
-
- if (access.length === 0) {
- console.log("Unauthorized access to", c.req.url);
- return c.json({ error: "Unauthorized" }, 401);
- }
- }
-
- // Get documents for space
- const [items, totalResult] = await Promise.all([
- db
- .select({
- documents,
- })
- .from(documents)
- .innerJoin(
- contentToSpace,
- eq(documents.id, contentToSpace.contentId)
- )
- .where(eq(contentToSpace.spaceId, space[0].id))
- .orderBy(desc(documents.createdAt))
- .limit(count)
- .offset(start),
- db
- .select({
- total: sql`count(*)`.as("total"),
- })
- .from(documents)
- .innerJoin(
- contentToSpace,
- eq(documents.id, contentToSpace.contentId)
- )
- .where(eq(contentToSpace.spaceId, space[0].id)),
- ]);
-
- const total = totalResult[0]?.total ?? 0;
-
- return c.json({
- items: items.map((item) => ({
- ...item.documents,
- id: item.documents.uuid,
- })),
- total,
- });
- }
-
- // Regular user memories endpoint
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- // Set cache control headers for 5 minutes
- c.header("Cache-Control", "private, max-age=300");
- c.header("Vary", "Cookie"); // Vary on Cookie since response depends on user
-
- // Generate ETag based on user ID, start, count
- const etag = `"${user.id}-${start}-${count}"`;
- c.header("ETag", etag);
-
- // Check if client has matching ETag
- const ifNoneMatch = c.req.header("If-None-Match");
- if (ifNoneMatch === etag) {
- return new Response(null, { status: 304 });
- }
-
- const [items, [{ total }]] = await Promise.all([
- db
- .select({
- documents: documents,
- })
- .from(documents)
- .leftJoin(contentToSpace, eq(documents.id, contentToSpace.contentId))
- .where(
- and(eq(documents.userId, user.id), isNull(contentToSpace.contentId))
- )
- .orderBy(desc(documents.createdAt))
- .limit(count)
- .offset(start),
- db
- .select({
- total: sql`count(*)`.as("total"),
- })
- .from(documents)
- .leftJoin(contentToSpace, eq(documents.id, contentToSpace.contentId))
- .where(
- and(eq(documents.userId, user.id), isNull(contentToSpace.contentId))
- ),
- ]);
-
- return c.json({
- items: items.map((item) => ({
- ...item.documents,
- id: item.documents.uuid,
- })),
- total,
- });
- }
- )
- .get("/:id", zValidator("param", z.object({ id: z.string() })), async (c) => {
- const { id } = c.req.valid("param");
- const user = c.get("user");
-
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const memory = await database(c.env.HYPERDRIVE.connectionString)
- .select()
- .from(documents)
- .where(and(eq(documents.uuid, id), eq(documents.userId, user.id)))
- .limit(1);
-
- return c.json(memory[0]);
- })
- .delete(
- "/:id",
- zValidator("param", z.object({ id: z.string() })),
- async (c) => {
- const { id } = c.req.valid("param");
- const user = c.get("user");
-
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const db = database(c.env.HYPERDRIVE.connectionString);
-
- let documentIdNum;
-
- try {
- documentIdNum = Number(id);
- } catch (e) {
- documentIdNum = null;
- }
-
- const doc = await db
- .select()
- .from(documents)
- .where(
- and(
- documentIdNum
- ? or(eq(documents.uuid, id), eq(documents.id, documentIdNum))
- : eq(documents.uuid, id),
- eq(documents.userId, user.id)
- )
- )
- .limit(1);
-
- if (!doc[0]) {
- return c.json({ error: "Document not found" }, 404);
- }
-
- const [document, contentToSpacei] = await Promise.all([
- db
- .delete(documents)
- .where(and(eq(documents.uuid, id), eq(documents.userId, user.id))),
- db
- .delete(contentToSpace)
- .where(eq(contentToSpace.contentId, doc[0].id)),
- ]);
-
- return c.json({ success: true });
- }
- )
- .post(
- "/batch-delete",
- zValidator(
- "json",
- z.object({
- ids: z.array(z.string()),
- })
- ),
- async (c) => {
- const { ids } = c.req.valid("json");
- const user = c.get("user");
-
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const db = database(c.env.HYPERDRIVE.connectionString);
-
- try {
- // First get all valid documents that belong to the user
- const docs = await db
- .select()
- .from(documents)
- .where(
- and(
- eq(documents.userId, user.id),
- sql`${documents.uuid} = ANY(ARRAY[${ids}]::text[])`
- )
- );
-
- if (docs.length === 0) {
- return c.json({ error: "No valid documents found" }, 404);
- }
-
- const docIds = docs.map((doc) => doc.id);
-
- // Delete in transaction to ensure consistency
- await db.transaction(async (tx) => {
- await Promise.all([
- // Delete document entries
- tx
- .delete(documents)
- .where(
- and(
- eq(documents.userId, user.id),
- sql`${documents.uuid} = ANY(ARRAY[${ids}]::text[])`
- )
- ),
- // Delete space connections
- tx
- .delete(contentToSpace)
- .where(
- sql`${contentToSpace.contentId} = ANY(ARRAY[${docIds}]::int[])`
- ),
- ]);
- });
-
- return c.json({
- success: true,
- deletedCount: docs.length,
- });
- } catch (error) {
- console.error("Batch delete error:", error);
- return c.json({ error: "Failed to delete documents" }, 500);
- }
- }
- );
-
-export default memories;
diff --git a/apps/backend/src/routes/spaces.ts b/apps/backend/src/routes/spaces.ts
deleted file mode 100644
index e004ce78..00000000
--- a/apps/backend/src/routes/spaces.ts
+++ /dev/null
@@ -1,709 +0,0 @@
-import { Hono } from "hono";
-import { Env, Variables } from "../types";
-import { and, database, desc, eq, isNotNull, or, sql } from "@supermemory/db";
-import {
- contentToSpace,
- documents,
- savedSpaces,
- spaceAccess,
- spaces,
- users,
-} from "@supermemory/db/schema";
-import { zValidator } from "@hono/zod-validator";
-import { z } from "zod";
-import { randomId } from "@supermemory/shared";
-import { fromHono } from "chanfana";
-
-const spacesRoute = fromHono(
- new Hono<{ Variables: Variables; Bindings: Env }>())
- .get("/", async (c) => {
- const user = c.get("user");
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const db = database(c.env.HYPERDRIVE.connectionString);
-
- const [allSpaces, savedSpacesList, spaceOwners] = await Promise.all([
- db
- .select({
- id: spaces.id,
- uuid: spaces.uuid,
- name: sql`REGEXP_REPLACE(${spaces.name}, E'[\\n\\r]+', ' ', 'g')`.as(
- "name"
- ),
- ownerId: spaces.ownerId,
- isPublic: spaces.isPublic,
- createdAt: spaces.createdAt,
- accessType: spaceAccess.accessType,
- })
- .from(spaces)
- .leftJoin(
- spaceAccess,
- and(
- eq(spaces.id, spaceAccess.spaceId),
- eq(spaceAccess.userEmail, user.email),
- eq(spaceAccess.status, "accepted")
- )
- )
- .where(or(eq(spaces.ownerId, user.id), isNotNull(spaceAccess.spaceId)))
- .orderBy(desc(spaces.createdAt)),
-
- db
- .select({
- spaceId: savedSpaces.spaceId,
- })
- .from(savedSpaces)
- .where(eq(savedSpaces.userId, user.id)),
-
- db
- .select({
- id: users.id,
- uuid: users.uuid,
- name: users.firstName,
- email: users.email,
- profileImage: users.profilePictureUrl,
- })
- .from(users)
- .innerJoin(spaces, eq(spaces.ownerId, users.id)),
- ]);
-
- const savedSpaceIds = new Set(savedSpacesList.map((s) => s.spaceId));
- const ownerMap = new Map(spaceOwners.map((owner) => [owner.id, owner]));
-
- const spacesWithDetails = allSpaces.map((space) => {
- const isOwner = space.ownerId === user.id;
- const owner = ownerMap.get(space.ownerId);
-
- return {
- ...space,
- favorited: savedSpaceIds.has(space.id),
- permissions: {
- canRead: space.isPublic || isOwner || space.accessType != null,
- canEdit: isOwner || space.accessType === "edit",
- isOwner,
- },
- owner: isOwner
- ? null
- : {
- id: owner?.uuid,
- name: owner?.name,
- email: owner?.email,
- profileImage: owner?.profileImage,
- },
- };
- });
-
- return c.json({ spaces: spacesWithDetails });
- })
- .get("/:spaceId", async (c) => {
- const user = c.get("user");
- const spaceId = c.req.param("spaceId");
- const db = database(c.env.HYPERDRIVE.connectionString);
-
- const space = await db
- .select()
- .from(spaces)
- .where(eq(spaces.uuid, spaceId))
- .limit(1);
-
- if (!space[0]) {
- return c.json({ error: "Space not found" }, 404);
- }
-
- // For public spaces, anyone can read but only owner can edit
- if (space[0].isPublic) {
- const canEdit = user?.id === space[0].ownerId;
- return c.json({
- ...space[0],
- permissions: {
- canRead: true,
- canEdit,
- isOwner: space[0].ownerId === user?.id,
- isPublic: space[0].isPublic,
- },
- });
- }
-
- // For private spaces, require authentication
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- // Check if user is owner or has access via spaceAccess
- const isOwner = space[0].ownerId === user.id;
- let canEdit = isOwner;
- if (!isOwner) {
- const spaceAccessCheck = await db
- .select()
- .from(spaceAccess)
- .where(
- and(
- eq(spaceAccess.spaceId, space[0].id),
- eq(spaceAccess.userEmail, user.email),
- eq(spaceAccess.status, "accepted")
- )
- )
- .limit(1);
-
- if (spaceAccessCheck.length === 0) {
- return c.json({ error: "Access denied" }, 403);
- }
-
- canEdit = spaceAccessCheck[0].accessType === "edit";
- }
-
- return c.json({
- ...space[0],
- permissions: {
- canRead: true,
- canEdit,
- isOwner: space[0].ownerId === user.id,
- isPublic: space[0].isPublic,
- },
- });
- })
- .post(
- "/create",
- zValidator(
- "json",
- z.object({
- spaceName: z.string().min(1, "Space name cannot be empty").max(100),
- isPublic: z.boolean(), // keep this explicit please
- })
- ),
- async (c) => {
- const body = c.req.valid("json");
- const user = c.get("user");
-
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- if (body.spaceName.trim() === "") {
- return c.json({ error: "Cannot create space with name " }, 400);
- }
-
- const db = database(c.env.HYPERDRIVE.connectionString);
- const uuid = randomId();
-
- try {
- const space = await db
- .insert(spaces)
- .values({
- name: body.spaceName.trim(),
- ownerId: user.id,
- uuid,
- isPublic: body.isPublic,
- createdAt: new Date(),
- })
- .returning();
-
- return c.json({
- message: "Space created successfully",
- space: {
- uuid: space[0].uuid,
- name: space[0].name,
- ownerId: space[0].ownerId,
- isPublic: space[0].isPublic,
- createdAt: space[0].createdAt,
- },
- });
- } catch (error) {
- console.error("[Space Creation Error]", error);
- return c.json({ error: "Failed to create space" }, 500);
- }
- }
- )
- .post(
- "/:spaceId/favorite",
- zValidator(
- "param",
- z.object({
- spaceId: z.string(),
- })
- ),
- async (c) => {
- const user = c.get("user");
- const { spaceId } = c.req.valid("param");
-
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const db = database(c.env.HYPERDRIVE.connectionString);
-
- // Get space details
- const space = await db
- .select()
- .from(spaces)
- .where(eq(spaces.uuid, spaceId))
- .limit(1);
-
- if (!space[0]) {
- return c.json({ error: "Space not found" }, 404);
- }
-
- // Check if it's user's own space
- if (space[0].ownerId === user.id) {
- return c.json({ error: "Cannot favorite your own space" }, 400);
- }
-
- try {
- await db.insert(savedSpaces).values({
- userId: user.id,
- spaceId: space[0].id,
- savedAt: new Date(),
- });
-
- return c.json({ message: "Space favorited successfully" });
- } catch (error) {
- if (
- error instanceof Error &&
- error.message.includes("saved_spaces_user_space_idx")
- ) {
- // Space is already favorited
- return c.json({ message: "Space already favorited" });
- }
- throw error;
- }
- }
- )
- .post(
- "/moveContent",
- zValidator(
- "json",
- z.object({
- spaceId: z.string(),
- documentId: z.string(),
- })
- ),
- async (c) => {
- const body = c.req.valid("json");
- const user = c.get("user");
- const { spaceId, documentId } = body;
-
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const db = database(c.env.HYPERDRIVE.connectionString);
-
- try {
- await db.transaction(async (tx) => {
- // If moving to , just remove all space connections
- if (spaceId === "") {
- const doc = await tx
- .select()
- .from(documents)
- .where(eq(documents.uuid, documentId))
- .limit(1);
-
- if (!doc[0]) {
- return c.json({ error: "Document not found" }, 404);
- }
-
- await tx
- .delete(contentToSpace)
- .where(eq(contentToSpace.contentId, doc[0].id));
- return;
- }
-
- // Get space and document, verify space ownership
- const results = (
- await tx
- .select({
- spaceId: spaces.id,
- documentId: documents.id,
- ownerId: spaces.ownerId,
- spaceName: spaces.name,
- })
- .from(spaces)
- .innerJoin(
- documents,
- and(eq(spaces.uuid, spaceId), eq(documents.uuid, documentId))
- )
- .limit(1)
- )[0];
-
- if (!results) {
- return c.json({ error: "Space or document not found" }, 404);
- }
-
- if (results.ownerId !== user.id) {
- return c.json(
- { error: "Not authorized to modify this space" },
- 403
- );
- }
-
- // Delete existing space relations for this document
- await tx
- .delete(contentToSpace)
- .where(eq(contentToSpace.contentId, results.documentId));
-
- // Add new space relation
- await tx.insert(contentToSpace).values({
- contentId: results.documentId,
- spaceId: results.spaceId,
- });
- });
-
- return c.json({ success: true, spaceId });
- } catch (e) {
- console.error("Failed to move content to space:", e);
- return c.json(
- {
- error: "Failed to move content to space",
- details: e instanceof Error ? e.message : "Unknown error",
- },
- 500
- );
- }
- }
- )
- .post(
- "/addContent",
- zValidator(
- "json",
- z.object({
- spaceId: z.string(),
- documentId: z.string(),
- })
- ),
- async (c) => {
- const body = c.req.valid("json");
- const user = c.get("user");
- const { spaceId, documentId } = body;
-
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const db = database(c.env.HYPERDRIVE.connectionString);
-
- try {
- await db.transaction(async (tx) => {
- // If adding to , just remove all space connections
- if (spaceId === "") {
- const doc = await tx
- .select()
- .from(documents)
- .where(eq(documents.uuid, documentId))
- .limit(1);
-
- if (!doc[0]) {
- return c.json({ error: "Document not found" }, 404);
- }
-
- await tx
- .delete(contentToSpace)
- .where(eq(contentToSpace.contentId, doc[0].id));
- return;
- }
-
- // Get space and document, verify space ownership
- const results = (
- await tx
- .select({
- spaceId: spaces.id,
- documentId: documents.id,
- ownerId: spaces.ownerId,
- })
- .from(spaces)
- .innerJoin(
- documents,
- and(eq(spaces.uuid, spaceId), eq(documents.uuid, documentId))
- )
- .limit(1)
- )[0];
-
- if (!results) {
- return c.json({ error: "Space or document not found" }, 404);
- }
-
- if (results.ownerId !== user.id) {
- return c.json(
- { error: "Not authorized to modify this space" },
- 403
- );
- }
-
- // Check if mapping already exists to avoid duplicates
- const existing = await tx
- .select()
- .from(contentToSpace)
- .where(
- and(
- eq(contentToSpace.contentId, results.documentId),
- eq(contentToSpace.spaceId, results.spaceId)
- )
- )
- .limit(1);
-
- if (existing.length > 0) {
- return c.json({ error: "Content already exists in space" }, 409);
- }
-
- await tx.insert(contentToSpace).values({
- contentId: results.documentId,
- spaceId: results.spaceId,
- });
- });
-
- return c.json({ success: true });
- } catch (e) {
- console.error("Failed to add content to space:", e);
- return c.json(
- {
- error: "Failed to add content to space",
- details: e instanceof Error ? e.message : "Unknown error",
- },
- 500
- );
- }
- }
- )
- .post(
- "/:spaceId/invite",
- zValidator(
- "json",
- z.object({
- email: z.string().email("Invalid email address"),
- accessType: z.enum(["read", "edit"], {
- errorMap: () => ({
- message: "Access type must be either 'read' or 'edit'",
- }),
- }),
- })
- ),
- async (c) => {
- const user = c.get("user");
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const { spaceId } = c.req.param();
- const { email, accessType } = c.req.valid("json");
-
- const db = database(c.env.HYPERDRIVE.connectionString);
-
- // Check if space exists and user has permission to invite
- const space = await db
- .select()
- .from(spaces)
- .where(eq(spaces.uuid, spaceId))
- .limit(1);
-
- if (space.length === 0) {
- return c.json({ error: "Space not found" }, 404);
- }
-
- // Only space owner can invite others
- if (space[0].ownerId !== user.id) {
- return c.json({ error: "Only space owner can invite users" }, 403);
- }
-
- // Check if invite already exists
- const existingInvite = await db
- .select()
- .from(spaceAccess)
- .where(
- and(
- eq(spaceAccess.spaceId, space[0].id),
- eq(spaceAccess.userEmail, email)
- )
- )
- .limit(1);
-
- if (existingInvite.length > 0) {
- return c.json(
- { error: "User already has access or pending invite" },
- 400
- );
- }
-
- // Create invite
- await db.insert(spaceAccess).values({
- spaceId: space[0].id,
- userEmail: email,
- accessType,
- status: "pending",
- });
-
- // TODO: send email to the user
-
- return c.json({ success: true });
- }
- )
- .get(
- "/:spaceId/invitation",
- zValidator("param", z.object({ spaceId: z.string() })),
- async (c) => {
- const { spaceId } = c.req.valid("param");
- const user = c.get("user");
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const db = database(c.env.HYPERDRIVE.connectionString);
-
- const space = await db
- .select()
- .from(spaces)
- .where(eq(spaces.uuid, spaceId))
- .limit(1);
-
- if (space.length === 0) {
- console.log("Space not found", spaceId);
- return c.json({ error: "Space not found" }, 401);
- }
-
- // Get pending invitation with access type
- const invitation = await db
- .select()
- .from(spaceAccess)
- .where(
- and(
- eq(spaceAccess.spaceId, space[0].id),
- eq(spaceAccess.userEmail, user.email),
- eq(spaceAccess.status, "pending")
- )
- )
- .limit(1);
-
- if (invitation.length === 0) {
- return c.json({ error: "No pending invitation found" }, 403);
- }
-
- return c.json({
- space: space[0],
- accessType: invitation[0].accessType,
- });
- }
- )
- .post(
- "/invites/:action",
- zValidator(
- "json",
- z.object({
- spaceId: z.string().min(5, "Invalid space ID format"),
- })
- ),
- async (c) => {
- const user = c.get("user");
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const db = database(c.env.HYPERDRIVE.connectionString);
-
- const { action } = c.req.param();
- if (action !== "accept" && action !== "reject") {
- return c.json({ error: "Invalid action" }, 400);
- }
-
- const { spaceId } = c.req.valid("json");
- console.log("space ID", spaceId);
-
- // Get space
- const space = await db
- .select()
- .from(spaces)
- .where(eq(spaces.uuid, spaceId))
- .limit(1);
-
- if (space.length === 0) {
- return c.json({ error: "Space not found" }, 404);
- }
-
- // Update invite status
- const updateResult = await db
- .update(spaceAccess)
- .set({ status: action === "accept" ? "accepted" : "rejected" })
- .where(
- and(
- eq(spaceAccess.spaceId, space[0].id),
- eq(spaceAccess.userEmail, user.email),
- eq(spaceAccess.status, "pending")
- )
- );
-
- if (updateResult.length === 0) {
- return c.json({ error: "No pending invite found" }, 404);
- }
-
- return c.json({ success: true });
- }
- )
- .patch(
- "/:spaceId",
- zValidator(
- "json",
- z.object({
- name: z.string().min(1, "Space name cannot be empty").max(100),
- })
- ),
- async (c) => {
- const user = c.get("user");
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const { spaceId } = c.req.param();
- const { name } = c.req.valid("json");
- const db = database(c.env.HYPERDRIVE.connectionString);
-
- // Get space and verify ownership
- const space = await db
- .select()
- .from(spaces)
- .where(eq(spaces.uuid, spaceId))
- .limit(1);
-
- if (space.length === 0) {
- return c.json({ error: "Space not found" }, 404);
- }
-
- if (space[0].ownerId !== user.id) {
- return c.json({ error: "Only space owner can edit space name" }, 403);
- }
-
- if (name.trim() === "") {
- return c.json({ error: "Cannot use reserved name " }, 400);
- }
-
- // Update space name
- await db
- .update(spaces)
- .set({ name: name.trim() })
- .where(eq(spaces.uuid, spaceId));
-
- return c.json({ success: true, name: name.trim() });
- }
- )
- .delete("/:spaceId", async (c) => {
- const user = c.get("user");
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const { spaceId } = c.req.param();
- const db = database(c.env.HYPERDRIVE.connectionString);
-
- const space = await db
- .select()
- .from(spaces)
- .where(eq(spaces.uuid, spaceId))
- .limit(1);
-
- if (space.length === 0) {
- return c.json({ error: "Space not found" }, 404);
- }
-
- await db.delete(spaces).where(eq(spaces.uuid, spaceId));
-
- return c.json({ success: true });
- });
-
-export default spacesRoute;
diff --git a/apps/backend/src/routes/user.ts b/apps/backend/src/routes/user.ts
deleted file mode 100644
index 4905989f..00000000
--- a/apps/backend/src/routes/user.ts
+++ /dev/null
@@ -1,193 +0,0 @@
-import { Hono } from "hono";
-import { Env, Variables } from "../types";
-import { and, database, desc, eq, isNotNull, or, sql } from "@supermemory/db";
-import {
- chatThreads,
- savedSpaces,
- spaceAccess,
- spaces,
- users,
-} from "@supermemory/db/schema";
-import { decryptApiKey, getApiKey } from "../auth";
-import { DurableObjectStore } from "@hono-rate-limiter/cloudflare";
-import { rateLimiter } from "hono-rate-limiter";
-import { fromHono } from "chanfana";
-
-const user = fromHono(new Hono<{ Variables: Variables; Bindings: Env }>())
- .get("/", (c) => {
- return c.json(c.get("user"));
- })
- .get("/spaces", async (c) => {
- const user = c.get("user");
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const db = database(c.env.HYPERDRIVE.connectionString);
-
- const [allSpaces, savedSpacesList, spaceOwners] = await Promise.all([
- db
- .select({
- id: spaces.id,
- uuid: spaces.uuid,
- name: sql`REGEXP_REPLACE(${spaces.name}, E'[\\n\\r]+', ' ', 'g')`.as(
- "name"
- ),
- ownerId: spaces.ownerId,
- isPublic: spaces.isPublic,
- createdAt: spaces.createdAt,
- accessType: spaceAccess.accessType,
- })
- .from(spaces)
- .leftJoin(
- spaceAccess,
- and(
- eq(spaces.id, spaceAccess.spaceId),
- eq(spaceAccess.userEmail, user.email),
- eq(spaceAccess.status, "accepted")
- )
- )
- .where(or(eq(spaces.ownerId, user.id), isNotNull(spaceAccess.spaceId)))
- .orderBy(desc(spaces.createdAt)),
-
- db
- .select({
- spaceId: savedSpaces.spaceId,
- })
- .from(savedSpaces)
- .where(eq(savedSpaces.userId, user.id)),
-
- db
- .select({
- id: users.id,
- uuid: users.uuid,
- name: users.firstName,
- email: users.email,
- profileImage: users.profilePictureUrl,
- })
- .from(users)
- .innerJoin(spaces, eq(spaces.ownerId, users.id)),
- ]);
-
- const savedSpaceIds = new Set(savedSpacesList.map((s) => s.spaceId));
- const ownerMap = new Map(spaceOwners.map((owner) => [owner.id, owner]));
-
- const spacesWithDetails = allSpaces.map((space) => {
- const isOwner = space.ownerId === user.id;
- const owner = ownerMap.get(space.ownerId);
-
- return {
- ...space,
- favorited: savedSpaceIds.has(space.id),
- permissions: {
- canRead: space.isPublic || isOwner || space.accessType != null,
- canEdit: isOwner || space.accessType === "edit",
- isOwner,
- },
- owner: isOwner
- ? null
- : {
- id: owner?.uuid,
- name: owner?.name,
- email: owner?.email,
- profileImage: owner?.profileImage,
- },
- };
- });
-
- return c.json({ spaces: spacesWithDetails });
- })
- .get("/history", async (c) => {
- const user = c.get("user");
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const history = await database(c.env.HYPERDRIVE.connectionString)
- .select()
- .from(chatThreads)
- .where(eq(chatThreads.userId, user.id))
- .orderBy(desc(chatThreads.createdAt))
- .limit(10);
-
- return c.json({ history });
- })
- .get("/invitations", async (c) => {
- const user = c.get("user");
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const db = database(c.env.HYPERDRIVE.connectionString);
-
- const invitations = await db
- .select({
- spaceAccess: spaceAccess,
- spaceUuid: spaces.uuid,
- spaceName: spaces.name,
- })
- .from(spaceAccess)
- .innerJoin(spaces, eq(spaceAccess.spaceId, spaces.id))
- .where(eq(spaceAccess.userEmail, user.email))
- .limit(100);
-
- return c.json({ invitations });
- })
- .get("/key", async (c) => {
- const user = c.get("user");
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- // we need user.id and user.lastApiKeyGeneratedAt
- const lastApiKeyGeneratedAt = user.lastApiKeyGeneratedAt?.getTime();
- if (!lastApiKeyGeneratedAt) {
- return c.json({ error: "No API key generated" }, 400);
- }
-
- const key = await getApiKey(user.uuid, lastApiKeyGeneratedAt.toString(), c);
-
- const decrypted = await decryptApiKey(key, c);
- return c.json({ key, decrypted });
- })
- .post("/update", async (c) => {
- const user = c.get("user");
- if (!user) {
- return c.json({ error: "Unauthorized" }, 401);
- }
-
- const body = await c.req.json();
-
- // Only allow updating specific safe fields
- const allowedFields = {
- firstName: true,
- lastName: true,
- profilePictureUrl: true,
- hasOnboarded: true,
- };
-
- const updateData: Record = {};
- for (const [key, value] of Object.entries(body)) {
- if (allowedFields[key as keyof typeof allowedFields]) {
- updateData[key] = value;
- }
- }
-
- if (Object.keys(updateData).length === 0) {
- return c.json({ error: "No valid fields to update" }, 400);
- }
-
- const db = database(c.env.HYPERDRIVE.connectionString);
-
- await db
- .update(users)
- .set({
- ...updateData,
- updatedAt: new Date(),
- })
- .where(eq(users.id, user.id));
-
- return c.json({ success: true });
- });
-
-export default user;
diff --git a/apps/backend/src/types.ts b/apps/backend/src/types.ts
deleted file mode 100644
index 0323a9e6..00000000
--- a/apps/backend/src/types.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-import { DurableObjectRateLimiter } from "@hono-rate-limiter/cloudflare";
-import { Session } from "@supermemory/authkit-remix-cloudflare/src/interfaces";
-import { User } from "@supermemory/db/schema";
-import { z } from "zod";
-
-export type Variables = {
- user: User | null;
- session: Session | null;
-};
-
-export type WorkflowParams = {
- userId: number;
- content: string;
- spaces?: string[];
- type: string;
- uuid: string;
- url?: string;
- prefetched?: {
- contentToVectorize: string;
- contentToSave: string;
- title: string;
- type: string;
- description: string;
- ogImage: string;
- };
- createdAt: string;
-};
-
-export type Env = {
- WORKOS_API_KEY: string;
- WORKOS_CLIENT_ID: string;
- WORKOS_COOKIE_PASSWORD: string;
- DATABASE_URL: string;
- CONTENT_WORKFLOW: Workflow;
- GEMINI_API_KEY: string;
- NODE_ENV: string;
- OPEN_AI_API_KEY: string;
- BRAINTRUST_API_KEY: string;
- RESEND_API_KEY: string;
- TURNSTILE_SECRET_KEY: string;
-
- MD_CACHE: KVNamespace;
- HYPERDRIVE: Hyperdrive;
- EMAIL_LIMITER: {
- limit: (params: { key: string }) => Promise<{ success: boolean }>;
- };
- ENCRYPTED_TOKENS: KVNamespace;
- RATE_LIMITER: DurableObjectNamespace;
- AI: Ai
-};
-
-export type JobData = {
- content: string;
- spaces?: Array;
- user: number;
- type: string;
-};
-
-type BaseChunks = {
- type: "tweet" | "page" | "note" | "image";
-};
-
-export type PageOrNoteChunks = BaseChunks & {
- type: "page" | "note";
- chunks: string[];
-};
-
-export type Metadata = {
- media?: Array;
- links?: Array; // idk how ideal this is will figure out after plate js thing
-};
-
-export type SpaceStatus = {
- type: "inviting" | "invited" | "pending" | "accepted";
-};
-
-export const recommendedQuestionsSchema = z
- .array(z.string().max(200))
- .length(10);
diff --git a/apps/backend/src/utils/chunkers.ts b/apps/backend/src/utils/chunkers.ts
deleted file mode 100644
index ce345d29..00000000
--- a/apps/backend/src/utils/chunkers.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-import nlp from "compromise";
-
-export default function chunkText(
- text: string,
- maxChunkSize: number,
- overlap: number = 0.2
-): string[] {
- // Pre-process text to remove excessive whitespace
- text = text.replace(/\s+/g, " ").trim();
-
- const sentences = nlp(text).sentences().out("array");
- const chunks: {
- text: string;
- start: number;
- end: number;
- metadata?: {
- position: string;
- context?: string;
- };
- }[] = [];
-
- let currentChunk: string[] = [];
- let currentSize = 0;
-
- for (let i = 0; i < sentences.length; i++) {
- const sentence = sentences[i].trim();
-
- // Skip empty sentences
- if (!sentence) continue;
-
- // If a single sentence is longer than maxChunkSize, split it
- if (sentence.length > maxChunkSize) {
- if (currentChunk.length > 0) {
- chunks.push({
- text: currentChunk.join(" "),
- start: i - currentChunk.length,
- end: i - 1,
- metadata: {
- position: `${i - currentChunk.length}-${i - 1}`,
- context: currentChunk[0].substring(0, 100), // First 100 chars for context
- },
- });
- currentChunk = [];
- currentSize = 0;
- }
-
- // Split long sentence into smaller chunks
- const words = sentence.split(" ");
- let tempChunk: string[] = [];
-
- for (const word of words) {
- if (tempChunk.join(" ").length + word.length > maxChunkSize) {
- chunks.push({
- text: tempChunk.join(" "),
- start: i,
- end: i,
- metadata: {
- position: `${i}`,
- context: "Split sentence",
- },
- });
- tempChunk = [];
- }
- tempChunk.push(word);
- }
-
- if (tempChunk.length > 0) {
- chunks.push({
- text: tempChunk.join(" "),
- start: i,
- end: i,
- metadata: {
- position: `${i}`,
- context: "Split sentence remainder",
- },
- });
- }
- continue;
- }
-
- currentChunk.push(sentence);
- currentSize += sentence.length;
-
- if (currentSize >= maxChunkSize) {
- const overlapSize = Math.floor(currentChunk.length * overlap);
- chunks.push({
- text: currentChunk.join(" "),
- start: i - currentChunk.length + 1,
- end: i,
- metadata: {
- position: `${i - currentChunk.length + 1}-${i}`,
- context: currentChunk[0].substring(0, 100),
- },
- });
-
- // Keep overlap sentences for next chunk
- currentChunk = currentChunk.slice(-overlapSize);
- currentSize = currentChunk.reduce((sum, s) => sum + s.length, 0);
- }
- }
-
- // Handle remaining sentences
- if (currentChunk.length > 0) {
- chunks.push({
- text: currentChunk.join(" "),
- start: sentences.length - currentChunk.length,
- end: sentences.length - 1,
- metadata: {
- position: `${sentences.length - currentChunk.length}-${sentences.length - 1}`,
- context: currentChunk[0].substring(0, 100),
- },
- });
- }
-
- return chunks.map((chunk) => chunk.text);
-}
diff --git a/apps/backend/src/utils/cipher.ts b/apps/backend/src/utils/cipher.ts
deleted file mode 100644
index 3ba2e905..00000000
--- a/apps/backend/src/utils/cipher.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-async function encrypt(data: string, key: string): Promise {
- try {
- const encoder = new TextEncoder();
- const encodedData = encoder.encode(data);
-
- const baseForIv = encoder.encode(data + key);
- const ivHash = await crypto.subtle.digest('SHA-256', baseForIv);
- const iv = new Uint8Array(ivHash).slice(0, 12);
-
- const cryptoKey = await crypto.subtle.importKey(
- "raw",
- encoder.encode(key),
- { name: "AES-GCM", length: 256 },
- false,
- ["encrypt", "decrypt"]
- );
-
- const encrypted = await crypto.subtle.encrypt(
- { name: "AES-GCM", iv: new Uint8Array(iv).buffer as ArrayBuffer },
- cryptoKey,
- encodedData
- );
-
- const combined = new Uint8Array([...iv, ...new Uint8Array(encrypted)]);
-
- // Convert to base64 safely
- const base64 = Buffer.from(combined).toString("base64");
-
- // Make URL-safe
- return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
- } catch (err) {
- console.error("Encryption error:", err);
- throw err;
- }
-}
-
-async function decrypt(encryptedData: string, key: string): Promise {
- try {
- // Restore base64 padding and convert URL-safe chars
- const base64 = encryptedData
- .replace(/-/g, "+")
- .replace(/_/g, "/")
- .padEnd(
- encryptedData.length + ((4 - (encryptedData.length % 4)) % 4),
- "="
- );
-
- // Use Buffer for safer base64 decoding
- const combined = Buffer.from(base64, "base64");
- const combinedArray = new Uint8Array(combined);
-
- // Extract the IV that was used for encryption
- const iv = combinedArray.slice(0, 12);
- const encrypted = combinedArray.slice(12);
-
- // Import the same key used for encryption
- const cryptoKey = await crypto.subtle.importKey(
- "raw",
- new TextEncoder().encode(key),
- { name: "AES-GCM", length: 256 },
- false,
- ["encrypt", "decrypt"]
- );
-
- // Use the extracted IV and key to decrypt
- const decrypted = await crypto.subtle.decrypt(
- { name: "AES-GCM", iv: new Uint8Array(iv).buffer as ArrayBuffer },
- cryptoKey,
- encrypted.buffer as ArrayBuffer
- );
-
- return new TextDecoder().decode(decrypted);
- } catch (err) {
- console.error("Decryption error:", err);
- throw err;
- }
-}
-
-export { encrypt, decrypt };
\ No newline at end of file
diff --git a/apps/backend/src/utils/extractDocumentContent.ts b/apps/backend/src/utils/extractDocumentContent.ts
deleted file mode 100644
index 8b7d9256..00000000
--- a/apps/backend/src/utils/extractDocumentContent.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-import * as mammoth from "mammoth";
-import { NonRetryableError } from "cloudflare:workflows";
-import { resolvePDFJS } from 'pdfjs-serverless';
-
-interface DocumentContent {
- content: string;
- error?: string;
-}
-
-export const extractDocumentContent = async (
- url: string
-): Promise => {
- try {
- const fileExtension = url.split(".").pop()?.toLowerCase();
-
- if (!fileExtension) {
- throw new Error("Invalid file URL");
- }
-
- console.log("file", fileExtension);
-
- switch (fileExtension) {
- case "pdf":
- return await extractPdfContent(url);
- case "md":
- case "txt":
- return await extractTextContent(url);
- case "doc":
- case "docx":
- return await extractWordContent(url);
- default:
- throw new NonRetryableError(`Unsupported file type: ${fileExtension}`);
- }
- } catch (error) {
- return {
- content: "",
- error: error instanceof Error ? error.message : "Unknown error occurred",
- };
- }
-};
-
-async function extractPdfContent(url: string): Promise {
- try {
- const response = await fetch(url);
- const arrayBuffer = await response.arrayBuffer();
-
- // Initialize PDF.js with serverless compatibility
- const { getDocument } = await resolvePDFJS();
-
- // Load the PDF document
- const pdf = await getDocument({
- data: arrayBuffer,
- useSystemFonts: true,
- }).promise;
-
- let fullText = "";
-
- // Extract text from each page
- for (let i = 1; i <= pdf.numPages; i++) {
- const page = await pdf.getPage(i);
- const textContent = await page.getTextContent();
- const pageText = textContent.items.map((item: any) => item.str).join(" ");
- fullText += pageText + "\n";
- }
-
- return { content: fullText };
- } catch (error) {
- console.error("Error extracting PDF content:", error);
- return {
- content: "",
- error: error instanceof Error ? error.message : "Failed to extract PDF content",
- };
- }
-}
-
-async function extractTextContent(url: string): Promise {
- const response = await fetch(url);
- const text = await response.text();
- return { content: text };
-}
-
-async function extractWordContent(url: string): Promise {
- const response = await fetch(url);
- const arrayBuffer = await response.arrayBuffer();
- const result = await mammoth.extractRawText({ arrayBuffer });
- return { content: result.value };
-}
diff --git a/apps/backend/src/utils/extractor.ts b/apps/backend/src/utils/extractor.ts
deleted file mode 100644
index f033f8e1..00000000
--- a/apps/backend/src/utils/extractor.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import { Env } from "../types";
-
-export const extractPageContent = async (content: string, env: Env) => {
- const resp = await fetch(`https://r.jina.ai/${content}`);
-
- if (!resp.ok) {
- throw new Error(
- `Failed to fetch ${content}: ${resp.statusText}` + (await resp.text())
- );
- }
-
- const metadataResp = await fetch(`https://md.dhr.wtf/metadata?url=${content}`);
-
- if (!metadataResp.ok) {
- throw new Error(
- `Failed to fetch metadata for ${content}: ${metadataResp.statusText}` +
- (await metadataResp.text())
- );
- }
-
- const metadata = await metadataResp.json() as {
- title?: string;
- description?: string;
- image?: string;
- favicon?: string;
- };
-
- const responseText = await resp.text();
-
- try {
- const json: {
- contentToVectorize: string;
- contentToSave: string;
- title?: string;
- description?: string;
- image?: string;
- favicon?: string;
- } = {
- contentToSave: responseText,
- contentToVectorize: responseText,
- title: metadata.title,
- description: metadata.description,
- image: metadata.image,
- favicon: metadata.favicon,
- };
- return json;
- } catch (e) {
- throw new Error(`Failed to parse JSON from ${content}: ${e}`);
- }
-};
diff --git a/apps/backend/src/utils/fetchers.ts b/apps/backend/src/utils/fetchers.ts
deleted file mode 100644
index 2329f48a..00000000
--- a/apps/backend/src/utils/fetchers.ts
+++ /dev/null
@@ -1,143 +0,0 @@
-import { WorkflowStep } from "cloudflare:workers";
-import { isErr, Ok } from "../errors/results";
-import { typeDecider } from "./typeDecider";
-import { Env, WorkflowParams } from "../types";
-import { unrollTweets } from "./tweetsToThreads";
-import { Tweet } from "react-tweet/api";
-import { NonRetryableError } from "cloudflare:workflows";
-import { extractPageContent } from "./extractor";
-import { extractDocumentContent } from "./extractDocumentContent";
-
-export const fetchContent = async (
- params: WorkflowParams,
- env: Env,
- step: WorkflowStep
-) => {
- const type = typeDecider(params.content);
-
- if (isErr(type)) {
- throw type.error;
- }
-
- switch (type.value) {
- case "page":
- const pageContent = await step?.do(
- "extract page content",
- async () => await extractPageContent(params.content, env)
- );
- return {
- ...pageContent,
- type: "page",
- };
-
- case "tweet":
- const tweetUrl = new URL(params.content);
- tweetUrl.search = ""; // Remove all search params
- const tweetId = tweetUrl.pathname.split("/").pop();
-
- const rawBaseTweetContent = await step.do(
- "extract tweet content",
- async () => {
- const url = `https://cdn.syndication.twimg.com/tweet-result?id=${tweetId}&lang=en&features=tfw_timeline_list%3A%3Btfw_follower_count_sunset%3Atrue%3Btfw_tweet_edit_backend%3Aon%3Btfw_refsrc_session%3Aon%3Btfw_fosnr_soft_interventions_enabled%3Aon%3Btfw_show_birdwatch_pivots_enabled%3Aon%3Btfw_show_business_verified_badge%3Aon%3Btfw_duplicate_scribes_to_settings%3Aon%3Btfw_use_profile_image_shape_enabled%3Aon%3Btfw_show_blue_verified_badge%3Aon%3Btfw_legacy_timeline_sunset%3Atrue%3Btfw_show_gov_verified_badge%3Aon%3Btfw_show_business_affiliate_badge%3Aon%3Btfw_tweet_edit_frontend%3Aon&token=4c2mmul6mnh`;
-
- const resp = await fetch(url, {
- headers: {
- "User-Agent":
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
- Accept: "application/json",
- "Accept-Language": "en-US,en;q=0.5",
- "Accept-Encoding": "gzip, deflate, br",
- Connection: "keep-alive",
- "Upgrade-Insecure-Requests": "1",
- "Cache-Control": "max-age=0",
- TE: "Trailers",
- },
- });
-
- const data = (await resp.json()) as Tweet;
- return data;
- }
- );
-
- let tweetContent: {
- text: string;
- metadata: {
- media?: string[] | undefined;
- links?: string[] | undefined;
- };
- raw: string;
- };
- const unrolledTweetContent = {
- value: [rawBaseTweetContent],
- };
- if (true) {
- console.error("Can't get thread, reverting back to single tweet");
- tweetContent = {
- text: rawBaseTweetContent.text,
- metadata: {
- media: [
- ...(rawBaseTweetContent.photos?.map((url) => url.expandedUrl) ??
- []),
- ...(rawBaseTweetContent.video?.variants[0].src ?? []),
- ],
- },
- raw: `${JSON.stringify(rawBaseTweetContent)} `,
- };
- } else {
- tweetContent = {
- text: unrolledTweetContent.value
- .map((tweet) => tweet.text)
- .join("\n"),
- metadata: {
- media: unrolledTweetContent.value.flatMap((tweet) => [
- ...tweet.videos,
- ...tweet.images,
- ]),
- links: unrolledTweetContent.value.flatMap((tweet) => tweet.links),
- },
- raw: `${JSON.stringify(rawBaseTweetContent)} `,
- };
- }
-
- // make it the same type as the page content
- const pageContentType: Awaited> & {
- type: string;
- } = {
- contentToVectorize:
- tweetContent.text +
- "\n\nMetadata for this tweet:\n" +
- JSON.stringify(tweetContent.metadata) +
- "\n\nRaw tweet data:\n" +
- tweetContent.raw,
- contentToSave: tweetContent.raw,
- title: "",
- description: JSON.stringify(tweetContent.metadata),
- image: "",
- favicon: "",
- type: "tweet",
- };
- return pageContentType;
- case "note":
- const noteContent = {
- contentToVectorize: params.content,
- // TODO: different when using platejs
- contentToSave: params.content,
- // title is the first 30 characters of the first line
- title: params.content.split("\n")[0].slice(0, 30),
- type: "note",
- };
- return noteContent;
- case "document":
- const documentContent = await step.do(
- "extract document content",
- async () => await extractDocumentContent(params.content)
- );
- return {
- contentToVectorize: documentContent.content,
- contentToSave: documentContent.content,
- type: "document",
- };
- default:
- throw new NonRetryableError("Unknown content type");
- }
-};
diff --git a/apps/backend/src/utils/notion.ts b/apps/backend/src/utils/notion.ts
deleted file mode 100644
index ebe559e1..00000000
--- a/apps/backend/src/utils/notion.ts
+++ /dev/null
@@ -1,239 +0,0 @@
-interface PageContent {
- content: string;
- url: string;
- title: string;
- id: string;
- createdAt: string;
-}
-
-interface NotionBlock {
- type: string;
- [key: string]: any;
-}
-
-interface SearchResponse {
- results: {
- id: string;
- object: string;
- url: string;
- created_time: string;
- properties: {
- title?: {
- title: Array<{
- plain_text: string;
- }>;
- };
- Name?: {
- title: Array<{
- plain_text: string;
- }>;
- };
- };
- }[];
- next_cursor: string | undefined;
- has_more: boolean;
-}
-
-interface BlockResponse {
- results: NotionBlock[];
- next_cursor: string | undefined;
- has_more: boolean;
-}
-
-export const getAllNotionPageContents = async (
- token: string,
- onProgress: (progress: number) => Promise
-): Promise => {
- const pages: PageContent[] = [];
- const NOTION_API_VERSION = "2022-06-28";
- const BASE_URL = "https://api.notion.com/v1";
- const MAX_RETRIES = 3;
- const BATCH_SIZE = 10; // Number of concurrent requests
- const PAGE_SIZE = 100; // Number of pages to fetch per search request
-
- const delay = (ms: number) =>
- new Promise((resolve) => setTimeout(resolve, ms));
-
- const notionFetch = async (
- endpoint: string,
- options: RequestInit = {},
- retries = 0
- ): Promise => {
- try {
- const response = await fetch(`${BASE_URL}${endpoint}`, {
- ...options,
- headers: {
- Authorization: `Bearer ${token}`,
- "Notion-Version": NOTION_API_VERSION,
- "Content-Type": "application/json",
- ...((options.headers || {}) as Record),
- },
- });
-
- if (response.status === 429) {
- // Rate limit error
- const retryAfter = parseInt(response.headers.get("Retry-After") || "5");
- if (retries < MAX_RETRIES) {
- await delay(retryAfter * 1000);
- return notionFetch(endpoint, options, retries + 1);
- }
- }
-
- if (!response.ok) {
- const errorText = await response.text();
- throw new Error(
- `Notion API error: ${response.statusText}\n${errorText}`
- );
- }
-
- return response.json();
- } catch (error) {
- if (retries < MAX_RETRIES) {
- await delay(2000 * (retries + 1)); // Exponential backoff
- return notionFetch(endpoint, options, retries + 1);
- }
- throw error;
- }
- };
-
- const convertBlockToMarkdown = (block: NotionBlock): string => {
- switch (block.type) {
- case "paragraph":
- return (
- block.paragraph?.rich_text
- ?.map((text: any) => text.plain_text)
- .join("") || ""
- );
- case "heading_1":
- return `# ${block.heading_1?.rich_text
- ?.map((text: any) => text.plain_text)
- .join("")}\n`;
- case "heading_2":
- return `## ${block.heading_2?.rich_text
- ?.map((text: any) => text.plain_text)
- .join("")}\n`;
- case "heading_3":
- return `### ${block.heading_3?.rich_text
- ?.map((text: any) => text.plain_text)
- .join("")}\n`;
- case "bulleted_list_item":
- return `* ${block.bulleted_list_item?.rich_text
- ?.map((text: any) => text.plain_text)
- .join("")}\n`;
- case "numbered_list_item":
- return `1. ${block.numbered_list_item?.rich_text
- ?.map((text: any) => text.plain_text)
- .join("")}\n`;
- case "to_do":
- const checked = block.to_do?.checked ? "x" : " ";
- return `- [${checked}] ${block.to_do?.rich_text
- ?.map((text: any) => text.plain_text)
- .join("")}\n`;
- case "code":
- return `\`\`\`${block.code?.language || ""}\n${block.code?.rich_text
- ?.map((text: any) => text.plain_text)
- .join("")}\n\`\`\`\n`;
- case "quote":
- return `> ${block.quote?.rich_text
- ?.map((text: any) => text.plain_text)
- .join("")}\n`;
- default:
- return "";
- }
- };
-
- const getAllBlocks = async (pageId: string): Promise => {
- const blocks: NotionBlock[] = [];
- let cursor: string | undefined = undefined;
-
- do {
- const endpoint = `/blocks/${pageId}/children${
- cursor ? `?start_cursor=${cursor}` : ""
- }`;
- const response = (await notionFetch(endpoint)) as BlockResponse;
- blocks.push(...response.results);
- cursor = response.next_cursor;
- } while (cursor);
-
- return blocks;
- };
-
- try {
- let hasMore = true;
- let cursor: string | undefined = undefined;
- let allPages: SearchResponse["results"] = [];
-
- // First, collect all pages
- while (hasMore) {
- const searchResponse = (await notionFetch("/search", {
- method: "POST",
- body: JSON.stringify({
- filter: {
- value: "page",
- property: "object",
- },
- sort: {
- direction: "ascending",
- timestamp: "last_edited_time",
- },
- start_cursor: cursor,
- page_size: PAGE_SIZE,
- }),
- })) as SearchResponse;
-
- allPages = [...allPages, ...searchResponse.results];
- cursor = searchResponse.next_cursor;
- hasMore = searchResponse.has_more;
-
- // Report progress for page collection (0-30%)
- const progressPercent = (allPages.length / (allPages.length + searchResponse.results.length)) * 30;
- await onProgress(progressPercent);
- }
-
- // Process pages in parallel batches
- for (let i = 0; i < allPages.length; i += BATCH_SIZE) {
- const batch = allPages.slice(i, i + BATCH_SIZE);
- const batchResults = await Promise.all(
- batch.map(async (page) => {
- try {
- const blocks = await getAllBlocks(page.id);
- const pageContent = {
- content: blocks.map(convertBlockToMarkdown).join("\n"),
- url: page.url || `https://notion.so/${page.id.replace(/-/g, "")}`,
- title:
- page.properties?.Name?.title?.[0]?.plain_text ||
- page.properties?.title?.title?.[0]?.plain_text ||
- "Untitled",
- id: page.id,
- createdAt: page.created_time,
- };
- return pageContent.content.length > 10 ? pageContent : null;
- } catch (error) {
- console.error(`Error processing page ${page.id}:`, error);
- return null;
- }
- })
- );
-
- pages.push(
- ...batchResults.filter(
- (result): result is PageContent => result !== null
- )
- );
-
- // Report progress for page processing (30-100%)
- const progressPercent = 30 + ((i + BATCH_SIZE) / allPages.length) * 70;
- await onProgress(Math.min(progressPercent, 100));
-
- // Add a small delay between batches to respect rate limits
- if (i + BATCH_SIZE < allPages.length) {
- await delay(1000);
- }
- }
-
- return pages.filter((page) => page.content.length > 10);
- } catch (error) {
- console.error("Error fetching Notion pages:", error);
- throw error;
- }
-};
diff --git a/apps/backend/src/utils/tweetsToThreads.ts b/apps/backend/src/utils/tweetsToThreads.ts
deleted file mode 100644
index 85f69b87..00000000
--- a/apps/backend/src/utils/tweetsToThreads.ts
+++ /dev/null
@@ -1,108 +0,0 @@
-import * as cheerio from "cheerio";
-import { BaseError } from "../errors/baseError";
-import { Ok, Result } from "../errors/results";
-
-interface Tweet {
- id: string;
- text: string;
- links: Array;
- images: Array;
- videos: Array;
-}
-
-class ProcessTweetsError extends BaseError {
- constructor(message?: string, source?: string) {
- super("[Thread Proceessing Error]", message, source);
- }
-}
-
-type TweetProcessResult = Array;
-
-// there won't be a need for url caching right?
-export async function unrollTweets(
- url: string
-): Promise> {
- const tweetId = url.split("/").pop();
- const response = await fetch(`https://unrollnow.com/status/${tweetId}`, {
- headers: {
- "User-Agent":
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
- "Cache-Control": "max-age=3600",
- },
- });
-
- if (!response.ok) {
- const error = await response.text();
- console.error(error);
- throw new Error(`HTTP error! status: ${response.status} - ${error}`);
- }
-
- const html = await response.text();
- const $ = cheerio.load(html);
- const tweets: Array = [];
-
- const urlRegex = /(https?:\/\/\S+)/g;
- const paragraphs = $(".mainarticle p").toArray();
-
- const processedTweets = await Promise.all(
- paragraphs.map(async (element, i) => {
- const $tweet = $(element);
- let tweetText = $tweet.text().trim();
- if (tweetText.length < 1) {
- return null;
- }
-
- if (i === paragraphs.length - 1 && tweetText.toLowerCase() === "yes") {
- return null;
- }
-
- const shortUrls = tweetText.match(urlRegex) || [];
- console.log("SHORT_URLS_LEN", shortUrls.length);
- console.log("SHORT_URLS", shortUrls);
-
- const expandedUrls = await Promise.all(shortUrls.map(expandShortUrl));
-
- tweetText = tweetText.replace(urlRegex, "").trim().replace(/\s+/g, " ");
-
- const images = $tweet
- .nextUntil("p")
- .find("img.tweetimg")
- .map((i, img) => $(img).attr("src"))
- .get();
-
- const videos = $tweet
- .nextUntil("p")
- .find("video > source")
- .map((i, vid) => $(vid).attr("src"))
- .get();
-
- return {
- id: `${tweetId}_${i}`,
- text: tweetText,
- links: expandedUrls,
- images: images,
- videos: videos,
- };
- })
- );
-
- tweets.push(
- ...processedTweets.filter((tweet): tweet is Tweet => tweet !== null)
- );
-
- return Ok(tweets);
-}
-
-async function expandShortUrl(shortUrl: string): Promise {
- try {
- const response = await fetch(shortUrl, {
- method: "HEAD",
- redirect: "follow",
- });
- const expandedUrl = response.url;
- return expandedUrl;
- } catch (error) {
- console.error(`Failed to expand URL: ${shortUrl}`, error);
- return shortUrl;
- }
-}
diff --git a/apps/backend/src/utils/typeDecider.ts b/apps/backend/src/utils/typeDecider.ts
deleted file mode 100644
index 642b178e..00000000
--- a/apps/backend/src/utils/typeDecider.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { Result, Ok, Err } from "../errors/results";
-import { BaseError } from "../errors/baseError";
-
-export type contentType = "page" | "tweet" | "note" | "document" | "notion";
-
-class GetTypeError extends BaseError {
- constructor(message?: string, source?: string) {
- super("[Decide Type Error]", message, source);
- }
-}
-export const typeDecider = (
- content: string
-): Result => {
- try {
- // if the content is a URL, then it's a page. if its a URL with https://x.com/user/status/123, then it's a tweet.
- // if it ends with .pdf etc then it's a document. else, it's a note.
- // do strict checking with regex
- if (
- content.match(/https?:\/\/(x\.com|twitter\.com)\/[\w]+\/[\w]+\/[\d]+/)
- ) {
- return Ok("tweet");
- } else if (content.match(/\.(pdf|doc|docx|txt|rtf|odt|md)/i)) {
- return Ok("document");
- } else if (
- content.match(/https?:\/\/(www\.)?notion\.so\/.*/)
- ) {
- return Ok("notion");
- } else if (
- content.match(
- /^(https?:\/\/)?(www\.)?[a-z0-9]+([-.]{1}[a-z0-9]+)*\.[a-z]{2,5}(\/.*)?$/i
- )
- ) {
- return Ok("page");
- } else {
- return Ok("note");
- }
- } catch (e) {
- console.error("[Decide Type Error]", e);
- return Err(new GetTypeError((e as Error).message, "typeDecider"));
- }
-};
diff --git a/apps/backend/src/workflow/index.ts b/apps/backend/src/workflow/index.ts
deleted file mode 100644
index 8efcfacc..00000000
--- a/apps/backend/src/workflow/index.ts
+++ /dev/null
@@ -1,217 +0,0 @@
-import {
- WorkflowEntrypoint,
- WorkflowStep,
- WorkflowEvent,
-} from "cloudflare:workers";
-import { Env, WorkflowParams } from "../types";
-import { fetchContent } from "../utils/fetchers";
-import chunkText from "../utils/chunkers";
-import { database, eq, inArray } from "@supermemory/db";
-import {
- ChunkInsert,
- contentToSpace,
- documents,
- spaces,
-} from "@supermemory/db/schema";
-import { embedMany } from "ai";
-import { openai } from "../providers";
-import { chunk } from "@supermemory/db/schema";
-import { NonRetryableError } from "cloudflare:workflows";
-
-// TODO: handle errors properly here.
-
-export class ContentWorkflow extends WorkflowEntrypoint {
- async run(event: WorkflowEvent, step: WorkflowStep) {
- // Step 0: Check if user has reached memory limit
- await step.do("check memory limit", async () => {
- const existingMemories = await database(
- this.env.HYPERDRIVE.connectionString
- )
- .select()
- .from(documents)
- .where(eq(documents.userId, event.payload.userId));
-
- if (existingMemories.length >= 2000) {
- await database(this.env.HYPERDRIVE.connectionString)
- .delete(documents)
- .where(eq(documents.uuid, event.payload.uuid));
- throw new NonRetryableError(
- "You have reached the maximum limit of 2000 memories"
- );
- }
- });
-
- // Step 1: Get and format the content.
- const rawContent =
- event.payload.prefetched ??
- (await step.do(
- "fetch content",
- async () => await fetchContent(event.payload, this.env, step)
- ));
-
- // check that the rawcontent is not too big
- if (rawContent.contentToVectorize.length > 100000) {
- await database(this.env.HYPERDRIVE.connectionString)
- .delete(documents)
- .where(eq(documents.uuid, event.payload.uuid));
- throw new NonRetryableError("The content is too big (maximum 20 pages)");
- }
-
- const chunked = await step.do("chunk content", async () =>
- chunkText(rawContent.contentToVectorize, 768)
- );
-
- // Step 2: Create the document in the database.
- const document = await step.do("create document", async () => {
- try {
- // First check if document exists
- const existingDoc = await database(this.env.HYPERDRIVE.connectionString)
- .select()
- .from(documents)
- .where(eq(documents.uuid, event.payload.uuid))
- .limit(1);
-
- return await database(this.env.HYPERDRIVE.connectionString)
- .insert(documents)
- .values({
- userId: event.payload.userId,
- type: event.payload.type,
- uuid: event.payload.uuid,
- ...(event.payload.url && { url: event.payload.url }),
- title: rawContent.title,
- content: rawContent.contentToSave,
- description:
- "description" in rawContent
- ? (rawContent.description ?? "")
- : (event.payload.prefetched?.description ?? undefined),
- ogImage:
- "image" in rawContent
- ? (rawContent.image ?? "")
- : (event.payload.prefetched?.ogImage ?? undefined),
- raw: rawContent.contentToVectorize,
- isSuccessfullyProcessed: false,
- updatedAt: new Date(),
- ...(event.payload.createdAt && {
- createdAt: new Date(event.payload.createdAt),
- }),
- })
- .onConflictDoUpdate({
- target: documents.uuid,
- set: {
- title: rawContent.title,
- content: rawContent.contentToSave,
- description:
- "description" in rawContent
- ? (rawContent.description ?? "")
- : (event.payload.prefetched?.description ?? undefined),
- ogImage:
- "image" in rawContent
- ? (rawContent.image ?? "")
- : (event.payload.prefetched?.ogImage ?? undefined),
- raw: rawContent.contentToVectorize,
- isSuccessfullyProcessed: false,
- updatedAt: new Date(),
- },
- })
- .returning();
- } catch (error) {
- console.log("here's the error", error);
- // Check if error is a unique constraint violation
- if (
- error instanceof Error &&
- error.message.includes("document_url_user_id_idx")
- ) {
- // Document already exists for this user, stop workflow
- await database(this.env.HYPERDRIVE.connectionString)
- .delete(documents)
- .where(eq(documents.uuid, event.payload.uuid));
- throw new NonRetryableError("Document already exists for this user");
- }
- if (
- error instanceof Error &&
- error.message.includes("document_raw_user_idx")
- ) {
- await database(this.env.HYPERDRIVE.connectionString)
- .delete(documents)
- .where(eq(documents.uuid, event.payload.uuid));
- throw new NonRetryableError("The exact same document already exists");
- }
- throw error; // Re-throw other errors
- }
- });
-
- if (!document || document.length === 0) {
- throw new Error(
- "Failed to create/update document - no document returned"
- );
- }
-
- // Step 3: Generate embeddings
- const { data: embeddings } = await this.env.AI.run(
- "@cf/baai/bge-base-en-v1.5",
- {
- text: chunked,
- }
- );
-
- // Step 4: Prepare chunk data
- const chunkInsertData: ChunkInsert[] = await step.do(
- "prepare chunk data",
- async () =>
- chunked.map((chunk, index) => ({
- documentId: document[0].id,
- textContent: chunk,
- orderInDocument: index,
- embeddings: embeddings[index],
- }))
- );
-
- // Step 5: Insert chunks
- if (chunkInsertData.length > 0) {
- await step.do("insert chunks", async () =>
- database(this.env.HYPERDRIVE.connectionString).transaction(
- async (trx) => {
- await trx.insert(chunk).values(chunkInsertData);
- }
- )
- );
- }
-
- // step 6: add content to spaces
- if (event.payload.spaces) {
- await step.do("add content to spaces", async () => {
- await database(this.env.HYPERDRIVE.connectionString).transaction(
- async (trx) => {
- // First get the space IDs from the UUIDs
- const spaceIds = await trx
- .select({ id: spaces.id })
- .from(spaces)
- .where(inArray(spaces.uuid, event.payload.spaces ?? []));
-
- if (spaceIds.length === 0) {
- return;
- }
-
- // Then insert the content-space mappings using the actual space IDs
- await trx.insert(contentToSpace).values(
- spaceIds.map((space) => ({
- contentId: document[0].id,
- spaceId: space.id,
- }))
- );
- }
- );
- });
- }
-
- // Step 7: Mark the document as successfully processed
- await step.do("mark document as successfully processed", async () => {
- await database(this.env.HYPERDRIVE.connectionString)
- .update(documents)
- .set({
- isSuccessfullyProcessed: true,
- })
- .where(eq(documents.id, document[0].id));
- });
- }
-}
diff --git a/apps/backend/tailwind.config.js b/apps/backend/tailwind.config.js
deleted file mode 100644
index f7c22ec3..00000000
--- a/apps/backend/tailwind.config.js
+++ /dev/null
@@ -1,9 +0,0 @@
-/** @type {import('tailwindcss').Config} */
-module.exports = {
- content: ["./src/**/*.{js,ts,jsx,tsx}"],
- theme: {
- extend: {},
- },
- plugins: [],
-}
-
diff --git a/apps/backend/tsconfig.json b/apps/backend/tsconfig.json
deleted file mode 100644
index a45a87e9..00000000
--- a/apps/backend/tsconfig.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "compilerOptions": {
- "target": "ESNext",
- "module": "ESNext",
- "moduleResolution": "Bundler",
- "strict": true,
- "skipLibCheck": true,
- "lib": ["ESNext"],
- "types": [
- "@cloudflare/workers-types/experimental",
- "@cloudflare/workers-types"
- ],
- "jsx": "react-jsx",
- "jsxImportSource": "hono/jsx"
- }
-}
diff --git a/apps/backend/types.d.ts b/apps/backend/types.d.ts
deleted file mode 100644
index 1a304bc7..00000000
--- a/apps/backend/types.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-declare module "@mixmark-io/domino" {
- export function createDocument(html: string): Document;
- }
\ No newline at end of file
diff --git a/apps/backend/wrangler.toml b/apps/backend/wrangler.toml
deleted file mode 100644
index 36832053..00000000
--- a/apps/backend/wrangler.toml
+++ /dev/null
@@ -1,55 +0,0 @@
-name = "supermemory-backend"
-main = "src/index.tsx"
-compatibility_date = "2024-10-11"
-compatibility_flags = [ "nodejs_compat" ]
-
-[assets]
-directory = "./public/"
-binding = "ASSETS"
-
-
-[observability]
-enabled = true
-
-[placement]
-mode = "smart"
-
-[ai]
-binding = "AI"
-
-[[workflows]]
-name = "content-workflow-supermemory"
-binding = "CONTENT_WORKFLOW"
-class_name = "ContentWorkflow"
-
-
-[[kv_namespaces]]
-binding= "MD_CACHE"
-id = "3186489f943d409a9b772d876a58a73e"
-preview_id = "3186489f943d409a9b772d876a58a73e"
-
-[[kv_namespaces]]
-binding = "ENCRYPTED_TOKENS"
-id = "a1f048ee14644468ad63b817b5648a31"
-preview_id = "a1f048ee14644468ad63b817b5648a31"
-
-[[hyperdrive]]
-binding = "HYPERDRIVE"
-id = "3a377d1b9c084e698ee201f10dfa8131"
-localConnectionString = "postgres://postgres:postgres@localhost:5432/supermemorylocal?sslmode=require"
-
-[[unsafe.bindings]]
-name = "EMAIL_LIMITER"
-type = "ratelimit"
-namespace_id = "2114284"
-simple = { limit = 1, period = 60 }
-
-tail_consumers = [{service = "supermemory-backend-tail"}]
-
-[[durable_objects.bindings]]
-name = "RATE_LIMITER"
-class_name = "DurableObjectRateLimiter"
-
-[[migrations]]
-tag = "v1"
-new_classes = ["DurableObjectRateLimiter"]
\ No newline at end of file
diff --git a/apps/docs/README.md b/apps/docs/README.md
deleted file mode 100644
index 4cbe0750..00000000
--- a/apps/docs/README.md
+++ /dev/null
@@ -1,32 +0,0 @@
-# Mintlify Starter Kit
-
-Click on `Use this template` to copy the Mintlify starter kit. The starter kit contains examples including
-
-- Guide pages
-- Navigation
-- Customizations
-- API Reference pages
-- Use of popular components
-
-### Development
-
-Install the [Mintlify CLI](https://www.npmjs.com/package/mintlify) to preview the documentation changes locally. To install, use the following command
-
-```
-npm i -g mintlify
-```
-
-Run the following command at the root of your documentation (where mint.json is)
-
-```
-mintlify dev
-```
-
-### Publishing Changes
-
-Install our Github App to auto propagate changes from your repo to your deployment. Changes will be deployed to production automatically after pushing to the default branch. Find the link to install on your dashboard.
-
-#### Troubleshooting
-
-- Mintlify dev isn't running - Run `mintlify install` it'll re-install dependencies.
-- Page loads as a 404 - Make sure you are running in a folder with `mint.json`
diff --git a/apps/docs/api-reference/endpoints/connect/connect-app.mdx b/apps/docs/api-reference/endpoints/connect/connect-app.mdx
deleted file mode 100644
index 712c0739..00000000
--- a/apps/docs/api-reference/endpoints/connect/connect-app.mdx
+++ /dev/null
@@ -1,10 +0,0 @@
----
-openapi: get /connect/{app}
----
-
-You may connect supermemory to other apps.
-when you send a GET request to the \/connect:APP?id= endpoint, you will get a redirectURL. This is a safe URL that your users can click and select the appropriate files with. Once this is done, supermemory will periodically re-fetch and make sure that the data is always fresh.
-
-As of right now, these apps are supported:
-- Notion
-
diff --git a/apps/docs/api-reference/endpoints/connect/connection-information.mdx b/apps/docs/api-reference/endpoints/connect/connection-information.mdx
deleted file mode 100644
index d13af160..00000000
--- a/apps/docs/api-reference/endpoints/connect/connection-information.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
----
-openapi: get /connections/{connectionId}
----
-
-Get the connection details using this endpoint.
\ No newline at end of file
diff --git a/apps/docs/api-reference/endpoints/memory-management/delete-delete.mdx b/apps/docs/api-reference/endpoints/memory-management/delete-delete.mdx
deleted file mode 100644
index 57ba0ea4..00000000
--- a/apps/docs/api-reference/endpoints/memory-management/delete-delete.mdx
+++ /dev/null
@@ -1,3 +0,0 @@
----
-openapi: delete /delete/{id}
----
\ No newline at end of file
diff --git a/apps/docs/api-reference/endpoints/memory-management/post-add.mdx b/apps/docs/api-reference/endpoints/memory-management/post-add.mdx
deleted file mode 100644
index dd03dbe4..00000000
--- a/apps/docs/api-reference/endpoints/memory-management/post-add.mdx
+++ /dev/null
@@ -1,59 +0,0 @@
----
-openapi: post /add
----
-
-Add a new memory with content and metadata.
-
-Fields:
-
-`content`: string
-
-`id`: string
-
-`metadata`: Record
-
-The `content` can be of the following types:
-
-- note \/ Markdown
-
- - If it is a markdown, all the images inside `![]` image tags will automatically be parsed.
-
-- pdf
-
-- tweet
-
-- google_doc
-
-- notion_doc
-
-- webpage URL
-
- - Images and other content is also intelligently parsed in case of a webpage.
-
-
-The metadata provided is a JSON object.
-
-for eg.
-
-``` json
-{
- "classId": "21412",
- "year": "fifth"
-}
-
- ```
-
-If you wish to do exact searches, please use strings. But if you want to search in a range (time, numbers, prices), you can use numbers too.
-
-``` json
-{
- "price": 1250
-}
-
- ```
-
-More about \[metadata filtering here\]([https://docs.supermemory.ai/essentials/metadata-filtering](https://docs.supermemory.ai/essentials/metadata-filtering))
-
-The `id` is optional. If provided, supermemory will store the same ID as your internal database. This can help for retrieval purposes.
-
-If the `id` already exists, supermemory will update it instead.
\ No newline at end of file
diff --git a/apps/docs/api-reference/endpoints/memory-management/put-update.mdx b/apps/docs/api-reference/endpoints/memory-management/put-update.mdx
deleted file mode 100644
index cd8b408c..00000000
--- a/apps/docs/api-reference/endpoints/memory-management/put-update.mdx
+++ /dev/null
@@ -1,7 +0,0 @@
----
-openapi: put /update/{id}
----
-
-Update an existing memory.
-Please note that all existing metadata will be replaced with the new ones.
-You can also use the \/add endpoint along with the ID specified.
\ No newline at end of file
diff --git a/apps/docs/api-reference/endpoints/search/get-fastsearch.mdx b/apps/docs/api-reference/endpoints/search/get-fastsearch.mdx
deleted file mode 100644
index 8e088e35..00000000
--- a/apps/docs/api-reference/endpoints/search/get-fastsearch.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
----
-openapi: get /fastsearch
----
-
-Fast, lossy search using quantized embeddings. This can be used in case your app has text completions, or when searching fast is absolutely necessary.
\ No newline at end of file
diff --git a/apps/docs/api-reference/endpoints/search/post-search.mdx b/apps/docs/api-reference/endpoints/search/post-search.mdx
deleted file mode 100644
index 72352e4a..00000000
--- a/apps/docs/api-reference/endpoints/search/post-search.mdx
+++ /dev/null
@@ -1,12 +0,0 @@
----
-openapi: post /search
----
-
-Search through documents with metadata filtering.
-
-Body:
-`q`: Your search query
-
-`limit`: Number of documents you want to get
-
-`filters`: Filters can be applied as `AND, OR, negate, numeric` types. You can read more about it here - \[metadata filtering here\]([https://docs.supermemory.ai/essentials/metadata-filtering](https://docs.supermemory.ai/essentials/metadata-filtering))
diff --git a/apps/docs/api-reference/endpoints/settings.mdx b/apps/docs/api-reference/endpoints/settings.mdx
deleted file mode 100644
index 89120be7..00000000
--- a/apps/docs/api-reference/endpoints/settings.mdx
+++ /dev/null
@@ -1,3 +0,0 @@
----
-openapi: put /settings
----
\ No newline at end of file
diff --git a/apps/docs/changelog/overview.mdx b/apps/docs/changelog/overview.mdx
deleted file mode 100644
index d9cf59fe..00000000
--- a/apps/docs/changelog/overview.mdx
+++ /dev/null
@@ -1,12 +0,0 @@
----
-title: "Product Updates"
-description: "New updates and improvements"
-mode: "center"
----
-
-
- - You can now search for memories in multiple spaces at once.
- - All endpoints have been updated to `/v1` for better versioning
- - Improved documentation and examples
- - Interactive [API Playground](https://docs.supermemory.ai/api-reference)
-
\ No newline at end of file
diff --git a/apps/docs/essentials/metadata-filtering.mdx b/apps/docs/essentials/metadata-filtering.mdx
deleted file mode 100644
index d2df77ea..00000000
--- a/apps/docs/essentials/metadata-filtering.mdx
+++ /dev/null
@@ -1,78 +0,0 @@
----
-title: "Managing Multi-User Search Results"
-description: "Learn how to handle search results for different users in Supermemory"
-icon: "users"
----
-
-When building multi-user applications with Supermemory, you'll often need to manage data for different users accessing the same account.
-
-You might also want filters, like memories from **_multiple users_**, or in a certain **_time range_**, or products within a certain price category.
-
-You can do all this filtering using Supermemory's api.
-
-Here's a quick example
-
-```json
-{
- "AND": [
- {
- "filterType": "numeric",
- "key": "timestamp",
- "value": "1742745777",
- "negate": false,
- "numericOperator": ">"
- },
- {
- "key": "group",
- "value": "jira_users",
- "negate": false
- },
- {
- "OR": [
- {
- "key": "team_name",
- "value": "engineering",
- "negate": false
- },
- {
- "key": "org_name",
- "value": "supermemory",
- "negate": false
- }
- ]
- }
- ]
-}
-```
-
-You can compose these conditions together to add filtering:
-
-- `AND`
-- `OR`
-- `numeric` (greater than / less than)
-
-Here's an example call:
-
-```bash
-curl --location 'https://v2.api.supermemory.ai/search' \
---header 'x-api-key: supermemory_RXPx' \
---header 'Content-Type: application/json' \
---data '{
- "q": "How to use teamcity to set up a project?",
- "limit": 10,
- "filters": {
- "AND": [
- {
- "key": "book",
- "value": "maths",
- "negate": false
- },
- {
- "key": "author",
- "value": "r.d. sharma",
- "negate": false
- }
- ]
- }
-}'
-```
\ No newline at end of file
diff --git a/apps/docs/essentials/pricing.mdx b/apps/docs/essentials/pricing.mdx
deleted file mode 100644
index a2167460..00000000
--- a/apps/docs/essentials/pricing.mdx
+++ /dev/null
@@ -1,47 +0,0 @@
----
-title: "Pricing"
-description: "Our pricing plans"
-icon: "dollar-sign"
----
-
-### Free!
-
-Yes, everything is free & open source.
-Supermemory is built by [me](https://dhravya.dev), a college student. My life situations make it very difficult and almost impossible to monetise the product.
-
-Any kind of sponsorships / support would mean a lot to me, and help me keep supermemory alive.
-
-You can sponsor on my Github sponsors page - https://github.com/sponsors/dhravya
-
-### How can I trust you?
-
-Making the product free makes it hard to trust. "How will you manage the infra?", "How will you keep the product running?" are very valid questions.
-
-I've got you covered.
-
-Supermemory has the support of [Cloudflare startups program](https://www.cloudflare.com/forstartups/), [Google Cloud startup program](https://cloud.google.com/startups) and grants by [Vercel](https://vercel.com) and other amazing companies.
-
-We're fully committed to keeping the product running, and happy to sign any agreements you'd like.
-
-### Ask
-
-Please email me at dhravya@supermemory.com if you're interested in:
-
-- Sponsoring the product
-- Funding the product
-- Signing a letter of intent for potential funding rounds
-- Partnering with us
-
-### Self hosting guidelines
-
-As of right now, Supermemory is licensed under the [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](https://github.com/supermemoryai/supermemory/blob/main/LICENSE)
-
-This means,
-
-- You can use the code for personal projects, given appropriate attribution.
-- For non-commercial use, the code must be open source.
-- Please reach out to me if you want to use the code for commercial projects.
-
-If you're an enterprise, please reach out to me at dhravya@supermemory.com.
-
-You can still use the API as a hosted service.
diff --git a/apps/docs/favicon.png b/apps/docs/favicon.png
deleted file mode 100644
index fd3dd8d3..00000000
Binary files a/apps/docs/favicon.png and /dev/null differ
diff --git a/apps/docs/image.png b/apps/docs/image.png
deleted file mode 100644
index a99caa14..00000000
Binary files a/apps/docs/image.png and /dev/null differ
diff --git a/apps/docs/images/checks-passed.png b/apps/docs/images/checks-passed.png
deleted file mode 100644
index 3303c773..00000000
Binary files a/apps/docs/images/checks-passed.png and /dev/null differ
diff --git a/apps/docs/images/hero-dark.svg b/apps/docs/images/hero-dark.svg
deleted file mode 100644
index b2c2bcee..00000000
--- a/apps/docs/images/hero-dark.svg
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/apps/docs/images/hero-light.svg b/apps/docs/images/hero-light.svg
deleted file mode 100644
index 4d347b2a..00000000
--- a/apps/docs/images/hero-light.svg
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/apps/docs/images/setup/1.png b/apps/docs/images/setup/1.png
deleted file mode 100644
index aba55dc7..00000000
Binary files a/apps/docs/images/setup/1.png and /dev/null differ
diff --git a/apps/docs/images/setup/2.png b/apps/docs/images/setup/2.png
deleted file mode 100644
index 32f195cb..00000000
Binary files a/apps/docs/images/setup/2.png and /dev/null differ
diff --git a/apps/docs/images/setup/3.png b/apps/docs/images/setup/3.png
deleted file mode 100644
index a91ecaa4..00000000
Binary files a/apps/docs/images/setup/3.png and /dev/null differ
diff --git a/apps/docs/introduction.mdx b/apps/docs/introduction.mdx
deleted file mode 100644
index 1d804825..00000000
--- a/apps/docs/introduction.mdx
+++ /dev/null
@@ -1,156 +0,0 @@
----
-title: "Introduction"
-description: "Supermemory is the Memory API for the AI era."
----
-
-We built [Supermemory](https://supermemory.ai) and scaled the RAG system to 10,000,000\+ documents and multiple thousands of users.
-We faced challenges. It turns out that building scalable, reliable, production-ready Memory layer is pretty hard.
-
-Introducing the Supermemory API. An _affordable_, _easy-to-use_, and _production-ready_ Memory API for the AI era.
-
-
-
-
-
-Trusted by Open source [9k\+ stars](https://git.new/memory), one of the fastest [growing projects in Q3 2024](https://runacap.com/ross-index/q3-2024/), Product of the day on [ProductHunt](https://www.producthunt.com/posts/supermemory).
-
-...and thousands of you\!
-
-## Why Supermemory?
-
-### The problem
-
-... so you want to build your own memory layer. Let's go through your decision process:
-
-
-
-
- Found a vector database? good luck
-
- - Oh no, it's way too expensive. Time to switch.
- - Turns out it's painfully slow. Let's try another.
- - Great, now it won't scale. Back to square one.
- - The maintenance is a nightmare. Need something else.
-
-
-
-
- Which one to choose? Unless you have a PhD in AI, good luck figuring out:
-
- - Which model fits your use case
- - What are the performance tradeoffs
- - How to keep up with new releases
-
-
-
-
-
- - Websites: How do you handle JavaScript? What about rate limits?
- - PDFs: OCR keeps failing, text extraction is inconsistent
- - Images: Need computer vision models now?
- - Audio/Video: Transcription costs add up quickly
-
-
- - Multiple languages: Different models for each?
- - Various formats to parse: \
- β’ Markdown: Tables break everything \
- β’ HTML: Scripts and styles get in the way \
- β’ PDF: Layout ruins the extraction \
- β’ Word docs: Good luck with formatting \
- β’ And somehow make it all work together...
-
-
-
-
-
-And in the middle of all this, you're wondering...
-
-> "When will I actually ship my product?"
-
-### The solution
-
-If you are not a fan of reinventing the wheel, you can use Supermemory.
-
-
-
-
- - Start for free, scale as you grow - Simple API, deploy in minutes - No
- complex setup or maintenance - Clear, predictable pricing
-
-
-
-
-
- - Notion, Google Drive, Slack integration - Web scraping and PDF
- processing - Email and calendar sync - Custom connector SDK
-
-
-
-
-
- - Enterprise-grade security - Sub-200ms latency at scale - Automatic
- failover and redundancy - 99.9% uptime guarantee
-
-
-
-
-
- - Open source core - Active community - Regular security audits -
- Transparent development
-
-
-
-
-
-Stop reinventing the wheel. Focus on building your product while we handle the memory infrastructure.
-
-## Use cases
-
-What can you do with Supermemory?
-
-
-
- Quickly built chat apps like:
-
- β’ Chat with your Twitter bookmarks \
- β’ Interact with your PDF documents \
- β’ Chat with your company documentation \
- β’ Chat with your personal knowledge base
- ... and more\\!
-
-
- Search things with AI:
-
- β’ Product recommendations \
- β’ Knowledge base search \
- β’ Document similarity matching \
- β’ Content discovery systems \
- β’ Research paper analysis
-
-
- Assistants and Agents:
-
- β’ Email management \
- β’ Meeting summarization \
- β’ Task prioritization \
- β’ Calendar organization \
- β’ Personal knowledge management
-
-
- You can contribute to supermemory by making community import tools. Examples:
-
- β’ Notion \
- β’ IOS shortcuts
-
- \
- β’ YOUR app / service
-
-
\ No newline at end of file
diff --git a/apps/docs/logo/dark.svg b/apps/docs/logo/dark.svg
deleted file mode 100644
index 513d7685..00000000
--- a/apps/docs/logo/dark.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/apps/docs/logo/light.svg b/apps/docs/logo/light.svg
deleted file mode 100644
index 96ae2b7b..00000000
--- a/apps/docs/logo/light.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/apps/docs/mint.json b/apps/docs/mint.json
deleted file mode 100644
index bb47ae72..00000000
--- a/apps/docs/mint.json
+++ /dev/null
@@ -1,75 +0,0 @@
-{
- "$schema": "https://mintlify.com/schema.json",
- "name": "Supermemory | Memory API for the AI era",
- "logo": {
- "dark": "/logo/dark.svg",
- "light": "/logo/light.svg"
- },
- "favicon": "/favicon.png",
- "colors": {
- "primary": "#1E3A8A",
- "light": "#3B82F6",
- "dark": "#1E3A8A",
- "anchors": {
- "from": "#1E3A8A",
- "to": "#3B82F6"
- }
- },
- "topbarLinks": [
- {
- "name": "Support",
- "url": "mailto:dhravya@supermemory.com"
- }
- ],
- "topbarCtaButton": {
- "name": "Dashboard",
- "url": "https://supermemory.ai"
- },
- "tabs": [
- {
- "name": "API Reference",
- "url": "api-reference/endpoints",
- "openapi": "/openapi.json"
- },
- {
- "name": "Changelog",
- "url": "changelog/overview"
- }
- ],
- "anchors": [
- {
- "name": "Github",
- "icon": "github",
- "url": "https://git.new/memory"
- },
- {
- "name": "Ask the founder",
- "icon": "mail",
- "url": "mailto:dhravya@supermemory.com"
- },
- {
- "name": "X (Twitter)",
- "icon": "twitter",
- "url": "https://x.com/supermemoryai"
- }
- ],
- "navigation": [
- {
- "group": "Get Started (5 mins)",
- "pages": ["introduction", "quickstart", "self-hosting"]
- },
- {
- "group": "Essentials",
- "pages": ["essentials/metadata-filtering", "essentials/pricing"]
- },
- {
- "group": "Changelog",
- "pages": ["changelog/overview"]
- }
- ],
- "footerSocials": {
- "x": "https://x.com/supermemoryai",
- "github": "https://github.com/supermemoryai",
- "linkedin": "https://linkedin.com/company/supermemoryai"
- }
-}
diff --git a/apps/docs/openapi.json b/apps/docs/openapi.json
deleted file mode 100644
index 1ac21936..00000000
--- a/apps/docs/openapi.json
+++ /dev/null
@@ -1,625 +0,0 @@
-{
- "openapi": "3.1.0",
- "info": {
- "title": "Supermemory API",
- "description": "best memory api on π",
- "version": "2.0.0"
- },
- "servers": [
- {
- "url": "https://v2.api.supermemory.ai",
- "description": "Production Server"
- }
- ],
- "paths": {
- "/settings": {
- "put": {
- "responses": {},
- "operationId": "putSettings",
- "parameters": [],
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "shouldLLMFilter": {
- "type": "boolean"
- },
- "categories": {
- "type": "array",
- "items": {
- "type": "string",
- "minLength": 1,
- "maxLength": 50
- }
- },
- "filterPrompt": {
- "type": "string",
- "minLength": 1,
- "maxLength": 750
- },
- "includeItems": {
- "type": "array",
- "items": {
- "type": "string",
- "minLength": 1,
- "maxLength": 20
- }
- },
- "excludeItems": {
- "type": "array",
- "items": {
- "type": "string",
- "minLength": 1,
- "maxLength": 20
- }
- },
- "filterTags": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "tag": {
- "type": "string",
- "minLength": 1,
- "maxLength": 50
- },
- "score": {
- "type": "number",
- "minimum": 0
- }
- },
- "required": ["tag", "score"]
- }
- }
- }
- }
- }
- }
- }
- }
- },
- "/add": {
- "post": {
- "responses": {
- "200": {
- "description": "Memory added successfully",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "id": {
- "type": "string"
- },
- "status": {
- "type": "string"
- }
- },
- "required": ["id", "status"]
- }
- }
- }
- },
- "401": {
- "description": "Unauthorized",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "error": {
- "type": "string"
- },
- "details": {
- "type": "string"
- }
- },
- "required": ["error"]
- }
- }
- }
- }
- },
- "operationId": "postAdd",
- "tags": ["Memory Management"],
- "parameters": [],
- "description": "Add a new memory with content and metadata",
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "content": {
- "type": "string"
- },
- "metadata": {
- "type": "object",
- "additionalProperties": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "number"
- },
- {
- "type": "boolean"
- }
- ]
- }
- },
- "spaceIds": {
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "summarizeMemories": {
- "type": "boolean",
- "default": false
- },
- "id": {
- "type": "string"
- }
- },
- "required": ["content"]
- }
- }
- }
- }
- }
- },
- "/update/{id}": {
- "put": {
- "responses": {
- "200": {
- "description": "Memory updated successfully",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "id": {
- "type": "string"
- },
- "status": {
- "type": "string"
- }
- },
- "required": ["id", "status"]
- }
- }
- }
- },
- "404": {
- "description": "Memory not found",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "error": {
- "type": "string"
- },
- "details": {
- "type": "string"
- }
- },
- "required": ["error"]
- }
- }
- }
- }
- },
- "operationId": "putUpdateById",
- "tags": ["Memory Management"],
- "parameters": [
- {
- "in": "path",
- "name": "id",
- "schema": {
- "type": "string"
- },
- "required": true
- }
- ],
- "description": "Update an existing memory",
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "content": {
- "type": "string"
- },
- "metadata": {
- "type": "object",
- "additionalProperties": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "number"
- },
- {
- "type": "boolean"
- }
- ]
- }
- },
- "spaceIds": {
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "summarizeMemories": {
- "type": "boolean",
- "default": false
- }
- },
- "required": ["content"]
- }
- }
- }
- }
- }
- },
- "/delete/{id}": {
- "delete": {
- "responses": {
- "200": {
- "description": "Memory deleted successfully",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "success": {
- "type": "boolean"
- }
- },
- "required": ["success"]
- }
- }
- }
- },
- "404": {
- "description": "Memory not found",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "error": {
- "type": "string"
- },
- "details": {
- "type": "string"
- }
- },
- "required": ["error"]
- }
- }
- }
- }
- },
- "operationId": "deleteDeleteById",
- "tags": ["Memory Management"],
- "parameters": [
- {
- "in": "path",
- "name": "id",
- "schema": {
- "type": "string"
- },
- "required": true
- }
- ],
- "description": "Delete a memory"
- }
- },
- "/search": {
- "post": {
- "responses": {
- "200": {
- "description": "Search results",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "results": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "documentId": {
- "type": "string"
- },
- "chunks": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "content": {
- "type": "string"
- },
- "isRelevant": {
- "type": "boolean"
- }
- },
- "required": ["content", "isRelevant"]
- }
- },
- "score": {
- "type": "number"
- },
- "documentSummary": {
- "type": "string"
- },
- "metadata": {
- "type": "object",
- "additionalProperties": {}
- },
- "title": {
- "type": "string"
- },
- "createdAt": {
- "type": "string"
- },
- "updatedAt": {
- "type": "string"
- }
- },
- "required": [
- "documentId",
- "chunks",
- "score",
- "documentSummary",
- "metadata",
- "title",
- "createdAt",
- "updatedAt"
- ]
- }
- }
- },
- "required": ["results"]
- }
- }
- }
- },
- "400": {
- "description": "Invalid request parameters",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "error": {
- "type": "string"
- },
- "details": {
- "type": "string"
- }
- },
- "required": ["error"]
- }
- }
- }
- },
- "500": {
- "description": "Server error",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "error": {
- "type": "string"
- },
- "details": {
- "type": "string"
- }
- },
- "required": ["error"]
- }
- }
- }
- }
- },
- "operationId": "postSearch",
- "tags": ["Search"],
- "parameters": [],
- "description": "Search through documents with metadata filtering",
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "q": {
- "type": "string",
- "minLength": 1
- },
- "limit": {
- "type": "integer",
- "exclusiveMinimum": 0,
- "default": 10
- },
- "filters": {
- "anyOf": [
- {
- "type": "object",
- "properties": {
- "OR": {
- "type": "array",
- "items": {}
- },
- "AND": {
- "type": "array",
- "items": {}
- }
- }
- },
- {
- "type": "object",
- "additionalProperties": {}
- }
- ]
- },
- "categoriesFilter": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- },
- "required": ["q"]
- }
- }
- }
- }
- }
- },
- "/fastsearch": {
- "get": {
- "responses": {
- "200": {
- "description": "Fast search results",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "results": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "id": {
- "type": "string"
- },
- "content": {
- "type": "string"
- },
- "similarity": {
- "type": "number"
- }
- },
- "required": ["id", "content", "similarity"]
- }
- }
- },
- "required": ["results"]
- }
- }
- }
- },
- "500": {
- "description": "Server error",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "error": {
- "type": "string"
- },
- "details": {
- "type": "string"
- }
- },
- "required": ["error"]
- }
- }
- }
- }
- },
- "operationId": "getFastsearch",
- "tags": ["Search"],
- "parameters": [
- {
- "in": "query",
- "name": "q",
- "schema": {
- "type": "string",
- "minLength": 1
- },
- "required": true
- },
- {
- "in": "query",
- "name": "limit",
- "schema": {
- "type": "string",
- "pattern": "^\\d+$"
- },
- "required": false
- }
- ],
- "description": "Fast, lossy search using quantized embeddings"
- }
- },
- "/connect/{app}": {
- "get": {
- "responses": {},
- "operationId": "getConnectByApp",
- "tags": ["Connect"],
- "parameters": [
- {
- "in": "path",
- "name": "app",
- "schema": {
- "type": "string",
- "enum": ["notion"]
- },
- "required": true
- },
- {
- "in": "query",
- "name": "id",
- "schema": {
- "type": "string"
- },
- "required": true
- },
- {
- "in": "query",
- "name": "redirectUrl",
- "schema": {
- "type": "string"
- },
- "required": false
- }
- ]
- }
- },
- "/connections/{connectionId}": {
- "get": {
- "responses": {},
- "operationId": "getConnectionsByConnectionId",
- "tags": ["Connect"],
- "parameters": [
- {
- "in": "path",
- "name": "connectionId",
- "schema": {
- "type": "string"
- },
- "required": true
- }
- ]
- }
- }
- },
- "components": {
- "schemas": {}
- }
-}
diff --git a/apps/docs/quickstart.mdx b/apps/docs/quickstart.mdx
deleted file mode 100644
index bf7b2f6b..00000000
--- a/apps/docs/quickstart.mdx
+++ /dev/null
@@ -1,59 +0,0 @@
----
-title: "Get Started (5 mins)"
-description: "Start using Supermemory API in under 5 minutes"
----
-
-To use the Supermemory API, you'll need:
-
-1. An API key (get one by signing up at https://dev.supermemory.ai )
-2. Basic understanding of REST APIs
-3. A tool to make HTTP requests (like curl, Postman, or your favorite programming language)
-
-
-
- 1. Login into https://dev.supermemory.ai and create an organization
- 2. Create an api key, copy and save it securely.
-
- 
-
- Keep your API key secure and never share it publicly. You'll need this key for authenticating all API requests.
-
-
-
-For even starter quickstart, you can use our API playground here - [API Playground](/api-reference/endpoints/add-new-content)
-
-You can also browse the postman collection - [Postman Collection](https://documenter.getpostman.com/view/21641015/2sB2cUBhvq#cf679c90-d60b-4d0d-a7aa-a909e97e41c3)
-
-## Base URL
-
-All API requests should be made to:
-
-```
-https://v2.api.supermemory.ai
-```
-
-## Add your first memory
-
-```bash
-curl -X POST https://v2.api.supermemory.ai/add \
- -H "x-api-key: YOUR_API_KEY" \
- -H "Content-Type: application/json" \
- -d '{"content": "This is the content of my first memory."}'
-```
-
-This will add a new memory to your Supermemory account.
-
-Try it out in the [API Playground](/api-reference/endpoints/add-new-content)
-
-## Search your memories
-
-```bash
-curl -X POST https://v2.api.supermemory.ai/search \
- -H "x-api-key: YOUR_API_KEY" \
- -H "Content-Type: application/json" \
- -d '{"q": "This is the content of my first memory."}'
-```
-
-Try it out in the [API Playground](/api-reference/endpoints/search-content)
-
-That's it\\! You've now added your first memory and searched for it.
\ No newline at end of file
diff --git a/apps/docs/self-hosting.mdx b/apps/docs/self-hosting.mdx
deleted file mode 100644
index efac8170..00000000
--- a/apps/docs/self-hosting.mdx
+++ /dev/null
@@ -1,94 +0,0 @@
----
-title: "Self-hosting"
-description: "Self-host Supermemory on your own infrastructure"
----
-
-## Local Setup
-
-
-
- ```bash
- git clone https://github.com/supermemoryai/supermemory.git
- cd supermemory
- npm i -g bun
- bun install
- ```
-
-
-
- To spin up the database locally, use Docker Compose:
-
- ```bash
- docker-compose up -d
- ```
-
- This will start a PostgreSQL database with pgvector extension at `localhost:5432`.
-
- To generate and apply migrations:
- ```bash
- bun run generate-migration
- bun run migrate:local
- ```
-
- > Note: When coding or making changes, you MUST use the drizzle-orm functions exported from `packages/db` for interacting with the database. Not using them will cause type errors that are hard to debug.
-
-
-
- #### Backend (`apps/backend/.env` and `apps/backend/.dev.vars`):
-
- ```env
- WORKOS_API_KEY=your_workos_api_key
- WORKOS_CLIENT_ID=your_workos_client_id
- WORKOS_COOKIE_PASSWORD=your_cookie_password
- DATABASE_URL="postgresql://postgres:postgres@localhost:5432/supermemorylocal"
- CONTENT_WORKFLOW=your_content_workflow
- GEMINI_API_KEY=your_gemini_api_key
- NODE_ENV=development
- OPEN_AI_API_KEY=your_openai_api_key
- BRAINTRUST_API_KEY=your_braintrust_api_key
- RESEND_API_KEY=your_resend_api_key
- TURNSTILE_SECRET_KEY=your_turnstile_secret_key
- ```
-
- #### Web (`apps/web/.env` and `apps/web/.dev.vars`):
-
- ```env
- WORKOS_CLIENT_ID=your_workos_client_id
- WORKOS_API_KEY=your_workos_api_key
- WORKOS_REDIRECT_URI="http://localhost:3000/callback"
- WORKOS_COOKIE_PASSWORD=your_cookie_password
- DATABASE_URL="postgresql://postgres:postgres@localhost:5432/supermemorylocal"
-
- CLOUDFLARE_ACCOUNT_ID=your_cloudflare_account_id
- R2_ACCESS_KEY_ID=your_r2_access_key_id
- R2_SECRET_ACCESS_KEY=your_r2_secret_access_key
-
- BACKEND_URL=http://localhost:8787
- OPENAI_API_KEY=your_openai_api_key
- NOTION_CLIENT_ID=your_notion_client_id
- NOTION_CLIENT_SECRET=your_notion_client_secret
-
- NODE_ENV=development
- STRIPE_CHECKOUT_KEY=your_stripe_checkout_key
- STRIPE_WEBHOOK_SECRET=your_stripe_webhook_secret
- ```
-
- You also need to update the Wrangler config for the web app and backend to your own account's resources on Cloudflare.
-
-
-
- To edit the database schema, modify the files in `packages/db/schema.ts`, and then repeat the migration steps from the Database Setup section.
-
-
-
- 1. Install dependencies:
- ```bash
- bun install
- ```
-
- 2. Start the development servers:
- ```bash
- bun run dev
- ```
-
-
diff --git a/apps/docs/snippets/snippet-intro.mdx b/apps/docs/snippets/snippet-intro.mdx
deleted file mode 100644
index 32f95c0d..00000000
--- a/apps/docs/snippets/snippet-intro.mdx
+++ /dev/null
@@ -1 +0,0 @@
-hi
\ No newline at end of file
diff --git a/apps/extension/.gitignore b/apps/extension/.gitignore
deleted file mode 100644
index 219b3b74..00000000
--- a/apps/extension/.gitignore
+++ /dev/null
@@ -1,27 +0,0 @@
-# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
-
-# dependencies
-node_modules
-
-# testing
-coverage
-
-# production
-dist
-
-# misc
-.DS_Store
-
-# local env files
-.env.local
-.env.development.local
-.env.test.local
-.env.production.local
-
-# debug files
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-
-# extension.js
-extension-env.d.ts
\ No newline at end of file
diff --git a/apps/extension/README.md b/apps/extension/README.md
deleted file mode 100644
index a019a77d..00000000
--- a/apps/extension/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-Extension for Supermemory
-
-helps in importing twitter bookmarks / chrome bookmarks / current tab content into Supermemory
\ No newline at end of file
diff --git a/apps/extension/components.json b/apps/extension/components.json
deleted file mode 100644
index 7769c9a4..00000000
--- a/apps/extension/components.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "$schema": "https://ui.shadcn.com/schema.json",
- "style": "new-york",
- "rsc": false,
- "tsx": true,
- "tailwind": {
- "config": "tailwind.config.js",
- "css": "css/globals.css",
- "baseColor": "zinc",
- "cssVariables": true,
- "prefix": ""
- },
- "aliases": {
- "components": "@/ui",
- "utils": "@/lib/utils",
- "ui": "@/ui/shadcn",
- "lib": "@/lib",
- "hooks": "@/hooks"
- },
- "iconLibrary": "lucide"
-}
diff --git a/apps/extension/css/globals.css b/apps/extension/css/globals.css
deleted file mode 100644
index a1be0c34..00000000
--- a/apps/extension/css/globals.css
+++ /dev/null
@@ -1,59 +0,0 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
-
-@layer base {
- :root {
- --background: 0 0% 100%;
- --foreground: 222.2 47.4% 11.2%;
- --muted: 210 40% 96.1%;
- --muted-foreground: 215.4 16.3% 46.9%;
- --popover: 0 0% 100%;
- --popover-foreground: 222.2 47.4% 11.2%;
- --border: 214.3 31.8% 91.4%;
- --input: 214.3 31.8% 91.4%;
- --card: 0 0% 100%;
- --card-foreground: 222.2 47.4% 11.2%;
- --primary: 222.2 47.4% 11.2%;
- --primary-foreground: 210 40% 98%;
- --secondary: 210 40% 96.1%;
- --secondary-foreground: 222.2 47.4% 11.2%;
- --accent: 210 40% 96.1%;
- --accent-foreground: 222.2 47.4% 11.2%;
- --destructive: 0 100% 50%;
- --destructive-foreground: 210 40% 98%;
- --ring: 215 20.2% 65.1%;
- --radius: 0.5rem;
- }
-
- .dark {
- --background: 224 71% 4%;
- --foreground: 213 31% 91%;
- --muted: 223 47% 11%;
- --muted-foreground: 215.4 16.3% 56.9%;
- --accent: 216 34% 17%;
- --accent-foreground: 210 40% 98%;
- --popover: 224 71% 4%;
- --popover-foreground: 215 20.2% 65.1%;
- --border: 216 34% 17%;
- --input: 216 34% 17%;
- --card: 224 71% 4%;
- --card-foreground: 213 31% 91%;
- --primary: 210 40% 98%;
- --primary-foreground: 222.2 47.4% 1.2%;
- --secondary: 222.2 47.4% 11.2%;
- --secondary-foreground: 210 40% 98%;
- --destructive: 0 63% 31%;
- --destructive-foreground: 210 40% 98%;
- --ring: 216 34% 17%;
- }
-}
-
-@layer base {
- * {
- @apply border-border;
- }
- body {
- @apply font-sans antialiased bg-background text-foreground;
- }
-}
diff --git a/apps/extension/extension-env.d.ts b/apps/extension/extension-env.d.ts
deleted file mode 100644
index 6005b801..00000000
--- a/apps/extension/extension-env.d.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-// Required Extension.js types for TypeScript projects.
-// This file is auto-generated and should not be excluded.
-// If you need additional types, consider creating a new *.d.ts file and
-// referencing it in the "include" array of your tsconfig.json file.
-// See https://www.typescriptlang.org/tsconfig#include for more information.
-///
-
-// Polyfill types for browser.* APIs.
-///
diff --git a/apps/extension/images/icon/128.png b/apps/extension/images/icon/128.png
deleted file mode 100644
index d1fedfe2..00000000
Binary files a/apps/extension/images/icon/128.png and /dev/null differ
diff --git a/apps/extension/images/icon/16.png b/apps/extension/images/icon/16.png
deleted file mode 100644
index 7c5d791a..00000000
Binary files a/apps/extension/images/icon/16.png and /dev/null differ
diff --git a/apps/extension/images/icon/32.png b/apps/extension/images/icon/32.png
deleted file mode 100644
index 3cd1aa93..00000000
Binary files a/apps/extension/images/icon/32.png and /dev/null differ
diff --git a/apps/extension/images/icon/48.png b/apps/extension/images/icon/48.png
deleted file mode 100644
index fe9e1c49..00000000
Binary files a/apps/extension/images/icon/48.png and /dev/null differ
diff --git a/apps/extension/images/icon/favicon.ico b/apps/extension/images/icon/favicon.ico
deleted file mode 100644
index 90d7aafc..00000000
Binary files a/apps/extension/images/icon/favicon.ico and /dev/null differ
diff --git a/apps/extension/lib/utils.ts b/apps/extension/lib/utils.ts
deleted file mode 100644
index b406ea53..00000000
--- a/apps/extension/lib/utils.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { clsx, type ClassValue } from "clsx";
-import { twMerge } from "tailwind-merge";
-
-export function cn(...inputs: ClassValue[]) {
- return twMerge(clsx(inputs));
-}
-
-// getBaseURL function that checks if we are in dev or prod and returns the correct baseURL
-export async function getBaseURL() {
- if (typeof chrome === "undefined") {
- console.error("chrome is undefined: only run in background script");
- throw new Error("chrome is undefined: only run in background script");
- }
- const extensionInfo = await chrome.management.getSelf();
- console.info(`Running in ${extensionInfo.installType} mode`);
- // If we're in development mode, the id will contain 'development'
- return extensionInfo.installType.includes("development")
- ? "http://localhost:3000"
- : "https://supermemory.ai";
-}
diff --git a/apps/extension/manifest.json b/apps/extension/manifest.json
deleted file mode 100644
index ff4aba05..00000000
--- a/apps/extension/manifest.json
+++ /dev/null
@@ -1,37 +0,0 @@
-{
- "$schema": "https://json.schemastore.org/chrome-manifest.json",
- "manifest_version": 3,
- "version": "5.0.200",
- "homepage_url": "https://supermemory.ai",
- "name": "Supermemory",
- "description": "An extension for https://supermemory.ai - an AI hub for all your knowledge.",
- "author": "Dhravya Shah",
- "permissions": [
- "activeTab",
- "scripting",
- "tabs",
- "management",
- "webRequest",
- "storage",
- "bookmarks"
- ],
- "host_permissions": ["*://*/*"],
- "background": {
- "service_worker": "src/background.ts"
- },
- "action": {},
- "externally_connectable": {
- "matches": [
- "http://localhost:3000/*",
- "https://supermemory.ai/*",
- "https://beta.supermemory.ai/*",
- "http://supermemory.com/*"
- ]
- },
- "icons": {
- "16": "images/icon/16.png",
- "32": "images/icon/32.png",
- "48": "images/icon/48.png",
- "128": "images/icon/128.png"
- }
-}
diff --git a/apps/extension/package.json b/apps/extension/package.json
deleted file mode 100644
index eadb7393..00000000
--- a/apps/extension/package.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- "name": "supermemory-extension",
- "version": "1.0.0",
- "description": "A memory enhancement extension",
- "type": "module",
- "scripts": {
- "dev:css": "npx tailwindcss -i css/globals.css -o public/globals.css --watch",
- "dev:extension": "extension dev",
- "dev": "concurrently \"npm:dev:css\" \"npm:dev:extension\"",
- "build:css": "npx tailwindcss -i css/globals.css -o public/globals.css",
- "build:extension": "extension build",
- "build": "npm run build:css && npm run build:extension",
- "start": "npm run build && extension start",
- "zip": "zip -r supermemory-extension.zip ./dist/chrome/*"
- },
- "dependencies": {
- "@mozilla/readability": "^0.5.0",
- "@radix-ui/react-dialog": "^1.1.2",
- "@radix-ui/react-popover": "^1.1.2",
- "@radix-ui/react-slot": "^1.1.0",
- "@radix-ui/react-toast": "^1.2.2",
- "@types/react": "^18.3.1",
- "@types/react-dom": "^18.3.1",
- "class-variance-authority": "^0.7.1",
- "clsx": "^2.1.1",
- "cmdk": "1.0.0",
- "lucide-react": "^0.462.0",
- "react": "^18.3.1",
- "react-dom": "^18.3.1",
- "tailwind-merge": "^2.5.5",
- "tailwindcss-animate": "^1.0.7"
- },
- "devDependencies": {
- "@types/chrome": "^0.0.260",
- "extension": "latest",
- "typescript": "^5.3.3"
- }
-}
diff --git a/apps/extension/postcss.config.js b/apps/extension/postcss.config.js
deleted file mode 100644
index 33ad091d..00000000
--- a/apps/extension/postcss.config.js
+++ /dev/null
@@ -1,6 +0,0 @@
-module.exports = {
- plugins: {
- tailwindcss: {},
- autoprefixer: {},
- },
-}
diff --git a/apps/extension/public/globals.css b/apps/extension/public/globals.css
deleted file mode 100644
index afee1545..00000000
--- a/apps/extension/public/globals.css
+++ /dev/null
@@ -1,1632 +0,0 @@
-*, ::before, ::after {
- --tw-border-spacing-x: 0;
- --tw-border-spacing-y: 0;
- --tw-translate-x: 0;
- --tw-translate-y: 0;
- --tw-rotate: 0;
- --tw-skew-x: 0;
- --tw-skew-y: 0;
- --tw-scale-x: 1;
- --tw-scale-y: 1;
- --tw-pan-x: ;
- --tw-pan-y: ;
- --tw-pinch-zoom: ;
- --tw-scroll-snap-strictness: proximity;
- --tw-gradient-from-position: ;
- --tw-gradient-via-position: ;
- --tw-gradient-to-position: ;
- --tw-ordinal: ;
- --tw-slashed-zero: ;
- --tw-numeric-figure: ;
- --tw-numeric-spacing: ;
- --tw-numeric-fraction: ;
- --tw-ring-inset: ;
- --tw-ring-offset-width: 0px;
- --tw-ring-offset-color: #fff;
- --tw-ring-color: rgb(59 130 246 / 0.5);
- --tw-ring-offset-shadow: 0 0 #0000;
- --tw-ring-shadow: 0 0 #0000;
- --tw-shadow: 0 0 #0000;
- --tw-shadow-colored: 0 0 #0000;
- --tw-blur: ;
- --tw-brightness: ;
- --tw-contrast: ;
- --tw-grayscale: ;
- --tw-hue-rotate: ;
- --tw-invert: ;
- --tw-saturate: ;
- --tw-sepia: ;
- --tw-drop-shadow: ;
- --tw-backdrop-blur: ;
- --tw-backdrop-brightness: ;
- --tw-backdrop-contrast: ;
- --tw-backdrop-grayscale: ;
- --tw-backdrop-hue-rotate: ;
- --tw-backdrop-invert: ;
- --tw-backdrop-opacity: ;
- --tw-backdrop-saturate: ;
- --tw-backdrop-sepia: ;
- --tw-contain-size: ;
- --tw-contain-layout: ;
- --tw-contain-paint: ;
- --tw-contain-style: ;
-}
-
-::backdrop {
- --tw-border-spacing-x: 0;
- --tw-border-spacing-y: 0;
- --tw-translate-x: 0;
- --tw-translate-y: 0;
- --tw-rotate: 0;
- --tw-skew-x: 0;
- --tw-skew-y: 0;
- --tw-scale-x: 1;
- --tw-scale-y: 1;
- --tw-pan-x: ;
- --tw-pan-y: ;
- --tw-pinch-zoom: ;
- --tw-scroll-snap-strictness: proximity;
- --tw-gradient-from-position: ;
- --tw-gradient-via-position: ;
- --tw-gradient-to-position: ;
- --tw-ordinal: ;
- --tw-slashed-zero: ;
- --tw-numeric-figure: ;
- --tw-numeric-spacing: ;
- --tw-numeric-fraction: ;
- --tw-ring-inset: ;
- --tw-ring-offset-width: 0px;
- --tw-ring-offset-color: #fff;
- --tw-ring-color: rgb(59 130 246 / 0.5);
- --tw-ring-offset-shadow: 0 0 #0000;
- --tw-ring-shadow: 0 0 #0000;
- --tw-shadow: 0 0 #0000;
- --tw-shadow-colored: 0 0 #0000;
- --tw-blur: ;
- --tw-brightness: ;
- --tw-contrast: ;
- --tw-grayscale: ;
- --tw-hue-rotate: ;
- --tw-invert: ;
- --tw-saturate: ;
- --tw-sepia: ;
- --tw-drop-shadow: ;
- --tw-backdrop-blur: ;
- --tw-backdrop-brightness: ;
- --tw-backdrop-contrast: ;
- --tw-backdrop-grayscale: ;
- --tw-backdrop-hue-rotate: ;
- --tw-backdrop-invert: ;
- --tw-backdrop-opacity: ;
- --tw-backdrop-saturate: ;
- --tw-backdrop-sepia: ;
- --tw-contain-size: ;
- --tw-contain-layout: ;
- --tw-contain-paint: ;
- --tw-contain-style: ;
-}
-
-/*
-! tailwindcss v3.4.15 | MIT License | https://tailwindcss.com
-*/
-
-/*
-1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
-2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
-*/
-
-*,
-::before,
-::after {
- box-sizing: border-box;
- /* 1 */
- border-width: 0;
- /* 2 */
- border-style: solid;
- /* 2 */
- border-color: #e5e7eb;
- /* 2 */
-}
-
-::before,
-::after {
- --tw-content: '';
-}
-
-/*
-1. Use a consistent sensible line-height in all browsers.
-2. Prevent adjustments of font size after orientation changes in iOS.
-3. Use a more readable tab size.
-4. Use the user's configured `sans` font-family by default.
-5. Use the user's configured `sans` font-feature-settings by default.
-6. Use the user's configured `sans` font-variation-settings by default.
-7. Disable tap highlights on iOS
-*/
-
-html,
-:host {
- line-height: 1.5;
- /* 1 */
- -webkit-text-size-adjust: 100%;
- /* 2 */
- -moz-tab-size: 4;
- /* 3 */
- -o-tab-size: 4;
- tab-size: 4;
- /* 3 */
- font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
- /* 4 */
- font-feature-settings: normal;
- /* 5 */
- font-variation-settings: normal;
- /* 6 */
- -webkit-tap-highlight-color: transparent;
- /* 7 */
-}
-
-/*
-1. Remove the margin in all browsers.
-2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
-*/
-
-body {
- margin: 0;
- /* 1 */
- line-height: inherit;
- /* 2 */
-}
-
-/*
-1. Add the correct height in Firefox.
-2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
-3. Ensure horizontal rules are visible by default.
-*/
-
-hr {
- height: 0;
- /* 1 */
- color: inherit;
- /* 2 */
- border-top-width: 1px;
- /* 3 */
-}
-
-/*
-Add the correct text decoration in Chrome, Edge, and Safari.
-*/
-
-abbr:where([title]) {
- -webkit-text-decoration: underline dotted;
- text-decoration: underline dotted;
-}
-
-/*
-Remove the default font size and weight for headings.
-*/
-
-h1,
-h2,
-h3,
-h4,
-h5,
-h6 {
- font-size: inherit;
- font-weight: inherit;
-}
-
-/*
-Reset links to optimize for opt-in styling instead of opt-out.
-*/
-
-a {
- color: inherit;
- text-decoration: inherit;
-}
-
-/*
-Add the correct font weight in Edge and Safari.
-*/
-
-b,
-strong {
- font-weight: bolder;
-}
-
-/*
-1. Use the user's configured `mono` font-family by default.
-2. Use the user's configured `mono` font-feature-settings by default.
-3. Use the user's configured `mono` font-variation-settings by default.
-4. Correct the odd `em` font sizing in all browsers.
-*/
-
-code,
-kbd,
-samp,
-pre {
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
- /* 1 */
- font-feature-settings: normal;
- /* 2 */
- font-variation-settings: normal;
- /* 3 */
- font-size: 1em;
- /* 4 */
-}
-
-/*
-Add the correct font size in all browsers.
-*/
-
-small {
- font-size: 80%;
-}
-
-/*
-Prevent `sub` and `sup` elements from affecting the line height in all browsers.
-*/
-
-sub,
-sup {
- font-size: 75%;
- line-height: 0;
- position: relative;
- vertical-align: baseline;
-}
-
-sub {
- bottom: -0.25em;
-}
-
-sup {
- top: -0.5em;
-}
-
-/*
-1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
-2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
-3. Remove gaps between table borders by default.
-*/
-
-table {
- text-indent: 0;
- /* 1 */
- border-color: inherit;
- /* 2 */
- border-collapse: collapse;
- /* 3 */
-}
-
-/*
-1. Change the font styles in all browsers.
-2. Remove the margin in Firefox and Safari.
-3. Remove default padding in all browsers.
-*/
-
-button,
-input,
-optgroup,
-select,
-textarea {
- font-family: inherit;
- /* 1 */
- font-feature-settings: inherit;
- /* 1 */
- font-variation-settings: inherit;
- /* 1 */
- font-size: 100%;
- /* 1 */
- font-weight: inherit;
- /* 1 */
- line-height: inherit;
- /* 1 */
- letter-spacing: inherit;
- /* 1 */
- color: inherit;
- /* 1 */
- margin: 0;
- /* 2 */
- padding: 0;
- /* 3 */
-}
-
-/*
-Remove the inheritance of text transform in Edge and Firefox.
-*/
-
-button,
-select {
- text-transform: none;
-}
-
-/*
-1. Correct the inability to style clickable types in iOS and Safari.
-2. Remove default button styles.
-*/
-
-button,
-input:where([type='button']),
-input:where([type='reset']),
-input:where([type='submit']) {
- -webkit-appearance: button;
- /* 1 */
- background-color: transparent;
- /* 2 */
- background-image: none;
- /* 2 */
-}
-
-/*
-Use the modern Firefox focus style for all focusable elements.
-*/
-
-:-moz-focusring {
- outline: auto;
-}
-
-/*
-Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
-*/
-
-:-moz-ui-invalid {
- box-shadow: none;
-}
-
-/*
-Add the correct vertical alignment in Chrome and Firefox.
-*/
-
-progress {
- vertical-align: baseline;
-}
-
-/*
-Correct the cursor style of increment and decrement buttons in Safari.
-*/
-
-::-webkit-inner-spin-button,
-::-webkit-outer-spin-button {
- height: auto;
-}
-
-/*
-1. Correct the odd appearance in Chrome and Safari.
-2. Correct the outline style in Safari.
-*/
-
-[type='search'] {
- -webkit-appearance: textfield;
- /* 1 */
- outline-offset: -2px;
- /* 2 */
-}
-
-/*
-Remove the inner padding in Chrome and Safari on macOS.
-*/
-
-::-webkit-search-decoration {
- -webkit-appearance: none;
-}
-
-/*
-1. Correct the inability to style clickable types in iOS and Safari.
-2. Change font properties to `inherit` in Safari.
-*/
-
-::-webkit-file-upload-button {
- -webkit-appearance: button;
- /* 1 */
- font: inherit;
- /* 2 */
-}
-
-/*
-Add the correct display in Chrome and Safari.
-*/
-
-summary {
- display: list-item;
-}
-
-/*
-Removes the default spacing and border for appropriate elements.
-*/
-
-blockquote,
-dl,
-dd,
-h1,
-h2,
-h3,
-h4,
-h5,
-h6,
-hr,
-figure,
-p,
-pre {
- margin: 0;
-}
-
-fieldset {
- margin: 0;
- padding: 0;
-}
-
-legend {
- padding: 0;
-}
-
-ol,
-ul,
-menu {
- list-style: none;
- margin: 0;
- padding: 0;
-}
-
-/*
-Reset default styling for dialogs.
-*/
-
-dialog {
- padding: 0;
-}
-
-/*
-Prevent resizing textareas horizontally by default.
-*/
-
-textarea {
- resize: vertical;
-}
-
-/*
-1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
-2. Set the default placeholder color to the user's configured gray 400 color.
-*/
-
-input::-moz-placeholder, textarea::-moz-placeholder {
- opacity: 1;
- /* 1 */
- color: #9ca3af;
- /* 2 */
-}
-
-input::placeholder,
-textarea::placeholder {
- opacity: 1;
- /* 1 */
- color: #9ca3af;
- /* 2 */
-}
-
-/*
-Set the default cursor for buttons.
-*/
-
-button,
-[role="button"] {
- cursor: pointer;
-}
-
-/*
-Make sure disabled buttons don't get the pointer cursor.
-*/
-
-:disabled {
- cursor: default;
-}
-
-/*
-1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
-2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
- This can trigger a poorly considered lint error in some tools but is included by design.
-*/
-
-img,
-svg,
-video,
-canvas,
-audio,
-iframe,
-embed,
-object {
- display: block;
- /* 1 */
- vertical-align: middle;
- /* 2 */
-}
-
-/*
-Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
-*/
-
-img,
-video {
- max-width: 100%;
- height: auto;
-}
-
-/* Make elements with the HTML hidden attribute stay hidden by default */
-
-[hidden]:where(:not([hidden="until-found"])) {
- display: none;
-}
-
-:root {
- --background: 0 0% 100%;
- --foreground: 222.2 47.4% 11.2%;
- --muted: 210 40% 96.1%;
- --muted-foreground: 215.4 16.3% 46.9%;
- --popover: 0 0% 100%;
- --popover-foreground: 222.2 47.4% 11.2%;
- --border: 214.3 31.8% 91.4%;
- --input: 214.3 31.8% 91.4%;
- --card: 0 0% 100%;
- --card-foreground: 222.2 47.4% 11.2%;
- --primary: 222.2 47.4% 11.2%;
- --primary-foreground: 210 40% 98%;
- --secondary: 210 40% 96.1%;
- --secondary-foreground: 222.2 47.4% 11.2%;
- --accent: 210 40% 96.1%;
- --accent-foreground: 222.2 47.4% 11.2%;
- --destructive: 0 100% 50%;
- --destructive-foreground: 210 40% 98%;
- --ring: 215 20.2% 65.1%;
- --radius: 0.5rem;
-}
-
-* {
- border-color: hsl(var(--border));
-}
-
-body {
- background-color: hsl(var(--background));
- font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
- color: hsl(var(--foreground));
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-.container {
- width: 100%;
-}
-
-@media (min-width: 640px) {
- .container {
- max-width: 640px;
- }
-}
-
-@media (min-width: 768px) {
- .container {
- max-width: 768px;
- }
-}
-
-@media (min-width: 1024px) {
- .container {
- max-width: 1024px;
- }
-}
-
-@media (min-width: 1280px) {
- .container {
- max-width: 1280px;
- }
-}
-
-@media (min-width: 1536px) {
- .container {
- max-width: 1536px;
- }
-}
-
-.sr-only {
- position: absolute;
- width: 1px;
- height: 1px;
- padding: 0;
- margin: -1px;
- overflow: hidden;
- clip: rect(0, 0, 0, 0);
- white-space: nowrap;
- border-width: 0;
-}
-
-.fixed {
- position: fixed;
-}
-
-.absolute {
- position: absolute;
-}
-
-.relative {
- position: relative;
-}
-
-.inset-0 {
- inset: 0px;
-}
-
-.left-0 {
- left: 0px;
-}
-
-.left-\[50\%\] {
- left: 50%;
-}
-
-.right-0 {
- right: 0px;
-}
-
-.right-4 {
- right: 1rem;
-}
-
-.top-4 {
- top: 1rem;
-}
-
-.top-\[50\%\] {
- top: 50%;
-}
-
-.top-full {
- top: 100%;
-}
-
-.z-50 {
- z-index: 50;
-}
-
-.-mx-1 {
- margin-left: -0.25rem;
- margin-right: -0.25rem;
-}
-
-.ml-auto {
- margin-left: auto;
-}
-
-.mr-2 {
- margin-right: 0.5rem;
-}
-
-.mt-1 {
- margin-top: 0.25rem;
-}
-
-.mt-2 {
- margin-top: 0.5rem;
-}
-
-.flex {
- display: flex;
-}
-
-.inline-flex {
- display: inline-flex;
-}
-
-.grid {
- display: grid;
-}
-
-.hidden {
- display: none;
-}
-
-.h-1 {
- height: 0.25rem;
-}
-
-.h-1\.5 {
- height: 0.375rem;
-}
-
-.h-10 {
- height: 2.5rem;
-}
-
-.h-2\.5 {
- height: 0.625rem;
-}
-
-.h-3 {
- height: 0.75rem;
-}
-
-.h-4 {
- height: 1rem;
-}
-
-.h-6 {
- height: 1.5rem;
-}
-
-.h-8 {
- height: 2rem;
-}
-
-.h-9 {
- height: 2.25rem;
-}
-
-.h-full {
- height: 100%;
-}
-
-.h-px {
- height: 1px;
-}
-
-.max-h-\[240px\] {
- max-height: 240px;
-}
-
-.max-h-\[300px\] {
- max-height: 300px;
-}
-
-.w-1\.5 {
- width: 0.375rem;
-}
-
-.w-2\.5 {
- width: 0.625rem;
-}
-
-.w-3 {
- width: 0.75rem;
-}
-
-.w-4 {
- width: 1rem;
-}
-
-.w-6 {
- width: 1.5rem;
-}
-
-.w-72 {
- width: 18rem;
-}
-
-.w-9 {
- width: 2.25rem;
-}
-
-.w-full {
- width: 100%;
-}
-
-.max-w-\[200px\] {
- max-width: 200px;
-}
-
-.max-w-lg {
- max-width: 32rem;
-}
-
-.flex-1 {
- flex: 1 1 0%;
-}
-
-.flex-shrink-0 {
- flex-shrink: 0;
-}
-
-.shrink-0 {
- flex-shrink: 0;
-}
-
-.translate-x-\[-50\%\] {
- --tw-translate-x: -50%;
- transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
-}
-
-.translate-y-\[-50\%\] {
- --tw-translate-y: -50%;
- transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
-}
-
-.rotate-180 {
- --tw-rotate: 180deg;
- transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
-}
-
-.transform {
- transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
-}
-
-@keyframes spin {
- to {
- transform: rotate(360deg);
- }
-}
-
-.animate-spin {
- animation: spin 1s linear infinite;
-}
-
-.cursor-default {
- cursor: default;
-}
-
-.select-none {
- -webkit-user-select: none;
- -moz-user-select: none;
- user-select: none;
-}
-
-.flex-col {
- flex-direction: column;
-}
-
-.flex-col-reverse {
- flex-direction: column-reverse;
-}
-
-.flex-wrap {
- flex-wrap: wrap;
-}
-
-.items-center {
- align-items: center;
-}
-
-.justify-center {
- justify-content: center;
-}
-
-.justify-between {
- justify-content: space-between;
-}
-
-.gap-0\.5 {
- gap: 0.125rem;
-}
-
-.gap-1 {
- gap: 0.25rem;
-}
-
-.gap-1\.5 {
- gap: 0.375rem;
-}
-
-.gap-2 {
- gap: 0.5rem;
-}
-
-.gap-3 {
- gap: 0.75rem;
-}
-
-.gap-4 {
- gap: 1rem;
-}
-
-.space-y-1\.5 > :not([hidden]) ~ :not([hidden]) {
- --tw-space-y-reverse: 0;
- margin-top: calc(0.375rem * calc(1 - var(--tw-space-y-reverse)));
- margin-bottom: calc(0.375rem * var(--tw-space-y-reverse));
-}
-
-.space-y-2 > :not([hidden]) ~ :not([hidden]) {
- --tw-space-y-reverse: 0;
- margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
- margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
-}
-
-.space-y-4 > :not([hidden]) ~ :not([hidden]) {
- --tw-space-y-reverse: 0;
- margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
- margin-bottom: calc(1rem * var(--tw-space-y-reverse));
-}
-
-.overflow-hidden {
- overflow: hidden;
-}
-
-.overflow-y-auto {
- overflow-y: auto;
-}
-
-.overflow-x-hidden {
- overflow-x: hidden;
-}
-
-.truncate {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.whitespace-nowrap {
- white-space: nowrap;
-}
-
-.rounded {
- border-radius: 0.25rem;
-}
-
-.rounded-full {
- border-radius: 9999px;
-}
-
-.rounded-md {
- border-radius: calc(var(--radius) - 2px);
-}
-
-.rounded-sm {
- border-radius: calc(var(--radius) - 4px);
-}
-
-.rounded-xl {
- border-radius: 0.75rem;
-}
-
-.rounded-b-xl {
- border-bottom-right-radius: 0.75rem;
- border-bottom-left-radius: 0.75rem;
-}
-
-.border {
- border-width: 1px;
-}
-
-.border-b {
- border-bottom-width: 1px;
-}
-
-.border-b-2 {
- border-bottom-width: 2px;
-}
-
-.border-blue-500 {
- --tw-border-opacity: 1;
- border-color: rgb(59 130 246 / var(--tw-border-opacity, 1));
-}
-
-.border-input {
- border-color: hsl(var(--input));
-}
-
-.border-transparent {
- border-color: transparent;
-}
-
-.border-white {
- --tw-border-opacity: 1;
- border-color: rgb(255 255 255 / var(--tw-border-opacity, 1));
-}
-
-.border-white\/20 {
- border-color: rgb(255 255 255 / 0.2);
-}
-
-.border-white\/50 {
- border-color: rgb(255 255 255 / 0.5);
-}
-
-.bg-background {
- background-color: hsl(var(--background));
-}
-
-.bg-black\/80 {
- background-color: rgb(0 0 0 / 0.8);
-}
-
-.bg-blue-400 {
- --tw-bg-opacity: 1;
- background-color: rgb(96 165 250 / var(--tw-bg-opacity, 1));
-}
-
-.bg-blue-500 {
- --tw-bg-opacity: 1;
- background-color: rgb(59 130 246 / var(--tw-bg-opacity, 1));
-}
-
-.bg-border {
- background-color: hsl(var(--border));
-}
-
-.bg-destructive {
- background-color: hsl(var(--destructive));
-}
-
-.bg-gray-700 {
- --tw-bg-opacity: 1;
- background-color: rgb(55 65 81 / var(--tw-bg-opacity, 1));
-}
-
-.bg-gray-800 {
- --tw-bg-opacity: 1;
- background-color: rgb(31 41 55 / var(--tw-bg-opacity, 1));
-}
-
-.bg-gray-900 {
- --tw-bg-opacity: 1;
- background-color: rgb(17 24 39 / var(--tw-bg-opacity, 1));
-}
-
-.bg-green-500 {
- --tw-bg-opacity: 1;
- background-color: rgb(34 197 94 / var(--tw-bg-opacity, 1));
-}
-
-.bg-popover {
- background-color: hsl(var(--popover));
-}
-
-.bg-primary {
- background-color: hsl(var(--primary));
-}
-
-.bg-red-500 {
- --tw-bg-opacity: 1;
- background-color: rgb(239 68 68 / var(--tw-bg-opacity, 1));
-}
-
-.bg-secondary {
- background-color: hsl(var(--secondary));
-}
-
-.bg-transparent {
- background-color: transparent;
-}
-
-.bg-white\/10 {
- background-color: rgb(255 255 255 / 0.1);
-}
-
-.bg-white\/20 {
- background-color: rgb(255 255 255 / 0.2);
-}
-
-.bg-yellow-500 {
- --tw-bg-opacity: 1;
- background-color: rgb(234 179 8 / var(--tw-bg-opacity, 1));
-}
-
-.bg-gradient-to-br {
- background-image: linear-gradient(to bottom right, var(--tw-gradient-stops));
-}
-
-.from-gray-800 {
- --tw-gradient-from: #1f2937 var(--tw-gradient-from-position);
- --tw-gradient-to: rgb(31 41 55 / 0) var(--tw-gradient-to-position);
- --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
-}
-
-.to-gray-900 {
- --tw-gradient-to: #111827 var(--tw-gradient-to-position);
-}
-
-.p-0 {
- padding: 0px;
-}
-
-.p-1 {
- padding: 0.25rem;
-}
-
-.p-4 {
- padding: 1rem;
-}
-
-.p-6 {
- padding: 1.5rem;
-}
-
-.px-2 {
- padding-left: 0.5rem;
- padding-right: 0.5rem;
-}
-
-.px-2\.5 {
- padding-left: 0.625rem;
- padding-right: 0.625rem;
-}
-
-.px-3 {
- padding-left: 0.75rem;
- padding-right: 0.75rem;
-}
-
-.px-4 {
- padding-left: 1rem;
- padding-right: 1rem;
-}
-
-.px-8 {
- padding-left: 2rem;
- padding-right: 2rem;
-}
-
-.py-0\.5 {
- padding-top: 0.125rem;
- padding-bottom: 0.125rem;
-}
-
-.py-1 {
- padding-top: 0.25rem;
- padding-bottom: 0.25rem;
-}
-
-.py-1\.5 {
- padding-top: 0.375rem;
- padding-bottom: 0.375rem;
-}
-
-.py-2 {
- padding-top: 0.5rem;
- padding-bottom: 0.5rem;
-}
-
-.py-3 {
- padding-top: 0.75rem;
- padding-bottom: 0.75rem;
-}
-
-.py-6 {
- padding-top: 1.5rem;
- padding-bottom: 1.5rem;
-}
-
-.text-left {
- text-align: left;
-}
-
-.text-center {
- text-align: center;
-}
-
-.text-2xl {
- font-size: 1.5rem;
- line-height: 2rem;
-}
-
-.text-lg {
- font-size: 1.125rem;
- line-height: 1.75rem;
-}
-
-.text-sm {
- font-size: 0.875rem;
- line-height: 1.25rem;
-}
-
-.text-xs {
- font-size: 0.75rem;
- line-height: 1rem;
-}
-
-.font-bold {
- font-weight: 700;
-}
-
-.font-medium {
- font-weight: 500;
-}
-
-.font-semibold {
- font-weight: 600;
-}
-
-.leading-none {
- line-height: 1;
-}
-
-.tracking-tight {
- letter-spacing: -0.025em;
-}
-
-.tracking-widest {
- letter-spacing: 0.1em;
-}
-
-.text-blue-100 {
- --tw-text-opacity: 1;
- color: rgb(219 234 254 / var(--tw-text-opacity, 1));
-}
-
-.text-destructive-foreground {
- color: hsl(var(--destructive-foreground));
-}
-
-.text-foreground {
- color: hsl(var(--foreground));
-}
-
-.text-gray-100 {
- --tw-text-opacity: 1;
- color: rgb(243 244 246 / var(--tw-text-opacity, 1));
-}
-
-.text-gray-200 {
- --tw-text-opacity: 1;
- color: rgb(229 231 235 / var(--tw-text-opacity, 1));
-}
-
-.text-gray-300 {
- --tw-text-opacity: 1;
- color: rgb(209 213 219 / var(--tw-text-opacity, 1));
-}
-
-.text-green-400 {
- --tw-text-opacity: 1;
- color: rgb(74 222 128 / var(--tw-text-opacity, 1));
-}
-
-.text-muted-foreground {
- color: hsl(var(--muted-foreground));
-}
-
-.text-popover-foreground {
- color: hsl(var(--popover-foreground));
-}
-
-.text-primary {
- color: hsl(var(--primary));
-}
-
-.text-primary-foreground {
- color: hsl(var(--primary-foreground));
-}
-
-.text-secondary-foreground {
- color: hsl(var(--secondary-foreground));
-}
-
-.text-white {
- --tw-text-opacity: 1;
- color: rgb(255 255 255 / var(--tw-text-opacity, 1));
-}
-
-.text-white\/70 {
- color: rgb(255 255 255 / 0.7);
-}
-
-.text-white\/90 {
- color: rgb(255 255 255 / 0.9);
-}
-
-.underline-offset-4 {
- text-underline-offset: 4px;
-}
-
-.placeholder-white\/50::-moz-placeholder {
- color: rgb(255 255 255 / 0.5);
-}
-
-.placeholder-white\/50::placeholder {
- color: rgb(255 255 255 / 0.5);
-}
-
-.opacity-50 {
- opacity: 0.5;
-}
-
-.opacity-60 {
- opacity: 0.6;
-}
-
-.opacity-70 {
- opacity: 0.7;
-}
-
-.shadow {
- --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
- --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
- box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
-}
-
-.shadow-lg {
- --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
- --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
- box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
-}
-
-.shadow-md {
- --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
- --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
- box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
-}
-
-.shadow-sm {
- --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
- --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
- box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
-}
-
-.outline-none {
- outline: 2px solid transparent;
- outline-offset: 2px;
-}
-
-.outline {
- outline-style: solid;
-}
-
-.ring-offset-background {
- --tw-ring-offset-color: hsl(var(--background));
-}
-
-.filter {
- filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
-}
-
-.transition-all {
- transition-property: all;
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
- transition-duration: 150ms;
-}
-
-.transition-colors {
- transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
- transition-duration: 150ms;
-}
-
-.transition-opacity {
- transition-property: opacity;
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
- transition-duration: 150ms;
-}
-
-.transition-transform {
- transition-property: transform;
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
- transition-duration: 150ms;
-}
-
-.duration-150 {
- transition-duration: 150ms;
-}
-
-.duration-200 {
- transition-duration: 200ms;
-}
-
-.placeholder\:text-muted-foreground::-moz-placeholder {
- color: hsl(var(--muted-foreground));
-}
-
-.placeholder\:text-muted-foreground::placeholder {
- color: hsl(var(--muted-foreground));
-}
-
-.hover\:bg-accent:hover {
- background-color: hsl(var(--accent));
-}
-
-.hover\:bg-destructive\/80:hover {
- background-color: hsl(var(--destructive) / 0.8);
-}
-
-.hover\:bg-destructive\/90:hover {
- background-color: hsl(var(--destructive) / 0.9);
-}
-
-.hover\:bg-gray-800:hover {
- --tw-bg-opacity: 1;
- background-color: rgb(31 41 55 / var(--tw-bg-opacity, 1));
-}
-
-.hover\:bg-green-600:hover {
- --tw-bg-opacity: 1;
- background-color: rgb(22 163 74 / var(--tw-bg-opacity, 1));
-}
-
-.hover\:bg-primary\/80:hover {
- background-color: hsl(var(--primary) / 0.8);
-}
-
-.hover\:bg-primary\/90:hover {
- background-color: hsl(var(--primary) / 0.9);
-}
-
-.hover\:bg-secondary\/80:hover {
- background-color: hsl(var(--secondary) / 0.8);
-}
-
-.hover\:bg-white\/20:hover {
- background-color: rgb(255 255 255 / 0.2);
-}
-
-.hover\:text-accent-foreground:hover {
- color: hsl(var(--accent-foreground));
-}
-
-.hover\:text-white:hover {
- --tw-text-opacity: 1;
- color: rgb(255 255 255 / var(--tw-text-opacity, 1));
-}
-
-.hover\:underline:hover {
- text-decoration-line: underline;
-}
-
-.hover\:opacity-100:hover {
- opacity: 1;
-}
-
-.focus\:border-blue-500:focus {
- --tw-border-opacity: 1;
- border-color: rgb(59 130 246 / var(--tw-border-opacity, 1));
-}
-
-.focus\:outline-none:focus {
- outline: 2px solid transparent;
- outline-offset: 2px;
-}
-
-.focus\:ring-2:focus {
- --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
- --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
- box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
-}
-
-.focus\:ring-ring:focus {
- --tw-ring-color: hsl(var(--ring));
-}
-
-.focus\:ring-offset-2:focus {
- --tw-ring-offset-width: 2px;
-}
-
-.focus-visible\:outline-none:focus-visible {
- outline: 2px solid transparent;
- outline-offset: 2px;
-}
-
-.focus-visible\:ring-1:focus-visible {
- --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
- --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
- box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
-}
-
-.focus-visible\:ring-ring:focus-visible {
- --tw-ring-color: hsl(var(--ring));
-}
-
-.disabled\:pointer-events-none:disabled {
- pointer-events: none;
-}
-
-.disabled\:cursor-not-allowed:disabled {
- cursor: not-allowed;
-}
-
-.disabled\:opacity-50:disabled {
- opacity: 0.5;
-}
-
-.data-\[disabled\=true\]\:pointer-events-none[data-disabled="true"] {
- pointer-events: none;
-}
-
-.data-\[selected\=true\]\:bg-accent[data-selected="true"] {
- background-color: hsl(var(--accent));
-}
-
-.data-\[state\=open\]\:bg-accent[data-state="open"] {
- background-color: hsl(var(--accent));
-}
-
-.data-\[selected\=true\]\:text-accent-foreground[data-selected="true"] {
- color: hsl(var(--accent-foreground));
-}
-
-.data-\[state\=open\]\:text-muted-foreground[data-state="open"] {
- color: hsl(var(--muted-foreground));
-}
-
-.data-\[disabled\=true\]\:opacity-50[data-disabled="true"] {
- opacity: 0.5;
-}
-
-@media (min-width: 640px) {
- .sm\:flex-row {
- flex-direction: row;
- }
-
- .sm\:justify-end {
- justify-content: flex-end;
- }
-
- .sm\:space-x-2 > :not([hidden]) ~ :not([hidden]) {
- --tw-space-x-reverse: 0;
- margin-right: calc(0.5rem * var(--tw-space-x-reverse));
- margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
- }
-
- .sm\:rounded-lg {
- border-radius: var(--radius);
- }
-
- .sm\:text-left {
- text-align: left;
- }
-}
-
-.\[\&_\[cmdk-group-heading\]\]\:px-2 [cmdk-group-heading] {
- padding-left: 0.5rem;
- padding-right: 0.5rem;
-}
-
-.\[\&_\[cmdk-group-heading\]\]\:py-1\.5 [cmdk-group-heading] {
- padding-top: 0.375rem;
- padding-bottom: 0.375rem;
-}
-
-.\[\&_\[cmdk-group-heading\]\]\:text-xs [cmdk-group-heading] {
- font-size: 0.75rem;
- line-height: 1rem;
-}
-
-.\[\&_\[cmdk-group-heading\]\]\:font-medium [cmdk-group-heading] {
- font-weight: 500;
-}
-
-.\[\&_\[cmdk-group-heading\]\]\:text-muted-foreground [cmdk-group-heading] {
- color: hsl(var(--muted-foreground));
-}
-
-.\[\&_\[cmdk-group\]\:not\(\[hidden\]\)_\~\[cmdk-group\]\]\:pt-0 [cmdk-group]:not([hidden]) ~[cmdk-group] {
- padding-top: 0px;
-}
-
-.\[\&_\[cmdk-group\]\]\:px-2 [cmdk-group] {
- padding-left: 0.5rem;
- padding-right: 0.5rem;
-}
-
-.\[\&_\[cmdk-input-wrapper\]_svg\]\:h-5 [cmdk-input-wrapper] svg {
- height: 1.25rem;
-}
-
-.\[\&_\[cmdk-input-wrapper\]_svg\]\:w-5 [cmdk-input-wrapper] svg {
- width: 1.25rem;
-}
-
-.\[\&_\[cmdk-input\]\]\:h-12 [cmdk-input] {
- height: 3rem;
-}
-
-.\[\&_\[cmdk-item\]\]\:px-2 [cmdk-item] {
- padding-left: 0.5rem;
- padding-right: 0.5rem;
-}
-
-.\[\&_\[cmdk-item\]\]\:py-3 [cmdk-item] {
- padding-top: 0.75rem;
- padding-bottom: 0.75rem;
-}
-
-.\[\&_\[cmdk-item\]_svg\]\:h-5 [cmdk-item] svg {
- height: 1.25rem;
-}
-
-.\[\&_\[cmdk-item\]_svg\]\:w-5 [cmdk-item] svg {
- width: 1.25rem;
-}
-
-.\[\&_svg\]\:pointer-events-none svg {
- pointer-events: none;
-}
-
-.\[\&_svg\]\:size-4 svg {
- width: 1rem;
- height: 1rem;
-}
-
-.\[\&_svg\]\:shrink-0 svg {
- flex-shrink: 0;
-}
diff --git a/apps/extension/public/logo.svg b/apps/extension/public/logo.svg
deleted file mode 100644
index 5ca15922..00000000
--- a/apps/extension/public/logo.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/apps/extension/scripts/content.tsx b/apps/extension/scripts/content.tsx
deleted file mode 100644
index a7668545..00000000
--- a/apps/extension/scripts/content.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-import React, { StrictMode } from "react";
-import { createRoot, Root } from "react-dom/client";
-import SupermemoryContent from "../src/content";
-import { css } from "./css";
-
-let globalRoot: Root | null = null;
-
-// Function to cleanup React app
-function cleanup() {
- const container = document.getElementById("supermemory-root");
- if (container) {
- globalRoot?.unmount();
- container.remove();
- }
-}
-
-async function injectReactApp() {
- // Create a shadow DOM root
- const containerId = "supermemory-root";
- let container = document.getElementById(containerId);
-
- if (!container) {
- container = document.createElement("div");
- container.id = containerId;
- container.style.position = "absolute";
- container.style.top = "0";
- container.style.left = "0";
- container.style.width = "100%";
- container.style.height = "100%";
- container.style.zIndex = "2147483647"; // Maximum z-index value
-
- // Add the container to document first
- document.body.appendChild(container);
-
- // Attach shadow DOM
- const shadowRoot = container.attachShadow({ mode: "open" });
-
- // Create an inner container for React
- const reactContainer = document.createElement("div");
- shadowRoot.appendChild(reactContainer);
-
- // Inject global CSS into shadow DOM by fetching the CSS file content
- // const cssURL = chrome.runtime.getURL("globals.css");
- // const cssURL = `chrome-extension://${chrome.runtime.id}/globals.css`;
-
- // i'm, fucking tired lol.
- // const response = await fetch(cssURL);
- // const cssText = await response.text();
- const globalStyle = document.createElement("style");
- globalStyle.textContent = css;
- shadowRoot.appendChild(globalStyle);
-
- const root = createRoot(reactContainer);
- globalRoot = root;
- root.render( );
- }
-}
-
-// check if there's already our react container
-if (document.getElementById("supermemory-root")) {
- cleanup();
-} else {
- injectReactApp();
-}
diff --git a/apps/extension/scripts/css.tsx b/apps/extension/scripts/css.tsx
deleted file mode 100644
index 5e8701a2..00000000
--- a/apps/extension/scripts/css.tsx
+++ /dev/null
@@ -1,1584 +0,0 @@
-export const css = `*, ::before, ::after {
- --tw-border-spacing-x: 0;
- --tw-border-spacing-y: 0;
- --tw-translate-x: 0;
- --tw-translate-y: 0;
- --tw-rotate: 0;
- --tw-skew-x: 0;
- --tw-skew-y: 0;
- --tw-scale-x: 1;
- --tw-scale-y: 1;
- --tw-pan-x: ;
- --tw-pan-y: ;
- --tw-pinch-zoom: ;
- --tw-scroll-snap-strictness: proximity;
- --tw-gradient-from-position: ;
- --tw-gradient-via-position: ;
- --tw-gradient-to-position: ;
- --tw-ordinal: ;
- --tw-slashed-zero: ;
- --tw-numeric-figure: ;
- --tw-numeric-spacing: ;
- --tw-numeric-fraction: ;
- --tw-ring-inset: ;
- --tw-ring-offset-width: 0px;
- --tw-ring-offset-color: #fff;
- --tw-ring-color: rgb(59 130 246 / 0.5);
- --tw-ring-offset-shadow: 0 0 #0000;
- --tw-ring-shadow: 0 0 #0000;
- --tw-shadow: 0 0 #0000;
- --tw-shadow-colored: 0 0 #0000;
- --tw-blur: ;
- --tw-brightness: ;
- --tw-contrast: ;
- --tw-grayscale: ;
- --tw-hue-rotate: ;
- --tw-invert: ;
- --tw-saturate: ;
- --tw-sepia: ;
- --tw-drop-shadow: ;
- --tw-backdrop-blur: ;
- --tw-backdrop-brightness: ;
- --tw-backdrop-contrast: ;
- --tw-backdrop-grayscale: ;
- --tw-backdrop-hue-rotate: ;
- --tw-backdrop-invert: ;
- --tw-backdrop-opacity: ;
- --tw-backdrop-saturate: ;
- --tw-backdrop-sepia: ;
- --tw-contain-size: ;
- --tw-contain-layout: ;
- --tw-contain-paint: ;
- --tw-contain-style: ;
-}
-
-::backdrop {
- --tw-border-spacing-x: 0;
- --tw-border-spacing-y: 0;
- --tw-translate-x: 0;
- --tw-translate-y: 0;
- --tw-rotate: 0;
- --tw-skew-x: 0;
- --tw-skew-y: 0;
- --tw-scale-x: 1;
- --tw-scale-y: 1;
- --tw-pan-x: ;
- --tw-pan-y: ;
- --tw-pinch-zoom: ;
- --tw-scroll-snap-strictness: proximity;
- --tw-gradient-from-position: ;
- --tw-gradient-via-position: ;
- --tw-gradient-to-position: ;
- --tw-ordinal: ;
- --tw-slashed-zero: ;
- --tw-numeric-figure: ;
- --tw-numeric-spacing: ;
- --tw-numeric-fraction: ;
- --tw-ring-inset: ;
- --tw-ring-offset-width: 0px;
- --tw-ring-offset-color: #fff;
- --tw-ring-color: rgb(59 130 246 / 0.5);
- --tw-ring-offset-shadow: 0 0 #0000;
- --tw-ring-shadow: 0 0 #0000;
- --tw-shadow: 0 0 #0000;
- --tw-shadow-colored: 0 0 #0000;
- --tw-blur: ;
- --tw-brightness: ;
- --tw-contrast: ;
- --tw-grayscale: ;
- --tw-hue-rotate: ;
- --tw-invert: ;
- --tw-saturate: ;
- --tw-sepia: ;
- --tw-drop-shadow: ;
- --tw-backdrop-blur: ;
- --tw-backdrop-brightness: ;
- --tw-backdrop-contrast: ;
- --tw-backdrop-grayscale: ;
- --tw-backdrop-hue-rotate: ;
- --tw-backdrop-invert: ;
- --tw-backdrop-opacity: ;
- --tw-backdrop-saturate: ;
- --tw-backdrop-sepia: ;
- --tw-contain-size: ;
- --tw-contain-layout: ;
- --tw-contain-paint: ;
- --tw-contain-style: ;
-}
-
-/*
-! tailwindcss v3.4.15 | MIT License | https://tailwindcss.com
-*/
-
-/*
-1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
-2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
-*/
-
-*,
-::before,
-::after {
- box-sizing: border-box;
- /* 1 */
- border-width: 0;
- /* 2 */
- border-style: solid;
- /* 2 */
- border-color: #e5e7eb;
- /* 2 */
-}
-
-::before,
-::after {
- --tw-content: '';
-}
-
-/*
-1. Use a consistent sensible line-height in all browsers.
-2. Prevent adjustments of font size after orientation changes in iOS.
-3. Use a more readable tab size.
-4. Use the user's configured \`sans\` font-family by default.
-5. Use the user's configured \`sans\` font-feature-settings by default.
-6. Use the user's configured \`sans\` font-variation-settings by default.
-7. Disable tap highlights on iOS
-*/
-
-html,
-:host {
- line-height: 1.5;
- /* 1 */
- -webkit-text-size-adjust: 100%;
- /* 2 */
- -moz-tab-size: 4;
- /* 3 */
- -o-tab-size: 4;
- tab-size: 4;
- /* 3 */
- font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
- /* 4 */
- font-feature-settings: normal;
- /* 5 */
- font-variation-settings: normal;
- /* 6 */
- -webkit-tap-highlight-color: transparent;
- /* 7 */
-}
-
-/*
-1. Remove the margin in all browsers.
-2. Inherit line-height from \`html\` so users can set them as a class directly on the \`html\` element.
-*/
-
-body {
- margin: 0;
- /* 1 */
- line-height: inherit;
- /* 2 */
-}
-
-/*
-1. Add the correct height in Firefox.
-2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
-3. Ensure horizontal rules are visible by default.
-*/
-
-hr {
- height: 0;
- /* 1 */
- color: inherit;
- /* 2 */
- border-top-width: 1px;
- /* 3 */
-}
-
-/*
-Add the correct text decoration in Chrome, Edge, and Safari.
-*/
-
-abbr:where([title]) {
- -webkit-text-decoration: underline dotted;
- text-decoration: underline dotted;
-}
-
-/*
-Remove the default font size and weight for headings.
-*/
-
-h1,
-h2,
-h3,
-h4,
-h5,
-h6 {
- font-size: inherit;
- font-weight: inherit;
-}
-
-/*
-Reset links to optimize for opt-in styling instead of opt-out.
-*/
-
-a {
- color: inherit;
- text-decoration: inherit;
-}
-
-/*
-Add the correct font weight in Edge and Safari.
-*/
-
-b,
-strong {
- font-weight: bolder;
-}
-
-/*
-1. Use the user's configured \`mono\` font-family by default.
-2. Use the user's configured \`mono\` font-feature-settings by default.
-3. Use the user's configured \`mono\` font-variation-settings by default.
-4. Correct the odd \`em\` font sizing in all browsers.
-*/
-
-code,
-kbd,
-samp,
-pre {
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
- /* 1 */
- font-feature-settings: normal;
- /* 2 */
- font-variation-settings: normal;
- /* 3 */
- font-size: 1em;
- /* 4 */
-}
-
-/*
-Add the correct font size in all browsers.
-*/
-
-small {
- font-size: 80%;
-}
-
-/*
-Prevent \`sub\` and \`sup\` elements from affecting the line height in all browsers.
-*/
-
-sub,
-sup {
- font-size: 75%;
- line-height: 0;
- position: relative;
- vertical-align: baseline;
-}
-
-sub {
- bottom: -0.25em;
-}
-
-sup {
- top: -0.5em;
-}
-
-/*
-1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
-2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
-3. Remove gaps between table borders by default.
-*/
-
-table {
- text-indent: 0;
- /* 1 */
- border-color: inherit;
- /* 2 */
- border-collapse: collapse;
- /* 3 */
-}
-
-/*
-1. Change the font styles in all browsers.
-2. Remove the margin in Firefox and Safari.
-3. Remove default padding in all browsers.
-*/
-
-button,
-input,
-optgroup,
-select,
-textarea {
- font-family: inherit;
- /* 1 */
- font-feature-settings: inherit;
- /* 1 */
- font-variation-settings: inherit;
- /* 1 */
- font-size: 100%;
- /* 1 */
- font-weight: inherit;
- /* 1 */
- line-height: inherit;
- /* 1 */
- letter-spacing: inherit;
- /* 1 */
- color: inherit;
- /* 1 */
- margin: 0;
- /* 2 */
- padding: 0;
- /* 3 */
-}
-
-/*
-Remove the inheritance of text transform in Edge and Firefox.
-*/
-
-button,
-select {
- text-transform: none;
-}
-
-/*
-1. Correct the inability to style clickable types in iOS and Safari.
-2. Remove default button styles.
-*/
-
-button,
-input:where([type='button']),
-input:where([type='reset']),
-input:where([type='submit']) {
- -webkit-appearance: button;
- /* 1 */
- background-color: transparent;
- /* 2 */
- background-image: none;
- /* 2 */
-}
-
-/*
-Use the modern Firefox focus style for all focusable elements.
-*/
-
-:-moz-focusring {
- outline: auto;
-}
-
-/*
-Remove the additional \`:invalid\` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
-*/
-
-:-moz-ui-invalid {
- box-shadow: none;
-}
-
-/*
-Add the correct vertical alignment in Chrome and Firefox.
-*/
-
-progress {
- vertical-align: baseline;
-}
-
-/*
-Correct the cursor style of increment and decrement buttons in Safari.
-*/
-
-::-webkit-inner-spin-button,
-::-webkit-outer-spin-button {
- height: auto;
-}
-
-/*
-1. Correct the odd appearance in Chrome and Safari.
-2. Correct the outline style in Safari.
-*/
-
-[type='search'] {
- -webkit-appearance: textfield;
- /* 1 */
- outline-offset: -2px;
- /* 2 */
-}
-
-/*
-Remove the inner padding in Chrome and Safari on macOS.
-*/
-
-::-webkit-search-decoration {
- -webkit-appearance: none;
-}
-
-/*
-1. Correct the inability to style clickable types in iOS and Safari.
-2. Change font properties to \`inherit\` in Safari.
-*/
-
-::-webkit-file-upload-button {
- -webkit-appearance: button;
- /* 1 */
- font: inherit;
- /* 2 */
-}
-
-/*
-Add the correct display in Chrome and Safari.
-*/
-
-summary {
- display: list-item;
-}
-
-/*
-Removes the default spacing and border for appropriate elements.
-*/
-
-blockquote,
-dl,
-dd,
-h1,
-h2,
-h3,
-h4,
-h5,
-h6,
-hr,
-figure,
-p,
-pre {
- margin: 0;
-}
-
-fieldset {
- margin: 0;
- padding: 0;
-}
-
-legend {
- padding: 0;
-}
-
-ol,
-ul,
-menu {
- list-style: none;
- margin: 0;
- padding: 0;
-}
-
-/*
-Reset default styling for dialogs.
-*/
-
-dialog {
- padding: 0;
-}
-
-/*
-Prevent resizing textareas horizontally by default.
-*/
-
-textarea {
- resize: vertical;
-}
-
-/*
-1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
-2. Set the default placeholder color to the user's configured gray 400 color.
-*/
-
-input::-moz-placeholder, textarea::-moz-placeholder {
- opacity: 1;
- /* 1 */
- color: #9ca3af;
- /* 2 */
-}
-
-input::placeholder,
-textarea::placeholder {
- opacity: 1;
- /* 1 */
- color: #9ca3af;
- /* 2 */
-}
-
-/*
-Set the default cursor for buttons.
-*/
-
-button,
-[role="button"] {
- cursor: pointer;
-}
-
-/*
-Make sure disabled buttons don't get the pointer cursor.
-*/
-
-:disabled {
- cursor: default;
-}
-
-/*
-1. Make replaced elements \`display: block\` by default. (https://github.com/mozdevs/cssremedy/issues/14)
-2. Add \`vertical-align: middle\` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
- This can trigger a poorly considered lint error in some tools but is included by design.
-*/
-
-img,
-svg,
-video,
-canvas,
-audio,
-iframe,
-embed,
-object {
- display: block;
- /* 1 */
- vertical-align: middle;
- /* 2 */
-}
-
-/*
-Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
-*/
-
-img,
-video {
- max-width: 100%;
- height: auto;
-}
-
-/* Make elements with the HTML hidden attribute stay hidden by default */
-
-[hidden]:where(:not([hidden="until-found"])) {
- display: none;
-}
-
-:root {
- --background: 0 0% 100%;
- --foreground: 222.2 47.4% 11.2%;
- --muted: 210 40% 96.1%;
- --muted-foreground: 215.4 16.3% 46.9%;
- --popover: 0 0% 100%;
- --popover-foreground: 222.2 47.4% 11.2%;
- --border: 214.3 31.8% 91.4%;
- --input: 214.3 31.8% 91.4%;
- --card: 0 0% 100%;
- --card-foreground: 222.2 47.4% 11.2%;
- --primary: 222.2 47.4% 11.2%;
- --primary-foreground: 210 40% 98%;
- --secondary: 210 40% 96.1%;
- --secondary-foreground: 222.2 47.4% 11.2%;
- --accent: 210 40% 96.1%;
- --accent-foreground: 222.2 47.4% 11.2%;
- --destructive: 0 100% 50%;
- --destructive-foreground: 210 40% 98%;
- --ring: 215 20.2% 65.1%;
- --radius: 0.5rem;
-}
-
-* {
- border-color: hsl(var(--border));
-}
-
-body {
- background-color: hsl(var(--background));
- font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
- color: hsl(var(--foreground));
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-.container {
- width: 100%;
-}
-
-@media (min-width: 640px) {
- .container {
- max-width: 640px;
- }
-}
-
-@media (min-width: 768px) {
- .container {
- max-width: 768px;
- }
-}
-
-@media (min-width: 1024px) {
- .container {
- max-width: 1024px;
- }
-}
-
-@media (min-width: 1280px) {
- .container {
- max-width: 1280px;
- }
-}
-
-@media (min-width: 1536px) {
- .container {
- max-width: 1536px;
- }
-}
-
-.sr-only {
- position: absolute;
- width: 1px;
- height: 1px;
- padding: 0;
- margin: -1px;
- overflow: hidden;
- clip: rect(0, 0, 0, 0);
- white-space: nowrap;
- border-width: 0;
-}
-
-.visible {
- visibility: visible;
-}
-
-.fixed {
- position: fixed;
-}
-
-.absolute {
- position: absolute;
-}
-
-.relative {
- position: relative;
-}
-
-.inset-0 {
- inset: 0px;
-}
-
-.left-0 {
- left: 0px;
-}
-
-.left-\[50\%\] {
- left: 50%;
-}
-
-.right-0 {
- right: 0px;
-}
-
-.right-4 {
- right: 1rem;
-}
-
-.top-4 {
- top: 1rem;
-}
-
-.top-\[50\%\] {
- top: 50%;
-}
-
-.top-full {
- top: 100%;
-}
-
-.z-50 {
- z-index: 50;
-}
-
-.-mx-1 {
- margin-left: -0.25rem;
- margin-right: -0.25rem;
-}
-
-.ml-auto {
- margin-left: auto;
-}
-
-.mr-2 {
- margin-right: 0.5rem;
-}
-
-.mt-1 {
- margin-top: 0.25rem;
-}
-
-.flex {
- display: flex;
-}
-
-.inline-flex {
- display: inline-flex;
-}
-
-.grid {
- display: grid;
-}
-
-.hidden {
- display: none;
-}
-
-.h-1 {
- height: 0.25rem;
-}
-
-.h-1\.5 {
- height: 0.375rem;
-}
-
-.h-10 {
- height: 2.5rem;
-}
-
-.h-2\.5 {
- height: 0.625rem;
-}
-
-.h-3 {
- height: 0.75rem;
-}
-
-.h-4 {
- height: 1rem;
-}
-
-.h-5 {
- height: 1.25rem;
-}
-
-.h-8 {
- height: 2rem;
-}
-
-.h-9 {
- height: 2.25rem;
-}
-
-.h-full {
- height: 100%;
-}
-
-.h-px {
- height: 1px;
-}
-
-.max-h-\[240px\] {
- max-height: 240px;
-}
-
-.max-h-\[300px\] {
- max-height: 300px;
-}
-
-.w-1\.5 {
- width: 0.375rem;
-}
-
-.w-2\.5 {
- width: 0.625rem;
-}
-
-.w-3 {
- width: 0.75rem;
-}
-
-.w-4 {
- width: 1rem;
-}
-
-.w-5 {
- width: 1.25rem;
-}
-
-.w-72 {
- width: 18rem;
-}
-
-.w-9 {
- width: 2.25rem;
-}
-
-.w-full {
- width: 100%;
-}
-
-.max-w-\[200px\] {
- max-width: 200px;
-}
-
-.max-w-lg {
- max-width: 32rem;
-}
-
-.flex-1 {
- flex: 1 1 0%;
-}
-
-.flex-shrink-0 {
- flex-shrink: 0;
-}
-
-.shrink-0 {
- flex-shrink: 0;
-}
-
-.translate-x-\[-50\%\] {
- --tw-translate-x: -50%;
- transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
-}
-
-.translate-y-\[-50\%\] {
- --tw-translate-y: -50%;
- transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
-}
-
-.rotate-180 {
- --tw-rotate: 180deg;
- transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
-}
-
-.transform {
- transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
-}
-
-@keyframes pulse {
- 50% {
- opacity: .5;
- }
-}
-
-.animate-pulse {
- animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
-}
-
-.cursor-default {
- cursor: default;
-}
-
-.select-none {
- -webkit-user-select: none;
- -moz-user-select: none;
- user-select: none;
-}
-
-.flex-col {
- flex-direction: column;
-}
-
-.flex-col-reverse {
- flex-direction: column-reverse;
-}
-
-.flex-wrap {
- flex-wrap: wrap;
-}
-
-.items-center {
- align-items: center;
-}
-
-.justify-center {
- justify-content: center;
-}
-
-.justify-between {
- justify-content: space-between;
-}
-
-.gap-0\.5 {
- gap: 0.125rem;
-}
-
-.gap-1 {
- gap: 0.25rem;
-}
-
-.gap-1\.5 {
- gap: 0.375rem;
-}
-
-.gap-2 {
- gap: 0.5rem;
-}
-
-.gap-3 {
- gap: 0.75rem;
-}
-
-.gap-4 {
- gap: 1rem;
-}
-
-.space-y-1\.5 > :not([hidden]) ~ :not([hidden]) {
- --tw-space-y-reverse: 0;
- margin-top: calc(0.375rem * calc(1 - var(--tw-space-y-reverse)));
- margin-bottom: calc(0.375rem * var(--tw-space-y-reverse));
-}
-
-.space-y-2 > :not([hidden]) ~ :not([hidden]) {
- --tw-space-y-reverse: 0;
- margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
- margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
-}
-
-.space-y-4 > :not([hidden]) ~ :not([hidden]) {
- --tw-space-y-reverse: 0;
- margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
- margin-bottom: calc(1rem * var(--tw-space-y-reverse));
-}
-
-.overflow-hidden {
- overflow: hidden;
-}
-
-.overflow-y-auto {
- overflow-y: auto;
-}
-
-.overflow-x-hidden {
- overflow-x: hidden;
-}
-
-.truncate {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.whitespace-nowrap {
- white-space: nowrap;
-}
-
-.rounded {
- border-radius: 0.25rem;
-}
-
-.rounded-full {
- border-radius: 9999px;
-}
-
-.rounded-lg {
- border-radius: var(--radius);
-}
-
-.rounded-md {
- border-radius: calc(var(--radius) - 2px);
-}
-
-.rounded-sm {
- border-radius: calc(var(--radius) - 4px);
-}
-
-.rounded-xl {
- border-radius: 0.75rem;
-}
-
-.border {
- border-width: 1px;
-}
-
-.border-b {
- border-bottom-width: 1px;
-}
-
-.border-blue-500 {
- --tw-border-opacity: 1;
- border-color: rgb(59 130 246 / var(--tw-border-opacity, 1));
-}
-
-.border-input {
- border-color: hsl(var(--input));
-}
-
-.border-transparent {
- border-color: transparent;
-}
-
-.border-white\/20 {
- border-color: rgb(255 255 255 / 0.2);
-}
-
-.border-white\/50 {
- border-color: rgb(255 255 255 / 0.5);
-}
-
-.bg-background {
- background-color: hsl(var(--background));
-}
-
-.bg-black\/80 {
- background-color: rgb(0 0 0 / 0.8);
-}
-
-.bg-blue-400 {
- --tw-bg-opacity: 1;
- background-color: rgb(96 165 250 / var(--tw-bg-opacity, 1));
-}
-
-.bg-blue-500 {
- --tw-bg-opacity: 1;
- background-color: rgb(59 130 246 / var(--tw-bg-opacity, 1));
-}
-
-.bg-border {
- background-color: hsl(var(--border));
-}
-
-.bg-destructive {
- background-color: hsl(var(--destructive));
-}
-
-.bg-gray-400 {
- --tw-bg-opacity: 1;
- background-color: rgb(156 163 175 / var(--tw-bg-opacity, 1));
-}
-
-.bg-gray-800 {
- --tw-bg-opacity: 1;
- background-color: rgb(31 41 55 / var(--tw-bg-opacity, 1));
-}
-
-.bg-gray-900 {
- --tw-bg-opacity: 1;
- background-color: rgb(17 24 39 / var(--tw-bg-opacity, 1));
-}
-
-.bg-popover {
- background-color: hsl(var(--popover));
-}
-
-.bg-primary {
- background-color: hsl(var(--primary));
-}
-
-.bg-secondary {
- background-color: hsl(var(--secondary));
-}
-
-.bg-transparent {
- background-color: transparent;
-}
-
-.bg-white\/10 {
- background-color: rgb(255 255 255 / 0.1);
-}
-
-.bg-white\/20 {
- background-color: rgb(255 255 255 / 0.2);
-}
-
-.bg-gradient-to-br {
- background-image: linear-gradient(to bottom right, var(--tw-gradient-stops));
-}
-
-.from-gray-800 {
- --tw-gradient-from: #1f2937 var(--tw-gradient-from-position);
- --tw-gradient-to: rgb(31 41 55 / 0) var(--tw-gradient-to-position);
- --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
-}
-
-.to-gray-900 {
- --tw-gradient-to: #111827 var(--tw-gradient-to-position);
-}
-
-.p-0 {
- padding: 0px;
-}
-
-.p-1 {
- padding: 0.25rem;
-}
-
-.p-4 {
- padding: 1rem;
-}
-
-.p-6 {
- padding: 1.5rem;
-}
-
-.px-2 {
- padding-left: 0.5rem;
- padding-right: 0.5rem;
-}
-
-.px-2\.5 {
- padding-left: 0.625rem;
- padding-right: 0.625rem;
-}
-
-.px-3 {
- padding-left: 0.75rem;
- padding-right: 0.75rem;
-}
-
-.px-4 {
- padding-left: 1rem;
- padding-right: 1rem;
-}
-
-.px-8 {
- padding-left: 2rem;
- padding-right: 2rem;
-}
-
-.py-0\.5 {
- padding-top: 0.125rem;
- padding-bottom: 0.125rem;
-}
-
-.py-1 {
- padding-top: 0.25rem;
- padding-bottom: 0.25rem;
-}
-
-.py-1\.5 {
- padding-top: 0.375rem;
- padding-bottom: 0.375rem;
-}
-
-.py-2 {
- padding-top: 0.5rem;
- padding-bottom: 0.5rem;
-}
-
-.py-3 {
- padding-top: 0.75rem;
- padding-bottom: 0.75rem;
-}
-
-.py-6 {
- padding-top: 1.5rem;
- padding-bottom: 1.5rem;
-}
-
-.text-left {
- text-align: left;
-}
-
-.text-center {
- text-align: center;
-}
-
-.text-lg {
- font-size: 1.125rem;
- line-height: 1.75rem;
-}
-
-.text-sm {
- font-size: 0.875rem;
- line-height: 1.25rem;
-}
-
-.text-xs {
- font-size: 0.75rem;
- line-height: 1rem;
-}
-
-.font-medium {
- font-weight: 500;
-}
-
-.font-semibold {
- font-weight: 600;
-}
-
-.leading-none {
- line-height: 1;
-}
-
-.tracking-tight {
- letter-spacing: -0.025em;
-}
-
-.tracking-widest {
- letter-spacing: 0.1em;
-}
-
-.text-blue-100 {
- --tw-text-opacity: 1;
- color: rgb(219 234 254 / var(--tw-text-opacity, 1));
-}
-
-.text-destructive-foreground {
- color: hsl(var(--destructive-foreground));
-}
-
-.text-foreground {
- color: hsl(var(--foreground));
-}
-
-.text-gray-100 {
- --tw-text-opacity: 1;
- color: rgb(243 244 246 / var(--tw-text-opacity, 1));
-}
-
-.text-gray-200 {
- --tw-text-opacity: 1;
- color: rgb(229 231 235 / var(--tw-text-opacity, 1));
-}
-
-.text-muted-foreground {
- color: hsl(var(--muted-foreground));
-}
-
-.text-popover-foreground {
- color: hsl(var(--popover-foreground));
-}
-
-.text-primary {
- color: hsl(var(--primary));
-}
-
-.text-primary-foreground {
- color: hsl(var(--primary-foreground));
-}
-
-.text-secondary-foreground {
- color: hsl(var(--secondary-foreground));
-}
-
-.text-white {
- --tw-text-opacity: 1;
- color: rgb(255 255 255 / var(--tw-text-opacity, 1));
-}
-
-.text-white\/70 {
- color: rgb(255 255 255 / 0.7);
-}
-
-.text-white\/90 {
- color: rgb(255 255 255 / 0.9);
-}
-
-.underline-offset-4 {
- text-underline-offset: 4px;
-}
-
-.placeholder-white\/50::-moz-placeholder {
- color: rgb(255 255 255 / 0.5);
-}
-
-.placeholder-white\/50::placeholder {
- color: rgb(255 255 255 / 0.5);
-}
-
-.opacity-50 {
- opacity: 0.5;
-}
-
-.opacity-60 {
- opacity: 0.6;
-}
-
-.opacity-70 {
- opacity: 0.7;
-}
-
-.shadow {
- --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
- --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
- box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
-}
-
-.shadow-lg {
- --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
- --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
- box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
-}
-
-.shadow-md {
- --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
- --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
- box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
-}
-
-.shadow-sm {
- --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
- --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
- box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
-}
-
-.outline-none {
- outline: 2px solid transparent;
- outline-offset: 2px;
-}
-
-.outline {
- outline-style: solid;
-}
-
-.ring-offset-background {
- --tw-ring-offset-color: hsl(var(--background));
-}
-
-.filter {
- filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
-}
-
-.transition-all {
- transition-property: all;
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
- transition-duration: 150ms;
-}
-
-.transition-colors {
- transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
- transition-duration: 150ms;
-}
-
-.transition-opacity {
- transition-property: opacity;
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
- transition-duration: 150ms;
-}
-
-.transition-transform {
- transition-property: transform;
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
- transition-duration: 150ms;
-}
-
-.duration-150 {
- transition-duration: 150ms;
-}
-
-.duration-200 {
- transition-duration: 200ms;
-}
-
-.placeholder\:text-muted-foreground::-moz-placeholder {
- color: hsl(var(--muted-foreground));
-}
-
-.placeholder\:text-muted-foreground::placeholder {
- color: hsl(var(--muted-foreground));
-}
-
-.hover\:bg-accent:hover {
- background-color: hsl(var(--accent));
-}
-
-.hover\:bg-destructive\/80:hover {
- background-color: hsl(var(--destructive) / 0.8);
-}
-
-.hover\:bg-destructive\/90:hover {
- background-color: hsl(var(--destructive) / 0.9);
-}
-
-.hover\:bg-gray-800:hover {
- --tw-bg-opacity: 1;
- background-color: rgb(31 41 55 / var(--tw-bg-opacity, 1));
-}
-
-.hover\:bg-primary\/80:hover {
- background-color: hsl(var(--primary) / 0.8);
-}
-
-.hover\:bg-primary\/90:hover {
- background-color: hsl(var(--primary) / 0.9);
-}
-
-.hover\:bg-secondary\/80:hover {
- background-color: hsl(var(--secondary) / 0.8);
-}
-
-.hover\:bg-white\/20:hover {
- background-color: rgb(255 255 255 / 0.2);
-}
-
-.hover\:text-accent-foreground:hover {
- color: hsl(var(--accent-foreground));
-}
-
-.hover\:text-white:hover {
- --tw-text-opacity: 1;
- color: rgb(255 255 255 / var(--tw-text-opacity, 1));
-}
-
-.hover\:underline:hover {
- text-decoration-line: underline;
-}
-
-.hover\:opacity-100:hover {
- opacity: 1;
-}
-
-.focus\:border-blue-500:focus {
- --tw-border-opacity: 1;
- border-color: rgb(59 130 246 / var(--tw-border-opacity, 1));
-}
-
-.focus\:outline-none:focus {
- outline: 2px solid transparent;
- outline-offset: 2px;
-}
-
-.focus\:ring-2:focus {
- --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
- --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
- box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
-}
-
-.focus\:ring-ring:focus {
- --tw-ring-color: hsl(var(--ring));
-}
-
-.focus\:ring-offset-2:focus {
- --tw-ring-offset-width: 2px;
-}
-
-.focus-visible\:outline-none:focus-visible {
- outline: 2px solid transparent;
- outline-offset: 2px;
-}
-
-.focus-visible\:ring-1:focus-visible {
- --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
- --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
- box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
-}
-
-.focus-visible\:ring-ring:focus-visible {
- --tw-ring-color: hsl(var(--ring));
-}
-
-.disabled\:pointer-events-none:disabled {
- pointer-events: none;
-}
-
-.disabled\:cursor-not-allowed:disabled {
- cursor: not-allowed;
-}
-
-.disabled\:opacity-50:disabled {
- opacity: 0.5;
-}
-
-.data-\[disabled\=true\]\:pointer-events-none[data-disabled="true"] {
- pointer-events: none;
-}
-
-.data-\[selected\=true\]\:bg-accent[data-selected="true"] {
- background-color: hsl(var(--accent));
-}
-
-.data-\[state\=open\]\:bg-accent[data-state="open"] {
- background-color: hsl(var(--accent));
-}
-
-.data-\[selected\=true\]\:text-accent-foreground[data-selected="true"] {
- color: hsl(var(--accent-foreground));
-}
-
-.data-\[state\=open\]\:text-muted-foreground[data-state="open"] {
- color: hsl(var(--muted-foreground));
-}
-
-.data-\[disabled\=true\]\:opacity-50[data-disabled="true"] {
- opacity: 0.5;
-}
-
-@media (min-width: 640px) {
- .sm\:flex-row {
- flex-direction: row;
- }
-
- .sm\:justify-end {
- justify-content: flex-end;
- }
-
- .sm\:space-x-2 > :not([hidden]) ~ :not([hidden]) {
- --tw-space-x-reverse: 0;
- margin-right: calc(0.5rem * var(--tw-space-x-reverse));
- margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
- }
-
- .sm\:rounded-lg {
- border-radius: var(--radius);
- }
-
- .sm\:text-left {
- text-align: left;
- }
-}
-
-.\[\&_\[cmdk-group-heading\]\]\:px-2 [cmdk-group-heading] {
- padding-left: 0.5rem;
- padding-right: 0.5rem;
-}
-
-.\[\&_\[cmdk-group-heading\]\]\:py-1\.5 [cmdk-group-heading] {
- padding-top: 0.375rem;
- padding-bottom: 0.375rem;
-}
-
-.\[\&_\[cmdk-group-heading\]\]\:text-xs [cmdk-group-heading] {
- font-size: 0.75rem;
- line-height: 1rem;
-}
-
-.\[\&_\[cmdk-group-heading\]\]\:font-medium [cmdk-group-heading] {
- font-weight: 500;
-}
-
-.\[\&_\[cmdk-group-heading\]\]\:text-muted-foreground [cmdk-group-heading] {
- color: hsl(var(--muted-foreground));
-}
-
-.\[\&_\[cmdk-group\]\:not\(\[hidden\]\)_\~\[cmdk-group\]\]\:pt-0 [cmdk-group]:not([hidden]) ~[cmdk-group] {
- padding-top: 0px;
-}
-
-.\[\&_\[cmdk-group\]\]\:px-2 [cmdk-group] {
- padding-left: 0.5rem;
- padding-right: 0.5rem;
-}
-
-.\[\&_\[cmdk-input-wrapper\]_svg\]\:h-5 [cmdk-input-wrapper] svg {
- height: 1.25rem;
-}
-
-.\[\&_\[cmdk-input-wrapper\]_svg\]\:w-5 [cmdk-input-wrapper] svg {
- width: 1.25rem;
-}
-
-.\[\&_\[cmdk-input\]\]\:h-12 [cmdk-input] {
- height: 3rem;
-}
-
-.\[\&_\[cmdk-item\]\]\:px-2 [cmdk-item] {
- padding-left: 0.5rem;
- padding-right: 0.5rem;
-}
-
-.\[\&_\[cmdk-item\]\]\:py-3 [cmdk-item] {
- padding-top: 0.75rem;
- padding-bottom: 0.75rem;
-}
-
-.\[\&_\[cmdk-item\]_svg\]\:h-5 [cmdk-item] svg {
- height: 1.25rem;
-}
-
-.\[\&_\[cmdk-item\]_svg\]\:w-5 [cmdk-item] svg {
- width: 1.25rem;
-}
-
-.\[\&_svg\]\:pointer-events-none svg {
- pointer-events: none;
-}
-
-.\[\&_svg\]\:size-4 svg {
- width: 1rem;
- height: 1rem;
-}
-
-.\[\&_svg\]\:shrink-0 svg {
- flex-shrink: 0;
-}
-`
\ No newline at end of file
diff --git a/apps/extension/src/background.ts b/apps/extension/src/background.ts
deleted file mode 100644
index b02d027f..00000000
--- a/apps/extension/src/background.ts
+++ /dev/null
@@ -1,225 +0,0 @@
-import { getBaseURL } from "@/lib/utils";
-import {
- messageListener,
- MessageType,
- registerMessageHandler,
-} from "./helpers";
-import { handleExportXBookmarks, setupTwitterHeaderListener } from "./twitter";
-
-type TabState = {
- isActive: boolean;
-};
-
-const tabStates = new Map();
-
-const checkIfLoggedIn = async () => {
- const baseURL = await getBaseURL();
- const response = await fetch(`${baseURL}/backend/v1/session`);
-
- return response.status == 200;
-};
-
-// When extension is installed
-chrome.runtime.onInstalled.addListener(async (details) => {
- const isLoggedIn = await checkIfLoggedIn();
-
- const baseURL = await getBaseURL();
- if (!isLoggedIn) {
- chrome.tabs.create({ url: `${baseURL}/signin` });
- }
-
- // TODO: show extension help page
-});
-
-// Clean up tab state when tab is closed
-chrome.tabs.onRemoved.addListener((tabId) => {
- tabStates.delete(tabId);
-});
-
-// communication with content script
-chrome.action.onClicked.addListener(async (tab) => {
- if (!tab.id) return;
-
- try {
- // Check if we can inject into this tab
- if (
- !tab.url ||
- tab.url.startsWith("chrome://") ||
- tab.url.startsWith("edge://") ||
- tab.url.startsWith("about:")
- ) {
- alert("Cannot modify Chrome system pages");
- return;
- }
-
- const baseURL = await getBaseURL();
-
- const isLoggedIn = await checkIfLoggedIn();
- if (!isLoggedIn) {
- chrome.tabs.create({ url: `${baseURL}/signin` });
- return;
- }
-
- const currentState = tabStates.get(tab.id) || { isActive: false };
- const newState = { isActive: !currentState.isActive };
-
- chrome.scripting.executeScript({
- target: { tabId: tab.id },
- files: ["scripts/content.js"],
- });
-
- // Update state
- tabStates.set(tab.id, newState);
-
- // Update icon title
- await chrome.action.setTitle({
- tabId: tab.id,
- title: newState.isActive ? "Disable SuperMemory" : "Enable SuperMemory",
- });
- } catch (error) {
- console.error("Failed to toggle content:", error);
- }
-});
-
-chrome.runtime.onMessage.addListener(messageListener);
-
-registerMessageHandler(
- "GET_SPACES",
- async (message, sender, sendResponse) => {
- // Handle getting spaces
- const baseURL = await getBaseURL();
- const response = await fetch(`${baseURL}/backend/v1/spaces`);
- const data = await response.json();
- sendResponse(data);
- }
-);
-
-registerMessageHandler(
- "EXPORT_TWITTER_BOOKMARKS",
- async (message, sender, sendResponse) => {
- handleExportXBookmarks();
- sendResponse({ status: "started" });
- }
-);
-
-registerMessageHandler(
- "SAVE_PAGE",
- async (message, sender, sendResponse) => {
- if (!message.payload) {
- sendResponse({ error: "No payload" });
- return;
- }
-
- const baseURL = await getBaseURL();
-
- const isLoggedIn = await checkIfLoggedIn();
- if (!isLoggedIn) {
- sendResponse({ error: "Not logged in" });
- chrome.tabs.create({ url: `${baseURL}/signin` });
- return;
- }
-
- console.log(message.payload);
-
- const response = await fetch(`${baseURL}/backend/v1/add`, {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({
- spaces: message.payload.spaces || [],
- content: message.payload.url,
- prefetched: message.payload.prefetched,
- }),
- });
- if (response.status !== 200) {
- sendResponse({ error: "Failed to save page", status: response.status });
- return;
- }
- const data = await response.json();
- // Handle saving highlight
- sendResponse({ success: true, data, status: response.status });
- }
-);
-
-registerMessageHandler(
- "ACTIVATE_CONTENT",
- async (message, sender, sendResponse) => {
- console.log("Activating content");
- chrome.tabs.query({ active: true, currentWindow: true }, async (tabs) => {
- const currentTab = tabs[0];
- if (currentTab.id) {
- try {
- await chrome.scripting.executeScript({
- target: { tabId: currentTab.id },
- files: ["scripts/content.js"],
- });
-
- } catch (error) {
- console.error("Error injecting content script:", error);
- }
- }
- });
- sendResponse({ success: true });
- }
-);
-
-registerMessageHandler(
- "SYNC_CHROME_BOOKMARKS",
- async (message, sender, sendResponse) => {
- // activate the chrome bookmarks syncing.
-
- // TODO: We probably want to sync bookmarks from the extension to the web app.
- chrome.bookmarks.onCreated.addListener((id, bookmark) => {
- console.log("Bookmark created:", bookmark);
- });
- }
-);
-
-registerMessageHandler(
- "IMPORT_CHROME_BOOKMARKS",
- async (message, sender, sendResponse) => {
- // activate the chrome bookmarks importing.
- // first get all chrome bookmarks
- chrome.bookmarks.getRecent(100, (bookmarks) => {
- console.log("Bookmarks:", bookmarks);
- });
- }
-);
-
-// External message listener
-chrome.runtime.onMessageExternal.addListener(
- async (request, sender, sendResponse) => {
- if (request.action === "exportBookmarks") {
- handleExportXBookmarks();
- sendResponse({ status: "exported" });
- return true;
- }
- if (request.action === "importBookmarks") {
- const baseURL = await getBaseURL();
- chrome.bookmarks.getRecent(100, async (bookmarks) => {
- for (const { url } of bookmarks) {
- console.log("Importing bookmark:", url);
- const r = await fetch(`${baseURL}/backend/v1/add`, {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({ content: url, spaces: [] }),
- });
-
- const response = await r.json();
- console.log("Response:", response);
- }
- sendResponse({ status: "imported", bookmarks });
- });
- return true;
- }
- if (request.action === "ping") {
- sendResponse({ status: "pong" });
- return true;
- }
- }
-);
-
-setupTwitterHeaderListener();
diff --git a/apps/extension/src/content.tsx b/apps/extension/src/content.tsx
deleted file mode 100644
index 6848bf37..00000000
--- a/apps/extension/src/content.tsx
+++ /dev/null
@@ -1,350 +0,0 @@
-import { useEffect, useState, useRef } from "react";
-import { Readability } from "@mozilla/readability";
-
-const DEBUG = true;
-
-const log = (message: string, ...args: any[]) => {
- if (DEBUG) {
- console.log("[content]", message, ...args);
- }
-};
-
-export default function SupermemoryContent({
- onClose: originalOnClose,
-}: {
- onClose: () => void;
-}) {
- const [progress, setProgress] = useState(0);
- const [showSaving, setShowSaving] = useState(true);
- const abortControllerRef = useRef(new AbortController());
- const [toastMessage, setToastMessage] = useState<{
- success: boolean;
- message: string;
- } | null>(null);
- const isAbortedRef = useRef(false);
- const [isImportingBookmarks, setIsImportingBookmarks] = useState(false);
- const [importProgress, setImportProgress] = useState(0);
- const [closeTimer, setCloseTimer] = useState(0);
- const closeTimerRef = useRef>();
- const [importStatus, setImportStatus] = useState<{
- status: number;
- message: string;
- } | null>(null);
- const [importComplete, setImportComplete] = useState(false);
-
- useEffect(() => {
- const isTwitter = window.location.hostname.match(/^(twitter\.com|x\.com)$/);
- if (isTwitter) {
- chrome.storage.local.get(["attemptingImportCurrently"], (result) => {
- if (result.attemptingImportCurrently) {
- setIsImportingBookmarks(true);
- setShowSaving(true);
- }
- });
- }
- }, []);
-
- useEffect(() => {
- const messageHandler = (
- message: any,
- sender: chrome.runtime.MessageSender,
- sendResponse: (response?: any) => void
- ) => {
- if (message.type === "IMPORT_PROGRESS_UPDATE") {
- setImportProgress(message.payload.progress);
- setShowSaving(true);
-
- switch (message.payload.status) {
- case 429:
- setImportStatus({
- status: 429,
- message: "Rate limited by Twitter. Waiting to retry...",
- });
- break;
- case 409:
- setImportStatus({
- status: 409,
- message: "Some tweets were already saved",
- });
- break;
- case 500:
- setImportStatus({
- status: 500,
- message: "Error importing some tweets",
- });
- break;
- case 102:
- setImportStatus({
- status: 102,
- message: "Processing tweets...",
- });
- break;
- default:
- setImportStatus(null);
- }
- } else if (message.type === "IMPORT_COMPLETE") {
- console.log("IMPORT_COMPLETE called");
- setImportComplete(true);
- setImportStatus(null);
- setToastMessage({
- success: true,
- message: "Bookmarks imported successfully",
- });
-
- // Send message to all supermemory.ai tabs
- chrome.tabs.query({ url: "*://*.supermemory.ai/*" }, (tabs) => {
- tabs.forEach((tab) => {
- if (tab.id) {
- chrome.tabs.sendMessage(tab.id, {
- type: "TWITTER_IMPORT_COMPLETE",
- });
- }
- });
- });
-
- // Start close timer after 2 seconds of showing success
- setTimeout(() => {
- if (!isImportingBookmarks) {
- startCloseTimer();
- }
- }, 1000);
- }
- };
-
- chrome.runtime.onMessage.addListener(messageHandler);
- return () => chrome.runtime.onMessage.removeListener(messageHandler);
- }, [isImportingBookmarks]);
-
- // Clear toast message after delay
- useEffect(() => {
- if (toastMessage && !importComplete) {
- const timer = setTimeout(() => {
- if (!isAbortedRef.current) {
- setToastMessage(null);
- }
- }, 3000); // Show toast for 3 seconds
- return () => clearTimeout(timer);
- }
- }, [toastMessage, importComplete]);
-
- const startCloseTimer = () => {
- if (closeTimerRef.current) {
- clearInterval(closeTimerRef.current);
- }
- setCloseTimer(0);
-
- let count = 0;
- closeTimerRef.current = setInterval(() => {
- if (!isAbortedRef.current) {
- count += 10;
- setCloseTimer(count);
-
- if (count >= 100) {
- if (closeTimerRef.current) {
- clearInterval(closeTimerRef.current);
- }
- handleClose();
- }
- }
- }, 200); // 20 steps of 10% over 2 seconds
- };
-
- const pauseCloseTimer = () => {
- if (closeTimerRef.current) {
- clearInterval(closeTimerRef.current);
- }
- };
-
- const savePage = async () => {
- if (isAbortedRef.current) return;
-
- const documentClone = document.cloneNode(true) as Document;
- const mainContent = new Readability(documentClone).parse();
-
- try {
- const response = await chrome.runtime.sendMessage({
- type: "SAVE_PAGE",
- payload: {
- description: mainContent?.excerpt,
- url: window.location.href,
- prefetched: {
- contentToVectorize: mainContent?.textContent,
- contentToSave: mainContent?.content,
- title: mainContent?.title,
- type: "page",
- },
- },
- });
-
- if (!isAbortedRef.current) {
- if (response.success) {
- setToastMessage({
- success: true,
- message: "Page saved successfully",
- });
- // Wait for toast to show before starting close timer
- setTimeout(() => {
- if (!isAbortedRef.current) {
- startCloseTimer();
- }
- }, 1000);
- } else {
- setToastMessage({
- success: false,
- message:
- response.status === 409
- ? "Content already exists"
- : "Failed to save page",
- });
- }
- }
-
- return response;
- } catch (error) {
- console.error("Error saving page:", error);
- setToastMessage({ success: false, message: "Failed to save page" });
- }
- };
-
- const handleClose = () => {
- isAbortedRef.current = true;
- abortControllerRef.current.abort();
- if (closeTimerRef.current) {
- clearInterval(closeTimerRef.current);
- }
- setProgress(0);
- setShowSaving(false);
- originalOnClose();
- };
-
- useEffect(() => {
- if (!showSaving || isImportingBookmarks) return;
- savePage();
- }, [showSaving]);
-
- if (!showSaving) return null;
-
- return (
- <>
-
-
-
-
-
-
- {isImportingBookmarks
- ? importComplete
- ? "Twitter Bookmarks Imported!"
- : "Importing Twitter Bookmarks"
- : "Saved to Supermemory"}
-
- {toastMessage && (
-
- {toastMessage.message}
-
- )}
- {importStatus && (
-
- {importStatus.message}
-
- )}
- {isImportingBookmarks && !importComplete && (
-
-
-
- {importProgress}
-
-
- tweets processed
-
-
- )}
- {importComplete && (
-
- Successfully imported {importProgress} tweets
-
- )}
-
-
- {importComplete ? (
-
-
-
- ) : (
-
-
-
-
- )}
- {importComplete
- ? "Done"
- : isImportingBookmarks
- ? "Close"
- : "Cancel"}
-
-
-
-
- {!isImportingBookmarks && (progress > 0 || closeTimer > 0) && (
-
- )}
-
- >
- );
-}
diff --git a/apps/extension/src/helpers.ts b/apps/extension/src/helpers.ts
deleted file mode 100644
index 96cab7e0..00000000
--- a/apps/extension/src/helpers.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-// Define message types
-export type MessageType =
- | {
- type: "SAVE_PAGE";
- payload: {
- html: string;
- url: string;
- spaces: string[];
- description: string;
- prefetched: {
- contentToVectorize: string;
- contentToSave: string;
- title: string;
- type: string;
- };
- };
- }
- | { type: "GET_SPACES"; payload: undefined }
- | { type: "EXPORT_TWITTER_BOOKMARKS"; payload: undefined }
- | { type: "ACTIVATE_CONTENT"; payload: undefined }
- | { type: "SYNC_CHROME_BOOKMARKS"; payload: undefined }
- | { type: "IMPORT_CHROME_BOOKMARKS"; payload: undefined };
-
-// Add more message types as needed
-
-// Type for message handlers
-export type MessageHandler = (
- message: T,
- sender: chrome.runtime.MessageSender,
- sendResponse: (response?: any) => void
-) => void | Promise;
-
-// Message handlers registry
-export const messageHandlers = new Map<
- MessageType["type"],
- MessageHandler
->();
-
-// Register message handlers
-export function registerMessageHandler(
- type: T["type"],
- handler: MessageHandler
-) {
- messageHandlers.set(type, handler as MessageHandler);
-}
-// Main message listener
-export const messageListener = (
- message: MessageType,
- sender: chrome.runtime.MessageSender,
- sendResponse: (response?: any) => void
-) => {
- const handler = messageHandlers.get(message.type);
- if (handler) {
- const result = handler(message, sender, sendResponse);
- if (result instanceof Promise) {
- result.catch(console.error);
- return true; // Keep message channel open for async response
- }
- } else {
- console.warn(`No handler registered for message type: ${message.type}`);
- }
- return false;
-};
-
-chrome.runtime.onMessage.addListener(messageListener);
diff --git a/apps/extension/src/twitter.constants.ts b/apps/extension/src/twitter.constants.ts
deleted file mode 100644
index 543337f7..00000000
--- a/apps/extension/src/twitter.constants.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-export const features = {
- graphql_timeline_v2_bookmark_timeline: true,
- rweb_tipjar_consumption_enabled: true,
- responsive_web_graphql_exclude_directive_enabled: true,
- verified_phone_label_enabled: false,
- creator_subscriptions_tweet_preview_api_enabled: true,
- responsive_web_graphql_timeline_navigation_enabled: true,
- responsive_web_graphql_skip_user_profile_image_extensions_enabled: false,
- communities_web_enable_tweet_community_results_fetch: true,
- c9s_tweet_anatomy_moderator_badge_enabled: true,
- articles_preview_enabled: true,
- tweetypie_unmention_optimization_enabled: true,
- responsive_web_edit_tweet_api_enabled: true,
- graphql_is_translatable_rweb_tweet_is_translatable_enabled: true,
- view_counts_everywhere_api_enabled: true,
- longform_notetweets_consumption_enabled: true,
- responsive_web_twitter_article_tweet_consumption_enabled: true,
- tweet_awards_web_tipping_enabled: false,
- creator_subscriptions_quote_tweet_preview_enabled: false,
- freedom_of_speech_not_reach_fetch_enabled: true,
- standardized_nudges_misinfo: true,
- tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true,
- rweb_video_timestamps_enabled: true,
- longform_notetweets_rich_text_read_enabled: true,
- longform_notetweets_inline_media_enabled: true,
- responsive_web_enhance_cards_enabled: false,
- profile_label_improvements_pcf_label_in_post_enabled: false,
- premium_content_api_read_enabled: true,
- responsive_web_grok_analyze_button_fetch_trends_enabled: true,
- responsive_web_grok_analyze_post_followups_enabled: true,
- responsive_web_grok_share_attachment_enabled: true,
- };
\ No newline at end of file
diff --git a/apps/extension/src/twitter.ts b/apps/extension/src/twitter.ts
deleted file mode 100644
index 09118973..00000000
--- a/apps/extension/src/twitter.ts
+++ /dev/null
@@ -1,470 +0,0 @@
-import { getBaseURL } from "@/lib/utils";
-import { features } from "./twitter.constants";
-
-const DEBUG = true;
-
-const log = (message: string, ...args: any[]) => {
- if (DEBUG) {
- console.log("[twitter]", message, ...args);
- }
-};
-
-const logError = (message: string, error?: any) => {
- // Always log errors
- console.error(message, error);
-};
-
-export const waitForRequiredData = () => {
- return new Promise((resolve) => {
- const checkData = () => {
- chrome.storage.local.get(
- ["bookmarksApiId", "cookie", "csrf", "auth"],
- (result) => {
- if (
- result.bookmarksApiId &&
- result.cookie &&
- result.csrf &&
- result.auth
- ) {
- log("Got all data needed to fetch bookmarks");
- resolve(true);
- } else {
- setTimeout(checkData, 100); // Check again after 100ms
- }
- }
- );
- };
- checkData();
- });
-};
-
-export const handleExportXBookmarks = async () => {
- log("Received export request from popup");
-
- // First, create the Twitter tab
- const tab = await chrome.tabs.create({
- url: "https://x.com/i/bookmarks/all",
- });
-
- // Wait for the tab to finish loading
- await new Promise((resolve) => {
- const checkTab = () => {
- if (tab.id) {
- chrome.tabs.get(tab.id, (updatedTab) => {
- if (updatedTab.status === "complete") {
- resolve(true);
- } else {
- setTimeout(checkTab, 100);
- }
- });
- }
- };
- checkTab();
- });
-
- void chrome.storage.local.set({ attemptingImportCurrently: true });
-
- chrome.tabs.query({ active: true, currentWindow: true }, async (tabs) => {
- const currentTab = tabs[0];
- if (currentTab.id) {
- try {
- await chrome.scripting.executeScript({
- target: { tabId: currentTab.id },
- files: ["scripts/content.js"],
- });
- } catch (error) {
- console.error("Error injecting content script:", error);
- }
- }
- });
-
- // Wait for required data and start the bookmark export
- await waitForRequiredData();
- await sendProgressUpdate(0, 200);
-
- await getBookmarks();
-
- return { status: 200 };
-};
-
-const getNextCursor = (entries: any[]) => {
- const cursorEntry = entries.find((entry) =>
- entry.entryId.startsWith("cursor-bottom-")
- );
- return cursorEntry ? cursorEntry.content.value : null;
-};
-
-type MessageType = "IMPORT_PROGRESS_UPDATE" | "IMPORT_COMPLETE";
-
-const sendMessageToTwitterTabs = async (
- message: {
- type: MessageType;
- payload: any;
- },
- retries = 3
-) => {
- try {
- log(`Sending message of type ${message.type}:`, message.payload);
-
- const tabs = await chrome.tabs.query({
- url: ["*://*.twitter.com/*", "*://*.x.com/*"],
- });
-
- if (tabs.length === 0) {
- if (retries > 0) {
- // Wait and retry if no matching tab found
- await new Promise((resolve) => setTimeout(resolve, 1000));
- return sendMessageToTwitterTabs(message, retries - 1);
- }
- throw new Error("No Twitter tab found");
- }
-
- const messagePromises = tabs.map((tab) => {
- if (!tab.id) return Promise.resolve();
- return chrome.tabs.sendMessage(tab.id, message).catch((error) => {
- logError(`Failed to send message to tab ${tab.id}:`, error);
- });
- });
-
- await Promise.all(messagePromises);
- log(`Message sent to ${tabs.length} tabs`);
- } catch (error) {
- logError(`Error sending message of type ${message.type}:`, error);
- }
-};
-
-const sendProgressUpdate = (progress: number, status: number) => {
- return sendMessageToTwitterTabs({
- type: "IMPORT_PROGRESS_UPDATE",
- payload: { progress, status },
- });
-};
-
-const sendImportComplete = () => {
- return sendMessageToTwitterTabs({
- type: "IMPORT_COMPLETE",
- payload: { success: true },
- });
-};
-
-const getBookmarks = async (cursor = "", totalImported = 0, allTweets = []) => {
- try {
- const getSessionData = (): Promise<{
- cookie: string;
- csrf: string;
- auth: string;
- bookmarksApiId: string;
- }> => {
- return new Promise((resolve) => {
- const checkData = () => {
- chrome.storage.local.get(
- ["cookie", "csrf", "auth", "bookmarksApiId"],
- (result) => {
- if (
- result.cookie &&
- result.csrf &&
- result.auth &&
- result.bookmarksApiId
- ) {
- resolve({
- cookie: result.cookie,
- csrf: result.csrf,
- auth: result.auth,
- bookmarksApiId: result.bookmarksApiId,
- });
- } else {
- setTimeout(checkData, 3000); // Check again after 3 seconds
- }
- }
- );
- };
- checkData();
- });
- };
-
- const sessionResult = await getSessionData();
- const baseURL = await getBaseURL();
-
- const headers = new Headers();
- headers.append("Cookie", sessionResult.cookie);
- headers.append("X-Csrf-token", sessionResult.csrf);
- headers.append("Authorization", sessionResult.auth);
-
- const variables = {
- count: 100,
- cursor: cursor,
- includePromotedContent: false,
- };
- const API_URL = `https://x.com/i/api/graphql/${
- sessionResult.bookmarksApiId
- }/Bookmarks?features=${encodeURIComponent(
- JSON.stringify(features)
- )}&variables=${encodeURIComponent(JSON.stringify(variables))}` as const;
-
- const response = await fetch(API_URL, {
- method: "GET",
- headers: headers,
- redirect: "follow",
- });
-
- if (response.status === 429) {
- log("Rate limited, waiting 60 seconds before retrying...");
- await sendProgressUpdate(totalImported, 429);
- await new Promise((resolve) => setTimeout(resolve, 60000));
- return getBookmarks(cursor, totalImported, allTweets);
- }
-
- let data = (await response.json()) as any;
-
- // Handle 400 error with missing features
- if (response.status === 400 && data.errors?.[0]?.message) {
- const errorMsg = data.errors[0].message;
- const missingFeatures = errorMsg.match(
- /following features cannot be null: (.*?)$/
- )?.[1];
-
- if (missingFeatures) {
- const featuresList = missingFeatures.split(", ");
- const updatedFeatures = { ...features };
-
- featuresList.forEach((feature: string) => {
- updatedFeatures[feature as keyof typeof updatedFeatures] = true;
- });
-
- // Retry with updated features
- const newUrl = `https://x.com/i/api/graphql/${
- sessionResult.bookmarksApiId
- }/Bookmarks?features=${encodeURIComponent(
- JSON.stringify(updatedFeatures)
- )}&variables=${encodeURIComponent(JSON.stringify(variables))}`;
-
- const retryResponse = await fetch(newUrl, {
- method: "GET",
- headers: headers,
- redirect: "follow",
- });
-
- const retryData = await retryResponse.json();
- data = retryData;
- }
- }
-
- const entries =
- data.data?.bookmark_timeline_v2?.timeline?.instructions?.[0]?.entries ||
- [];
-
- const tweetEntries = entries.filter((entry: { entryId: string }) =>
- entry.entryId.startsWith("tweet-")
- );
-
- // Process tweets and create URLs
- const tweetUrls = tweetEntries
- .map((tweet: any) => {
- const tweetId = tweet?.entryId?.split("-")[1];
- const username =
- tweet?.content?.itemContent?.tweet_results?.result?.core?.user_results
- ?.result?.legacy?.screen_name;
-
- if (!tweetId) return null;
- return `https://x.com/${username || "supermemoryai"}/status/${tweetId}`;
- })
- .filter(Boolean);
-
- // Send progress update before processing batch
- await sendProgressUpdate(totalImported, 102); // 102 = Processing batch
-
- // Send all tweets in parallel
- const addRequests = tweetUrls.map((tweetUrl: string) =>
- fetch(`${baseURL}/backend/v1/add`, {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({
- content: tweetUrl,
- }),
- })
- );
-
- const results = await Promise.all(addRequests);
-
- // Track different response statuses
- const statusCounts = results.reduce((acc: { [key: number]: number }, r) => {
- const status = r.status;
- acc[status] = (acc[status] || 0) + 1;
- return acc;
- }, {});
-
- // Log status counts
- Object.entries(statusCounts).forEach(([status, count]) => {
- log(`Status ${status}: ${count} tweets`);
- });
-
- // If we have any 409s, send that in the progress update
- if (statusCounts[409]) {
- await sendProgressUpdate(totalImported, 409);
- }
-
- // Consider request successful even if some tweets already exist (409)
- const failedRequests = results.filter(
- (r) => !r.ok && r.status !== 409
- ).length;
- if (failedRequests > 0) {
- await sendProgressUpdate(totalImported, 500); // 500 = Some requests failed
- }
-
- allTweets = allTweets.concat(tweetEntries);
- const newTweetsCount = tweetEntries.length;
- totalImported += newTweetsCount;
-
- // Update progress based on total tweets found so far
- const estimatedTotalTweets = Math.max(totalImported, 200); // Adjust estimate as we find more
- await sendProgressUpdate(
- totalImported,
- failedRequests > 0 ? 500 : statusCounts[409] ? 409 : 200
- );
-
- log(
- `Processing batch: ${newTweetsCount} new tweets, total: ${totalImported}`
- );
- const nextCursor = getNextCursor(entries);
-
- if (nextCursor && newTweetsCount > 0) {
- // Add delay between batches to avoid rate limiting
- await new Promise((resolve) => setTimeout(resolve, 1500));
- return getBookmarks(nextCursor, totalImported, allTweets);
- } else {
- // Final success update
- await sendImportComplete();
-
- chrome.storage.local.set({ bookmarks: allTweets }, () => {
- log("Bookmarks stored in local storage");
- });
- const timestamp = new Date().toISOString();
- chrome.storage.local.get(["successful_exports"], (result) => {
- const successful_exports = result.successful_exports || [];
- successful_exports.push({
- timestamp,
- tweetCount: allTweets.length,
- });
- chrome.storage.local.set({ successful_exports }, () => {
- log(`Export completed: ${allTweets.length} tweets`);
- });
- });
- void chrome.storage.local.set({ attemptingImportCurrently: false });
-
- // After successful import completion:
- window.postMessage(
- { type: "TWITTER_IMPORT_COMPLETE" },
- window.location.origin
- );
- }
- } catch (error) {
- logError("Error fetching bookmarks:", error);
- void chrome.storage.local.set({ attemptingImportCurrently: false });
- }
-};
-
-export const setupTwitterHeaderListener = () => {
- chrome.webRequest.onBeforeSendHeaders.addListener(
- (details) => {
- try {
- // Validate input
- if (!details || !details.url) {
- console.error("Invalid details object received");
- return;
- }
-
- // Check if URL is from Twitter/X
- if (
- !(
- details.url.includes("x.com") || details.url.includes("twitter.com")
- )
- ) {
- return;
- }
-
- // Ensure requestHeaders exists
- if (!details.requestHeaders) {
- console.error("No request headers found");
- return;
- }
-
- // Check if stuff is already stored
- chrome.storage.local.get(
- ["bookmarksApiId", "cookie", "csrf", "auth"],
- (result) => {
- try {
- // Check if the URL matches the pattern for bookmarks API
- const bookmarksUrlPattern =
- /https:\/\/x\.com\/i\/api\/graphql\/([^/]+)\/Bookmarks\?/;
- const match = details.url.match(bookmarksUrlPattern);
-
- if (match?.[1] && !result.bookmarksApiId) {
- const bookmarksApiId = match[1];
- chrome.storage.local.set({ bookmarksApiId }, () => {
- if (chrome.runtime.lastError) {
- console.error(
- "Error storing bookmarksApiId:",
- chrome.runtime.lastError
- );
- return;
- }
- console.log(`Stored bookmarksApiId: ${bookmarksApiId}`);
- });
- }
-
- // Extract headers with error handling
- const getHeaderValue = (name: string): string => {
- const header = details.requestHeaders?.find(
- (h) => h.name.toLowerCase() === name.toLowerCase()
- );
- return header?.value || "";
- };
-
- const auth = getHeaderValue("authorization");
- const cookie = getHeaderValue("cookie");
- const csrf = getHeaderValue("x-csrf-token");
-
- // // Validate required headers
- // if (!auth || !cookie || !csrf) {
- // console.warn("Missing required headers", {
- // hasAuth: !!auth,
- // hasCookie: !!cookie,
- // hasCsrf: !!csrf,
- // });
- // return;
- // }
-
- // Only update storage if values have changed
- if (
- result.cookie !== cookie ||
- result.csrf !== csrf ||
- result.auth !== auth
- ) {
- chrome.storage.local.set({ cookie, csrf, auth }, () => {
- if (chrome.runtime.lastError) {
- console.error(
- "Error updating credentials:",
- chrome.runtime.lastError
- );
- return;
- }
- console.log(
- "Updated cookie, csrf, and auth in local storage"
- );
- });
- }
- } catch (err) {
- console.error("Error processing request headers:", err);
- }
- }
- );
- } catch (err) {
- console.error("Top level error in onBeforeSendHeaders listener:", err);
- }
- },
- { urls: ["*://x.com/*", "*://twitter.com/*"] },
- ["requestHeaders", "extraHeaders"]
- );
-};
diff --git a/apps/extension/tailwind.config.cjs b/apps/extension/tailwind.config.cjs
deleted file mode 100644
index 466e9b93..00000000
--- a/apps/extension/tailwind.config.cjs
+++ /dev/null
@@ -1,50 +0,0 @@
-/** @type {import('tailwindcss').Config} */
-export default {
- darkMode: ["class"],
- content: ["./src/**/*.{ts,tsx}", "./ui/**/*.{ts,tsx}"],
- theme: {
- extend: {
- colors: {
- border: "hsl(var(--border))",
- input: "hsl(var(--input))",
- ring: "hsl(var(--ring))",
- background: "hsl(var(--background))",
- foreground: "hsl(var(--foreground))",
- primary: {
- DEFAULT: "hsl(var(--primary))",
- foreground: "hsl(var(--primary-foreground))",
- },
- secondary: {
- DEFAULT: "hsl(var(--secondary))",
- foreground: "hsl(var(--secondary-foreground))",
- },
- destructive: {
- DEFAULT: "hsl(var(--destructive))",
- foreground: "hsl(var(--destructive-foreground))",
- },
- muted: {
- DEFAULT: "hsl(var(--muted))",
- foreground: "hsl(var(--muted-foreground))",
- },
- accent: {
- DEFAULT: "hsl(var(--accent))",
- foreground: "hsl(var(--accent-foreground))",
- },
- popover: {
- DEFAULT: "hsl(var(--popover))",
- foreground: "hsl(var(--popover-foreground))",
- },
- card: {
- DEFAULT: "hsl(var(--card))",
- foreground: "hsl(var(--card-foreground))",
- },
- },
- borderRadius: {
- lg: `var(--radius)`,
- md: `calc(var(--radius) - 2px)`,
- sm: "calc(var(--radius) - 4px)",
- },
- },
- },
- plugins: [import("tailwindcss-animate")],
-}
diff --git a/apps/extension/tsconfig.json b/apps/extension/tsconfig.json
deleted file mode 100644
index ade28a04..00000000
--- a/apps/extension/tsconfig.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "compilerOptions": {
- "target": "ES2020",
- "module": "ES2020",
- "strict": true,
- "esModuleInterop": true,
- "skipLibCheck": true,
- "forceConsistentCasingInFileNames": true,
- "moduleResolution": "node",
- "resolveJsonModule": true,
- "isolatedModules": true,
- "noEmit": true,
- "jsx": "preserve",
- "types": ["chrome"],
- "baseUrl": ".",
- "paths": {
- "@/*": ["./*"]
- }
- },
- "include": ["src/**/*.ts", "src/**/*.tsx", "ui/**/*.tsx", "src/content.tsx"],
- "exclude": ["node_modules"]
-}
diff --git a/apps/extension/ui/hooks/use-spaces.tsx b/apps/extension/ui/hooks/use-spaces.tsx
deleted file mode 100644
index a7b5f4df..00000000
--- a/apps/extension/ui/hooks/use-spaces.tsx
+++ /dev/null
@@ -1,147 +0,0 @@
-import { Space } from "@supermemory/db/schema";
-import { useState, useEffect, useCallback } from "react";
-import { toast } from "sonner";
-import { getBaseURL } from "@/lib/utils";
-
-export type ExtraSpaceMetaData = {
- permissions: {
- canRead: boolean;
- canEdit: boolean;
- isOwner: boolean;
- };
- owner: {
- id: string;
- name: string;
- email: string;
- profileImage: string;
- } | null;
- favorited: boolean;
-};
-
-type SpaceResponse = {
- spaces: (Space & ExtraSpaceMetaData)[];
-};
-
-type CreateSpaceResponse = {
- message: string;
- space: {
- name: string;
- uuid: string;
- isPublic: boolean;
- };
-};
-
-async function fetchSpaces(): Promise {
- return new Promise((resolve, reject) => {
- chrome.runtime.sendMessage(
- { type: "GET_SPACES", payload: undefined },
- (response) => {
- if (chrome.runtime.lastError) {
- reject(new Error(chrome.runtime.lastError.message));
- return;
- }
- resolve(response);
- }
- );
- });
-}
-
-async function createSpace(data: {
- spaceName: string;
- isPublic: boolean;
-}): Promise {
- const baseURL = await getBaseURL();
- const response = await fetch(`${baseURL}/backend/v1/space/create`, {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify(data),
- });
-
- if (!response.ok) {
- const error = await response.json();
- throw new Error(
- (error as { error: string }).error || "Failed to create space"
- );
- }
-
- return response.json();
-}
-
-async function makeFavorite(spaceId: string) {
- const baseURL = await getBaseURL();
- const response = await fetch(
- `${baseURL}/backend/v1/space/favorite/${spaceId}`,
- {
- method: "POST",
- }
- );
-
- if (!response.ok) {
- throw new Error("Failed to make favorite");
- }
-
- return response.json();
-}
-
-export function useSpaces() {
- const [spaces, setSpaces] = useState<(Space & ExtraSpaceMetaData)[]>([]);
- const [isLoading, setIsLoading] = useState(true);
- const [error, setError] = useState(null);
- const [isCreating, setIsCreating] = useState(false);
- const [createError, setCreateError] = useState(null);
-
- const loadSpaces = useCallback(async () => {
- try {
- setIsLoading(true);
- const response = await fetchSpaces();
- setSpaces(response.spaces);
- setError(null);
- } catch (err) {
- console.error("Error fetching spaces:", err); // Add error logging
- setError(
- err instanceof Error ? err : new Error("Failed to fetch spaces")
- );
- } finally {
- setIsLoading(false);
- }
- }, []); // Empty dependency array since we don't use any external values
-
- useEffect(() => {
- loadSpaces().catch((err) => {
- console.error("Failed to load spaces:", err); // Add error handling
- });
- }, []); // Use empty dependency array instead of [loadSpaces]
-
- const handleCreateSpace = async (data: {
- spaceName: string;
- isPublic: boolean;
- }) => {
- try {
- setIsCreating(true);
- setCreateError(null);
- const response = await createSpace(data);
- toast.success(response.message);
- loadSpaces(); // Refresh spaces after creation
- } catch (err) {
- const error =
- err instanceof Error ? err : new Error("Failed to create space");
- console.error("Failed to create space", error);
- toast.error(error.message);
- setCreateError(error);
- } finally {
- setIsCreating(false);
- }
- };
-
- return {
- spaces,
- isLoading,
- error,
- refetch: loadSpaces,
- createSpace: handleCreateSpace,
- isCreating,
- createError,
- };
-}
diff --git a/apps/extension/ui/shadcn/badge.tsx b/apps/extension/ui/shadcn/badge.tsx
deleted file mode 100644
index e87d62bf..00000000
--- a/apps/extension/ui/shadcn/badge.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import * as React from "react"
-import { cva, type VariantProps } from "class-variance-authority"
-
-import { cn } from "@/lib/utils"
-
-const badgeVariants = cva(
- "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
- {
- variants: {
- variant: {
- default:
- "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",
- secondary:
- "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
- destructive:
- "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80",
- outline: "text-foreground",
- },
- },
- defaultVariants: {
- variant: "default",
- },
- }
-)
-
-export interface BadgeProps
- extends React.HTMLAttributes,
- VariantProps {}
-
-function Badge({ className, variant, ...props }: BadgeProps) {
- return (
-
- )
-}
-
-export { Badge, badgeVariants }
diff --git a/apps/extension/ui/shadcn/button.tsx b/apps/extension/ui/shadcn/button.tsx
deleted file mode 100644
index 65d4fcd9..00000000
--- a/apps/extension/ui/shadcn/button.tsx
+++ /dev/null
@@ -1,57 +0,0 @@
-import * as React from "react"
-import { Slot } from "@radix-ui/react-slot"
-import { cva, type VariantProps } from "class-variance-authority"
-
-import { cn } from "@/lib/utils"
-
-const buttonVariants = cva(
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
- {
- variants: {
- variant: {
- default:
- "bg-primary text-primary-foreground shadow hover:bg-primary/90",
- destructive:
- "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
- outline:
- "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
- secondary:
- "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
- ghost: "hover:bg-accent hover:text-accent-foreground",
- link: "text-primary underline-offset-4 hover:underline",
- },
- size: {
- default: "h-9 px-4 py-2",
- sm: "h-8 rounded-md px-3 text-xs",
- lg: "h-10 rounded-md px-8",
- icon: "h-9 w-9",
- },
- },
- defaultVariants: {
- variant: "default",
- size: "default",
- },
- }
-)
-
-export interface ButtonProps
- extends React.ButtonHTMLAttributes,
- VariantProps {
- asChild?: boolean
-}
-
-const Button = React.forwardRef(
- ({ className, variant, size, asChild = false, ...props }, ref) => {
- const Comp = asChild ? Slot : "button"
- return (
-
- )
- }
-)
-Button.displayName = "Button"
-
-export { Button, buttonVariants }
diff --git a/apps/extension/ui/shadcn/command.tsx b/apps/extension/ui/shadcn/command.tsx
deleted file mode 100644
index 3bb14d39..00000000
--- a/apps/extension/ui/shadcn/command.tsx
+++ /dev/null
@@ -1,151 +0,0 @@
-import * as React from "react"
-import { type DialogProps } from "@radix-ui/react-dialog"
-import { Command as CommandPrimitive } from "cmdk"
-import { Search } from "lucide-react"
-
-import { cn } from "@/lib/utils"
-import { Dialog, DialogContent } from "@/ui/shadcn/dialog"
-
-const Command = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-Command.displayName = CommandPrimitive.displayName
-
-const CommandDialog = ({ children, ...props }: DialogProps) => {
- return (
-
-
-
- {children}
-
-
-
- )
-}
-
-const CommandInput = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-
-
-
-))
-
-CommandInput.displayName = CommandPrimitive.Input.displayName
-
-const CommandList = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-
-CommandList.displayName = CommandPrimitive.List.displayName
-
-const CommandEmpty = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->((props, ref) => (
-
-))
-
-CommandEmpty.displayName = CommandPrimitive.Empty.displayName
-
-const CommandGroup = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-
-CommandGroup.displayName = CommandPrimitive.Group.displayName
-
-const CommandSeparator = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-CommandSeparator.displayName = CommandPrimitive.Separator.displayName
-
-const CommandItem = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-
-CommandItem.displayName = CommandPrimitive.Item.displayName
-
-const CommandShortcut = ({
- className,
- ...props
-}: React.HTMLAttributes) => {
- return (
-
- )
-}
-CommandShortcut.displayName = "CommandShortcut"
-
-export {
- Command,
- CommandDialog,
- CommandInput,
- CommandList,
- CommandEmpty,
- CommandGroup,
- CommandItem,
- CommandShortcut,
- CommandSeparator,
-}
diff --git a/apps/extension/ui/shadcn/dialog.tsx b/apps/extension/ui/shadcn/dialog.tsx
deleted file mode 100644
index 1647513e..00000000
--- a/apps/extension/ui/shadcn/dialog.tsx
+++ /dev/null
@@ -1,122 +0,0 @@
-"use client"
-
-import * as React from "react"
-import * as DialogPrimitive from "@radix-ui/react-dialog"
-import { X } from "lucide-react"
-
-import { cn } from "@/lib/utils"
-
-const Dialog = DialogPrimitive.Root
-
-const DialogTrigger = DialogPrimitive.Trigger
-
-const DialogPortal = DialogPrimitive.Portal
-
-const DialogClose = DialogPrimitive.Close
-
-const DialogOverlay = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
-
-const DialogContent = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, children, ...props }, ref) => (
-
-
-
- {children}
-
-
- Close
-
-
-
-))
-DialogContent.displayName = DialogPrimitive.Content.displayName
-
-const DialogHeader = ({
- className,
- ...props
-}: React.HTMLAttributes) => (
-
-)
-DialogHeader.displayName = "DialogHeader"
-
-const DialogFooter = ({
- className,
- ...props
-}: React.HTMLAttributes) => (
-
-)
-DialogFooter.displayName = "DialogFooter"
-
-const DialogTitle = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-DialogTitle.displayName = DialogPrimitive.Title.displayName
-
-const DialogDescription = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-DialogDescription.displayName = DialogPrimitive.Description.displayName
-
-export {
- Dialog,
- DialogPortal,
- DialogOverlay,
- DialogTrigger,
- DialogClose,
- DialogContent,
- DialogHeader,
- DialogFooter,
- DialogTitle,
- DialogDescription,
-}
diff --git a/apps/extension/ui/shadcn/popover.tsx b/apps/extension/ui/shadcn/popover.tsx
deleted file mode 100644
index eafc78a4..00000000
--- a/apps/extension/ui/shadcn/popover.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import * as React from "react"
-import * as PopoverPrimitive from "@radix-ui/react-popover"
-
-import { cn } from "@/lib/utils"
-
-const Popover = PopoverPrimitive.Root
-
-const PopoverTrigger = PopoverPrimitive.Trigger
-
-const PopoverAnchor = PopoverPrimitive.Anchor
-
-const PopoverContent = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
-
-
-
-))
-PopoverContent.displayName = PopoverPrimitive.Content.displayName
-
-export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }
diff --git a/apps/extension/ui/spaces-selector.tsx b/apps/extension/ui/spaces-selector.tsx
deleted file mode 100644
index be5e0eac..00000000
--- a/apps/extension/ui/spaces-selector.tsx
+++ /dev/null
@@ -1,217 +0,0 @@
-import { useSpaces } from "./hooks/use-spaces";
-import { useState, useEffect, useRef } from "react";
-import { cn } from "@/lib/utils";
-
-interface SpacesSelectorProps {
- onSelecting?: (isSelecting: boolean) => void;
- onSpacesChange?: (spaces: any[]) => void;
- passRef?: React.RefObject;
-}
-
-export default function SpacesSelector({
- onSelecting,
- onSpacesChange,
- passRef,
-}: SpacesSelectorProps) {
- const { spaces } = useSpaces();
- const [isOpen, setIsOpen] = useState(false);
- const [selectedSpaces, setSelectedSpaces] = useState([]);
- const [searchQuery, setSearchQuery] = useState("");
- const dropdownRef = useRef(null);
- const dropdownContentRef = useRef(null);
-
- const toggleSpace = (space: any) => {
- const isSelected = selectedSpaces.some((s) => s.id === space.id);
- const newSelectedSpaces = isSelected
- ? selectedSpaces.filter((s) => s.id !== space.id)
- : [...selectedSpaces, space];
-
- setSelectedSpaces(newSelectedSpaces);
- onSpacesChange?.(newSelectedSpaces);
- };
-
- const removeSpace = (spaceId: string) => {
- const newSelectedSpaces = selectedSpaces.filter((s) => s.id !== spaceId);
- setSelectedSpaces(newSelectedSpaces);
- onSpacesChange?.(newSelectedSpaces);
- };
-
- useEffect(() => {
- const handleClickOutside = (event: MouseEvent) => {
- // Get the shadow root
- const shadowRoot = dropdownRef.current?.getRootNode() as ShadowRoot;
- const target = event.composedPath()[0] as Node;
-
- // Check if click is inside either the trigger or dropdown content
- const isInsideTrigger = dropdownRef.current?.contains(target);
- const isInsideDropdown = dropdownContentRef.current?.contains(target);
-
- if (!isInsideTrigger && !isInsideDropdown) {
- setIsOpen(false);
- onSelecting?.(false);
- }
- };
-
- // Listen on the window to catch all clicks, including those in shadow DOM
- window.addEventListener("click", handleClickOutside, true);
- return () => {
- window.removeEventListener("click", handleClickOutside, true);
- // cleanup all states
- setIsOpen(false);
- setSelectedSpaces([]);
- setSearchQuery("");
- };
- }, [onSelecting]);
-
- const filteredSpaces = spaces?.filter((space) =>
- space.name.toLowerCase().includes(searchQuery.toLowerCase())
- );
-
- const toggleDropdown = () => {
- setIsOpen(!isOpen);
- onSelecting?.(!isOpen);
- };
-
- return (
-
-
-
-
-
-
- {selectedSpaces.length === 0 && "Select spaces to save to..."}
- {selectedSpaces.length === 1 && selectedSpaces[0].name}
- {selectedSpaces.length > 1 &&
- `${selectedSpaces.length} spaces selected`}
-
-
-
-
-
-
-
- {isOpen && (
-
-
- setSearchQuery(e.target.value)}
- className="w-full px-2 py-1.5 text-sm bg-gray-800 rounded border border-white/20 text-white placeholder-white/50 focus:outline-none focus:border-blue-500"
- autoFocus
- />
-
-
-
- {filteredSpaces?.length === 0 && (
-
- No spaces found
-
- )}
-
- {filteredSpaces?.map((space) => {
- const isSelected = selectedSpaces.some(
- (s) => s.id === space.id
- );
- return (
-
toggleSpace(space)}
- className={cn(
- "w-full px-3 py-2 text-left text-sm flex items-center gap-2",
- "text-white hover:bg-gray-800",
- isSelected && "bg-gray-800"
- )}
- >
-
- {isSelected && (
-
-
-
- )}
-
- {space.name}
-
- );
- })}
-
-
- )}
-
-
- {selectedSpaces.length > 0 && (
-
- {selectedSpaces.map((space) => (
-
-
-
{space.name}
-
removeSpace(space.id)}
- className="opacity-60 hover:opacity-100 transition-opacity"
- >
-
-
-
-
-
- ))}
-
- )}
-
- );
-}
diff --git a/apps/web/.env.example b/apps/web/.env.example
new file mode 100644
index 00000000..969d7377
--- /dev/null
+++ b/apps/web/.env.example
@@ -0,0 +1,2 @@
+NEXT_PUBLIC_BACKEND_URL=https://api.supermemory.ai
+NEXT_PUBLIC_POSTHOG_KEY=
\ No newline at end of file
diff --git a/apps/web/.gitignore b/apps/web/.gitignore
index e42a8020..4f328319 100644
--- a/apps/web/.gitignore
+++ b/apps/web/.gitignore
@@ -1,18 +1,37 @@
-node_modules
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
-/.cache
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+.yarn/install-state.gz
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
/build
-.env
-.dev.vars
-.wrangler
+# misc
+.DS_Store
+*.pem
-.env.*
-.env
-.dev.vars
-*.vars
-bun.lockb
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
-# Million Lint
-.million
-database.sql
+# env files (can opt-in for commiting if needed)
+.env*
+!.env.example
+
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
+next-env.d.ts
diff --git a/apps/web/.prettierrc b/apps/web/.prettierrc
deleted file mode 100644
index be27a4b9..00000000
--- a/apps/web/.prettierrc
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "printWidth": 100,
- "singleQuote": false,
- "semi": true,
- "useTabs": true,
- "plugins": ["prettier-plugin-tailwindcss", "@trivago/prettier-plugin-sort-imports"],
- "importOrder": [
- "^react",
- "^@remix-run/(.*)$",
- "^@ui/(.*)$",
- "^components/(.*)$",
- "^lib/(.*)$",
- "^[./]",
- ""
- ],
- "importOrderSeparation": true,
- "importOrderSortSpecifiers": true,
- "importOrderGroupNamespaceSpecifiers": true
-}
diff --git a/apps/web/README.md b/apps/web/README.md
index dec7f30b..9cd849fb 100644
--- a/apps/web/README.md
+++ b/apps/web/README.md
@@ -1,47 +1 @@
-# Welcome to Remix + Cloudflare!
-
-- π [Remix docs](https://remix.run/docs)
-- π [Remix Cloudflare docs](https://remix.run/guides/vite#cloudflare)
-
-## Development
-
-Run the dev server:
-
-```sh
-npm run dev
-```
-
-To run Wrangler:
-
-```sh
-npm run build
-npm run start
-```
-
-## Typegen
-
-Generate types for your Cloudflare bindings in `wrangler.toml`:
-
-```sh
-npm run typegen
-```
-
-You will need to rerun typegen whenever you make changes to `wrangler.toml`.
-
-## Deployment
-
-First, build your app for production:
-
-```sh
-npm run build
-```
-
-Then, deploy your app to Cloudflare Pages:
-
-```sh
-npm run deploy
-```
-
-## Styling
-
-This template comes with [Tailwind CSS](https://tailwindcss.com/) already configured for a simple default starting experience. You can use whatever css framework you prefer. See the [Vite docs on css](https://vitejs.dev/guide/features.html#css) for more information.
+# supermemory Consumer
\ No newline at end of file
diff --git a/apps/web/app/(auth)/login/page.tsx b/apps/web/app/(auth)/login/page.tsx
new file mode 100644
index 00000000..e2f72129
--- /dev/null
+++ b/apps/web/app/(auth)/login/page.tsx
@@ -0,0 +1,12 @@
+import { LoginPage } from "@repo/ui/pages/login"
+
+export default function Page() {
+ return (
+
+ )
+}
diff --git a/apps/web/app/api/emails/welcome/route.tsx b/apps/web/app/api/emails/welcome/route.tsx
new file mode 100644
index 00000000..48883d6b
--- /dev/null
+++ b/apps/web/app/api/emails/welcome/route.tsx
@@ -0,0 +1,19 @@
+/** biome-ignore-all lint/performance/noImgElement: Not Next.js environment */
+import { ImageResponse } from "next/og";
+
+export async function GET() {
+ return new ImageResponse(
+
+
+
,
+ {
+ width: 1200,
+ height: 630,
+ },
+ );
+}
diff --git a/apps/web/app/components/Chat.tsx b/apps/web/app/components/Chat.tsx
deleted file mode 100644
index 214d41ea..00000000
--- a/apps/web/app/components/Chat.tsx
+++ /dev/null
@@ -1,329 +0,0 @@
-import { useEffect, useRef, useState } from "react";
-import Markdown from "react-markdown";
-
-import ChatInputForm from "./ChatInputForm";
-import Navbar from "./Navbar";
-import SharedCard from "./memories/SharedCard";
-
-import { User } from "@supermemory/shared/types";
-import { CoreMessage } from "ai";
-import { AnimatePresence, motion } from "framer-motion";
-import { ChevronDown, ChevronUp } from "lucide-react";
-import { useChatStream } from "~/lib/hooks/use-chat-stream";
-import { Memory } from "~/lib/types/memory";
-
-interface ChatProps {
- user: User;
- chatMessages: CoreMessage[];
- initialThreadUuid?: string;
-}
-
-function Chat({ user, chatMessages, initialThreadUuid }: ChatProps) {
- const {
- threadUuid,
- chatMessages: chatMessagesStreamed,
- input,
- setInput,
- sendMessage,
- isLoading,
- } = useChatStream(chatMessages, initialThreadUuid);
-
- const [expandedMessageIndexes, setExpandedMessageIndexes] = useState([]);
- const [shouldAutoScroll, setShouldAutoScroll] = useState(true);
- const messagesEndRef = useRef(null);
- const scrollContainerRef = useRef(null);
- const [streamingText, setStreamingText] = useState("");
-
- const hasAnnotations = chatMessagesStreamed.some(
- (message) => message.role === "assistant" && message.annotations?.length,
- );
-
- const toggleExpand = (index: number) => {
- setExpandedMessageIndexes((prev) =>
- prev.includes(index) ? prev.filter((i) => i !== index) : [...prev, index],
- );
- };
-
- const scrollToBottom = () => {
- if (messagesEndRef.current && shouldAutoScroll) {
- messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
- }
- };
-
- useEffect(() => {
- scrollToBottom();
- }, [chatMessagesStreamed]);
-
- useEffect(() => {
- const lastMessage = chatMessagesStreamed[chatMessagesStreamed.length - 1];
- if (lastMessage?.role === "assistant" && isLoading) {
- setStreamingText(lastMessage.content as string);
- } else {
- setStreamingText("");
- }
- }, [chatMessagesStreamed, isLoading]);
-
- const handleScroll = () => {
- if (!scrollContainerRef.current) return;
-
- const { scrollTop, scrollHeight, clientHeight } = scrollContainerRef.current;
- const isAtBottom = Math.abs(scrollHeight - clientHeight - scrollTop) < 10;
- setShouldAutoScroll(isAtBottom);
- };
-
- const renderAttachments = (attachments: any[]) => (
-
- {attachments.map((attachment) => (
-
- {attachment.url.endsWith(".png") ||
- attachment.url.endsWith(".jpg") ||
- attachment.url.endsWith(".jpeg") ? (
-
- ) : (
-
- )}
-
- ))}
-
- );
-
- const renderMessageContent = (content: string | any, isLatestAndLoading: boolean) => (
-
-
- {isLatestAndLoading ? streamingText : typeof content === "string" ? content.replace(/[\s\S]*?<\/context>/g, "") : content}
-
-
- );
-
- const groupAnnotationsByHost = (annotations: Memory[]) => {
- return annotations.reduce(
- (acc, curr) => {
- let host = "";
- try {
- const url = new URL(curr.url || "");
- host = url.host;
- } catch {
- host = "unknown";
- }
- if (!acc[host]) acc[host] = [];
- acc[host].push(curr);
- return acc;
- },
- {} as Record,
- );
- };
-
- const renderAnnotations = (messageAnnotations: Memory[], index: number, isMobile = false) => {
- const isExpanded = expandedMessageIndexes.includes(index);
- const groupedAnnotations = groupAnnotationsByHost(messageAnnotations);
-
- return (
-
-
- {!isExpanded ? (
- toggleExpand(index)}
- className={`text-${isMobile ? "xs" : "sm"} text-muted-foreground hover:text-foreground transition-colors flex items-center gap-1`}
- whileHover={{ scale: 1.02 }}
- whileTap={{ scale: 0.98 }}
- >
-
- {messageAnnotations.length} relevant{" "}
- {messageAnnotations.length === 1 ? "item" : "items"}
-
- ) : (
-
-
- Related Context
-
-
- {isMobile
- ? messageAnnotations.map((annotation, i) => (
-
-
-
- ))
- : Object.entries(groupedAnnotations).map(([host, items], i) => (
-
- {items.length > 1 && (
-
- {host} ({items.length} items)
-
- )}
-
- {items.map((annotation, j) => (
-
-
-
- ))}
-
-
- ))}
-
- toggleExpand(index)}
- className={`flex items-center gap-${isMobile ? "1" : "2"} text-${isMobile ? "xs" : "sm"} text-muted-foreground hover:text-foreground transition-colors`}
- whileHover={{ scale: 1.02 }}
- whileTap={{ scale: 0.98 }}
- >
-
- Show less
-
-
- )}
-
-
- );
- };
-
- return (
-
-
-
-
-
-
- {chatMessagesStreamed.map((message, index) => {
- const isLatestAndLoading = index === chatMessagesStreamed.length - 1 && isLoading && message.role === "assistant";
-
- if (message.role === "user") {
- return (
-
- {message.experimental_attachments &&
- renderAttachments(message.experimental_attachments)}
- {message.content}
-
- );
- }
-
- if (message.role === "assistant") {
- const messageAnnotations = message.annotations?.[0]
- ? (message.annotations[0] as unknown as Memory[])
- : undefined;
-
- return (
-
- <>
- {messageAnnotations &&
- messageAnnotations.length > 0 &&
- renderAnnotations(messageAnnotations, index, true)}
-
-
{renderMessageContent(message.content, isLatestAndLoading)}
- {messageAnnotations &&
- messageAnnotations.length > 0 &&
- renderAnnotations(messageAnnotations, index)}
-
- >
-
- );
- }
- return null;
- })}
-
- {isLoading && !chatMessagesStreamed[chatMessagesStreamed.length - 1]?.content && (
-
-
-
- {[3 / 4, 1 / 2, 2 / 3, 1 / 3].map((width, i) => (
-
- ))}
-
-
- {hasAnnotations && (
-
-
- {[...Array(2)].map((_, i) => (
-
- ))}
-
-
- )}
-
- )}
-
-
-
-
-
-
-
-
-
-
- );
-}
-
-export default Chat;
diff --git a/apps/web/app/components/ChatInputForm.tsx b/apps/web/app/components/ChatInputForm.tsx
deleted file mode 100644
index 80b077a9..00000000
--- a/apps/web/app/components/ChatInputForm.tsx
+++ /dev/null
@@ -1,502 +0,0 @@
-import { KeyboardEvent, useCallback, useRef, useState } from "react";
-
-import { useFetcher, useLoaderData } from "@remix-run/react";
-
-import { useUploadFile } from "../lib/hooks/use-upload-file";
-import SpacesSelector from "./memories/SpacesSelector";
-import { Button } from "./ui/button";
-import { Textarea } from "./ui/textarea";
-
-import { SpaceIcon } from "@supermemory/shared/icons";
-import { cn } from "~/lib/utils";
-import { loader } from "~/routes/_index";
-
-function MemoryInputForm({
- user,
- input,
- setInput,
- submit: externalSubmit,
- mini = false,
- fileURLs = [],
- setFileURLs,
- isLoading = false,
-}: {
- user: ReturnType>["user"];
- input: string;
- setInput: React.Dispatch>;
- submit: () => void;
- mini?: boolean;
- fileURLs?: string[];
- setFileURLs?: React.Dispatch>;
- isLoading?: boolean;
-}) {
- const [previews, setPreviews] = useState([]);
- const { uploadFile, isUploading } = useUploadFile();
- const fetcher = useFetcher();
- const fileInputRef = useRef(null);
- const [isDragActive, setIsDragActive] = useState(false);
- const [selectedSpaces, setSelectedSpaces] = useState([]);
-
- const submit = useCallback(() => {
- if (input.trim() || fileURLs.length > 0) {
- if (!isLoading) {
- externalSubmit();
- setInput("");
- setFileURLs?.([]);
- setPreviews([]);
- }
- }
- }, [externalSubmit, input, fileURLs.length, setInput, isLoading]);
-
- const handlePaste = useCallback(
- (e: React.ClipboardEvent) => {
- const items = e.clipboardData.items;
- for (const item of items) {
- if (item.type.startsWith("image/") || item.type === "application/pdf") {
- const file = item.getAsFile();
- if (file) {
- if (isUploading || fileURLs.length !== previews.length) {
- console.log(
- "Cannot upload file: Upload in progress or previous upload not completed",
- );
- return;
- }
- if (fileURLs.length >= 5) {
- console.log("Maximum file limit reached");
- return;
- }
- handleFileUpload(file);
- break; // Only handle one file per paste
- }
- }
- }
- },
- [isUploading, fileURLs.length, previews.length],
- );
-
- const handleKeyDown = useCallback(
- (e: KeyboardEvent) => {
- if (e.key === "Enter" && !e.shiftKey) {
- e.preventDefault();
- submit();
- }
- },
- [submit],
- );
-
- const handleAttachClick = useCallback(() => {
- if (isUploading || fileURLs.length !== previews.length) {
- console.log("Cannot attach file: Upload in progress or previous upload not completed");
- return;
- }
- if (fileInputRef.current) {
- fileInputRef.current.click();
- // For mobile Safari, we need to focus and blur to ensure the file picker opens
- fileInputRef.current.focus();
- fileInputRef.current.blur();
- }
- }, [isUploading, fileURLs.length, previews.length]);
-
- const handleFileChange = useCallback(
- (e: React.ChangeEvent) => {
- const files = Array.from(e.target.files || []);
- const remainingSlots = 5 - fileURLs.length;
- files.slice(0, remainingSlots).forEach(handleFileUpload);
- e.target.value = "";
- },
- [fileURLs.length],
- );
-
- const handleFileUpload = useCallback(
- async (file: File) => {
- if (fileURLs.length >= 5) {
- console.log("Maximum file limit reached");
- return;
- }
-
- if (
- file.type !== "image/jpeg" &&
- file.type !== "image/png" &&
- file.type !== "application/pdf"
- ) {
- console.error("Unsupported file type:", file.type);
- return;
- }
-
- const reader = new FileReader();
- reader.onload = (ev) => {
- const previewURL = ev.target?.result as string;
- if (previews.includes(previewURL)) {
- console.log("Duplicate file detected. Skipping upload.");
- return;
- }
- setPreviews((prev) => [...prev, previewURL]);
- };
- reader.readAsDataURL(file);
-
- try {
- const { url: fileURL, error } = await uploadFile(file);
- if (error) {
- console.error("File upload failed:", error);
- setPreviews((prev) => prev.filter((_, i) => i !== fileURLs.length));
- return;
- }
- if (fileURL) {
- const encodedURL = encodeURIComponent(fileURL);
- if (fileURLs.includes(encodedURL)) {
- console.log("Duplicate file URL detected. Skipping.");
- return;
- }
- setFileURLs?.((prev) => [...prev, encodedURL]);
- } else {
- console.error("File upload failed:", fileURL);
- }
- } catch (error) {
- console.error("File upload failed:", error);
- }
- },
- [fileURLs, previews, uploadFile],
- );
-
- const removeFile = useCallback((index: number) => {
- setFileURLs?.((prev) => prev.filter((_, i) => i !== index));
- setPreviews((prev) => prev.filter((_, i) => i !== index));
- }, []);
-
- const handleDragEnter = useCallback((e: React.DragEvent) => {
- e.preventDefault();
- e.stopPropagation();
- setIsDragActive(true);
- }, []);
-
- const handleDragLeave = useCallback((e: React.DragEvent) => {
- e.preventDefault();
- e.stopPropagation();
- const relatedTarget = e.relatedTarget as Node | null;
- if (!relatedTarget || !e.currentTarget.contains(relatedTarget)) {
- setIsDragActive(false);
- }
- }, []);
-
- const handleDragOver = useCallback((e: React.DragEvent) => {
- e.preventDefault();
- e.stopPropagation();
- }, []);
-
- const handleDrop = useCallback(
- (e: React.DragEvent) => {
- e.preventDefault();
- e.stopPropagation();
- setIsDragActive(false);
-
- const files = Array.from(e.dataTransfer.files);
- const remainingSlots = 5 - fileURLs.length;
- files.slice(0, remainingSlots).forEach(handleFileUpload);
- },
- [fileURLs.length, handleFileUpload],
- );
-
- return (
-
-
-
- {previews.length > 0 && (
-
- {fileURLs.map((fileURL, index) => {
- const isPDF = previews[index].startsWith("data:application/pdf");
- return (
-
- );
- })}
- {fileURLs.length !== previews.length && previews[fileURLs.length] && (
- <>
- {previews[fileURLs.length].startsWith("data:application/pdf") ? (
-
-
-
-
-
Open PDF
-
Uploading PDF...
-
- ) : (
-
- )}
- >
- )}
- {fileURLs.length !== previews.length && !previews[fileURLs.length] && (
-
- )}
-
- )}
-
- {!mini && (
-
-
= 5 || isUploading || fileURLs.length !== previews.length}
- aria-label="Attach file"
- >
-
-
-
- Attach ({fileURLs.length}/5)
-
-
-
-
-
-
- {isLoading ? (
-
-
-
-
- ) : (
-
-
-
- )}
-
-
-
- )}
-
- );
-}
-
-export default MemoryInputForm;
diff --git a/apps/web/app/components/Histories.tsx b/apps/web/app/components/Histories.tsx
deleted file mode 100644
index 5b86c6d3..00000000
--- a/apps/web/app/components/Histories.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import React from "react";
-
-import { Clock } from "lucide-react";
-
-function Histories({
- historyMessages,
-}: {
- historyMessages: { chatId: string; firstMessage: string }[];
-}) {
- return (
-
-
-
- Recently Asked
-
-
-
- );
-}
-
-export default Histories;
diff --git a/apps/web/app/components/Landing/Feature.tsx b/apps/web/app/components/Landing/Feature.tsx
deleted file mode 100644
index e46fa41e..00000000
--- a/apps/web/app/components/Landing/Feature.tsx
+++ /dev/null
@@ -1,157 +0,0 @@
-"use client";
-export default function Feature2() {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Meet Supermemory.
-
Your second brain for knowledge.
-
- Save the things you like, and over time, build the knowledge base of your dreams.
-
- Go down rabbit holes, make connections, search what's important to you.
-
-
-
- );
-}
diff --git a/apps/web/app/components/Landing/Footer.tsx b/apps/web/app/components/Landing/Footer.tsx
deleted file mode 100644
index 3f0b3f3e..00000000
--- a/apps/web/app/components/Landing/Footer.tsx
+++ /dev/null
@@ -1,142 +0,0 @@
-import { PlusGrid, PlusGridItem, PlusGridRow } from "./plus-grid";
-
-function SitemapHeading({ children }: { children: React.ReactNode }) {
- return {children} ;
-}
-
-function SitemapLinks({ children }: { children: React.ReactNode }) {
- return ;
-}
-
-function SitemapLink(props: React.ComponentPropsWithoutRef<"a">) {
- return (
-
-
-
- );
-}
-
-function Sitemap() {
- return (
- <>
-
- Product
-
- Documentation
- Chrome Extension
- iOS Shortcut
-
-
-
- Community
-
- Discord
-
- Report Issue
-
- Get Help
-
-
-
- Legal
-
- Terms of Service
- Privacy Policy
-
-
- >
- );
-}
-
-function SocialIconX(props: React.ComponentPropsWithoutRef<"svg">) {
- return (
-
-
-
- );
-}
-
-function SocialIconGitHub(props: React.ComponentPropsWithoutRef<"svg">) {
- return (
-
-
-
- );
-}
-
-function SocialLinks() {
- return (
- <>
-
-
-
-
-
-
- >
- );
-}
-
-function Copyright() {
- return (
-
- © {new Date().getFullYear()} Supermemory, Inc.
-
- );
-}
-
-export default function Footer() {
- return (
-
-
-
-
-
-
-
-
-
-
- Supermemory
-
-
- Supermemory is a free, open-source AI knowlege platform.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-}
diff --git a/apps/web/app/components/Landing/Hero.tsx b/apps/web/app/components/Landing/Hero.tsx
deleted file mode 100644
index 353d0211..00000000
--- a/apps/web/app/components/Landing/Hero.tsx
+++ /dev/null
@@ -1,299 +0,0 @@
-"use client";
-
-import { DiscordIcon, GithubIcon } from "../icons/IntegrationIcons";
-import { Logo } from "../icons/Logo";
-
-interface PlusPatternBackgroundProps {
- plusSize?: number;
- plusColor?: string;
- backgroundColor?: string;
- className?: string;
- style?: React.CSSProperties;
- fade?: boolean;
- [key: string]: any;
-}
-
-export const BackgroundPlus: React.FC = ({
- plusColor = "#CCE5FF",
- backgroundColor = "transparent",
- plusSize = 60,
- className,
- fade = true,
- style,
- ...props
-}) => {
- const encodedPlusColor = encodeURIComponent(plusColor);
-
- const maskStyle: React.CSSProperties = fade
- ? {
- maskImage: "radial-gradient(circle, white 10%, transparent 90%)",
- WebkitMaskImage: "radial-gradient(circle, white 10%, transparent 90%)",
- }
- : {};
-
- const backgroundStyle: React.CSSProperties = {
- backgroundColor,
- backgroundImage: `url("data:image/svg+xml,%3Csvg width='${plusSize}' height='${plusSize}' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='${encodedPlusColor}' fill-opacity='0.5'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E")`,
- ...maskStyle,
- ...style,
- };
-
- return (
-
- );
-};
-
-export default function Hero() {
- return (
-
-
-
-
- {/* Header */}
-
-
-
- {/* Left section */}
-
-
-
-
- supermemory.ai
-
-
-
- {/* Products dropdown commented out for now
-
- ...
-
- */}
-
-
- Docs
-
-
-
-
- {/* Right section */}
-
-
-
-
-
- {/* Hero Section */}
-
-
-
- {/* Hero Content */}
-
- {/* Announcement Banner */}
-
-
- AI for all your knowledge.
-
-
- Supermemory helps you collect, organize, and recall all your knowledge.
- {/* list of notable features */}
-
-
-
-
-
- Connect with your existing tools and bookmarks
-
-
-
-
-
- Chat and find with AI & actually use your knowledge
-
-
-
-
-
- Share your knowledge with your friends and colleagues
-
-
-
-
-
-
-
-
-
-
-
-
- {/* Video Section */}
-
-
-
- {/* Integration Tags */}
-
-
- Integrate with your favorite tools
-
-
- {[
- "Notion",
- "Twitter",
- "Obsidian",
- "Reddit",
- "LinkedIn",
- "Chrome Extension",
- "iOS App",
- "Slack",
- // "Google Drive",
- // "Microsoft Teams"
- ].map((tool) => (
-
- {tool}
-
- ))}
-
-
-
-
-
- );
-}
diff --git a/apps/web/app/components/Landing/Note.tsx b/apps/web/app/components/Landing/Note.tsx
deleted file mode 100644
index 8fe2d4e1..00000000
--- a/apps/web/app/components/Landing/Note.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-export default function Note() {
- return (
-
-
-
-
-
-
-
-
- {/* Profile Image */}
-
-
-
-
- {/* Message Bubble */}
-
-
- π Hey there! I'm Dhravya
-
-
- I'm a college student who built Supermemory as a weekend project. What started
- as a simple idea has grown into something I'm really proud of, thanks to
- amazing support from the open-source community! π
-
-
-
- When you see "we" on the website - that's actually just me! π
I maintain and
- build everything myself, supported by wonderful donors and grants that help
- keep this project free and open source.
-
-
-
- In this AI-driven world, I believe in augmenting human knowledge rather than
- replacing it. My goal is simple: build something that genuinely helps people
- learn and grow. π‘
-
-
-
- If you'd like to follow my journey, you can find me on{" "}
-
- Twitter
- {" "}
- and{" "}
-
- GitHub
-
- . And if you believe in what we're building, consider{" "}
-
- supporting Supermemory's development
- {" "}
- β€οΈ
-
-
-
-
-
-
-
-
-
- );
-}
diff --git a/apps/web/app/components/Landing/Private.tsx b/apps/web/app/components/Landing/Private.tsx
deleted file mode 100644
index 7e944887..00000000
--- a/apps/web/app/components/Landing/Private.tsx
+++ /dev/null
@@ -1,62 +0,0 @@
-import { Eye, Lock, ShieldCheck } from "lucide-react";
-
-export default function Private() {
- const privacyFeatures = [
- { icon: ShieldCheck, text: "End-to-end encryption" },
- { icon: Lock, text: "Self-hosted option available" },
- { icon: Eye, text: "Zero knowledge architecture" },
- ];
-
- return (
-
-
-
-
- Your knowledge stays
-
- private and secure
-
-
-
- We take privacy seriously. Your data is fully encrypted, never shared with third
- parties. Even on the hosted version, we securely store your data in our own servers.
-
-
-
- {privacyFeatures.map((feature, index) => (
-
- ))}
-
-
-
-
-
-
- );
-}
diff --git a/apps/web/app/components/Landing/index.tsx b/apps/web/app/components/Landing/index.tsx
deleted file mode 100644
index 0a432ec2..00000000
--- a/apps/web/app/components/Landing/index.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import Feature2 from "./Feature";
-import Footer from "./Footer";
-import Hero from "./Hero";
-import Note from "./Note";
-import Private from "./Private";
-
-export default function Landing() {
- return (
-
- );
-}
diff --git a/apps/web/app/components/Landing/plus-grid.tsx b/apps/web/app/components/Landing/plus-grid.tsx
deleted file mode 100644
index 752ccefc..00000000
--- a/apps/web/app/components/Landing/plus-grid.tsx
+++ /dev/null
@@ -1,88 +0,0 @@
-import { clsx } from "clsx";
-
-export function PlusGrid({
- className = "",
- children,
-}: {
- className?: string;
- children: React.ReactNode;
-}) {
- return {children}
;
-}
-
-export function PlusGridRow({
- className = "",
- children,
-}: {
- className?: string;
- children: React.ReactNode;
-}) {
- return (
-
- );
-}
-
-export function PlusGridItem({
- className = "",
- children,
-}: {
- className?: string;
- children: React.ReactNode;
-}) {
- return (
-
- );
-}
-
-export function PlusGridIcon({
- className = "",
- placement,
-}: {
- className?: string;
- placement: `${"top" | "bottom"} ${"right" | "left"}`;
-}) {
- let [yAxis, xAxis] = placement.split(" ");
-
- let yClass = yAxis === "top" ? "-top-2" : "-bottom-2";
- let xClass = xAxis === "left" ? "-left-2" : "-right-2";
-
- return (
-
-
-
- );
-}
diff --git a/apps/web/app/components/Navbar.tsx b/apps/web/app/components/Navbar.tsx
deleted file mode 100644
index dc5b8485..00000000
--- a/apps/web/app/components/Navbar.tsx
+++ /dev/null
@@ -1,155 +0,0 @@
-import { Form } from "@remix-run/react";
-
-import { Logo } from "./icons/Logo";
-import { AddMemoryModal } from "./memories/AddMemory";
-import { Button } from "./ui/button";
-
-import { User } from "@supermemory/shared/types";
-import {
- ChevronDown,
- Cloud,
- Github,
- LifeBuoy,
- LogOut,
- Moon,
- Sun,
- User as UserIcon,
-} from "lucide-react";
-import { Avatar, AvatarFallback, AvatarImage } from "~/components/ui/avatar";
-import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuGroup,
- DropdownMenuItem,
- DropdownMenuLabel,
- DropdownMenuSeparator,
- DropdownMenuShortcut,
- DropdownMenuTrigger,
-} from "~/components/ui/dropdown-menu";
-import { useKeyboardShortcut } from "~/lib/hooks/use-keyboard";
-import { Theme, useTheme } from "~/lib/theme-provider";
-
-function Navbar({ user }: { user?: User }) {
- const [theme, setTheme] = useTheme();
-
- const toggleTheme = (e: Event) => {
- e.preventDefault();
- setTheme(theme === Theme.LIGHT ? Theme.DARK : Theme.LIGHT);
- };
-
- useKeyboardShortcut(
- ["c"],
- () => {
- console.log("Add Memory");
- document.getElementById("add-memory-button")?.click();
- },
- "Add Memory",
- );
-
- return (
-
-
-
-
-
-
- {user ? (
- <>
-
-
-
- C
-
- Add Memory
-
-
-
-
-
-
-
-
-
- {user.firstName?.charAt(0) ?? "?"}
- {user.lastName?.charAt(0) ?? "?"}
-
-
-
-
-
-
- {user.firstName} {user.lastName}
- {user.email}
-
-
-
- {/* TODO: Add profile modal */}
- {/*
-
-
- Profile
-
- */}
-
- {theme === Theme.LIGHT ? (
-
- ) : (
-
- )}
- {theme === Theme.LIGHT ? "Dark mode" : "Light mode"}
-
-
-
-
- Support
-
-
-
-
-
- API
-
-
-
-
-
-
-
- GitHub
-
-
-
-
-
-
-
-
- >
- ) : (
-
- )}
-
-
- );
-}
-
-export default Navbar;
diff --git a/apps/web/app/components/Reminders.tsx b/apps/web/app/components/Reminders.tsx
deleted file mode 100644
index 5de30e25..00000000
--- a/apps/web/app/components/Reminders.tsx
+++ /dev/null
@@ -1,354 +0,0 @@
-import React, { useEffect, useState } from "react";
-import Markdown from "react-markdown";
-
-import { useNavigate } from "@remix-run/react";
-
-import image from "./gradients/gradient1.png";
-import { AddMemoryModal } from "./memories/AddMemory";
-import { Button } from "./ui/button";
-
-import { MemoryIcon, SpaceIcon } from "@supermemory/shared/icons";
-import { motion } from "framer-motion";
-import { BookIcon, BookOpen, ChevronDownIcon, SparkleIcon } from "lucide-react";
-import { Theme, useTheme } from "~/lib/theme-provider";
-
-function Reminder({ content, contentId }: { content: string; contentId: string }) {
- const [theme] = useTheme();
- const navigate = useNavigate();
- const [isExpanded, setIsExpanded] = useState(false);
- const [isOverflowing, setIsOverflowing] = useState(false);
- const contentRef = React.useRef(null);
-
- useEffect(() => {
- if (contentRef.current) {
- setIsOverflowing(contentRef.current.scrollHeight > contentRef.current.clientHeight);
- }
- }, [content]);
-
- if (typeof window === "undefined") return null;
-
- return (
-
-
-
-
Remember this? A topic you forgot.
-
-
-
-
-
- {content}
-
-
- {!isExpanded && isOverflowing && (
-
- )}
-
-
- {isOverflowing && (
-
setIsExpanded(!isExpanded)}
- className="w-full text-xs flex items-center gap-1 py-1"
- >
- {isExpanded ? "Show less" : "Show more"}
-
-
- )}
-
-
- navigate(`/content/${contentId}`)}
- className="dark flex items-center justify-center gap-1 md:gap-2 border text-xs md:text-sm py-2 min-h-[36px]"
- >
-
-
- View content
-
-
-
-
-
- Show related
-
-
-
-
- );
-}
-
-function LoadingReminder() {
- return (
-
- );
-}
-
-function Reminders() {
- const [suggestedLearnings, setSuggestedLearnings] = useState>>([]);
- const [currentIndex, setCurrentIndex] = useState(0);
- const [isLoading, setIsLoading] = useState(true);
- const navigate = useNavigate();
-
- useEffect(() => {
- fetch(`/backend/v1/suggested-learnings`, {
- credentials: "include",
- })
- .then((res) => res.json() as Promise<{ suggestedLearnings: Array> }>)
- .then((data) => {
- setSuggestedLearnings(data.suggestedLearnings);
- setIsLoading(false);
- })
- .catch((err) => {
- console.error("Failed to fetch suggested learnings:", err);
- setIsLoading(false);
- });
- }, []);
-
- if (typeof window === "undefined") return null;
-
- const handleDragEnd = (event: any, info: any) => {
- const DRAG_THRESHOLD = window?.innerWidth * 0.15;
-
- if (Math.abs(info.offset.x) > DRAG_THRESHOLD) {
- const direction = info.offset.x > 0 ? -1 : 1;
- handleNavigate(direction);
- }
- };
-
- const handleNavigate = (direction: number) => {
- setCurrentIndex((prevIndex) => {
- const newIndex = prevIndex + direction;
- if (newIndex < 0) return suggestedLearnings.length - 1;
- if (newIndex >= suggestedLearnings.length) return 0;
- return newIndex;
- });
- };
-
- if (!isLoading && (!suggestedLearnings || suggestedLearnings.length === 0)) {
- return (
-
-
-
-
-
- Your Memory Hub Awaits
-
-
- Start saving content to get bite-sized memory snippets that keep you on top of your
- game. We'll transform your notes into smart reminders that help you retain knowledge
- effortlessly.
-
-
-
-
- Add Your First Memory
-
-
-
-
-
- );
- }
-
- return (
-
-
- {isLoading
- ? // Show 3 loading cards when loading
- [...Array(3)]?.map((_, index) => {
- const xOffset = index * (window?.innerWidth < 768 ? 12 : 16);
- const yOffset = index * (window?.innerWidth < 768 ? 12 : 16);
- const opacity = Math.max(1 - index * 0.15, 0.4);
- const scale = 1 - index * (window?.innerWidth < 768 ? 0.02 : 0.03);
-
- return (
-
-
-
- );
- })
- : suggestedLearnings?.map((learning, index) => {
- const position =
- (index - currentIndex + suggestedLearnings.length) % suggestedLearnings.length;
-
- if (position >= 3) return null;
-
- if (typeof window === "undefined") return null;
-
- const contentId = Object.keys(learning)[0];
- const content = learning[contentId];
-
- const zIndex = suggestedLearnings.length - position;
- const xOffset = position * (window?.innerWidth < 768 ? 12 : 16);
- const yOffset = position * (window?.innerWidth < 768 ? 12 : 16);
- const opacity = Math.max(1 - position * 0.15, 0.4);
- const scale = 1 - position * (window?.innerWidth < 768 ? 0.02 : 0.03);
-
- return (
- = 768
- ? {
- transition: {
- duration: 0.3,
- ease: [0.4, 0, 0.2, 1],
- },
- }
- : undefined
- }
- role="group"
- aria-label={`Memory card ${index + 1} of ${suggestedLearnings.length}`}
- >
-
-
- );
- })}
-
-
- {/* Navigation controls - Hidden on mobile since we use swipe */}
- {!isLoading && suggestedLearnings.length > 0 && (
-
-
handleNavigate(-1)}
- className="p-2 rounded-full bg-gray-200 hover:bg-gray-300 dark:bg-gray-800 dark:hover:bg-gray-700"
- aria-label="Previous card"
- >
-
-
-
-
-
-
- {suggestedLearnings?.map((_, index) => (
- handleNavigate(index - currentIndex)}
- className={`w-1.5 h-1.5 rounded-full transition-colors ${
- index === currentIndex ? "bg-blue-500" : "bg-gray-300"
- } hover:bg-blue-400`}
- aria-label={`Go to card ${index + 1}`}
- />
- ))}
-
-
-
handleNavigate(1)}
- className="p-2 rounded-full bg-gray-200 hover:bg-gray-300 dark:bg-gray-800 dark:hover:bg-gray-700"
- aria-label="Next card"
- >
-
-
-
-
-
- )}
-
- {/* Mobile swipe indicator */}
- {!isLoading && suggestedLearnings.length > 0 && (
-
- Swipe to navigate β’ {currentIndex + 1}/{suggestedLearnings.length}
-
- )}
-
- );
-}
-
-export default Reminders;
diff --git a/apps/web/app/components/Suggestions.tsx b/apps/web/app/components/Suggestions.tsx
deleted file mode 100644
index 56c40eda..00000000
--- a/apps/web/app/components/Suggestions.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import React from "react";
-import { cn } from "~/lib/utils";
-import { Button } from "~/components/ui/button";
-import { CircleHelp } from "lucide-react";
-
-interface SuggestionProps {
- text: string;
- onClick: () => void;
-}
-
-const SingleSuggestion: React.FC = ({ text, onClick }) => {
- return (
-
-
- {text}
-
- );
-};
-
-interface SuggestionsProps {
- items: string[];
- onSelect: (item: string) => void;
-}
-
-const Suggestions: React.FC = ({ items, onSelect }) => {
- return (
-
- {items?.map((item, index) => (
- onSelect(item)}
- />
- ))}
-
- );
-};
-
-export default Suggestions;
diff --git a/apps/web/app/components/editor/plate-editor.tsx b/apps/web/app/components/editor/plate-editor.tsx
deleted file mode 100644
index ed9237de..00000000
--- a/apps/web/app/components/editor/plate-editor.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import { DndProvider } from "react-dnd";
-import { HTML5Backend } from "react-dnd-html5-backend";
-
-import { Plate } from "@udecode/plate-common/react";
-import { useCreateEditor } from "~/components/editor/use-create-editor";
-import { Editor, EditorContainer } from "~/components/plate-ui/editor";
-
-export function PlateEditor() {
- const editor = useCreateEditor();
-
- return (
-
-
-
-
-
-
-
- );
-}
diff --git a/apps/web/app/components/editor/plate-types.ts b/apps/web/app/components/editor/plate-types.ts
deleted file mode 100644
index 75e79cfc..00000000
--- a/apps/web/app/components/editor/plate-types.ts
+++ /dev/null
@@ -1,221 +0,0 @@
-'use client';
-
-import type React from 'react';
-
-import type { BlockquotePlugin } from '@udecode/plate-block-quote/react';
-import type {
- CodeBlockPlugin,
- CodeLinePlugin,
-} from '@udecode/plate-code-block/react';
-import type { TCommentText } from '@udecode/plate-comments';
-import type { TElement, TText } from '@udecode/plate-common';
-import type { ParagraphPlugin } from '@udecode/plate-common/react';
-import type { TExcalidrawElement } from '@udecode/plate-excalidraw';
-import type { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react';
-import type { HEADING_KEYS } from '@udecode/plate-heading';
-import type { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';
-import type { TLinkElement } from '@udecode/plate-link';
-import type { LinkPlugin } from '@udecode/plate-link/react';
-import type { TImageElement, TMediaEmbedElement } from '@udecode/plate-media';
-import type { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';
-import type {
- TMentionElement,
- TMentionInputElement,
-} from '@udecode/plate-mention';
-import type {
- MentionInputPlugin,
- MentionPlugin,
-} from '@udecode/plate-mention/react';
-import type { TTableElement } from '@udecode/plate-table';
-import type {
- TableCellPlugin,
- TablePlugin,
- TableRowPlugin,
-} from '@udecode/plate-table/react';
-import type { TToggleElement } from '@udecode/plate-toggle';
-import type { TogglePlugin } from '@udecode/plate-toggle/react';
-
-/** Text */
-
-export type EmptyText = {
- text: '';
-};
-
-export type PlainText = {
- text: string;
-};
-
-export interface RichText extends TText, TCommentText {
- backgroundColor?: React.CSSProperties['backgroundColor'];
- bold?: boolean;
- code?: boolean;
- color?: React.CSSProperties['color'];
- fontFamily?: React.CSSProperties['fontFamily'];
- fontSize?: React.CSSProperties['fontSize'];
- fontWeight?: React.CSSProperties['fontWeight'];
- italic?: boolean;
- kbd?: boolean;
- strikethrough?: boolean;
- subscript?: boolean;
- underline?: boolean;
-}
-
-/** Inline Elements */
-
-export interface MyLinkElement extends TLinkElement {
- children: RichText[];
- type: typeof LinkPlugin.key;
-}
-
-export interface MyMentionInputElement extends TMentionInputElement {
- children: [PlainText];
- type: typeof MentionInputPlugin.key;
-}
-
-export interface MyMentionElement extends TMentionElement {
- children: [EmptyText];
- type: typeof MentionPlugin.key;
-}
-
-export type MyInlineElement =
- | MyLinkElement
- | MyMentionElement
- | MyMentionInputElement;
-
-export type MyInlineDescendant = MyInlineElement | RichText;
-
-export type MyInlineChildren = MyInlineDescendant[];
-
-/** Block props */
-
-export interface MyIndentProps {
- indent?: number;
-}
-
-export interface MyIndentListProps extends MyIndentProps {
- listRestart?: number;
- listStart?: number;
- listStyleType?: string;
-}
-
-export interface MyLineHeightProps {
- lineHeight?: React.CSSProperties['lineHeight'];
-}
-
-export interface MyAlignProps {
- align?: React.CSSProperties['textAlign'];
-}
-
-export interface MyBlockElement
- extends TElement,
- MyIndentListProps,
- MyLineHeightProps {
- id?: string;
-}
-
-/** Blocks */
-
-export interface MyParagraphElement extends MyBlockElement {
- children: MyInlineChildren;
- type: typeof ParagraphPlugin.key;
-}
-
-export interface MyH1Element extends MyBlockElement {
- children: MyInlineChildren;
- type: typeof HEADING_KEYS.h1;
-}
-
-export interface MyH2Element extends MyBlockElement {
- children: MyInlineChildren;
- type: typeof HEADING_KEYS.h2;
-}
-
-export interface MyH3Element extends MyBlockElement {
- children: MyInlineChildren;
- type: typeof HEADING_KEYS.h3;
-}
-
-export interface MyBlockquoteElement extends MyBlockElement {
- children: MyInlineChildren;
- type: typeof BlockquotePlugin.key;
-}
-
-export interface MyCodeBlockElement extends MyBlockElement {
- children: MyCodeLineElement[];
- type: typeof CodeBlockPlugin.key;
-}
-
-export interface MyCodeLineElement extends TElement {
- children: PlainText[];
- type: typeof CodeLinePlugin.key;
-}
-
-export interface MyTableElement extends TTableElement, MyBlockElement {
- children: MyTableRowElement[];
- type: typeof TablePlugin.key;
-}
-
-export interface MyTableRowElement extends TElement {
- children: MyTableCellElement[];
- type: typeof TableRowPlugin.key;
-}
-
-export interface MyTableCellElement extends TElement {
- children: MyNestableBlock[];
- type: typeof TableCellPlugin.key;
-}
-
-export interface MyToggleElement extends TToggleElement, MyBlockElement {
- children: MyInlineChildren;
- type: typeof TogglePlugin.key;
-}
-
-export interface MyImageElement extends TImageElement, MyBlockElement {
- children: [EmptyText];
- type: typeof ImagePlugin.key;
-}
-
-export interface MyMediaEmbedElement
- extends TMediaEmbedElement,
- MyBlockElement {
- children: [EmptyText];
- type: typeof MediaEmbedPlugin.key;
-}
-
-export interface MyHrElement extends MyBlockElement {
- children: [EmptyText];
- type: typeof HorizontalRulePlugin.key;
-}
-
-export interface MyExcalidrawElement
- extends TExcalidrawElement,
- MyBlockElement {
- children: [EmptyText];
- type: typeof ExcalidrawPlugin.key;
-}
-
-export type MyNestableBlock = MyParagraphElement;
-
-export type MyRootBlock =
- | MyBlockquoteElement
- | MyCodeBlockElement
- | MyExcalidrawElement
- | MyH1Element
- | MyH2Element
- | MyH3Element
- | MyHrElement
- | MyImageElement
- | MyMediaEmbedElement
- | MyParagraphElement
- | MyTableElement
- | MyToggleElement;
-
-export type MyValue = MyRootBlock[];
-
-// export type MyElement = ElementOf;
-
-// export type MyBlock = Exclude;
-
-// export type MyEditor = ReturnType;
-
-// export const useEditor = () => useEditorRef();
diff --git a/apps/web/app/components/editor/plugins/ai-plugins.tsx b/apps/web/app/components/editor/plugins/ai-plugins.tsx
deleted file mode 100644
index 727e0148..00000000
--- a/apps/web/app/components/editor/plugins/ai-plugins.tsx
+++ /dev/null
@@ -1,195 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import { withProps } from '@udecode/cn';
-import { AIChatPlugin, AIPlugin } from '@udecode/plate-ai/react';
-import {
- BoldPlugin,
- CodePlugin,
- ItalicPlugin,
- StrikethroughPlugin,
- UnderlinePlugin,
-} from '@udecode/plate-basic-marks/react';
-import { BlockquotePlugin } from '@udecode/plate-block-quote/react';
-import {
- CodeBlockPlugin,
- CodeLinePlugin,
- CodeSyntaxPlugin,
-} from '@udecode/plate-code-block/react';
-import {
- ParagraphPlugin,
- PlateLeaf,
- createPlateEditor,
-} from '@udecode/plate-common/react';
-import { HEADING_KEYS } from '@udecode/plate-heading';
-import { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';
-import { LinkPlugin } from '@udecode/plate-link/react';
-import { MarkdownPlugin } from '@udecode/plate-markdown';
-import { BlockSelectionPlugin } from '@udecode/plate-selection/react';
-
-import { AIMenu } from '~/components/plate-ui/ai-menu';
-import { BlockquoteElement } from '~/components/plate-ui/blockquote-element';
-import { CodeBlockElement } from '~/components/plate-ui/code-block-element';
-import { CodeLeaf } from '~/components/plate-ui/code-leaf';
-import { CodeLineElement } from '~/components/plate-ui/code-line-element';
-import { CodeSyntaxLeaf } from '~/components/plate-ui/code-syntax-leaf';
-import { HeadingElement } from '~/components/plate-ui/heading-element';
-import { HrElement } from '~/components/plate-ui/hr-element';
-import { LinkElement } from '~/components/plate-ui/link-element';
-import { ParagraphElement } from '~/components/plate-ui/paragraph-element';
-
-import { basicNodesPlugins } from './basic-nodes-plugins';
-import { indentListPlugins } from './indent-list-plugins';
-import { linkPlugin } from './link-plugin';
-
-const createAIEditor = () => {
- const editor = createPlateEditor({
- id: 'ai',
- override: {
- components: {
- [BlockquotePlugin.key]: BlockquoteElement,
- [BoldPlugin.key]: withProps(PlateLeaf, { as: 'strong' }),
- [CodeBlockPlugin.key]: CodeBlockElement,
- [CodeLinePlugin.key]: CodeLineElement,
- [CodePlugin.key]: CodeLeaf,
- [CodeSyntaxPlugin.key]: CodeSyntaxLeaf,
- [HEADING_KEYS.h1]: withProps(HeadingElement, { variant: 'h1' }),
- [HEADING_KEYS.h2]: withProps(HeadingElement, { variant: 'h2' }),
- [HEADING_KEYS.h3]: withProps(HeadingElement, { variant: 'h3' }),
- [HorizontalRulePlugin.key]: HrElement,
- [ItalicPlugin.key]: withProps(PlateLeaf, { as: 'em' }),
- [LinkPlugin.key]: LinkElement,
- [ParagraphPlugin.key]: ParagraphElement,
- [StrikethroughPlugin.key]: withProps(PlateLeaf, { as: 's' }),
- [UnderlinePlugin.key]: withProps(PlateLeaf, { as: 'u' }),
- },
- },
- plugins: [
- ParagraphPlugin,
- ...basicNodesPlugins,
- HorizontalRulePlugin,
- linkPlugin,
- ...indentListPlugins,
- MarkdownPlugin.configure({ options: { indentList: true } }),
- // FIXME
- BlockSelectionPlugin.configure({
- api: {},
- extendEditor: null,
- options: {},
- render: {},
- useHooks: null,
- handlers: {},
- }),
- ],
- value: [{ children: [{ text: '' }], type: 'p' }],
- });
-
- return editor;
-};
-
-const systemCommon = `\
-You are an advanced AI-powered note-taking assistant, designed to enhance productivity and creativity in note management.
-Respond directly to user prompts with clear, concise, and relevant content. Maintain a neutral, helpful tone.
-
-Rules:
-- is the entire note the user is working on.
-- is a reminder of how you should reply to INSTRUCTIONS. It does not apply to questions.
-- Anything else is the user prompt.
-- Your response should be tailored to the user's prompt, providing precise assistance to optimize note management.
-- For INSTRUCTIONS: Follow the exactly. Provide ONLY the content to be inserted or replaced. No explanations or comments.
-- For QUESTIONS: Provide a helpful and concise answer. You may include brief explanations if necessary.
-- CRITICAL: Distinguish between INSTRUCTIONS and QUESTIONS. Instructions typically ask you to modify or add content. Questions ask for information or clarification.
-`;
-
-const systemDefault = `\
-${systemCommon}
-- is the current block of text the user is working on.
-- Ensure your output can seamlessly fit into the existing structure.
-- CRITICAL: Provide only a single block of text. DO NOT create multiple paragraphs or separate blocks.
-
-{block}
-
-`;
-
-const systemSelecting = `\
-${systemCommon}
-- is the block of text containing the user's selection, providing context.
-- Ensure your output can seamlessly fit into the existing structure.
-- is the specific text the user has selected in the block and wants to modify or ask about.
-- Consider the context provided by , but only modify . Your response should be a direct replacement for .
-
-{block}
-
-
-{selection}
-
-`;
-
-const systemBlockSelecting = `\
-${systemCommon}
-- represents the full blocks of text the user has selected and wants to modify or ask about.
-- Your response should be a direct replacement for the entire .
-- Maintain the overall structure and formatting of the selected blocks, unless explicitly instructed otherwise.
-- CRITICAL: Provide only the content to replace . Do not add additional blocks or change the block structure unless specifically requested.
-
-{block}
-
-`;
-
-const userDefault = `
-CRITICAL: DO NOT use block formatting. You can only use inline formatting.
-CRITICAL: DO NOT start new lines or paragraphs.
-NEVER write .
-
-{prompt}`;
-
-const userSelecting = `
-If this is a question, provide a helpful and concise answer about .
-If this is an instruction, provide ONLY the text to replace . No explanations.
-Ensure it fits seamlessly within . If is empty, write ONE random sentence.
-NEVER write or .
-
-{prompt} about `;
-
-const userBlockSelecting = `
-If this is a question, provide a helpful and concise answer about .
-If this is an instruction, provide ONLY the content to replace the entire . No explanations.
-Maintain the overall structure unless instructed otherwise.
-NEVER write or .
-
-{prompt} about `;
-
-export const PROMPT_TEMPLATES = {
- systemBlockSelecting,
- systemDefault,
- systemSelecting,
- userBlockSelecting,
- userDefault,
- userSelecting,
-};
-
-export const aiPlugins = [
- MarkdownPlugin.configure({ options: { indentList: true } }),
- AIPlugin,
- AIChatPlugin.configure({
- options: {
- createAIEditor,
- promptTemplate: ({ isBlockSelecting, isSelecting }) => {
- return isBlockSelecting
- ? PROMPT_TEMPLATES.userBlockSelecting
- : isSelecting
- ? PROMPT_TEMPLATES.userSelecting
- : PROMPT_TEMPLATES.userDefault;
- },
- systemTemplate: ({ isBlockSelecting, isSelecting }) => {
- return isBlockSelecting
- ? PROMPT_TEMPLATES.systemBlockSelecting
- : isSelecting
- ? PROMPT_TEMPLATES.systemSelecting
- : PROMPT_TEMPLATES.systemDefault;
- },
- },
- render: { afterEditable: () => },
- }),
-] as const;
diff --git a/apps/web/app/components/editor/plugins/align-plugin.ts b/apps/web/app/components/editor/plugins/align-plugin.ts
deleted file mode 100644
index 24a7e284..00000000
--- a/apps/web/app/components/editor/plugins/align-plugin.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-'use client';
-
-import { AlignPlugin } from '@udecode/plate-alignment/react';
-import { ParagraphPlugin } from '@udecode/plate-common/react';
-import { HEADING_LEVELS } from '@udecode/plate-heading';
-import { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';
-
-export const alignPlugin = AlignPlugin.extend({
- inject: {
- targetPlugins: [
- ParagraphPlugin.key,
- ...HEADING_LEVELS,
- MediaEmbedPlugin.key,
- ImagePlugin.key,
- ],
- },
-});
diff --git a/apps/web/app/components/editor/plugins/autoformat-plugin.ts b/apps/web/app/components/editor/plugins/autoformat-plugin.ts
deleted file mode 100644
index ca80d06a..00000000
--- a/apps/web/app/components/editor/plugins/autoformat-plugin.ts
+++ /dev/null
@@ -1,273 +0,0 @@
-'use client';
-
-import type { AutoformatRule } from '@udecode/plate-autoformat';
-import type { SlateEditor } from '@udecode/plate-common';
-
-import {
- autoformatArrow,
- autoformatLegal,
- autoformatLegalHtml,
- autoformatMath,
- autoformatPunctuation,
- autoformatSmartQuotes,
-} from '@udecode/plate-autoformat';
-import { AutoformatPlugin } from '@udecode/plate-autoformat/react';
-import {
- BoldPlugin,
- CodePlugin,
- ItalicPlugin,
- StrikethroughPlugin,
- SubscriptPlugin,
- SuperscriptPlugin,
- UnderlinePlugin,
-} from '@udecode/plate-basic-marks/react';
-import { BlockquotePlugin } from '@udecode/plate-block-quote/react';
-import { insertEmptyCodeBlock } from '@udecode/plate-code-block';
-import {
- CodeBlockPlugin,
- CodeLinePlugin,
-} from '@udecode/plate-code-block/react';
-import {
- getParentNode,
- insertNodes,
- isElement,
- isType,
- setNodes,
-} from '@udecode/plate-common';
-import { ParagraphPlugin } from '@udecode/plate-common/react';
-import { HEADING_KEYS } from '@udecode/plate-heading';
-import { HighlightPlugin } from '@udecode/plate-highlight/react';
-import { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';
-import {
- INDENT_LIST_KEYS,
- ListStyleType,
- toggleIndentList,
-} from '@udecode/plate-indent-list';
-import { TogglePlugin, openNextToggles } from '@udecode/plate-toggle/react';
-
-export const format = (editor: SlateEditor, customFormatting: any) => {
- if (editor.selection) {
- const parentEntry = getParentNode(editor, editor.selection);
-
- if (!parentEntry) return;
-
- const [node] = parentEntry;
-
- if (
- isElement(node) &&
- !isType(editor, node, CodeBlockPlugin.key) &&
- !isType(editor, node, CodeLinePlugin.key)
- ) {
- customFormatting();
- }
- }
-};
-
-export const autoformatMarks: AutoformatRule[] = [
- {
- match: '***',
- mode: 'mark',
- type: [BoldPlugin.key, ItalicPlugin.key],
- },
- {
- match: '__*',
- mode: 'mark',
- type: [UnderlinePlugin.key, ItalicPlugin.key],
- },
- {
- match: '__**',
- mode: 'mark',
- type: [UnderlinePlugin.key, BoldPlugin.key],
- },
- {
- match: '___***',
- mode: 'mark',
- type: [UnderlinePlugin.key, BoldPlugin.key, ItalicPlugin.key],
- },
- {
- match: '**',
- mode: 'mark',
- type: BoldPlugin.key,
- },
- {
- match: '__',
- mode: 'mark',
- type: UnderlinePlugin.key,
- },
- {
- match: '*',
- mode: 'mark',
- type: ItalicPlugin.key,
- },
- {
- match: '_',
- mode: 'mark',
- type: ItalicPlugin.key,
- },
- {
- match: '~~',
- mode: 'mark',
- type: StrikethroughPlugin.key,
- },
- {
- match: '^',
- mode: 'mark',
- type: SuperscriptPlugin.key,
- },
- {
- match: '~',
- mode: 'mark',
- type: SubscriptPlugin.key,
- },
- {
- match: '==',
- mode: 'mark',
- type: HighlightPlugin.key,
- },
- {
- match: 'β‘',
- mode: 'mark',
- type: HighlightPlugin.key,
- },
- {
- match: '`',
- mode: 'mark',
- type: CodePlugin.key,
- },
-];
-
-export const autoformatBlocks: AutoformatRule[] = [
- {
- match: '# ',
- mode: 'block',
- type: HEADING_KEYS.h1,
- },
- {
- match: '## ',
- mode: 'block',
- type: HEADING_KEYS.h2,
- },
- {
- match: '### ',
- mode: 'block',
- type: HEADING_KEYS.h3,
- },
- {
- match: '#### ',
- mode: 'block',
- type: HEADING_KEYS.h4,
- },
- {
- match: '##### ',
- mode: 'block',
- type: HEADING_KEYS.h5,
- },
- {
- match: '###### ',
- mode: 'block',
- type: HEADING_KEYS.h6,
- },
- {
- match: '> ',
- mode: 'block',
- type: BlockquotePlugin.key,
- },
- {
- format: (editor) => {
- insertEmptyCodeBlock(editor, {
- defaultType: ParagraphPlugin.key,
- insertNodesOptions: { select: true },
- });
- },
- match: '```',
- mode: 'block',
- triggerAtBlockStart: false,
- type: CodeBlockPlugin.key,
- },
- {
- match: '+ ',
- mode: 'block',
- preFormat: openNextToggles,
- type: TogglePlugin.key,
- },
- {
- format: (editor) => {
- setNodes(editor, { type: HorizontalRulePlugin.key });
- insertNodes(editor, {
- children: [{ text: '' }],
- type: ParagraphPlugin.key,
- });
- },
- match: ['---', 'β-', '___ '],
- mode: 'block',
- type: HorizontalRulePlugin.key,
- },
-];
-
-export const autoformatIndentLists: AutoformatRule[] = [
- {
- format: (editor) => {
- toggleIndentList(editor, {
- listStyleType: ListStyleType.Disc,
- });
- },
- match: ['* ', '- '],
- mode: 'block',
- type: 'list',
- },
- {
- format: (editor) =>
- toggleIndentList(editor, {
- listStyleType: ListStyleType.Decimal,
- }),
- match: [String.raw`^\d+\.$ `, String.raw`^\d+\)$ `],
- matchByRegex: true,
- mode: 'block',
- type: 'list',
- },
- {
- format: (editor) => {
- toggleIndentList(editor, {
- listStyleType: INDENT_LIST_KEYS.todo,
- });
- setNodes(editor, {
- checked: false,
- listStyleType: INDENT_LIST_KEYS.todo,
- });
- },
- match: ['[] '],
- mode: 'block',
- type: 'list',
- },
- {
- format: (editor) => {
- toggleIndentList(editor, {
- listStyleType: INDENT_LIST_KEYS.todo,
- });
- setNodes(editor, {
- checked: true,
- listStyleType: INDENT_LIST_KEYS.todo,
- });
- },
- match: ['[x] '],
- mode: 'block',
- type: 'list',
- },
-];
-
-export const autoformatPlugin = AutoformatPlugin.configure({
- options: {
- enableUndoOnDelete: true,
- rules: [
- ...autoformatBlocks,
- ...autoformatMarks,
- ...autoformatSmartQuotes,
- ...autoformatPunctuation,
- ...autoformatLegal,
- ...autoformatLegalHtml,
- ...autoformatArrow,
- ...autoformatMath,
- ...autoformatIndentLists,
- ],
- },
-});
diff --git a/apps/web/app/components/editor/plugins/basic-nodes-plugins.tsx b/apps/web/app/components/editor/plugins/basic-nodes-plugins.tsx
deleted file mode 100644
index e336e24f..00000000
--- a/apps/web/app/components/editor/plugins/basic-nodes-plugins.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-'use client';
-
-import { BasicMarksPlugin } from '@udecode/plate-basic-marks/react';
-import { BlockquotePlugin } from '@udecode/plate-block-quote/react';
-import { CodeBlockPlugin } from '@udecode/plate-code-block/react';
-import { HeadingPlugin } from '@udecode/plate-heading/react';
-import Prism from 'prismjs';
-
-export const basicNodesPlugins = [
- HeadingPlugin.configure({ options: { levels: 3 } }),
- BlockquotePlugin,
- CodeBlockPlugin.configure({ options: { prism: Prism } }),
- BasicMarksPlugin,
-] as const;
diff --git a/apps/web/app/components/editor/plugins/block-menu-plugins.ts b/apps/web/app/components/editor/plugins/block-menu-plugins.ts
deleted file mode 100644
index 7bf0320b..00000000
--- a/apps/web/app/components/editor/plugins/block-menu-plugins.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-'use client';
-
-import { BlockMenuPlugin } from '@udecode/plate-selection/react';
-
-import { BlockContextMenu } from '~/components/plate-ui/block-context-menu';
-
-import { blockSelectionPlugins } from './block-selection-plugins';
-
-export const blockMenuPlugins = [
- ...blockSelectionPlugins,
- BlockMenuPlugin.configure({
- render: { aboveEditable: BlockContextMenu },
- }),
-] as const;
diff --git a/apps/web/app/components/editor/plugins/block-selection-plugins.ts b/apps/web/app/components/editor/plugins/block-selection-plugins.ts
deleted file mode 100644
index ab35e38f..00000000
--- a/apps/web/app/components/editor/plugins/block-selection-plugins.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-'use client';
-
-import { BlockSelectionPlugin } from '@udecode/plate-selection/react';
-
-export const blockSelectionPlugins = [
- BlockSelectionPlugin.configure({
- inject: {
- excludeBelowPlugins: ['tr'],
- excludePlugins: ['table', 'code_line', 'column_group', 'column'],
- },
- options: {
- areaOptions: {
- behaviour: {
- scrolling: {
- speedDivider: 1.5,
- },
- startThreshold: 4,
- },
- },
- enableContextMenu: true,
- },
- }),
-] as const;
diff --git a/apps/web/app/components/editor/plugins/comments-plugin.tsx b/apps/web/app/components/editor/plugins/comments-plugin.tsx
deleted file mode 100644
index 6292eed9..00000000
--- a/apps/web/app/components/editor/plugins/comments-plugin.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-'use client';
-
-import { CommentsPlugin } from '@udecode/plate-comments/react';
-
-import { CommentsPopover } from '~/components/plate-ui/comments-popover';
-
-export const commentsPlugin = CommentsPlugin.configure({
- options: {
- myUserId: '1',
- users: {
- 1: {
- id: '1',
- avatarUrl: 'https://avatars.githubusercontent.com/u/19695832?s=96&v=4',
- name: 'zbeyens',
- },
- 2: {
- id: '2',
- avatarUrl: 'https://avatars.githubusercontent.com/u/4272090?v=4',
- name: '12joan',
- },
- },
- },
- render: { afterEditable: () => },
-});
diff --git a/apps/web/app/components/editor/plugins/copilot-plugins.ts b/apps/web/app/components/editor/plugins/copilot-plugins.ts
deleted file mode 100644
index 6fa41dcc..00000000
--- a/apps/web/app/components/editor/plugins/copilot-plugins.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-'use client';
-
-import type { TElement } from '@udecode/plate-common';
-
-import { faker } from '@faker-js/faker';
-import { CopilotPlugin } from '@udecode/plate-ai/react';
-import { getAncestorNode } from '@udecode/plate-common';
-import { serializeMdNodes, stripMarkdown } from '@udecode/plate-markdown';
-
-import { GhostText } from '~/components/plate-ui/ghost-text';
-
-export const copilotPlugins = [
- CopilotPlugin.configure(({ api }) => ({
- options: {
- completeOptions: {
- api: '/api/ai/copilot',
- body: {
- system: `You are an advanced AI writing assistant, similar to VSCode Copilot but for general text. Your task is to predict and generate the next part of the text based on the given context.
-
- Rules:
- - Continue the text naturally up to the next punctuation mark (., ,, ;, :, ?, or !).
- - Maintain style and tone. Don't repeat given text.
- - For unclear context, provide the most likely continuation.
- - Handle code snippets, lists, or structured text if needed.
- - Don't include """ in your response.
- - CRITICAL: Always end with a punctuation mark.
- - CRITICAL: Avoid starting a new block. Do not use block formatting like >, #, 1., 2., -, etc. The suggestion should continue in the same block as the context.
- - If no context is provided or you can't generate a continuation, return "0" without explanation.`,
- },
- onError: () => {
- // Mock the API response. Remove it when you implement the route /api/ai/copilot
- api.copilot.setBlockSuggestion({
- text: stripMarkdown(faker.lorem.sentence()),
- });
- },
- onFinish: (_, completion) => {
- if (completion === '0') return;
-
- api.copilot.setBlockSuggestion({
- text: stripMarkdown(completion),
- });
- },
- },
- debounceDelay: 500,
- getPrompt: ({ editor }) => {
- const contextEntry = getAncestorNode(editor);
-
- if (!contextEntry) return '';
-
- const prompt = serializeMdNodes([contextEntry[0] as TElement]);
-
- return `Continue the text up to the next punctuation mark:
- """
- ${prompt}
- """`;
- },
- renderGhostText: GhostText,
- },
- })),
-] as const;
diff --git a/apps/web/app/components/editor/plugins/delete-plugins.ts b/apps/web/app/components/editor/plugins/delete-plugins.ts
deleted file mode 100644
index 947137bc..00000000
--- a/apps/web/app/components/editor/plugins/delete-plugins.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-'use client';
-
-import { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';
-import { ImagePlugin, MediaEmbedPlugin } from '@udecode/plate-media/react';
-import { DeletePlugin, SelectOnBackspacePlugin } from '@udecode/plate-select';
-
-export const deletePlugins = [
- SelectOnBackspacePlugin.configure({
- options: {
- query: {
- allow: [
- ImagePlugin.key,
- MediaEmbedPlugin.key,
- HorizontalRulePlugin.key,
- ],
- },
- },
- }),
- DeletePlugin,
-] as const;
diff --git a/apps/web/app/components/editor/plugins/dnd-plugins.tsx b/apps/web/app/components/editor/plugins/dnd-plugins.tsx
deleted file mode 100644
index 6b0db41b..00000000
--- a/apps/web/app/components/editor/plugins/dnd-plugins.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-'use client';
-
-import { DndPlugin } from '@udecode/plate-dnd';
-import { ImagePlugin } from '@udecode/plate-media/react';
-import { NodeIdPlugin } from '@udecode/plate-node-id';
-
-export const dndPlugins = [
- NodeIdPlugin,
- DndPlugin.configure({
- options: {
- enableScroller: true,
- onDropFiles: ({ dragItem, editor, target }) => {
- editor
- .getTransforms(ImagePlugin)
- .insert.imageFromFiles(dragItem.files, {
- at: target,
- nextBlock: false,
- });
- },
- },
- }),
-] as const;
diff --git a/apps/web/app/components/editor/plugins/editor-plugins.tsx b/apps/web/app/components/editor/plugins/editor-plugins.tsx
deleted file mode 100644
index fa24ba7a..00000000
--- a/apps/web/app/components/editor/plugins/editor-plugins.tsx
+++ /dev/null
@@ -1,100 +0,0 @@
-'use client';
-
-import { CalloutPlugin } from '@udecode/plate-callout/react';
-import { ParagraphPlugin } from '@udecode/plate-common/react';
-import { DatePlugin } from '@udecode/plate-date/react';
-import { DocxPlugin } from '@udecode/plate-docx';
-import {
- FontBackgroundColorPlugin,
- FontColorPlugin,
- FontSizePlugin,
-} from '@udecode/plate-font/react';
-import { HighlightPlugin } from '@udecode/plate-highlight/react';
-import { HorizontalRulePlugin } from '@udecode/plate-horizontal-rule/react';
-import { JuicePlugin } from '@udecode/plate-juice';
-import { KbdPlugin } from '@udecode/plate-kbd/react';
-import { ColumnPlugin } from '@udecode/plate-layout/react';
-import { MarkdownPlugin } from '@udecode/plate-markdown';
-import {
- EquationPlugin,
- InlineEquationPlugin,
-} from '@udecode/plate-math/react';
-import { CursorOverlayPlugin } from '@udecode/plate-selection/react';
-import { SlashPlugin } from '@udecode/plate-slash-command/react';
-import { TogglePlugin } from '@udecode/plate-toggle/react';
-import { TrailingBlockPlugin } from '@udecode/plate-trailing-block';
-
-import { CursorOverlay } from '~/components/plate-ui/cursor-overlay';
-
-import { aiPlugins } from './ai-plugins';
-import { alignPlugin } from './align-plugin';
-import { autoformatPlugin } from './autoformat-plugin';
-import { basicNodesPlugins } from './basic-nodes-plugins';
-import { blockMenuPlugins } from './block-menu-plugins';
-import { commentsPlugin } from './comments-plugin';
-import { deletePlugins } from './delete-plugins';
-import { dndPlugins } from './dnd-plugins';
-import { exitBreakPlugin } from './exit-break-plugin';
-import { indentListPlugins } from './indent-list-plugins';
-import { lineHeightPlugin } from './line-height-plugin';
-import { linkPlugin } from './link-plugin';
-import { mediaPlugins } from './media-plugins';
-import { mentionPlugin } from './mention-plugin';
-import { resetBlockTypePlugin } from './reset-block-type-plugin';
-import { softBreakPlugin } from './soft-break-plugin';
-import { tablePlugin } from './table-plugin';
-import { tocPlugin } from './toc-plugin';
-
-export const editorPlugins = [
- // AI
- ...aiPlugins,
-
- // Nodes
- ...basicNodesPlugins,
- HorizontalRulePlugin,
- linkPlugin,
- DatePlugin,
- mentionPlugin,
- SlashPlugin,
- tablePlugin,
- TogglePlugin,
- tocPlugin,
- ...mediaPlugins,
- InlineEquationPlugin,
- EquationPlugin,
- CalloutPlugin,
- ColumnPlugin,
-
- // Marks
- FontColorPlugin,
- FontBackgroundColorPlugin,
- FontSizePlugin,
- HighlightPlugin,
- KbdPlugin,
-
- // Block Style
- alignPlugin,
- ...indentListPlugins,
- lineHeightPlugin,
-
- // Functionality
- autoformatPlugin,
- CursorOverlayPlugin.configure({
- render: { afterEditable: () => },
- }),
- ...blockMenuPlugins,
- ...dndPlugins,
- exitBreakPlugin,
- resetBlockTypePlugin,
- ...deletePlugins,
- softBreakPlugin,
- TrailingBlockPlugin.configure({ options: { type: ParagraphPlugin.key } }),
-
- // Collaboration
- commentsPlugin,
-
- // Deserialization
- DocxPlugin,
- MarkdownPlugin.configure({ options: { indentList: true } }),
- JuicePlugin,
-];
diff --git a/apps/web/app/components/editor/plugins/exit-break-plugin.ts b/apps/web/app/components/editor/plugins/exit-break-plugin.ts
deleted file mode 100644
index 038a92b3..00000000
--- a/apps/web/app/components/editor/plugins/exit-break-plugin.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-'use client';
-
-import { ExitBreakPlugin } from '@udecode/plate-break/react';
-import { HEADING_LEVELS } from '@udecode/plate-heading';
-
-export const exitBreakPlugin = ExitBreakPlugin.configure({
- options: {
- rules: [
- {
- hotkey: 'mod+enter',
- },
- {
- before: true,
- hotkey: 'mod+shift+enter',
- },
- {
- hotkey: 'enter',
- level: 1,
- query: {
- allow: HEADING_LEVELS,
- end: true,
- start: true,
- },
- relative: true,
- },
- ],
- },
-});
diff --git a/apps/web/app/components/editor/plugins/fixed-toolbar-plugin.tsx b/apps/web/app/components/editor/plugins/fixed-toolbar-plugin.tsx
deleted file mode 100644
index b77d6c75..00000000
--- a/apps/web/app/components/editor/plugins/fixed-toolbar-plugin.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-'use client';
-
-import { createPlatePlugin } from '@udecode/plate-common/react';
-
-import { FixedToolbar } from '~/components/plate-ui/fixed-toolbar';
-import { FixedToolbarButtons } from '~/components/plate-ui/fixed-toolbar-buttons';
-
-export const FixedToolbarPlugin = createPlatePlugin({
- key: 'fixed-toolbar',
- render: {
- beforeEditable: () => (
-
-
-
- ),
- },
-});
diff --git a/apps/web/app/components/editor/plugins/floating-toolbar-plugin.tsx b/apps/web/app/components/editor/plugins/floating-toolbar-plugin.tsx
deleted file mode 100644
index aa200eaa..00000000
--- a/apps/web/app/components/editor/plugins/floating-toolbar-plugin.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-'use client';
-
-import { createPlatePlugin } from '@udecode/plate-common/react';
-
-import { FloatingToolbar } from '~/components/plate-ui/floating-toolbar';
-import { FloatingToolbarButtons } from '~/components/plate-ui/floating-toolbar-buttons';
-
-export const FloatingToolbarPlugin = createPlatePlugin({
- key: 'floating-toolbar',
- render: {
- afterEditable: () => (
-
-
-
- ),
- },
-});
diff --git a/apps/web/app/components/editor/plugins/indent-list-plugins.ts b/apps/web/app/components/editor/plugins/indent-list-plugins.ts
deleted file mode 100644
index b4b5ebbc..00000000
--- a/apps/web/app/components/editor/plugins/indent-list-plugins.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-'use client';
-
-import { BlockquotePlugin } from '@udecode/plate-block-quote/react';
-import { CodeBlockPlugin } from '@udecode/plate-code-block/react';
-import { ParagraphPlugin } from '@udecode/plate-common/react';
-import { HEADING_LEVELS } from '@udecode/plate-heading';
-import { IndentPlugin } from '@udecode/plate-indent/react';
-import { IndentListPlugin } from '@udecode/plate-indent-list/react';
-import { TogglePlugin } from '@udecode/plate-toggle/react';
-
-import {
- FireLiComponent,
- FireMarker,
-} from '~/components/plate-ui/indent-fire-marker';
-import {
- TodoLi,
- TodoMarker,
-} from '~/components/plate-ui/indent-todo-marker';
-
-export const indentListPlugins = [
- IndentPlugin.extend({
- inject: {
- targetPlugins: [
- ParagraphPlugin.key,
- ...HEADING_LEVELS,
- BlockquotePlugin.key,
- CodeBlockPlugin.key,
- TogglePlugin.key,
- ],
- },
- }),
- IndentListPlugin.extend({
- inject: {
- targetPlugins: [
- ParagraphPlugin.key,
- ...HEADING_LEVELS,
- BlockquotePlugin.key,
- CodeBlockPlugin.key,
- TogglePlugin.key,
- ],
- },
- options: {
- listStyleTypes: {
- fire: {
- liComponent: FireLiComponent,
- markerComponent: FireMarker,
- type: 'fire',
- },
- todo: {
- liComponent: TodoLi,
- markerComponent: TodoMarker,
- type: 'todo',
- },
- },
- },
- }),
-];
diff --git a/apps/web/app/components/editor/plugins/line-height-plugin.ts b/apps/web/app/components/editor/plugins/line-height-plugin.ts
deleted file mode 100644
index 3639cabe..00000000
--- a/apps/web/app/components/editor/plugins/line-height-plugin.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-'use client';
-
-import { ParagraphPlugin } from '@udecode/plate-common/react';
-import { HEADING_LEVELS } from '@udecode/plate-heading';
-import { LineHeightPlugin } from '@udecode/plate-line-height/react';
-
-export const lineHeightPlugin = LineHeightPlugin.configure({
- inject: {
- nodeProps: {
- defaultNodeValue: 1.5,
- validNodeValues: [1, 1.2, 1.5, 2, 3],
- },
- targetPlugins: [ParagraphPlugin.key, ...HEADING_LEVELS],
- },
-});
diff --git a/apps/web/app/components/editor/plugins/link-plugin.tsx b/apps/web/app/components/editor/plugins/link-plugin.tsx
deleted file mode 100644
index 435b6e10..00000000
--- a/apps/web/app/components/editor/plugins/link-plugin.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-'use client';
-
-import { LinkPlugin } from '@udecode/plate-link/react';
-
-import { LinkFloatingToolbar } from '~/components/plate-ui/link-floating-toolbar';
-
-export const linkPlugin = LinkPlugin.extend({
- render: { afterEditable: () => },
-});
diff --git a/apps/web/app/components/editor/plugins/media-plugins.tsx b/apps/web/app/components/editor/plugins/media-plugins.tsx
deleted file mode 100644
index 03c1930e..00000000
--- a/apps/web/app/components/editor/plugins/media-plugins.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-'use client';
-
-import { CaptionPlugin } from '@udecode/plate-caption/react';
-import {
- AudioPlugin,
- FilePlugin,
- ImagePlugin,
- MediaEmbedPlugin,
- PlaceholderPlugin,
- VideoPlugin,
-} from '@udecode/plate-media/react';
-
-import { ImagePreview } from '~/components/plate-ui/image-preview';
-
-export const mediaPlugins = [
- PlaceholderPlugin,
- ImagePlugin.extend({
- options: {
- disableUploadInsert: true,
- },
- render: { afterEditable: ImagePreview },
- }),
- MediaEmbedPlugin,
- VideoPlugin,
- AudioPlugin,
- FilePlugin,
- CaptionPlugin.configure({
- options: { plugins: [ImagePlugin, MediaEmbedPlugin] },
- }),
-] as const;
diff --git a/apps/web/app/components/editor/plugins/mention-plugin.ts b/apps/web/app/components/editor/plugins/mention-plugin.ts
deleted file mode 100644
index 0b7421fd..00000000
--- a/apps/web/app/components/editor/plugins/mention-plugin.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-'use client';
-
-import { MentionPlugin } from '@udecode/plate-mention/react';
-
-export const mentionPlugin = MentionPlugin.configure({
- options: { triggerPreviousCharPattern: /^$|^[\s"']$/ },
-});
diff --git a/apps/web/app/components/editor/plugins/reset-block-type-plugin.ts b/apps/web/app/components/editor/plugins/reset-block-type-plugin.ts
deleted file mode 100644
index 61973e92..00000000
--- a/apps/web/app/components/editor/plugins/reset-block-type-plugin.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-'use client';
-
-import { BlockquotePlugin } from '@udecode/plate-block-quote/react';
-import { CalloutPlugin } from '@udecode/plate-callout/react';
-import {
- isCodeBlockEmpty,
- isSelectionAtCodeBlockStart,
- unwrapCodeBlock,
-} from '@udecode/plate-code-block';
-import { CodeBlockPlugin } from '@udecode/plate-code-block/react';
-import {
- isBlockAboveEmpty,
- isSelectionAtBlockStart,
-} from '@udecode/plate-common';
-import { ParagraphPlugin } from '@udecode/plate-common/react';
-import { HEADING_LEVELS } from '@udecode/plate-heading';
-import { INDENT_LIST_KEYS, ListStyleType } from '@udecode/plate-indent-list';
-import { ResetNodePlugin } from '@udecode/plate-reset-node/react';
-
-const resetBlockTypesCommonRule = {
- defaultType: ParagraphPlugin.key,
- types: [
- ...HEADING_LEVELS,
- BlockquotePlugin.key,
- INDENT_LIST_KEYS.todo,
- ListStyleType.Disc,
- ListStyleType.Decimal,
- CalloutPlugin.key,
- ],
-};
-
-const resetBlockTypesCodeBlockRule = {
- defaultType: ParagraphPlugin.key,
- types: [CodeBlockPlugin.key],
- onReset: unwrapCodeBlock,
-};
-
-export const resetBlockTypePlugin = ResetNodePlugin.configure({
- options: {
- rules: [
- {
- ...resetBlockTypesCommonRule,
- hotkey: 'Enter',
- predicate: isBlockAboveEmpty,
- },
- {
- ...resetBlockTypesCommonRule,
- hotkey: 'Backspace',
- predicate: isSelectionAtBlockStart,
- },
- {
- ...resetBlockTypesCodeBlockRule,
- hotkey: 'Enter',
- predicate: isCodeBlockEmpty,
- },
- {
- ...resetBlockTypesCodeBlockRule,
- hotkey: 'Backspace',
- predicate: isSelectionAtCodeBlockStart,
- },
- ],
- },
-});
diff --git a/apps/web/app/components/editor/plugins/soft-break-plugin.ts b/apps/web/app/components/editor/plugins/soft-break-plugin.ts
deleted file mode 100644
index a5ed0d45..00000000
--- a/apps/web/app/components/editor/plugins/soft-break-plugin.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-'use client';
-
-import { BlockquotePlugin } from '@udecode/plate-block-quote/react';
-import { SoftBreakPlugin } from '@udecode/plate-break/react';
-import { CalloutPlugin } from '@udecode/plate-callout/react';
-import { CodeBlockPlugin } from '@udecode/plate-code-block/react';
-import {
- TableCellHeaderPlugin,
- TableCellPlugin,
-} from '@udecode/plate-table/react';
-
-export const softBreakPlugin = SoftBreakPlugin.configure({
- options: {
- rules: [
- { hotkey: 'shift+enter' },
- {
- hotkey: 'enter',
- query: {
- allow: [
- CodeBlockPlugin.key,
- BlockquotePlugin.key,
- TableCellPlugin.key,
- TableCellHeaderPlugin.key,
- CalloutPlugin.key,
- ],
- },
- },
- ],
- },
-});
diff --git a/apps/web/app/components/editor/plugins/table-plugin.ts b/apps/web/app/components/editor/plugins/table-plugin.ts
deleted file mode 100644
index 82f65ffa..00000000
--- a/apps/web/app/components/editor/plugins/table-plugin.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-'use client';
-
-import { TablePlugin } from '@udecode/plate-table/react';
-
-export const tablePlugin = TablePlugin.configure({
- options: {
- enableMerging: true,
- },
-});
diff --git a/apps/web/app/components/editor/plugins/toc-plugin.ts b/apps/web/app/components/editor/plugins/toc-plugin.ts
deleted file mode 100644
index 0fd7d1f0..00000000
--- a/apps/web/app/components/editor/plugins/toc-plugin.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-'use client';
-
-import { TocPlugin } from '@udecode/plate-heading/react';
-
-export const tocPlugin = TocPlugin.configure({
- options: {
- // isScroll: true,
- topOffset: 80,
- },
-});
diff --git a/apps/web/app/components/editor/transforms.ts b/apps/web/app/components/editor/transforms.ts
deleted file mode 100644
index 7bd776c3..00000000
--- a/apps/web/app/components/editor/transforms.ts
+++ /dev/null
@@ -1,206 +0,0 @@
-'use client';
-
-import type { PlateEditor } from '@udecode/plate-common/react';
-
-import { insertCallout } from '@udecode/plate-callout';
-import { CalloutPlugin } from '@udecode/plate-callout/react';
-import { insertCodeBlock } from '@udecode/plate-code-block';
-import { CodeBlockPlugin } from '@udecode/plate-code-block/react';
-import {
- type TElement,
- type TNodeEntry,
- getBlockAbove,
- getBlocks,
- getNodeEntry,
- insertNodes,
- removeEmptyPreviousBlock,
- setNodes,
- unsetNodes,
- withoutNormalizing,
-} from '@udecode/plate-common';
-import { insertDate } from '@udecode/plate-date';
-import { DatePlugin } from '@udecode/plate-date/react';
-import { insertToc } from '@udecode/plate-heading';
-import { TocPlugin } from '@udecode/plate-heading/react';
-import { INDENT_LIST_KEYS, ListStyleType } from '@udecode/plate-indent-list';
-import { IndentListPlugin } from '@udecode/plate-indent-list/react';
-import { insertColumnGroup, toggleColumnGroup } from '@udecode/plate-layout';
-import { LinkPlugin, triggerFloatingLink } from '@udecode/plate-link/react';
-import { insertEquation, insertInlineEquation } from '@udecode/plate-math';
-import {
- EquationPlugin,
- InlineEquationPlugin,
-} from '@udecode/plate-math/react';
-import {
- insertAudioPlaceholder,
- insertFilePlaceholder,
- insertMedia,
- insertVideoPlaceholder,
-} from '@udecode/plate-media';
-import {
- AudioPlugin,
- FilePlugin,
- ImagePlugin,
- MediaEmbedPlugin,
- VideoPlugin,
-} from '@udecode/plate-media/react';
-import { TablePlugin, insertTable } from '@udecode/plate-table/react';
-import { Path } from 'slate';
-
-const ACTION_THREE_COLUMNS = 'action_three_columns';
-
-const insertList = (editor: PlateEditor, type: string) => {
- insertNodes(
- editor,
- editor.api.create.block({
- indent: 1,
- listStyleType: type,
- }),
- { select: true }
- );
-};
-
-const insertBlockMap: Record<
- string,
- (editor: PlateEditor, type: string) => void
-> = {
- [ACTION_THREE_COLUMNS]: (editor) =>
- insertColumnGroup(editor, { layout: 3, select: true }),
- [AudioPlugin.key]: (editor) =>
- insertAudioPlaceholder(editor, { select: true }),
- [CalloutPlugin.key]: (editor) => insertCallout(editor, { select: true }),
- [CodeBlockPlugin.key]: (editor) => insertCodeBlock(editor, { select: true }),
- [EquationPlugin.key]: (editor) => insertEquation(editor, { select: true }),
- [FilePlugin.key]: (editor) => insertFilePlaceholder(editor, { select: true }),
- [INDENT_LIST_KEYS.todo]: insertList,
- [ImagePlugin.key]: (editor) =>
- insertMedia(editor, {
- select: true,
- type: ImagePlugin.key,
- }),
- [ListStyleType.Decimal]: insertList,
- [ListStyleType.Disc]: insertList,
- [MediaEmbedPlugin.key]: (editor) =>
- insertMedia(editor, {
- select: true,
- type: MediaEmbedPlugin.key,
- }),
- [TablePlugin.key]: (editor) => insertTable(editor, {}, { select: true }),
- [TocPlugin.key]: (editor) => insertToc(editor, { select: true }),
- [VideoPlugin.key]: (editor) =>
- insertVideoPlaceholder(editor, { select: true }),
-};
-
-const insertInlineMap: Record<
- string,
- (editor: PlateEditor, type: string) => void
-> = {
- [DatePlugin.key]: (editor) => insertDate(editor, { select: true }),
- [InlineEquationPlugin.key]: (editor) =>
- insertInlineEquation(editor, '', { select: true }),
- [LinkPlugin.key]: (editor) => triggerFloatingLink(editor, { focused: true }),
-};
-
-export const insertBlock = (editor: PlateEditor, type: string) => {
- withoutNormalizing(editor, () => {
- if (type in insertBlockMap) {
- insertBlockMap[type](editor, type);
- } else {
- const path = getBlockAbove(editor)?.[1];
-
- if (!path) return;
-
- const at = Path.next(path);
-
- insertNodes(editor, editor.api.create.block({ type }), {
- at,
- select: true,
- });
- }
-
- removeEmptyPreviousBlock(editor);
- });
-};
-
-export const insertInlineElement = (editor: PlateEditor, type: string) => {
- if (insertInlineMap[type]) {
- insertInlineMap[type](editor, type);
- }
-};
-
-const setList = (
- editor: PlateEditor,
- type: string,
- entry: TNodeEntry
-) => {
- setNodes(
- editor,
- editor.api.create.block({
- indent: 1,
- listStyleType: type,
- }),
- {
- at: entry[1],
- }
- );
-};
-
-const setBlockMap: Record<
- string,
- (editor: PlateEditor, type: string, entry: TNodeEntry) => void
-> = {
- [ACTION_THREE_COLUMNS]: (editor) => toggleColumnGroup(editor, { layout: 3 }),
- [INDENT_LIST_KEYS.todo]: setList,
- [ListStyleType.Decimal]: setList,
- [ListStyleType.Disc]: setList,
-};
-
-export const setBlockType = (
- editor: PlateEditor,
- type: string,
- { at }: { at?: Path } = {}
-) => {
- withoutNormalizing(editor, () => {
- const setEntry = (entry: TNodeEntry) => {
- const [node, path] = entry;
-
- if (node[IndentListPlugin.key]) {
- unsetNodes(editor, [IndentListPlugin.key, 'indent'], { at: path });
- }
- if (type in setBlockMap) {
- return setBlockMap[type](editor, type, entry);
- }
- if (node.type !== type) {
- editor.setNodes({ type }, { at: path });
- }
- };
-
- if (at) {
- const entry = getNodeEntry(editor, at);
-
- if (entry) {
- setEntry(entry);
-
- return;
- }
- }
-
- const entries = getBlocks(editor);
-
- entries.forEach((entry) => setEntry(entry));
- });
-};
-
-export const getBlockType = (block: TElement) => {
- if (block[IndentListPlugin.key]) {
- if (block[IndentListPlugin.key] === ListStyleType.Decimal) {
- return ListStyleType.Decimal;
- } else if (block[IndentListPlugin.key] === INDENT_LIST_KEYS.todo) {
- return INDENT_LIST_KEYS.todo;
- } else {
- return ListStyleType.Disc;
- }
- }
-
- return block.type;
-};
diff --git a/apps/web/app/components/editor/use-chat.tsx b/apps/web/app/components/editor/use-chat.tsx
deleted file mode 100644
index 11b6ee6e..00000000
--- a/apps/web/app/components/editor/use-chat.tsx
+++ /dev/null
@@ -1,270 +0,0 @@
-"use client";
-
-import { type ReactNode, createContext, useContext, useState } from "react";
-
-import { faker } from "@faker-js/faker";
-import { cn } from "@udecode/cn";
-import { CopilotPlugin } from "@udecode/plate-ai/react";
-import { useEditorPlugin } from "@udecode/plate-common/react";
-import { useChat as useBaseChat } from "ai/react";
-import { ArrowUpRight, Check, ChevronsUpDown, Eye, EyeOff, Settings } from "lucide-react";
-import { Button } from "~/components/plate-ui/button";
-import {
- Command,
- CommandEmpty,
- CommandGroup,
- CommandInput,
- CommandItem,
- CommandList,
-} from "~/components/plate-ui/command";
-import {
- Dialog,
- DialogContent,
- DialogDescription,
- DialogHeader,
- DialogTitle,
- DialogTrigger,
-} from "~/components/plate-ui/dialog";
-import { Input } from "~/components/plate-ui/input";
-import { Popover, PopoverContent, PopoverTrigger } from "~/components/plate-ui/popover";
-
-export const useChat = (props?: Parameters[0]) => {
- return useBaseChat({
- id: "editor",
- api: "/api/ai/command",
- ...props,
- });
-};
-
-// Used for testing. Remove it after implementing useChat api.
-const fakeStreamText = ({
- chunkCount = 10,
- streamProtocol = "data",
-}: {
- chunkCount?: number;
- streamProtocol?: "data" | "text";
-} = {}) => {
- const chunks = Array.from({ length: chunkCount }, () => ({
- delay: faker.number.int({ max: 150, min: 50 }),
- texts: faker.lorem.words({ max: 3, min: 1 }) + " ",
- }));
- const encoder = new TextEncoder();
-
- return new ReadableStream({
- async start(controller) {
- for (const chunk of chunks) {
- await new Promise((resolve) => setTimeout(resolve, chunk.delay));
-
- if (streamProtocol === "text") {
- controller.enqueue(encoder.encode(chunk.texts));
- } else {
- controller.enqueue(encoder.encode(`0:${JSON.stringify(chunk.texts)}\n`));
- }
- }
-
- if (streamProtocol === "data") {
- controller.enqueue(
- `d:{"finishReason":"stop","usage":{"promptTokens":0,"completionTokens":${chunks.length}}}\n`,
- );
- }
-
- controller.close();
- },
- });
-};
-
-interface Model {
- label: string;
- value: string;
-}
-
-interface OpenAIContextType {
- apiKey: string;
- model: Model;
- setApiKey: (key: string) => void;
- setModel: (model: Model) => void;
-}
-
-export const models: Model[] = [
- { label: "gpt-4o-mini", value: "gpt-4o-mini" },
- { label: "gpt-4o", value: "gpt-4o" },
- { label: "gpt-4-turbo", value: "gpt-4-turbo" },
- { label: "gpt-4", value: "gpt-4" },
- { label: "gpt-3.5-turbo", value: "gpt-3.5-turbo" },
- { label: "gpt-3.5-turbo-instruct", value: "gpt-3.5-turbo-instruct" },
-];
-
-const OpenAIContext = createContext(undefined);
-
-export function OpenAIProvider({ children }: { children: ReactNode }) {
- const [apiKey, setApiKey] = useState("");
- const [model, setModel] = useState(models[0]);
-
- return (
-
- {children}
-
- );
-}
-
-export function useOpenAI() {
- const context = useContext(OpenAIContext);
-
- return (
- context ??
- ({
- apiKey: "",
- model: models[0],
- setApiKey: () => {},
- setModel: () => {},
- } as OpenAIContextType)
- );
-}
-
-export function SettingsDialog() {
- const { apiKey, model, setApiKey, setModel } = useOpenAI();
- const [tempKey, setTempKey] = useState(apiKey);
- const [showKey, setShowKey] = useState(false);
- const [open, setOpen] = useState(false);
- const [openModel, setOpenModel] = useState(false);
-
- const { getOptions, setOption } = useEditorPlugin(CopilotPlugin);
-
- const handleSubmit = (e: React.FormEvent) => {
- e.preventDefault();
- setApiKey(tempKey);
- setOpen(false);
-
- const completeOptions = getOptions().completeOptions ?? {};
-
- setOption("completeOptions", {
- ...completeOptions,
- body: {
- ...completeOptions.body,
- apiKey: tempKey,
- model: model.value,
- },
- });
- };
-
- return (
-
-
-
-
-
-
- Settings
-
-
-
-
-
-
- AI Settings
-
- Enter your{" "}
-
- OpenAI API key
-
- {" "}
- to use AI features.
-
-
-
-
- Not stored anywhere. Used only for current session requests.
-
-
-
- );
-}
diff --git a/apps/web/app/components/editor/use-create-editor.tsx b/apps/web/app/components/editor/use-create-editor.tsx
deleted file mode 100644
index bae45a74..00000000
--- a/apps/web/app/components/editor/use-create-editor.tsx
+++ /dev/null
@@ -1,137 +0,0 @@
-import { withProps } from "@udecode/cn";
-import { AIPlugin } from "@udecode/plate-ai/react";
-import {
- BoldPlugin,
- CodePlugin,
- ItalicPlugin,
- StrikethroughPlugin,
- SubscriptPlugin,
- SuperscriptPlugin,
- UnderlinePlugin,
-} from "@udecode/plate-basic-marks/react";
-import { BlockquotePlugin } from "@udecode/plate-block-quote/react";
-import { CodeBlockPlugin, CodeLinePlugin, CodeSyntaxPlugin } from "@udecode/plate-code-block/react";
-import { CommentsPlugin } from "@udecode/plate-comments/react";
-import { Value } from "@udecode/plate-common";
-import { ParagraphPlugin, PlateLeaf, usePlateEditor } from "@udecode/plate-common/react";
-import { DatePlugin } from "@udecode/plate-date/react";
-import { ExcalidrawPlugin } from "@udecode/plate-excalidraw/react";
-import { HEADING_KEYS } from "@udecode/plate-heading";
-import { TocPlugin } from "@udecode/plate-heading/react";
-import { HighlightPlugin } from "@udecode/plate-highlight/react";
-import { HorizontalRulePlugin } from "@udecode/plate-horizontal-rule/react";
-import { KbdPlugin } from "@udecode/plate-kbd/react";
-import { ColumnItemPlugin, ColumnPlugin } from "@udecode/plate-layout/react";
-import { LinkPlugin } from "@udecode/plate-link/react";
-import { MarkdownPlugin } from "@udecode/plate-markdown";
-import { ImagePlugin, MediaEmbedPlugin } from "@udecode/plate-media/react";
-import { MentionInputPlugin, MentionPlugin } from "@udecode/plate-mention/react";
-import { SlashInputPlugin } from "@udecode/plate-slash-command/react";
-import {
- TableCellHeaderPlugin,
- TableCellPlugin,
- TablePlugin,
- TableRowPlugin,
-} from "@udecode/plate-table/react";
-import { TogglePlugin } from "@udecode/plate-toggle/react";
-import { copilotPlugins } from "~/components/editor/plugins/copilot-plugins";
-import { editorPlugins } from "~/components/editor/plugins/editor-plugins";
-import { FixedToolbarPlugin } from "~/components/editor/plugins/fixed-toolbar-plugin";
-import { FloatingToolbarPlugin } from "~/components/editor/plugins/floating-toolbar-plugin";
-import { AILeaf } from "~/components/plate-ui/ai-leaf";
-import { BlockquoteElement } from "~/components/plate-ui/blockquote-element";
-import { CodeBlockElement } from "~/components/plate-ui/code-block-element";
-import { CodeLeaf } from "~/components/plate-ui/code-leaf";
-import { CodeLineElement } from "~/components/plate-ui/code-line-element";
-import { CodeSyntaxLeaf } from "~/components/plate-ui/code-syntax-leaf";
-import { ColumnElement } from "~/components/plate-ui/column-element";
-import { ColumnGroupElement } from "~/components/plate-ui/column-group-element";
-import { CommentLeaf } from "~/components/plate-ui/comment-leaf";
-import { DateElement } from "~/components/plate-ui/date-element";
-import { ExcalidrawElement } from "~/components/plate-ui/excalidraw-element";
-import { HeadingElement } from "~/components/plate-ui/heading-element";
-import { HighlightLeaf } from "~/components/plate-ui/highlight-leaf";
-import { HrElement } from "~/components/plate-ui/hr-element";
-import { ImageElement } from "~/components/plate-ui/image-element";
-import { KbdLeaf } from "~/components/plate-ui/kbd-leaf";
-import { LinkElement } from "~/components/plate-ui/link-element";
-import { MediaEmbedElement } from "~/components/plate-ui/media-embed-element";
-import { MentionElement } from "~/components/plate-ui/mention-element";
-import { MentionInputElement } from "~/components/plate-ui/mention-input-element";
-import { ParagraphElement } from "~/components/plate-ui/paragraph-element";
-import { withPlaceholders } from "~/components/plate-ui/placeholder";
-import { SlashInputElement } from "~/components/plate-ui/slash-input-element";
-import { TableCellElement, TableCellHeaderElement } from "~/components/plate-ui/table-cell-element";
-import { TableElement } from "~/components/plate-ui/table-element";
-import { TableRowElement } from "~/components/plate-ui/table-row-element";
-import { TocElement } from "~/components/plate-ui/toc-element";
-import { ToggleElement } from "~/components/plate-ui/toggle-element";
-import { withDraggables } from "~/components/plate-ui/with-draggables";
-
-export const useCreateEditor = ({ initialValue }: { initialValue?: Value }) => {
- return usePlateEditor({
- override: {
- components: withDraggables(
- withPlaceholders({
- [AIPlugin.key]: AILeaf,
- [BlockquotePlugin.key]: BlockquoteElement,
- [BoldPlugin.key]: withProps(PlateLeaf, { as: "strong" }),
- [CodeBlockPlugin.key]: CodeBlockElement,
- [CodeLinePlugin.key]: CodeLineElement,
- [CodePlugin.key]: CodeLeaf,
- [CodeSyntaxPlugin.key]: CodeSyntaxLeaf,
- [ColumnItemPlugin.key]: ColumnElement,
- [ColumnPlugin.key]: ColumnGroupElement,
- [CommentsPlugin.key]: CommentLeaf,
- [DatePlugin.key]: DateElement,
- // [EmojiInputPlugin.key]: EmojiInputElement,
- [ExcalidrawPlugin.key]: ExcalidrawElement,
- [HEADING_KEYS.h1]: withProps(HeadingElement, { variant: "h1" }),
- [HEADING_KEYS.h2]: withProps(HeadingElement, { variant: "h2" }),
- [HEADING_KEYS.h3]: withProps(HeadingElement, { variant: "h3" }),
- [HEADING_KEYS.h4]: withProps(HeadingElement, { variant: "h4" }),
- [HEADING_KEYS.h5]: withProps(HeadingElement, { variant: "h5" }),
- [HEADING_KEYS.h6]: withProps(HeadingElement, { variant: "h6" }),
- [HighlightPlugin.key]: HighlightLeaf,
- [HorizontalRulePlugin.key]: HrElement,
- [ImagePlugin.key]: ImageElement,
- [ItalicPlugin.key]: withProps(PlateLeaf, { as: "em" }),
- [KbdPlugin.key]: KbdLeaf,
- [LinkPlugin.key]: LinkElement,
- [MediaEmbedPlugin.key]: MediaEmbedElement,
- [MentionInputPlugin.key]: MentionInputElement,
- [MentionPlugin.key]: MentionElement,
- [ParagraphPlugin.key]: ParagraphElement,
- [SlashInputPlugin.key]: SlashInputElement,
- [StrikethroughPlugin.key]: withProps(PlateLeaf, { as: "s" }),
- [SubscriptPlugin.key]: withProps(PlateLeaf, { as: "sub" }),
- [SuperscriptPlugin.key]: withProps(PlateLeaf, { as: "sup" }),
- [TableCellHeaderPlugin.key]: TableCellHeaderElement,
- [TableCellPlugin.key]: TableCellElement,
- [TablePlugin.key]: TableElement,
- [TableRowPlugin.key]: TableRowElement,
- [TocPlugin.key]: TocElement,
- [TogglePlugin.key]: ToggleElement,
- [UnderlinePlugin.key]: withProps(PlateLeaf, { as: "u" }),
- }),
- ),
- },
- plugins: [
- ...copilotPlugins,
- ...editorPlugins,
- FixedToolbarPlugin,
- FloatingToolbarPlugin,
- MarkdownPlugin,
- ],
- value: initialValue ?? [
- {
- children: [{ text: "Supermemory docs" }],
- type: "h1",
- },
- {
- children: [{ text: "Auto-updating AI-powered docs" }],
- type: ParagraphPlugin.key,
- },
- ],
- });
-};
diff --git a/apps/web/app/components/editor/writing-playground.tsx b/apps/web/app/components/editor/writing-playground.tsx
deleted file mode 100644
index b303ffc8..00000000
--- a/apps/web/app/components/editor/writing-playground.tsx
+++ /dev/null
@@ -1,242 +0,0 @@
-import { lazy, memo, useEffect, useRef, useState } from "react";
-import { DndProvider } from "react-dnd";
-import { HTML5Backend } from "react-dnd-html5-backend";
-
-import { useChat } from "@ai-sdk/react";
-import { Message } from "ai";
-import { OpenAIProvider } from "~/components/editor/use-chat";
-import { useCreateEditor } from "~/components/editor/use-create-editor";
-import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs";
-import { useLiveTranscript } from "~/lib/hooks/use-live-transcript";
-import { Theme, useTheme } from "~/lib/theme-provider";
-
-const PlateEditorImport = lazy(() =>
- import("@udecode/plate-common/react").then((mod) => ({ default: mod.Plate })),
-);
-
-const EditorContainerImport = lazy(() =>
- import("~/components/plate-ui/editor").then((mod) => ({ default: mod.EditorContainer })),
-);
-
-const EditorImport = lazy(() =>
- import("~/components/plate-ui/editor").then((mod) => ({ default: mod.Editor })),
-);
-
-const Plate = memo(PlateEditorImport);
-const EditorContainer = memo(EditorContainerImport);
-const Editor = memo(EditorImport);
-
-export function WritingPlayground() {
- if (typeof window === "undefined") {
- return Loading...
;
- }
- const localValue = localStorage.getItem("editorContent");
- const editor = useCreateEditor({ initialValue: localValue ? JSON.parse(localValue) : undefined });
-
- const [theme, setTheme] = useTheme();
-
- useEffect(() => {
- setTheme(Theme.LIGHT);
- }, [theme, setTheme]);
-
- const { toggleMicrophone, caption, status, isListening, isLoading } = useLiveTranscript();
-
- const { messages, input, handleInputChange, handleSubmit } = useChat({
- id: "editor",
- api: "/api/ai/command",
- initialMessages: [
- {
- id: "1",
- content: "Hi! I am here to help you quickly find what you're looking for.",
- role: "assistant",
- },
- {
- id: "2",
- content: "Just drop a question when you need me, ok?",
- role: "assistant",
- },
- ],
- keepLastMessageOnError: true,
- // @ts-expect-error
- experimental_prepareRequestBody: (request) => {
- // messages with the documentation content
- // @ts-expect-error
- const markdown = editor.api.markdown.serialize();
- console.log(JSON.stringify(editor.children));
- console.log(markdown);
- return {
- messages: [
- ...request.messages,
- {
- id: "3",
- content: `Here is the documentation for the company: ${markdown}`,
- role: "user",
- } satisfies Message,
- ],
- };
- },
- });
-
- const [lastProcessedLength, setLastProcessedLength] = useState(0);
- const [isProcessing, setIsProcessing] = useState(false);
- const updateTimeoutRef = useRef();
-
- useEffect(() => {
- if (!isListening) {
- return;
- }
- // Clear existing timeout
- if (updateTimeoutRef.current) {
- clearTimeout(updateTimeoutRef.current);
- }
-
- const currentSentences = caption.split(".").length;
-
- // Only process if we have new sentences and aren't currently processing
- if (currentSentences > lastProcessedLength && !isProcessing) {
- // Debounce the update for 2 seconds
- updateTimeoutRef.current = setTimeout(async () => {
- setIsProcessing(true);
- try {
- const result = await fetch("/api/ai/update", {
- method: "POST",
- body: JSON.stringify({ caption, document: editor.children }),
- });
- const data = (await result.json()) as {
- action: "edit" | "delete" | "append" | "ignore";
- blockId?: string;
- content?: string;
- reason: string;
- };
- if (data.action === "ignore") {
- return;
- }
- if (data.action === "edit") {
- // Make a copy of the editor children
- const newChildren = [...editor.children];
- // Find and update the block in the copy
- const blockIndex = newChildren.findIndex((block) => block.id === data.blockId);
- if (blockIndex !== -1) {
- newChildren[blockIndex] = {
- ...newChildren[blockIndex],
- children: [{ text: data.content ?? "" }],
- };
- }
- editor.tf.setValue(newChildren);
- } else if (data.action === "delete") {
- // Make a copy of the editor children and filter out the block
- const newChildren = editor.children.filter((block) => block.id !== data.blockId);
- editor.tf.setValue(newChildren);
- } else if (data.action === "append") {
- editor.tf.setValue([
- ...editor.children,
- {
- type: "paragraph",
- children: [{ text: data.content ?? "" }],
- },
- ]);
- }
- setLastProcessedLength(currentSentences);
- } catch (error) {
- console.error("Error updating editor:", error);
- } finally {
- setIsProcessing(false);
- }
- }, 2000);
- }
-
- return () => {
- if (updateTimeoutRef.current) {
- clearTimeout(updateTimeoutRef.current);
- }
- };
- }, [caption, editor, lastProcessedLength, isProcessing]);
-
- return (
-
-
-
- Docs
- Transcript
-
-
-
-
-
-
-
- {
- // For performance, debounce your saving logic
- localStorage.setItem("editorContent", JSON.stringify(value));
- }}
- editor={editor}
- >
-
-
-
-
-
-
-
-
- {caption}
-
-
-
-
-
- {messages.map((message) => (
-
-
- {message.content}
-
-
- ))}
-
-
-
-
-
-
- );
-}
\ No newline at end of file
diff --git a/apps/web/app/components/gradients/gradient1.png b/apps/web/app/components/gradients/gradient1.png
deleted file mode 100644
index 123ebf32..00000000
Binary files a/apps/web/app/components/gradients/gradient1.png and /dev/null differ
diff --git a/apps/web/app/components/icons/IntegrationIcons.tsx b/apps/web/app/components/icons/IntegrationIcons.tsx
deleted file mode 100644
index 1a8998b5..00000000
--- a/apps/web/app/components/icons/IntegrationIcons.tsx
+++ /dev/null
@@ -1,70 +0,0 @@
-import type { SVGProps } from "react";
-
-export const NotionIcon = (props: SVGProps) => (
-
-
-
-
-);
-
-export const GoogleCalendarIcon = (props: SVGProps) => (
-
-
-
-);
-
-export const TwitterIcon = (props: SVGProps) => (
-
-
-
-);
-
-export const GithubIcon = (props: SVGProps) => (
-
-
-
-);
-
-export const DiscordIcon = (props: SVGProps) => (
-
-
-
-);
diff --git a/apps/web/app/components/icons/Logo.tsx b/apps/web/app/components/icons/Logo.tsx
deleted file mode 100644
index 8679cfea..00000000
--- a/apps/web/app/components/icons/Logo.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-export const Logo: React.FC> = (props) => (
-
-
-
-);
diff --git a/apps/web/app/components/markdown/codeblock.tsx b/apps/web/app/components/markdown/codeblock.tsx
deleted file mode 100644
index 7f6756d7..00000000
--- a/apps/web/app/components/markdown/codeblock.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import type { CodeToHtmlOptions } from "@llm-ui/code";
-import { allLangs, allLangsAlias, loadHighlighter, useCodeBlockToHtml } from "@llm-ui/code";
-import { type LLMOutputComponent } from "@llm-ui/react";
-import parseHtml from "html-react-parser";
-import { getHighlighterCore } from "shiki/core";
-import { bundledLanguagesInfo } from "shiki/langs";
-// WARNING: Importing bundledThemes increases your bundle size
-// see: https://llm-ui.com/docs/blocks/code#bundle-size
-import { bundledThemes } from "shiki/themes";
-import getWasm from "shiki/wasm";
-
-const highlighter = loadHighlighter(
- getHighlighterCore({
- langs: allLangs(bundledLanguagesInfo),
- langAlias: allLangsAlias(bundledLanguagesInfo),
- themes: Object.values(bundledThemes),
- loadWasm: getWasm,
- }),
-);
-
-const codeToHtmlOptions: CodeToHtmlOptions = {
- theme: "github-dark",
-};
-
-export const CodeBlock: LLMOutputComponent = ({ blockMatch }) => {
- const { html, code } = useCodeBlockToHtml({
- markdownCodeBlock: blockMatch.output,
- highlighter,
- codeToHtmlOptions,
- });
- if (!html) {
- // fallback to if Shiki is not loaded yet
- return (
-
- {code}
-
- );
- }
- return <>{parseHtml(html)}>;
-};
diff --git a/apps/web/app/components/markdown/renderer.tsx b/apps/web/app/components/markdown/renderer.tsx
deleted file mode 100644
index 12e47331..00000000
--- a/apps/web/app/components/markdown/renderer.tsx
+++ /dev/null
@@ -1,10 +0,0 @@
-import ReactMarkdown from "react-markdown";
-import remarkGfm from "remark-gfm";
-import { type LLMOutputComponent } from "@llm-ui/react";
-
-
-// Customize this component with your own styling
-export const MarkdownComponent: LLMOutputComponent = ({ blockMatch }) => {
- const markdown = blockMatch.output;
- return {markdown} ;
-};
\ No newline at end of file
diff --git a/apps/web/app/components/memories/AddMemory.tsx b/apps/web/app/components/memories/AddMemory.tsx
deleted file mode 100644
index e863d209..00000000
--- a/apps/web/app/components/memories/AddMemory.tsx
+++ /dev/null
@@ -1,583 +0,0 @@
-import React, { useEffect, useState } from "react";
-
-import { Logo } from "../icons/Logo";
-import { Button } from "../ui/button";
-import { Input } from "../ui/input";
-import { Switch } from "../ui/switch";
-import { Textarea } from "../ui/textarea";
-import Integrations from "./Integrations";
-import { FetchAndRenderContent, typeDecider } from "./SharedCard";
-import SpacesSelector from "./SpacesSelector";
-
-import { FileIcon, Link1Icon, PlusCircledIcon } from "@radix-ui/react-icons";
-import { SpaceIcon } from "@supermemory/shared/icons";
-import { AnimatePresence, motion } from "framer-motion";
-import { NotebookIcon, Plus, PuzzleIcon, Settings2Icon, Upload } from "lucide-react";
-import { toast } from "sonner";
-import {
- Credenza,
- CredenzaBody,
- CredenzaClose,
- CredenzaContent,
- CredenzaFooter,
- CredenzaHeader,
- CredenzaTitle,
- CredenzaTrigger,
-} from "~/components/ui/credenza";
-import { Label } from "~/components/ui/label";
-import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs";
-import { useDebounce } from "~/lib/hooks/use-debounce";
-import { useMemories } from "~/lib/hooks/use-memories";
-import { useSpaces } from "~/lib/hooks/use-spaces";
-import { useUploadFile } from "~/lib/hooks/use-upload-file";
-import { cn } from "~/lib/utils";
-
-export function AddMemoryModal({
- children,
- spaceTab,
-}: {
- children: React.ReactNode;
- spaceTab?: boolean;
-}) {
- const [content, setContent] = useState(null);
- const [activeTab, setActiveTab] = useState<
- "url" | "note" | "space" | "document" | "integrations"
- >(spaceTab ? "space" : "url");
- const [file, setFile] = useState(null);
- const [isUploading, setIsUploading] = useState(false);
-
- const [isPublic, setIsPublic] = useState(false);
-
- const { uploadFile } = useUploadFile();
-
- useEffect(() => {
- if (!spaceTab) {
- const validTabs = ["url", "note", "space", "document", "integrations"];
- const savedTab = window.localStorage.getItem("lastUsedMemoryTab");
-
- if (savedTab && validTabs.includes(savedTab)) {
- setActiveTab(savedTab as typeof activeTab);
- }
- }
- }, [spaceTab]);
-
- // Get space ID from URL if we're in a space
- const [selectedSpaces, setSelectedSpaces] = useState(() => {
- if (typeof window !== "undefined") {
- const match = window.location.pathname.match(/\/space\/([^\/]+)/);
- return match ? [match[1].split("---")[0]] : [];
- }
- return [];
- });
-
- const { createSpace, isCreating } = useSpaces();
- const { addMemory } = useMemories();
-
- // Debounce the content to avoid rapid type detection
- const debouncedContent = useDebounce(content, 500);
-
- // Reset content when switching tabs manually
- const handleTabChange = (value: string) => {
- setContent(null);
- setFile(null);
- setActiveTab(value as "url" | "note" | "space" | "document");
- window.localStorage.setItem("lastUsedMemoryTab", value);
- };
-
- const handleSubmit = async () => {
- if (activeTab === "document") {
- if (!file) return;
-
- setIsUploading(true);
- try {
- const { url } = await uploadFile(file);
- if (url) {
- addMemory({
- content: url,
- spaces: selectedSpaces,
- });
- }
- } catch (error) {
- console.error("Error uploading file:", error);
- toast.error("Failed to upload file");
- } finally {
- setIsUploading(false);
- }
- } else if (!content) {
- return;
- } else if (activeTab === "space") {
- try {
- createSpace({
- spaceName: content,
- isPublic,
- });
- } catch (error) {
- console.error("Error creating space:", error);
- }
- } else {
- try {
- console.log("Add memory run");
- addMemory({
- content,
- spaces: selectedSpaces,
- });
- } catch (error) {
- console.error("Error adding memory:", error);
- }
- }
- // click the close-memory-modal button
- const closeButton = document.getElementById("close-memory-modal");
- if (closeButton) {
- closeButton.click();
- }
- };
-
- const handleFileChange = (e: React.ChangeEvent) => {
- const selectedFile = e.target.files?.[0];
- if (selectedFile) {
- setFile(selectedFile);
- // Create object URL for preview
- const fileUrl = URL.createObjectURL(selectedFile);
- setContent(fileUrl);
- }
- };
-
- return (
-
- {children}
-
-
-
-
-
-
-
-
-
-
-
- Website
-
- Add a website or tweet URL
-
-
-
-
- Note
-
- Add a note or use the rich editor
-
-
-
-
- Document
-
- Upload a PDF or other document
-
-
-
-
- Integrations
-
- Import memories from third-party services
-
-
-
-
- Create Space
-
- A collection of memories
-
-
-
-
-
-
-
-
-
-
-
-
- {/* Ask for space name */}
-
-
- Create a space
-
-
setContent(e.target.value)}
- autoFocus
- />
-
-
-
-
- Public
-
- {isPublic && (
-
-
-
-
-
-
- When public, anyone with the link can view this space
-
- )}
-
-
-
-
-
-
- Upload Document
-
-
-
-
-
-
-
- Click to upload or drag and drop
-
-
- PDF, DOC, DOCX (MAX. 10MB)
-
-
-
-
-
-
- {file && (
-
-
- {file.name}
-
- )}
-
-
-
-
-
-
-
-
-
- {activeTab !== "integrations" && (
-
-
-
- {activeTab === "space" ? (
-
-
-
-
-
-
- Create a Space
-
-
- Spaces help you organize your memories. Create a new space to start
- collecting related memories together.
-
-
-
- ) : activeTab === "document" && file ? (
-
-
-
-
-
- Document
-
-
- {file.name}
-
-
-
-
- ) : debouncedContent ? (
-
- ) : (
-
-
-
-
-
- Create a Memory
-
-
- Add your first memory to start building your knowledge base. You will see
- a preview here.
-
-
-
- )}
-
-
-
-
- )}
-
-
-
-
-
- Cancel
-
-
-
- {isUploading ? (
- <>
-
- Add {activeTab === "space" ? "Space" : "Memory"}
-
-
- >
- ) : (
- <>Add {activeTab === "space" ? "Space" : "Memory"}>
- )}
-
-
-
-
-
- );
-}
-
-function AddMemory({ isSpace = false }: { isSpace?: boolean }) {
- const [isMobile, setIsMobile] = useState(false);
-
- useEffect(() => {
- const checkMobile = () => {
- setIsMobile(window.innerWidth <= 768);
- };
-
- checkMobile();
- window.addEventListener("resize", checkMobile);
-
- return () => window.removeEventListener("resize", checkMobile);
- }, []);
-
- return (
-
-
-
- {isMobile ? (
-
-
-
- Add Memory
-
-
- ) : (
- <>
-
-
- Add to your second brain.
-
-
- Add a link, a note, a document, tweet, etc.
-
- >
- )}
-
-
-
-
-
-
- Memory
-
-
- {!isSpace && (
-
-
-
- Space
-
-
- )}
-
-
- {isMobile && !isSpace && (
-
-
-
- Create Space
-
-
- )}
-
- );
-}
-
-export default AddMemory;
diff --git a/apps/web/app/components/memories/CSVUploadModal.tsx b/apps/web/app/components/memories/CSVUploadModal.tsx
deleted file mode 100644
index 66359269..00000000
--- a/apps/web/app/components/memories/CSVUploadModal.tsx
+++ /dev/null
@@ -1,267 +0,0 @@
-import { useEffect, useState } from "react";
-
-import { Button } from "../ui/button";
-import { Dialog, DialogContent, DialogDescription, DialogTitle } from "../ui/dialog";
-import SpacesSelector from "./SpacesSelector";
-
-import { motion } from "framer-motion";
-import { AlertCircle, CheckCircle, Upload } from "lucide-react";
-import Papa from "papaparse";
-import { toast } from "sonner";
-
-interface CSVUploadModalProps {
- isOpen: boolean;
- onClose: () => void;
-}
-
-export function CSVUploadModal({ isOpen, onClose }: CSVUploadModalProps) {
- const [file, setFile] = useState(null);
- const [urls, setUrls] = useState([]);
- const [isUploading, setIsUploading] = useState(false);
- const [progress, setProgress] = useState<{
- progress: number;
- processed: number;
- total: number;
- succeeded: number;
- failed: number;
- status: string;
- } | null>(null);
- const [selectedSpaces, setSelectedSpaces] = useState([]);
-
- const handleFileChange = (e: React.ChangeEvent) => {
- const selectedFile = e.target.files?.[0];
- if (selectedFile) {
- if (!selectedFile.name.endsWith(".csv")) {
- toast.error("Please upload a CSV file");
- return;
- }
- setFile(selectedFile);
-
- // Parse CSV file
- Papa.parse(selectedFile, {
- complete: (results) => {
- // Find column containing URLs by checking first row
- const firstRow = results.data[0];
- let urlColumnIndex = -1;
-
- // Look for a column containing URLs in the header row
- // @ts-expect-error - firstRow is of type unknown
- firstRow.forEach((cell: string, index: number) => {
- if (
- cell?.toLowerCase().includes("url") ||
- (cell && typeof cell === "string" && cell.trim().startsWith("http"))
- ) {
- urlColumnIndex = index;
- }
- });
-
- // If no URL column found in header, check first data row
- if (urlColumnIndex === -1 && results.data[1]) {
- // @ts-expect-error - results.data[1] is of type unknown
- results.data[1].forEach((cell: string, index: number) => {
- if (cell && typeof cell === "string" && cell.trim().startsWith("http")) {
- urlColumnIndex = index;
- }
- });
- }
-
- if (urlColumnIndex === -1) {
- toast.error("Could not find a column containing URLs");
- setFile(null);
- return;
- }
-
- // Extract URLs from the identified column
- const validUrls = results.data
- .slice(1) // Skip header row
- .map((row: any) => row[urlColumnIndex])
- .filter((url: string) => url && url.trim() && url.startsWith("http"));
-
- if (validUrls.length === 0) {
- toast.error("No valid URLs found in the CSV file");
- setFile(null);
- return;
- }
-
- setUrls(validUrls);
- toast.success(`Found ${validUrls.length} valid URLs in column ${urlColumnIndex + 1}`);
- },
- error: (error) => {
- toast.error("Error parsing CSV file: " + error.message);
- setFile(null);
- },
- });
- }
- };
-
- const handleUpload = async () => {
- if (!file || urls.length === 0) return;
-
- setIsUploading(true);
- try {
- const response = await fetch("/backend/v1/batch-add", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({
- urls,
- spaces: selectedSpaces,
- }),
- });
-
- if (!response.ok) {
- throw new Error("Failed to start batch upload");
- }
-
- const reader = response.body?.getReader();
- if (!reader) throw new Error("No reader available");
-
- while (true) {
- const { done, value } = await reader.read();
- if (done) break;
-
- const text = new TextDecoder().decode(value);
- const lines = text.split("\n");
-
- for (const line of lines) {
- if (line.startsWith("data: ")) {
- try {
- const data = JSON.parse(line.slice(5));
- setProgress(data);
-
- if (data.status === "complete") {
- toast.success(
- `Batch upload complete! ${data.succeeded} succeeded, ${data.failed} failed`,
- );
- setTimeout(() => {
- onClose();
- setFile(null);
- setUrls([]);
- setProgress(null);
- }, 2000);
- }
- } catch (e) {
- console.error("Error parsing SSE data:", e);
- }
- }
- }
- }
- } catch (error) {
- toast.error("Upload failed: " + (error instanceof Error ? error.message : "Unknown error"));
- } finally {
- setIsUploading(false);
- }
- };
-
- return (
- !isUploading && onClose()}>
-
- {isUploading ? (
-
- {progress ? (
- <>
-
-
-
- {progress.progress}%
-
-
-
-
-
-
-
-
- Processing URLs ({progress.processed}/{progress.total})
-
-
- {progress.succeeded} succeeded, {progress.failed} failed
-
- >
- ) : (
-
-
-
- )}
-
- ) : (
-
-
Upload CSV File
-
- Upload a CSV file containing URLs to add to your memories. The URLs should be in the
- first column.
-
-
-
-
-
-
-
- Click to upload or drag and drop
-
-
CSV files only
-
-
-
-
-
- {file && (
- <>
-
-
-
- {file.name} ({urls.length} URLs found)
-
-
-
-
-
-
-
- Cancel
-
-
- Upload
-
-
- >
- )}
-
- )}
-
-
- );
-}
diff --git a/apps/web/app/components/memories/Integrations.tsx b/apps/web/app/components/memories/Integrations.tsx
deleted file mode 100644
index c5bd2996..00000000
--- a/apps/web/app/components/memories/Integrations.tsx
+++ /dev/null
@@ -1,697 +0,0 @@
-import { useEffect, useState } from "react";
-
-import { useNavigate, useRouteLoaderData } from "@remix-run/react";
-
-import { Button } from "../ui/button";
-import { Card } from "../ui/card";
-import { Dialog, DialogContent, DialogDescription, DialogTitle } from "../ui/dialog";
-import { CSVUploadModal } from "./CSVUploadModal";
-import { MarkdownUploadModal } from "./MarkdownUploadModal";
-
-import { motion } from "framer-motion";
-import {
- AlertCircle,
- BookIcon,
- CheckCircle,
- Clipboard,
- ClipboardCheckIcon,
- FileUpIcon,
- X,
-} from "lucide-react";
-import { toast } from "sonner";
-import { type IntegrationConfig, getIntegrations } from "~/config/integrations";
-import { getChromeExtensionId } from "~/config/util";
-import { cn } from "~/lib/utils";
-import { loader } from "~/root";
-
-function IntegrationButton({
- integration,
- onClick,
-}: {
- integration: IntegrationConfig;
- onClick: () => void;
-}) {
- return (
-
-
-
-
- {integration.icon && (
-
-
-
- )}
-
-
-
{integration.name}
-
- {integration.description}
-
-
-
-
- );
-}
-
-function LoadingIntegration({
- integration,
- onCancel,
-}: {
- integration: IntegrationConfig;
- onCancel: () => void;
-}) {
- const [extensionPresent, setExtensionPresent] = useState(false);
- const [importComplete, setImportComplete] = useState(false);
-
- useEffect(() => {
- if (integration.id === "xBookmarks") {
- try {
- // Listen for import complete message
- const handleMessage = (event: MessageEvent) => {
- if (event.data.type === "TWITTER_IMPORT_COMPLETE") {
- setImportComplete(true);
- // Auto close after 2 seconds
- setTimeout(() => {
- onCancel();
- }, 2000);
- }
- };
-
- window.addEventListener("message", handleMessage);
-
- // Check if extension is present
- chrome?.runtime.sendMessage(getChromeExtensionId(), { action: "ping" }, (response: any) => {
- setExtensionPresent(!chrome?.runtime.lastError);
- });
-
- return () => {
- window.removeEventListener("message", handleMessage);
- };
- } catch (e) {
- setExtensionPresent(false);
- }
- }
- }, [integration, onCancel]);
-
- return (
- onCancel()}>
-
- {integration.id === "xBookmarks" && !extensionPresent ? (
-
-
-
Extension Required
-
- Please install the SuperMemory extension to connect with X
-
-
- Cancel
-
-
- ) : importComplete ? (
-
-
- Import Complete!
- Your X bookmarks have been successfully imported.
-
- ) : (
-
- {integration.icon && (
-
-
-
- )}
- Importing from {integration.name}...
-
- The import has started. It will keep going in the background. You can close this modal
- and enjoy supermemory! (You might need to reload to see the changes!)
-
-
- Cancel
-
-
- )}
-
-
- );
-}
-
-function Integrations() {
- const navigate = useNavigate();
- const data = useRouteLoaderData("root");
- const env = data?.ENV || {};
- const integrations = getIntegrations(env);
- const [loadingIntegration, setLoadingIntegration] = useState(null);
- const [apiKey, setApiKey] = useState(null);
- const [copied, setCopied] = useState(false);
- const [isCSVModalOpen, setIsCSVModalOpen] = useState(false);
- const [isMarkdownModalOpen, setIsMarkdownModalOpen] = useState(false);
-
- const handleIntegrationClick = (integration: IntegrationConfig) => {
- setLoadingIntegration(integration);
-
- if (integration.handleConnection) {
- integration.handleConnection(env, navigate);
- } else if (integration.getAuthUrl) {
- const authUrl = integration.getAuthUrl(env);
-
- // Small delay to show the loading state
- setTimeout(() => {
- if (authUrl.startsWith(window.location.origin)) {
- navigate(new URL(authUrl).pathname);
- } else {
- window.location.href = authUrl;
- }
- }, 500);
- }
- };
-
- const getApiKey = async () => {
- const response = await fetch(`/backend/v1/user/key`, {
- credentials: "include",
- });
- if (response.ok) {
- const data = (await response.json()) as { key: string };
- setApiKey(data.key);
- } else {
- toast.error("Failed to fetch API key");
- console.error("Failed to fetch API key", response);
- return null;
- }
- };
-
- useEffect(() => {
- getApiKey();
- }, []);
-
- useEffect(() => {
- if (copied) {
- const timeout = setTimeout(() => {
- setCopied(false);
- }, 2000);
- return () => clearTimeout(timeout);
- }
- }, [copied]);
-
- return (
-
-
-
- Import your content
-
-
- Connect your favorite platforms to import your content into Supermemory
-
-
-
-
-
-
- Your API Key
-
- {apiKey ? (
-
{
- navigator.clipboard.writeText(apiKey);
- setCopied(true);
- toast.success("API key copied to clipboard!");
- }}
- className="flex-1 flex items-center gap-2 font-mono text-sm bg-white dark:bg-neutral-800 px-3 py-1.5 rounded group hover:bg-neutral-100 dark:hover:bg-neutral-700 transition-all overflow-hidden"
- >
-
- {copied ? (
-
-
-
- ) : (
-
-
-
- )}
-
-
- {apiKey}
-
-
- ) : (
-
Loading...
- )}
-
-
-
-
-
setIsMarkdownModalOpen(true)}
- >
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Obsidian
-
- Import notes from your Obsidian vault
-
-
-
-
-
-
setIsCSVModalOpen(true)}
- >
-
-
-
-
-
-
-
CSV Upload
-
- Bulk import URLs from a CSV file
-
-
-
-
-
- {Object.entries(integrations).map(([key, integration]) => (
-
handleIntegrationClick(integration)}
- />
- ))}
-
-
- {loadingIntegration && (
-
setLoadingIntegration(null)}
- />
- )}
-
- setIsCSVModalOpen(false)} />
- setIsMarkdownModalOpen(false)}
- />
-
-
-
- );
-}
-
-type ImportStatus = "idle" | "loading" | "success" | "error";
-
-export function IntegrationModals({ integrationId }: { integrationId: string }) {
- const [status, setStatus] = useState("idle");
- const [progress, setProgress] = useState(0);
- const [isModalOpen, setIsModalOpen] = useState(true);
- const router = useNavigate();
-
- useEffect(() => {
- if (integrationId === "notion") {
- handleNotionImport();
- }
- }, [integrationId]);
-
- const handleNotionImport = async () => {
- setStatus("loading");
- let toastId: string | number | undefined;
-
- try {
- const eventSource = new EventSource(`/backend/v1/integrations/notion/import`, {
- withCredentials: true,
- });
-
- eventSource.onmessage = (event) => {
- try {
- const data = JSON.parse(event.data);
- if (data.progress) {
- setProgress(data.progress);
- if (data.page) {
- toastId = toast.loading(`Importing ${data.page}... ${data.progress}%`, {
- id: toastId,
- });
- } else {
- toastId = toast.loading(`Importing from Notion: ${data.progress}%`, { id: toastId });
- }
- }
- if (data.warning) {
- toast.warning(data.message);
- }
- if (data.error) {
- throw new Error(data.error);
- }
- if (data.progress === 100) {
- eventSource.close();
- setStatus("success");
- if (toastId) {
- toast.success("Successfully imported from Notion!", { id: toastId });
- } else {
- toast.success("Successfully imported from Notion!");
- }
- setTimeout(() => {
- router("/");
- }, 1500);
- }
- } catch (e) {
- console.error("Error parsing SSE data:", e);
- eventSource.close();
- setStatus("error");
- if (toastId) {
- toast.error(e instanceof Error ? e.message : "Failed to import from Notion", {
- id: toastId,
- });
- } else {
- toast.error(e instanceof Error ? e.message : "Failed to import from Notion");
- }
- }
- };
-
- eventSource.onerror = (error) => {
- console.error("EventSource error:", error);
- eventSource.close();
- setStatus("error");
- if (toastId) {
- toast.error("Failed to connect to import stream", { id: toastId });
- } else {
- toast.error("Failed to connect to import stream");
- }
- };
- } catch (error) {
- console.error("Import error:", error);
- setStatus("error");
- if (toastId) {
- toast.error(error instanceof Error ? error.message : "Failed to import from Notion", {
- id: toastId,
- });
- } else {
- toast.error(error instanceof Error ? error.message : "Failed to import from Notion");
- }
- }
- };
-
- const handleClose = () => {
- setIsModalOpen(false);
- };
-
- if (!integrationId || !isModalOpen) return null;
-
- return (
-
- e.stopPropagation()}
- >
-
-
-
-
-
- {status === "loading" && (
- <>
-
-
- {progress}%
-
-
-
-
-
-
-
-
-
- Importing from Notion
-
-
- This may take a few minutes. You can close this modal and let it run in the
- background.
-
-
- >
- )}
-
- {status === "success" && (
- <>
-
-
-
-
-
- Import Complete!
-
-
- Redirecting you to your dashboard...
-
-
- >
- )}
-
- {status === "error" && (
- <>
-
-
-
-
-
- Import Failed
-
-
- Please try again or contact support if the issue persists
-
-
- Retry Import
-
-
- >
- )}
-
-
-
- );
-}
-
-export default Integrations;
diff --git a/apps/web/app/components/memories/MarkdownUploadModal.tsx b/apps/web/app/components/memories/MarkdownUploadModal.tsx
deleted file mode 100644
index 23e6f33b..00000000
--- a/apps/web/app/components/memories/MarkdownUploadModal.tsx
+++ /dev/null
@@ -1,294 +0,0 @@
-import { useEffect, useState } from "react";
-
-import { Button } from "../ui/button";
-import { Dialog, DialogContent, DialogDescription, DialogTitle } from "../ui/dialog";
-import SpacesSelector from "./SpacesSelector";
-
-import { motion } from "framer-motion";
-import { AlertCircle, CheckCircle, Upload } from "lucide-react";
-import { toast } from "sonner";
-
-interface MarkdownUploadModalProps {
- isOpen: boolean;
- onClose: () => void;
-}
-
-export function MarkdownUploadModal({ isOpen, onClose }: MarkdownUploadModalProps) {
- const [files, setFiles] = useState([]);
- const [isUploading, setIsUploading] = useState(false);
- const [progress, setProgress] = useState<{
- progress: number;
- processed: number;
- total: number;
- succeeded: number;
- failed: number;
- status: string;
- } | null>(null);
- const [selectedSpaces, setSelectedSpaces] = useState([]);
-
- const handleFileChange = async (e: React.ChangeEvent) => {
- const selectedFiles = e.target.files;
- if (!selectedFiles) return;
-
- const mdFiles: File[] = [];
- const processFile = async (file: File) => {
- if (file.name.endsWith(".md")) {
- mdFiles.push(file);
- }
- };
-
- // Handle both individual files and directory
- const files = Array.from(selectedFiles);
- await Promise.all(files.map(processFile));
-
- if (mdFiles.length === 0) {
- toast.error("No markdown files found");
- return;
- }
-
- setFiles(mdFiles);
- toast.success(`Found ${mdFiles.length} markdown files`);
- };
-
- const handleUpload = async () => {
- if (files.length === 0) return;
-
- setIsUploading(true);
- const progressToastId = toast.loading("Starting markdown import...");
- let lastToastTime = Date.now();
-
- try {
- // Convert markdown files to content
- const contents = await Promise.all(
- files.map(async (file) => {
- const content = await file.text();
- return {
- content,
- title: file.name.replace(".md", ""),
- type: "note",
- };
- }),
- );
-
- // Send to batch endpoint
- const response = await fetch("/backend/v1/batch-add", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({
- contents,
- spaces: selectedSpaces,
- }),
- });
-
- if (!response.ok) {
- throw new Error("Failed to start batch upload");
- }
-
- const reader = response.body?.getReader();
- if (!reader) throw new Error("No reader available");
-
- while (true) {
- const { done, value } = await reader.read();
- if (done) break;
-
- const text = new TextDecoder().decode(value);
- const lines = text.split("\n");
-
- for (const line of lines) {
- if (line.startsWith("data: ")) {
- try {
- const data = JSON.parse(line.slice(5));
- setProgress(data);
-
- // Update the main progress toast every 500ms
- const now = Date.now();
- if (now - lastToastTime > 500) {
- toast.loading(
- `Processing files: ${data.processed}/${data.total} (${data.progress}%)`,
- { id: progressToastId },
- );
- lastToastTime = now;
- }
-
- // Show individual file status toasts with a limit
- if (data.status === "success" && data.processed % 5 === 0) {
- toast.success(`Successfully imported ${data.processed} files so far`);
- } else if (data.status === "error") {
- toast.error(`Failed to import: ${data.title} - ${data.error}`);
- }
-
- if (data.status === "complete") {
- toast.success(
- `Import complete! ${data.succeeded} succeeded, ${data.failed} failed`,
- { id: progressToastId, duration: 5000 },
- );
-
- // Wait for 2 seconds before closing
- await new Promise((resolve) => setTimeout(resolve, 2000));
- onClose();
- setFiles([]);
- setProgress(null);
- break;
- }
- } catch (e) {
- console.error("Error parsing SSE data:", e);
- }
- }
- }
- }
- } catch (error) {
- toast.error("Upload failed: " + (error instanceof Error ? error.message : "Unknown error"));
- } finally {
- setIsUploading(false);
- }
- };
-
- return (
- !isUploading && onClose()}>
-
- {isUploading ? (
-
- {progress ? (
- <>
-
-
-
- {progress.progress}%
-
-
-
-
-
-
-
-
- Processing Files ({progress.processed}/{progress.total})
-
-
- {progress.succeeded} succeeded, {progress.failed} failed
-
- >
- ) : (
-
-
-
- )}
-
- ) : (
-
-
Import from Obsidian
-
- Upload markdown files from your Obsidian vault. You can select multiple files or drop
- a folder.
-
-
-
- {/* Individual Files Selection */}
-
-
-
-
-
- Select Files
-
-
- Choose individual markdown files
-
-
-
-
-
-
-
OR
-
- {/* Folder Selection */}
-
-
-
-
-
- Select Folder
-
-
- Choose an entire folder
-
-
-
-
-
-
-
- {files.length > 0 && (
- <>
-
-
-
- {files.length} markdown files selected
-
-
-
-
-
-
-
- Cancel
-
- Import
-
- >
- )}
-
- )}
-
-
- );
-}
diff --git a/apps/web/app/components/memories/MemoriesPage.tsx b/apps/web/app/components/memories/MemoriesPage.tsx
deleted file mode 100644
index da12427e..00000000
--- a/apps/web/app/components/memories/MemoriesPage.tsx
+++ /dev/null
@@ -1,423 +0,0 @@
-import { createContext, memo, useCallback, useContext, useMemo, useState } from "react";
-import { useParams } from "react-router-dom";
-
-import { Button } from "../ui/button";
-import AddMemory from "./AddMemory";
-import SharedCard from "./SharedCard";
-
-import { Trash2 } from "lucide-react";
-import { Masonry, useInfiniteLoader } from "masonic";
-import { useHydrated } from "remix-utils/use-hydrated";
-import { toast } from "sonner";
-import { useMemories } from "~/lib/hooks/use-memories";
-import { useSpaces } from "~/lib/hooks/use-spaces";
-import { Memory } from "~/lib/types/memory";
-import { cn } from "~/lib/utils";
-
-const variants = ["All Memories", "Web pages", "Tweets", "Documents", "Spaces", "Notes"] as const;
-type Variant = (typeof variants)[number];
-
-interface MemoriesPageProps {
- showAddButtons?: boolean;
- isSpace?: boolean;
-}
-
-interface SelectionContextType {
- isSelectionMode: boolean;
- selectedItems: Set;
- toggleSelection: (uuid: string) => void;
-}
-
-const SelectionContext = createContext(null);
-
-function MemoriesPage({ showAddButtons = true, isSpace = false }: MemoriesPageProps) {
- const isHydrated = useHydrated();
- const { spaceId } = useParams();
- const [selectedVariant, setSelectedVariant] = useState("All Memories");
- const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
- const [isSelectionMode, setIsSelectionMode] = useState(false);
- const [selectedItems, setSelectedItems] = useState>(new Set());
- const [isDeleting, setIsDeleting] = useState(false);
-
- const { memories, isLoading, loadMore, hasMore, mutate } = useMemories(0, 20, spaceId);
-
- const { spaces } = useSpaces();
-
- const handleToggleSelection = useCallback((uuid: string) => {
- setSelectedItems((prev) => {
- const newSet = new Set(prev);
- if (newSet.has(uuid)) {
- newSet.delete(uuid);
- } else {
- newSet.add(uuid);
- }
- return newSet;
- });
- }, []);
-
- const handleBatchDelete = useCallback(async () => {
- if (selectedItems.size === 0) return;
-
- const confirmed = window.confirm(
- `Are you sure you want to delete ${selectedItems.size} item${selectedItems.size > 1 ? "s" : ""}?`,
- );
-
- if (!confirmed) return;
-
- setIsDeleting(true);
- try {
- const response = await fetch("/backend/v1/memories/batch-delete", {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify({ ids: Array.from(selectedItems) }),
- credentials: "include",
- });
-
- if (!response.ok) {
- throw new Error("Failed to delete items");
- }
-
- const data = (await response.json()) as { success: boolean; deletedCount: number };
- toast.success(
- `Successfully deleted ${data.deletedCount} item${data.deletedCount > 1 ? "s" : ""}`,
- );
-
- // Reset selection mode and clear selected items
- setIsSelectionMode(false);
- setSelectedItems(new Set());
-
- // Refresh the memories list
- mutate();
- } catch (error) {
- toast.error(error instanceof Error ? error.message : "Failed to delete items");
- } finally {
- setIsDeleting(false);
- }
- }, [selectedItems, mutate]);
-
- const loadMoreItems = useCallback(
- (startIndex: number, stopIndex: number) => {
- if (!hasMore || isLoading) {
- return Promise.resolve();
- }
- return loadMore();
- },
- [hasMore, isLoading, loadMore],
- );
-
- const maybeLoadMore = useInfiniteLoader(loadMoreItems, {
- isItemLoaded: (index) => !hasMore || index < (memories?.length || 0),
- minimumBatchSize: 20,
- threshold: 6,
- });
-
- // Memoize space items transformation
- const spaceItems = useMemo(() => {
- if (spaceId) return [];
- return spaces
- .filter((space) => space.uuid !== "")
- .map((space) => ({
- id: space.uuid,
- type: "space",
- content: space.name,
- createdAt: new Date(space.createdAt),
- description: null,
- ogImage: null,
- title: space.name,
- url: `/space/${space.uuid}`,
- uuid: space.uuid,
- updatedAt: null,
- raw: null,
- userId: space.ownerId,
- isSuccessfullyProcessed: true,
- }));
- }, [spaces, spaceId]);
-
- // Memoize filtered memories
- const filteredMemories = useMemo(() => {
- const baseMemories = memories || [];
- switch (selectedVariant) {
- case "Web pages":
- return baseMemories.filter((m) => m.type === "page");
- case "Tweets":
- return baseMemories.filter((m) => m.type === "tweet");
- case "Documents":
- return baseMemories.filter((m) => m.type === "document");
- case "Spaces":
- return spaceId ? baseMemories : [];
- case "Notes":
- return baseMemories.filter((m) => m.type === "note");
- default:
- return baseMemories;
- }
- }, [memories, selectedVariant, spaceId]);
-
- // Memoize add button item
- const addButtonItem = useMemo(() => {
- if (!showAddButtons) return [];
- return [
- {
- id: "add-button",
- type: "note",
- content: null,
- createdAt: new Date(),
- description: null,
- ogImage: null,
- title: null,
- url: null,
- uuid: "add-button",
- updatedAt: null,
- raw: null,
- userId: "0",
- isSuccessfullyProcessed: true,
- },
- ];
- }, [showAddButtons]);
-
- // Combine items and generate key
- const { items, key } = useMemo(() => {
- const shouldShowSpaces =
- !isSpace && (selectedVariant === "All Memories" || selectedVariant === "Spaces");
- const allItems = [
- ...addButtonItem,
- ...(shouldShowSpaces ? spaceItems : []),
- ...filteredMemories,
- ];
-
- return {
- items: allItems,
- key: `${selectedVariant || "default"}-${spaceId || "no-space"}-${allItems.length}`,
- };
- }, [addButtonItem, spaceItems, filteredMemories, selectedVariant, spaceId, isSpace]);
-
- const selectionContextValue = useMemo(
- () => ({
- isSelectionMode,
- selectedItems,
- toggleSelection: handleToggleSelection,
- }),
- [isSelectionMode, selectedItems, handleToggleSelection],
- );
-
- const MemoizedSharedCard = memo(
- ({
- data,
- index,
- showAddButtons,
- isSpace,
- }: {
- data: Memory;
- index: number;
- showAddButtons: boolean;
- isSpace: boolean;
- }) => {
- const selection = useContext(SelectionContext);
-
- if (index === 0 && showAddButtons) {
- return ;
- }
- if (data.type === "space") {
- return ;
- }
- return (
- selection?.toggleSelection(data.uuid)}
- />
- );
- },
- (prevProps, nextProps) => {
- // Custom comparison function for memo
- return prevProps.data.uuid === nextProps.data.uuid;
- },
- );
-
- MemoizedSharedCard.displayName = "MemoizedSharedCard";
-
- const renderCard = useCallback(
- ({ data, index }: { data: Memory; index: number }) => (
-
- ),
- [showAddButtons, isSpace],
- );
-
- const handleVariantClick = useCallback((variant: Variant) => {
- setSelectedVariant(variant);
- setIsMobileMenuOpen(false);
- if (variant === "Spaces") {
- setIsSelectionMode(false);
- setSelectedItems(new Set());
- }
- }, []);
-
- const SelectionControls = useMemo(
- () => (
-
- {selectedVariant !== "Spaces" && (
- <>
- {
- setIsSelectionMode(!isSelectionMode);
- if (!isSelectionMode) {
- setSelectedItems(new Set());
- }
- }}
- >
- {isSelectionMode ? "Cancel Selection" : "Select Items"}
-
- {isSelectionMode && (
- <>
- {
- // Get all non-space items' UUIDs
- const allUuids = filteredMemories
- .filter((item) => item.type !== "space")
- .map((item) => item.uuid);
-
- // If all items are selected, clear selection
- if (allUuids.every((uuid) => selectedItems.has(uuid))) {
- setSelectedItems(new Set());
- } else {
- // Otherwise, select all items
- setSelectedItems(new Set(allUuids));
- }
- }}
- >
- {filteredMemories.every(
- (item) => item.type === "space" || selectedItems.has(item.uuid),
- )
- ? "Deselect All"
- : "Select All"}
-
-
-
- {isDeleting ? "Deleting..." : `Delete Selected (${selectedItems.size})`}
-
- >
- )}
- >
- )}
-
- ),
- [
- isSelectionMode,
- selectedItems.size,
- isDeleting,
- handleBatchDelete,
- selectedVariant,
- filteredMemories,
- selectedItems,
- ],
- );
-
- const MobileVariantButton = useMemo(
- () => (
- setIsMobileMenuOpen((prev) => !prev)}
- >
- {selectedVariant} βΌ
-
- ),
- [selectedVariant],
- );
-
- const MobileVariantMenu = useMemo(
- () => (
-
-
- {variants
- .filter((variant) => !(isSpace && variant === "Spaces"))
- .map((variant) => (
- handleVariantClick(variant)}
- className={cn(
- "text-muted-foreground hover:bg-accent hover:text-foreground text-base w-full py-4 rounded-lg transition-colors",
- selectedVariant === variant
- ? "bg-accent text-foreground font-medium shadow-sm"
- : "hover:shadow-sm",
- )}
- >
- {variant}
-
- ))}
-
-
- ),
- [selectedVariant, isMobileMenuOpen, handleVariantClick, isSpace],
- );
-
- const DesktopVariantMenu = useMemo(
- () => (
-
- {variants
- .filter((variant) => !(isSpace && variant === "Spaces"))
- .map((variant) => (
- setSelectedVariant(variant)}
- className={cn(
- "text-muted-foreground hover:bg-accent hover:text-foreground text-base",
- selectedVariant === variant ? "bg-accent text-foreground" : "",
- )}
- >
- {variant}
-
- ))}
-
- ),
- [selectedVariant, isSpace],
- );
-
- if (!isHydrated) return null;
-
- return (
-
-
-
- {MobileVariantButton}
- {MobileVariantMenu}
- {DesktopVariantMenu}
-
-
- {SelectionControls}
-
-
-
- {isLoading &&
Loading more...
}
-
-
- );
-}
-
-export default MemoriesPage;
diff --git a/apps/web/app/components/memories/SharedCard.tsx b/apps/web/app/components/memories/SharedCard.tsx
deleted file mode 100644
index 04ba769b..00000000
--- a/apps/web/app/components/memories/SharedCard.tsx
+++ /dev/null
@@ -1,892 +0,0 @@
-import * as ReactTweet from "react-tweet";
-import { memo, useCallback, useEffect, useMemo, useState } from "react";
-import { useInView } from "react-intersection-observer";
-import { TweetSkeleton } from "react-tweet";
-
-import { useNavigate, useParams } from "@remix-run/react";
-
-import { NotionIcon } from "../icons/IntegrationIcons";
-import { CustomTwitterComp } from "../twitter/render-tweet";
-import Loader from "../ui/Loader";
-import { Button, ButtonProps } from "../ui/button";
-import { Card } from "../ui/card";
-import { Checkbox } from "../ui/checkbox";
-import {
- Command,
- CommandEmpty,
- CommandGroup,
- CommandInput,
- CommandItem,
- CommandList,
-} from "../ui/command";
-import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuGroup,
- DropdownMenuItem,
- DropdownMenuLabel,
- DropdownMenuPortal,
- DropdownMenuSeparator,
- DropdownMenuSub,
- DropdownMenuSubContent,
- DropdownMenuSubTrigger,
- DropdownMenuTrigger,
-} from "../ui/dropdown-menu";
-
-import { FileIcon } from "@radix-ui/react-icons";
-import { SpaceIcon } from "@supermemory/shared/icons";
-import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
-import { FastAverageColor } from "fast-average-color";
-import { MenuIcon, TrashIcon } from "lucide-react";
-import { FolderIcon, MoreVertical, Trash } from "lucide-react";
-import { toast } from "sonner";
-import { pastelColors } from "~/lib/constants/pastelColors";
-import { typeIcons } from "~/lib/constants/typeIcons";
-import { ExtraSpaceMetaData, fetchSpaces } from "~/lib/hooks/use-spaces";
-import { useTextOverflow } from "~/lib/hooks/use-text-overflow";
-import { Memory, WebsiteMetadata } from "~/lib/types/memory";
-import { cn } from "~/lib/utils";
-
-const { useTweet } = ReactTweet;
-
-export const typeDecider = (content: string) => {
- try {
- // If it's a tweet URL
- if (content.match(/https?:\/\/(x\.com|twitter\.com)\/[\w]+\/[\w]+\/[\d]+/)) {
- return "tweet";
- }
- // If it's a document
- if (content.match(/\.(pdf|doc|docx|txt|rtf|odt|md)/i)) {
- return "document";
- }
- // If it's a Notion URL
- if (content.match(/https?:\/\/(www\.)?notion\.so/)) {
- return "notion";
- }
- // If it's any other URL
- if (content.match(/^(https?:\/\/)?(www\.)?[a-z0-9]+([-.]{1}[a-z0-9]+)*\.[a-z]{2,5}(\/.*)?$/i)) {
- return "page";
- }
- // Otherwise it's a note
- return "note";
- } catch (e) {
- console.error("[Decide Type Error]", e);
- return "note";
- }
-};
-
-// Create a cache to store fetched metadata
-const metadataCache: Record = {};
-
-const renderContent = {
- tweet: ({ data: ourData }: { data: Memory }) => {
- // If content starts with , parse the JSON inside
- if (ourData.content?.startsWith("")) {
- const rawContent = ourData.content.replace(/<\/?raw>/g, "");
- try {
- const parsedData = JSON.parse(rawContent);
- return ;
- } catch (error) {
- console.error("Error parsing raw tweet data:", error);
- return (
- Error parsing tweet data. {rawContent}
- );
- }
- }
-
- // Otherwise use normal tweet ID flow
- const tweetId = ourData.url?.match(/\/status\/(\d+)/)?.[1] ?? ourData.url;
- const { data, error } = useTweet(tweetId ?? undefined);
-
- if (error) {
- console.error("Error parsing tweet:", error);
- console.log("Tweet ID:", tweetId);
- return (
-
- Error parsing tweet. {tweetId} {JSON.stringify(error)}
-
- );
- }
-
- if (!data || typeof data == "undefined") {
- return ;
- }
-
- return ;
- },
-
- page: ({ data }: { data: Memory }) => (
-
- ),
-
- note: ({ data }: { data: Memory }) => {
- const { contentRef, showFade } = useTextOverflow(data.content ?? "", 5);
-
- // Use a constant color for id 0, otherwise select based on content length
- const color = useMemo(
- () =>
- data.id === 0
- ? pastelColors[0]
- : pastelColors[(data.content?.length ?? 0) % pastelColors.length],
- [data.content, data.id],
- );
-
- const formattedDate = new Date(data.createdAt).toLocaleDateString("en-US", {
- month: "short",
- day: "numeric",
- year: "numeric",
- });
-
- return (
-
-
- {data.content}
-
- {showFade &&
}
-
-
-
- );
- },
-
- notion: ({ data }: { data: Memory }) => {
- const { contentRef, showFade } = useTextOverflow(data.content ?? "", 5);
- const formattedDate = new Date(data.createdAt).toLocaleDateString("en-US", {
- month: "short",
- day: "numeric",
- year: "numeric",
- });
-
- return (
-
-
-
- Notion Page
-
-
-
- {data.content}
-
- {showFade &&
}
-
-
-
- {formattedDate}
-
-
-
-
-
-
-
-
-
- );
- },
-
- space: ({ data }: { data: Memory & Partial }) => {
- return (
-
-
-
- Space
-
-
- {data.content}
-
-
-
- {data.permissions?.isPublic ? (
-
- ) : (
-
- )}
-
- {data.favorited && (
-
- )}
-
-
- {data.owner ? (
- <>
-
- {data.permissions?.canRead && !data.permissions.canEdit && (
-
- Can Read
-
- )}
- {data.permissions?.canEdit && (
-
- Can Edit
-
- )}
-
-
-
- {data.owner.profileImage ? (
-
- ) : (
-
- )}
-
{data.owner.name}
-
- >
- ) : null}
-
-
- );
- },
-
- document: ({ data }: { data: Memory }) => {
- // just render the document like normally
- // and get the name from the url
-
- // TODO: This can be improved
- return (
-
-
-
-
- Document
-
- {decodeURIComponent(data.url?.split("/").pop() ?? "")}
-
-
-
-
- );
- },
-};
-
-async function fetchWebsiteMetadata(url: string): Promise {
- // Check if metadata is already in cache
- if (metadataCache[url]) {
- return metadataCache[url];
- }
-
- // Add http:// if not present
- if (!url.startsWith("http://") && !url.startsWith("https://")) {
- url = "http://" + url;
- }
-
- try {
- const controller = new AbortController();
- const timeoutId = setTimeout(() => controller.abort(), 5000); // 5 second timeout
-
- const response = await fetch(`/api/metadata?url=${encodeURIComponent(url)}`, {
- signal: controller.signal,
- });
-
- clearTimeout(timeoutId);
-
- if (!response.ok) {
- throw new Error("Failed to fetch metadata");
- }
-
- const metadata = (await response.json()) as WebsiteMetadata;
-
- if (metadata.image) {
- try {
- const fac = new FastAverageColor();
- const color = await fac.getColorAsync(metadata.image, {
- algorithm: "dominant",
- crossOrigin: "anonymous",
- mode: "speed",
- });
- metadata.dominantColor = color.hex;
- metadata.isDark = color.isDark;
- } catch (error) {
- console.error("Error getting dominant color:", error);
- // Fallback to a default color if there's an error
- metadata.dominantColor = "#CFCFCF";
- metadata.isDark = false;
- }
- } else {
- metadata.dominantColor = "#CFCFCF";
- metadata.isDark = false;
- }
-
- // Store the fetched metadata in cache
- metadataCache[url] = metadata;
- return metadata;
- } catch (error) {
- console.error("Error fetching metadata:", error);
- return {
- title: "Unknown",
- description: "No description available",
- image: "",
- dominantColor: "#CFCFCF",
- isDark: false,
- };
- }
-}
-
-const WebsiteCard = memo(
- ({
- url,
- title,
- description,
- image,
- id,
- }: {
- url: string;
- title?: string | null;
- description?: string | null;
- image?: string | null;
- id: string;
- }) => {
- // Memoize domain extraction to avoid recalculation
- const domain = useMemo(() => {
- try {
- let formattedUrl = url;
- if (!formattedUrl.startsWith("http")) {
- formattedUrl = "http://" + formattedUrl;
- }
- return new URL(formattedUrl).hostname.replace(/^www\./, "");
- } catch {
- return url;
- }
- }, [url]);
-
- // Memoize initial color based on URL
- const initialColor = useMemo(() => {
- if (!image) {
- const hash = url.split("").reduce((acc, char) => {
- return char.charCodeAt(0) + ((acc << 5) - acc);
- }, 0);
- return `hsl(${hash % 360}, 70%, 85%)`; // Slightly lighter base color
- }
- return "#f0f0f0"; // Lighter default color
- }, [url, image]);
-
- const [dominantColor, setDominantColor] = useState(initialColor);
- const [isDark, setIsDark] = useState(false);
- // Only calculate dominant color when component is in view
- useEffect(() => {
- if (image) {
- const fac = new FastAverageColor();
- fac
- .getColorAsync(image, {
- algorithm: "dominant",
- crossOrigin: "anonymous",
- mode: "speed",
- })
- .then((color) => {
- setDominantColor(color.hex);
- setIsDark(color.isDark);
- })
- .catch((error) => {
- console.error("Error getting dominant color:", error);
- });
- }
- }, [image]);
-
- const displayTitle = title || domain;
- const displayDescription = description || `Saved from ${domain}`;
-
- return (
-
-
- {image && (
-
-
-
-
- )}
-
-
-
- );
- },
-);
-
-export function FetchAndRenderContent({ content }: { content: string }) {
- const [memory, setMemory] = useState(null);
- const [isLoading, setIsLoading] = useState(false);
-
- useEffect(() => {
- const controller = new AbortController();
- const timeoutId = setTimeout(() => controller.abort(), 5000); // 5 second timeout
-
- (async () => {
- const type = typeDecider(content);
-
- if (type !== "page") {
- const item: Memory = {
- type: type,
- content: content,
- createdAt: new Date(),
- description: null,
- id: 0,
- ogImage: null,
- title: null,
- url: null,
- uuid: "",
- updatedAt: null,
- raw: null,
- userId: 0,
- isSuccessfullyProcessed: true,
- errorMessage: null,
- contentHash: null,
- metadata: null,
- };
- setMemory(item);
- return;
- }
-
- try {
- setIsLoading(true);
- const metadata = await fetchWebsiteMetadata(content);
-
- const item: Memory = {
- type: type,
- content: content,
- createdAt: new Date(),
- description: metadata?.description ?? null,
- id: 0,
- ogImage: metadata?.image ?? null,
- title: metadata?.title ?? null,
- url: content,
- uuid: "",
- updatedAt: null,
- raw: null,
- userId: 0,
- isSuccessfullyProcessed: true,
- errorMessage: null,
- contentHash: null,
- metadata: null,
- };
- setMemory(item);
- } catch (error) {
- // If metadata fetch fails, create memory with basic URL info
- const item: Memory = {
- type: type,
- content: content,
- createdAt: new Date(),
- description: null,
- id: 0,
- ogImage: null,
- title: content,
- url: content,
- uuid: "",
- updatedAt: null,
- raw: null,
- userId: 0,
- isSuccessfullyProcessed: false,
- errorMessage: null,
- contentHash: null,
- metadata: null,
- };
- setMemory(item);
- } finally {
- setIsLoading(false);
- clearTimeout(timeoutId);
- }
- })();
-
- return () => {
- clearTimeout(timeoutId);
- controller.abort();
- };
- }, [content]);
-
- if (isLoading) {
- return Loading website metadata...
;
- }
-
- return memory ? : null;
-}
-
-interface SharedCardProps {
- data: Memory;
- isSelectionMode?: boolean;
- isSelected?: boolean;
- onToggleSelect?: () => void;
-}
-
-export default function SharedCard({
- data,
- isSelectionMode,
- isSelected,
- onToggleSelect,
-}: SharedCardProps) {
- const queryClient = useQueryClient();
- const navigate = useNavigate();
-
- // Flatten the data if it's a nested array and get the first item
- if (Array.isArray(data)) {
- console.log("weird data here, will try flattening.", data);
- data = data.flat(Infinity)[0];
- }
-
- const ContentRenderer =
- renderContent[data.type as keyof typeof renderContent] ||
- (() => {
- console.log("SharedCard data", data);
- return (
-
- Unsupported content type: {typeof data.type === "undefined" ? "undefined" : data.type}
-
- );
- });
-
- // Delete mutation
- const deleteMutation = useMutation({
- mutationFn: async (id: number) => {
- const response = await fetch(`/backend/v1/memories/${id}`, {
- method: "DELETE",
- credentials: "include",
- });
- if (!response.ok) {
- throw new Error("Failed to delete memory");
- }
- return response.json();
- },
- onMutate: async (id) => {
- // Cancel outgoing refetches
- await queryClient.cancelQueries({ queryKey: ["memories"] });
-
- // Snapshot the previous value
- const previousMemories = queryClient.getQueryData(["memories"]);
-
- // Optimistically remove the memory
- queryClient.setQueryData(["memories"], (old: any) => {
- return old?.filter((memory: Memory) => memory.id !== id);
- });
-
- return { previousMemories };
- },
- onError: (err, variables, context) => {
- // Revert the optimistic update
- queryClient.setQueryData(["memories"], context?.previousMemories);
- toast.error("Failed to delete memory");
- },
- onSuccess: () => {
- toast.success("Memory deleted successfully");
- queryClient.invalidateQueries({ queryKey: ["memories"] });
- queryClient.invalidateQueries({ queryKey: ["spaces"] });
- },
- });
-
- // Move to space mutation
- const moveToSpaceMutation = useMutation({
- mutationFn: async ({ spaceId, documentId }: { spaceId: string; documentId: string }) => {
- const response = await fetch("/backend/v1/spaces/moveContent", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- credentials: "include",
- body: JSON.stringify({ spaceId, documentId }),
- });
- if (!response.ok) {
- throw new Error("Failed to move memory");
- }
- return response.json() as Promise<{ spaceId: string }>;
- },
- onError: (err) => {
- toast.error("Failed to move memory to space");
- },
- onSuccess: ({ spaceId }: { spaceId: string }) => {
- toast.success("Memory moved successfully");
- queryClient.invalidateQueries({ queryKey: ["memories"] });
- queryClient.invalidateQueries({ queryKey: ["spaces"] });
- if (spaceId === "") {
- return navigate("/");
- }
- return navigate(`/space/${spaceId}`);
- },
- });
-
- const handleDelete = (e?: Event) => {
- if (e) {
- e.preventDefault();
- e.stopPropagation();
- }
- if (window.confirm("Are you sure you want to delete this memory?")) {
- deleteMutation.mutate(data.id);
- }
- };
-
- const handleMoveToSpace = (spaceId: string) => {
- moveToSpaceMutation.mutate({
- spaceId,
- documentId: data.uuid,
- });
- };
-
- const handleClick = (e: React.MouseEvent) => {
- if (isSelectionMode && onToggleSelect) {
- e.preventDefault();
- onToggleSelect();
- return;
- }
- };
-
- return (
- {
- switch (data.type) {
- case "note":
- return "border-primary/30";
- case "document":
- return "border-secondary/30";
- default:
- return "border-accent/30";
- }
- })(),
- isSelectionMode && "hover:ring-2 hover:ring-primary",
- isSelected && "ring-2 ring-primary bg-primary/5",
- )}
- onClick={handleClick}
- >
- {isSelectionMode ? (
-
-
-
- ) : (
- data.type !== "space" && (
-
-
-
-
-
-
-
-
- Move to ...
-
-
-
-
- handleDelete(e)} asChild>
-
- Delete
-
-
-
-
- )
- )}
-
-
- );
-}
-
-export const SpaceSelector = function SpaceSelector({
- contentId,
- onSelect,
-}: {
- contentId: number;
- onSelect: (spaceId: string) => void;
-}) {
- const [search, setSearch] = useState("");
- const { spaceId } = useParams();
-
- console.log(spaceId);
-
- const {
- data: spacesData,
- isLoading,
- error,
- } = useQuery({
- queryKey: ["spaces"],
- queryFn: fetchSpaces,
- staleTime: 5 * 60 * 1000, // Consider data fresh for 5 minutes
- });
-
- const filteredSpaces = useMemo(() => {
- if (!spacesData?.spaces) return [];
- return spacesData.spaces.filter(
- (space) =>
- space.name.toLowerCase().includes(search.toLowerCase()) &&
- space.uuid !== (spaceId ? spaceId.split("---")[0] : ""),
- );
- }, [spacesData?.spaces, search]);
-
- if (isLoading) {
- return (
-
-
-
-
- Loading spaces...
-
-
-
- );
- }
-
- if (error) {
- return (
-
-
-
- Error: {error instanceof Error ? error.message : "Failed to load spaces"}
-
-
-
- );
- }
-
- return (
-
-
-
-
-
- {filteredSpaces.map((space) => (
- onSelect(space.uuid)}
- >
-
-
- {space.name}
-
-
- ))}
- {filteredSpaces.length === 0 && No spaces found. }
-
-
-
-
- );
-};
-
-const MemoizedSpaceSelector = memo(SpaceSelector);
diff --git a/apps/web/app/components/memories/SpacesSelector.tsx b/apps/web/app/components/memories/SpacesSelector.tsx
deleted file mode 100644
index f8581946..00000000
--- a/apps/web/app/components/memories/SpacesSelector.tsx
+++ /dev/null
@@ -1,134 +0,0 @@
-import React from "react";
-
-import { SpaceIcon } from "@supermemory/shared/icons";
-
-import { Check, ChevronsUpDown, X } from "lucide-react";
-import { Badge } from "~/components/ui/badge";
-import { Button } from "~/components/ui/button";
-import {
- Command,
- CommandEmpty,
- CommandGroup,
- CommandInput,
- CommandItem,
-} from "~/components/ui/command";
-import { Popover, PopoverContent, PopoverTrigger } from "~/components/ui/popover";
-import { useSpaces } from "~/lib/hooks/use-spaces";
-import { cn } from "~/lib/utils";
-
-function SpacesSelector({
- selectedSpaces = [],
- onChange,
-}: {
- selectedSpaces?: string[];
- onChange?: (spaces: string[]) => void;
-}) {
- const { spaces, isLoading } = useSpaces();
- const [open, setOpen] = React.useState(false);
-
- const handleSelect = (currentValue: string) => {
- if (!onChange || !spaces) return;
-
- const selectedSpace = spaces.find(
- (space) => space.name.toLowerCase() === currentValue.toLowerCase(),
- );
- if (!selectedSpace) return;
-
- const spaceId = selectedSpace.uuid;
- if (selectedSpaces.includes(spaceId)) {
- onChange(selectedSpaces.filter((id) => id !== spaceId));
- } else {
- onChange([...selectedSpaces, spaceId]);
- }
- setOpen(false);
- };
-
- const handleRemove = (e: React.MouseEvent, spaceId: string) => {
- e.stopPropagation();
- if (!onChange) return;
- onChange(selectedSpaces.filter((id) => id !== spaceId));
- };
-
- return (
-
-
-
-
-
- {isLoading ? (
-
Loading...
- ) : selectedSpaces.length === 0 ? (
-
Space
- ) : (
-
- {selectedSpaces.slice(0, 2).map((spaceId) => {
- const space = spaces?.find((s) => s.uuid === spaceId);
- if (!space) return null;
- return (
-
- {space.name}
- handleRemove(e, spaceId)}
- />
-
- );
- })}
- {selectedSpaces.length > 2 && (
-
- +{selectedSpaces.length - 2} more
-
- )}
-
- )}
-
- {/* Mobile badge count */}
- {selectedSpaces.length > 0 && (
-
- {selectedSpaces.length}
-
- )}
-
-
-
-
-
-
- No spaces found.
-
- {spaces?.map((space) => (
-
-
-
- {space.name}
- {space.isPublic && (
-
- Public
-
- )}
-
-
- ))}
-
-
-
-
- );
-}
-
-export default SpacesSelector;
diff --git a/apps/web/app/components/plate-ui/ai-chat-editor.tsx b/apps/web/app/components/plate-ui/ai-chat-editor.tsx
deleted file mode 100644
index a34755a0..00000000
--- a/apps/web/app/components/plate-ui/ai-chat-editor.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-'use client';
-
-import React, { memo } from 'react';
-
-import { AIChatPlugin, useLastAssistantMessage } from '@udecode/plate-ai/react';
-import {
- type PlateEditor,
- Plate,
- useEditorPlugin,
-} from '@udecode/plate-common/react';
-import { deserializeMd } from '@udecode/plate-markdown';
-
-import { Editor } from './editor';
-
-export const AIChatEditor = memo(
- ({
- aiEditorRef,
- }: {
- aiEditorRef: React.MutableRefObject;
- }) => {
- const { getOptions } = useEditorPlugin(AIChatPlugin);
- const lastAssistantMessage = useLastAssistantMessage();
- const content = lastAssistantMessage?.content ?? '';
-
- const aiEditor = React.useMemo(() => {
- const editor = getOptions().createAIEditor();
-
- const fragment = deserializeMd(editor, content);
- editor.children =
- fragment.length > 0 ? fragment : editor.api.create.value();
-
- return editor;
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, []);
-
- React.useEffect(() => {
- if (aiEditor && content) {
- aiEditorRef.current = aiEditor;
-
- setTimeout(() => {
- aiEditor.tf.setValue(deserializeMd(aiEditor, content));
- }, 0);
- }
- }, [aiEditor, aiEditorRef, content]);
-
- if (!content) return null;
-
- return (
-
-
-
- );
- }
-);
diff --git a/apps/web/app/components/plate-ui/ai-leaf.tsx b/apps/web/app/components/plate-ui/ai-leaf.tsx
deleted file mode 100644
index 0080ac45..00000000
--- a/apps/web/app/components/plate-ui/ai-leaf.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import { cn, withRef } from '@udecode/cn';
-import { PlateLeaf } from '@udecode/plate-common/react';
-
-export const AILeaf = withRef(
- ({ children, className, ...props }, ref) => {
- return (
-
- {children}
-
- );
- }
-);
diff --git a/apps/web/app/components/plate-ui/ai-menu-items.tsx b/apps/web/app/components/plate-ui/ai-menu-items.tsx
deleted file mode 100644
index a00f8f54..00000000
--- a/apps/web/app/components/plate-ui/ai-menu-items.tsx
+++ /dev/null
@@ -1,301 +0,0 @@
-'use client';
-
-import { useEffect, useMemo } from 'react';
-
-import { AIChatPlugin, AIPlugin } from '@udecode/plate-ai/react';
-import {
- getAncestorNode,
- getEndPoint,
- getNodeString,
-} from '@udecode/plate-common';
-import {
- type PlateEditor,
- focusEditor,
- useEditorPlugin,
-} from '@udecode/plate-common/react';
-import { useIsSelecting } from '@udecode/plate-selection/react';
-import {
- Album,
- BadgeHelp,
- Check,
- CornerUpLeft,
- FeatherIcon,
- ListEnd,
- ListMinus,
- ListPlus,
- PenLine,
- Wand,
- X,
-} from 'lucide-react';
-
-import { CommandGroup, CommandItem } from './command';
-
-export type EditorChatState =
- | 'cursorCommand'
- | 'cursorSuggestion'
- | 'selectionCommand'
- | 'selectionSuggestion';
-
-export const aiChatItems = {
- accept: {
- icon: ,
- label: 'Accept',
- value: 'accept',
- onSelect: ({ editor }) => {
- editor.getTransforms(AIChatPlugin).aiChat.accept();
- focusEditor(editor, getEndPoint(editor, editor.selection!));
- },
- },
- continueWrite: {
- icon: ,
- label: 'Continue writing',
- value: 'continueWrite',
- onSelect: ({ editor }) => {
- const ancestorNode = getAncestorNode(editor);
-
- if (!ancestorNode) return;
-
- const isEmpty = getNodeString(ancestorNode[0]).trim().length === 0;
-
- void editor.getApi(AIChatPlugin).aiChat.submit({
- mode: 'insert',
- prompt: isEmpty
- ? `
-{editor}
-
-Start writing a new paragraph AFTER ONLY ONE SENTENCE`
- : 'Continue writing AFTER ONLY ONE SENTENCE. DONT REPEAT THE TEXT.',
- });
- },
- },
- discard: {
- icon: ,
- label: 'Discard',
- shortcut: 'Escape',
- value: 'discard',
- onSelect: ({ editor }) => {
- editor.getTransforms(AIPlugin).ai.undo();
- editor.getApi(AIChatPlugin).aiChat.hide();
- },
- },
- explain: {
- icon: ,
- label: 'Explain',
- value: 'explain',
- onSelect: ({ editor }) => {
- void editor.getApi(AIChatPlugin).aiChat.submit({
- prompt: {
- default: 'Explain {editor}',
- selecting: 'Explain',
- },
- });
- },
- },
- fixSpelling: {
- icon: ,
- label: 'Fix spelling & grammar',
- value: 'fixSpelling',
- onSelect: ({ editor }) => {
- void editor.getApi(AIChatPlugin).aiChat.submit({
- prompt: 'Fix spelling and grammar',
- });
- },
- },
- improveWriting: {
- icon: ,
- label: 'Improve writing',
- value: 'improveWriting',
- onSelect: ({ editor }) => {
- void editor.getApi(AIChatPlugin).aiChat.submit({
- prompt: 'Improve the writing',
- });
- },
- },
- insertBelow: {
- icon: ,
- label: 'Insert below',
- value: 'insertBelow',
- onSelect: ({ aiEditor, editor }) => {
- void editor.getTransforms(AIChatPlugin).aiChat.insertBelow(aiEditor);
- },
- },
- makeLonger: {
- icon: ,
- label: 'Make longer',
- value: 'makeLonger',
- onSelect: ({ editor }) => {
- void editor.getApi(AIChatPlugin).aiChat.submit({
- prompt: 'Make longer',
- });
- },
- },
- makeShorter: {
- icon: ,
- label: 'Make shorter',
- value: 'makeShorter',
- onSelect: ({ editor }) => {
- void editor.getApi(AIChatPlugin).aiChat.submit({
- prompt: 'Make shorter',
- });
- },
- },
- replace: {
- icon: ,
- label: 'Replace selection',
- value: 'replace',
- onSelect: ({ aiEditor, editor }) => {
- void editor.getTransforms(AIChatPlugin).aiChat.replaceSelection(aiEditor);
- },
- },
- simplifyLanguage: {
- icon: ,
- label: 'Simplify language',
- value: 'simplifyLanguage',
- onSelect: ({ editor }) => {
- void editor.getApi(AIChatPlugin).aiChat.submit({
- prompt: 'Simplify the language',
- });
- },
- },
- summarize: {
- icon: ,
- label: 'Add a summary',
- value: 'summarize',
- onSelect: ({ editor }) => {
- void editor.getApi(AIChatPlugin).aiChat.submit({
- mode: 'insert',
- prompt: {
- default: 'Summarize {editor}',
- selecting: 'Summarize',
- },
- });
- },
- },
- tryAgain: {
- icon: ,
- label: 'Try again',
- value: 'tryAgain',
- onSelect: ({ editor }) => {
- void editor.getApi(AIChatPlugin).aiChat.reload();
- },
- },
-} satisfies Record<
- string,
- {
- icon: React.ReactNode;
- label: string;
- value: string;
- component?: React.ComponentType<{ menuState: EditorChatState }>;
- filterItems?: boolean;
- items?: { label: string; value: string }[];
- shortcut?: string;
- onSelect?: ({
- aiEditor,
- editor,
- }: {
- aiEditor: PlateEditor;
- editor: PlateEditor;
- }) => void;
- }
->;
-
-const menuStateItems: Record<
- EditorChatState,
- {
- items: (typeof aiChatItems)[keyof typeof aiChatItems][];
- heading?: string;
- }[]
-> = {
- cursorCommand: [
- {
- items: [
- aiChatItems.continueWrite,
- aiChatItems.summarize,
- aiChatItems.explain,
- ],
- },
- ],
- cursorSuggestion: [
- {
- items: [aiChatItems.accept, aiChatItems.discard, aiChatItems.tryAgain],
- },
- ],
- selectionCommand: [
- {
- items: [
- aiChatItems.improveWriting,
- aiChatItems.makeLonger,
- aiChatItems.makeShorter,
- aiChatItems.fixSpelling,
- aiChatItems.simplifyLanguage,
- ],
- },
- ],
- selectionSuggestion: [
- {
- items: [
- aiChatItems.replace,
- aiChatItems.insertBelow,
- aiChatItems.discard,
- aiChatItems.tryAgain,
- ],
- },
- ],
-};
-
-export const AIMenuItems = ({
- aiEditorRef,
- setValue,
-}: {
- aiEditorRef: React.MutableRefObject;
- setValue: (value: string) => void;
-}) => {
- const { editor, useOption } = useEditorPlugin(AIChatPlugin);
- const { messages } = useOption('chat');
- const isSelecting = useIsSelecting();
-
- const menuState = useMemo(() => {
- if (messages && messages.length > 0) {
- return isSelecting ? 'selectionSuggestion' : 'cursorSuggestion';
- }
-
- return isSelecting ? 'selectionCommand' : 'cursorCommand';
- }, [isSelecting, messages]);
-
- const menuGroups = useMemo(() => {
- const items = menuStateItems[menuState];
-
- return items;
- }, [menuState]);
-
- useEffect(() => {
- if (menuGroups.length > 0 && menuGroups[0].items.length > 0) {
- setValue(menuGroups[0].items[0].value);
- }
- }, [menuGroups, setValue]);
-
- return (
- <>
- {menuGroups.map((group, index) => (
-
- {group.items.map((menuItem) => (
- {
- menuItem.onSelect?.({
- aiEditor: aiEditorRef.current!,
- editor: editor,
- });
- }}
- >
- {menuItem.icon}
- {menuItem.label}
-
- ))}
-
- ))}
- >
- );
-};
diff --git a/apps/web/app/components/plate-ui/ai-menu.tsx b/apps/web/app/components/plate-ui/ai-menu.tsx
deleted file mode 100644
index 37ed2d75..00000000
--- a/apps/web/app/components/plate-ui/ai-menu.tsx
+++ /dev/null
@@ -1,165 +0,0 @@
-'use client';
-
-import * as React from 'react';
-
-import { AIChatPlugin, useEditorChat } from '@udecode/plate-ai/react';
-import {
- type TElement,
- type TNodeEntry,
- getAncestorNode,
- getBlocks,
- isElementEmpty,
- isHotkey,
- isSelectionAtBlockEnd,
-} from '@udecode/plate-common';
-import {
- type PlateEditor,
- toDOMNode,
- useEditorPlugin,
- useHotkeys,
-} from '@udecode/plate-common/react';
-import {
- BlockSelectionPlugin,
- useIsSelecting,
-} from '@udecode/plate-selection/react';
-import { Loader2Icon } from 'lucide-react';
-
-import { useChat } from '~/components/editor/use-chat';
-
-import { AIChatEditor } from './ai-chat-editor';
-import { AIMenuItems } from './ai-menu-items';
-import { Command, CommandList, InputCommand } from './command';
-import { Popover, PopoverAnchor, PopoverContent } from './popover';
-
-export function AIMenu() {
- const { api, editor, useOption } = useEditorPlugin(AIChatPlugin);
- const open = useOption('open');
- const mode = useOption('mode');
- const isSelecting = useIsSelecting();
-
- const aiEditorRef = React.useRef(null);
- const [value, setValue] = React.useState('');
-
- const chat = useChat();
-
- const { input, isLoading, messages, setInput } = chat;
- const [anchorElement, setAnchorElement] = React.useState(
- null
- );
-
- const setOpen = (open: boolean) => {
- if (open) {
- api.aiChat.show();
- } else {
- api.aiChat.hide();
- }
- };
-
- const show = (anchorElement: HTMLElement) => {
- setAnchorElement(anchorElement);
- setOpen(true);
- };
-
- useEditorChat({
- chat,
- onOpenBlockSelection: (blocks: TNodeEntry[]) => {
- show(toDOMNode(editor, blocks.at(-1)![0])!);
- },
- onOpenChange: (open) => {
- if (!open) {
- setAnchorElement(null);
- setInput('');
- }
- },
- onOpenCursor: () => {
- const ancestor = getAncestorNode(editor)?.[0] as TElement;
-
- if (!isSelectionAtBlockEnd(editor) && !isElementEmpty(editor, ancestor)) {
- editor
- .getApi(BlockSelectionPlugin)
- .blockSelection.addSelectedRow(ancestor.id as string);
- }
-
- show(toDOMNode(editor, ancestor)!);
- },
- onOpenSelection: () => {
- show(toDOMNode(editor, getBlocks(editor).at(-1)![0])!);
- },
- });
-
- useHotkeys(
- 'meta+j',
- () => {
- api.aiChat.show();
- },
- { enableOnContentEditable: true, enableOnFormTags: true }
- );
-
- return (
-
-
-
- {
- e.preventDefault();
-
- if (isLoading) {
- api.aiChat.stop();
- } else {
- api.aiChat.hide();
- }
- }}
- align="center"
- avoidCollisions={false}
- side="bottom"
- >
-
- {mode === 'chat' && isSelecting && messages.length > 0 && (
-
- )}
-
- {isLoading ? (
-
-
- {messages.length > 1 ? 'Editing...' : 'Thinking...'}
-
- ) : (
- {
- if (isHotkey('backspace')(e) && input.length === 0) {
- e.preventDefault();
- api.aiChat.hide();
- }
- if (isHotkey('enter')(e) && !e.shiftKey && !value) {
- e.preventDefault();
- void api.aiChat.submit();
- }
- }}
- onValueChange={setInput}
- placeholder="Ask AI anything..."
- data-plate-focus
- autoFocus
- />
- )}
-
- {!isLoading && (
-
-
-
- )}
-
-
-
- );
-}
diff --git a/apps/web/app/components/plate-ui/ai-toolbar-button.tsx b/apps/web/app/components/plate-ui/ai-toolbar-button.tsx
deleted file mode 100644
index 566d86b2..00000000
--- a/apps/web/app/components/plate-ui/ai-toolbar-button.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import { withRef } from '@udecode/cn';
-import { AIChatPlugin } from '@udecode/plate-ai/react';
-import { useEditorPlugin } from '@udecode/plate-common/react';
-
-import { ToolbarButton } from './toolbar';
-
-export const AIToolbarButton = withRef(
- ({ children, ...rest }, ref) => {
- const { api } = useEditorPlugin(AIChatPlugin);
-
- return (
- {
- api.aiChat.show();
- }}
- onMouseDown={(e) => {
- e.preventDefault();
- }}
- >
- {children}
-
- );
- }
-);
diff --git a/apps/web/app/components/plate-ui/align-dropdown-menu.tsx b/apps/web/app/components/plate-ui/align-dropdown-menu.tsx
deleted file mode 100644
index e0764690..00000000
--- a/apps/web/app/components/plate-ui/align-dropdown-menu.tsx
+++ /dev/null
@@ -1,75 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';
-
-import {
- useAlignDropdownMenu,
- useAlignDropdownMenuState,
-} from '@udecode/plate-alignment/react';
-import {
- AlignCenterIcon,
- AlignJustifyIcon,
- AlignLeftIcon,
- AlignRightIcon,
-} from 'lucide-react';
-
-import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuRadioGroup,
- DropdownMenuRadioItem,
- DropdownMenuTrigger,
- useOpenState,
-} from './dropdown-menu';
-import { ToolbarButton } from './toolbar';
-
-const items = [
- {
- icon: AlignLeftIcon,
- value: 'left',
- },
- {
- icon: AlignCenterIcon,
- value: 'center',
- },
- {
- icon: AlignRightIcon,
- value: 'right',
- },
- {
- icon: AlignJustifyIcon,
- value: 'justify',
- },
-];
-
-export function AlignDropdownMenu({ children, ...props }: DropdownMenuProps) {
- const state = useAlignDropdownMenuState();
- const { radioGroupProps } = useAlignDropdownMenu(state);
-
- const openState = useOpenState();
- const IconValue =
- items.find((item) => item.value === radioGroupProps.value)?.icon ??
- AlignLeftIcon;
-
- return (
-
-
-
-
-
-
-
-
-
- {items.map(({ icon: Icon, value: itemValue }) => (
-
-
-
- ))}
-
-
-
- );
-}
diff --git a/apps/web/app/components/plate-ui/avatar.tsx b/apps/web/app/components/plate-ui/avatar.tsx
deleted file mode 100644
index 3aad74b5..00000000
--- a/apps/web/app/components/plate-ui/avatar.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-'use client';
-
-import * as AvatarPrimitive from '@radix-ui/react-avatar';
-import { withCn } from '@udecode/cn';
-
-export const Avatar = withCn(
- AvatarPrimitive.Root,
- 'relative flex size-10 shrink-0 overflow-hidden rounded-full'
-);
-
-export const AvatarImage = withCn(
- AvatarPrimitive.Image,
- 'aspect-square size-full'
-);
-
-export const AvatarFallback = withCn(
- AvatarPrimitive.Fallback,
- 'flex size-full items-center justify-center rounded-full bg-muted'
-);
diff --git a/apps/web/app/components/plate-ui/block-context-menu.tsx b/apps/web/app/components/plate-ui/block-context-menu.tsx
deleted file mode 100644
index bec50b02..00000000
--- a/apps/web/app/components/plate-ui/block-context-menu.tsx
+++ /dev/null
@@ -1,206 +0,0 @@
-'use client';
-
-import { useCallback, useState } from 'react';
-
-import { AIChatPlugin } from '@udecode/plate-ai/react';
-import { BlockquotePlugin } from '@udecode/plate-block-quote/react';
-import { unsetNodes } from '@udecode/plate-common';
-import {
- ParagraphPlugin,
- focusEditor,
- useEditorPlugin,
-} from '@udecode/plate-common/react';
-import { HEADING_KEYS } from '@udecode/plate-heading';
-import { IndentListPlugin } from '@udecode/plate-indent-list/react';
-import {
- BLOCK_CONTEXT_MENU_ID,
- BlockMenuPlugin,
- BlockSelectionPlugin,
-} from '@udecode/plate-selection/react';
-
-import { useIsTouchDevice } from '~/lib/hooks/use-is-touch-device';
-
-import {
- ContextMenu,
- ContextMenuContent,
- ContextMenuGroup,
- ContextMenuItem,
- ContextMenuSub,
- ContextMenuSubContent,
- ContextMenuSubTrigger,
- ContextMenuTrigger,
-} from './context-menu';
-
-type Value = 'askAI' | null;
-
-export function BlockContextMenu({ children }: { children: React.ReactNode }) {
- const { api, editor } = useEditorPlugin(BlockMenuPlugin);
- const [value, setValue] = useState(null);
- const isTouch = useIsTouchDevice();
-
- const handleTurnInto = useCallback(
- (type: string) => {
- editor
- .getApi(BlockSelectionPlugin)
- .blockSelection.getNodes()
- .forEach(([node, path]) => {
- if (node[IndentListPlugin.key]) {
- unsetNodes(editor, [IndentListPlugin.key, 'indent'], { at: path });
- }
-
- editor.tf.toggle.block({ type }, { at: path });
- });
- },
- [editor]
- );
-
- const handleAlign = useCallback(
- (align: 'center' | 'left' | 'right') => {
- editor
- .getTransforms(BlockSelectionPlugin)
- .blockSelection.setNodes({ align });
- },
- [editor]
- );
-
- if (isTouch) {
- return children;
- }
-
- return (
- {
- if (!open) {
- // prevent unselect the block selection
- setTimeout(() => {
- api.blockMenu.hide();
- }, 0);
- }
- }}
- modal={false}
- >
- {
- const dataset = (event.target as HTMLElement).dataset;
-
- const disabled = dataset?.slateEditor === 'true';
-
- if (disabled) return event.preventDefault();
-
- api.blockMenu.show(BLOCK_CONTEXT_MENU_ID, {
- x: event.clientX,
- y: event.clientY,
- });
- }}
- >
- {children}
-
- {
- e.preventDefault();
- editor.getApi(BlockSelectionPlugin).blockSelection.focus();
-
- if (value === 'askAI') {
- editor.getApi(AIChatPlugin).aiChat.show();
- }
-
- setValue(null);
- }}
- >
-
- {
- setValue('askAI');
- }}
- >
- Ask AI
-
- {
- editor
- .getTransforms(BlockSelectionPlugin)
- .blockSelection.removeNodes();
- focusEditor(editor);
- }}
- >
- Delete
-
- {
- editor
- .getTransforms(BlockSelectionPlugin)
- .blockSelection.duplicate(
- editor.getApi(BlockSelectionPlugin).blockSelection.getNodes()
- );
- }}
- >
- Duplicate
- {/* β + D */}
-
-
- Turn into
-
- handleTurnInto(ParagraphPlugin.key)}
- >
- Paragraph
-
-
- handleTurnInto(HEADING_KEYS.h1)}>
- Heading 1
-
- handleTurnInto(HEADING_KEYS.h2)}>
- Heading 2
-
- handleTurnInto(HEADING_KEYS.h3)}>
- Heading 3
-
- handleTurnInto(BlockquotePlugin.key)}
- >
- Blockquote
-
-
-
-
-
-
-
- editor
- .getTransforms(BlockSelectionPlugin)
- .blockSelection.setIndent(1)
- }
- >
- Indent
-
-
- editor
- .getTransforms(BlockSelectionPlugin)
- .blockSelection.setIndent(-1)
- }
- >
- Outdent
-
-
- Align
-
- handleAlign('left')}>
- Left
-
- handleAlign('center')}>
- Center
-
- handleAlign('right')}>
- Right
-
-
-
-
-
-
- );
-}
diff --git a/apps/web/app/components/plate-ui/block-selection.tsx b/apps/web/app/components/plate-ui/block-selection.tsx
deleted file mode 100644
index b0562fe7..00000000
--- a/apps/web/app/components/plate-ui/block-selection.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-'use client';
-
-import { cn } from '@udecode/cn';
-import { useBlockSelected } from '@udecode/plate-selection/react';
-import { type VariantProps, cva } from 'class-variance-authority';
-
-export const blockSelectionVariants = cva(
- 'pointer-events-none absolute inset-0 z-[1] bg-brand/[.13] transition-opacity',
- {
- defaultVariants: {
- active: true,
- },
- variants: {
- active: {
- false: 'opacity-0',
- true: 'opacity-100',
- },
- },
- }
-);
-
-export function BlockSelection({
- className,
- ...props
-}: React.HTMLAttributes &
- VariantProps) {
- const isBlockSelected = useBlockSelected();
-
- if (!isBlockSelected) return null;
-
- return (
-
- );
-}
diff --git a/apps/web/app/components/plate-ui/blockquote-element.tsx b/apps/web/app/components/plate-ui/blockquote-element.tsx
deleted file mode 100644
index f6fa8a20..00000000
--- a/apps/web/app/components/plate-ui/blockquote-element.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import { cn, withRef } from '@udecode/cn';
-
-import { PlateElement } from './plate-element';
-
-export const BlockquoteElement = withRef(
- ({ children, className, ...props }, ref) => {
- return (
-
- {children}
-
- );
- }
-);
diff --git a/apps/web/app/components/plate-ui/button.tsx b/apps/web/app/components/plate-ui/button.tsx
deleted file mode 100644
index d017db41..00000000
--- a/apps/web/app/components/plate-ui/button.tsx
+++ /dev/null
@@ -1,57 +0,0 @@
-import * as React from 'react';
-
-import { Slot } from '@radix-ui/react-slot';
-import { cn, withRef } from '@udecode/cn';
-import { type VariantProps, cva } from 'class-variance-authority';
-
-export const buttonVariants = cva(
- 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
- {
- defaultVariants: {
- size: 'sm',
- variant: 'default',
- },
- variants: {
- isMenu: {
- true: 'w-full cursor-pointer justify-start',
- },
- size: {
- icon: 'size-[28px] rounded-md px-1.5',
- lg: 'h-10 rounded-md px-4',
- md: 'h-8 px-3 text-sm',
- none: '',
- sm: 'h-[28px] rounded-md px-2.5',
- xs: 'h-8 rounded-md px-3 text-xs',
- },
- variant: {
- default: 'bg-primary text-primary-foreground hover:bg-primary/90',
- destructive:
- 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
- ghost: 'hover:bg-accent hover:text-accent-foreground',
- inlineLink: 'text-base text-primary underline underline-offset-4',
- link: 'text-primary underline-offset-4 hover:underline',
- outline:
- 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
- secondary:
- 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
- },
- },
- }
-);
-
-export const Button = withRef<
- 'button',
- {
- asChild?: boolean;
- } & VariantProps
->(({ asChild = false, className, isMenu, size, variant, ...props }, ref) => {
- const Comp = asChild ? Slot : 'button';
-
- return (
-
- );
-});
diff --git a/apps/web/app/components/plate-ui/calendar.tsx b/apps/web/app/components/plate-ui/calendar.tsx
deleted file mode 100644
index 2205ef1a..00000000
--- a/apps/web/app/components/plate-ui/calendar.tsx
+++ /dev/null
@@ -1,68 +0,0 @@
-'use client';
-
-import * as React from 'react';
-import { DayPicker } from 'react-day-picker';
-
-import { cn } from '@udecode/cn';
-import { ChevronLeft, ChevronRight } from 'lucide-react';
-
-import { buttonVariants } from './button';
-
-export type CalendarProps = React.ComponentProps;
-
-function Calendar({
- className,
- classNames,
- showOutsideDays = true,
- ...props
-}: CalendarProps) {
- return (
- ,
- IconRight: () => ,
- }}
- showOutsideDays={showOutsideDays}
- {...props}
- />
- );
-}
-
-Calendar.displayName = 'Calendar';
-
-export { Calendar };
diff --git a/apps/web/app/components/plate-ui/caption.tsx b/apps/web/app/components/plate-ui/caption.tsx
deleted file mode 100644
index 9ab81642..00000000
--- a/apps/web/app/components/plate-ui/caption.tsx
+++ /dev/null
@@ -1,48 +0,0 @@
-'use client';
-
-import {
- cn,
- createPrimitiveComponent,
- withCn,
- withVariants,
-} from '@udecode/cn';
-import {
- Caption as CaptionPrimitive,
- CaptionTextarea as CaptionTextareaPrimitive,
- useCaptionButton,
- useCaptionButtonState,
-} from '@udecode/plate-caption/react';
-import { cva } from 'class-variance-authority';
-
-import { Button } from './button';
-
-const captionVariants = cva('max-w-full', {
- defaultVariants: {
- align: 'center',
- },
- variants: {
- align: {
- center: 'mx-auto',
- left: 'mr-auto',
- right: 'ml-auto',
- },
- },
-});
-
-export const Caption = withVariants(CaptionPrimitive, captionVariants, [
- 'align',
-]);
-
-export const CaptionTextarea = withCn(
- CaptionTextareaPrimitive,
- cn(
- 'mt-2 w-full resize-none border-none bg-inherit p-0 font-[inherit] text-inherit',
- 'focus:outline-none focus:[&::placeholder]:opacity-0',
- 'text-center print:placeholder:text-transparent'
- )
-);
-
-export const CaptionButton = createPrimitiveComponent(Button)({
- propsHook: useCaptionButton,
- stateHook: useCaptionButtonState,
-});
diff --git a/apps/web/app/components/plate-ui/checkbox.tsx b/apps/web/app/components/plate-ui/checkbox.tsx
deleted file mode 100644
index d369c923..00000000
--- a/apps/web/app/components/plate-ui/checkbox.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-'use client';
-
-import * as React from 'react';
-
-import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
-import { cn, withRef } from '@udecode/cn';
-import { Check } from 'lucide-react';
-
-export const Checkbox = withRef(
- ({ className, ...props }, ref) => (
-
-
-
-
-
- )
-);
diff --git a/apps/web/app/components/plate-ui/code-block-combobox.tsx b/apps/web/app/components/plate-ui/code-block-combobox.tsx
deleted file mode 100644
index 7ec8055b..00000000
--- a/apps/web/app/components/plate-ui/code-block-combobox.tsx
+++ /dev/null
@@ -1,202 +0,0 @@
-'use client';
-
-import React, { useState } from 'react';
-
-import { cn } from '@udecode/cn';
-import {
- useCodeBlockCombobox,
- useCodeBlockComboboxState,
-} from '@udecode/plate-code-block/react';
-import { Check, ChevronsUpDown } from 'lucide-react';
-
-// Prism must be imported before all language files
-import Prism from 'prismjs';
-
-import { Button } from './button';
-import {
- Command,
- CommandEmpty,
- CommandInput,
- CommandItem,
- CommandList,
-} from './command';
-import { Popover, PopoverContent, PopoverTrigger } from './popover';
-
-import 'prismjs/components/prism-antlr4.js';
-import 'prismjs/components/prism-bash.js';
-import 'prismjs/components/prism-c.js';
-import 'prismjs/components/prism-cmake.js';
-import 'prismjs/components/prism-coffeescript.js';
-import 'prismjs/components/prism-cpp.js';
-import 'prismjs/components/prism-csharp.js';
-import 'prismjs/components/prism-css.js';
-import 'prismjs/components/prism-dart.js';
-
-// import 'prismjs/components/prism-django.js';
-import 'prismjs/components/prism-docker.js';
-
-// import 'prismjs/components/prism-ejs.js';
-import 'prismjs/components/prism-erlang.js';
-import 'prismjs/components/prism-git.js';
-import 'prismjs/components/prism-go.js';
-import 'prismjs/components/prism-graphql.js';
-import 'prismjs/components/prism-groovy.js';
-import 'prismjs/components/prism-java.js';
-import 'prismjs/components/prism-javascript.js';
-import 'prismjs/components/prism-json.js';
-import 'prismjs/components/prism-jsx.js';
-import 'prismjs/components/prism-kotlin.js';
-import 'prismjs/components/prism-latex.js';
-import 'prismjs/components/prism-less.js';
-import 'prismjs/components/prism-lua.js';
-import 'prismjs/components/prism-makefile.js';
-import 'prismjs/components/prism-markdown.js';
-import 'prismjs/components/prism-matlab.js';
-import 'prismjs/components/prism-mermaid.js';
-import 'prismjs/components/prism-objectivec.js';
-import 'prismjs/components/prism-perl.js';
-
-// import 'prismjs/components/prism-php.js';
-import 'prismjs/components/prism-powershell.js';
-import 'prismjs/components/prism-properties.js';
-import 'prismjs/components/prism-protobuf.js';
-import 'prismjs/components/prism-python.js';
-import 'prismjs/components/prism-r.js';
-import 'prismjs/components/prism-ruby.js';
-import 'prismjs/components/prism-sass.js';
-import 'prismjs/components/prism-scala.js';
-import 'prismjs/components/prism-scheme.js';
-import 'prismjs/components/prism-scss.js';
-import 'prismjs/components/prism-sql.js';
-import 'prismjs/components/prism-swift.js';
-import 'prismjs/components/prism-tsx.js';
-import 'prismjs/components/prism-typescript.js';
-import 'prismjs/components/prism-wasm.js';
-import 'prismjs/components/prism-yaml.js';
-
-export { Prism };
-
-const languages: { label: string; value: string }[] = [
- { label: 'Plain Text', value: 'text' },
- { label: 'Bash', value: 'bash' },
- { label: 'CSS', value: 'css' },
- { label: 'Git', value: 'git' },
- { label: 'GraphQL', value: 'graphql' },
- { label: 'HTML', value: 'html' },
- { label: 'JavaScript', value: 'javascript' },
- { label: 'JSON', value: 'json' },
- { label: 'JSX', value: 'jsx' },
- { label: 'Markdown', value: 'markdown' },
- { label: 'SQL', value: 'sql' },
- { label: 'SVG', value: 'svg' },
- { label: 'TSX', value: 'tsx' },
- { label: 'TypeScript', value: 'typescript' },
- { label: 'WebAssembly', value: 'wasm' },
- { label: 'ANTLR4', value: 'antlr4' },
- { label: 'C', value: 'c' },
- { label: 'CMake', value: 'cmake' },
- { label: 'CoffeeScript', value: 'coffeescript' },
- { label: 'C#', value: 'csharp' },
- { label: 'Dart', value: 'dart' },
- { label: 'Django', value: 'django' },
- { label: 'Docker', value: 'docker' },
- { label: 'EJS', value: 'ejs' },
- { label: 'Erlang', value: 'erlang' },
- { label: 'Go', value: 'go' },
- { label: 'Groovy', value: 'groovy' },
- { label: 'Java', value: 'java' },
- { label: 'Kotlin', value: 'kotlin' },
- { label: 'LaTeX', value: 'latex' },
- { label: 'Less', value: 'less' },
- { label: 'Lua', value: 'lua' },
- { label: 'Makefile', value: 'makefile' },
- { label: 'Markup', value: 'markup' },
- { label: 'MATLAB', value: 'matlab' },
- { label: 'Mermaid', value: 'mermaid' },
- { label: 'Objective-C', value: 'objectivec' },
- { label: 'Perl', value: 'perl' },
- { label: 'PHP', value: 'php' },
- { label: 'PowerShell', value: 'powershell' },
- { label: '.properties', value: 'properties' },
- { label: 'Protocol Buffers', value: 'protobuf' },
- { label: 'Python', value: 'python' },
- { label: 'R', value: 'r' },
- { label: 'Ruby', value: 'ruby' },
- { label: 'Sass (Sass)', value: 'sass' },
- // FIXME: Error with current scala grammar
- { label: 'Scala', value: 'scala' },
- { label: 'Scheme', value: 'scheme' },
- { label: 'Sass (Scss)', value: 'scss' },
- { label: 'Shell', value: 'shell' },
- { label: 'Swift', value: 'swift' },
- { label: 'XML', value: 'xml' },
- { label: 'YAML', value: 'yaml' },
-];
-
-export function CodeBlockCombobox() {
- const state = useCodeBlockComboboxState();
- const { commandItemProps } = useCodeBlockCombobox(state);
-
- const [open, setOpen] = useState(false);
- const [value, setValue] = useState('');
-
- if (state.readOnly) return null;
-
- const items = languages.filter(
- (language) =>
- !value ||
- language.label.toLowerCase().includes(value.toLowerCase()) ||
- language.value.toLowerCase().includes(value.toLowerCase())
- );
-
- return (
-
-
-
- {state.value
- ? languages.find((language) => language.value === state.value)
- ?.label
- : 'Plain Text'}
-
-
-
-
-
- setValue(value)}
- placeholder="Search language..."
- />
- No language found.
-
-
- {items.map((language) => (
- {
- commandItemProps.onSelect(_value);
- setOpen(false);
- }}
- >
-
- {language.label}
-
- ))}
-
-
-
-
- );
-}
diff --git a/apps/web/app/components/plate-ui/code-block-element.css b/apps/web/app/components/plate-ui/code-block-element.css
deleted file mode 100644
index ef6d891a..00000000
--- a/apps/web/app/components/plate-ui/code-block-element.css
+++ /dev/null
@@ -1,404 +0,0 @@
-.slate-code_block code[class*='language-'],
-.slate-code_block pre[class*='language-'] {
- background: hsl(230, 1%, 98%);
- color: hsl(230, 8%, 24%);
- font-family: 'Fira Code', 'Fira Mono', Menlo, Consolas, 'DejaVu Sans Mono',
- monospace;
- direction: ltr;
- text-align: left;
- white-space: pre;
- word-spacing: normal;
- word-break: normal;
- line-height: 1.5;
- -moz-tab-size: 2;
- -o-tab-size: 2;
- tab-size: 2;
- -webkit-hyphens: none;
- -moz-hyphens: none;
- -ms-hyphens: none;
- hyphens: none;
-}
-
-/* Selection */
-.slate-code_block code[class*='language-']::-moz-selection,
-.slate-code_block code[class*='language-'] *::-moz-selection,
-.slate-code_block pre[class*='language-'] *::-moz-selection {
- background: hsl(230, 1%, 90%);
- color: inherit;
-}
-
-.slate-code_block code[class*='language-']::selection,
-.slate-code_block code[class*='language-'] *::selection,
-.slate-code_block pre[class*='language-'] *::selection {
- background: hsl(230, 1%, 90%);
- color: inherit;
-}
-
-/* Code blocks */
-.slate-code_block pre[class*='language-'] {
- padding: 1em;
- margin: 0.5em 0;
- overflow: auto;
- border-radius: 0.3em;
-}
-
-/* Inline code */
-.slate-code_block :not(pre) > code[class*='language-'] {
- padding: 0.2em 0.3em;
- border-radius: 0.3em;
- white-space: normal;
-}
-
-.token.comment,
-.token.prolog,
-.token.cdata {
- color: hsl(230, 4%, 64%);
-}
-
-.token.doctype,
-.token.punctuation,
-.token.entity {
- color: hsl(230, 8%, 24%);
-}
-
-.token.attr-name,
-.token.class-name,
-.token.boolean,
-.token.constant,
-.token.number,
-.token.atrule {
- color: hsl(35, 99%, 36%);
-}
-
-.token.keyword {
- color: hsl(301, 63%, 40%);
-}
-
-.token.property,
-.token.tag,
-.token.symbol,
-.token.deleted,
-.token.important {
- color: hsl(5, 74%, 59%);
-}
-
-.token.selector,
-.token.string,
-.token.char,
-.token.builtin,
-.token.inserted,
-.token.regex,
-.token.attr-value,
-.token.attr-value > .token.punctuation {
- color: hsl(119, 34%, 47%);
-}
-
-.token.variable,
-.token.operator,
-.token.function {
- color: hsl(221, 87%, 60%);
-}
-
-.token.url {
- color: hsl(198, 99%, 37%);
-}
-
-/* HTML overrides */
-.token.attr-value > .token.punctuation.attr-equals,
-.token.special-attr > .token.attr-value > .token.value.css {
- color: hsl(230, 8%, 24%);
-}
-
-/* CSS overrides */
-.language-css .token.selector {
- color: hsl(5, 74%, 59%);
-}
-
-.language-css .token.property {
- color: hsl(230, 8%, 24%);
-}
-
-.language-css .token.function,
-.language-css .token.url > .token.function {
- color: hsl(198, 99%, 37%);
-}
-
-.language-css .token.url > .token.string.url {
- color: hsl(119, 34%, 47%);
-}
-
-.language-css .token.important,
-.language-css .token.atrule .token.rule {
- color: hsl(301, 63%, 40%);
-}
-
-/* JS overrides */
-.language-javascript .token.operator {
- color: hsl(301, 63%, 40%);
-}
-
-.language-javascript
- .token.template-string
- > .token.interpolation
- > .token.interpolation-punctuation.punctuation {
- color: hsl(344, 84%, 43%);
-}
-
-/* JSON overrides */
-.language-json .token.operator {
- color: hsl(230, 8%, 24%);
-}
-
-.language-json .token.null.keyword {
- color: hsl(35, 99%, 36%);
-}
-
-/* MD overrides */
-.language-markdown .token.url,
-.language-markdown .token.url > .token.operator,
-.language-markdown .token.url-reference.url > .token.string {
- color: hsl(230, 8%, 24%);
-}
-
-.language-markdown .token.url > .token.content {
- color: hsl(221, 87%, 60%);
-}
-
-.language-markdown .token.url > .token.url,
-.language-markdown .token.url-reference.url {
- color: hsl(198, 99%, 37%);
-}
-
-.language-markdown .token.blockquote.punctuation,
-.language-markdown .token.hr.punctuation {
- color: hsl(230, 4%, 64%);
- font-style: italic;
-}
-
-.language-markdown .token.code-snippet {
- color: hsl(119, 34%, 47%);
-}
-
-.language-markdown .token.bold .token.content {
- color: hsl(35, 99%, 36%);
-}
-
-.language-markdown .token.italic .token.content {
- color: hsl(301, 63%, 40%);
-}
-
-.language-markdown .token.strike .token.content,
-.language-markdown .token.strike .token.punctuation,
-.language-markdown .token.list.punctuation,
-.language-markdown .token.title.important > .token.punctuation {
- color: hsl(5, 74%, 59%);
-}
-
-/* General */
-.token.bold {
- font-weight: bold;
-}
-
-.token.comment,
-.token.italic {
- font-style: italic;
-}
-
-.token.entity {
- cursor: help;
-}
-
-.token.namespace {
- opacity: 0.8;
-}
-
-/* Plugin overrides */
-/* Selectors should have higher specificity than those in the plugins' default stylesheets */
-
-/* Show Invisibles plugin overrides */
-.token.token.tab:not(:empty):before,
-.token.token.cr:before,
-.token.token.lf:before,
-.token.token.space:before {
- color: hsla(230, 8%, 24%, 0.2);
-}
-
-/* Toolbar plugin overrides */
-/* Space out all buttons and move them away from the right edge of the code block */
-div.code-toolbar > .toolbar.toolbar > .toolbar-item {
- margin-right: 0.4em;
-}
-
-/* Styling the buttons */
-div.code-toolbar > .toolbar.toolbar > .toolbar-item > button,
-div.code-toolbar > .toolbar.toolbar > .toolbar-item > a,
-div.code-toolbar > .toolbar.toolbar > .toolbar-item > span {
- background: hsl(230, 1%, 90%);
- color: hsl(230, 6%, 44%);
- padding: 0.1em 0.4em;
- border-radius: 0.3em;
-}
-
-div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:hover,
-div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:focus,
-div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:hover,
-div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:focus,
-div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:hover,
-div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:focus {
- background: hsl(230, 1%, 78%); /* custom: darken(--syntax-bg, 20%) */
- color: hsl(230, 8%, 24%);
-}
-
-/* Line Highlight plugin overrides */
-/* The highlighted line itself */
-.line-highlight.line-highlight {
- background: hsla(230, 8%, 24%, 0.05);
-}
-
-/* Default line numbers in Line Highlight plugin */
-.line-highlight.line-highlight:before,
-.line-highlight.line-highlight[data-end]:after {
- background: hsl(230, 1%, 90%);
- color: hsl(230, 8%, 24%);
- padding: 0.1em 0.6em;
- border-radius: 0.3em;
- box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.2); /* same as Toolbar plugin default */
-}
-
-/* Hovering over a linkable line number (in the gutter area) */
-/* Requires Line Numbers plugin as well */
-pre[id].linkable-line-numbers.linkable-line-numbers
- span.line-numbers-rows
- > span:hover:before {
- background-color: hsla(230, 8%, 24%, 0.05);
-}
-
-/* Line Numbers and Command Line plugins overrides */
-/* Line separating gutter from coding area */
-.line-numbers.line-numbers .line-numbers-rows,
-.command-line .command-line-prompt {
- border-right-color: hsla(230, 8%, 24%, 0.2);
-}
-
-/* Stuff in the gutter */
-.line-numbers .line-numbers-rows > span:before,
-.command-line .command-line-prompt > span:before {
- color: hsl(230, 1%, 62%);
-}
-
-/* Match Braces plugin overrides */
-/* Note: Outline colour is inherited from the braces */
-.rainbow-braces .token.token.punctuation.brace-level-1,
-.rainbow-braces .token.token.punctuation.brace-level-5,
-.rainbow-braces .token.token.punctuation.brace-level-9 {
- color: hsl(5, 74%, 59%);
-}
-
-.rainbow-braces .token.token.punctuation.brace-level-2,
-.rainbow-braces .token.token.punctuation.brace-level-6,
-.rainbow-braces .token.token.punctuation.brace-level-10 {
- color: hsl(119, 34%, 47%);
-}
-
-.rainbow-braces .token.token.punctuation.brace-level-3,
-.rainbow-braces .token.token.punctuation.brace-level-7,
-.rainbow-braces .token.token.punctuation.brace-level-11 {
- color: hsl(221, 87%, 60%);
-}
-
-.rainbow-braces .token.token.punctuation.brace-level-4,
-.rainbow-braces .token.token.punctuation.brace-level-8,
-.rainbow-braces .token.token.punctuation.brace-level-12 {
- color: hsl(301, 63%, 40%);
-}
-
-/* Diff Highlight plugin overrides */
-/* Taken from https://github.com/atom/github/blob/master/styles/variables.less */
-pre.diff-highlight > code .token.token.deleted:not(.prefix),
-pre > code.diff-highlight .token.token.deleted:not(.prefix) {
- background-color: hsla(353, 100%, 66%, 0.15);
-}
-
-pre.diff-highlight > code .token.token.deleted:not(.prefix)::-moz-selection,
-pre.diff-highlight > code .token.token.deleted:not(.prefix) *::-moz-selection,
-pre > code.diff-highlight .token.token.deleted:not(.prefix)::-moz-selection,
-pre > code.diff-highlight .token.token.deleted:not(.prefix) *::-moz-selection {
- background-color: hsla(353, 95%, 66%, 0.25);
-}
-
-pre.diff-highlight > code .token.token.deleted:not(.prefix)::selection,
-pre.diff-highlight > code .token.token.deleted:not(.prefix) *::selection,
-pre > code.diff-highlight .token.token.deleted:not(.prefix)::selection,
-pre > code.diff-highlight .token.token.deleted:not(.prefix) *::selection {
- background-color: hsla(353, 95%, 66%, 0.25);
-}
-
-pre.diff-highlight > code .token.token.inserted:not(.prefix),
-pre > code.diff-highlight .token.token.inserted:not(.prefix) {
- background-color: hsla(137, 100%, 55%, 0.15);
-}
-
-pre.diff-highlight > code .token.token.inserted:not(.prefix)::-moz-selection,
-pre.diff-highlight > code .token.token.inserted:not(.prefix) *::-moz-selection,
-pre > code.diff-highlight .token.token.inserted:not(.prefix)::-moz-selection,
-pre > code.diff-highlight .token.token.inserted:not(.prefix) *::-moz-selection {
- background-color: hsla(135, 73%, 55%, 0.25);
-}
-
-pre.diff-highlight > code .token.token.inserted:not(.prefix)::selection,
-pre.diff-highlight > code .token.token.inserted:not(.prefix) *::selection,
-pre > code.diff-highlight .token.token.inserted:not(.prefix)::selection,
-pre > code.diff-highlight .token.token.inserted:not(.prefix) *::selection {
- background-color: hsla(135, 73%, 55%, 0.25);
-}
-
-/* Previewers plugin overrides */
-/* Based on https://github.com/atom-community/atom-ide-datatip/blob/master/styles/atom-ide-datatips.less and https://github.com/atom/atom/blob/master/packages/one-light-ui */
-/* Border around popup */
-.prism-previewer.prism-previewer:before,
-.prism-previewer-gradient.prism-previewer-gradient div {
- border-color: hsl(0, 0, 95%);
-}
-
-/* Angle and time should remain as circles and are hence not included */
-.prism-previewer-color.prism-previewer-color:before,
-.prism-previewer-gradient.prism-previewer-gradient div,
-.prism-previewer-easing.prism-previewer-easing:before {
- border-radius: 0.3em;
-}
-
-/* Triangles pointing to the code */
-.prism-previewer.prism-previewer:after {
- border-top-color: hsl(0, 0, 95%);
-}
-
-.prism-previewer-flipped.prism-previewer-flipped.after {
- border-bottom-color: hsl(0, 0, 95%);
-}
-
-/* Background colour within the popup */
-.prism-previewer-angle.prism-previewer-angle:before,
-.prism-previewer-time.prism-previewer-time:before,
-.prism-previewer-easing.prism-previewer-easing {
- background: hsl(0, 0%, 100%);
-}
-
-/* For angle, this is the positive area (eg. 90deg will display one quadrant in this colour) */
-/* For time, this is the alternate colour */
-.prism-previewer-angle.prism-previewer-angle circle,
-.prism-previewer-time.prism-previewer-time circle {
- stroke: hsl(230, 8%, 24%);
- stroke-opacity: 1;
-}
-
-/* Stroke colours of the handle, direction point, and vector itself */
-.prism-previewer-easing.prism-previewer-easing circle,
-.prism-previewer-easing.prism-previewer-easing path,
-.prism-previewer-easing.prism-previewer-easing line {
- stroke: hsl(230, 8%, 24%);
-}
-
-/* Fill colour of the handle */
-.prism-previewer-easing.prism-previewer-easing circle {
- fill: transparent;
-}
diff --git a/apps/web/app/components/plate-ui/code-block-element.tsx b/apps/web/app/components/plate-ui/code-block-element.tsx
deleted file mode 100644
index afc18a52..00000000
--- a/apps/web/app/components/plate-ui/code-block-element.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import { cn, withRef } from '@udecode/cn';
-import { useCodeBlockElementState } from '@udecode/plate-code-block/react';
-
-import { CodeBlockCombobox } from './code-block-combobox';
-import { PlateElement } from './plate-element';
-
-import './code-block-element.css';
-
-export const CodeBlockElement = withRef(
- ({ children, className, ...props }, ref) => {
- const { element } = props;
- const state = useCodeBlockElementState({ element });
-
- return (
-
-
- {children}
-
-
- {state.syntax && (
-
-
-
- )}
-
- );
- }
-);
diff --git a/apps/web/app/components/plate-ui/code-leaf.tsx b/apps/web/app/components/plate-ui/code-leaf.tsx
deleted file mode 100644
index dd0c48a2..00000000
--- a/apps/web/app/components/plate-ui/code-leaf.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import { cn, withRef } from '@udecode/cn';
-import { PlateLeaf } from '@udecode/plate-common/react';
-
-export const CodeLeaf = withRef(
- ({ children, className, ...props }, ref) => {
- return (
-
- {children}
-
- );
- }
-);
diff --git a/apps/web/app/components/plate-ui/code-line-element.tsx b/apps/web/app/components/plate-ui/code-line-element.tsx
deleted file mode 100644
index aa23472c..00000000
--- a/apps/web/app/components/plate-ui/code-line-element.tsx
+++ /dev/null
@@ -1,10 +0,0 @@
-'use client';
-
-
-import { withRef } from '@udecode/cn';
-
-import { PlateElement } from './plate-element';
-
-export const CodeLineElement = withRef((props, ref) => (
-
-));
diff --git a/apps/web/app/components/plate-ui/code-syntax-leaf.tsx b/apps/web/app/components/plate-ui/code-syntax-leaf.tsx
deleted file mode 100644
index 5698f0b7..00000000
--- a/apps/web/app/components/plate-ui/code-syntax-leaf.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-'use client';
-
-
-import { withRef } from '@udecode/cn';
-import { useCodeSyntaxLeaf } from '@udecode/plate-code-block/react';
-import { PlateLeaf } from '@udecode/plate-common/react';
-
-export const CodeSyntaxLeaf = withRef(
- ({ children, ...props }, ref) => {
- const { leaf } = props;
-
- const { tokenProps } = useCodeSyntaxLeaf({ leaf });
-
- return (
-
- {children}
-
- );
- }
-);
diff --git a/apps/web/app/components/plate-ui/color-constants.ts b/apps/web/app/components/plate-ui/color-constants.ts
deleted file mode 100644
index 1508c25f..00000000
--- a/apps/web/app/components/plate-ui/color-constants.ts
+++ /dev/null
@@ -1,436 +0,0 @@
-export const DEFAULT_COLORS = [
- {
- isBrightColor: false,
- name: 'black',
- value: '#000000',
- },
- {
- isBrightColor: false,
- name: 'dark grey 4',
- value: '#434343',
- },
- {
- isBrightColor: false,
- name: 'dark grey 3',
- value: '#666666',
- },
- {
- isBrightColor: false,
- name: 'dark grey 2',
- value: '#999999',
- },
- {
- isBrightColor: false,
- name: 'dark grey 1',
- value: '#B7B7B7',
- },
- {
- isBrightColor: false,
- name: 'grey',
- value: '#CCCCCC',
- },
- {
- isBrightColor: false,
- name: 'light grey 1',
- value: '#D9D9D9',
- },
- {
- isBrightColor: true,
- name: 'light grey 2',
- value: '#EFEFEF',
- },
- {
- isBrightColor: true,
- name: 'light grey 3',
- value: '#F3F3F3',
- },
- {
- isBrightColor: true,
- name: 'white',
- value: '#FFFFFF',
- },
- {
- isBrightColor: false,
- name: 'red berry',
- value: '#980100',
- },
- {
- isBrightColor: false,
- name: 'red',
- value: '#FE0000',
- },
- {
- isBrightColor: false,
- name: 'orange',
- value: '#FE9900',
- },
- {
- isBrightColor: true,
- name: 'yellow',
- value: '#FEFF00',
- },
- {
- isBrightColor: false,
- name: 'green',
- value: '#00FF00',
- },
- {
- isBrightColor: false,
- name: 'cyan',
- value: '#00FFFF',
- },
- {
- isBrightColor: false,
- name: 'cornflower blue',
- value: '#4B85E8',
- },
- {
- isBrightColor: false,
- name: 'blue',
- value: '#1300FF',
- },
- {
- isBrightColor: false,
- name: 'purple',
- value: '#9900FF',
- },
- {
- isBrightColor: false,
- name: 'magenta',
- value: '#FF00FF',
- },
-
- {
- isBrightColor: false,
- name: 'light red berry 3',
- value: '#E6B8AF',
- },
- {
- isBrightColor: false,
- name: 'light red 3',
- value: '#F4CCCC',
- },
- {
- isBrightColor: true,
- name: 'light orange 3',
- value: '#FCE4CD',
- },
- {
- isBrightColor: true,
- name: 'light yellow 3',
- value: '#FFF2CC',
- },
- {
- isBrightColor: true,
- name: 'light green 3',
- value: '#D9EAD3',
- },
- {
- isBrightColor: false,
- name: 'light cyan 3',
- value: '#D0DFE3',
- },
- {
- isBrightColor: false,
- name: 'light cornflower blue 3',
- value: '#C9DAF8',
- },
- {
- isBrightColor: true,
- name: 'light blue 3',
- value: '#CFE1F3',
- },
- {
- isBrightColor: true,
- name: 'light purple 3',
- value: '#D9D2E9',
- },
- {
- isBrightColor: true,
- name: 'light magenta 3',
- value: '#EAD1DB',
- },
-
- {
- isBrightColor: false,
- name: 'light red berry 2',
- value: '#DC7E6B',
- },
- {
- isBrightColor: false,
- name: 'light red 2',
- value: '#EA9999',
- },
- {
- isBrightColor: false,
- name: 'light orange 2',
- value: '#F9CB9C',
- },
- {
- isBrightColor: true,
- name: 'light yellow 2',
- value: '#FFE598',
- },
- {
- isBrightColor: false,
- name: 'light green 2',
- value: '#B7D6A8',
- },
- {
- isBrightColor: false,
- name: 'light cyan 2',
- value: '#A1C4C9',
- },
- {
- isBrightColor: false,
- name: 'light cornflower blue 2',
- value: '#A4C2F4',
- },
- {
- isBrightColor: false,
- name: 'light blue 2',
- value: '#9FC5E8',
- },
- {
- isBrightColor: false,
- name: 'light purple 2',
- value: '#B5A7D5',
- },
- {
- isBrightColor: false,
- name: 'light magenta 2',
- value: '#D5A6BD',
- },
-
- {
- isBrightColor: false,
- name: 'light red berry 1',
- value: '#CC4125',
- },
- {
- isBrightColor: false,
- name: 'light red 1',
- value: '#E06666',
- },
- {
- isBrightColor: false,
- name: 'light orange 1',
- value: '#F6B26B',
- },
- {
- isBrightColor: false,
- name: 'light yellow 1',
- value: '#FFD966',
- },
- {
- isBrightColor: false,
- name: 'light green 1',
- value: '#93C47D',
- },
- {
- isBrightColor: false,
- name: 'light cyan 1',
- value: '#76A5AE',
- },
- {
- isBrightColor: false,
- name: 'light cornflower blue 1',
- value: '#6C9EEB',
- },
- {
- isBrightColor: false,
- name: 'light blue 1',
- value: '#6FA8DC',
- },
- {
- isBrightColor: false,
- name: 'light purple 1',
- value: '#8D7CC3',
- },
- {
- isBrightColor: false,
- name: 'light magenta 1',
- value: '#C27BA0',
- },
-
- {
- isBrightColor: false,
- name: 'dark red berry 1',
- value: '#A61B00',
- },
- {
- isBrightColor: false,
- name: 'dark red 1',
- value: '#CC0000',
- },
- {
- isBrightColor: false,
- name: 'dark orange 1',
- value: '#E59138',
- },
- {
- isBrightColor: false,
- name: 'dark yellow 1',
- value: '#F1C231',
- },
- {
- isBrightColor: false,
- name: 'dark green 1',
- value: '#6AA74F',
- },
- {
- isBrightColor: false,
- name: 'dark cyan 1',
- value: '#45818E',
- },
- {
- isBrightColor: false,
- name: 'dark cornflower blue 1',
- value: '#3B78D8',
- },
- {
- isBrightColor: false,
- name: 'dark blue 1',
- value: '#3E84C6',
- },
- {
- isBrightColor: false,
- name: 'dark purple 1',
- value: '#664EA6',
- },
- {
- isBrightColor: false,
- name: 'dark magenta 1',
- value: '#A64D78',
- },
-
- {
- isBrightColor: false,
- name: 'dark red berry 2',
- value: '#84200D',
- },
- {
- isBrightColor: false,
- name: 'dark red 2',
- value: '#990001',
- },
- {
- isBrightColor: false,
- name: 'dark orange 2',
- value: '#B45F05',
- },
- {
- isBrightColor: false,
- name: 'dark yellow 2',
- value: '#BF9002',
- },
- {
- isBrightColor: false,
- name: 'dark green 2',
- value: '#38761D',
- },
- {
- isBrightColor: false,
- name: 'dark cyan 2',
- value: '#124F5C',
- },
- {
- isBrightColor: false,
- name: 'dark cornflower blue 2',
- value: '#1155CB',
- },
- {
- isBrightColor: false,
- name: 'dark blue 2',
- value: '#0C5394',
- },
- {
- isBrightColor: false,
- name: 'dark purple 2',
- value: '#351C75',
- },
- {
- isBrightColor: false,
- name: 'dark magenta 2',
- value: '#741B47',
- },
-
- {
- isBrightColor: false,
- name: 'dark red berry 3',
- value: '#5B0F00',
- },
- {
- isBrightColor: false,
- name: 'dark red 3',
- value: '#660000',
- },
- {
- isBrightColor: false,
- name: 'dark orange 3',
- value: '#783F04',
- },
- {
- isBrightColor: false,
- name: 'dark yellow 3',
- value: '#7E6000',
- },
- {
- isBrightColor: false,
- name: 'dark green 3',
- value: '#274E12',
- },
- {
- isBrightColor: false,
- name: 'dark cyan 3',
- value: '#0D343D',
- },
- {
- isBrightColor: false,
- name: 'dark cornflower blue 3',
- value: '#1B4487',
- },
- {
- isBrightColor: false,
- name: 'dark blue 3',
- value: '#083763',
- },
- {
- isBrightColor: false,
- name: 'dark purple 3',
- value: '#1F124D',
- },
- {
- isBrightColor: false,
- name: 'dark magenta 3',
- value: '#4C1130',
- },
-];
-
-export const DEFAULT_CUSTOM_COLORS = [
- {
- isBrightColor: false,
- name: 'dark orange 3',
- value: '#783F04',
- },
- {
- isBrightColor: false,
- name: 'dark grey 3',
- value: '#666666',
- },
- {
- isBrightColor: false,
- name: 'dark grey 2',
- value: '#999999',
- },
- {
- isBrightColor: false,
- name: 'light cornflower blue 1',
- value: '#6C9EEB',
- },
- {
- isBrightColor: false,
- name: 'dark magenta 3',
- value: '#4C1130',
- },
-];
diff --git a/apps/web/app/components/plate-ui/color-dropdown-menu-items.tsx b/apps/web/app/components/plate-ui/color-dropdown-menu-items.tsx
deleted file mode 100644
index 8714bdd9..00000000
--- a/apps/web/app/components/plate-ui/color-dropdown-menu-items.tsx
+++ /dev/null
@@ -1,111 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import type { DropdownMenuItemProps } from '@radix-ui/react-dropdown-menu';
-
-import { cn } from '@udecode/cn';
-import { Check } from 'lucide-react';
-
-import { buttonVariants } from './button';
-import { DropdownMenuItem } from './dropdown-menu';
-import {
- Tooltip,
- TooltipContent,
- TooltipProvider,
- TooltipTrigger,
-} from './tooltip';
-
-export type TColor = {
- isBrightColor: boolean;
- name: string;
- value: string;
-};
-
-type ColorDropdownMenuItemProps = {
- isBrightColor: boolean;
- isSelected: boolean;
- updateColor: (color: string) => void;
- value: string;
- name?: string;
-} & DropdownMenuItemProps;
-
-export function ColorDropdownMenuItem({
- className,
- isBrightColor,
- isSelected,
- name,
- updateColor,
- value,
- ...props
-}: ColorDropdownMenuItemProps) {
- const content = (
- {
- e.preventDefault();
- updateColor(value);
- }}
- {...props}
- >
- {isSelected ? : null}
-
- );
-
- return name ? (
-
- {content}
- {name}
-
- ) : (
- content
- );
-}
-
-type ColorDropdownMenuItemsProps = {
- colors: TColor[];
- updateColor: (color: string) => void;
- color?: string;
-} & React.HTMLAttributes;
-
-export function ColorDropdownMenuItems({
- className,
- color,
- colors,
- updateColor,
- ...props
-}: ColorDropdownMenuItemsProps) {
- return (
-
-
- {colors.map(({ isBrightColor, name, value }) => (
-
- ))}
- {props.children}
-
-
- );
-}
diff --git a/apps/web/app/components/plate-ui/color-dropdown-menu.tsx b/apps/web/app/components/plate-ui/color-dropdown-menu.tsx
deleted file mode 100644
index 924f77c2..00000000
--- a/apps/web/app/components/plate-ui/color-dropdown-menu.tsx
+++ /dev/null
@@ -1,58 +0,0 @@
-'use client';
-
-import type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';
-
-import {
- useColorDropdownMenu,
- useColorDropdownMenuState,
-} from '@udecode/plate-font/react';
-
-import { DEFAULT_COLORS, DEFAULT_CUSTOM_COLORS } from './color-constants';
-import { ColorPicker } from './color-picker';
-import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuTrigger,
-} from './dropdown-menu';
-import { ToolbarButton } from './toolbar';
-
-type ColorDropdownMenuProps = {
- nodeType: string;
- tooltip?: string;
-} & DropdownMenuProps;
-
-export function ColorDropdownMenu({
- children,
- nodeType,
- tooltip,
-}: ColorDropdownMenuProps) {
- const state = useColorDropdownMenuState({
- closeOnSelect: true,
- colors: DEFAULT_COLORS,
- customColors: DEFAULT_CUSTOM_COLORS,
- nodeType,
- });
-
- const { buttonProps, menuProps } = useColorDropdownMenu(state);
-
- return (
-
-
-
- {children}
-
-
-
-
-
-
-
- );
-}
diff --git a/apps/web/app/components/plate-ui/color-input.tsx b/apps/web/app/components/plate-ui/color-input.tsx
deleted file mode 100644
index 749b9ec8..00000000
--- a/apps/web/app/components/plate-ui/color-input.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import { cn, withRef } from '@udecode/cn';
-import { useComposedRef } from '@udecode/plate-common/react';
-import { useColorInput } from '@udecode/plate-font/react';
-
-export const ColorInput = withRef<'input'>(
- ({ children, className, value = '#000000', ...props }, ref) => {
- const { childProps, inputRef } = useColorInput();
-
- return (
-
- {React.Children.map(children, (child) => {
- if (!child) return child;
-
- return React.cloneElement(child as React.ReactElement, childProps);
- })}
-
-
-
- );
- }
-);
diff --git a/apps/web/app/components/plate-ui/color-picker.tsx b/apps/web/app/components/plate-ui/color-picker.tsx
deleted file mode 100644
index e51c8dc5..00000000
--- a/apps/web/app/components/plate-ui/color-picker.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import { cn, withRef } from '@udecode/cn';
-import { EraserIcon } from 'lucide-react';
-
-import {
- type TColor,
- ColorDropdownMenuItems,
-} from './color-dropdown-menu-items';
-import { ColorCustom } from './colors-custom';
-import { DropdownMenuGroup, DropdownMenuItem } from './dropdown-menu';
-
-export const ColorPickerContent = withRef<
- 'div',
- {
- clearColor: () => void;
- colors: TColor[];
- customColors: TColor[];
- updateColor: (color: string) => void;
- updateCustomColor: (color: string) => void;
- color?: string;
- }
->(
- (
- {
- className,
- clearColor,
- color,
- colors,
- customColors,
- updateColor,
- updateCustomColor,
- ...props
- },
- ref
- ) => {
- return (
-
-
-
-
-
-
-
- {color && (
-
-
-
- Clear
-
-
- )}
-
- );
- }
-);
-
-export const ColorPicker = React.memo(
- ColorPickerContent,
- (prev, next) =>
- prev.color === next.color &&
- prev.colors === next.colors &&
- prev.customColors === next.customColors
-);
diff --git a/apps/web/app/components/plate-ui/colors-custom.tsx b/apps/web/app/components/plate-ui/colors-custom.tsx
deleted file mode 100644
index e5568e72..00000000
--- a/apps/web/app/components/plate-ui/colors-custom.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-'use client';
-
-import React, { type ComponentPropsWithoutRef } from 'react';
-
-import { cn } from '@udecode/cn';
-import {
- useColorsCustom,
- useColorsCustomState,
-} from '@udecode/plate-font/react';
-import { PlusIcon } from 'lucide-react';
-
-import { buttonVariants } from './button';
-import {
- type TColor,
- ColorDropdownMenuItems,
-} from './color-dropdown-menu-items';
-import { ColorInput } from './color-input';
-
-// import { ColorInput } from './color-input';
-import { DropdownMenuItem } from './dropdown-menu';
-
-type ColorCustomProps = {
- colors: TColor[];
- customColors: TColor[];
- updateColor: (color: string) => void;
- updateCustomColor: (color: string) => void;
- color?: string;
-} & ComponentPropsWithoutRef<'div'>;
-
-export function ColorCustom({
- className,
- color,
- colors,
- customColors,
- updateColor,
- updateCustomColor,
- ...props
-}: ColorCustomProps) {
- const state = useColorsCustomState({
- color,
- colors,
- customColors,
- updateCustomColor,
- });
- const { inputProps, menuItemProps } = useColorsCustom(state);
-
- return (
-
- );
-}
diff --git a/apps/web/app/components/plate-ui/column-element.tsx b/apps/web/app/components/plate-ui/column-element.tsx
deleted file mode 100644
index 7d22126f..00000000
--- a/apps/web/app/components/plate-ui/column-element.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import type { TColumnElement } from '@udecode/plate-layout';
-
-import { cn, withRef } from '@udecode/cn';
-import { useElement, withHOC } from '@udecode/plate-common/react';
-import { ResizableProvider } from '@udecode/plate-resizable';
-import { useReadOnly } from 'slate-react';
-
-import { PlateElement } from './plate-element';
-
-export const ColumnElement = withHOC(
- ResizableProvider,
- withRef(({ children, className, ...props }, ref) => {
- const readOnly = useReadOnly();
- const { width } = useElement();
-
- return (
-
- {children}
-
- );
- })
-);
diff --git a/apps/web/app/components/plate-ui/column-group-element.tsx b/apps/web/app/components/plate-ui/column-group-element.tsx
deleted file mode 100644
index 10d903bd..00000000
--- a/apps/web/app/components/plate-ui/column-group-element.tsx
+++ /dev/null
@@ -1,186 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import type { TColumnElement } from '@udecode/plate-layout';
-
-import { cn, withRef } from '@udecode/cn';
-import { useElement, useRemoveNodeButton } from '@udecode/plate-common/react';
-import {
- ColumnItemPlugin,
- useColumnState,
- useDebouncePopoverOpen,
-} from '@udecode/plate-layout/react';
-import { type LucideProps, Trash2Icon } from 'lucide-react';
-import { useReadOnly } from 'slate-react';
-
-import { Button } from './button';
-import { PlateElement } from './plate-element';
-import { Popover, PopoverAnchor, PopoverContent } from './popover';
-import { Separator } from './separator';
-
-export const ColumnGroupElement = withRef(
- ({ children, className, ...props }, ref) => {
- return (
-
-
- {children}
-
-
- );
- }
-);
-
-export function ColumnFloatingToolbar({ children }: React.PropsWithChildren) {
- const readOnly = useReadOnly();
-
- const {
- setDoubleColumn,
- setDoubleSideDoubleColumn,
- setLeftSideDoubleColumn,
- setRightSideDoubleColumn,
- setThreeColumn,
- } = useColumnState();
-
- const element = useElement(ColumnItemPlugin.key);
-
- const { props: buttonProps } = useRemoveNodeButton({ element });
-
- const isOpen = useDebouncePopoverOpen();
-
- if (readOnly) return <>{children}>;
-
- return (
-
- {children}
- e.preventDefault()}
- align="center"
- side="top"
- sideOffset={10}
- >
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-}
-
-const DoubleColumnOutlined = (props: LucideProps) => (
-
-
-
-);
-
-const ThreeColumnOutlined = (props: LucideProps) => (
-
-
-
-);
-
-const RightSideDoubleColumnOutlined = (props: LucideProps) => (
-
-
-
-);
-
-const LeftSideDoubleColumnOutlined = (props: LucideProps) => (
-
-
-
-);
-
-const DoubleSideDoubleColumnOutlined = (props: LucideProps) => (
-
-
-
-);
diff --git a/apps/web/app/components/plate-ui/command.tsx b/apps/web/app/components/plate-ui/command.tsx
deleted file mode 100644
index 0a4b9dc1..00000000
--- a/apps/web/app/components/plate-ui/command.tsx
+++ /dev/null
@@ -1,88 +0,0 @@
-'use client';
-
-import * as React from 'react';
-
-import type { DialogProps } from '@radix-ui/react-dialog';
-
-import {
- cn,
- createPrimitiveElement,
- withCn,
- withRef,
- withVariants,
-} from '@udecode/cn';
-import { Command as CommandPrimitive } from 'cmdk';
-import { Search } from 'lucide-react';
-
-import { Dialog, DialogContent, DialogTitle } from './dialog';
-import { inputVariants } from './input';
-
-export const Command = withCn(
- CommandPrimitive,
- 'flex size-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground'
-);
-
-export function CommandDialog({ children, ...props }: DialogProps) {
- return (
-
-
- Command Dialog
-
- {children}
-
-
-
- );
-}
-
-export const CommandInput = withRef(
- ({ className, ...props }, ref) => (
-
-
-
-
- )
-);
-
-export const InputCommand = withVariants(
- CommandPrimitive.Input,
- inputVariants,
- ['variant']
-);
-
-export const CommandList = withCn(
- CommandPrimitive.List,
- 'max-h-[500px] overflow-y-auto overflow-x-hidden'
-);
-
-export const CommandEmpty = withCn(
- CommandPrimitive.Empty,
- 'py-6 text-center text-sm'
-);
-
-export const CommandGroup = withCn(
- CommandPrimitive.Group,
- 'overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground'
-);
-
-export const CommandSeparator = withCn(
- CommandPrimitive.Separator,
- '-mx-1 h-px bg-border'
-);
-
-export const CommandItem = withCn(
- CommandPrimitive.Item,
- 'relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0'
-);
-
-export const CommandShortcut = withCn(
- createPrimitiveElement('span'),
- 'ml-auto text-xs tracking-widest text-muted-foreground'
-);
diff --git a/apps/web/app/components/plate-ui/comment-avatar.tsx b/apps/web/app/components/plate-ui/comment-avatar.tsx
deleted file mode 100644
index f9a963ac..00000000
--- a/apps/web/app/components/plate-ui/comment-avatar.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import { CommentsPlugin } from '@udecode/plate-comments/react';
-import { useEditorPlugin } from '@udecode/plate-common/react';
-
-import { Avatar, AvatarFallback, AvatarImage } from './avatar';
-
-export function CommentAvatar({ userId }: { userId: string | null }) {
- const { useOption } = useEditorPlugin(CommentsPlugin);
- const user = useOption('userById', userId);
-
- if (!user) return null;
-
- return (
-
-
- {user.name?.[0]}
-
- );
-}
diff --git a/apps/web/app/components/plate-ui/comment-create-form.tsx b/apps/web/app/components/plate-ui/comment-create-form.tsx
deleted file mode 100644
index 3ccc6f82..00000000
--- a/apps/web/app/components/plate-ui/comment-create-form.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import { cn } from '@udecode/cn';
-import {
- CommentNewSubmitButton,
- CommentNewTextarea,
- CommentsPlugin,
-} from '@udecode/plate-comments/react';
-import { useEditorPlugin } from '@udecode/plate-common/react';
-
-import { buttonVariants } from './button';
-import { CommentAvatar } from './comment-avatar';
-import { inputVariants } from './input';
-
-export function CommentCreateForm() {
- const { useOption } = useEditorPlugin(CommentsPlugin);
-
- const myUserId = useOption('myUserId');
-
- return (
-
-
-
-
-
-
-
- Comment
-
-
-
- );
-}
diff --git a/apps/web/app/components/plate-ui/comment-item.tsx b/apps/web/app/components/plate-ui/comment-item.tsx
deleted file mode 100644
index 07fcc476..00000000
--- a/apps/web/app/components/plate-ui/comment-item.tsx
+++ /dev/null
@@ -1,74 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import {
- CommentProvider,
- CommentsPlugin,
- useCommentItemContentState,
-} from '@udecode/plate-comments/react';
-import { useEditorPlugin } from '@udecode/plate-common/react';
-import { formatDistance } from 'date-fns';
-
-import { CommentAvatar } from './comment-avatar';
-import { CommentMoreDropdown } from './comment-more-dropdown';
-import { CommentResolveButton } from './comment-resolve-button';
-import { CommentValue } from './comment-value';
-
-type PlateCommentProps = {
- commentId: string;
-};
-
-function CommentItemContent() {
- const {
- comment,
- commentText,
- editingValue,
- isMyComment,
- isReplyComment,
- user,
- } = useCommentItemContentState();
-
- return (
-
-
-
-
-
{user?.name}
-
-
- {formatDistance(comment.createdAt, Date.now())} ago
-
-
- {isMyComment && (
-
- {isReplyComment ? null : }
-
-
-
- )}
-
-
-
- {editingValue ? (
-
- ) : (
-
{commentText}
- )}
-
-
- );
-}
-
-export function CommentItem({ commentId }: PlateCommentProps) {
- const { useOption } = useEditorPlugin(CommentsPlugin);
- const comment = useOption('commentById', commentId);
-
- if (!comment) return null;
-
- return (
-
- );
-}
diff --git a/apps/web/app/components/plate-ui/comment-leaf.tsx b/apps/web/app/components/plate-ui/comment-leaf.tsx
deleted file mode 100644
index 0751d01d..00000000
--- a/apps/web/app/components/plate-ui/comment-leaf.tsx
+++ /dev/null
@@ -1,49 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import type { TCommentText } from '@udecode/plate-comments';
-
-import { cn } from '@udecode/cn';
-import {
- useCommentLeaf,
- useCommentLeafState,
-} from '@udecode/plate-comments/react';
-import { type PlateLeafProps, PlateLeaf } from '@udecode/plate-common/react';
-
-export function CommentLeaf({
- className,
- ...props
-}: PlateLeafProps) {
- const { children, leaf, nodeProps } = props;
-
- const state = useCommentLeafState({ leaf });
- const { props: rootProps } = useCommentLeaf(state);
-
- if (!state.commentCount) return <>{children}>;
-
- let aboveChildren = <>{children}>;
-
- if (!state.isActive) {
- for (let i = 1; i < state.commentCount; i++) {
- aboveChildren = {aboveChildren} ;
- }
- }
-
- return (
-
- {aboveChildren}
-
- );
-}
diff --git a/apps/web/app/components/plate-ui/comment-more-dropdown.tsx b/apps/web/app/components/plate-ui/comment-more-dropdown.tsx
deleted file mode 100644
index 2a5316e5..00000000
--- a/apps/web/app/components/plate-ui/comment-more-dropdown.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import { cn } from '@udecode/cn';
-import {
- useCommentDeleteButton,
- useCommentDeleteButtonState,
- useCommentEditButton,
- useCommentEditButtonState,
-} from '@udecode/plate-comments/react';
-import { MoreHorizontal } from 'lucide-react';
-
-import { Button } from './button';
-import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuGroup,
- DropdownMenuItem,
- DropdownMenuTrigger,
-} from './dropdown-menu';
-
-export function CommentMoreDropdown() {
- const editButtonState = useCommentEditButtonState();
- const { props: editProps } = useCommentEditButton(editButtonState);
- const deleteButtonState = useCommentDeleteButtonState();
- const { props: deleteProps } = useCommentDeleteButton(deleteButtonState);
-
- return (
-
-
-
-
-
-
-
-
- Edit comment
- Delete comment
-
-
-
- );
-}
diff --git a/apps/web/app/components/plate-ui/comment-reply-items.tsx b/apps/web/app/components/plate-ui/comment-reply-items.tsx
deleted file mode 100644
index 543a13f5..00000000
--- a/apps/web/app/components/plate-ui/comment-reply-items.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import {
- SCOPE_ACTIVE_COMMENT,
- useCommentReplies,
-} from '@udecode/plate-comments/react';
-
-import { CommentItem } from './comment-item';
-
-export function CommentReplyItems() {
- const commentReplies = useCommentReplies(SCOPE_ACTIVE_COMMENT);
-
- return (
- <>
- {Object.keys(commentReplies).map((id) => (
-
- ))}
- >
- );
-}
diff --git a/apps/web/app/components/plate-ui/comment-resolve-button.tsx b/apps/web/app/components/plate-ui/comment-resolve-button.tsx
deleted file mode 100644
index 239a59ac..00000000
--- a/apps/web/app/components/plate-ui/comment-resolve-button.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import { cn } from '@udecode/cn';
-import {
- CommentResolveButton as CommentResolveButtonPrimitive,
- useComment,
-} from '@udecode/plate-comments/react';
-import { Check, RotateCcw } from 'lucide-react';
-
-import { buttonVariants } from './button';
-
-export function CommentResolveButton() {
- const comment = useComment()!;
-
- return (
-
- {comment.isResolved ? (
-
- ) : (
-
- )}
-
- );
-}
diff --git a/apps/web/app/components/plate-ui/comment-toolbar-button.tsx b/apps/web/app/components/plate-ui/comment-toolbar-button.tsx
deleted file mode 100644
index 16f8ac08..00000000
--- a/apps/web/app/components/plate-ui/comment-toolbar-button.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import { useCommentAddButton } from '@udecode/plate-comments/react';
-import { MessageSquarePlus } from 'lucide-react';
-
-import { ToolbarButton } from './toolbar';
-
-export function CommentToolbarButton() {
- const { hidden, props } = useCommentAddButton();
-
- if (hidden) return null;
-
- return (
-
-
-
- );
-}
diff --git a/apps/web/app/components/plate-ui/comment-value.tsx b/apps/web/app/components/plate-ui/comment-value.tsx
deleted file mode 100644
index 9c531484..00000000
--- a/apps/web/app/components/plate-ui/comment-value.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import { cn } from '@udecode/cn';
-import {
- CommentEditActions,
- CommentEditTextarea,
-} from '@udecode/plate-comments/react';
-
-import { buttonVariants } from './button';
-import { inputVariants } from './input';
-
-export function CommentValue() {
- return (
-
-
-
-
-
- Cancel
-
-
-
- Save
-
-
-
- );
-}
diff --git a/apps/web/app/components/plate-ui/comments-popover.tsx b/apps/web/app/components/plate-ui/comments-popover.tsx
deleted file mode 100644
index 298e19a9..00000000
--- a/apps/web/app/components/plate-ui/comments-popover.tsx
+++ /dev/null
@@ -1,63 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import { cn } from '@udecode/cn';
-import {
- CommentProvider,
- CommentsPositioner,
- SCOPE_ACTIVE_COMMENT,
- useFloatingCommentsContentState,
- useFloatingCommentsState,
-} from '@udecode/plate-comments/react';
-import { PortalBody } from '@udecode/plate-common/react';
-
-import { CommentCreateForm } from './comment-create-form';
-import { CommentItem } from './comment-item';
-import { CommentReplyItems } from './comment-reply-items';
-import { popoverVariants } from './popover';
-
-export type FloatingCommentsContentProps = {
- disableForm?: boolean;
-};
-
-export function CommentsPopoverContent(props: FloatingCommentsContentProps) {
- const { disableForm } = props;
-
- const { activeCommentId, hasNoComment, myUserId, ref } =
- useFloatingCommentsContentState();
-
- return (
-
- );
-}
-
-export function CommentsPopover() {
- const { activeCommentId, loaded } = useFloatingCommentsState();
-
- if (!loaded || !activeCommentId) return null;
-
- return (
-
-
-
-
-
- );
-}
diff --git a/apps/web/app/components/plate-ui/context-menu.tsx b/apps/web/app/components/plate-ui/context-menu.tsx
deleted file mode 100644
index baf1d1f1..00000000
--- a/apps/web/app/components/plate-ui/context-menu.tsx
+++ /dev/null
@@ -1,229 +0,0 @@
-'use client';
-
-import * as React from 'react';
-
-import * as ContextMenuPrimitive from '@radix-ui/react-context-menu';
-import { cn } from '@udecode/cn';
-import { Check, ChevronRight, Circle } from 'lucide-react';
-
-const ContextMenu = ContextMenuPrimitive.Root;
-
-const ContextMenuTrigger = ContextMenuPrimitive.Trigger;
-
-const ContextMenuGroup = React.forwardRef<
- HTMLDivElement,
- { label?: React.ReactNode } & React.ComponentPropsWithoutRef<
- typeof ContextMenuPrimitive.Group
- >
->(({ label, ...props }, ref) => {
- return (
- <>
-
-
-
- {label && {label} }
- {props.children}
-
- >
- );
-});
-
-const ContextMenuPortal = ContextMenuPrimitive.Portal;
-
-const ContextMenuSub = ContextMenuPrimitive.Sub;
-
-const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup;
-
-const ContextMenuSubTrigger = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef & {
- inset?: boolean;
- }
->(({ children, className, inset, ...props }, ref) => (
-
- {children}
-
-
-));
-ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName;
-
-const ContextMenuSubContent = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-));
-ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName;
-
-const ContextMenuContent = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-
-
-));
-ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName;
-
-const ContextMenuItem = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef & {
- inset?: boolean;
- }
->(({ className, inset, ...props }, ref) => (
-
-));
-ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName;
-
-const ContextMenuCheckboxItem = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ checked, children, className, ...props }, ref) => (
-
-
-
-
-
-
- {children}
-
-));
-ContextMenuCheckboxItem.displayName =
- ContextMenuPrimitive.CheckboxItem.displayName;
-
-const ContextMenuRadioItem = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ children, className, ...props }, ref) => (
-
-
-
-
-
-
- {children}
-
-));
-ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName;
-
-const ContextMenuLabel = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef & {
- inset?: boolean;
- }
->(({ className, inset, ...props }, ref) => (
-
-));
-ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName;
-
-const ContextMenuSeparator = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-));
-ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName;
-
-const ContextMenuShortcut = ({
- className,
- ...props
-}: React.HTMLAttributes) => {
- return (
-
- );
-};
-ContextMenuShortcut.displayName = 'ContextMenuShortcut';
-
-export {
- ContextMenu,
- ContextMenuCheckboxItem,
- ContextMenuContent,
- ContextMenuGroup,
- ContextMenuItem,
- ContextMenuLabel,
- ContextMenuPortal,
- ContextMenuRadioGroup,
- ContextMenuRadioItem,
- ContextMenuSeparator,
- ContextMenuShortcut,
- ContextMenuSub,
- ContextMenuSubContent,
- ContextMenuSubTrigger,
- ContextMenuTrigger,
-};
diff --git a/apps/web/app/components/plate-ui/cursor-overlay.tsx b/apps/web/app/components/plate-ui/cursor-overlay.tsx
deleted file mode 100644
index f964d93c..00000000
--- a/apps/web/app/components/plate-ui/cursor-overlay.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-'use client';
-
-import React from 'react';
-
-import { cn } from '@udecode/cn';
-import { isCollapsed } from '@udecode/plate-common';
-import {
- type CursorData,
- type CursorOverlayState,
- useCursorOverlay,
-} from '@udecode/plate-selection/react';
-
-export function Cursor({
- id,
- caretPosition,
- data,
- selection,
- selectionRects,
-}: CursorOverlayState) {
- const { style, selectionStyle = style } = data ?? ({} as CursorData);
- const isCursor = isCollapsed(selection);
-
- return (
- <>
- {selectionRects.map((position, i) => {
- return (
-
- );
- })}
- {caretPosition && (
-
- )}
- >
- );
-}
-
-export function CursorOverlay() {
- const { cursors } = useCursorOverlay();
-
- return (
- <>
- {cursors.map((cursor) => (
-
- ))}
- >
- );
-}
diff --git a/apps/web/app/components/plate-ui/date-element.tsx b/apps/web/app/components/plate-ui/date-element.tsx
deleted file mode 100644
index a9b12737..00000000
--- a/apps/web/app/components/plate-ui/date-element.tsx
+++ /dev/null
@@ -1,85 +0,0 @@
-'use client';
-
-import { cn, withRef } from '@udecode/cn';
-import { setNodes } from '@udecode/plate-common';
-import { findNodePath } from '@udecode/plate-common/react';
-
-import { Calendar } from './calendar';
-import { PlateElement } from './plate-element';
-import { Popover, PopoverContent, PopoverTrigger } from './popover';
-
-export const DateElement = withRef(
- ({ children, className, ...props }, ref) => {
- const { editor, element } = props;
-
- return (
-