sync
This commit is contained in:
parent
cd174d8cba
commit
19a41ab297
6 changed files with 139 additions and 53 deletions
|
|
@ -62,14 +62,13 @@ CREATE TABLE `session` (
|
||||||
--> statement-breakpoint
|
--> statement-breakpoint
|
||||||
CREATE TABLE `todo` (
|
CREATE TABLE `todo` (
|
||||||
`session_id` text NOT NULL,
|
`session_id` text NOT NULL,
|
||||||
`id` text NOT NULL,
|
|
||||||
`content` text NOT NULL,
|
`content` text NOT NULL,
|
||||||
`status` text NOT NULL,
|
`status` text NOT NULL,
|
||||||
`priority` text NOT NULL,
|
`priority` text NOT NULL,
|
||||||
`position` integer NOT NULL,
|
`position` integer NOT NULL,
|
||||||
`time_created` integer NOT NULL,
|
`time_created` integer NOT NULL,
|
||||||
`time_updated` integer NOT NULL,
|
`time_updated` integer NOT NULL,
|
||||||
CONSTRAINT `todo_pk` PRIMARY KEY(`session_id`, `id`),
|
CONSTRAINT `todo_pk` PRIMARY KEY(`session_id`, `position`),
|
||||||
CONSTRAINT `fk_todo_session_id_session_id_fk` FOREIGN KEY (`session_id`) REFERENCES `session`(`id`) ON DELETE CASCADE
|
CONSTRAINT `fk_todo_session_id_session_id_fk` FOREIGN KEY (`session_id`) REFERENCES `session`(`id`) ON DELETE CASCADE
|
||||||
);
|
);
|
||||||
--> statement-breakpoint
|
--> statement-breakpoint
|
||||||
|
|
@ -88,4 +87,4 @@ CREATE INDEX `part_message_idx` ON `part` (`message_id`);--> statement-breakpoin
|
||||||
CREATE INDEX `part_session_idx` ON `part` (`session_id`);--> statement-breakpoint
|
CREATE INDEX `part_session_idx` ON `part` (`session_id`);--> statement-breakpoint
|
||||||
CREATE INDEX `session_project_idx` ON `session` (`project_id`);--> statement-breakpoint
|
CREATE INDEX `session_project_idx` ON `session` (`project_id`);--> statement-breakpoint
|
||||||
CREATE INDEX `session_parent_idx` ON `session` (`parent_id`);--> statement-breakpoint
|
CREATE INDEX `session_parent_idx` ON `session` (`parent_id`);--> statement-breakpoint
|
||||||
CREATE INDEX `todo_session_idx` ON `todo` (`session_id`);
|
CREATE INDEX `todo_session_idx` ON `todo` (`session_id`);
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"version": "7",
|
"version": "7",
|
||||||
"dialect": "sqlite",
|
"dialect": "sqlite",
|
||||||
"id": "0e365b40-39c4-447f-9729-9714d865d8ff",
|
"id": "068758ed-a97a-46f6-8a59-6c639ae7c20c",
|
||||||
"prevIds": [
|
"prevIds": [
|
||||||
"00000000-0000-0000-0000-000000000000"
|
"00000000-0000-0000-0000-000000000000"
|
||||||
],
|
],
|
||||||
|
|
@ -160,7 +160,17 @@
|
||||||
"autoincrement": false,
|
"autoincrement": false,
|
||||||
"default": null,
|
"default": null,
|
||||||
"generated": null,
|
"generated": null,
|
||||||
"name": "created_at",
|
"name": "time_created",
|
||||||
|
"entityType": "columns",
|
||||||
|
"table": "message"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": null,
|
||||||
|
"generated": null,
|
||||||
|
"name": "time_updated",
|
||||||
"entityType": "columns",
|
"entityType": "columns",
|
||||||
"table": "message"
|
"table": "message"
|
||||||
},
|
},
|
||||||
|
|
@ -204,6 +214,26 @@
|
||||||
"entityType": "columns",
|
"entityType": "columns",
|
||||||
"table": "part"
|
"table": "part"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": null,
|
||||||
|
"generated": null,
|
||||||
|
"name": "time_created",
|
||||||
|
"entityType": "columns",
|
||||||
|
"table": "part"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": null,
|
||||||
|
"generated": null,
|
||||||
|
"name": "time_updated",
|
||||||
|
"entityType": "columns",
|
||||||
|
"table": "part"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
|
|
@ -224,6 +254,26 @@
|
||||||
"entityType": "columns",
|
"entityType": "columns",
|
||||||
"table": "permission"
|
"table": "permission"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": null,
|
||||||
|
"generated": null,
|
||||||
|
"name": "time_created",
|
||||||
|
"entityType": "columns",
|
||||||
|
"table": "permission"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": null,
|
||||||
|
"generated": null,
|
||||||
|
"name": "time_updated",
|
||||||
|
"entityType": "columns",
|
||||||
|
"table": "permission"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
|
|
@ -360,37 +410,7 @@
|
||||||
"autoincrement": false,
|
"autoincrement": false,
|
||||||
"default": null,
|
"default": null,
|
||||||
"generated": null,
|
"generated": null,
|
||||||
"name": "revert_message_id",
|
"name": "revert",
|
||||||
"entityType": "columns",
|
|
||||||
"table": "session"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "text",
|
|
||||||
"notNull": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"default": null,
|
|
||||||
"generated": null,
|
|
||||||
"name": "revert_part_id",
|
|
||||||
"entityType": "columns",
|
|
||||||
"table": "session"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "text",
|
|
||||||
"notNull": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"default": null,
|
|
||||||
"generated": null,
|
|
||||||
"name": "revert_snapshot",
|
|
||||||
"entityType": "columns",
|
|
||||||
"table": "session"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "text",
|
|
||||||
"notNull": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"default": null,
|
|
||||||
"generated": null,
|
|
||||||
"name": "revert_diff",
|
|
||||||
"entityType": "columns",
|
"entityType": "columns",
|
||||||
"table": "session"
|
"table": "session"
|
||||||
},
|
},
|
||||||
|
|
@ -454,16 +474,6 @@
|
||||||
"entityType": "columns",
|
"entityType": "columns",
|
||||||
"table": "todo"
|
"table": "todo"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "text",
|
|
||||||
"notNull": true,
|
|
||||||
"autoincrement": false,
|
|
||||||
"default": null,
|
|
||||||
"generated": null,
|
|
||||||
"name": "id",
|
|
||||||
"entityType": "columns",
|
|
||||||
"table": "todo"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"notNull": true,
|
"notNull": true,
|
||||||
|
|
@ -504,6 +514,26 @@
|
||||||
"entityType": "columns",
|
"entityType": "columns",
|
||||||
"table": "todo"
|
"table": "todo"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": null,
|
||||||
|
"generated": null,
|
||||||
|
"name": "time_created",
|
||||||
|
"entityType": "columns",
|
||||||
|
"table": "todo"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": null,
|
||||||
|
"generated": null,
|
||||||
|
"name": "time_updated",
|
||||||
|
"entityType": "columns",
|
||||||
|
"table": "todo"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"notNull": false,
|
"notNull": false,
|
||||||
|
|
@ -544,6 +574,26 @@
|
||||||
"entityType": "columns",
|
"entityType": "columns",
|
||||||
"table": "session_share"
|
"table": "session_share"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": null,
|
||||||
|
"generated": null,
|
||||||
|
"name": "time_created",
|
||||||
|
"entityType": "columns",
|
||||||
|
"table": "session_share"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": null,
|
||||||
|
"generated": null,
|
||||||
|
"name": "time_updated",
|
||||||
|
"entityType": "columns",
|
||||||
|
"table": "session_share"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"columns": [
|
"columns": [
|
||||||
"session_id"
|
"session_id"
|
||||||
|
|
@ -637,7 +687,7 @@
|
||||||
{
|
{
|
||||||
"columns": [
|
"columns": [
|
||||||
"session_id",
|
"session_id",
|
||||||
"id"
|
"position"
|
||||||
],
|
],
|
||||||
"nameExplicit": false,
|
"nameExplicit": false,
|
||||||
"name": "todo_pk",
|
"name": "todo_pk",
|
||||||
|
|
@ -67,14 +67,16 @@ export const TodoTable = sqliteTable(
|
||||||
session_id: text()
|
session_id: text()
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => SessionTable.id, { onDelete: "cascade" }),
|
.references(() => SessionTable.id, { onDelete: "cascade" }),
|
||||||
id: text().notNull(),
|
|
||||||
content: text().notNull(),
|
content: text().notNull(),
|
||||||
status: text().notNull(),
|
status: text().notNull(),
|
||||||
priority: text().notNull(),
|
priority: text().notNull(),
|
||||||
position: integer().notNull(),
|
position: integer().notNull(),
|
||||||
...Timestamps,
|
...Timestamps,
|
||||||
},
|
},
|
||||||
(table) => [primaryKey({ columns: [table.session_id, table.id] }), index("todo_session_idx").on(table.session_id)],
|
(table) => [
|
||||||
|
primaryKey({ columns: [table.session_id, table.position] }),
|
||||||
|
index("todo_session_idx").on(table.session_id),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
export const PermissionTable = sqliteTable("permission", {
|
export const PermissionTable = sqliteTable("permission", {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ export namespace Todo {
|
||||||
content: z.string().describe("Brief description of the task"),
|
content: z.string().describe("Brief description of the task"),
|
||||||
status: z.string().describe("Current status of the task: pending, in_progress, completed, cancelled"),
|
status: z.string().describe("Current status of the task: pending, in_progress, completed, cancelled"),
|
||||||
priority: z.string().describe("Priority level of the task: high, medium, low"),
|
priority: z.string().describe("Priority level of the task: high, medium, low"),
|
||||||
id: z.string().describe("Unique identifier for the todo item"),
|
|
||||||
})
|
})
|
||||||
.meta({ ref: "Todo" })
|
.meta({ ref: "Todo" })
|
||||||
export type Info = z.infer<typeof Info>
|
export type Info = z.infer<typeof Info>
|
||||||
|
|
@ -33,7 +32,6 @@ export namespace Todo {
|
||||||
.values(
|
.values(
|
||||||
input.todos.map((todo, position) => ({
|
input.todos.map((todo, position) => ({
|
||||||
session_id: input.sessionID,
|
session_id: input.sessionID,
|
||||||
id: todo.id,
|
|
||||||
content: todo.content,
|
content: todo.content,
|
||||||
status: todo.status,
|
status: todo.status,
|
||||||
priority: todo.priority,
|
priority: todo.priority,
|
||||||
|
|
@ -50,7 +48,6 @@ export namespace Todo {
|
||||||
db.select().from(TodoTable).where(eq(TodoTable.session_id, sessionID)).orderBy(asc(TodoTable.position)).all(),
|
db.select().from(TodoTable).where(eq(TodoTable.session_id, sessionID)).orderBy(asc(TodoTable.position)).all(),
|
||||||
)
|
)
|
||||||
return rows.map((row) => ({
|
return rows.map((row) => ({
|
||||||
id: row.id,
|
|
||||||
content: row.content,
|
content: row.content,
|
||||||
status: row.status,
|
status: row.status,
|
||||||
priority: row.priority,
|
priority: row.priority,
|
||||||
|
|
|
||||||
|
|
@ -235,14 +235,15 @@ export namespace JsonMigration {
|
||||||
}
|
}
|
||||||
for (let position = 0; position < data.length; position++) {
|
for (let position = 0; position < data.length; position++) {
|
||||||
const todo = data[position]
|
const todo = data[position]
|
||||||
if (!todo?.id || !todo?.content || !todo?.status || !todo?.priority) continue
|
if (!todo?.content || !todo?.status || !todo?.priority) continue
|
||||||
values.push({
|
values.push({
|
||||||
session_id: sessionID,
|
session_id: sessionID,
|
||||||
id: todo.id,
|
|
||||||
content: todo.content,
|
content: todo.content,
|
||||||
status: todo.status,
|
status: todo.status,
|
||||||
priority: todo.priority,
|
priority: todo.priority,
|
||||||
position,
|
position,
|
||||||
|
time_created: Date.now(),
|
||||||
|
time_updated: Date.now(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -282,17 +282,54 @@ describe("JSON to SQLite migration", () => {
|
||||||
expect(stats?.todos).toBe(2)
|
expect(stats?.todos).toBe(2)
|
||||||
|
|
||||||
const db = drizzle({ client: sqlite })
|
const db = drizzle({ client: sqlite })
|
||||||
const todos = db.select().from(TodoTable).all()
|
const todos = db.select().from(TodoTable).orderBy(TodoTable.position).all()
|
||||||
expect(todos.length).toBe(2)
|
expect(todos.length).toBe(2)
|
||||||
expect(todos[0].id).toBe("todo_1")
|
|
||||||
expect(todos[0].content).toBe("First todo")
|
expect(todos[0].content).toBe("First todo")
|
||||||
expect(todos[0].status).toBe("pending")
|
expect(todos[0].status).toBe("pending")
|
||||||
expect(todos[0].priority).toBe("high")
|
expect(todos[0].priority).toBe("high")
|
||||||
expect(todos[0].position).toBe(0)
|
expect(todos[0].position).toBe(0)
|
||||||
expect(todos[1].id).toBe("todo_2")
|
expect(todos[1].content).toBe("Second todo")
|
||||||
expect(todos[1].position).toBe(1)
|
expect(todos[1].position).toBe(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("todos are ordered by position", async () => {
|
||||||
|
await Bun.write(
|
||||||
|
path.join(storageDir, "project", "proj_test123abc.json"),
|
||||||
|
JSON.stringify({
|
||||||
|
id: "proj_test123abc",
|
||||||
|
worktree: "/",
|
||||||
|
time: { created: Date.now(), updated: Date.now() },
|
||||||
|
sandboxes: [],
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
await Bun.write(
|
||||||
|
path.join(storageDir, "session", "proj_test123abc", "ses_test456def.json"),
|
||||||
|
JSON.stringify({ ...fixtures.session }),
|
||||||
|
)
|
||||||
|
|
||||||
|
await Bun.write(
|
||||||
|
path.join(storageDir, "todo", "ses_test456def.json"),
|
||||||
|
JSON.stringify([
|
||||||
|
{ content: "Third", status: "pending", priority: "low" },
|
||||||
|
{ content: "First", status: "pending", priority: "high" },
|
||||||
|
{ content: "Second", status: "in_progress", priority: "medium" },
|
||||||
|
]),
|
||||||
|
)
|
||||||
|
|
||||||
|
await JsonMigration.run(sqlite)
|
||||||
|
|
||||||
|
const db = drizzle({ client: sqlite })
|
||||||
|
const todos = db.select().from(TodoTable).orderBy(TodoTable.position).all()
|
||||||
|
|
||||||
|
expect(todos.length).toBe(3)
|
||||||
|
expect(todos[0].content).toBe("Third")
|
||||||
|
expect(todos[0].position).toBe(0)
|
||||||
|
expect(todos[1].content).toBe("First")
|
||||||
|
expect(todos[1].position).toBe(1)
|
||||||
|
expect(todos[2].content).toBe("Second")
|
||||||
|
expect(todos[2].position).toBe(2)
|
||||||
|
})
|
||||||
|
|
||||||
test("migrates permissions", async () => {
|
test("migrates permissions", async () => {
|
||||||
// First create the project
|
// First create the project
|
||||||
await Bun.write(
|
await Bun.write(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue