From 875d4cfd58fd7a12610fb48596253b23a4f94d67 Mon Sep 17 00:00:00 2001 From: Harish V Date: Thu, 25 Jul 2024 23:18:33 +0800 Subject: [PATCH 1/7] add migration for versions --- .../studio/prisma/generated/generatedTypes.ts | 10 +++++- .../prisma/generated/selectableTypes.ts | 1 + .../20240725140719_add_versions/migration.sql | 35 +++++++++++++++++++ apps/studio/prisma/schema.prisma | 35 ++++++++++++------- apps/studio/prisma/seed.ts | 6 ++-- .../server/modules/folder/folder.router.ts | 2 +- .../src/server/modules/page/page.router.ts | 2 +- .../modules/resource/resource.service.ts | 7 ++-- .../server/modules/resource/resource.types.ts | 3 +- apps/studio/tests/msw/handlers/page.ts | 10 +++--- 10 files changed, 82 insertions(+), 29 deletions(-) create mode 100644 apps/studio/prisma/migrations/20240725140719_add_versions/migration.sql diff --git a/apps/studio/prisma/generated/generatedTypes.ts b/apps/studio/prisma/generated/generatedTypes.ts index fc0130e34..b8ef53380 100644 --- a/apps/studio/prisma/generated/generatedTypes.ts +++ b/apps/studio/prisma/generated/generatedTypes.ts @@ -46,7 +46,7 @@ export interface Resource { permalink: string siteId: number parentId: string | null - mainBlobId: string | null + versionId: string | null draftBlobId: string | null state: Generated type: ResourceType @@ -77,6 +77,13 @@ export interface VerificationToken { attempts: Generated expires: Timestamp } +export interface Version { + id: GeneratedAlways + versionNum: string + resourceId: string + blobId: string + publishedAt: Generated +} export interface DB { Blob: Blob Footer: Footer @@ -87,4 +94,5 @@ export interface DB { SiteMember: SiteMember User: User VerificationToken: VerificationToken + Version: Version } diff --git a/apps/studio/prisma/generated/selectableTypes.ts b/apps/studio/prisma/generated/selectableTypes.ts index 558f14bb1..1bca01e5c 100644 --- a/apps/studio/prisma/generated/selectableTypes.ts +++ b/apps/studio/prisma/generated/selectableTypes.ts @@ -12,3 +12,4 @@ export type Site = Selectable export type SiteMember = Selectable export type User = Selectable export type VerificationToken = Selectable +export type Version = Selectable diff --git a/apps/studio/prisma/migrations/20240725140719_add_versions/migration.sql b/apps/studio/prisma/migrations/20240725140719_add_versions/migration.sql new file mode 100644 index 000000000..f59c6e856 --- /dev/null +++ b/apps/studio/prisma/migrations/20240725140719_add_versions/migration.sql @@ -0,0 +1,35 @@ +/* + Warnings: + + - You are about to drop the column `mainBlobId` on the `Resource` table. All the data in the column will be lost. + +*/ +-- DropForeignKey +ALTER TABLE "Resource" DROP CONSTRAINT "Resource_mainBlobId_fkey"; + +-- DropIndex +DROP INDEX "Resource_mainBlobId_key"; + +-- AlterTable +ALTER TABLE "Resource" DROP COLUMN "mainBlobId", +ADD COLUMN "versionId" BIGINT; + +-- CreateTable +CREATE TABLE "Version" ( + "id" BIGSERIAL NOT NULL, + "versionNum" BIGINT NOT NULL, + "resourceId" BIGINT NOT NULL, + "blobId" BIGINT NOT NULL, + "publishedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "Version_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "Version_resourceId_key" ON "Version"("resourceId"); + +-- AddForeignKey +ALTER TABLE "Version" ADD CONSTRAINT "Version_resourceId_fkey" FOREIGN KEY ("resourceId") REFERENCES "Resource"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Version" ADD CONSTRAINT "Version_blobId_fkey" FOREIGN KEY ("blobId") REFERENCES "Blob"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/apps/studio/prisma/schema.prisma b/apps/studio/prisma/schema.prisma index 66d0b3e65..b2a454166 100644 --- a/apps/studio/prisma/schema.prisma +++ b/apps/studio/prisma/schema.prisma @@ -33,6 +33,16 @@ model VerificationToken { expires DateTime } +model Version { + id BigInt @id @default(autoincrement()) + versionNum BigInt + resourceId BigInt @unique + resource Resource @relation("CurrentVersion", fields: [resourceId], references: [id]) + blobId BigInt + blob Blob @relation(fields: [blobId], references: [id]) + publishedAt DateTime @default(now()) +} + model Resource { id BigInt @id @default(autoincrement()) title String @@ -46,16 +56,25 @@ model Resource { permission Permission[] - mainBlob Blob? @relation("MainBlob", fields: [mainBlobId], references: [id]) - mainBlobId BigInt? @unique + versionId BigInt? + version Version? @relation("CurrentVersion") - draftBlob Blob? @relation("DraftBlob", fields: [draftBlobId], references: [id]) draftBlobId BigInt? @unique + draftBlob Blob? @relation(fields: [draftBlobId], references: [id]) state ResourceState? @default(Draft) type ResourceType } +model Blob { + id BigInt @id @default(autoincrement()) + /// @kyselyType(PrismaJson.BlobJsonContent) + /// [BlobJsonContent] + content Json + versions Version[] + draftResource Resource? +} + enum ResourceState { Draft Published @@ -124,16 +143,6 @@ model Footer { content Json } -model Blob { - id BigInt @id @default(autoincrement()) - /// @kyselyType(PrismaJson.BlobJsonContent) - /// [BlobJsonContent] - content Json - - mainResource Resource? @relation("MainBlob") - draftResource Resource? @relation("DraftBlob") -} - model SiteMember { userId String user User @relation(fields: [userId], references: [id]) diff --git a/apps/studio/prisma/seed.ts b/apps/studio/prisma/seed.ts index 66f3f4aeb..997fd3e77 100644 --- a/apps/studio/prisma/seed.ts +++ b/apps/studio/prisma/seed.ts @@ -223,7 +223,7 @@ async function main() { await db .insertInto("Resource") .values({ - mainBlobId: String(blobId), + draftBlobId: String(blobId), permalink: "home", siteId, type: "Page", @@ -232,8 +232,8 @@ async function main() { .onConflict((oc) => oc - .column("mainBlobId") - .doUpdateSet((eb) => ({ mainBlobId: eb.ref("excluded.mainBlobId") })), + .column("draftBlobId") + .doUpdateSet((eb) => ({ draftBlobId: eb.ref("excluded.draftBlobId") })), ) .executeTakeFirstOrThrow() diff --git a/apps/studio/src/server/modules/folder/folder.router.ts b/apps/studio/src/server/modules/folder/folder.router.ts index 31596044a..e2e949b27 100644 --- a/apps/studio/src/server/modules/folder/folder.router.ts +++ b/apps/studio/src/server/modules/folder/folder.router.ts @@ -26,7 +26,7 @@ export const folderRouter = router({ .where("parentId", "=", String(input.resourceId)) .execute() const children = childrenResult.map((c) => { - if (c.draftBlobId || c.mainBlobId) { + if (c.draftBlobId || c.versionId) { return { id: c.id, permalink: c.permalink, diff --git a/apps/studio/src/server/modules/page/page.router.ts b/apps/studio/src/server/modules/page/page.router.ts index cf3dec0c2..566723d1f 100644 --- a/apps/studio/src/server/modules/page/page.router.ts +++ b/apps/studio/src/server/modules/page/page.router.ts @@ -78,7 +78,7 @@ export const pageRouter = router({ "Resource.id", "Resource.permalink", "Resource.title", - "Resource.mainBlobId", + "Resource.versionId", "Resource.draftBlobId", "Resource.type", ]) diff --git a/apps/studio/src/server/modules/resource/resource.service.ts b/apps/studio/src/server/modules/resource/resource.service.ts index f4d616142..abdbaa9ac 100644 --- a/apps/studio/src/server/modules/resource/resource.service.ts +++ b/apps/studio/src/server/modules/resource/resource.service.ts @@ -12,7 +12,7 @@ const defaultResourceSelect: SelectExpression[] = [ "Resource.permalink", "Resource.siteId", "Resource.parentId", - "Resource.mainBlobId", + "Resource.versionId", "Resource.draftBlobId", "Resource.type", "Resource.state", @@ -89,8 +89,9 @@ export const getFullPageById = async ( } return getById(tx, args) - .where("Resource.mainBlobId", "is not", null) - .innerJoin("Blob", "Resource.mainBlobId", "Blob.id") + .where("Resource.versionId", "is not", null) + .innerJoin("Version", "Resource.versionId", "Version.id") + .innerJoin("Blob", "Version.blobId", "Blob.id") .select(defaultResourceWithBlobSelect) .forUpdate() .executeTakeFirst() diff --git a/apps/studio/src/server/modules/resource/resource.types.ts b/apps/studio/src/server/modules/resource/resource.types.ts index 8e9c7227a..4a7a0b2d6 100644 --- a/apps/studio/src/server/modules/resource/resource.types.ts +++ b/apps/studio/src/server/modules/resource/resource.types.ts @@ -2,7 +2,6 @@ import { type IsomerPageSchemaType, type IsomerSiteProps, } from "@opengovsg/isomer-components" -import { type SetRequired } from "type-fest" import type { Resource } from "~server/db" @@ -12,7 +11,7 @@ export type PageContent = Omit< > // TODO: Technically mainBlobId is not required before 1st publish -export type Page = SetRequired +export type Page = Resource export interface Navbar { items: IsomerSiteProps["navBarItems"] diff --git a/apps/studio/tests/msw/handlers/page.ts b/apps/studio/tests/msw/handlers/page.ts index 898ecdd6c..1c6b841fd 100644 --- a/apps/studio/tests/msw/handlers/page.ts +++ b/apps/studio/tests/msw/handlers/page.ts @@ -13,23 +13,23 @@ const pageListQuery = (wait?: DelayMode | number) => { id: "4", permalink: "test-page-1", title: "Test page 1", - mainBlobId: "3", - draftBlobId: null, + versionId: null, + draftBlobId: "3", type: "Page", }, { id: "5", permalink: "test-page-2", title: "Test page 2", - mainBlobId: "4", - draftBlobId: null, + versionId: null, + draftBlobId: "4", type: "Page", }, { id: "6", permalink: "folder", title: "Test folder 1", - mainBlobId: null, + versionId: null, draftBlobId: null, type: "Folder", }, From 72de6df2ed833f887e7bfb958b305bd40d17eb48 Mon Sep 17 00:00:00 2001 From: Harish V Date: Sun, 28 Jul 2024 20:17:07 +0800 Subject: [PATCH 2/7] update version resource relations --- .../studio/prisma/generated/generatedEnums.ts | 26 +-- .../studio/prisma/generated/generatedTypes.ts | 190 +++++++++--------- .../migration.sql | 7 +- apps/studio/prisma/schema.prisma | 12 +- 4 files changed, 115 insertions(+), 120 deletions(-) rename apps/studio/prisma/migrations/{20240725140719_add_versions => 20240728121558_add_versions}/migration.sql (77%) diff --git a/apps/studio/prisma/generated/generatedEnums.ts b/apps/studio/prisma/generated/generatedEnums.ts index 341006ab5..db2053dcf 100644 --- a/apps/studio/prisma/generated/generatedEnums.ts +++ b/apps/studio/prisma/generated/generatedEnums.ts @@ -1,16 +1,16 @@ export const ResourceState = { - Draft: "Draft", - Published: "Published", -} as const -export type ResourceState = (typeof ResourceState)[keyof typeof ResourceState] + Draft: "Draft", + Published: "Published" +} as const; +export type ResourceState = (typeof ResourceState)[keyof typeof ResourceState]; export const ResourceType = { - Page: "Page", - Folder: "Folder", -} as const -export type ResourceType = (typeof ResourceType)[keyof typeof ResourceType] + Page: "Page", + Folder: "Folder" +} as const; +export type ResourceType = (typeof ResourceType)[keyof typeof ResourceType]; export const RoleType = { - Admin: "Admin", - Editor: "Editor", - Publisher: "Publisher", -} as const -export type RoleType = (typeof RoleType)[keyof typeof RoleType] + Admin: "Admin", + Editor: "Editor", + Publisher: "Publisher" +} as const; +export type RoleType = (typeof RoleType)[keyof typeof RoleType]; diff --git a/apps/studio/prisma/generated/generatedTypes.ts b/apps/studio/prisma/generated/generatedTypes.ts index b8ef53380..520721098 100644 --- a/apps/studio/prisma/generated/generatedTypes.ts +++ b/apps/studio/prisma/generated/generatedTypes.ts @@ -1,98 +1,96 @@ -import type { ColumnType, GeneratedAlways } from "kysely" +import type { ColumnType, GeneratedAlways } from "kysely"; +export type Generated = T extends ColumnType + ? ColumnType + : ColumnType; +export type Timestamp = ColumnType; -import type { ResourceState, ResourceType, RoleType } from "./generatedEnums" +import type { ResourceState, ResourceType, RoleType } from "./generatedEnums"; -export type Generated = - T extends ColumnType - ? ColumnType - : ColumnType -export type Timestamp = ColumnType - -export interface Blob { - id: GeneratedAlways - /** - * @kyselyType(PrismaJson.BlobJsonContent) - * [BlobJsonContent] - */ - content: PrismaJson.BlobJsonContent -} -export interface Footer { - id: GeneratedAlways - siteId: number - /** - * @kyselyType(PrismaJson.FooterJsonContent) - * [FooterJsonContent] - */ - content: PrismaJson.FooterJsonContent -} -export interface Navbar { - id: GeneratedAlways - siteId: number - /** - * @kyselyType(PrismaJson.NavbarJsonContent) - * [NavbarJsonContent] - */ - content: PrismaJson.NavbarJsonContent -} -export interface Permission { - id: GeneratedAlways - resourceId: string - userId: string - role: RoleType -} -export interface Resource { - id: GeneratedAlways - title: string - permalink: string - siteId: number - parentId: string | null - versionId: string | null - draftBlobId: string | null - state: Generated - type: ResourceType -} -export interface Site { - id: GeneratedAlways - name: string - /** - * @kyselyType(PrismaJson.SiteJsonConfig) - * [SiteJsonConfig] - */ - config: PrismaJson.SiteJsonConfig -} -export interface SiteMember { - userId: string - siteId: number -} -export interface User { - id: string - name: string - email: string - phone: string - preferredName: string | null -} -export interface VerificationToken { - identifier: string - token: string - attempts: Generated - expires: Timestamp -} -export interface Version { - id: GeneratedAlways - versionNum: string - resourceId: string - blobId: string - publishedAt: Generated -} -export interface DB { - Blob: Blob - Footer: Footer - Navbar: Navbar - Permission: Permission - Resource: Resource - Site: Site - SiteMember: SiteMember - User: User - VerificationToken: VerificationToken - Version: Version -} +export type Blob = { + id: GeneratedAlways; + /** + * @kyselyType(PrismaJson.BlobJsonContent) + * [BlobJsonContent] + */ + content: PrismaJson.BlobJsonContent; +}; +export type Footer = { + id: GeneratedAlways; + siteId: number; + /** + * @kyselyType(PrismaJson.FooterJsonContent) + * [FooterJsonContent] + */ + content: PrismaJson.FooterJsonContent; +}; +export type Navbar = { + id: GeneratedAlways; + siteId: number; + /** + * @kyselyType(PrismaJson.NavbarJsonContent) + * [NavbarJsonContent] + */ + content: PrismaJson.NavbarJsonContent; +}; +export type Permission = { + id: GeneratedAlways; + resourceId: string; + userId: string; + role: RoleType; +}; +export type Resource = { + id: GeneratedAlways; + title: string; + permalink: string; + siteId: number; + parentId: string | null; + versionId: string | null; + draftBlobId: string | null; + state: Generated; + type: ResourceType; +}; +export type Site = { + id: GeneratedAlways; + name: string; + /** + * @kyselyType(PrismaJson.SiteJsonConfig) + * [SiteJsonConfig] + */ + config: PrismaJson.SiteJsonConfig; +}; +export type SiteMember = { + userId: string; + siteId: number; +}; +export type User = { + id: string; + name: string; + email: string; + phone: string; + preferredName: string | null; +}; +export type VerificationToken = { + identifier: string; + token: string; + attempts: Generated; + expires: Timestamp; +}; +export type Version = { + id: GeneratedAlways; + versionNum: string; + resourceId: string; + blobId: string; + publishedAt: Generated; +}; +export type DB = { + Blob: Blob; + Footer: Footer; + Navbar: Navbar; + Permission: Permission; + Resource: Resource; + Site: Site; + SiteMember: SiteMember; + User: User; + VerificationToken: VerificationToken; + Version: Version; +}; diff --git a/apps/studio/prisma/migrations/20240725140719_add_versions/migration.sql b/apps/studio/prisma/migrations/20240728121558_add_versions/migration.sql similarity index 77% rename from apps/studio/prisma/migrations/20240725140719_add_versions/migration.sql rename to apps/studio/prisma/migrations/20240728121558_add_versions/migration.sql index f59c6e856..44cc76a1a 100644 --- a/apps/studio/prisma/migrations/20240725140719_add_versions/migration.sql +++ b/apps/studio/prisma/migrations/20240728121558_add_versions/migration.sql @@ -25,11 +25,8 @@ CREATE TABLE "Version" ( CONSTRAINT "Version_pkey" PRIMARY KEY ("id") ); --- CreateIndex -CREATE UNIQUE INDEX "Version_resourceId_key" ON "Version"("resourceId"); - -- AddForeignKey -ALTER TABLE "Version" ADD CONSTRAINT "Version_resourceId_fkey" FOREIGN KEY ("resourceId") REFERENCES "Resource"("id") ON DELETE RESTRICT ON UPDATE CASCADE; +ALTER TABLE "Version" ADD CONSTRAINT "Version_blobId_fkey" FOREIGN KEY ("blobId") REFERENCES "Blob"("id") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "Version" ADD CONSTRAINT "Version_blobId_fkey" FOREIGN KEY ("blobId") REFERENCES "Blob"("id") ON DELETE RESTRICT ON UPDATE CASCADE; +ALTER TABLE "Resource" ADD CONSTRAINT "Resource_versionId_fkey" FOREIGN KEY ("versionId") REFERENCES "Version"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/apps/studio/prisma/schema.prisma b/apps/studio/prisma/schema.prisma index b2a454166..aa8483c29 100644 --- a/apps/studio/prisma/schema.prisma +++ b/apps/studio/prisma/schema.prisma @@ -34,13 +34,13 @@ model VerificationToken { } model Version { - id BigInt @id @default(autoincrement()) + id BigInt @id @default(autoincrement()) versionNum BigInt - resourceId BigInt @unique - resource Resource @relation("CurrentVersion", fields: [resourceId], references: [id]) + resourceId BigInt + resources Resource[] blobId BigInt - blob Blob @relation(fields: [blobId], references: [id]) - publishedAt DateTime @default(now()) + blob Blob @relation(fields: [blobId], references: [id]) + publishedAt DateTime @default(now()) } model Resource { @@ -57,7 +57,7 @@ model Resource { permission Permission[] versionId BigInt? - version Version? @relation("CurrentVersion") + version Version? @relation(fields: [versionId], references: [id]) draftBlobId BigInt? @unique draftBlob Blob? @relation(fields: [draftBlobId], references: [id]) From e153fb2cad668b00a1fd5c0fd9e9a12c64671787 Mon Sep 17 00:00:00 2001 From: Harish V Date: Mon, 29 Jul 2024 15:51:51 +0800 Subject: [PATCH 3/7] update schema --- apps/studio/prisma/generated/generatedTypes.ts | 5 +++-- .../migration.sql | 14 +++++++++++--- apps/studio/prisma/schema.prisma | 9 ++++++--- 3 files changed, 20 insertions(+), 8 deletions(-) rename apps/studio/prisma/migrations/{20240728121558_add_versions => 20240729075103_add_versions}/migration.sql (51%) diff --git a/apps/studio/prisma/generated/generatedTypes.ts b/apps/studio/prisma/generated/generatedTypes.ts index 520721098..73a445186 100644 --- a/apps/studio/prisma/generated/generatedTypes.ts +++ b/apps/studio/prisma/generated/generatedTypes.ts @@ -44,7 +44,7 @@ export type Resource = { permalink: string; siteId: number; parentId: string | null; - versionId: string | null; + publishedVersionId: string | null; draftBlobId: string | null; state: Generated; type: ResourceType; @@ -77,10 +77,11 @@ export type VerificationToken = { }; export type Version = { id: GeneratedAlways; - versionNum: string; + versionNum: number; resourceId: string; blobId: string; publishedAt: Generated; + publishedBy: string; }; export type DB = { Blob: Blob; diff --git a/apps/studio/prisma/migrations/20240728121558_add_versions/migration.sql b/apps/studio/prisma/migrations/20240729075103_add_versions/migration.sql similarity index 51% rename from apps/studio/prisma/migrations/20240728121558_add_versions/migration.sql rename to apps/studio/prisma/migrations/20240729075103_add_versions/migration.sql index 44cc76a1a..3bcbb5b00 100644 --- a/apps/studio/prisma/migrations/20240728121558_add_versions/migration.sql +++ b/apps/studio/prisma/migrations/20240729075103_add_versions/migration.sql @@ -2,6 +2,7 @@ Warnings: - You are about to drop the column `mainBlobId` on the `Resource` table. All the data in the column will be lost. + - A unique constraint covering the columns `[publishedVersionId]` on the table `Resource` will be added. If there are existing duplicate values, this will fail. */ -- DropForeignKey @@ -12,21 +13,28 @@ DROP INDEX "Resource_mainBlobId_key"; -- AlterTable ALTER TABLE "Resource" DROP COLUMN "mainBlobId", -ADD COLUMN "versionId" BIGINT; +ADD COLUMN "publishedVersionId" BIGINT; -- CreateTable CREATE TABLE "Version" ( "id" BIGSERIAL NOT NULL, - "versionNum" BIGINT NOT NULL, + "versionNum" INTEGER NOT NULL, "resourceId" BIGINT NOT NULL, "blobId" BIGINT NOT NULL, "publishedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "publishedBy" TEXT NOT NULL, CONSTRAINT "Version_pkey" PRIMARY KEY ("id") ); +-- CreateIndex +CREATE UNIQUE INDEX "Resource_publishedVersionId_key" ON "Resource"("publishedVersionId"); + -- AddForeignKey ALTER TABLE "Version" ADD CONSTRAINT "Version_blobId_fkey" FOREIGN KEY ("blobId") REFERENCES "Blob"("id") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "Resource" ADD CONSTRAINT "Resource_versionId_fkey" FOREIGN KEY ("versionId") REFERENCES "Version"("id") ON DELETE SET NULL ON UPDATE CASCADE; +ALTER TABLE "Version" ADD CONSTRAINT "Version_publishedBy_fkey" FOREIGN KEY ("publishedBy") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Resource" ADD CONSTRAINT "Resource_publishedVersionId_fkey" FOREIGN KEY ("publishedVersionId") REFERENCES "Version"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/apps/studio/prisma/schema.prisma b/apps/studio/prisma/schema.prisma index aa8483c29..b800df5cb 100644 --- a/apps/studio/prisma/schema.prisma +++ b/apps/studio/prisma/schema.prisma @@ -35,12 +35,14 @@ model VerificationToken { model Version { id BigInt @id @default(autoincrement()) - versionNum BigInt + versionNum Int resourceId BigInt resources Resource[] blobId BigInt blob Blob @relation(fields: [blobId], references: [id]) publishedAt DateTime @default(now()) + publishedBy String + publisher User @relation(fields: [publishedBy], references: [id]) } model Resource { @@ -56,8 +58,8 @@ model Resource { permission Permission[] - versionId BigInt? - version Version? @relation(fields: [versionId], references: [id]) + publishedVersionId BigInt? @unique + version Version? @relation(fields: [publishedVersionId], references: [id]) draftBlobId BigInt? @unique draftBlob Blob? @relation(fields: [draftBlobId], references: [id]) @@ -94,6 +96,7 @@ model User { permission Permission[] siteMembers SiteMember[] + Version Version[] } model Permission { From 32e2e40aab67ff5e55261fcdf5e8b1a10201bf56 Mon Sep 17 00:00:00 2001 From: Harish V Date: Mon, 29 Jul 2024 16:06:50 +0800 Subject: [PATCH 4/7] update schema --- .../migration.sql | 3 +++ apps/studio/prisma/schema.prisma | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) rename apps/studio/prisma/migrations/{20240729075103_add_versions => 20240729080623_add_versions}/migration.sql (94%) diff --git a/apps/studio/prisma/migrations/20240729075103_add_versions/migration.sql b/apps/studio/prisma/migrations/20240729080623_add_versions/migration.sql similarity index 94% rename from apps/studio/prisma/migrations/20240729075103_add_versions/migration.sql rename to apps/studio/prisma/migrations/20240729080623_add_versions/migration.sql index 3bcbb5b00..568f48414 100644 --- a/apps/studio/prisma/migrations/20240729075103_add_versions/migration.sql +++ b/apps/studio/prisma/migrations/20240729080623_add_versions/migration.sql @@ -27,6 +27,9 @@ CREATE TABLE "Version" ( CONSTRAINT "Version_pkey" PRIMARY KEY ("id") ); +-- CreateIndex +CREATE UNIQUE INDEX "Version_blobId_key" ON "Version"("blobId"); + -- CreateIndex CREATE UNIQUE INDEX "Resource_publishedVersionId_key" ON "Resource"("publishedVersionId"); diff --git a/apps/studio/prisma/schema.prisma b/apps/studio/prisma/schema.prisma index b800df5cb..f9a511bf7 100644 --- a/apps/studio/prisma/schema.prisma +++ b/apps/studio/prisma/schema.prisma @@ -38,7 +38,7 @@ model Version { versionNum Int resourceId BigInt resources Resource[] - blobId BigInt + blobId BigInt @unique blob Blob @relation(fields: [blobId], references: [id]) publishedAt DateTime @default(now()) publishedBy String @@ -73,8 +73,8 @@ model Blob { /// @kyselyType(PrismaJson.BlobJsonContent) /// [BlobJsonContent] content Json - versions Version[] draftResource Resource? + version Version? } enum ResourceState { From 67a946430a2a983ac25ab3110ad06c5579ccdcdb Mon Sep 17 00:00:00 2001 From: Harish V Date: Wed, 31 Jul 2024 14:37:58 +0800 Subject: [PATCH 5/7] fix type issues --- apps/studio/src/server/modules/page/page.router.ts | 2 +- .../server/modules/resource/resource.service.ts | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/studio/src/server/modules/page/page.router.ts b/apps/studio/src/server/modules/page/page.router.ts index 566723d1f..50d9f8d3e 100644 --- a/apps/studio/src/server/modules/page/page.router.ts +++ b/apps/studio/src/server/modules/page/page.router.ts @@ -78,7 +78,7 @@ export const pageRouter = router({ "Resource.id", "Resource.permalink", "Resource.title", - "Resource.versionId", + "Resource.publishedVersionId", "Resource.draftBlobId", "Resource.type", ]) diff --git a/apps/studio/src/server/modules/resource/resource.service.ts b/apps/studio/src/server/modules/resource/resource.service.ts index abdbaa9ac..b6250fb2b 100644 --- a/apps/studio/src/server/modules/resource/resource.service.ts +++ b/apps/studio/src/server/modules/resource/resource.service.ts @@ -1,4 +1,4 @@ -import type { SelectExpression, Transaction } from "kysely" +import type { SelectExpression } from "kysely" import { type DB } from "~prisma/generated/generatedTypes" import type { SafeKysely } from "../database" @@ -12,7 +12,7 @@ const defaultResourceSelect: SelectExpression[] = [ "Resource.permalink", "Resource.siteId", "Resource.parentId", - "Resource.versionId", + "Resource.publishedVersionId", "Resource.draftBlobId", "Resource.type", "Resource.state", @@ -69,14 +69,14 @@ const getById = ( // NOTE: Throw here to fail early if our invariant that a page has a `blobId` is violated export const getFullPageById = async ( - tx: Transaction, + db: SafeKysely, args: { resourceId: number siteId: number }, ) => { // Check if draft blob exists and return that preferentially - const draftBlob = await getById(tx, args) + const draftBlob = await getById(db, args) .where("Resource.draftBlobId", "is not", null) .innerJoin("Blob", "Resource.draftBlobId", "Blob.id") .select(defaultResourceWithBlobSelect) @@ -88,9 +88,9 @@ export const getFullPageById = async ( return draftBlob } - return getById(tx, args) - .where("Resource.versionId", "is not", null) - .innerJoin("Version", "Resource.versionId", "Version.id") + return getById(db, args) + .where("Resource.publishedVersionId", "is not", null) + .innerJoin("Version", "Resource.publishedVersionId", "Version.id") .innerJoin("Blob", "Version.blobId", "Blob.id") .select(defaultResourceWithBlobSelect) .forUpdate() From 428ba7372783356defca23c397680c46fdb1dcdd Mon Sep 17 00:00:00 2001 From: Harish V Date: Wed, 31 Jul 2024 14:46:03 +0800 Subject: [PATCH 6/7] address pr comments --- .../migration.sql | 0 apps/studio/prisma/schema.prisma | 4 ++-- apps/studio/src/server/modules/folder/folder.router.ts | 2 +- apps/studio/src/server/modules/resource/resource.types.ts | 1 - apps/studio/tests/msw/handlers/page.ts | 6 +++--- 5 files changed, 6 insertions(+), 7 deletions(-) rename apps/studio/prisma/migrations/{20240729080623_add_versions => 20240731063902_add_versions}/migration.sql (100%) diff --git a/apps/studio/prisma/migrations/20240729080623_add_versions/migration.sql b/apps/studio/prisma/migrations/20240731063902_add_versions/migration.sql similarity index 100% rename from apps/studio/prisma/migrations/20240729080623_add_versions/migration.sql rename to apps/studio/prisma/migrations/20240731063902_add_versions/migration.sql diff --git a/apps/studio/prisma/schema.prisma b/apps/studio/prisma/schema.prisma index f9a511bf7..9c8dcaae6 100644 --- a/apps/studio/prisma/schema.prisma +++ b/apps/studio/prisma/schema.prisma @@ -59,7 +59,7 @@ model Resource { permission Permission[] publishedVersionId BigInt? @unique - version Version? @relation(fields: [publishedVersionId], references: [id]) + publishedVersion Version? @relation(fields: [publishedVersionId], references: [id]) draftBlobId BigInt? @unique draftBlob Blob? @relation(fields: [draftBlobId], references: [id]) @@ -96,7 +96,7 @@ model User { permission Permission[] siteMembers SiteMember[] - Version Version[] + versions Version[] } model Permission { diff --git a/apps/studio/src/server/modules/folder/folder.router.ts b/apps/studio/src/server/modules/folder/folder.router.ts index e2e949b27..5a7188fc1 100644 --- a/apps/studio/src/server/modules/folder/folder.router.ts +++ b/apps/studio/src/server/modules/folder/folder.router.ts @@ -26,7 +26,7 @@ export const folderRouter = router({ .where("parentId", "=", String(input.resourceId)) .execute() const children = childrenResult.map((c) => { - if (c.draftBlobId || c.versionId) { + if (c.draftBlobId || c.publishedVersionId) { return { id: c.id, permalink: c.permalink, diff --git a/apps/studio/src/server/modules/resource/resource.types.ts b/apps/studio/src/server/modules/resource/resource.types.ts index 4a7a0b2d6..c8d0549f9 100644 --- a/apps/studio/src/server/modules/resource/resource.types.ts +++ b/apps/studio/src/server/modules/resource/resource.types.ts @@ -10,7 +10,6 @@ export type PageContent = Omit< "layout" | "LinkComponent" | "ScriptComponent" > -// TODO: Technically mainBlobId is not required before 1st publish export type Page = Resource export interface Navbar { diff --git a/apps/studio/tests/msw/handlers/page.ts b/apps/studio/tests/msw/handlers/page.ts index 1c6b841fd..6d8c3e123 100644 --- a/apps/studio/tests/msw/handlers/page.ts +++ b/apps/studio/tests/msw/handlers/page.ts @@ -13,7 +13,7 @@ const pageListQuery = (wait?: DelayMode | number) => { id: "4", permalink: "test-page-1", title: "Test page 1", - versionId: null, + publishedVersionId: null, draftBlobId: "3", type: "Page", }, @@ -21,7 +21,7 @@ const pageListQuery = (wait?: DelayMode | number) => { id: "5", permalink: "test-page-2", title: "Test page 2", - versionId: null, + publishedVersionId: null, draftBlobId: "4", type: "Page", }, @@ -29,7 +29,7 @@ const pageListQuery = (wait?: DelayMode | number) => { id: "6", permalink: "folder", title: "Test folder 1", - versionId: null, + publishedVersionId: null, draftBlobId: null, type: "Folder", }, From 26d6de3c79d82d753bc915b2d4565f9a56b01d01 Mon Sep 17 00:00:00 2001 From: Harish V Date: Wed, 31 Jul 2024 15:04:22 +0800 Subject: [PATCH 7/7] minor schema update --- .../migration.sql | 0 apps/studio/prisma/schema.prisma | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename apps/studio/prisma/migrations/{20240731063902_add_versions => 20240731070336_add_versions}/migration.sql (100%) diff --git a/apps/studio/prisma/migrations/20240731063902_add_versions/migration.sql b/apps/studio/prisma/migrations/20240731070336_add_versions/migration.sql similarity index 100% rename from apps/studio/prisma/migrations/20240731063902_add_versions/migration.sql rename to apps/studio/prisma/migrations/20240731070336_add_versions/migration.sql diff --git a/apps/studio/prisma/schema.prisma b/apps/studio/prisma/schema.prisma index 9c8dcaae6..95636578d 100644 --- a/apps/studio/prisma/schema.prisma +++ b/apps/studio/prisma/schema.prisma @@ -94,7 +94,7 @@ model User { phone String preferredName String? - permission Permission[] + permissions Permission[] siteMembers SiteMember[] versions Version[] }