Skip to content

Commit 75dd71a

Browse files
author
Sprite
committed
fix: preserve Personal project ownership
1 parent ff986b2 commit 75dd71a

2 files changed

Lines changed: 34 additions & 0 deletions

File tree

packages/models/src/project.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,18 @@ export class Project extends DBModel {
314314
id: string,
315315
fields: Partial<{ name: string; kind: string; thread_id: string }>
316316
): Promise<Project | null> {
317+
const existing = await Project.findOwned(userId, id);
318+
if (!existing) return null;
319+
// Personal is a permanent account space. Keep its marker immutable, and
320+
// do not let a named project be converted into the reserved kind.
321+
if (
322+
fields.kind !== undefined &&
323+
fields.kind !== existing.kind &&
324+
(existing.kind === PERSONAL_PROJECT_KIND ||
325+
fields.kind === PERSONAL_PROJECT_KIND)
326+
) {
327+
return null;
328+
}
317329
const db = getDb();
318330
const rows = await db
319331
.update(projects)

packages/models/tests/project.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,28 @@ describe("Project model", () => {
108108
expect(updated!.updated_at > "2020-01-01T00:00:00.000Z").toBe(true);
109109
});
110110

111+
it("keeps Personal permanently personal", async () => {
112+
const personal = await Project.ensurePersonal("u1");
113+
expect(
114+
await Project.updateOwned("u1", personal.id, { kind: "campaign" })
115+
).toBeNull();
116+
expect((await Project.findById(personal.id))?.kind).toBe(
117+
PERSONAL_PROJECT_KIND
118+
);
119+
120+
const named = await Project.create<Project>({
121+
user_id: "u1",
122+
name: "Campaign",
123+
kind: "campaign"
124+
});
125+
expect(
126+
await Project.updateOwned("u1", named.id, {
127+
kind: PERSONAL_PROJECT_KIND
128+
})
129+
).toBeNull();
130+
expect((await Project.findById(named.id))?.kind).toBe("campaign");
131+
});
132+
111133
it("deletes the project and moves its documents back to the loose bucket", async () => {
112134
const project = await Project.create<Project>({ user_id: "u1", name: "Aurora" });
113135
const board = await Storyboard.create<Storyboard>({

0 commit comments

Comments
 (0)