Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
CREATE TABLE IF NOT EXISTS "workspace_admin_stats_daily" (
"workspace_id" VARCHAR NOT NULL,
"date" DATE NOT NULL,
"snapshot_size" BIGINT NOT NULL DEFAULT 0,
"blob_size" BIGINT NOT NULL DEFAULT 0,
"member_count" BIGINT NOT NULL DEFAULT 0,
"updated_at" TIMESTAMPTZ(3) NOT NULL DEFAULT NOW(),
CONSTRAINT "workspace_admin_stats_daily_pkey" PRIMARY KEY ("workspace_id", "date"),
CONSTRAINT "workspace_admin_stats_daily_workspace_id_fkey" FOREIGN KEY ("workspace_id") REFERENCES "workspaces"("id") ON DELETE CASCADE ON UPDATE CASCADE
);

CREATE INDEX IF NOT EXISTS "workspace_admin_stats_daily_date_idx" ON "workspace_admin_stats_daily" ("date");

CREATE TABLE IF NOT EXISTS "sync_active_users_minutely" (
"minute_ts" TIMESTAMPTZ(3) NOT NULL,
"active_users" INTEGER NOT NULL DEFAULT 0,
"updated_at" TIMESTAMPTZ(3) NOT NULL DEFAULT NOW(),
CONSTRAINT "sync_active_users_minutely_pkey" PRIMARY KEY ("minute_ts")
);

CREATE TABLE IF NOT EXISTS "workspace_doc_view_daily" (
"workspace_id" VARCHAR NOT NULL,
"doc_id" VARCHAR NOT NULL,
"date" DATE NOT NULL,
"total_views" BIGINT NOT NULL DEFAULT 0,
"unique_views" BIGINT NOT NULL DEFAULT 0,
"guest_views" BIGINT NOT NULL DEFAULT 0,
"last_accessed_at" TIMESTAMPTZ(3),
"updated_at" TIMESTAMPTZ(3) NOT NULL DEFAULT NOW(),
CONSTRAINT "workspace_doc_view_daily_pkey" PRIMARY KEY ("workspace_id", "doc_id", "date"),
CONSTRAINT "workspace_doc_view_daily_workspace_id_fkey" FOREIGN KEY ("workspace_id") REFERENCES "workspaces"("id") ON DELETE CASCADE ON UPDATE CASCADE
);

CREATE INDEX IF NOT EXISTS "workspace_doc_view_daily_workspace_id_date_idx" ON "workspace_doc_view_daily" ("workspace_id", "date");

CREATE TABLE IF NOT EXISTS "workspace_member_last_access" (
"workspace_id" VARCHAR NOT NULL,
"user_id" VARCHAR NOT NULL,
"last_accessed_at" TIMESTAMPTZ(3) NOT NULL,
"last_doc_id" VARCHAR,
"updated_at" TIMESTAMPTZ(3) NOT NULL DEFAULT NOW(),
CONSTRAINT "workspace_member_last_access_pkey" PRIMARY KEY ("workspace_id", "user_id"),
CONSTRAINT "workspace_member_last_access_workspace_id_fkey" FOREIGN KEY ("workspace_id") REFERENCES "workspaces"("id") ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT "workspace_member_last_access_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE
);

CREATE INDEX IF NOT EXISTS "workspace_member_last_access_workspace_id_last_accessed_at_idx" ON "workspace_member_last_access" ("workspace_id", "last_accessed_at" DESC);

CREATE INDEX IF NOT EXISTS "workspace_member_last_access_workspace_id_last_doc_id_idx" ON "workspace_member_last_access" ("workspace_id", "last_doc_id");

CREATE INDEX IF NOT EXISTS "workspace_pages_public_published_at_idx" ON "workspace_pages" ("public", "published_at");

CREATE INDEX IF NOT EXISTS "ai_sessions_messages_created_at_role_idx" ON "ai_sessions_messages" ("created_at", "role");

DROP TRIGGER IF EXISTS user_features_set_feature_id ON "user_features";

DROP TRIGGER IF EXISTS workspace_features_set_feature_id ON "workspace_features";

DROP FUNCTION IF EXISTS set_user_feature_id_from_name();

DROP FUNCTION IF EXISTS set_workspace_feature_id_from_name();

DROP FUNCTION IF EXISTS ensure_feature_exists(TEXT);

ALTER TABLE
"user_features" DROP CONSTRAINT "user_features_feature_id_fkey";

ALTER TABLE
"workspace_features" DROP CONSTRAINT "workspace_features_feature_id_fkey";

DROP INDEX "user_features_feature_id_idx";

DROP INDEX "workspace_features_feature_id_idx";

ALTER TABLE
"user_features" DROP COLUMN "feature_id";

ALTER TABLE
"workspace_features" DROP COLUMN "feature_id";

DROP TABLE "features";
108 changes: 85 additions & 23 deletions packages/backend/server/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,32 @@ model User {
registered Boolean @default(true)
disabled Boolean @default(false)

features UserFeature[]
userStripeCustomer UserStripeCustomer?
workspaces WorkspaceUserRole[]
features UserFeature[]
userStripeCustomer UserStripeCustomer?
workspaces WorkspaceUserRole[]
// Invite others to join the workspace
WorkspaceInvitations WorkspaceUserRole[] @relation("inviter")
docPermissions WorkspaceDocUserRole[]
connectedAccounts ConnectedAccount[]
calendarAccounts CalendarAccount[]
sessions UserSession[]
aiSessions AiSession[]
appConfigs AppConfig[]
userSnapshots UserSnapshot[]
createdSnapshot Snapshot[] @relation("createdSnapshot")
updatedSnapshot Snapshot[] @relation("updatedSnapshot")
createdUpdate Update[] @relation("createdUpdate")
createdHistory SnapshotHistory[] @relation("createdHistory")
createdAiJobs AiJobs[] @relation("createdAiJobs")
WorkspaceInvitations WorkspaceUserRole[] @relation("inviter")
docPermissions WorkspaceDocUserRole[]
connectedAccounts ConnectedAccount[]
calendarAccounts CalendarAccount[]
sessions UserSession[]
aiSessions AiSession[]
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?
comments Comment[]
replies Reply[]
commentAttachments CommentAttachment[] @relation("createdCommentAttachments")
AccessToken AccessToken[]
workspaceCalendars WorkspaceCalendar[]
notifications Notification[] @relation("user_notifications")
settings UserSettings?
comments Comment[]
replies Reply[]
commentAttachments CommentAttachment[] @relation("createdCommentAttachments")
AccessToken AccessToken[]
workspaceCalendars WorkspaceCalendar[]
workspaceMemberLastAccesses WorkspaceMemberLastAccess[]

@@index([email])
@@map("users")
Expand Down Expand Up @@ -151,6 +152,9 @@ model Workspace {
workspaceCalendars WorkspaceCalendar[]
workspaceAdminStats WorkspaceAdminStats[]
workspaceAdminStatsDirties WorkspaceAdminStatsDirty[]
workspaceAdminStatsDaily WorkspaceAdminStatsDaily[]
workspaceDocViewDaily WorkspaceDocViewDaily[]
workspaceMemberLastAccess WorkspaceMemberLastAccess[]

@@index([lastCheckEmbeddings])
@@index([createdAt])
Expand Down Expand Up @@ -180,6 +184,7 @@ model WorkspaceDoc {

@@id([workspaceId, docId])
@@index([workspaceId, public])
@@index([public, publishedAt])
@@map("workspace_pages")
}

Expand Down Expand Up @@ -320,6 +325,62 @@ model WorkspaceAdminStatsDirty {
@@map("workspace_admin_stats_dirty")
}

model WorkspaceAdminStatsDaily {
workspaceId String @map("workspace_id") @db.VarChar
date DateTime @db.Date
snapshotSize BigInt @default(0) @map("snapshot_size") @db.BigInt
blobSize BigInt @default(0) @map("blob_size") @db.BigInt
memberCount BigInt @default(0) @map("member_count") @db.BigInt
updatedAt DateTime @default(now()) @map("updated_at") @db.Timestamptz(3)

workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)

@@id([workspaceId, date])
@@index([date])
@@map("workspace_admin_stats_daily")
}

model SyncActiveUsersMinutely {
minuteTs DateTime @id @map("minute_ts") @db.Timestamptz(3)
activeUsers Int @default(0) @map("active_users") @db.Integer
updatedAt DateTime @default(now()) @map("updated_at") @db.Timestamptz(3)

@@map("sync_active_users_minutely")
}

model WorkspaceDocViewDaily {
workspaceId String @map("workspace_id") @db.VarChar
docId String @map("doc_id") @db.VarChar
date DateTime @db.Date
totalViews BigInt @default(0) @map("total_views") @db.BigInt
uniqueViews BigInt @default(0) @map("unique_views") @db.BigInt
guestViews BigInt @default(0) @map("guest_views") @db.BigInt
lastAccessedAt DateTime? @map("last_accessed_at") @db.Timestamptz(3)
updatedAt DateTime @default(now()) @map("updated_at") @db.Timestamptz(3)

workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)

@@id([workspaceId, docId, date])
@@index([workspaceId, date])
@@map("workspace_doc_view_daily")
}

model WorkspaceMemberLastAccess {
workspaceId String @map("workspace_id") @db.VarChar
userId String @map("user_id") @db.VarChar
lastAccessedAt DateTime @map("last_accessed_at") @db.Timestamptz(3)
lastDocId String? @map("last_doc_id") @db.VarChar
updatedAt DateTime @default(now()) @map("updated_at") @db.Timestamptz(3)

workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)

@@id([workspaceId, userId])
@@index([workspaceId, lastAccessedAt(sort: Desc)])
@@index([workspaceId, lastDocId])
@@map("workspace_member_last_access")
}

// the latest snapshot of each doc that we've seen
// Snapshot + Updates are the latest state of the doc
model Snapshot {
Expand Down Expand Up @@ -456,6 +517,7 @@ model AiSessionMessage {
session AiSession @relation(fields: [sessionId], references: [id], onDelete: Cascade)

@@index([sessionId])
@@index([createdAt, role])
@@map("ai_sessions_messages")
}

Expand Down
Loading
Loading