From 0878b5e87f9f9c73879f7774a357a59e3cadadc4 Mon Sep 17 00:00:00 2001 From: Zimeng Xiong Date: Fri, 21 Nov 2025 19:31:59 -0800 Subject: [PATCH] Trash ID Update Collections --- backend/dev.db | Bin 28672 -> 0 bytes backend/prisma/dev.db | Bin 0 -> 36864 bytes .../20251122032308_add_preview/migration.sql | 2 + backend/prisma/migrations/migration_lock.toml | 4 +- backend/prisma/schema.prisma | 1 + backend/src/generated/client/edge.js | 10 +- backend/src/generated/client/index-browser.js | 1 + backend/src/generated/client/index.d.ts | 151 +++++++++++------- backend/src/generated/client/index.js | 10 +- backend/src/generated/client/package.json | 2 +- backend/src/generated/client/schema.prisma | 1 + backend/src/generated/client/wasm.js | 1 + backend/src/index.ts | 35 +++- frontend/src/components/Sidebar.tsx | 16 +- frontend/src/pages/Dashboard.tsx | 20 +-- frontend/src/pages/Editor.tsx | 16 +- 16 files changed, 169 insertions(+), 101 deletions(-) delete mode 100644 backend/dev.db create mode 100644 backend/prisma/migrations/20251122032308_add_preview/migration.sql diff --git a/backend/dev.db b/backend/dev.db deleted file mode 100644 index ea34ea10e7413d2300ae471beb9ce3beee461380..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28672 zcmeI5O>f)C8ONzOvRiizFVIDO$c5n^8Uvy*GbD$kPE{n@)vjYZddVgYw!(-U+KgpM zOVUofK@LHHw#OFjska__=sAZ1y>`Drfnq<(_ST0ICD~StWP#1W*@vg$jGa>WH0jRcSY5yOYTZP~M zJQcmZtjFSMG&soLmTOI~+V<3T_3n|Hb#JTM z*=egZuf-qs`_fM#b0cr!?KQo|_HG7Dy`!Daplzy6Z_9(~YhFv$YO{U- z{*3&ly0@#=y&VtqX?Zz+i0bTT-BD}RR;^n1RyXzK<&EmCf)Wh^`7HUW55J&v#Ys9G zhr79?U7DY)ynMX0vT^%%;ZEXLfph-fjx1yq?aT{^~Qbdda24J6){-g`5alH(_FJI!ziEFw0{!EFk^Jn=vczV$D_PDm@E1b6qKZL zlz^3;48}d3&JCU27MPe8Xr!esyd8)f~QYt}(*E)qZjNB{{S0VIF~kN^@u0!RP}Ab}ql zfl8s+*(er?uq}u8n9eO~>82~FE=I~K_y?EHr>|228V{r?}?V8QMp z0VIF~kN^@u0!RP}AOR$R1dzZ7MIhV%f0r8qnZg-$3Ty2)Kfca6~2eT&+3|l~D8(2?Vmv zds8=N;|Ar9!Qe`p8@5AD(_*Gk()!WhXxhsD&_9}$@}iW>yS)`W5c{zmcfP9YwfbjP zy-TxhyjfmO%`#)$;+a;!#+^lnrJwIu`zVi%j1tvTZTL zBGdu(W+GE}7RW_53{Gs@utELztntp>ZtZiHIL~S)A>GzbNuy5mD>bI@wbZf=Ei-3U zOn4av?M0m#amw7D2s)M70^_zUC%5?PEi-$o%ocGu=$9GkTxLECnvLk z^O-t`#PM*Dt#+^sb1>m-`Iyhtu%v)&j!VwZ)g~;@FkesNrurJN9Dfk2vH50+*}2u2 z!)%qQJd+hx(1nTG0glXsFW$d{#FGyMi_0-g0$@T{FUMa#*G?n(^zOokn@_{>0bMzW zqo5Ui4Id8}d9epO|9|}F2wwm6i?8SV|LfmokMH$C5i=tJB!C2v01`j~NB{{S0VIF~ zkN^@u0*Z2HsZ+3oPYDZ|?sJ=gk3aa+e24O$4mba-fb@Ka8gBMq^_ql`9uc8G*<&#o zk$NvMxNh_$_yp`(LD=&%xBZ)r0X_hQO?6-Nq@LYefE^hK64P;EKZKdW@o!}N|L?MO F^MAr*A|?O; diff --git a/backend/prisma/dev.db b/backend/prisma/dev.db index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4fc93a68d45fadb9817e7982bafd79bfeb0a397d 100644 GIT binary patch literal 36864 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 R9#K>P5fyx`_<#K%{r~WrzG(me literal 0 HcmV?d00001 diff --git a/backend/prisma/migrations/20251122032308_add_preview/migration.sql b/backend/prisma/migrations/20251122032308_add_preview/migration.sql new file mode 100644 index 0000000..90ee242 --- /dev/null +++ b/backend/prisma/migrations/20251122032308_add_preview/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Drawing" ADD COLUMN "preview" TEXT; diff --git a/backend/prisma/migrations/migration_lock.toml b/backend/prisma/migrations/migration_lock.toml index 2a5a444..e5e5c47 100644 --- a/backend/prisma/migrations/migration_lock.toml +++ b/backend/prisma/migrations/migration_lock.toml @@ -1,3 +1,3 @@ # Please do not edit this file manually -# It should be added in your version-control system (e.g., Git) -provider = "sqlite" +# It should be added in your version-control system (i.e. Git) +provider = "sqlite" \ No newline at end of file diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index 5ba7370..59bccb0 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -24,6 +24,7 @@ model Drawing { name String elements String // Stored as JSON string appState String // Stored as JSON string + preview String? // SVG string for thumbnail version Int @default(1) collectionId String? collection Collection? @relation(fields: [collectionId], references: [id]) diff --git a/backend/src/generated/client/edge.js b/backend/src/generated/client/edge.js index e2231c9..71a296e 100644 --- a/backend/src/generated/client/edge.js +++ b/backend/src/generated/client/edge.js @@ -99,6 +99,7 @@ exports.Prisma.DrawingScalarFieldEnum = { name: 'name', elements: 'elements', appState: 'appState', + preview: 'preview', version: 'version', collectionId: 'collectionId', createdAt: 'createdAt', @@ -149,7 +150,7 @@ const config = { "isCustomOutput": true }, "relativeEnvPaths": { - "rootEnvPath": "../../../.env", + "rootEnvPath": null, "schemaEnvPath": "../../../.env" }, "relativePath": "../../../prisma", @@ -159,7 +160,6 @@ const config = { "db" ], "activeProvider": "sqlite", - "postinstall": false, "inlineDatasources": { "db": { "url": { @@ -168,13 +168,13 @@ const config = { } } }, - "inlineSchema": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\ngenerator client {\n provider = \"prisma-client-js\"\n output = \"../src/generated/client\"\n}\n\ndatasource db {\n provider = \"sqlite\"\n url = env(\"DATABASE_URL\")\n}\n\nmodel Collection {\n id String @id @default(uuid())\n name String\n drawings Drawing[]\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Drawing {\n id String @id @default(uuid())\n name String\n elements String // Stored as JSON string\n appState String // Stored as JSON string\n version Int @default(1)\n collectionId String?\n collection Collection? @relation(fields: [collectionId], references: [id])\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n", - "inlineSchemaHash": "481a5f143c00eb5cbae4281008c7bf10c3e13066bfd88f97f47bd22f56672c24", + "inlineSchema": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\ngenerator client {\n provider = \"prisma-client-js\"\n output = \"../src/generated/client\"\n}\n\ndatasource db {\n provider = \"sqlite\"\n url = env(\"DATABASE_URL\")\n}\n\nmodel Collection {\n id String @id @default(uuid())\n name String\n drawings Drawing[]\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Drawing {\n id String @id @default(uuid())\n name String\n elements String // Stored as JSON string\n appState String // Stored as JSON string\n preview String? // SVG string for thumbnail\n version Int @default(1)\n collectionId String?\n collection Collection? @relation(fields: [collectionId], references: [id])\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n", + "inlineSchemaHash": "67e1a3789d22e31866fa8b498914744bb15a8743c766f6c9cb36263d6b7740a9", "copyEngine": true } config.dirname = '/' -config.runtimeDataModel = JSON.parse("{\"models\":{\"Collection\":{\"dbName\":null,\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":true,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"String\",\"default\":{\"name\":\"uuid(4)\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"name\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"drawings\",\"kind\":\"object\",\"isList\":true,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"Drawing\",\"relationName\":\"CollectionToDrawing\",\"relationFromFields\":[],\"relationToFields\":[],\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"DateTime\",\"default\":{\"name\":\"now\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"DateTime\",\"isGenerated\":false,\"isUpdatedAt\":true}],\"primaryKey\":null,\"uniqueFields\":[],\"uniqueIndexes\":[],\"isGenerated\":false},\"Drawing\":{\"dbName\":null,\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":true,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"String\",\"default\":{\"name\":\"uuid(4)\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"name\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"elements\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"appState\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"version\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"Int\",\"default\":1,\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"collectionId\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":false,\"isUnique\":false,\"isId\":false,\"isReadOnly\":true,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"collection\",\"kind\":\"object\",\"isList\":false,\"isRequired\":false,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"Collection\",\"relationName\":\"CollectionToDrawing\",\"relationFromFields\":[\"collectionId\"],\"relationToFields\":[\"id\"],\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"DateTime\",\"default\":{\"name\":\"now\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"DateTime\",\"isGenerated\":false,\"isUpdatedAt\":true}],\"primaryKey\":null,\"uniqueFields\":[],\"uniqueIndexes\":[],\"isGenerated\":false}},\"enums\":{},\"types\":{}}") +config.runtimeDataModel = JSON.parse("{\"models\":{\"Collection\":{\"dbName\":null,\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":true,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"String\",\"default\":{\"name\":\"uuid(4)\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"name\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"drawings\",\"kind\":\"object\",\"isList\":true,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"Drawing\",\"relationName\":\"CollectionToDrawing\",\"relationFromFields\":[],\"relationToFields\":[],\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"DateTime\",\"default\":{\"name\":\"now\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"DateTime\",\"isGenerated\":false,\"isUpdatedAt\":true}],\"primaryKey\":null,\"uniqueFields\":[],\"uniqueIndexes\":[],\"isGenerated\":false},\"Drawing\":{\"dbName\":null,\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":true,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"String\",\"default\":{\"name\":\"uuid(4)\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"name\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"elements\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"appState\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"preview\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":false,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"version\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"Int\",\"default\":1,\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"collectionId\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":false,\"isUnique\":false,\"isId\":false,\"isReadOnly\":true,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"collection\",\"kind\":\"object\",\"isList\":false,\"isRequired\":false,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"Collection\",\"relationName\":\"CollectionToDrawing\",\"relationFromFields\":[\"collectionId\"],\"relationToFields\":[\"id\"],\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"DateTime\",\"default\":{\"name\":\"now\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"DateTime\",\"isGenerated\":false,\"isUpdatedAt\":true}],\"primaryKey\":null,\"uniqueFields\":[],\"uniqueIndexes\":[],\"isGenerated\":false}},\"enums\":{},\"types\":{}}") defineDmmfProperty(exports.Prisma, config.runtimeDataModel) config.engineWasm = undefined diff --git a/backend/src/generated/client/index-browser.js b/backend/src/generated/client/index-browser.js index 144ab05..83e61fc 100644 --- a/backend/src/generated/client/index-browser.js +++ b/backend/src/generated/client/index-browser.js @@ -131,6 +131,7 @@ exports.Prisma.DrawingScalarFieldEnum = { name: 'name', elements: 'elements', appState: 'appState', + preview: 'preview', version: 'version', collectionId: 'collectionId', createdAt: 'createdAt', diff --git a/backend/src/generated/client/index.d.ts b/backend/src/generated/client/index.d.ts index 6733910..b446dc8 100644 --- a/backend/src/generated/client/index.d.ts +++ b/backend/src/generated/client/index.d.ts @@ -1918,6 +1918,7 @@ export namespace Prisma { name: string | null elements: string | null appState: string | null + preview: string | null version: number | null collectionId: string | null createdAt: Date | null @@ -1929,6 +1930,7 @@ export namespace Prisma { name: string | null elements: string | null appState: string | null + preview: string | null version: number | null collectionId: string | null createdAt: Date | null @@ -1940,6 +1942,7 @@ export namespace Prisma { name: number elements: number appState: number + preview: number version: number collectionId: number createdAt: number @@ -1961,6 +1964,7 @@ export namespace Prisma { name?: true elements?: true appState?: true + preview?: true version?: true collectionId?: true createdAt?: true @@ -1972,6 +1976,7 @@ export namespace Prisma { name?: true elements?: true appState?: true + preview?: true version?: true collectionId?: true createdAt?: true @@ -1983,6 +1988,7 @@ export namespace Prisma { name?: true elements?: true appState?: true + preview?: true version?: true collectionId?: true createdAt?: true @@ -2081,6 +2087,7 @@ export namespace Prisma { name: string elements: string appState: string + preview: string | null version: number collectionId: string | null createdAt: Date @@ -2111,6 +2118,7 @@ export namespace Prisma { name?: boolean elements?: boolean appState?: boolean + preview?: boolean version?: boolean collectionId?: boolean createdAt?: boolean @@ -2123,6 +2131,7 @@ export namespace Prisma { name?: boolean elements?: boolean appState?: boolean + preview?: boolean version?: boolean collectionId?: boolean createdAt?: boolean @@ -2135,6 +2144,7 @@ export namespace Prisma { name?: boolean elements?: boolean appState?: boolean + preview?: boolean version?: boolean collectionId?: boolean createdAt?: boolean @@ -2158,6 +2168,7 @@ export namespace Prisma { name: string elements: string appState: string + preview: string | null version: number collectionId: string | null createdAt: Date @@ -2560,6 +2571,7 @@ export namespace Prisma { readonly name: FieldRef<"Drawing", 'String'> readonly elements: FieldRef<"Drawing", 'String'> readonly appState: FieldRef<"Drawing", 'String'> + readonly preview: FieldRef<"Drawing", 'String'> readonly version: FieldRef<"Drawing", 'Int'> readonly collectionId: FieldRef<"Drawing", 'String'> readonly createdAt: FieldRef<"Drawing", 'DateTime'> @@ -2935,6 +2947,7 @@ export namespace Prisma { name: 'name', elements: 'elements', appState: 'appState', + preview: 'preview', version: 'version', collectionId: 'collectionId', createdAt: 'createdAt', @@ -3054,6 +3067,7 @@ export namespace Prisma { name?: StringFilter<"Drawing"> | string elements?: StringFilter<"Drawing"> | string appState?: StringFilter<"Drawing"> | string + preview?: StringNullableFilter<"Drawing"> | string | null version?: IntFilter<"Drawing"> | number collectionId?: StringNullableFilter<"Drawing"> | string | null createdAt?: DateTimeFilter<"Drawing"> | Date | string @@ -3066,6 +3080,7 @@ export namespace Prisma { name?: SortOrder elements?: SortOrder appState?: SortOrder + preview?: SortOrderInput | SortOrder version?: SortOrder collectionId?: SortOrderInput | SortOrder createdAt?: SortOrder @@ -3081,6 +3096,7 @@ export namespace Prisma { name?: StringFilter<"Drawing"> | string elements?: StringFilter<"Drawing"> | string appState?: StringFilter<"Drawing"> | string + preview?: StringNullableFilter<"Drawing"> | string | null version?: IntFilter<"Drawing"> | number collectionId?: StringNullableFilter<"Drawing"> | string | null createdAt?: DateTimeFilter<"Drawing"> | Date | string @@ -3093,6 +3109,7 @@ export namespace Prisma { name?: SortOrder elements?: SortOrder appState?: SortOrder + preview?: SortOrderInput | SortOrder version?: SortOrder collectionId?: SortOrderInput | SortOrder createdAt?: SortOrder @@ -3112,6 +3129,7 @@ export namespace Prisma { name?: StringWithAggregatesFilter<"Drawing"> | string elements?: StringWithAggregatesFilter<"Drawing"> | string appState?: StringWithAggregatesFilter<"Drawing"> | string + preview?: StringNullableWithAggregatesFilter<"Drawing"> | string | null version?: IntWithAggregatesFilter<"Drawing"> | number collectionId?: StringNullableWithAggregatesFilter<"Drawing"> | string | null createdAt?: DateTimeWithAggregatesFilter<"Drawing"> | Date | string @@ -3176,6 +3194,7 @@ export namespace Prisma { name: string elements: string appState: string + preview?: string | null version?: number createdAt?: Date | string updatedAt?: Date | string @@ -3187,6 +3206,7 @@ export namespace Prisma { name: string elements: string appState: string + preview?: string | null version?: number collectionId?: string | null createdAt?: Date | string @@ -3198,6 +3218,7 @@ export namespace Prisma { name?: StringFieldUpdateOperationsInput | string elements?: StringFieldUpdateOperationsInput | string appState?: StringFieldUpdateOperationsInput | string + preview?: NullableStringFieldUpdateOperationsInput | string | null version?: IntFieldUpdateOperationsInput | number createdAt?: DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string @@ -3209,6 +3230,7 @@ export namespace Prisma { name?: StringFieldUpdateOperationsInput | string elements?: StringFieldUpdateOperationsInput | string appState?: StringFieldUpdateOperationsInput | string + preview?: NullableStringFieldUpdateOperationsInput | string | null version?: IntFieldUpdateOperationsInput | number collectionId?: NullableStringFieldUpdateOperationsInput | string | null createdAt?: DateTimeFieldUpdateOperationsInput | Date | string @@ -3220,6 +3242,7 @@ export namespace Prisma { name: string elements: string appState: string + preview?: string | null version?: number collectionId?: string | null createdAt?: Date | string @@ -3231,6 +3254,7 @@ export namespace Prisma { name?: StringFieldUpdateOperationsInput | string elements?: StringFieldUpdateOperationsInput | string appState?: StringFieldUpdateOperationsInput | string + preview?: NullableStringFieldUpdateOperationsInput | string | null version?: IntFieldUpdateOperationsInput | number createdAt?: DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string @@ -3241,6 +3265,7 @@ export namespace Prisma { name?: StringFieldUpdateOperationsInput | string elements?: StringFieldUpdateOperationsInput | string appState?: StringFieldUpdateOperationsInput | string + preview?: NullableStringFieldUpdateOperationsInput | string | null version?: IntFieldUpdateOperationsInput | number collectionId?: NullableStringFieldUpdateOperationsInput | string | null createdAt?: DateTimeFieldUpdateOperationsInput | Date | string @@ -3334,17 +3359,6 @@ export namespace Prisma { _max?: NestedDateTimeFilter<$PrismaModel> } - export type IntFilter<$PrismaModel = never> = { - equals?: number | IntFieldRefInput<$PrismaModel> - in?: number[] - notIn?: number[] - lt?: number | IntFieldRefInput<$PrismaModel> - lte?: number | IntFieldRefInput<$PrismaModel> - gt?: number | IntFieldRefInput<$PrismaModel> - gte?: number | IntFieldRefInput<$PrismaModel> - not?: NestedIntFilter<$PrismaModel> | number - } - export type StringNullableFilter<$PrismaModel = never> = { equals?: string | StringFieldRefInput<$PrismaModel> | null in?: string[] | null @@ -3359,6 +3373,17 @@ export namespace Prisma { not?: NestedStringNullableFilter<$PrismaModel> | string | null } + export type IntFilter<$PrismaModel = never> = { + equals?: number | IntFieldRefInput<$PrismaModel> + in?: number[] + notIn?: number[] + lt?: number | IntFieldRefInput<$PrismaModel> + lte?: number | IntFieldRefInput<$PrismaModel> + gt?: number | IntFieldRefInput<$PrismaModel> + gte?: number | IntFieldRefInput<$PrismaModel> + not?: NestedIntFilter<$PrismaModel> | number + } + export type CollectionNullableRelationFilter = { is?: CollectionWhereInput | null isNot?: CollectionWhereInput | null @@ -3374,6 +3399,7 @@ export namespace Prisma { name?: SortOrder elements?: SortOrder appState?: SortOrder + preview?: SortOrder version?: SortOrder collectionId?: SortOrder createdAt?: SortOrder @@ -3389,6 +3415,7 @@ export namespace Prisma { name?: SortOrder elements?: SortOrder appState?: SortOrder + preview?: SortOrder version?: SortOrder collectionId?: SortOrder createdAt?: SortOrder @@ -3400,6 +3427,7 @@ export namespace Prisma { name?: SortOrder elements?: SortOrder appState?: SortOrder + preview?: SortOrder version?: SortOrder collectionId?: SortOrder createdAt?: SortOrder @@ -3410,22 +3438,6 @@ export namespace Prisma { version?: SortOrder } - export type IntWithAggregatesFilter<$PrismaModel = never> = { - equals?: number | IntFieldRefInput<$PrismaModel> - in?: number[] - notIn?: number[] - lt?: number | IntFieldRefInput<$PrismaModel> - lte?: number | IntFieldRefInput<$PrismaModel> - gt?: number | IntFieldRefInput<$PrismaModel> - gte?: number | IntFieldRefInput<$PrismaModel> - not?: NestedIntWithAggregatesFilter<$PrismaModel> | number - _count?: NestedIntFilter<$PrismaModel> - _avg?: NestedFloatFilter<$PrismaModel> - _sum?: NestedIntFilter<$PrismaModel> - _min?: NestedIntFilter<$PrismaModel> - _max?: NestedIntFilter<$PrismaModel> - } - export type StringNullableWithAggregatesFilter<$PrismaModel = never> = { equals?: string | StringFieldRefInput<$PrismaModel> | null in?: string[] | null @@ -3443,6 +3455,22 @@ export namespace Prisma { _max?: NestedStringNullableFilter<$PrismaModel> } + export type IntWithAggregatesFilter<$PrismaModel = never> = { + equals?: number | IntFieldRefInput<$PrismaModel> + in?: number[] + notIn?: number[] + lt?: number | IntFieldRefInput<$PrismaModel> + lte?: number | IntFieldRefInput<$PrismaModel> + gt?: number | IntFieldRefInput<$PrismaModel> + gte?: number | IntFieldRefInput<$PrismaModel> + not?: NestedIntWithAggregatesFilter<$PrismaModel> | number + _count?: NestedIntFilter<$PrismaModel> + _avg?: NestedFloatFilter<$PrismaModel> + _sum?: NestedIntFilter<$PrismaModel> + _min?: NestedIntFilter<$PrismaModel> + _max?: NestedIntFilter<$PrismaModel> + } + export type DrawingCreateNestedManyWithoutCollectionInput = { create?: XOR | DrawingCreateWithoutCollectionInput[] | DrawingUncheckedCreateWithoutCollectionInput[] connectOrCreate?: DrawingCreateOrConnectWithoutCollectionInput | DrawingCreateOrConnectWithoutCollectionInput[] @@ -3499,6 +3527,10 @@ export namespace Prisma { connect?: CollectionWhereUniqueInput } + export type NullableStringFieldUpdateOperationsInput = { + set?: string | null + } + export type IntFieldUpdateOperationsInput = { set?: number increment?: number @@ -3517,10 +3549,6 @@ export namespace Prisma { update?: XOR, CollectionUncheckedUpdateWithoutDrawingsInput> } - export type NullableStringFieldUpdateOperationsInput = { - set?: string | null - } - export type NestedStringFilter<$PrismaModel = never> = { equals?: string | StringFieldRefInput<$PrismaModel> in?: string[] @@ -3602,33 +3630,6 @@ export namespace Prisma { not?: NestedStringNullableFilter<$PrismaModel> | string | null } - export type NestedIntWithAggregatesFilter<$PrismaModel = never> = { - equals?: number | IntFieldRefInput<$PrismaModel> - in?: number[] - notIn?: number[] - lt?: number | IntFieldRefInput<$PrismaModel> - lte?: number | IntFieldRefInput<$PrismaModel> - gt?: number | IntFieldRefInput<$PrismaModel> - gte?: number | IntFieldRefInput<$PrismaModel> - not?: NestedIntWithAggregatesFilter<$PrismaModel> | number - _count?: NestedIntFilter<$PrismaModel> - _avg?: NestedFloatFilter<$PrismaModel> - _sum?: NestedIntFilter<$PrismaModel> - _min?: NestedIntFilter<$PrismaModel> - _max?: NestedIntFilter<$PrismaModel> - } - - export type NestedFloatFilter<$PrismaModel = never> = { - equals?: number | FloatFieldRefInput<$PrismaModel> - in?: number[] - notIn?: number[] - lt?: number | FloatFieldRefInput<$PrismaModel> - lte?: number | FloatFieldRefInput<$PrismaModel> - gt?: number | FloatFieldRefInput<$PrismaModel> - gte?: number | FloatFieldRefInput<$PrismaModel> - not?: NestedFloatFilter<$PrismaModel> | number - } - export type NestedStringNullableWithAggregatesFilter<$PrismaModel = never> = { equals?: string | StringFieldRefInput<$PrismaModel> | null in?: string[] | null @@ -3657,11 +3658,39 @@ export namespace Prisma { not?: NestedIntNullableFilter<$PrismaModel> | number | null } + export type NestedIntWithAggregatesFilter<$PrismaModel = never> = { + equals?: number | IntFieldRefInput<$PrismaModel> + in?: number[] + notIn?: number[] + lt?: number | IntFieldRefInput<$PrismaModel> + lte?: number | IntFieldRefInput<$PrismaModel> + gt?: number | IntFieldRefInput<$PrismaModel> + gte?: number | IntFieldRefInput<$PrismaModel> + not?: NestedIntWithAggregatesFilter<$PrismaModel> | number + _count?: NestedIntFilter<$PrismaModel> + _avg?: NestedFloatFilter<$PrismaModel> + _sum?: NestedIntFilter<$PrismaModel> + _min?: NestedIntFilter<$PrismaModel> + _max?: NestedIntFilter<$PrismaModel> + } + + export type NestedFloatFilter<$PrismaModel = never> = { + equals?: number | FloatFieldRefInput<$PrismaModel> + in?: number[] + notIn?: number[] + lt?: number | FloatFieldRefInput<$PrismaModel> + lte?: number | FloatFieldRefInput<$PrismaModel> + gt?: number | FloatFieldRefInput<$PrismaModel> + gte?: number | FloatFieldRefInput<$PrismaModel> + not?: NestedFloatFilter<$PrismaModel> | number + } + export type DrawingCreateWithoutCollectionInput = { id?: string name: string elements: string appState: string + preview?: string | null version?: number createdAt?: Date | string updatedAt?: Date | string @@ -3672,6 +3701,7 @@ export namespace Prisma { name: string elements: string appState: string + preview?: string | null version?: number createdAt?: Date | string updatedAt?: Date | string @@ -3710,6 +3740,7 @@ export namespace Prisma { name?: StringFilter<"Drawing"> | string elements?: StringFilter<"Drawing"> | string appState?: StringFilter<"Drawing"> | string + preview?: StringNullableFilter<"Drawing"> | string | null version?: IntFilter<"Drawing"> | number collectionId?: StringNullableFilter<"Drawing"> | string | null createdAt?: DateTimeFilter<"Drawing"> | Date | string @@ -3765,6 +3796,7 @@ export namespace Prisma { name: string elements: string appState: string + preview?: string | null version?: number createdAt?: Date | string updatedAt?: Date | string @@ -3775,6 +3807,7 @@ export namespace Prisma { name?: StringFieldUpdateOperationsInput | string elements?: StringFieldUpdateOperationsInput | string appState?: StringFieldUpdateOperationsInput | string + preview?: NullableStringFieldUpdateOperationsInput | string | null version?: IntFieldUpdateOperationsInput | number createdAt?: DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string @@ -3785,6 +3818,7 @@ export namespace Prisma { name?: StringFieldUpdateOperationsInput | string elements?: StringFieldUpdateOperationsInput | string appState?: StringFieldUpdateOperationsInput | string + preview?: NullableStringFieldUpdateOperationsInput | string | null version?: IntFieldUpdateOperationsInput | number createdAt?: DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string @@ -3795,6 +3829,7 @@ export namespace Prisma { name?: StringFieldUpdateOperationsInput | string elements?: StringFieldUpdateOperationsInput | string appState?: StringFieldUpdateOperationsInput | string + preview?: NullableStringFieldUpdateOperationsInput | string | null version?: IntFieldUpdateOperationsInput | number createdAt?: DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: DateTimeFieldUpdateOperationsInput | Date | string diff --git a/backend/src/generated/client/index.js b/backend/src/generated/client/index.js index a73eeca..b9fb90f 100644 --- a/backend/src/generated/client/index.js +++ b/backend/src/generated/client/index.js @@ -100,6 +100,7 @@ exports.Prisma.DrawingScalarFieldEnum = { name: 'name', elements: 'elements', appState: 'appState', + preview: 'preview', version: 'version', collectionId: 'collectionId', createdAt: 'createdAt', @@ -150,7 +151,7 @@ const config = { "isCustomOutput": true }, "relativeEnvPaths": { - "rootEnvPath": "../../../.env", + "rootEnvPath": null, "schemaEnvPath": "../../../.env" }, "relativePath": "../../../prisma", @@ -160,7 +161,6 @@ const config = { "db" ], "activeProvider": "sqlite", - "postinstall": false, "inlineDatasources": { "db": { "url": { @@ -169,8 +169,8 @@ const config = { } } }, - "inlineSchema": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\ngenerator client {\n provider = \"prisma-client-js\"\n output = \"../src/generated/client\"\n}\n\ndatasource db {\n provider = \"sqlite\"\n url = env(\"DATABASE_URL\")\n}\n\nmodel Collection {\n id String @id @default(uuid())\n name String\n drawings Drawing[]\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Drawing {\n id String @id @default(uuid())\n name String\n elements String // Stored as JSON string\n appState String // Stored as JSON string\n version Int @default(1)\n collectionId String?\n collection Collection? @relation(fields: [collectionId], references: [id])\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n", - "inlineSchemaHash": "481a5f143c00eb5cbae4281008c7bf10c3e13066bfd88f97f47bd22f56672c24", + "inlineSchema": "// This is your Prisma schema file,\n// learn more about it in the docs: https://pris.ly/d/prisma-schema\n\ngenerator client {\n provider = \"prisma-client-js\"\n output = \"../src/generated/client\"\n}\n\ndatasource db {\n provider = \"sqlite\"\n url = env(\"DATABASE_URL\")\n}\n\nmodel Collection {\n id String @id @default(uuid())\n name String\n drawings Drawing[]\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Drawing {\n id String @id @default(uuid())\n name String\n elements String // Stored as JSON string\n appState String // Stored as JSON string\n preview String? // SVG string for thumbnail\n version Int @default(1)\n collectionId String?\n collection Collection? @relation(fields: [collectionId], references: [id])\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n", + "inlineSchemaHash": "67e1a3789d22e31866fa8b498914744bb15a8743c766f6c9cb36263d6b7740a9", "copyEngine": true } @@ -191,7 +191,7 @@ if (!fs.existsSync(path.join(__dirname, 'schema.prisma'))) { config.isBundled = true } -config.runtimeDataModel = JSON.parse("{\"models\":{\"Collection\":{\"dbName\":null,\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":true,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"String\",\"default\":{\"name\":\"uuid(4)\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"name\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"drawings\",\"kind\":\"object\",\"isList\":true,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"Drawing\",\"relationName\":\"CollectionToDrawing\",\"relationFromFields\":[],\"relationToFields\":[],\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"DateTime\",\"default\":{\"name\":\"now\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"DateTime\",\"isGenerated\":false,\"isUpdatedAt\":true}],\"primaryKey\":null,\"uniqueFields\":[],\"uniqueIndexes\":[],\"isGenerated\":false},\"Drawing\":{\"dbName\":null,\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":true,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"String\",\"default\":{\"name\":\"uuid(4)\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"name\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"elements\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"appState\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"version\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"Int\",\"default\":1,\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"collectionId\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":false,\"isUnique\":false,\"isId\":false,\"isReadOnly\":true,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"collection\",\"kind\":\"object\",\"isList\":false,\"isRequired\":false,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"Collection\",\"relationName\":\"CollectionToDrawing\",\"relationFromFields\":[\"collectionId\"],\"relationToFields\":[\"id\"],\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"DateTime\",\"default\":{\"name\":\"now\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"DateTime\",\"isGenerated\":false,\"isUpdatedAt\":true}],\"primaryKey\":null,\"uniqueFields\":[],\"uniqueIndexes\":[],\"isGenerated\":false}},\"enums\":{},\"types\":{}}") +config.runtimeDataModel = JSON.parse("{\"models\":{\"Collection\":{\"dbName\":null,\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":true,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"String\",\"default\":{\"name\":\"uuid(4)\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"name\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"drawings\",\"kind\":\"object\",\"isList\":true,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"Drawing\",\"relationName\":\"CollectionToDrawing\",\"relationFromFields\":[],\"relationToFields\":[],\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"DateTime\",\"default\":{\"name\":\"now\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"DateTime\",\"isGenerated\":false,\"isUpdatedAt\":true}],\"primaryKey\":null,\"uniqueFields\":[],\"uniqueIndexes\":[],\"isGenerated\":false},\"Drawing\":{\"dbName\":null,\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":true,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"String\",\"default\":{\"name\":\"uuid(4)\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"name\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"elements\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"appState\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"preview\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":false,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"version\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"Int\",\"default\":1,\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"collectionId\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":false,\"isUnique\":false,\"isId\":false,\"isReadOnly\":true,\"hasDefaultValue\":false,\"type\":\"String\",\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"collection\",\"kind\":\"object\",\"isList\":false,\"isRequired\":false,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"Collection\",\"relationName\":\"CollectionToDrawing\",\"relationFromFields\":[\"collectionId\"],\"relationToFields\":[\"id\"],\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":true,\"type\":\"DateTime\",\"default\":{\"name\":\"now\",\"args\":[]},\"isGenerated\":false,\"isUpdatedAt\":false},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"isList\":false,\"isRequired\":true,\"isUnique\":false,\"isId\":false,\"isReadOnly\":false,\"hasDefaultValue\":false,\"type\":\"DateTime\",\"isGenerated\":false,\"isUpdatedAt\":true}],\"primaryKey\":null,\"uniqueFields\":[],\"uniqueIndexes\":[],\"isGenerated\":false}},\"enums\":{},\"types\":{}}") defineDmmfProperty(exports.Prisma, config.runtimeDataModel) config.engineWasm = undefined diff --git a/backend/src/generated/client/package.json b/backend/src/generated/client/package.json index 09e11ab..8252243 100644 --- a/backend/src/generated/client/package.json +++ b/backend/src/generated/client/package.json @@ -1,5 +1,5 @@ { - "name": "prisma-client-83e2d97f7605e3fc4b9dd655248fc3537e09c5d5de3bea41e3f804da1ddcbc6e", + "name": "prisma-client-3ebeea41bd8603a2c294a840f7d22c864ae7fc82298676ca177ef806525c6187", "main": "index.js", "types": "index.d.ts", "browser": "index-browser.js", diff --git a/backend/src/generated/client/schema.prisma b/backend/src/generated/client/schema.prisma index 5ba7370..59bccb0 100644 --- a/backend/src/generated/client/schema.prisma +++ b/backend/src/generated/client/schema.prisma @@ -24,6 +24,7 @@ model Drawing { name String elements String // Stored as JSON string appState String // Stored as JSON string + preview String? // SVG string for thumbnail version Int @default(1) collectionId String? collection Collection? @relation(fields: [collectionId], references: [id]) diff --git a/backend/src/generated/client/wasm.js b/backend/src/generated/client/wasm.js index 144ab05..83e61fc 100644 --- a/backend/src/generated/client/wasm.js +++ b/backend/src/generated/client/wasm.js @@ -131,6 +131,7 @@ exports.Prisma.DrawingScalarFieldEnum = { name: 'name', elements: 'elements', appState: 'appState', + preview: 'preview', version: 'version', collectionId: 'collectionId', createdAt: 'createdAt', diff --git a/backend/src/index.ts b/backend/src/index.ts index 9ca8840..90022b9 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -8,7 +8,8 @@ import { PrismaClient } from "./generated/client"; dotenv.config(); // Ensure DATABASE_URL is absolute to avoid relative path issues with generated client -const dbPath = path.resolve(__dirname, "../dev.db"); +// Point to the same DB file as Prisma CLI (relative to schema.prisma, usually in prisma/ folder) +const dbPath = path.resolve(__dirname, "../prisma/dev.db"); process.env.DATABASE_URL = `file:${dbPath}`; console.log("Resolved DATABASE_URL:", process.env.DATABASE_URL); @@ -35,6 +36,12 @@ app.get("/drawings", async (req, res) => { where.collectionId = null; } else if (collectionId) { where.collectionId = String(collectionId); + } else { + // Default: Exclude trash, but include unorganized (null) + where.OR = [ + { collectionId: { not: "trash" } }, + { collectionId: null }, + ]; } const drawings = await prisma.drawing.findMany({ @@ -79,7 +86,7 @@ app.get("/drawings/:id", async (req, res) => { // POST /drawings app.post("/drawings", async (req, res) => { try { - const { name, elements, appState, collectionId } = req.body; + const { name, elements, appState, collectionId, preview } = req.body; const newDrawing = await prisma.drawing.create({ data: { @@ -87,6 +94,7 @@ app.post("/drawings", async (req, res) => { elements: JSON.stringify(elements || []), appState: JSON.stringify(appState || {}), collectionId: collectionId || null, + preview: preview || null, }, }); @@ -104,7 +112,7 @@ app.post("/drawings", async (req, res) => { app.put("/drawings/:id", async (req, res) => { try { const { id } = req.params; - const { name, elements, appState, collectionId } = req.body; + const { name, elements, appState, collectionId, preview } = req.body; const data: any = { version: { increment: 1 }, @@ -114,6 +122,7 @@ app.put("/drawings/:id", async (req, res) => { if (elements !== undefined) data.elements = JSON.stringify(elements); if (appState !== undefined) data.appState = JSON.stringify(appState); if (collectionId !== undefined) data.collectionId = collectionId; + if (preview !== undefined) data.preview = preview; const updatedDrawing = await prisma.drawing.update({ where: { id }, @@ -236,6 +245,24 @@ app.delete("/collections/:id", async (req, res) => { } }); -app.listen(PORT, () => { +// Ensure Trash collection exists +const ensureTrashCollection = async () => { + try { + const trash = await prisma.collection.findUnique({ + where: { id: "trash" }, + }); + if (!trash) { + await prisma.collection.create({ + data: { id: "trash", name: "Trash" }, + }); + console.log("Created Trash collection"); + } + } catch (error) { + console.error("Failed to ensure Trash collection:", error); + } +}; + +app.listen(PORT, async () => { + await ensureTrashCollection(); console.log(`Server running on port ${PORT}`); }); diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index b2ed213..55f257f 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -292,24 +292,14 @@ export const Sidebar: React.FC = ({ onDrop={(e) => { e.preventDefault(); setIsTrashDragOver(false); - const trashId = collections.find(c => c.name === 'Trash')?.id; - if (trashId) { - onDrop?.(e, trashId); - } else { - onDrop?.(e, 'TRASH'); - } + onDrop?.(e, 'trash'); }} onClick={() => { - const trashCollection = collections.find(c => c.name === 'Trash'); - if (trashCollection) { - navigate(`/collections?id=${trashCollection.id}`); - } else { - onCreateCollection('Trash'); - } + navigate('/collections?id=trash'); }} className={clsx( "w-full flex items-center gap-3 px-3 py-2 text-sm font-bold rounded-xl transition-all duration-200 border-2 border-black dark:border-neutral-700 shadow-[2px_2px_0px_0px_rgba(0,0,0,1)] dark:shadow-[2px_2px_0px_0px_rgba(255,255,255,0.2)] mb-4", - collections.find(c => c.name === 'Trash')?.id === selectedCollectionId || isTrashDragOver + selectedCollectionId === 'trash' || isTrashDragOver ? "bg-rose-50 dark:bg-rose-900/30 text-rose-900 dark:text-rose-300 -translate-y-0.5" : "bg-white dark:bg-neutral-900 text-slate-900 dark:text-neutral-200 hover:bg-rose-50 dark:hover:bg-rose-900/30 hover:text-rose-900 dark:hover:text-rose-300 hover:shadow-[4px_4px_0px_0px_rgba(0,0,0,1)] dark:hover:shadow-[4px_4px_0px_0px_rgba(255,255,255,0.2)] hover:-translate-y-0.5" )} diff --git a/frontend/src/pages/Dashboard.tsx b/frontend/src/pages/Dashboard.tsx index 294ec6b..46083ef 100644 --- a/frontend/src/pages/Dashboard.tsx +++ b/frontend/src/pages/Dashboard.tsx @@ -267,15 +267,7 @@ export const Dashboard: React.FC = () => { }; // Trash Helpers - const trashCollection = collections.find(c => c.name === 'Trash'); - const isTrashView = selectedCollectionId === trashCollection?.id && trashCollection !== undefined; - - const getOrCreateTrashId = async () => { - if (trashCollection) return trashCollection.id; - const newCol = await api.createCollection('Trash'); - setCollections(prev => [...prev, newCol]); - return newCol.id; - }; + const isTrashView = selectedCollectionId === 'trash'; const handleCreateDrawing = async () => { if (isTrashView) return; @@ -300,7 +292,7 @@ export const Dashboard: React.FC = () => { setDrawingToDelete(id); } else { // Move to Trash -> No Confirm - const trashId = await getOrCreateTrashId(); + const trashId = 'trash'; // Optimistic Remove from current view setDrawings(prev => prev.filter(d => d.id !== id)); @@ -373,7 +365,7 @@ export const Dashboard: React.FC = () => { }; const executeBulkMoveToTrash = async () => { - const trashId = await getOrCreateTrashId(); + const trashId = 'trash'; const ids = Array.from(selectedIds); setDrawings(prev => prev.filter(d => !selectedIds.has(d.id))); @@ -489,6 +481,7 @@ export const Dashboard: React.FC = () => { const viewTitle = React.useMemo(() => { if (selectedCollectionId === undefined) return "All Drawings"; if (selectedCollectionId === null) return "Unorganized"; + if (selectedCollectionId === 'trash') return "Trash"; const collection = collections.find(c => c.id === selectedCollectionId); return collection ? collection.name : "Collection"; }, [selectedCollectionId, collections]); @@ -589,9 +582,12 @@ export const Dashboard: React.FC = () => { setDrawings(prev => prev.map(d => d.id === id ? { ...d, preview } : d)); }; + // Filter out trash from the collections list passed to sidebar + const visibleCollections = React.useMemo(() => collections.filter(c => c.id !== 'trash'), [collections]); + return ( { viewBackgroundColor: appState.viewBackgroundColor, gridSize: appState.gridSize, }; + + // Generate preview + const files = excalidrawAPI.current?.getFiles() || null; + const svg = await exportToSvg({ + elements, + appState: { + ...appState, + exportBackground: true, + viewBackgroundColor: appState.viewBackgroundColor || '#ffffff', + }, + files, + }); + const preview = svg.outerHTML; await api.updateDrawing(id, { elements, appState: persistableAppState, + preview, }); } catch (err) { console.error('Failed to save drawing', err);