Browse Source

Merge pull request #10984 from mizozobu/prisma-re

support: Migrate to Prisma(2)
Yuki Takei 5 ngày trước cách đây
mục cha
commit
9c922bf602

+ 3 - 1
.devcontainer/app/devcontainer.json

@@ -49,7 +49,9 @@
         "mongodb.mongodb-vscode",
         // Debug
         "msjsdiag.debugger-for-chrome",
-        "firefox-devtools.vscode-firefox-debug"
+        "firefox-devtools.vscode-firefox-debug",
+        // prisma
+        "Prisma.prisma@6.19.0"
       ],
       "settings": {
         "terminal.integrated.defaultProfile.linux": "bash"

+ 12 - 0
.github/workflows/ci-app.yml

@@ -72,6 +72,10 @@ jobs:
           pnpm add turbo --global
           pnpm install --frozen-lockfile
 
+      - name: Generate schema
+        run: |
+          pnpm run --filter @growi/app prisma:generate
+
       - name: Lint
         run: |
           turbo run lint --filter=@growi/app --filter=./packages/*
@@ -127,6 +131,10 @@ jobs:
           pnpm add turbo --global
           pnpm install --frozen-lockfile
 
+      - name: Generate schema
+        run: |
+          pnpm run --filter @growi/app prisma:generate
+
       - name: Test
         run: |
           turbo run test --filter=@growi/app --filter=./packages/* --env-mode=loose
@@ -192,6 +200,10 @@ jobs:
           pnpm add turbo --global
           pnpm install --frozen-lockfile
 
+      - name: Generate schema
+        run: |
+          pnpm run --filter @growi/app prisma:generate
+
       - name: turbo run launch-dev:ci
         working-directory: ./apps/app
         run: |

+ 4 - 0
.vscode/settings.json

@@ -21,6 +21,10 @@
     "editor.defaultFormatter": "biomejs.biome"
   },
 
+  "[prisma]": {
+    "editor.defaultFormatter": "Prisma.prisma"
+  },
+
   // use vscode-stylelint
   // see https://github.com/stylelint/vscode-stylelint
   "stylelint.validate": ["css", "less", "scss"],

+ 3 - 0
apps/app/.gitignore

@@ -23,3 +23,6 @@ next.config.js
 
 # cache
 /.swc/
+
+# prisma
+/src/generated/prisma

+ 34 - 0
apps/app/bin/migrate.ts

@@ -0,0 +1,34 @@
+/**
+ * umzug cli
+ *
+ * Usage:
+ *   pnpm ts-node bin/migrate.ts
+ */
+import { resolve } from 'node:path';
+import { MongoClient } from 'mongodb';
+import { MongoDBStorage, Umzug } from 'umzug';
+
+import { prisma } from '~/utils/prisma';
+
+(async () => {
+  const url = process.env.MONGO_URI;
+  if (url === undefined) {
+    throw new Error('MONGO_URI is required');
+  }
+  const client = new MongoClient(url);
+  await client.connect();
+
+  const umzug = new Umzug({
+    migrations: { glob: resolve(__dirname, '../prisma/migrations/*.(ts|js)') },
+    context: prisma,
+    storage: new MongoDBStorage({
+      connection: client.db(),
+    }),
+    logger: console,
+  });
+
+  if (require.main === module) {
+    await umzug.runAsCLI();
+    process.exit(0);
+  }
+})();

+ 12 - 4
apps/app/package.json

@@ -16,16 +16,19 @@
     "preserver": "cross-env NODE_ENV=production pnpm run migrate",
     "pre:styles-commons": "vite build -c vite.vendor-styles-commons.ts",
     "pre:styles-components": "vite build --config vite.vendor-styles-components.ts",
-    "migrate": "node -r dotenv-flow/config node_modules/migrate-mongo/bin/migrate-mongo up -f config/migrate-mongo-config.js",
+    "migrate": "pnpm run migrate:migrate-mongo && pnpm run migrate:umzug",
+    "migrate:migrate-mongo": "node -r dotenv-flow/config node_modules/migrate-mongo/bin/migrate-mongo up -f config/migrate-mongo-config.js",
+    "migrate:umzug": "pnpm run ts-node bin/migrate.ts",
     "//// for development": "",
     "dev": "cross-env NODE_ENV=development nodemon --exec pnpm run ts-node --inspect src/server/app.ts",
     "dev:pre:styles-commons": "pnpm run pre:styles-commons --mode dev",
     "dev:pre:styles-components": "pnpm run pre:styles-components",
     "dev:migrate-mongo": "cross-env NODE_ENV=development pnpm run ts-node node_modules/migrate-mongo/bin/migrate-mongo",
+    "dev:umzug": "cross-env NODE_ENV=development pnpm run ts-node bin/migrate.ts",
     "dev:migrate": "pnpm run dev:migrate:status > tmp/cache/migration-status.out && pnpm run dev:migrate:up",
-    "dev:migrate:status": "pnpm run dev:migrate-mongo status -f config/migrate-mongo-config.js",
-    "dev:migrate:up": "pnpm run dev:migrate-mongo up -f config/migrate-mongo-config.js",
-    "dev:migrate:down": "pnpm run dev:migrate-mongo down -f config/migrate-mongo-config.js",
+    "dev:migrate:status": "pnpm run dev:migrate-mongo status -f config/migrate-mongo-config.js && pnpm run dev:umzug executed && pnpm run dev:umzug pending",
+    "dev:migrate:up": "pnpm run dev:migrate-mongo up -f config/migrate-mongo-config.js && pnpm run dev:umzug up",
+    "dev:migrate:down": "pnpm run dev:umzug down && pnpm run dev:migrate-mongo down -f config/migrate-mongo-config.js",
     "//// for CI": "",
     "launch-dev:ci": "cross-env NODE_ENV=development pnpm run dev:migrate && pnpm run ts-node src/server/app.ts --ci",
     "lint:typecheck": "tsgo --noEmit",
@@ -45,6 +48,8 @@
     "//// misc": "",
     "console": "npm run repl",
     "repl": "cross-env NODE_ENV=development npm run ts-node src/server/repl.ts",
+    "prisma:generate": "prisma generate",
+    "prisma:pull": "prisma db pull",
     "openapi:build:generate-operation-ids": "vite build -c bin/openapi/generate-operation-ids/vite.config.ts",
     "openapi:generate-spec:apiv3": "sh bin/openapi/generate-spec-apiv3.sh",
     "openapi:generate-spec:apiv1": "sh bin/openapi/generate-spec-apiv1.sh",
@@ -109,6 +114,7 @@
     "@opentelemetry/sdk-node": "^0.202.0",
     "@opentelemetry/sdk-trace-node": "^2.0.1",
     "@opentelemetry/semantic-conventions": "^1.34.0",
+    "@prisma/client": "^6.19.2",
     "@replit/codemirror-emacs": "^6.1.0",
     "@replit/codemirror-vim": "^6.2.1",
     "@replit/codemirror-vscode-keymap": "^6.0.2",
@@ -334,6 +340,7 @@
     "mongodb-connection-string-url": "^7.0.0",
     "mongodb-memory-server-core": "^9.1.1",
     "openapi-typescript": "^7.8.0",
+    "prisma": "^6.19.2",
     "rehype-rewrite": "^4.0.2",
     "remark-github-admonitions-to-directives": "^2.0.0",
     "sass": "^1.53.0",
@@ -341,6 +348,7 @@
     "supertest": "^7.1.4",
     "swagger2openapi": "^7.0.8",
     "tinykeys": "^3.0.0",
+    "umzug": "^3.8.2",
     "unist-util-is": "^6.0.0",
     "unist-util-visit-parents": "^6.0.0"
   }

+ 16 - 0
apps/app/prisma.config.ts

@@ -0,0 +1,16 @@
+import { config } from 'dotenv-flow';
+import { defineConfig } from 'prisma/config';
+
+config();
+
+// biome-ignore lint/style/noDefaultExport: prisma requires a default export
+export default defineConfig({
+  schema: 'prisma/schema.prisma',
+  migrations: {
+    path: 'prisma/migrations',
+  },
+  engine: 'classic',
+  datasource: {
+    url: process.env.MONGO_URI,
+  },
+});

+ 0 - 0
apps/app/prisma/migrations/.keep


+ 516 - 0
apps/app/prisma/schema.prisma

@@ -0,0 +1,516 @@
+generator client {
+  provider = "prisma-client"
+  output   = "../src/generated/prisma"
+}
+
+datasource db {
+  provider = "mongodb"
+  url      = env("MONGO_URI")
+}
+
+type ActivitiesSnapshot {
+  id       String @map("_id") @db.ObjectId
+  username String
+}
+
+type AiassistantsGrantedGroupsForAccessScope {
+  /// Field referred in an index, but found no data to define the type.
+  item Json?
+}
+
+type AiassistantsGrantedGroupsForShareScope {
+  /// Field referred in an index, but found no data to define the type.
+  item Json?
+}
+
+type PageoperationsExPage {
+  /// Field referred in an index, but found no data to define the type.
+  id   Json? @map("_id")
+  /// Field referred in an index, but found no data to define the type.
+  path Json?
+}
+
+type PageoperationsPage {
+  /// Field referred in an index, but found no data to define the type.
+  id   Json? @map("_id")
+  /// Field referred in an index, but found no data to define the type.
+  path Json?
+}
+
+type PagesGrantedGroups {
+  /// Field referred in an index, but found no data to define the type.
+  item Json?
+}
+
+model accesstokens {
+  id        String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  expiredAt Json?
+  /// Field referred in an index, but found no data to define the type.
+  tokenHash Json?  @unique(map: "tokenHash_1")
+
+  @@index([expiredAt], map: "expiredAt_1")
+}
+
+model activities {
+  id          String             @id @default(auto()) @map("_id") @db.ObjectId
+  v           Int                @map("__v")
+  action      String
+  createdAt   DateTime           @db.Date
+  endpoint    String
+  ip          String
+  snapshot    ActivitiesSnapshot
+  target      String?            @db.ObjectId
+  targetModel String?
+  user        String?            @db.ObjectId
+
+  @@unique([user, target, action, createdAt], map: "user_1_target_1_action_1_createdAt_1")
+  @@index([user], map: "user_1")
+  @@index([snapshot.username], map: "snapshot.username_1")
+  @@index([target, action], map: "target_1_action_1")
+  @@index([createdAt], map: "createdAt_1")
+}
+
+model aiassistants {
+  id                          String                                   @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  grantedGroupsForAccessScope AiassistantsGrantedGroupsForAccessScope?
+  /// Field referred in an index, but found no data to define the type.
+  grantedGroupsForShareScope  AiassistantsGrantedGroupsForShareScope?
+
+  @@index([grantedGroupsForShareScope.item], map: "grantedGroupsForShareScope.item_1")
+  @@index([grantedGroupsForAccessScope.item], map: "grantedGroupsForAccessScope.item_1")
+}
+
+model attachments {
+  id       String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  creator  Json?
+  /// Field referred in an index, but found no data to define the type.
+  fileName Json?  @unique(map: "fileName_1")
+  /// Field referred in an index, but found no data to define the type.
+  page     Json?
+
+  @@index([page], map: "page_1")
+  @@index([creator], map: "creator_1")
+}
+
+model bookmarkfolders {
+  id    String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  owner Json?
+
+  @@index([owner], map: "owner_1")
+}
+
+model bookmarks {
+  id   String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  page Json?
+  /// Field referred in an index, but found no data to define the type.
+  user Json?
+
+  @@unique([page, user], map: "page_1_user_1")
+  @@index([page], map: "page_1")
+  @@index([user], map: "user_1")
+}
+
+model comments {
+  id       String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  creator  Json?
+  /// Field referred in an index, but found no data to define the type.
+  page     Json?
+  /// Field referred in an index, but found no data to define the type.
+  revision Json?
+
+  @@index([page], map: "page_1")
+  @@index([creator], map: "creator_1")
+  @@index([revision], map: "revision_1")
+}
+
+model configs {
+  id        String   @id @default(auto()) @map("_id") @db.ObjectId
+  v         Int?     @map("__v")
+  createdAt DateTime @db.Date
+  key       String   @unique(map: "key_1")
+  updatedAt DateTime @db.Date
+  value     String
+}
+
+model editorsettings {
+  id String @id @default(auto()) @map("_id") @db.ObjectId
+}
+
+model externalaccounts {
+  id           String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  accountId    Json?
+  /// Field referred in an index, but found no data to define the type.
+  providerType Json?
+
+  @@unique([providerType, accountId], map: "providerType_1_accountId_1")
+}
+
+model externalusergrouprelations {
+  id String @id @default(auto()) @map("_id") @db.ObjectId
+}
+
+model externalusergroups {
+  id         String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  externalId Json?  @unique(map: "externalId_1")
+  /// Field referred in an index, but found no data to define the type.
+  name       Json?
+  /// Field referred in an index, but found no data to define the type.
+  parent     Json?
+  /// Field referred in an index, but found no data to define the type.
+  provider   Json?
+
+  @@unique([name, provider], map: "name_1_provider_1")
+  @@index([parent], map: "parent_1")
+}
+
+model failedemails {
+  id        String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  createdAt Json?
+
+  @@index([createdAt], map: "createdAt_1")
+}
+
+model globalnotificationsettings {
+  id String @id @default(auto()) @map("_id") @db.ObjectId
+}
+
+model growiplugins {
+  id String @id @default(auto()) @map("_id") @db.ObjectId
+}
+
+model inappnotifications {
+  id        String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  action    Json?
+  /// Field referred in an index, but found no data to define the type.
+  createdAt Json?
+  /// Field referred in an index, but found no data to define the type.
+  status    Json?
+  /// Field referred in an index, but found no data to define the type.
+  target    Json?
+  /// Field referred in an index, but found no data to define the type.
+  user      Json?
+
+  @@index([user], map: "user_1")
+  @@index([status], map: "status_1")
+  @@index([createdAt], map: "createdAt_1")
+  @@index([user, target, action, createdAt], map: "user_1_target_1_action_1_createdAt_1")
+}
+
+model inappnotificationsettings {
+  id String @id @default(auto()) @map("_id") @db.ObjectId
+}
+
+model migrations {
+  id        String   @id @default(auto()) @map("_id") @db.ObjectId
+  appliedAt DateTime @db.Date
+  fileName  String
+}
+
+model namedqueries {
+  id            String @id @default(auto()) @map("_id") @db.ObjectId
+  v             Int    @map("__v")
+  /// Could not determine type: the field only had null or empty values in the sample set.
+  creator       Json?
+  delegatorName String
+  name          String @unique(map: "name_1")
+
+  @@index([creator], map: "creator_1")
+}
+
+model pagebulkexportjobs {
+  id String @id @default(auto()) @map("_id") @db.ObjectId
+}
+
+model pagebulkexportpagesnapshots {
+  id String @id @default(auto()) @map("_id") @db.ObjectId
+}
+
+model pageoperations {
+  id          String                @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  actionStage Json?
+  /// Field referred in an index, but found no data to define the type.
+  actionType  Json?
+  /// Field referred in an index, but found no data to define the type.
+  exPage      PageoperationsExPage?
+  /// Field referred in an index, but found no data to define the type.
+  fromPath    Json?
+  /// Field referred in an index, but found no data to define the type.
+  page        PageoperationsPage?
+  /// Field referred in an index, but found no data to define the type.
+  toPath      Json?
+
+  @@index([actionType], map: "actionType_1")
+  @@index([actionStage], map: "actionStage_1")
+  @@index([fromPath], map: "fromPath_1")
+  @@index([toPath], map: "toPath_1")
+  @@index([page.id], map: "page._id_1")
+  @@index([page.path], map: "page.path_1")
+  @@index([exPage.id], map: "exPage._id_1")
+  @@index([exPage.path], map: "exPage.path_1")
+}
+
+model pageredirects {
+  id       String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  fromPath Json?  @unique(map: "fromPath_1")
+}
+
+model pages {
+  id                       String      @id @default(auto()) @map("_id") @db.ObjectId
+  v                        Int         @map("__v")
+  commentCount             Int
+  createdAt                DateTime    @db.Date
+  creator                  String?     @db.ObjectId
+  descendantCount          Int
+  grant                    Int
+  /// Nested objects had no data in the sample dataset to introspect a nested type.
+  grantedGroups            Json?
+  /// Could not determine type: the field only had null or empty values in the sample set.
+  grantedUsers             Json?
+  isEmpty                  Boolean
+  lastUpdateUser           String?     @db.ObjectId
+  latestRevisionBodyLength Int?
+  /// Could not determine type: the field only had null or empty values in the sample set.
+  liker                    Json?
+  parent                   String?     @db.ObjectId
+  path                     String
+  revision                 String?     @db.ObjectId
+  seenUsers                String[]
+  status                   String
+  ttlTimestamp             DateTime?   @db.Date
+  updatedAt                DateTime    @db.Date
+  wip                      Boolean?
+  revisions                revisions[]
+
+  @@index([parent], map: "parent_1")
+  @@index([path], map: "path_1")
+  @@index([status], map: "status_1")
+  @@index([grant], map: "grant_1")
+  @@index([creator], map: "creator_1")
+  @@index([createdAt], map: "createdAt_1")
+  @@index([updatedAt], map: "updatedAt_1")
+  @@index([ttlTimestamp], map: "ttlTimestamp_1")
+}
+
+model pagetagrelations {
+  id            String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  isPageTrashed Json?
+  /// Field referred in an index, but found no data to define the type.
+  relatedPage   Json?
+  /// Field referred in an index, but found no data to define the type.
+  relatedTag    Json?
+
+  @@unique([relatedPage, relatedTag], map: "relatedPage_1_relatedTag_1")
+  @@index([relatedPage], map: "relatedPage_1")
+  @@index([relatedTag], map: "relatedTag_1")
+  @@index([isPageTrashed], map: "isPageTrashed_1")
+}
+
+model passwordresetorders {
+  id    String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  token Json?  @unique(map: "token_1")
+}
+
+model revisions {
+  id        String   @id @default(auto()) @map("_id") @db.ObjectId
+  v         Int      @map("__v")
+  author    String   @db.ObjectId
+  body      String
+  createdAt DateTime @db.Date
+  format    String
+  origin    String?
+  pageId    String   @db.ObjectId
+
+  page pages @relation(fields: [pageId], references: [id])
+
+  @@index([pageId], map: "pageId_1")
+}
+
+model rlflx {
+  id     String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  expire Json?
+  /// Field referred in an index, but found no data to define the type.
+  key    Json?  @unique(map: "key_1")
+
+  @@index([expire(sort: Desc)], map: "expire_-1")
+}
+
+model sessions {
+  id      String   @id @map("_id")
+  expires DateTime @db.Date
+  session String
+
+  @@index([expires], map: "expires_1")
+}
+
+model sharelinks {
+  id          String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  relatedPage Json?
+
+  @@index([relatedPage], map: "relatedPage_1")
+}
+
+model slackappintegrations {
+  id        String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  isPrimary Json?  @unique(map: "isPrimary_1")
+  /// Field referred in an index, but found no data to define the type.
+  tokenGtoP Json?  @unique(map: "tokenGtoP_1")
+  /// Field referred in an index, but found no data to define the type.
+  tokenPtoG Json?  @unique(map: "tokenPtoG_1")
+}
+
+model subscriptions {
+  id   String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  user Json?
+
+  @@index([user], map: "user_1")
+}
+
+model tags {
+  id   String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  name Json?  @unique(map: "name_1")
+}
+
+model threadrelations {
+  id       String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  threadId Json?  @unique(map: "threadId_1")
+}
+
+model transferkeys {
+  id        String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  expireAt  Json?
+  /// Field referred in an index, but found no data to define the type.
+  key       Json?  @unique(map: "key_1")
+  /// Field referred in an index, but found no data to define the type.
+  keyString Json?  @unique(map: "keyString_1")
+
+  @@index([expireAt], map: "expireAt_1")
+}
+
+model updateposts {
+  id      String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  creator Json?
+
+  @@index([creator], map: "creator_1")
+}
+
+model usergrouprelations {
+  id           String   @id @default(auto()) @map("_id") @db.ObjectId
+  v            Int      @map("__v")
+  createdAt    DateTime @db.Date
+  relatedGroup String   @db.ObjectId
+  relatedUser  String   @db.ObjectId
+}
+
+model usergroups {
+  id          String   @id @default(auto()) @map("_id") @db.ObjectId
+  v           Int      @map("__v")
+  createdAt   DateTime @db.Date
+  description String
+  name        String   @unique(map: "name_1")
+  /// Could not determine type: the field only had null or empty values in the sample set.
+  parent      Json?
+  updatedAt   DateTime @db.Date
+
+  @@index([parent], map: "parent_1")
+}
+
+model userregistrationorders {
+  id    String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  token Json?  @unique(map: "token_1")
+}
+
+model users {
+  id                      String   @id @default(auto()) @map("_id") @db.ObjectId
+  v                       Int      @map("__v")
+  admin                   Boolean
+  /// Field referred in an index, but found no data to define the type.
+  apiToken                Json?
+  createdAt               DateTime @db.Date
+  email                   String   @unique(map: "email_1")
+  imageUrlCached          String
+  isEmailPublished        Boolean
+  isGravatarEnabled       Boolean
+  isInvitationEmailSended Boolean
+  lang                    String
+  /// Field referred in an index, but found no data to define the type.
+  lastLoginAt             Json?
+  name                    String
+  password                String
+  readOnly                Boolean
+  /// Field referred in an index, but found no data to define the type.
+  slackMemberId           Json?    @unique(map: "slackMemberId_1")
+  status                  Int
+  updatedAt               DateTime @db.Date
+  username                String   @unique(map: "username_1")
+
+  @@index([name], map: "name_1")
+  @@index([apiToken], map: "apiToken_1")
+  @@index([status], map: "status_1")
+  @@index([lastLoginAt], map: "lastLoginAt_1")
+  @@index([admin], map: "admin_1")
+}
+
+model useruisettings {
+  id   String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  user Json?  @unique(map: "user_1")
+}
+
+model vectorstorefilerelations {
+  id                    String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  attachment            Json?
+  /// Field referred in an index, but found no data to define the type.
+  page                  Json?
+  /// Field referred in an index, but found no data to define the type.
+  vectorStoreRelationId Json?
+
+  @@unique([vectorStoreRelationId, page, attachment], map: "vectorStoreRelationId_1_page_1_attachment_1")
+}
+
+model vectorstores {
+  id            String @id @default(auto()) @map("_id") @db.ObjectId
+  /// Field referred in an index, but found no data to define the type.
+  vectorStoreId Json?  @unique(map: "vectorStoreId_1")
+}
+
+model yjs_writings {
+  id      String  @id @default(auto()) @map("_id") @db.ObjectId
+  action  String?
+  clock   Int?
+  docName String
+  metaKey String?
+  /// Field referred in an index, but found no data to define the type.
+  part    Json?
+  /// Multiple data types found: Float: 33.3%, Binary: 66.7% out of 3 sampled entries
+  value   Json
+  version String
+
+  @@index([version, docName, action, clock, part], map: "version_1_docName_1_action_1_clock_1_part_1")
+  @@index([version, docName, metaKey], map: "version_1_docName_1_metaKey_1")
+  @@index([docName, clock], map: "docName_1_clock_1")
+  @@map("yjs-writings")
+}

+ 6 - 0
apps/app/prisma/types.ts

@@ -0,0 +1,6 @@
+import type { PrismaClient } from '~/generated/prisma/client';
+
+/**
+ * Migration function type
+ */
+export type Migration = (args: { context: PrismaClient }) => Promise<void>;

+ 1 - 0
apps/app/src/features/page/index.ts

@@ -0,0 +1 @@
+export * from './models';

+ 1 - 0
apps/app/src/features/page/models/index.ts

@@ -0,0 +1 @@
+export * from './revision';

+ 5 - 0
apps/app/src/features/page/models/revision.ts

@@ -0,0 +1,5 @@
+import { Prisma } from '~/generated/prisma/client';
+
+export const extension = Prisma.defineExtension((client) =>
+  client.$extends({}),
+);

+ 5 - 0
apps/app/src/utils/prisma.ts

@@ -0,0 +1,5 @@
+import { extension as RevisionExtension } from '~/features/page';
+import { PrismaClient as OriginalPrismaClient } from '~/generated/prisma/client';
+
+export const prisma = new OriginalPrismaClient().$extends(RevisionExtension);
+export type PrismaClient = typeof prisma;

+ 1 - 1
apps/app/tsconfig.json

@@ -26,7 +26,7 @@
       { "transform": "typescript-transform-paths", "afterDeclarations": true }
     ]
   },
-  "include": ["next-env.d.ts", "config", "src"],
+  "include": ["next-env.d.ts", "bin", "config", "prisma", "src"],
   "exclude": ["src/**/*.vendor-styles.*"],
   "ts-node": {
     "transpileOnly": true,

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 333 - 46
pnpm-lock.yaml


Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác