Skip to content
Closed
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
6 changes: 6 additions & 0 deletions packages/database/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.1.0] - 2026-05-29

### Added

- Add template version persistence tables and exported Prisma types for draft and published form versioning.

## [1.0.9] - 2026-05-11

- Update AWS SDK packages to latest versions
Expand Down
2 changes: 1 addition & 1 deletion packages/database/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@gcforms/database",
"version": "1.0.9",
"version": "1.1.0",
"author": "Canadian Digital Service",
"license": "MIT",
"publishConfig": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
-- CreateEnum
CREATE TYPE "TemplateVersionStatus" AS ENUM ('DRAFT', 'PUBLISHED', 'SUPERSEDED');

-- AlterTable
ALTER TABLE "Template" ADD COLUMN "currentPublishedVersionId" TEXT;
ALTER TABLE "Template" ADD COLUMN "currentDraftVersionId" TEXT;

-- CreateTable
CREATE TABLE "TemplateVersion" (
"id" TEXT NOT NULL,
"templateId" TEXT NOT NULL,
"versionNumber" INTEGER NOT NULL,
"status" "TemplateVersionStatus" NOT NULL,
"jsonConfig" JSONB NOT NULL,
"createdAt" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(6) NOT NULL,
"publishedAt" TIMESTAMPTZ(6),
"supersededAt" TIMESTAMPTZ(6),
"createdByUserId" TEXT,
"publishedByUserId" TEXT,
"publishReason" TEXT NOT NULL DEFAULT '',
"publishFormType" TEXT NOT NULL DEFAULT '',
"publishDesc" TEXT NOT NULL DEFAULT '',

CONSTRAINT "TemplateVersion_pkey" PRIMARY KEY ("id")
);

-- Backfill each existing template into an initial version record. Runtime code
-- continues to read Template.jsonConfig until follow-up work switches over.
INSERT INTO "TemplateVersion" (
"id",
"templateId",
"versionNumber",
"status",
"jsonConfig",
"createdAt",
"updatedAt",
"publishedAt",
"publishReason",
"publishFormType",
"publishDesc"
)
SELECT
'tv_' || "id",
"id",
1,
CASE WHEN "isPublished" THEN 'PUBLISHED'::"TemplateVersionStatus" ELSE 'DRAFT'::"TemplateVersionStatus" END,
"jsonConfig",
"created_at",
"updated_at",
CASE WHEN "isPublished" THEN "updated_at" ELSE NULL END,
"publishReason",
"publishFormType",
"publishDesc"
FROM "Template";

UPDATE "Template"
SET "currentPublishedVersionId" = 'tv_' || "id"
WHERE "isPublished" = true;

UPDATE "Template"
SET "currentDraftVersionId" = 'tv_' || "id"
WHERE "isPublished" = false;

-- CreateIndex
CREATE UNIQUE INDEX "Template_currentPublishedVersionId_key" ON "Template"("currentPublishedVersionId");
CREATE UNIQUE INDEX "Template_currentDraftVersionId_key" ON "Template"("currentDraftVersionId");
CREATE INDEX "TemplateVersion_templateId_status_idx" ON "TemplateVersion"("templateId", "status");
CREATE UNIQUE INDEX "TemplateVersion_templateId_versionNumber_key" ON "TemplateVersion"("templateId", "versionNumber");

-- AddForeignKey
ALTER TABLE "TemplateVersion" ADD CONSTRAINT "TemplateVersion_templateId_fkey" FOREIGN KEY ("templateId") REFERENCES "Template"("id") ON DELETE CASCADE ON UPDATE NO ACTION;
ALTER TABLE "Template" ADD CONSTRAINT "Template_currentPublishedVersionId_fkey" FOREIGN KEY ("currentPublishedVersionId") REFERENCES "TemplateVersion"("id") ON DELETE SET NULL ON UPDATE NO ACTION;
ALTER TABLE "Template" ADD CONSTRAINT "Template_currentDraftVersionId_fkey" FOREIGN KEY ("currentDraftVersionId") REFERENCES "TemplateVersion"("id") ON DELETE SET NULL ON UPDATE NO ACTION;
36 changes: 35 additions & 1 deletion packages/database/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ model Template {
name String @default("")
jsonConfig Json
isPublished Boolean @default(false)
currentPublishedVersionId String? @unique
currentDraftVersionId String? @unique
currentPublishedVersion TemplateVersion? @relation("CurrentPublishedVersion", fields: [currentPublishedVersionId], references: [id], onDelete: SetNull, onUpdate: NoAction)
currentDraftVersion TemplateVersion? @relation("CurrentDraftVersion", fields: [currentDraftVersionId], references: [id], onDelete: SetNull, onUpdate: NoAction)
versions TemplateVersion[] @relation("TemplateVersions")
formPurpose String @default("")
publishReason String @default("")
publishFormType String @default("")
Expand All @@ -72,6 +77,35 @@ model Template {
notificationsUsers User[] @relation("TemplateNotificationsUsers")
}

model TemplateVersion {
id String @id @default(cuid())
templateId String
versionNumber Int
status TemplateVersionStatus
jsonConfig Json
createdAt DateTime @default(now()) @db.Timestamptz(6)
updatedAt DateTime @updatedAt @db.Timestamptz(6)
publishedAt DateTime? @db.Timestamptz(6)
supersededAt DateTime? @db.Timestamptz(6)
createdByUserId String?
publishedByUserId String?
publishReason String @default("")
publishFormType String @default("")
publishDesc String @default("")
template Template @relation("TemplateVersions", fields: [templateId], references: [id], onDelete: Cascade, onUpdate: NoAction)
currentPublishedFor Template? @relation("CurrentPublishedVersion")
currentDraftFor Template? @relation("CurrentDraftVersion")

@@unique([templateId, versionNumber])
@@index([templateId, status])
}

enum TemplateVersionStatus {
DRAFT
PUBLISHED
SUPERSEDED
}

model DeliveryOption {
id String @id @default(cuid())
emailAddress String
Expand Down Expand Up @@ -180,4 +214,4 @@ model UserFeature {
user User @relation(fields: [userId], references: [id], onDelete: Cascade)

@@unique([userId, feature])
}
}
2 changes: 2 additions & 0 deletions packages/database/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export {
type ApiServiceAccount,
type Session,
type Template,
type TemplateVersion,
TemplateVersionStatus,
type DeliveryOption,
type Privilege,
type User,
Expand Down
Loading