mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 12:28:42 +00:00
This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [@prisma/client](https://www.prisma.io) ([source](https://redirect.github.com/prisma/prisma/tree/HEAD/packages/client)) | [`^5.22.0` -> `^6.0.0`](https://renovatebot.com/diffs/npm/@prisma%2fclient/5.22.0/6.0.1) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | | [@prisma/instrumentation](https://www.prisma.io) ([source](https://redirect.github.com/prisma/prisma/tree/HEAD/packages/instrumentation)) | [`^5.22.0` -> `^6.0.0`](https://renovatebot.com/diffs/npm/@prisma%2finstrumentation/5.22.0/6.0.1) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | | [prisma](https://www.prisma.io) ([source](https://redirect.github.com/prisma/prisma/tree/HEAD/packages/cli)) | [`^5.22.0` -> `^6.0.0`](https://renovatebot.com/diffs/npm/prisma/5.22.0/6.0.1) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes <details> <summary>prisma/prisma (@​prisma/client)</summary> ### [`v6.0.1`](https://redirect.github.com/prisma/prisma/compare/6.0.0...6.0.1) [Compare Source](https://redirect.github.com/prisma/prisma/compare/6.0.0...6.0.1) ### [`v6.0.0`](https://redirect.github.com/prisma/prisma/releases/tag/6.0.0) [Compare Source](https://redirect.github.com/prisma/prisma/compare/5.22.0...6.0.0) We’re excited to share the Prisma ORM v6 release today 🎉 As this is a major release, it includes a few breaking changes that may affect your application. Before upgrading, we recommend that you check out our [upgrade guide](https://www.prisma.io/docs/orm/more/upgrade-guides/upgrading-versions/upgrading-to-prisma-6) to understand the impact on your application. If you want to have an overview of what we accomplished since v5, check out our announcement blog post: [Prisma 6: Better Performance, More Flexibility & Type-Safe SQL](https://www.prisma.io/blog/prisma-6-better-performance-more-flexibility-and-type-safe-sql). 🌟 **Help us spread the word about Prisma by starring the repo ☝️ or [posting on X](https://twitter.com/intent/tweet?text=Check%20out%20the%20latest%20@​prisma%20release%20v6.0.0%20%F0%9F%9A%80%0D%0A%0D%0Ahttps://github.com/prisma/prisma/releases/tag/6.0.0) about the release.** ##### Breaking changes ⚠️ This section contains a list of breaking changes. If you upgrade your application to Prisma ORM v6 without addressing these, your application is going to break! **For detailed upgrade instructions, check out the [upgrade guide](https://www.prisma.io/docs/orm/more/upgrade-guides/upgrading-versions/upgrading-to-prisma-6).** ⚠️ ##### Minimum supported Node.js versions The new minimum supported Node.js versions for Prisma ORM v6 are: - for Node.js 18 the minimum supported version is **18.18.0** - for Node.js 20 the minimum supported version is **20.9.0** - for Node.js 22 the minimum supported version is **22.11.0** There is no official support for Node.js <18.18.0, 19, 21, 23. ##### Minimum supported TypeScript version The new minimum supported TypeScript version for Prisma ORM v6 is: **5.1.0**. ##### Schema change for implicit m-n relations on PostgreSQL If you're using PostgreSQL and are defining [implicit many-to-many relations](https://www.prisma.io/docs/orm/prisma-schema/data-model/relations/many-to-many-relations#implicit-many-to-many-relations) in your Prisma schema, Prisma ORM maintains the [relation table](https://www.prisma.io/docs/orm/prisma-schema/data-model/relations/many-to-many-relations#relation-tables) for you under the hood. This relation table has `A` and `B` columns to represent the tables of the models that are part of this relation. Previous versions of Prisma ORM used to create a *unique index* on these two columns. In Prisma v6, this unique index is changing to a *primary key* in order to [simplify for the default replica identity behaviour](https://redirect.github.com/prisma/prisma/issues/25196). If you're defining implicit m-n relations in your Prisma schema, the next migration you'll create will contain `ALTER TABLE` statements for *all* the relation tables that belong to these relations. ##### Full-text search on PostgreSQL The `fullTextSearch` Preview feature is promoted to General Availability only for MySQL. This means that if you're using PostgreSQL and currently make use of this Preview feature, you now need to use the new `fullTextSearchPostgres` Preview feature. ##### Usage of `Buffer` Prisma v6 replaces the usage of [`Buffer`](https://nodejs.org/api/buffer.html) with [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) to represent fields of type `Bytes`. Make sure to replace all your occurrences of the `Buffer` type with the new `Uint8Array`. ##### Removed `NotFoundError` In Prisma v6, we removed the `NotFoundError` in favor of `PrismaClientKnownRequestError` with error code [`P2025`](https://www.prisma.io/docs/orm/reference/error-reference#p2025) in [`findUniqueOrThrow()`](https://www.prisma.io/docs/orm/reference/prisma-client-reference#finduniqueorthrow) and [`findFirstOrThrow()`](https://www.prisma.io/docs/orm/reference/prisma-client-reference#findfirstorthrow). If you've relied on catching `NotFoundError` instances in your code, you need to adjust the code accordingly. ##### New keywords that can't be used as model names: `async`, `await`, `using` With this release, you can't use `async`, `await` and `using` as model names any more. *** ⚠️ **For detailed upgrade instructions, check out the [upgrade guide](https://www.prisma.io/docs/orm/more/upgrade-guides/upgrading-versions/upgrading-to-prisma-6).** ⚠️ ##### Preview features promoted to General Availability In this release, we are promoting a number of [Preview](https://www.prisma.io/docs/orm/more/releases#preview) features to [General Availability](https://www.prisma.io/docs/orm/more/releases#generally-available-ga). ##### `fullTextIndex` If you use the [full-text index](https://www.prisma.io/docs/orm/prisma-schema/data-model/indexes#full-text-indexes-mysql-and-mongodb) feature in your app, you can now remove `fullTextIndex` from the `previewFeatures` in your Prisma schema: ```diff generator client { provider = "prisma-client-js" - previewFeatures = ["fullTextIndex"] } ``` ##### `fullTextSearch` If you use the [full-text search](https://www.prisma.io/docs/orm/prisma-client/queries/full-text-search) feature with **MySQL** in your app, you can now remove `fullTextSearch` from the `previewFeatures` in your Prisma schema: ```diff generator client { provider = "prisma-client-js" - previewFeatures = ["fullTextSearch"] } ``` If you are using it with **PostgreSQL**, you need to update the name of the feature flag to `fullTextSearchPostgres`: ```diff generator client { provider = "prisma-client-js" - previewFeatures = ["fullTextSearch"] + previewFeatures = ["fullTextSearchPostgres"] } ``` ##### New features We are also releasing new features with this release: - [cuid2() support](https://redirect.github.com/prisma/prisma-engines/pull/5047) - [Include unused enum definitions in `prisma generate`'s output](https://redirect.github.com/prisma/prisma/pull/25740) - [Improved compatibility with Deno 2](https://redirect.github.com/prisma/prisma/pull/25734) ##### Company news ##### 🚀 Prisma Postgres is free during Early Access In case you missed it: We recently launched [Prisma Postgres](https://www.prisma.io/blog/announcing-prisma-postgres-early-access), a serverless database with zero cold starts, a generous free tier, connection pooling, real-time events, and a lot more! It’s entirely free during the Early Access phase, try it now! ##### ✨ Let us know what you think of Prisma ORM We're always trying to improve! If you've recently used Prisma ORM, we'd appreciate hearing your thoughts about your experience via this [2min survey](https://pris.ly/orm/survey/release-5-22). </details> <details> <summary>prisma/prisma (@​prisma/instrumentation)</summary> ### [`v6.0.1`](https://redirect.github.com/prisma/prisma/releases/tag/6.0.1) [Compare Source](https://redirect.github.com/prisma/prisma/compare/6.0.0...6.0.1) Today we are releasing the `6.0.1` patch release to address an issue with using Prisma Client generated in a custom output path with Next.js. ##### Changes - [Revert `"type": "commonjs"` addition in generated `package.json`](https://redirect.github.com/prisma/prisma/pull/25767) ### [`v6.0.0`](https://redirect.github.com/prisma/prisma/releases/tag/6.0.0) [Compare Source](https://redirect.github.com/prisma/prisma/compare/5.22.0...6.0.0) We’re excited to share the Prisma ORM v6 release today 🎉 As this is a major release, it includes a few breaking changes that may affect your application. Before upgrading, we recommend that you check out our [upgrade guide](https://www.prisma.io/docs/orm/more/upgrade-guides/upgrading-versions/upgrading-to-prisma-6) to understand the impact on your application. If you want to have an overview of what we accomplished since v5, check out our announcement blog post: [Prisma 6: Better Performance, More Flexibility & Type-Safe SQL](https://www.prisma.io/blog/prisma-6-better-performance-more-flexibility-and-type-safe-sql). 🌟 **Help us spread the word about Prisma by starring the repo ☝️ or [posting on X](https://twitter.com/intent/tweet?text=Check%20out%20the%20latest%20@​prisma%20release%20v6.0.0%20%F0%9F%9A%80%0D%0A%0D%0Ahttps://github.com/prisma/prisma/releases/tag/6.0.0) about the release.** #### Breaking changes ⚠️ This section contains a list of breaking changes. If you upgrade your application to Prisma ORM v6 without addressing these, your application is going to break! **For detailed upgrade instructions, check out the [upgrade guide](https://www.prisma.io/docs/orm/more/upgrade-guides/upgrading-versions/upgrading-to-prisma-6).** ⚠️ ##### Minimum supported Node.js versions The new minimum supported Node.js versions for Prisma ORM v6 are: - for Node.js 18 the minimum supported version is **18.18.0** - for Node.js 20 the minimum supported version is **20.9.0** - for Node.js 22 the minimum supported version is **22.11.0** There is no official support for Node.js <18.18.0, 19, 21, 23. ##### Minimum supported TypeScript version The new minimum supported TypeScript version for Prisma ORM v6 is: **5.1.0**. ##### Schema change for implicit m-n relations on PostgreSQL If you're using PostgreSQL and are defining [implicit many-to-many relations](https://www.prisma.io/docs/orm/prisma-schema/data-model/relations/many-to-many-relations#implicit-many-to-many-relations) in your Prisma schema, Prisma ORM maintains the [relation table](https://www.prisma.io/docs/orm/prisma-schema/data-model/relations/many-to-many-relations#relation-tables) for you under the hood. This relation table has `A` and `B` columns to represent the tables of the models that are part of this relation. Previous versions of Prisma ORM used to create a *unique index* on these two columns. In Prisma v6, this unique index is changing to a *primary key* in order to [simplify for the default replica identity behaviour](https://redirect.github.com/prisma/prisma/issues/25196). If you're defining implicit m-n relations in your Prisma schema, the next migration you'll create will contain `ALTER TABLE` statements for *all* the relation tables that belong to these relations. ##### Full-text search on PostgreSQL The `fullTextSearch` Preview feature is promoted to General Availability only for MySQL. This means that if you're using PostgreSQL and currently make use of this Preview feature, you now need to use the new `fullTextSearchPostgres` Preview feature. ##### Usage of `Buffer` Prisma v6 replaces the usage of [`Buffer`](https://nodejs.org/api/buffer.html) with [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) to represent fields of type `Bytes`. Make sure to replace all your occurrences of the `Buffer` type with the new `Uint8Array`. ##### Removed `NotFoundError` In Prisma v6, we removed the `NotFoundError` in favor of `PrismaClientKnownRequestError` with error code [`P2025`](https://www.prisma.io/docs/orm/reference/error-reference#p2025) in [`findUniqueOrThrow()`](https://www.prisma.io/docs/orm/reference/prisma-client-reference#finduniqueorthrow) and [`findFirstOrThrow()`](https://www.prisma.io/docs/orm/reference/prisma-client-reference#findfirstorthrow). If you've relied on catching `NotFoundError` instances in your code, you need to adjust the code accordingly. ##### New keywords that can't be used as model names: `async`, `await`, `using` With this release, you can't use `async`, `await` and `using` as model names any more. *** ⚠️ **For detailed upgrade instructions, check out the [upgrade guide](https://www.prisma.io/docs/orm/more/upgrade-guides/upgrading-versions/upgrading-to-prisma-6).** ⚠️ #### Preview features promoted to General Availability In this release, we are promoting a number of [Preview](https://www.prisma.io/docs/orm/more/releases#preview) features to [General Availability](https://www.prisma.io/docs/orm/more/releases#generally-available-ga). ##### `fullTextIndex` If you use the [full-text index](https://www.prisma.io/docs/orm/prisma-schema/data-model/indexes#full-text-indexes-mysql-and-mongodb) feature in your app, you can now remove `fullTextIndex` from the `previewFeatures` in your Prisma schema: ```diff generator client { provider = "prisma-client-js" - previewFeatures = ["fullTextIndex"] } ``` ##### `fullTextSearch` If you use the [full-text search](https://www.prisma.io/docs/orm/prisma-client/queries/full-text-search) feature with **MySQL** in your app, you can now remove `fullTextSearch` from the `previewFeatures` in your Prisma schema: ```diff generator client { provider = "prisma-client-js" - previewFeatures = ["fullTextSearch"] } ``` If you are using it with **PostgreSQL**, you need to update the name of the feature flag to `fullTextSearchPostgres`: ```diff generator client { provider = "prisma-client-js" - previewFeatures = ["fullTextSearch"] + previewFeatures = ["fullTextSearchPostgres"] } ``` #### New features We are also releasing new features with this release: - [cuid2() support](https://redirect.github.com/prisma/prisma-engines/pull/5047) - [Include unused enum definitions in `prisma generate`'s output](https://redirect.github.com/prisma/prisma/pull/25740) - [Improved compatibility with Deno 2](https://redirect.github.com/prisma/prisma/pull/25734) #### Company news ##### 🚀 Prisma Postgres is free during Early Access In case you missed it: We recently launched [Prisma Postgres](https://www.prisma.io/blog/announcing-prisma-postgres-early-access), a serverless database with zero cold starts, a generous free tier, connection pooling, real-time events, and a lot more! It’s entirely free during the Early Access phase, try it now! ##### ✨ Let us know what you think of Prisma ORM We're always trying to improve! If you've recently used Prisma ORM, we'd appreciate hearing your thoughts about your experience via this [2min survey](https://pris.ly/orm/survey/release-5-22). </details> <details> <summary>prisma/prisma (prisma)</summary> ### [`v6.0.1`](https://redirect.github.com/prisma/prisma/compare/6.0.0...6.0.1) [Compare Source](https://redirect.github.com/prisma/prisma/compare/6.0.0...6.0.1) ### [`v6.0.0`](https://redirect.github.com/prisma/prisma/releases/tag/6.0.0) [Compare Source](https://redirect.github.com/prisma/prisma/compare/5.22.0...6.0.0) We’re excited to share the Prisma ORM v6 release today 🎉 As this is a major release, it includes a few breaking changes that may affect your application. Before upgrading, we recommend that you check out our [upgrade guide](https://www.prisma.io/docs/orm/more/upgrade-guides/upgrading-versions/upgrading-to-prisma-6) to understand the impact on your application. If you want to have an overview of what we accomplished since v5, check out our announcement blog post: [Prisma 6: Better Performance, More Flexibility & Type-Safe SQL](https://www.prisma.io/blog/prisma-6-better-performance-more-flexibility-and-type-safe-sql). 🌟 **Help us spread the word about Prisma by starring the repo ☝️ or [posting on X](https://twitter.com/intent/tweet?text=Check%20out%20the%20latest%20@​prisma%20release%20v6.0.0%20%F0%9F%9A%80%0D%0A%0D%0Ahttps://github.com/prisma/prisma/releases/tag/6.0.0) about the release.** ##### Breaking changes ⚠️ This section contains a list of breaking changes. If you upgrade your application to Prisma ORM v6 without addressing these, your application is going to break! **For detailed upgrade instructions, check out the [upgrade guide](https://www.prisma.io/docs/orm/more/upgrade-guides/upgrading-versions/upgrading-to-prisma-6).** ⚠️ ##### Minimum supported Node.js versions The new minimum supported Node.js versions for Prisma ORM v6 are: - for Node.js 18 the minimum supported version is **18.18.0** - for Node.js 20 the minimum supported version is **20.9.0** - for Node.js 22 the minimum supported version is **22.11.0** There is no official support for Node.js <18.18.0, 19, 21, 23. ##### Minimum supported TypeScript version The new minimum supported TypeScript version for Prisma ORM v6 is: **5.1.0**. ##### Schema change for implicit m-n relations on PostgreSQL If you're using PostgreSQL and are defining [implicit many-to-many relations](https://www.prisma.io/docs/orm/prisma-schema/data-model/relations/many-to-many-relations#implicit-many-to-many-relations) in your Prisma schema, Prisma ORM maintains the [relation table](https://www.prisma.io/docs/orm/prisma-schema/data-model/relations/many-to-many-relations#relation-tables) for you under the hood. This relation table has `A` and `B` columns to represent the tables of the models that are part of this relation. Previous versions of Prisma ORM used to create a *unique index* on these two columns. In Prisma v6, this unique index is changing to a *primary key* in order to [simplify for the default replica identity behaviour](https://redirect.github.com/prisma/prisma/issues/25196). If you're defining implicit m-n relations in your Prisma schema, the next migration you'll create will contain `ALTER TABLE` statements for *all* the relation tables that belong to these relations. ##### Full-text search on PostgreSQL The `fullTextSearch` Preview feature is promoted to General Availability only for MySQL. This means that if you're using PostgreSQL and currently make use of this Preview feature, you now need to use the new `fullTextSearchPostgres` Preview feature. ##### Usage of `Buffer` Prisma v6 replaces the usage of [`Buffer`](https://nodejs.org/api/buffer.html) with [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) to represent fields of type `Bytes`. Make sure to replace all your occurrences of the `Buffer` type with the new `Uint8Array`. ##### Removed `NotFoundError` In Prisma v6, we removed the `NotFoundError` in favor of `PrismaClientKnownRequestError` with error code [`P2025`](https://www.prisma.io/docs/orm/reference/error-reference#p2025) in [`findUniqueOrThrow()`](https://www.prisma.io/docs/orm/reference/prisma-client-reference#finduniqueorthrow) and [`findFirstOrThrow()`](https://www.prisma.io/docs/orm/reference/prisma-client-reference#findfirstorthrow). If you've relied on catching `NotFoundError` instances in your code, you need to adjust the code accordingly. ##### New keywords that can't be used as model names: `async`, `await`, `using` With this release, you can't use `async`, `await` and `using` as model names any more. *** ⚠️ **For detailed upgrade instructions, check out the [upgrade guide](https://www.prisma.io/docs/orm/more/upgrade-guides/upgrading-versions/upgrading-to-prisma-6).** ⚠️ ##### Preview features promoted to General Availability In this release, we are promoting a number of [Preview](https://www.prisma.io/docs/orm/more/releases#preview) features to [General Availability](https://www.prisma.io/docs/orm/more/releases#generally-available-ga). ##### `fullTextIndex` If you use the [full-text index](https://www.prisma.io/docs/orm/prisma-schema/data-model/indexes#full-text-indexes-mysql-and-mongodb) feature in your app, you can now remove `fullTextIndex` from the `previewFeatures` in your Prisma schema: ```diff generator client { provider = "prisma-client-js" - previewFeatures = ["fullTextIndex"] } ``` ##### `fullTextSearch` If you use the [full-text search](https://www.prisma.io/docs/orm/prisma-client/queries/full-text-search) feature with **MySQL** in your app, you can now remove `fullTextSearch` from the `previewFeatures` in your Prisma schema: ```diff generator client { provider = "prisma-client-js" - previewFeatures = ["fullTextSearch"] } ``` If you are using it with **PostgreSQL**, you need to update the name of the feature flag to `fullTextSearchPostgres`: ```diff generator client { provider = "prisma-client-js" - previewFeatures = ["fullTextSearch"] + previewFeatures = ["fullTextSearchPostgres"] } ``` ##### New features We are also releasing new features with this release: - [cuid2() support](https://redirect.github.com/prisma/prisma-engines/pull/5047) - [Include unused enum definitions in `prisma generate`'s output](https://redirect.github.com/prisma/prisma/pull/25740) - [Improved compatibility with Deno 2](https://redirect.github.com/prisma/prisma/pull/25734) ##### Company news ##### 🚀 Prisma Postgres is free during Early Access In case you missed it: We recently launched [Prisma Postgres](https://www.prisma.io/blog/announcing-prisma-postgres-early-access), a serverless database with zero cold starts, a generous free tier, connection pooling, real-time events, and a lot more! It’s entirely free during the Early Access phase, try it now! ##### ✨ Let us know what you think of Prisma ORM We're always trying to improve! If you've recently used Prisma ORM, we'd appreciate hearing your thoughts about your experience via this [2min survey](https://pris.ly/orm/survey/release-5-22). </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xOS4wIiwidXBkYXRlZEluVmVyIjoiMzkuNTguMSIsInRhcmdldEJyYW5jaCI6ImNhbmFyeSIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->
775 lines
30 KiB
Plaintext
775 lines
30 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
output = "./node_modules/.prisma/client"
|
|
binaryTargets = ["native", "debian-openssl-3.0.x", "linux-arm64-openssl-3.0.x"]
|
|
previewFeatures = ["metrics", "relationJoins", "nativeDistinct", "postgresqlExtensions"]
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
extensions = [pgvector(map: "vector")]
|
|
}
|
|
|
|
model User {
|
|
id String @id @default(uuid()) @db.VarChar
|
|
name String @db.VarChar
|
|
email String @unique @db.VarChar
|
|
emailVerifiedAt DateTime? @map("email_verified") @db.Timestamptz(3)
|
|
avatarUrl String? @map("avatar_url") @db.VarChar
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
/// Not available if user signed up through OAuth providers
|
|
password String? @db.VarChar
|
|
/// Indicate whether the user finished the signup progress.
|
|
/// for example, the value will be false if user never registered and invited into a workspace by others.
|
|
registered Boolean @default(true)
|
|
disabled Boolean @default(false)
|
|
|
|
features UserFeature[]
|
|
userStripeCustomer UserStripeCustomer?
|
|
workspacePermissions WorkspaceUserRole[]
|
|
docPermissions WorkspaceDocUserRole[]
|
|
connectedAccounts ConnectedAccount[]
|
|
sessions UserSession[]
|
|
aiSessions AiSession[]
|
|
/// @deprecated
|
|
deprecatedAppRuntimeSettings DeprecatedAppRuntimeSettings[]
|
|
appConfigs AppConfig[]
|
|
userSnapshots UserSnapshot[]
|
|
createdSnapshot Snapshot[] @relation("createdSnapshot")
|
|
updatedSnapshot Snapshot[] @relation("updatedSnapshot")
|
|
createdUpdate Update[] @relation("createdUpdate")
|
|
createdHistory SnapshotHistory[] @relation("createdHistory")
|
|
createdAiJobs AiJobs[] @relation("createdAiJobs")
|
|
// receive notifications
|
|
notifications Notification[] @relation("user_notifications")
|
|
settings UserSettings?
|
|
|
|
@@index([email])
|
|
@@map("users")
|
|
}
|
|
|
|
model ConnectedAccount {
|
|
id String @id @default(uuid()) @db.VarChar
|
|
userId String @map("user_id") @db.VarChar
|
|
provider String @db.VarChar
|
|
providerAccountId String @map("provider_account_id") @db.VarChar
|
|
scope String? @db.Text
|
|
accessToken String? @map("access_token") @db.Text
|
|
refreshToken String? @map("refresh_token") @db.Text
|
|
expiresAt DateTime? @map("expires_at") @db.Timestamptz(3)
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([userId])
|
|
@@index([providerAccountId])
|
|
@@map("user_connected_accounts")
|
|
}
|
|
|
|
model Session {
|
|
id String @id @default(uuid()) @db.VarChar
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
userSessions UserSession[]
|
|
|
|
// @deprecated use [UserSession.expiresAt]
|
|
deprecated_expiresAt DateTime? @map("expires_at") @db.Timestamptz(3)
|
|
|
|
@@map("multiple_users_sessions")
|
|
}
|
|
|
|
model UserSession {
|
|
id String @id @default(uuid()) @db.VarChar
|
|
sessionId String @map("session_id") @db.VarChar
|
|
userId String @map("user_id") @db.VarChar
|
|
expiresAt DateTime? @map("expires_at") @db.Timestamptz(3)
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
|
|
session Session @relation(fields: [sessionId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([sessionId, userId])
|
|
@@map("user_sessions")
|
|
}
|
|
|
|
model VerificationToken {
|
|
token String @db.VarChar
|
|
type Int @db.SmallInt
|
|
credential String? @db.Text
|
|
expiresAt DateTime @db.Timestamptz(3)
|
|
|
|
@@unique([type, token])
|
|
@@map("verification_tokens")
|
|
}
|
|
|
|
model Workspace {
|
|
id String @id @default(uuid()) @db.VarChar
|
|
public Boolean
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
// workspace level feature flags
|
|
enableAi Boolean @default(true) @map("enable_ai")
|
|
enableUrlPreview Boolean @default(false) @map("enable_url_preview")
|
|
name String? @db.VarChar
|
|
avatarKey String? @map("avatar_key") @db.VarChar
|
|
|
|
features WorkspaceFeature[]
|
|
docs WorkspaceDoc[]
|
|
permissions WorkspaceUserRole[]
|
|
docPermissions WorkspaceDocUserRole[]
|
|
blobs Blob[]
|
|
|
|
@@map("workspaces")
|
|
}
|
|
|
|
// Table for workspace page meta data
|
|
// NOTE:
|
|
// We won't make sure every page has a corresponding record in this table.
|
|
// Only the ones that have ever changed will have records here,
|
|
// and for others we will make sure it's has a default value return in our business logic.
|
|
model WorkspaceDoc {
|
|
workspaceId String @map("workspace_id") @db.VarChar
|
|
docId String @map("page_id") @db.VarChar
|
|
public Boolean @default(false)
|
|
// Workspace user's default role in this page, default is `Manager`
|
|
defaultRole Int @default(30) @db.SmallInt
|
|
// Page/Edgeless
|
|
mode Int @default(0) @db.SmallInt
|
|
// Whether the doc is blocked
|
|
blocked Boolean @default(false)
|
|
title String? @db.VarChar
|
|
summary String? @db.VarChar
|
|
|
|
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
|
|
|
@@id([workspaceId, docId])
|
|
@@map("workspace_pages")
|
|
}
|
|
|
|
enum WorkspaceMemberStatus {
|
|
Pending // 1. old state accepted = false
|
|
NeedMoreSeat // 2.1 for team: workspace owner need to buy more seat
|
|
NeedMoreSeatAndReview // 2.2 for team: workspace owner need to buy more seat and member need review
|
|
UnderReview // 3. for team: member is under review
|
|
Accepted // 4. old state accepted = true
|
|
}
|
|
|
|
model WorkspaceUserRole {
|
|
id String @id @default(uuid()) @db.VarChar
|
|
workspaceId String @map("workspace_id") @db.VarChar
|
|
userId String @map("user_id") @db.VarChar
|
|
// Workspace Role, Owner/Admin/Collaborator/External
|
|
type Int @db.SmallInt
|
|
/// @deprecated Whether the permission invitation is accepted by the user
|
|
accepted Boolean @default(false)
|
|
/// Whether the invite status of the workspace member
|
|
status WorkspaceMemberStatus @default(Pending)
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
/// When the invite status changed
|
|
updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([workspaceId, userId])
|
|
// optimize for querying user's workspace permissions
|
|
@@index(userId)
|
|
@@map("workspace_user_permissions")
|
|
}
|
|
|
|
model WorkspaceDocUserRole {
|
|
workspaceId String @map("workspace_id") @db.VarChar
|
|
docId String @map("page_id") @db.VarChar
|
|
userId String @map("user_id") @db.VarChar
|
|
// External/Reader/Editor/Manager/Owner
|
|
type Int @db.SmallInt
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
|
|
|
@@id([workspaceId, docId, userId])
|
|
@@map("workspace_page_user_permissions")
|
|
}
|
|
|
|
model Feature {
|
|
id Int @id @default(autoincrement())
|
|
name String @map("feature") @db.VarChar
|
|
configs Json @default("{}") @db.Json
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
/// TODO(@forehalo): remove in the coming version
|
|
/// @deprecated
|
|
/// we don't need to record all the historical version of features
|
|
deprecatedVersion Int @default(0) @map("version") @db.Integer
|
|
/// @deprecated
|
|
/// we don't need to record type of features any more, there are always static,
|
|
/// but set it in `WorkspaceFeature` and `UserFeature` for fast query with just a little redundant.
|
|
deprecatedType Int @default(0) @map("type") @db.Integer
|
|
|
|
userFeatures UserFeature[]
|
|
workspaceFeatures WorkspaceFeature[]
|
|
|
|
@@unique([name, deprecatedVersion])
|
|
@@map("features")
|
|
}
|
|
|
|
model UserFeature {
|
|
id Int @id @default(autoincrement())
|
|
userId String @map("user_id") @db.VarChar
|
|
featureId Int @map("feature_id") @db.Integer
|
|
// it should be typed as `optional` in the codebase, but we would keep all values exists during data migration.
|
|
// so it's safe to assert it a non-null value.
|
|
name String @default("") @map("name") @db.VarChar
|
|
// a little redundant, but fast the queries
|
|
type Int @default(0) @map("type") @db.Integer
|
|
reason String @db.VarChar
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
expiredAt DateTime? @map("expired_at") @db.Timestamptz(3)
|
|
activated Boolean @default(false)
|
|
|
|
feature Feature @relation(fields: [featureId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([userId])
|
|
@@index([name])
|
|
@@index([featureId])
|
|
@@map("user_features")
|
|
}
|
|
|
|
model WorkspaceFeature {
|
|
id Int @id @default(autoincrement())
|
|
workspaceId String @map("workspace_id") @db.VarChar
|
|
featureId Int @map("feature_id") @db.Integer
|
|
// it should be typed as `optional` in the codebase, but we would keep all values exists during data migration.
|
|
// so it's safe to assert it a non-null value.
|
|
name String @default("") @map("name") @db.VarChar
|
|
// a little redundant, but fast the queries
|
|
type Int @default(0) @map("type") @db.Integer
|
|
/// overrides for the default feature configs
|
|
configs Json @default("{}") @db.Json
|
|
reason String @db.VarChar
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
activated Boolean @default(false)
|
|
expiredAt DateTime? @map("expired_at") @db.Timestamptz(3)
|
|
|
|
feature Feature @relation(fields: [featureId], references: [id], onDelete: Cascade)
|
|
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([workspaceId])
|
|
@@index([name])
|
|
@@index([featureId])
|
|
@@map("workspace_features")
|
|
}
|
|
|
|
// the latest snapshot of each doc that we've seen
|
|
// Snapshot + Updates are the latest state of the doc
|
|
model Snapshot {
|
|
workspaceId String @map("workspace_id") @db.VarChar
|
|
id String @default(uuid()) @map("guid") @db.VarChar
|
|
blob Bytes @db.ByteA
|
|
state Bytes? @db.ByteA
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
// the `updated_at` field will not record the time of record changed,
|
|
// but the created time of last seen update that has been merged into snapshot.
|
|
updatedAt DateTime @map("updated_at") @db.Timestamptz(3)
|
|
createdBy String? @map("created_by") @db.VarChar
|
|
updatedBy String? @map("updated_by") @db.VarChar
|
|
|
|
// should not delete origin snapshot even if user is deleted
|
|
// we only delete the snapshot if the workspace is deleted
|
|
createdByUser User? @relation(name: "createdSnapshot", fields: [createdBy], references: [id], onDelete: SetNull)
|
|
updatedByUser User? @relation(name: "updatedSnapshot", fields: [updatedBy], references: [id], onDelete: SetNull)
|
|
|
|
// @deprecated use updatedAt only
|
|
seq Int? @default(0) @db.Integer
|
|
|
|
// we need to clear all hanging updates and snapshots before enable the foreign key on workspaceId
|
|
// workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
|
|
|
embedding AiWorkspaceEmbedding?
|
|
|
|
@@id([workspaceId, id])
|
|
@@index([workspaceId, updatedAt])
|
|
@@map("snapshots")
|
|
}
|
|
|
|
// user snapshots are special snapshots for user storage like personal app settings, distinguished from workspace snapshots
|
|
// basically they share the same structure with workspace snapshots
|
|
// but for convenience, we don't fork the updates queue and history for user snapshots, until we have to
|
|
// which means all operation on user snapshot will happen in-pace
|
|
model UserSnapshot {
|
|
userId String @map("user_id") @db.VarChar
|
|
id String @map("id") @db.VarChar
|
|
blob Bytes @db.ByteA
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@id([userId, id])
|
|
@@map("user_snapshots")
|
|
}
|
|
|
|
model Update {
|
|
workspaceId String @map("workspace_id") @db.VarChar
|
|
id String @map("guid") @db.VarChar
|
|
blob Bytes @db.ByteA
|
|
createdAt DateTime @map("created_at") @db.Timestamptz(3)
|
|
createdBy String? @map("created_by") @db.VarChar
|
|
|
|
// will delete creator record if creator's account is deleted
|
|
createdByUser User? @relation(name: "createdUpdate", fields: [createdBy], references: [id], onDelete: SetNull)
|
|
|
|
// @deprecated use createdAt only
|
|
seq Int? @db.Integer
|
|
|
|
@@id([workspaceId, id, createdAt])
|
|
@@map("updates")
|
|
}
|
|
|
|
model SnapshotHistory {
|
|
workspaceId String @map("workspace_id") @db.VarChar
|
|
id String @map("guid") @db.VarChar
|
|
timestamp DateTime @db.Timestamptz(3)
|
|
blob Bytes @db.ByteA
|
|
state Bytes? @db.ByteA
|
|
expiredAt DateTime @map("expired_at") @db.Timestamptz(3)
|
|
createdBy String? @map("created_by") @db.VarChar
|
|
|
|
// will delete creator record if creator's account is deleted
|
|
createdByUser User? @relation(name: "createdHistory", fields: [createdBy], references: [id], onDelete: SetNull)
|
|
|
|
@@id([workspaceId, id, timestamp])
|
|
@@map("snapshot_histories")
|
|
}
|
|
|
|
enum AiPromptRole {
|
|
system
|
|
assistant
|
|
user
|
|
}
|
|
|
|
model AiPromptMessage {
|
|
promptId Int @map("prompt_id") @db.Integer
|
|
// if a group of prompts contains multiple sentences, idx specifies the order of each sentence
|
|
idx Int @db.Integer
|
|
// system/assistant/user
|
|
role AiPromptRole
|
|
// prompt content
|
|
content String @db.Text
|
|
attachments Json? @db.Json
|
|
params Json? @db.Json
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
|
|
prompt AiPrompt @relation(fields: [promptId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([promptId, idx])
|
|
@@map("ai_prompts_messages")
|
|
}
|
|
|
|
model AiPrompt {
|
|
id Int @id @default(autoincrement()) @db.Integer
|
|
name String @unique @db.VarChar(32)
|
|
// an mark identifying which view to use to display the session
|
|
// it is only used in the frontend and does not affect the backend
|
|
action String? @db.VarChar
|
|
model String @db.VarChar
|
|
config Json? @db.Json
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @default(now()) @map("updated_at") @db.Timestamptz(3)
|
|
// whether the prompt is modified by the admin panel
|
|
modified Boolean @default(false)
|
|
|
|
messages AiPromptMessage[]
|
|
sessions AiSession[]
|
|
|
|
@@map("ai_prompts_metadata")
|
|
}
|
|
|
|
model AiSessionMessage {
|
|
id String @id @default(uuid()) @db.VarChar
|
|
sessionId String @map("session_id") @db.VarChar
|
|
role AiPromptRole
|
|
content String @db.Text
|
|
attachments Json? @db.Json
|
|
params Json? @db.Json
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
|
|
session AiSession @relation(fields: [sessionId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([sessionId])
|
|
@@map("ai_sessions_messages")
|
|
}
|
|
|
|
model AiSession {
|
|
id String @id @default(uuid()) @db.VarChar
|
|
userId String @map("user_id") @db.VarChar
|
|
workspaceId String @map("workspace_id") @db.VarChar
|
|
docId String @map("doc_id") @db.VarChar
|
|
promptName String @map("prompt_name") @db.VarChar(32)
|
|
// the session id of the parent session if this session is a forked session
|
|
parentSessionId String? @map("parent_session_id") @db.VarChar
|
|
messageCost Int @default(0)
|
|
tokenCost Int @default(0)
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(3)
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
prompt AiPrompt @relation(fields: [promptName], references: [name], onDelete: Cascade)
|
|
messages AiSessionMessage[]
|
|
context AiContext[]
|
|
|
|
@@index([userId])
|
|
@@index([userId, workspaceId])
|
|
@@map("ai_sessions_metadata")
|
|
}
|
|
|
|
model AiContext {
|
|
id String @id @default(uuid()) @db.VarChar
|
|
sessionId String @map("session_id") @db.VarChar
|
|
config Json @db.Json
|
|
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
|
|
embeddings AiContextEmbedding[]
|
|
session AiSession @relation(fields: [sessionId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("ai_contexts")
|
|
}
|
|
|
|
model AiContextEmbedding {
|
|
id String @id @default(uuid()) @db.VarChar
|
|
contextId String @map("context_id") @db.VarChar
|
|
fileId String @map("file_id") @db.VarChar
|
|
// a file can be divided into multiple chunks and embedded separately.
|
|
chunk Int @db.Integer
|
|
content String @db.VarChar
|
|
embedding Unsupported("vector(1024)")
|
|
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
|
|
context AiContext @relation(fields: [contextId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([contextId, fileId, chunk])
|
|
@@index([embedding], map: "ai_context_embeddings_idx")
|
|
@@map("ai_context_embeddings")
|
|
}
|
|
|
|
model AiWorkspaceEmbedding {
|
|
workspaceId String @map("workspace_id") @db.VarChar
|
|
docId String @map("doc_id") @db.VarChar
|
|
// a doc can be divided into multiple chunks and embedded separately.
|
|
chunk Int @db.Integer
|
|
content String @db.VarChar
|
|
embedding Unsupported("vector(1024)")
|
|
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
|
|
// workspace level search not available for non-cloud workspaces
|
|
// so we can match this record with the snapshot one by one
|
|
snapshot Snapshot @relation(fields: [workspaceId, docId], references: [workspaceId, id], onDelete: Cascade)
|
|
|
|
@@id([workspaceId, docId])
|
|
@@unique([workspaceId, docId, chunk])
|
|
@@index([embedding], map: "ai_workspace_embeddings_idx")
|
|
@@map("ai_workspace_embeddings")
|
|
}
|
|
|
|
enum AiJobStatus {
|
|
pending
|
|
running
|
|
finished
|
|
claimed
|
|
failed
|
|
}
|
|
|
|
enum AiJobType {
|
|
transcription
|
|
}
|
|
|
|
model AiJobs {
|
|
id String @id @default(uuid()) @db.VarChar
|
|
workspaceId String @map("workspace_id") @db.VarChar
|
|
blobId String @map("blob_id") @db.VarChar
|
|
createdBy String? @map("created_by") @db.VarChar
|
|
// job type, like "transcription"
|
|
type AiJobType
|
|
status AiJobStatus @default(pending)
|
|
// job result
|
|
payload Json @db.Json
|
|
|
|
startedAt DateTime @default(now()) @map("started_at") @db.Timestamptz(3)
|
|
finishedAt DateTime? @map("finished_at") @db.Timestamptz(3)
|
|
|
|
// will delete creator record if creator's account is deleted
|
|
createdByUser User? @relation(name: "createdAiJobs", fields: [createdBy], references: [id], onDelete: SetNull)
|
|
|
|
@@unique([createdBy, workspaceId, blobId])
|
|
@@map("ai_jobs")
|
|
}
|
|
|
|
model DataMigration {
|
|
id String @id @default(uuid()) @db.VarChar
|
|
name String @unique @db.VarChar
|
|
startedAt DateTime @default(now()) @map("started_at") @db.Timestamptz(3)
|
|
finishedAt DateTime? @map("finished_at") @db.Timestamptz(3)
|
|
|
|
@@map("_data_migrations")
|
|
}
|
|
|
|
enum RuntimeConfigType {
|
|
String
|
|
Number
|
|
Boolean
|
|
Object
|
|
Array
|
|
}
|
|
|
|
/// @deprecated use AppConfig instead
|
|
model DeprecatedAppRuntimeSettings {
|
|
id String @id @db.VarChar
|
|
type RuntimeConfigType
|
|
module String @db.VarChar
|
|
key String @db.VarChar
|
|
value Json @db.Json
|
|
description String @db.Text
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(3)
|
|
lastUpdatedBy String? @map("last_updated_by") @db.VarChar
|
|
|
|
lastUpdatedByUser User? @relation(fields: [lastUpdatedBy], references: [id])
|
|
|
|
@@unique([module, key])
|
|
@@map("app_runtime_settings")
|
|
}
|
|
|
|
model AppConfig {
|
|
id String @id @db.VarChar
|
|
value Json @db.JsonB
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
lastUpdatedBy String? @map("last_updated_by") @db.VarChar
|
|
|
|
lastUpdatedByUser User? @relation(fields: [lastUpdatedBy], references: [id], onDelete: SetNull)
|
|
|
|
@@map("app_configs")
|
|
}
|
|
|
|
model DeprecatedUserSubscription {
|
|
id Int @id @default(autoincrement()) @db.Integer
|
|
userId String @map("user_id") @db.VarChar
|
|
plan String @db.VarChar(20)
|
|
// yearly/monthly/lifetime
|
|
recurring String @db.VarChar(20)
|
|
// onetime subscription or anything else
|
|
variant String? @db.VarChar(20)
|
|
// subscription.id, null for lifetime payment or one time payment subscription
|
|
stripeSubscriptionId String? @unique @map("stripe_subscription_id")
|
|
// subscription.status, active/past_due/canceled/unpaid...
|
|
status String @db.VarChar(20)
|
|
// subscription.current_period_start
|
|
start DateTime @map("start") @db.Timestamptz(3)
|
|
// subscription.current_period_end, null for lifetime payment
|
|
end DateTime? @map("end") @db.Timestamptz(3)
|
|
// subscription.billing_cycle_anchor
|
|
nextBillAt DateTime? @map("next_bill_at") @db.Timestamptz(3)
|
|
// subscription.canceled_at
|
|
canceledAt DateTime? @map("canceled_at") @db.Timestamptz(3)
|
|
// subscription.trial_start
|
|
trialStart DateTime? @map("trial_start") @db.Timestamptz(3)
|
|
// subscription.trial_end
|
|
trialEnd DateTime? @map("trial_end") @db.Timestamptz(3)
|
|
stripeScheduleId String? @map("stripe_schedule_id") @db.VarChar
|
|
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
|
|
@@unique([userId, plan])
|
|
@@map("user_subscriptions")
|
|
}
|
|
|
|
model DeprecatedUserInvoice {
|
|
id Int @id @default(autoincrement()) @db.Integer
|
|
userId String @map("user_id") @db.VarChar
|
|
stripeInvoiceId String @unique @map("stripe_invoice_id")
|
|
currency String @db.VarChar(3)
|
|
// CNY 12.50 stored as 1250
|
|
amount Int @db.Integer
|
|
status String @db.VarChar(20)
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
// billing reason
|
|
reason String? @db.VarChar
|
|
lastPaymentError String? @map("last_payment_error") @db.Text
|
|
// stripe hosted invoice link
|
|
link String? @db.Text
|
|
|
|
// @deprecated
|
|
plan String? @db.VarChar(20)
|
|
// @deprecated
|
|
recurring String? @db.VarChar(20)
|
|
|
|
@@index([userId])
|
|
@@map("user_invoices")
|
|
}
|
|
|
|
model UserStripeCustomer {
|
|
userId String @id @map("user_id") @db.VarChar
|
|
stripeCustomerId String @unique @map("stripe_customer_id") @db.VarChar
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("user_stripe_customers")
|
|
}
|
|
|
|
model Subscription {
|
|
id Int @id @default(autoincrement()) @db.Integer
|
|
targetId String @map("target_id") @db.VarChar
|
|
plan String @db.VarChar(20)
|
|
// yearly/monthly/lifetime
|
|
recurring String @db.VarChar(20)
|
|
// onetime subscription or anything else
|
|
variant String? @db.VarChar(20)
|
|
quantity Int @default(1) @db.Integer
|
|
// subscription.id, null for lifetime payment or one time payment subscription
|
|
stripeSubscriptionId String? @unique @map("stripe_subscription_id")
|
|
// stripe schedule id
|
|
stripeScheduleId String? @map("stripe_schedule_id") @db.VarChar
|
|
// subscription.status, active/past_due/canceled/unpaid...
|
|
status String @db.VarChar(20)
|
|
// subscription.current_period_start
|
|
start DateTime @map("start") @db.Timestamptz(3)
|
|
// subscription.current_period_end, null for lifetime payment
|
|
end DateTime? @map("end") @db.Timestamptz(3)
|
|
// subscription.billing_cycle_anchor
|
|
nextBillAt DateTime? @map("next_bill_at") @db.Timestamptz(3)
|
|
// subscription.canceled_at
|
|
canceledAt DateTime? @map("canceled_at") @db.Timestamptz(3)
|
|
// subscription.trial_start
|
|
trialStart DateTime? @map("trial_start") @db.Timestamptz(3)
|
|
// subscription.trial_end
|
|
trialEnd DateTime? @map("trial_end") @db.Timestamptz(3)
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
|
|
@@unique([targetId, plan])
|
|
@@map("subscriptions")
|
|
}
|
|
|
|
model Invoice {
|
|
stripeInvoiceId String @id @map("stripe_invoice_id")
|
|
targetId String @map("target_id") @db.VarChar
|
|
currency String @db.VarChar(3)
|
|
// CNY 12.50 stored as 1250
|
|
amount Int @db.Integer
|
|
status String @db.VarChar(20)
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
// billing reason
|
|
reason String? @db.VarChar
|
|
lastPaymentError String? @map("last_payment_error") @db.Text
|
|
// stripe hosted invoice link
|
|
link String? @db.Text
|
|
// whether the onetime subscription has been redeemed
|
|
onetimeSubscriptionRedeemed Boolean @default(false) @map("onetime_subscription_redeemed")
|
|
|
|
@@index([targetId])
|
|
@@map("invoices")
|
|
}
|
|
|
|
model License {
|
|
key String @id @map("key") @db.VarChar
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
revealedAt DateTime? @map("revealed_at") @db.Timestamptz(3)
|
|
installedAt DateTime? @map("installed_at") @db.Timestamptz(3)
|
|
validateKey String? @map("validate_key") @db.VarChar
|
|
|
|
@@map("licenses")
|
|
}
|
|
|
|
model InstalledLicense {
|
|
key String @id @map("key") @db.VarChar
|
|
workspaceId String @unique @map("workspace_id") @db.VarChar
|
|
quantity Int @default(1) @db.Integer
|
|
recurring String @db.VarChar
|
|
installedAt DateTime @default(now()) @map("installed_at") @db.Timestamptz(3)
|
|
validateKey String @map("validate_key") @db.VarChar
|
|
validatedAt DateTime @map("validated_at") @db.Timestamptz(3)
|
|
expiredAt DateTime? @map("expired_at") @db.Timestamptz(3)
|
|
|
|
@@map("installed_licenses")
|
|
}
|
|
|
|
// Blob table only exists for fast non-data queries.
|
|
// like, total size of blobs in a workspace, or blob list for sync service.
|
|
// it should only be a map of metadata of blobs stored anywhere else
|
|
model Blob {
|
|
workspaceId String @map("workspace_id") @db.VarChar
|
|
key String @db.VarChar
|
|
size Int @db.Integer
|
|
mime String @db.VarChar
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
deletedAt DateTime? @map("deleted_at") @db.Timestamptz(3)
|
|
|
|
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
|
|
|
@@id([workspaceId, key])
|
|
@@map("blobs")
|
|
}
|
|
|
|
enum NotificationType {
|
|
Mention
|
|
Invitation
|
|
InvitationAccepted
|
|
InvitationBlocked
|
|
InvitationRejected
|
|
InvitationReviewRequest
|
|
InvitationReviewApproved
|
|
InvitationReviewDeclined
|
|
}
|
|
|
|
enum NotificationLevel {
|
|
// Makes a sound and appears as a heads-up notification
|
|
High
|
|
// Makes a sound
|
|
Default
|
|
// Makes no sound
|
|
Low
|
|
Min
|
|
None
|
|
}
|
|
|
|
model Notification {
|
|
id String @id @default(uuid()) @db.VarChar
|
|
userId String @map("user_id") @db.VarChar
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
level NotificationLevel
|
|
read Boolean @default(false)
|
|
type NotificationType
|
|
body Json @db.JsonB
|
|
|
|
user User @relation(name: "user_notifications", fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
// for user notifications list, including read and unread, ordered by createdAt
|
|
@@index([userId, createdAt, read])
|
|
@@map("notifications")
|
|
}
|
|
|
|
model UserSettings {
|
|
userId String @id @map("user_id") @db.VarChar
|
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
|
payload Json @db.JsonB
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("user_settings")
|
|
}
|