Skip to content

Commit bc87ba6

Browse files
Add onboarding status to Project model and implement related database migrations
- Introduced `onboardingStatus` field to the Project model with a default value of "completed". - Created migration scripts to add the new column and validate its values against predefined statuses. - Updated relevant queries and components to handle the new onboarding status in project creation and updates. - Enhanced tests to ensure proper functionality of the onboarding status feature.
1 parent a2e2de0 commit bc87ba6

15 files changed

Lines changed: 1952 additions & 160 deletions

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
ALTER TABLE "Project"
2+
ADD COLUMN "onboardingStatus" TEXT NOT NULL DEFAULT 'completed';
3+
4+
ALTER TABLE "Project"
5+
ADD CONSTRAINT "Project_onboardingStatus_valid"
6+
CHECK (
7+
"onboardingStatus" IN (
8+
'config_choice',
9+
'apps_selection',
10+
'auth_setup',
11+
'domain_setup',
12+
'email_theme_setup',
13+
'payments_setup',
14+
'completed'
15+
)
16+
) NOT VALID;
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { randomUUID } from "crypto";
2+
import type { Sql } from "postgres";
3+
import { expect } from "vitest";
4+
5+
export const preMigration = async (sql: Sql) => {
6+
const projectId = `test-${randomUUID()}`;
7+
await sql`
8+
INSERT INTO "Project" ("id", "createdAt", "updatedAt", "displayName", "description", "isProductionMode")
9+
VALUES (${projectId}, NOW(), NOW(), 'Onboarding Test', '', false)
10+
`;
11+
return { projectId };
12+
};
13+
14+
export const postMigration = async (sql: Sql, ctx: Awaited<ReturnType<typeof preMigration>>) => {
15+
const rows = await sql`
16+
SELECT "onboardingStatus"
17+
FROM "Project"
18+
WHERE "id" = ${ctx.projectId}
19+
`;
20+
expect(rows).toHaveLength(1);
21+
expect(rows[0].onboardingStatus).toBe("completed");
22+
23+
const validProjectId = `test-${randomUUID()}`;
24+
await sql`
25+
INSERT INTO "Project" (
26+
"id",
27+
"createdAt",
28+
"updatedAt",
29+
"displayName",
30+
"description",
31+
"isProductionMode",
32+
"onboardingStatus"
33+
)
34+
VALUES (${validProjectId}, NOW(), NOW(), 'Valid Status Project', '', false, 'auth_setup')
35+
`;
36+
37+
const invalidProjectId = `test-${randomUUID()}`;
38+
await expect(sql`
39+
INSERT INTO "Project" (
40+
"id",
41+
"createdAt",
42+
"updatedAt",
43+
"displayName",
44+
"description",
45+
"isProductionMode",
46+
"onboardingStatus"
47+
)
48+
VALUES (${invalidProjectId}, NOW(), NOW(), 'Invalid Status Project', '', false, 'invalid_status')
49+
`).rejects.toThrow(/Project_onboardingStatus_valid/);
50+
};
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ALTER TABLE "Project"
2+
VALIDATE CONSTRAINT "Project_onboardingStatus_valid";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import type { Sql } from "postgres";
2+
import { expect } from "vitest";
3+
4+
export const postMigration = async (sql: Sql) => {
5+
const rows = await sql`
6+
SELECT "convalidated"
7+
FROM "pg_constraint"
8+
WHERE "conname" = 'Project_onboardingStatus_valid'
9+
`;
10+
11+
expect(rows).toHaveLength(1);
12+
expect(rows[0].convalidated).toBe(true);
13+
};

apps/backend/prisma/schema.prisma

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ model Project {
2626
description String @default("")
2727
isProductionMode Boolean
2828
ownerTeamId String? @db.Uuid
29+
onboardingStatus String @default("completed")
2930
3031
logoUrl String?
3132
logoFullUrl String?

apps/backend/src/lib/projects.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ export function getProjectQuery(projectId: string): RawQuery<Promise<Omit<Projec
6666
created_at_millis: new Date(row.createdAt + "Z").getTime(),
6767
is_production_mode: row.isProductionMode,
6868
owner_team_id: row.ownerTeamId,
69+
onboarding_status: row.onboardingStatus,
6970
};
7071
},
7172
};
@@ -119,6 +120,14 @@ export async function createOrUpdateProjectWithLegacyConfig(
119120
},
120121
});
121122

123+
if (options.data.onboarding_status !== undefined) {
124+
await tx.$executeRaw`
125+
UPDATE "Project"
126+
SET "onboardingStatus" = ${options.data.onboarding_status}
127+
WHERE "id" = ${project.id}
128+
`;
129+
}
130+
122131
await tx.tenancy.create({
123132
data: {
124133
projectId: project.id,
@@ -152,6 +161,14 @@ export async function createOrUpdateProjectWithLegacyConfig(
152161
logoFullDarkModeUrl: logoUrls['logo_full_dark_mode_url'],
153162
},
154163
});
164+
165+
if (options.data.onboarding_status !== undefined) {
166+
await tx.$executeRaw`
167+
UPDATE "Project"
168+
SET "onboardingStatus" = ${options.data.onboarding_status}
169+
WHERE "id" = ${project.id}
170+
`;
171+
}
155172
branchId = options.branchId;
156173
}
157174

0 commit comments

Comments
 (0)