mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-04-02 07:03:45 +00:00
feat(id): brand ProjectID through Drizzle and Zod schemas (#16948)
This commit is contained in:
@@ -8,6 +8,7 @@ import path from "path"
|
||||
import fs from "fs/promises"
|
||||
import { pathToFileURL } from "url"
|
||||
import { Global } from "../../src/global"
|
||||
import { ProjectID } from "../../src/project/schema"
|
||||
import { Filesystem } from "../../src/util/filesystem"
|
||||
|
||||
// Get managed config directory from environment (set in preload.ts)
|
||||
@@ -44,7 +45,7 @@ async function check(map: (dir: string) => string) {
|
||||
const cfg = await Config.get()
|
||||
expect(cfg.snapshot).toBe(true)
|
||||
expect(Instance.directory).toBe(Filesystem.resolve(tmp.path))
|
||||
expect(Instance.project.id).not.toBe("global")
|
||||
expect(Instance.project.id).not.toBe(ProjectID.global)
|
||||
},
|
||||
})
|
||||
} finally {
|
||||
|
||||
@@ -6,6 +6,7 @@ import path from "path"
|
||||
import { tmpdir } from "../fixture/fixture"
|
||||
import { Filesystem } from "../../src/util/filesystem"
|
||||
import { GlobalBus } from "../../src/bus/global"
|
||||
import { ProjectID } from "../../src/project/schema"
|
||||
|
||||
Log.init({ print: false })
|
||||
|
||||
@@ -74,7 +75,7 @@ describe("Project.fromDirectory", () => {
|
||||
const { project } = await p.fromDirectory(tmp.path)
|
||||
|
||||
expect(project).toBeDefined()
|
||||
expect(project.id).toBe("global")
|
||||
expect(project.id).toBe(ProjectID.global)
|
||||
expect(project.vcs).toBe("git")
|
||||
expect(project.worktree).toBe(tmp.path)
|
||||
|
||||
@@ -90,7 +91,7 @@ describe("Project.fromDirectory", () => {
|
||||
const { project } = await p.fromDirectory(tmp.path)
|
||||
|
||||
expect(project).toBeDefined()
|
||||
expect(project.id).not.toBe("global")
|
||||
expect(project.id).not.toBe(ProjectID.global)
|
||||
expect(project.vcs).toBe("git")
|
||||
expect(project.worktree).toBe(tmp.path)
|
||||
|
||||
@@ -107,7 +108,7 @@ describe("Project.fromDirectory", () => {
|
||||
await withMode("rev-list-fail", async () => {
|
||||
const { project } = await p.fromDirectory(tmp.path)
|
||||
expect(project.vcs).toBe("git")
|
||||
expect(project.id).toBe("global")
|
||||
expect(project.id).toBe(ProjectID.global)
|
||||
expect(project.worktree).toBe(tmp.path)
|
||||
})
|
||||
})
|
||||
@@ -301,7 +302,7 @@ describe("Project.update", () => {
|
||||
|
||||
await expect(
|
||||
Project.update({
|
||||
projectID: "nonexistent-project-id",
|
||||
projectID: ProjectID.make("nonexistent-project-id"),
|
||||
name: "Should Fail",
|
||||
}),
|
||||
).rejects.toThrow("Project not found: nonexistent-project-id")
|
||||
|
||||
@@ -8,6 +8,7 @@ import { readFileSync, readdirSync } from "fs"
|
||||
import { JsonMigration } from "../../src/storage/json-migration"
|
||||
import { Global } from "../../src/global"
|
||||
import { ProjectTable } from "../../src/project/project.sql"
|
||||
import { ProjectID } from "../../src/project/schema"
|
||||
import { SessionTable, MessageTable, PartTable, TodoTable, PermissionTable } from "../../src/session/session.sql"
|
||||
import { SessionShareTable } from "../../src/share/share.sql"
|
||||
|
||||
@@ -123,7 +124,7 @@ describe("JSON to SQLite migration", () => {
|
||||
const db = drizzle({ client: sqlite })
|
||||
const projects = db.select().from(ProjectTable).all()
|
||||
expect(projects.length).toBe(1)
|
||||
expect(projects[0].id).toBe("proj_test123abc")
|
||||
expect(projects[0].id).toBe(ProjectID.make("proj_test123abc"))
|
||||
expect(projects[0].worktree).toBe("/test/path")
|
||||
expect(projects[0].name).toBe("Test Project")
|
||||
expect(projects[0].sandboxes).toEqual(["/test/sandbox"])
|
||||
@@ -148,7 +149,7 @@ describe("JSON to SQLite migration", () => {
|
||||
const db = drizzle({ client: sqlite })
|
||||
const projects = db.select().from(ProjectTable).all()
|
||||
expect(projects.length).toBe(1)
|
||||
expect(projects[0].id).toBe("proj_filename") // Uses filename, not JSON id
|
||||
expect(projects[0].id).toBe(ProjectID.make("proj_filename")) // Uses filename, not JSON id
|
||||
})
|
||||
|
||||
test("migrates project with commands", async () => {
|
||||
@@ -169,7 +170,7 @@ describe("JSON to SQLite migration", () => {
|
||||
const db = drizzle({ client: sqlite })
|
||||
const projects = db.select().from(ProjectTable).all()
|
||||
expect(projects.length).toBe(1)
|
||||
expect(projects[0].id).toBe("proj_with_commands")
|
||||
expect(projects[0].id).toBe(ProjectID.make("proj_with_commands"))
|
||||
expect(projects[0].commands).toEqual({ start: "npm run dev" })
|
||||
})
|
||||
|
||||
@@ -190,7 +191,7 @@ describe("JSON to SQLite migration", () => {
|
||||
const db = drizzle({ client: sqlite })
|
||||
const projects = db.select().from(ProjectTable).all()
|
||||
expect(projects.length).toBe(1)
|
||||
expect(projects[0].id).toBe("proj_no_commands")
|
||||
expect(projects[0].id).toBe(ProjectID.make("proj_no_commands"))
|
||||
expect(projects[0].commands).toBeNull()
|
||||
})
|
||||
|
||||
@@ -220,7 +221,7 @@ describe("JSON to SQLite migration", () => {
|
||||
const sessions = db.select().from(SessionTable).all()
|
||||
expect(sessions.length).toBe(1)
|
||||
expect(sessions[0].id).toBe("ses_test456def")
|
||||
expect(sessions[0].project_id).toBe("proj_test123abc")
|
||||
expect(sessions[0].project_id).toBe(ProjectID.make("proj_test123abc"))
|
||||
expect(sessions[0].slug).toBe("test-session")
|
||||
expect(sessions[0].title).toBe("Test Session Title")
|
||||
expect(sessions[0].summary_additions).toBe(10)
|
||||
@@ -426,7 +427,7 @@ describe("JSON to SQLite migration", () => {
|
||||
const sessions = db.select().from(SessionTable).all()
|
||||
expect(sessions.length).toBe(1)
|
||||
expect(sessions[0].id).toBe("ses_migrated")
|
||||
expect(sessions[0].project_id).toBe(gitBasedProjectID) // Uses directory, not stale JSON
|
||||
expect(sessions[0].project_id).toBe(ProjectID.make(gitBasedProjectID)) // Uses directory, not stale JSON
|
||||
})
|
||||
|
||||
test("uses filename for session id when JSON has different value", async () => {
|
||||
@@ -458,7 +459,7 @@ describe("JSON to SQLite migration", () => {
|
||||
const sessions = db.select().from(SessionTable).all()
|
||||
expect(sessions.length).toBe(1)
|
||||
expect(sessions[0].id).toBe("ses_from_filename") // Uses filename, not JSON id
|
||||
expect(sessions[0].project_id).toBe("proj_test123abc")
|
||||
expect(sessions[0].project_id).toBe(ProjectID.make("proj_test123abc"))
|
||||
})
|
||||
|
||||
test("is idempotent (running twice doesn't duplicate)", async () => {
|
||||
@@ -643,7 +644,7 @@ describe("JSON to SQLite migration", () => {
|
||||
const db = drizzle({ client: sqlite })
|
||||
const projects = db.select().from(ProjectTable).all()
|
||||
expect(projects.length).toBe(1)
|
||||
expect(projects[0].id).toBe("proj_test123abc")
|
||||
expect(projects[0].id).toBe(ProjectID.make("proj_test123abc"))
|
||||
})
|
||||
|
||||
test("skips invalid todo entries while preserving source positions", async () => {
|
||||
|
||||
Reference in New Issue
Block a user