diff --git a/drizzle/0003_famous_skaar.sql b/drizzle/0003_famous_skaar.sql deleted file mode 100644 index 3511c3e8..00000000 --- a/drizzle/0003_famous_skaar.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE "workspace_share_links" ADD COLUMN "claim_count" integer DEFAULT 0 NOT NULL; diff --git a/drizzle/meta/0003_snapshot.json b/drizzle/meta/0003_snapshot.json deleted file mode 100644 index 26089e8e..00000000 --- a/drizzle/meta/0003_snapshot.json +++ /dev/null @@ -1,2083 +0,0 @@ -{ - "id": "fe5effef-0bfd-4d84-84dc-571c0b80b2ae", - "prevId": "77a2e4b0-3244-4eda-8ffd-41ba7999b3e1", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.account": { - "name": "account", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "account_id": { - "name": "account_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "provider_id": { - "name": "provider_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "access_token": { - "name": "access_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "refresh_token": { - "name": "refresh_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "id_token": { - "name": "id_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "access_token_expires_at": { - "name": "access_token_expires_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "refresh_token_expires_at": { - "name": "refresh_token_expires_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "scope": { - "name": "scope", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "password": { - "name": "password", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "idx_account_user_id": { - "name": "idx_account_user_id", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "text_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "account_user_id_user_id_fk": { - "name": "account_user_id_user_id_fk", - "tableFrom": "account", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.chat_messages": { - "name": "chat_messages", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "thread_id": { - "name": "thread_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "message_id": { - "name": "message_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "parent_id": { - "name": "parent_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "format": { - "name": "format", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "content": { - "name": "content", - "type": "jsonb", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": { - "idx_chat_messages_thread": { - "name": "idx_chat_messages_thread", - "columns": [ - { - "expression": "thread_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "uuid_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_chat_messages_thread_created": { - "name": "idx_chat_messages_thread_created", - "columns": [ - { - "expression": "thread_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "uuid_ops" - }, - { - "expression": "created_at", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "timestamptz_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "chat_messages_thread_id_chat_threads_id_fk": { - "name": "chat_messages_thread_id_chat_threads_id_fk", - "tableFrom": "chat_messages", - "tableTo": "chat_threads", - "columnsFrom": ["thread_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "chat_messages_thread_message_key": { - "name": "chat_messages_thread_message_key", - "nullsNotDistinct": false, - "columns": ["thread_id", "message_id"] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.chat_threads": { - "name": "chat_threads", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "workspace_id": { - "name": "workspace_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "title": { - "name": "title", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "is_archived": { - "name": "is_archived", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "external_id": { - "name": "external_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "last_message_at": { - "name": "last_message_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "head_message_id": { - "name": "head_message_id", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "idx_chat_threads_workspace": { - "name": "idx_chat_threads_workspace", - "columns": [ - { - "expression": "workspace_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "uuid_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_chat_threads_user": { - "name": "idx_chat_threads_user", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "text_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_chat_threads_last_message": { - "name": "idx_chat_threads_last_message", - "columns": [ - { - "expression": "workspace_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "uuid_ops" - }, - { - "expression": "last_message_at", - "isExpression": false, - "asc": false, - "nulls": "first", - "opclass": "timestamptz_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "chat_threads_workspace_id_workspaces_id_fk": { - "name": "chat_threads_workspace_id_workspaces_id_fk", - "tableFrom": "chat_threads", - "tableTo": "workspaces", - "columnsFrom": ["workspace_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "chat_threads_user_id_user_id_fk": { - "name": "chat_threads_user_id_user_id_fk", - "tableFrom": "chat_threads", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": { - "chat_threads_user_scoped": { - "name": "chat_threads_user_scoped", - "as": "PERMISSIVE", - "for": "ALL", - "to": ["authenticated"], - "using": "((chat_threads.user_id = (auth.jwt() ->> 'sub'::text))\n AND ((EXISTS ( SELECT 1 FROM workspaces w\n WHERE ((w.id = chat_threads.workspace_id) AND (w.user_id = (auth.jwt() ->> 'sub'::text)))))\n OR (EXISTS ( SELECT 1 FROM workspace_collaborators c\n WHERE ((c.workspace_id = chat_threads.workspace_id) AND (c.user_id = (auth.jwt() ->> 'sub'::text)))))))" - } - }, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.session": { - "name": "session", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true - }, - "token": { - "name": "token", - "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 - }, - "ip_address": { - "name": "ip_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "user_agent": { - "name": "user_agent", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "idx_session_user_id": { - "name": "idx_session_user_id", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "text_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_session_token": { - "name": "idx_session_token", - "columns": [ - { - "expression": "token", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "text_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "session_user_id_user_id_fk": { - "name": "session_user_id_user_id_fk", - "tableFrom": "session", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "session_token_unique": { - "name": "session_token_unique", - "nullsNotDistinct": false, - "columns": ["token"] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.user": { - "name": "user", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "email": { - "name": "email", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "email_verified": { - "name": "email_verified", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "image": { - "name": "image", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "is_anonymous": { - "name": "is_anonymous", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "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": { - "idx_user_email": { - "name": "idx_user_email", - "columns": [ - { - "expression": "email", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "text_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "user_email_unique": { - "name": "user_email_unique", - "nullsNotDistinct": false, - "columns": ["email"] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.user_profiles": { - "name": "user_profiles", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "onboarding_completed": { - "name": "onboarding_completed", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "onboarding_completed_at": { - "name": "onboarding_completed_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": { - "idx_user_profiles_user_id": { - "name": "idx_user_profiles_user_id", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "text_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "user_profiles_user_id_key": { - "name": "user_profiles_user_id_key", - "nullsNotDistinct": false, - "columns": ["user_id"] - } - }, - "policies": { - "Users can insert their own profile": { - "name": "Users can insert their own profile", - "as": "PERMISSIVE", - "for": "INSERT", - "to": ["authenticated"], - "withCheck": "(( SELECT (auth.jwt() ->> 'sub'::text)) = user_id)" - }, - "Users can update their own profile": { - "name": "Users can update their own profile", - "as": "PERMISSIVE", - "for": "UPDATE", - "to": ["authenticated"] - }, - "Users can view their own profile": { - "name": "Users can view their own profile", - "as": "PERMISSIVE", - "for": "SELECT", - "to": ["authenticated"] - } - }, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.verification": { - "name": "verification", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "identifier": { - "name": "identifier", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp", - "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()" - } - }, - "indexes": { - "idx_verification_identifier": { - "name": "idx_verification_identifier", - "columns": [ - { - "expression": "identifier", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "text_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.workspace_collaborators": { - "name": "workspace_collaborators", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "workspace_id": { - "name": "workspace_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "permission_level": { - "name": "permission_level", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'editor'" - }, - "invite_token": { - "name": "invite_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "last_opened_at": { - "name": "last_opened_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": { - "idx_workspace_collaborators_lookup": { - "name": "idx_workspace_collaborators_lookup", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "text_ops" - }, - { - "expression": "workspace_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "uuid_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_workspace_collaborators_workspace": { - "name": "idx_workspace_collaborators_workspace", - "columns": [ - { - "expression": "workspace_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "uuid_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_workspace_collaborators_last_opened_at": { - "name": "idx_workspace_collaborators_last_opened_at", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "text_ops" - }, - { - "expression": "last_opened_at", - "isExpression": false, - "asc": false, - "nulls": "first", - "opclass": "timestamptz_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "workspace_collaborators_workspace_id_fkey": { - "name": "workspace_collaborators_workspace_id_fkey", - "tableFrom": "workspace_collaborators", - "tableTo": "workspaces", - "columnsFrom": ["workspace_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "workspace_collaborators_invite_token_unique": { - "name": "workspace_collaborators_invite_token_unique", - "nullsNotDistinct": false, - "columns": ["invite_token"] - }, - "workspace_collaborators_workspace_user_unique": { - "name": "workspace_collaborators_workspace_user_unique", - "nullsNotDistinct": false, - "columns": ["workspace_id", "user_id"] - } - }, - "policies": { - "Owners can manage collaborators": { - "name": "Owners can manage collaborators", - "as": "PERMISSIVE", - "for": "ALL", - "to": ["authenticated"], - "using": "(EXISTS ( SELECT 1\n FROM workspaces w\n WHERE ((w.id = workspace_collaborators.workspace_id) AND (w.user_id = (auth.jwt() ->> 'sub'::text)))))" - }, - "Collaborators can view their access": { - "name": "Collaborators can view their access", - "as": "PERMISSIVE", - "for": "SELECT", - "to": ["authenticated"], - "using": "(user_id = (auth.jwt() ->> 'sub'::text))" - } - }, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.workspace_invites": { - "name": "workspace_invites", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "workspace_id": { - "name": "workspace_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "email": { - "name": "email", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "token": { - "name": "token", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "inviter_id": { - "name": "inviter_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "permission_level": { - "name": "permission_level", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'editor'" - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": { - "idx_workspace_invites_token": { - "name": "idx_workspace_invites_token", - "columns": [ - { - "expression": "token", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "text_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_workspace_invites_email": { - "name": "idx_workspace_invites_email", - "columns": [ - { - "expression": "email", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "text_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_workspace_invites_workspace": { - "name": "idx_workspace_invites_workspace", - "columns": [ - { - "expression": "workspace_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "uuid_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "workspace_invites_workspace_id_fkey": { - "name": "workspace_invites_workspace_id_fkey", - "tableFrom": "workspace_invites", - "tableTo": "workspaces", - "columnsFrom": ["workspace_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "workspace_invites_token_key": { - "name": "workspace_invites_token_key", - "nullsNotDistinct": false, - "columns": ["token"] - } - }, - "policies": { - "Public can view invite by token": { - "name": "Public can view invite by token", - "as": "PERMISSIVE", - "for": "SELECT", - "to": ["public"], - "using": "true" - }, - "Users can insert invites for workspaces they own/edit": { - "name": "Users can insert invites for workspaces they own/edit", - "as": "PERMISSIVE", - "for": "INSERT", - "to": ["authenticated"], - "withCheck": "(EXISTS ( SELECT 1\n FROM workspaces w\n WHERE ((w.id = workspace_invites.workspace_id) AND (w.user_id = (auth.jwt() ->> 'sub'::text))))) OR (EXISTS ( SELECT 1\n FROM workspace_collaborators c\n WHERE ((c.workspace_id = workspace_invites.workspace_id) AND (c.user_id = (auth.jwt() ->> 'sub'::text)) AND (c.permission_level = 'editor'::text))))" - } - }, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.workspace_item_content": { - "name": "workspace_item_content", - "schema": "", - "columns": { - "workspace_id": { - "name": "workspace_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "item_id": { - "name": "item_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "data_schema_version": { - "name": "data_schema_version", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 1 - }, - "content_hash": { - "name": "content_hash", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "''" - }, - "text_content": { - "name": "text_content", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "structured_data": { - "name": "structured_data", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "asset_data": { - "name": "asset_data", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "embed_data": { - "name": "embed_data", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "source_data": { - "name": "source_data", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "idx_workspace_item_content_workspace": { - "name": "idx_workspace_item_content_workspace", - "columns": [ - { - "expression": "workspace_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "uuid_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "workspace_item_content_workspace_item_fkey": { - "name": "workspace_item_content_workspace_item_fkey", - "tableFrom": "workspace_item_content", - "tableTo": "workspace_items", - "columnsFrom": ["workspace_id", "item_id"], - "columnsTo": ["workspace_id", "item_id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "workspace_item_content_pkey": { - "name": "workspace_item_content_pkey", - "columns": ["workspace_id", "item_id"] - } - }, - "uniqueConstraints": {}, - "policies": { - "Users can read workspace item content they have access to": { - "name": "Users can read workspace item content they have access to", - "as": "PERMISSIVE", - "for": "SELECT", - "to": ["public"], - "using": "(EXISTS ( SELECT 1\n FROM workspaces\n WHERE ((workspaces.id = workspace_item_content.workspace_id) AND (workspaces.user_id = (auth.jwt() ->> 'sub'::text))))) OR (EXISTS ( SELECT 1\n FROM workspace_collaborators c\n WHERE ((c.workspace_id = workspace_item_content.workspace_id) AND (c.user_id = (auth.jwt() ->> 'sub'::text)))))" - }, - "Users can write workspace item content they have write access to": { - "name": "Users can write workspace item content they have write access to", - "as": "PERMISSIVE", - "for": "ALL", - "to": ["public"], - "using": "(EXISTS ( SELECT 1\n FROM workspaces\n WHERE ((workspaces.id = workspace_item_content.workspace_id) AND (workspaces.user_id = (auth.jwt() ->> 'sub'::text))))) OR (EXISTS ( SELECT 1\n FROM workspace_collaborators c\n WHERE ((c.workspace_id = workspace_item_content.workspace_id) AND (c.user_id = (auth.jwt() ->> 'sub'::text)) AND (c.permission_level = 'editor'::text))))", - "withCheck": "(EXISTS ( SELECT 1\n FROM workspaces\n WHERE ((workspaces.id = workspace_item_content.workspace_id) AND (workspaces.user_id = (auth.jwt() ->> 'sub'::text))))) OR (EXISTS ( SELECT 1\n FROM workspace_collaborators c\n WHERE ((c.workspace_id = workspace_item_content.workspace_id) AND (c.user_id = (auth.jwt() ->> 'sub'::text)) AND (c.permission_level = 'editor'::text))))" - } - }, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.workspace_item_extracted": { - "name": "workspace_item_extracted", - "schema": "", - "columns": { - "workspace_id": { - "name": "workspace_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "item_id": { - "name": "item_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "search_text": { - "name": "search_text", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "''" - }, - "content_preview": { - "name": "content_preview", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "ocr_text": { - "name": "ocr_text", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "transcript_text": { - "name": "transcript_text", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "ocr_pages": { - "name": "ocr_pages", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "transcript_segments": { - "name": "transcript_segments", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "idx_workspace_item_extracted_workspace": { - "name": "idx_workspace_item_extracted_workspace", - "columns": [ - { - "expression": "workspace_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "uuid_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "workspace_item_extracted_workspace_item_fkey": { - "name": "workspace_item_extracted_workspace_item_fkey", - "tableFrom": "workspace_item_extracted", - "tableTo": "workspace_items", - "columnsFrom": ["workspace_id", "item_id"], - "columnsTo": ["workspace_id", "item_id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "workspace_item_extracted_pkey": { - "name": "workspace_item_extracted_pkey", - "columns": ["workspace_id", "item_id"] - } - }, - "uniqueConstraints": {}, - "policies": { - "Users can read workspace item extracted data they have access to": { - "name": "Users can read workspace item extracted data they have access to", - "as": "PERMISSIVE", - "for": "SELECT", - "to": ["public"], - "using": "(EXISTS ( SELECT 1\n FROM workspaces\n WHERE ((workspaces.id = workspace_item_extracted.workspace_id) AND (workspaces.user_id = (auth.jwt() ->> 'sub'::text))))) OR (EXISTS ( SELECT 1\n FROM workspace_collaborators c\n WHERE ((c.workspace_id = workspace_item_extracted.workspace_id) AND (c.user_id = (auth.jwt() ->> 'sub'::text)))))" - }, - "Users can write workspace item extracted data they have write access to": { - "name": "Users can write workspace item extracted data they have write access to", - "as": "PERMISSIVE", - "for": "ALL", - "to": ["public"], - "using": "(EXISTS ( SELECT 1\n FROM workspaces\n WHERE ((workspaces.id = workspace_item_extracted.workspace_id) AND (workspaces.user_id = (auth.jwt() ->> 'sub'::text))))) OR (EXISTS ( SELECT 1\n FROM workspace_collaborators c\n WHERE ((c.workspace_id = workspace_item_extracted.workspace_id) AND (c.user_id = (auth.jwt() ->> 'sub'::text)) AND (c.permission_level = 'editor'::text))))", - "withCheck": "(EXISTS ( SELECT 1\n FROM workspaces\n WHERE ((workspaces.id = workspace_item_extracted.workspace_id) AND (workspaces.user_id = (auth.jwt() ->> 'sub'::text))))) OR (EXISTS ( SELECT 1\n FROM workspace_collaborators c\n WHERE ((c.workspace_id = workspace_item_extracted.workspace_id) AND (c.user_id = (auth.jwt() ->> 'sub'::text)) AND (c.permission_level = 'editor'::text))))" - } - }, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.workspace_items": { - "name": "workspace_items", - "schema": "", - "columns": { - "workspace_id": { - "name": "workspace_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "item_id": { - "name": "item_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "subtitle": { - "name": "subtitle", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "''" - }, - "color": { - "name": "color", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "folder_id": { - "name": "folder_id", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "layout": { - "name": "layout", - "type": "jsonb", - "primaryKey": false, - "notNull": false - }, - "last_modified": { - "name": "last_modified", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "source_version": { - "name": "source_version", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "data_schema_version": { - "name": "data_schema_version", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 1 - }, - "content_hash": { - "name": "content_hash", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "''" - }, - "processing_status": { - "name": "processing_status", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "has_ocr": { - "name": "has_ocr", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "ocr_status": { - "name": "ocr_status", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "ocr_page_count": { - "name": "ocr_page_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "has_transcript": { - "name": "has_transcript", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "source_count": { - "name": "source_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "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": { - "idx_workspace_items_workspace": { - "name": "idx_workspace_items_workspace", - "columns": [ - { - "expression": "workspace_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "uuid_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_workspace_items_workspace_folder": { - "name": "idx_workspace_items_workspace_folder", - "columns": [ - { - "expression": "workspace_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "uuid_ops" - }, - { - "expression": "folder_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "text_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_workspace_items_workspace_type": { - "name": "idx_workspace_items_workspace_type", - "columns": [ - { - "expression": "workspace_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "uuid_ops" - }, - { - "expression": "type", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "text_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_workspace_items_workspace_updated": { - "name": "idx_workspace_items_workspace_updated", - "columns": [ - { - "expression": "workspace_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "uuid_ops" - }, - { - "expression": "updated_at", - "isExpression": false, - "asc": false, - "nulls": "first", - "opclass": "timestamptz_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_workspace_items_workspace_version": { - "name": "idx_workspace_items_workspace_version", - "columns": [ - { - "expression": "workspace_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "uuid_ops" - }, - { - "expression": "source_version", - "isExpression": false, - "asc": false, - "nulls": "first", - "opclass": "int4_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_workspace_items_workspace_processing": { - "name": "idx_workspace_items_workspace_processing", - "columns": [ - { - "expression": "workspace_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "uuid_ops" - }, - { - "expression": "processing_status", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "text_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_workspace_items_workspace_ocr": { - "name": "idx_workspace_items_workspace_ocr", - "columns": [ - { - "expression": "workspace_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "uuid_ops" - }, - { - "expression": "has_ocr", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "bool_ops" - }, - { - "expression": "ocr_status", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "text_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_workspace_items_workspace_ocr_page_count": { - "name": "idx_workspace_items_workspace_ocr_page_count", - "columns": [ - { - "expression": "workspace_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "uuid_ops" - }, - { - "expression": "ocr_page_count", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "int4_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_workspace_items_workspace_has_transcript": { - "name": "idx_workspace_items_workspace_has_transcript", - "columns": [ - { - "expression": "workspace_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "uuid_ops" - }, - { - "expression": "has_transcript", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "bool_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_workspace_items_workspace_source_count": { - "name": "idx_workspace_items_workspace_source_count", - "columns": [ - { - "expression": "workspace_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "uuid_ops" - }, - { - "expression": "source_count", - "isExpression": false, - "asc": false, - "nulls": "first", - "opclass": "int4_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "workspace_items_workspace_id_fkey": { - "name": "workspace_items_workspace_id_fkey", - "tableFrom": "workspace_items", - "tableTo": "workspaces", - "columnsFrom": ["workspace_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": { - "workspace_items_pkey": { - "name": "workspace_items_pkey", - "columns": ["workspace_id", "item_id"] - } - }, - "uniqueConstraints": {}, - "policies": { - "Users can read workspace items they have access to": { - "name": "Users can read workspace items they have access to", - "as": "PERMISSIVE", - "for": "SELECT", - "to": ["public"], - "using": "(EXISTS ( SELECT 1\n FROM workspaces\n WHERE ((workspaces.id = workspace_items.workspace_id) AND (workspaces.user_id = (auth.jwt() ->> 'sub'::text))))) OR (EXISTS ( SELECT 1\n FROM workspace_collaborators c\n WHERE ((c.workspace_id = workspace_items.workspace_id) AND (c.user_id = (auth.jwt() ->> 'sub'::text)))))" - }, - "Users can write workspace items they have write access to": { - "name": "Users can write workspace items they have write access to", - "as": "PERMISSIVE", - "for": "ALL", - "to": ["public"], - "using": "(EXISTS ( SELECT 1\n FROM workspaces\n WHERE ((workspaces.id = workspace_items.workspace_id) AND (workspaces.user_id = (auth.jwt() ->> 'sub'::text))))) OR (EXISTS ( SELECT 1\n FROM workspace_collaborators c\n WHERE ((c.workspace_id = workspace_items.workspace_id) AND (c.user_id = (auth.jwt() ->> 'sub'::text)) AND (c.permission_level = 'editor'::text))))", - "withCheck": "(EXISTS ( SELECT 1\n FROM workspaces\n WHERE ((workspaces.id = workspace_items.workspace_id) AND (workspaces.user_id = (auth.jwt() ->> 'sub'::text))))) OR (EXISTS ( SELECT 1\n FROM workspace_collaborators c\n WHERE ((c.workspace_id = workspace_items.workspace_id) AND (c.user_id = (auth.jwt() ->> 'sub'::text)) AND (c.permission_level = 'editor'::text))))" - } - }, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.workspace_share_links": { - "name": "workspace_share_links", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "workspace_id": { - "name": "workspace_id", - "type": "uuid", - "primaryKey": false, - "notNull": true - }, - "token": { - "name": "token", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "permission_level": { - "name": "permission_level", - "type": "text", - "primaryKey": false, - "notNull": true, - "default": "'editor'" - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "claim_count": { - "name": "claim_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - } - }, - "indexes": { - "idx_workspace_share_links_token": { - "name": "idx_workspace_share_links_token", - "columns": [ - { - "expression": "token", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "text_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_workspace_share_links_workspace": { - "name": "idx_workspace_share_links_workspace", - "columns": [ - { - "expression": "workspace_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "uuid_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "workspace_share_links_workspace_id_fkey": { - "name": "workspace_share_links_workspace_id_fkey", - "tableFrom": "workspace_share_links", - "tableTo": "workspaces", - "columnsFrom": ["workspace_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "workspace_share_links_token_key": { - "name": "workspace_share_links_token_key", - "nullsNotDistinct": false, - "columns": ["token"] - }, - "workspace_share_links_workspace_key": { - "name": "workspace_share_links_workspace_key", - "nullsNotDistinct": false, - "columns": ["workspace_id"] - } - }, - "policies": { - "Public can view share link by token": { - "name": "Public can view share link by token", - "as": "PERMISSIVE", - "for": "SELECT", - "to": ["public"], - "using": "true" - }, - "Owners and editors can manage share links": { - "name": "Owners and editors can manage share links", - "as": "PERMISSIVE", - "for": "ALL", - "to": ["authenticated"], - "using": "(EXISTS ( SELECT 1\n FROM workspaces w\n WHERE ((w.id = workspace_share_links.workspace_id) AND (w.user_id = (auth.jwt() ->> 'sub'::text))))) OR (EXISTS ( SELECT 1\n FROM workspace_collaborators c\n WHERE ((c.workspace_id = workspace_share_links.workspace_id) AND (c.user_id = (auth.jwt() ->> 'sub'::text)) AND (c.permission_level = 'editor'::text))))" - } - }, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.workspaces": { - "name": "workspaces", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "user_id": { - "name": "user_id", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false, - "default": "''" - }, - "template": { - "name": "template", - "type": "text", - "primaryKey": false, - "notNull": false, - "default": "'blank'" - }, - "is_public": { - "name": "is_public", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "slug": { - "name": "slug", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "icon": { - "name": "icon", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "sort_order": { - "name": "sort_order", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "color": { - "name": "color", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "last_opened_at": { - "name": "last_opened_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "idx_workspaces_created_at": { - "name": "idx_workspaces_created_at", - "columns": [ - { - "expression": "created_at", - "isExpression": false, - "asc": false, - "nulls": "first", - "opclass": "timestamptz_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_workspaces_slug": { - "name": "idx_workspaces_slug", - "columns": [ - { - "expression": "slug", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "text_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_workspaces_user_id": { - "name": "idx_workspaces_user_id", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "text_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_workspaces_user_slug": { - "name": "idx_workspaces_user_slug", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "text_ops" - }, - { - "expression": "slug", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "text_ops" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_workspaces_user_sort_order": { - "name": "idx_workspaces_user_sort_order", - "columns": [ - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "text_ops" - }, - { - "expression": "sort_order", - "isExpression": false, - "asc": true, - "nulls": "last", - "opclass": "int4_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "idx_workspaces_last_opened_at": { - "name": "idx_workspaces_last_opened_at", - "columns": [ - { - "expression": "last_opened_at", - "isExpression": false, - "asc": false, - "nulls": "first", - "opclass": "timestamptz_ops" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": { - "Users can delete their own workspaces": { - "name": "Users can delete their own workspaces", - "as": "PERMISSIVE", - "for": "DELETE", - "to": ["authenticated"], - "using": "(( SELECT (auth.jwt() ->> 'sub'::text)) = user_id)" - }, - "Users can insert their own workspaces": { - "name": "Users can insert their own workspaces", - "as": "PERMISSIVE", - "for": "INSERT", - "to": ["authenticated"] - }, - "Users can update their own workspaces": { - "name": "Users can update their own workspaces", - "as": "PERMISSIVE", - "for": "UPDATE", - "to": ["authenticated"] - }, - "Users can view their own workspaces": { - "name": "Users can view their own workspaces", - "as": "PERMISSIVE", - "for": "SELECT", - "to": ["authenticated"] - } - }, - "checkConstraints": {}, - "isRLSEnabled": false - } - }, - "enums": {}, - "schemas": {}, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index ed0f8b33..c5478bf0 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -22,13 +22,6 @@ "when": 1775793600000, "tag": "0002_zero_publication", "breakpoints": true - }, - { - "idx": 3, - "version": "7", - "when": 1776913168760, - "tag": "0003_famous_skaar", - "breakpoints": true } ] } diff --git a/src/app/api/share-link/claim/route.ts b/src/app/api/share-link/claim/route.ts index 7c2b4dd4..fd901478 100644 --- a/src/app/api/share-link/claim/route.ts +++ b/src/app/api/share-link/claim/route.ts @@ -1,5 +1,5 @@ import { NextRequest, NextResponse } from "next/server"; -import { and, eq, sql } from "drizzle-orm"; +import { and, eq } from "drizzle-orm"; import { requireAuth, withErrorHandling } from "@/lib/api/workspace-helpers"; import { db } from "@/lib/db/client"; import { @@ -47,41 +47,31 @@ async function handlePOST(request: NextRequest) { return NextResponse.json({ error: "Share link expired" }, { status: 410 }); } + const [existing] = await db + .select() + .from(workspaceCollaborators) + .where( + and( + eq(workspaceCollaborators.workspaceId, shareLink.workspaceId), + eq(workspaceCollaborators.userId, userId), + ), + ) + .limit(1); + + if (!existing) { + await db.insert(workspaceCollaborators).values({ + workspaceId: shareLink.workspaceId, + userId, + permissionLevel: shareLink.permissionLevel, + }); + } + const [workspace] = await db - .select({ - slug: workspaces.slug, - id: workspaces.id, - ownerId: workspaces.userId, - }) + .select({ slug: workspaces.slug, id: workspaces.id }) .from(workspaces) .where(eq(workspaces.id, shareLink.workspaceId)) .limit(1); - if (workspace && workspace.ownerId !== userId) { - const [existing] = await db - .select() - .from(workspaceCollaborators) - .where( - and( - eq(workspaceCollaborators.workspaceId, shareLink.workspaceId), - eq(workspaceCollaborators.userId, userId), - ), - ) - .limit(1); - - if (!existing) { - await db.insert(workspaceCollaborators).values({ - workspaceId: shareLink.workspaceId, - userId, - permissionLevel: shareLink.permissionLevel, - }); - await db - .update(workspaceShareLinks) - .set({ claimCount: sql`${workspaceShareLinks.claimCount} + 1` }) - .where(eq(workspaceShareLinks.id, shareLink.id)); - } - } - return NextResponse.json({ success: true, workspaceId: workspace?.id, diff --git a/src/app/api/workspaces/[id]/share-link/route.ts b/src/app/api/workspaces/[id]/share-link/route.ts index 23c139a2..8e9a0a50 100644 --- a/src/app/api/workspaces/[id]/share-link/route.ts +++ b/src/app/api/workspaces/[id]/share-link/route.ts @@ -54,29 +54,6 @@ async function handlePOST( return NextResponse.json({ token, url }); } -async function handleGET( - _request: NextRequest, - { params }: { params: Promise<{ id: string }> }, -) { - const userId = await requireAuth(); - const { id: workspaceId } = await params; - - await verifyWorkspaceAccess(workspaceId, userId, "editor"); - - const [shareLink] = await db - .select({ claimCount: workspaceShareLinks.claimCount }) - .from(workspaceShareLinks) - .where(eq(workspaceShareLinks.workspaceId, workspaceId)) - .limit(1); - - return NextResponse.json({ claimCount: shareLink?.claimCount ?? 0 }); -} - -export const GET = withErrorHandling( - handleGET, - "GET /api/workspaces/[id]/share-link", -); - export const POST = withErrorHandling( handlePOST, "POST /api/workspaces/[id]/share-link", diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx index 1cb4d4d0..c1d9bfff 100644 --- a/src/app/dashboard/page.tsx +++ b/src/app/dashboard/page.tsx @@ -18,7 +18,6 @@ import { useSession } from "@/lib/auth-client"; import { WorkspaceSection } from "@/components/workspace-canvas/WorkspaceSection"; import { OpenWorkspaceItemView } from "@/components/workspace-canvas/OpenWorkspaceItemView"; import { AnonymousSignInPrompt } from "@/components/modals/AnonymousSignInPrompt"; -import { RafflePopup } from "@/components/modals/RafflePopup"; import { DashboardLayout } from "@/components/layout/DashboardLayout"; import WorkspaceHeader from "@/components/workspace-canvas/WorkspaceHeader"; import { WorkspaceSearchDialog } from "@/components/workspace-canvas/WorkspaceSearchDialog"; @@ -71,10 +70,6 @@ function DashboardContent({ const currentWorkspaceTitle = currentWorkspace?.name; const currentWorkspaceIcon = currentWorkspace?.icon; const currentWorkspaceColor = currentWorkspace?.color; - const isWorkspaceOwner = - !!session?.user?.id && - !!currentWorkspace && - session.user.id === currentWorkspace.userId; // Check onboarding status // const { shouldShowOnboarding, isLoading: isLoadingOnboarding } = useOnboardingStatus(); @@ -143,9 +138,6 @@ function DashboardContent({ const [showWorkspaceSettings, setShowWorkspaceSettings] = useState(false); const [showWorkspaceShare, setShowWorkspaceShare] = useState(false); - // Manual open state for the raffle popup (re-opened via the share-count badge). - const [showRafflePopup, setShowRafflePopup] = useState(false); - const showSignInPrompt = !!session?.user?.isAnonymous && !isLoadingWorkspace && @@ -287,14 +279,6 @@ function DashboardContent({ } }} /> - setShowWorkspaceShare(true)} - manuallyOpen={showRafflePopup} - onManuallyClose={() => setShowRafflePopup(false)} - /> setShowRafflePopup(true)} /> ) : undefined } @@ -371,7 +353,6 @@ function DashboardContent({ state={state} addItem={operations.createItem} updateItem={operations.updateItem} - updateItemData={operations.updateItemData} deleteItem={operations.deleteItem} updateAllItems={operations.updateAllItems} isChatMaximized={isChatMaximized} diff --git a/src/app/invite/claim/[token]/page.tsx b/src/app/invite/claim/[token]/page.tsx index 84bbaa1f..b0d69f1d 100644 --- a/src/app/invite/claim/[token]/page.tsx +++ b/src/app/invite/claim/[token]/page.tsx @@ -1,6 +1,6 @@ import { headers } from "next/headers"; import { redirect } from "next/navigation"; -import { eq, sql } from "drizzle-orm"; +import { eq } from "drizzle-orm"; import { auth } from "@/lib/auth"; import { db } from "@/lib/db/client"; import { @@ -17,24 +17,8 @@ async function claimAndResolveSlug(params: { workspaceId: string; userId: string; permissionLevel: string; -}): Promise<{ slug: string | null; inserted: boolean; isOwner: boolean }> { - const [workspace] = await db - .select({ slug: workspaces.slug, ownerId: workspaces.userId }) - .from(workspaces) - .where(eq(workspaces.id, params.workspaceId)) - .limit(1); - - if (!workspace) { - return { slug: null, inserted: false, isOwner: false }; - } - - const isOwner = workspace.ownerId === params.userId; - - if (isOwner) { - return { slug: workspace.slug, inserted: false, isOwner: true }; - } - - const inserted = await db +}): Promise<{ slug: string | null }> { + await db .insert(workspaceCollaborators) .values({ workspaceId: params.workspaceId, @@ -46,14 +30,15 @@ async function claimAndResolveSlug(params: { workspaceCollaborators.workspaceId, workspaceCollaborators.userId, ], - }) - .returning({ id: workspaceCollaborators.id }); + }); + + const [workspace] = await db + .select({ slug: workspaces.slug }) + .from(workspaces) + .where(eq(workspaces.id, params.workspaceId)) + .limit(1); - return { - slug: workspace.slug, - inserted: inserted.length > 0, - isOwner: false, - }; + return { slug: workspace?.slug ?? null }; } export default async function InviteClaimPage({ @@ -130,7 +115,7 @@ export default async function InviteClaimPage({ if (new Date(shareLink.expiresAt) < new Date()) { error = "expired"; } else { - const { slug, inserted } = await claimAndResolveSlug({ + const { slug } = await claimAndResolveSlug({ workspaceId: shareLink.workspaceId, userId: session.user.id, permissionLevel: shareLink.permissionLevel, @@ -139,12 +124,6 @@ export default async function InviteClaimPage({ if (!slug) { error = "workspace-deleted"; } else { - if (inserted) { - await db - .update(workspaceShareLinks) - .set({ claimCount: sql`${workspaceShareLinks.claimCount} + 1` }) - .where(eq(workspaceShareLinks.id, shareLink.id)); - } workspaceSlug = slug; } } diff --git a/src/components/modals/RafflePopup.tsx b/src/components/modals/RafflePopup.tsx deleted file mode 100644 index e4379bcc..00000000 --- a/src/components/modals/RafflePopup.tsx +++ /dev/null @@ -1,231 +0,0 @@ -"use client"; - -import { useEffect, useState } from "react"; -import { Check, Copy, Files, Gift, Link2, Mail } from "lucide-react"; -import { toast } from "sonner"; -import { - Dialog, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, -} from "@/components/ui/dialog"; -import { Badge } from "@/components/ui/badge"; -import { Button } from "@/components/ui/button"; -import { Input } from "@/components/ui/input"; -import { useSession } from "@/lib/auth-client"; -import { useNewFeature } from "@/lib/utils/new-feature"; -import type { WorkspaceWithState } from "@/lib/workspace-state/types"; - -interface RafflePopupProps { - workspace: WorkspaceWithState | null; - currentWorkspaceId: string | null; - isLoadingWorkspace: boolean; - onOpenFullShare?: () => void; - /** Force the popup open regardless of dismissal state (e.g. user clicked the share-count badge). */ - manuallyOpen?: boolean; - /** Called when a manually-opened popup is closed; parent should clear its manual-open state. */ - onManuallyClose?: () => void; -} - -const FEATURE_KEY = "midterms-raffle-2026-04"; -const FEATURE_END_DATE = new Date(2026, 3, 25, 23, 59, 59); - -export function RafflePopup({ - workspace, - currentWorkspaceId, - isLoadingWorkspace, - onOpenFullShare, - manuallyOpen = false, - onManuallyClose, -}: RafflePopupProps) { - const { data: session } = useSession(); - const { isNew, dismiss } = useNewFeature({ - featureKey: FEATURE_KEY, - endDate: FEATURE_END_DATE, - }); - const [linkMode, setLinkMode] = useState<"collaborate" | "deepcopy">( - "collaborate", - ); - const [shareLinkUrl, setShareLinkUrl] = useState(""); - const [isLoadingShareLink, setIsLoadingShareLink] = useState(false); - const [copied, setCopied] = useState(false); - - const canShowPopup = - !!currentWorkspaceId && - !isLoadingWorkspace && - !!workspace && - session?.user?.isAnonymous !== true && - workspace?.userId === session?.user?.id; - - const isOpen = canShowPopup && (isNew || manuallyOpen); - - useEffect(() => { - if (!isOpen || !workspace) return; - - const controller = new AbortController(); - setIsLoadingShareLink(true); - setShareLinkUrl(""); - - fetch(`/api/workspaces/${workspace.id}/share-link`, { - method: "POST", - signal: controller.signal, - }) - .then((res) => res.json()) - .then((data) => { - if (data.url) setShareLinkUrl(data.url); - }) - .catch((err) => { - if ((err as { name?: string } | null)?.name !== "AbortError") { - console.error(err); - } - }) - .finally(() => { - if (!controller.signal.aborted) setIsLoadingShareLink(false); - }); - - return () => { - controller.abort(); - }; - }, [isOpen, workspace]); - - if (!canShowPopup || !workspace) { - return null; - } - - const handleClose = () => { - if (isNew) dismiss(); - onManuallyClose?.(); - }; - - const deepCopyUrl = `${typeof window !== "undefined" ? window.location.origin : ""}/share-copy/${workspace.id}`; - const activeUrl = linkMode === "collaborate" ? shareLinkUrl : deepCopyUrl; - const isActiveLoading = linkMode === "collaborate" && isLoadingShareLink; - - const handleCopyShareLink = async () => { - if (!activeUrl) return; - - try { - await navigator.clipboard.writeText(activeUrl); - setCopied(true); - toast.success("Link copied"); - setTimeout(() => setCopied(false), 2000); - } catch { - toast.error("Failed to copy"); - } - }; - - return ( - { - if (!next) handleClose(); - }} - > - - -
-
- -
- - Raffle - -
- Win a $50 Amazon gift card - - Share this workspace with 5 or more people and - you'll be entered to win a $50 Amazon gift card. - Copy your share link below and send it over — each person who joins - counts. - -
- -
- - -
- -
- - -
- -

- {linkMode === "collaborate" - ? "Adds them as a collaborator. Expires in 7 days." - : "Recipient gets their own independent copy. Does not expire."} -

- - - {onOpenFullShare ? ( - - ) : ( - - )} - - -
-
- ); -} diff --git a/src/components/workspace-canvas/FlashcardContent.tsx b/src/components/workspace-canvas/FlashcardContent.tsx index 082ed22b..b1c4cb10 100644 --- a/src/components/workspace-canvas/FlashcardContent.tsx +++ b/src/components/workspace-canvas/FlashcardContent.tsx @@ -1,101 +1,37 @@ "use client"; -import { useCallback, useEffect, useMemo, useRef, useState } from "react"; -import { Check } from "lucide-react"; -import { DocumentEditor } from "@/components/editor/DocumentEditor"; +import { useMemo } from "react"; import type { Item, ItemData, FlashcardData, } from "@/lib/workspace-state/types"; import { StreamdownMarkdown } from "@/components/ui/streamdown-markdown"; -import { cn } from "@/lib/utils"; interface FlashcardContentProps { item: Item; onUpdateData: (updater: (prev: ItemData) => ItemData) => void; } -function FlashcardSideEditable({ +function FlashcardSidePreview({ title, markdown, emptyLabel, - isEditing, - onStartEditing, - onStopEditing, - onChange, - cardName, }: { title: string; markdown: string; emptyLabel: string; - isEditing: boolean; - onStartEditing: () => void; - onStopEditing: () => void; - onChange: (markdown: string) => void; - cardName?: string; }) { - const containerRef = useRef(null); - - useEffect(() => { - if (!isEditing) return; - const el = containerRef.current; - if (!el) return; - - const handler = (e: KeyboardEvent) => { - if (e.key !== "Escape") return; - e.preventDefault(); - e.stopPropagation(); - onStopEditing(); - }; - - el.addEventListener("keydown", handler); - return () => el.removeEventListener("keydown", handler); - }, [isEditing, onStopEditing]); - return ( -
-
-
- {title} -
- {isEditing && ( - - )} +
+
+ {title}
{ - if (isEditing) return; - const target = e.target as HTMLElement; - if (target.closest("a")) return; - onStartEditing(); - }} > - {isEditing ? ( - onChange(nextMarkdown)} - /> - ) : !markdown.trim() ? ( + {!markdown.trim() ? (
{emptyLabel}
@@ -111,73 +47,9 @@ function FlashcardSideEditable({ ); } -export function FlashcardContent({ item, onUpdateData }: FlashcardContentProps) { +export function FlashcardContent({ item }: FlashcardContentProps) { const flashcardData = item.data as FlashcardData; const cards = useMemo(() => flashcardData.cards ?? [], [flashcardData.cards]); - const [editing, setEditing] = useState<{ - cardId: string; - side: "front" | "back"; - } | null>(null); - - // Local drafts override stale `card.front`/`card.back` while `onUpdateData` - // is debounced (~500ms). Without this, re-entering a side within the - // debounce window would mount the editor with the stale props value and - // silently drop the queued keystrokes when the user types again. Drafts - // also prevent the read-only preview from flickering back to old content - // between Done and flush. - const [drafts, setDrafts] = useState>({}); - const draftKey = (cardId: string, side: "front" | "back") => - `${cardId}:${side}`; - - const resolveMarkdown = useCallback( - (card: { id: string; front: string; back: string }, side: "front" | "back"): string => { - const draft = drafts[draftKey(card.id, side)]; - const source = side === "front" ? card.front : card.back; - return draft ?? source; - }, - [drafts], - ); - - // Drop a draft once the authoritative source (item.data) catches up, so - // future remote edits via realtime sync aren't masked by a stale local - // override. - useEffect(() => { - setDrafts((prev) => { - let changed = false; - const next: Record = {}; - for (const [key, value] of Object.entries(prev)) { - const [cardId, side] = key.split(":") as [string, "front" | "back"]; - const card = cards.find((c) => c.id === cardId); - if (!card) { - changed = true; - continue; - } - const source = side === "front" ? card.front : card.back; - if (source === value) { - changed = true; - continue; - } - next[key] = value; - } - return changed ? next : prev; - }); - }, [cards]); - - const handleChange = useCallback( - (cardId: string, side: "front" | "back", markdown: string) => { - setDrafts((prev) => ({ ...prev, [draftKey(cardId, side)]: markdown })); - onUpdateData((prev) => { - const prevFc = prev as FlashcardData; - return { - ...prevFc, - cards: (prevFc.cards ?? []).map((c) => - c.id === cardId ? { ...c, [side]: markdown } : c, - ), - } as FlashcardData; - }); - }, - [onUpdateData], - ); return (
@@ -201,38 +73,16 @@ export function FlashcardContent({ item, onUpdateData }: FlashcardContentProps)
- - setEditing({ cardId: card.id, side: "front" }) - } - onStopEditing={() => setEditing(null)} - onChange={(markdown) => - handleChange(card.id, "front", markdown) - } - cardName={item.name} /> - - setEditing({ cardId: card.id, side: "back" }) - } - onStopEditing={() => setEditing(null)} - onChange={(markdown) => - handleChange(card.id, "back", markdown) - } - cardName={item.name} />
diff --git a/src/components/workspace-canvas/FlashcardWorkspaceCard.tsx b/src/components/workspace-canvas/FlashcardWorkspaceCard.tsx index 1de720b6..047d3105 100644 --- a/src/components/workspace-canvas/FlashcardWorkspaceCard.tsx +++ b/src/components/workspace-canvas/FlashcardWorkspaceCard.tsx @@ -7,8 +7,6 @@ import { Trash2, CheckCircle2, Pencil, - ZoomIn, - ZoomOut, Palette, ChevronLeft, ChevronRight, @@ -19,7 +17,6 @@ import { PiMouseScrollFill, PiMouseScrollBold } from "react-icons/pi"; import { useTheme } from "next-themes"; import type { Item, - ItemData, FlashcardData, FlashcardItem, } from "@/lib/workspace-state/types"; @@ -73,16 +70,6 @@ interface FlashcardWorkspaceCardProps { workspaceIcon?: string | null; workspaceColor?: string | null; onUpdateItem: (itemId: string, updates: Partial) => void; - /** - * Optional updater-style data patcher. Preferred for patching individual - * fields inside `data` (e.g. `zoom`) because it composes with other - * in-flight `updateItemData` updaters instead of overwriting the whole - * blob the way `onUpdateItem({ data })` does. - */ - onUpdateItemData?: ( - itemId: string, - updater: (prev: ItemData) => ItemData, - ) => void; onDeleteItem: (itemId: string) => void; onOpenModal: (itemId: string) => void; onMoveItem?: (itemId: string, folderId: string | null) => void; // Callback to move item to folder @@ -96,15 +83,10 @@ const EMPTY_FLASHCARD_PLACEHOLDER: FlashcardItem = { back: "", }; -const ZOOM_MIN = 0.5; -const ZOOM_MAX = 2.5; -const ZOOM_STEP = 0.1; -const ZOOM_DEFAULT = 1; - /** Center all markdown blocks on the card; keep code blocks full-width and left-aligned. */ const FLASHCARD_STREAMDOWN_CLASS = cn( // Fluid type: size comes from the nearest [container-type:size] ancestor (card face) - "font-medium max-w-none text-center leading-[1.45] text-[length:calc(clamp(0.82rem,0.42rem+3cqmin,2.85rem)*var(--flashcard-zoom,1))]", + "font-medium max-w-none text-center leading-[1.45] text-[length:clamp(0.82rem,0.42rem+3cqmin,2.85rem)]", // globals.css fixes .streamdown-content at 0.875rem — inherit this wrapper’s fluid size instead "[&_.streamdown-content]:!text-inherit [&_.streamdown-content]:![font-size:1em]", "[&_.streamdown-content_p]:!text-inherit [&_.streamdown-content_li]:!text-inherit [&_.streamdown-content_td]:!text-inherit [&_.streamdown-content_th]:!text-inherit", @@ -147,7 +129,7 @@ const FlashcardSideMarkdownView = memo( >
{!markdown.trim() ? ( -
+
Ask the AI or click the pencil icon to add flashcards
) : ( @@ -173,7 +155,6 @@ export function FlashcardWorkspaceCard({ workspaceIcon, workspaceColor, onUpdateItem, - onUpdateItemData, onDeleteItem, onOpenModal, onMoveItem, @@ -196,9 +177,6 @@ export function FlashcardWorkspaceCard({ (state) => state.toggleItemScrollLocked, ); const flashcardData = item.data as FlashcardData; - const persistedZoom = - (flashcardData as FlashcardData & { zoom?: number }).zoom ?? ZOOM_DEFAULT; - const [localZoom, setLocalZoom] = useState(persistedZoom); // Navigation State const [currentIndex, setCurrentIndex] = useState(0); @@ -215,34 +193,6 @@ export function FlashcardWorkspaceCard({ } }, [cards.length, currentIndex]); - useEffect(() => { - setLocalZoom(persistedZoom); - }, [persistedZoom]); - - const clampZoom = (z: number) => - Math.min(ZOOM_MAX, Math.max(ZOOM_MIN, Math.round(z * 10) / 10)); - - const applyZoom = useCallback( - (next: number) => { - const clamped = clampZoom(next); - setLocalZoom(clamped); - if (onUpdateItemData) { - // Preferred path: compose with any in-flight `updateItemData` updaters - // for this item so we never clobber pending Tiptap edits. - onUpdateItemData(item.id, (prev) => ({ - ...(prev as FlashcardData), - zoom: clamped, - })); - return; - } - // Fallback (legacy wiring): full `data` replacement via updateItem. - onUpdateItem(item.id, { - data: { ...(item.data as FlashcardData), zoom: clamped }, - }); - }, - [item.id, item.data, onUpdateItem, onUpdateItemData], - ); - // Persist index change (optional debounce?) const handleIndexChange = useCallback((newIndex: number) => { // Don't persist on every click to avoid network spam, or do? @@ -535,7 +485,7 @@ export function FlashcardWorkspaceCard({
@@ -581,62 +531,6 @@ export function FlashcardWorkspaceCard({ -
- - - -
- - - {tooltip} - - ); -} diff --git a/src/components/workspace-canvas/WorkspaceContent.tsx b/src/components/workspace-canvas/WorkspaceContent.tsx index f9f85b87..1cccec17 100644 --- a/src/components/workspace-canvas/WorkspaceContent.tsx +++ b/src/components/workspace-canvas/WorkspaceContent.tsx @@ -3,7 +3,7 @@ import { useQueryClient } from "@tanstack/react-query"; import { useWorkspaceStore } from "@/lib/stores/workspace-store"; import { Plus, Upload } from "lucide-react"; import { EmptyState } from "@/components/empty-state"; -import type { Item, ItemData, CardType } from "@/lib/workspace-state/types"; +import type { Item, CardType } from "@/lib/workspace-state/types"; import { filterItemsByFolder } from "@/lib/workspace-state/search"; import { useAutoScroll } from "@/hooks/ui/use-auto-scroll"; import { transcriptSegmentsQueryKey } from "@/hooks/workspace/use-transcript-segments"; @@ -26,10 +26,6 @@ interface WorkspaceContentProps { initialData?: Partial, ) => string; updateItem: (itemId: string, updates: Partial) => void; - updateItemData: ( - itemId: string, - updater: (prev: ItemData) => ItemData, - ) => void; deleteItem: (itemId: string) => void; updateAllItems: (items: Item[]) => void; openWorkspaceItem: (itemId: string | null) => void; @@ -50,7 +46,6 @@ export default function WorkspaceContent({ viewState, addItem, updateItem, - updateItemData, deleteItem, updateAllItems, openWorkspaceItem, @@ -340,7 +335,6 @@ export default function WorkspaceContent({ onDragStart={handleDragStart} onDragStop={handleDragStop} onUpdateItem={handleUpdateItem} - onUpdateItemData={updateItemData} onDeleteItem={handleDeleteItem} onUpdateAllItems={handleUpdateAllItems} onOpenModal={handleOpenModal} diff --git a/src/components/workspace-canvas/WorkspaceGrid.tsx b/src/components/workspace-canvas/WorkspaceGrid.tsx index e11c8b15..ddfdc8e1 100644 --- a/src/components/workspace-canvas/WorkspaceGrid.tsx +++ b/src/components/workspace-canvas/WorkspaceGrid.tsx @@ -3,7 +3,7 @@ import { wrapCompactor, fastVerticalCompactor } from "react-grid-layout/extras"; import { useFeatureFlagEnabled } from "posthog-js/react"; import { useMemo, useCallback, useRef, useEffect, useState } from "react"; import React from "react"; -import type { Item, ItemData } from "@/lib/workspace-state/types"; +import type { Item } from "@/lib/workspace-state/types"; import { itemsToLayout, generateMissingLayouts, updateItemsWithLayout } from "@/lib/workspace-state/grid-layout-helpers"; import { isDescendantOf } from "@/lib/workspace-state/search"; import { WorkspaceCard } from "./WorkspaceCard"; @@ -35,10 +35,6 @@ interface WorkspaceGridProps { onDragStart: () => void; onDragStop: (layout: LayoutItem[]) => void; onUpdateItem: (itemId: string, updates: Partial) => void; - onUpdateItemData?: ( - itemId: string, - updater: (prev: ItemData) => ItemData, - ) => void; onDeleteItem: (itemId: string) => void; onUpdateAllItems: (items: Item[]) => void; onOpenModal: (itemId: string) => void; @@ -65,7 +61,6 @@ function WorkspaceGridComponent({ onDragStart, onDragStop, onUpdateItem, - onUpdateItemData, onDeleteItem, onUpdateAllItems, onOpenModal, @@ -667,7 +662,6 @@ function WorkspaceGridComponent({ workspaceIcon={workspaceIcon} workspaceColor={workspaceColor} onUpdateItem={handleUpdateItem} - onUpdateItemData={onUpdateItemData} onDeleteItem={handleDeleteItem} onOpenModal={handleOpenModal} onMoveItem={onMoveItem} @@ -691,7 +685,6 @@ function WorkspaceGridComponent({ allItems, displayItems, handleUpdateItem, - onUpdateItemData, handleDeleteItem, handleOpenModal, onMoveItem, diff --git a/src/components/workspace-canvas/WorkspaceHeader.tsx b/src/components/workspace-canvas/WorkspaceHeader.tsx index c481fae6..0bfb0dfe 100644 --- a/src/components/workspace-canvas/WorkspaceHeader.tsx +++ b/src/components/workspace-canvas/WorkspaceHeader.tsx @@ -73,7 +73,6 @@ import { AudioRecorderDialog } from "@/components/modals/AudioRecorderDialog"; import { useAudioRecordingStore } from "@/lib/stores/audio-recording-store"; import { renderWorkspaceMenuItems } from "./workspace-menu-items"; import { WorkspaceFeedbackDialog } from "./WorkspaceFeedbackDialog"; -import { ShareCountBadge } from "@/components/workspace-canvas/ShareCountBadge"; import { PromptBuilderDialog } from "@/components/assistant-ui/PromptBuilderDialog"; const EMPTY_ITEMS: Item[] = []; const EMPTY_RESPONSIVE_BREADCRUMBS = { @@ -255,8 +254,6 @@ interface WorkspaceHeaderProps { // Workspace actions onOpenSettings?: () => void; onOpenShare?: () => void; - /** Open the raffle details popup (reopens the "Win a $50 Amazon gift card" dialog). */ - onShowRaffleDetails?: () => void; /** Item shown in the fullscreen workspace viewer (`openMode === "single"`) — breadcrumbs + header actions */ activeOpenWorkspaceItem?: Item | null; @@ -267,7 +264,6 @@ interface WorkspaceHeaderProps { /** Flush pending saves and read latest document markdown from workspace cache (avoids stale export). */ getDocumentMarkdownForExport?: (itemId: string) => string; googleLoginHint?: string | null; - isWorkspaceOwner?: boolean; } export function WorkspaceHeader({ @@ -288,7 +284,6 @@ export function WorkspaceHeader({ onRenameFolder, onOpenSettings, onOpenShare, - onShowRaffleDetails, activeOpenWorkspaceItem = null, onCloseActiveItem, @@ -297,7 +292,6 @@ export function WorkspaceHeader({ onUpdateActiveItem, getDocumentMarkdownForExport, googleLoginHint, - isWorkspaceOwner = false, }: WorkspaceHeaderProps) { const [isNewMenuOpen, setIsNewMenuOpen] = useState(false); const [showRenameDialog, setShowRenameDialog] = useState(false); @@ -1243,12 +1237,6 @@ export function WorkspaceHeader({ Feedback - {isWorkspaceOwner && currentWorkspaceId && ( - - )} {onOpenShare && (