feat(session): filter v2 session list by parent (#35037)
Co-authored-by: Dax <mail@thdxr.com>
This commit is contained in:
co-authored by
Dax
parent
7ebd344fa2
commit
6555df912a
@@ -3,7 +3,7 @@ export * from "./session/schema"
|
||||
|
||||
import { DateTime, Effect, Layer, Schema, Context, Stream, Scope } from "effect"
|
||||
import { ListAnchor } from "@opencode-ai/schema/session"
|
||||
import { and, asc, desc, eq, gt, like, lt, or, type SQL } from "drizzle-orm"
|
||||
import { and, asc, desc, eq, gt, isNull, like, lt, or, type SQL } from "drizzle-orm"
|
||||
import { ProjectV2 } from "./project"
|
||||
import { WorkspaceV2 } from "./workspace"
|
||||
import { ModelV2 } from "./model"
|
||||
@@ -61,6 +61,7 @@ const ListInputBase = {
|
||||
search: Schema.String.pipe(Schema.optional),
|
||||
limit: PositiveInt.pipe(Schema.optional),
|
||||
order: Schema.Literals(["asc", "desc"]).pipe(Schema.optional),
|
||||
parentID: Schema.NullOr(SessionSchema.ID).pipe(Schema.optional),
|
||||
anchor: ListAnchor.pipe(Schema.optional),
|
||||
}
|
||||
|
||||
@@ -358,12 +359,16 @@ const layer = Layer.effect(
|
||||
const direction = input.anchor?.direction ?? "next"
|
||||
const requestedOrder = input.order ?? "desc"
|
||||
const order = direction === "previous" ? (requestedOrder === "asc" ? "desc" : "asc") : requestedOrder
|
||||
const sortColumn = SessionTable.time_created
|
||||
const sortColumn = SessionTable.time_updated
|
||||
const conditions: SQL[] = []
|
||||
if ("directory" in input) conditions.push(eq(SessionTable.directory, input.directory))
|
||||
if (input.workspaceID) conditions.push(eq(SessionTable.workspace_id, input.workspaceID))
|
||||
if ("project" in input) conditions.push(eq(SessionTable.project_id, input.project))
|
||||
if (input.search) conditions.push(like(SessionTable.title, `%${input.search}%`))
|
||||
if (input.parentID !== undefined)
|
||||
conditions.push(
|
||||
input.parentID === null ? isNull(SessionTable.parent_id) : eq(SessionTable.parent_id, input.parentID),
|
||||
)
|
||||
if (input.anchor) {
|
||||
conditions.push(
|
||||
order === "asc"
|
||||
|
||||
@@ -130,6 +130,53 @@ describe("SessionV2.create", () => {
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("filters root sessions before applying the page limit", () =>
|
||||
Effect.gen(function* () {
|
||||
const session = yield* SessionV2.Service
|
||||
const { db } = yield* Database.Service
|
||||
const staleRoot = yield* session.create({ location, title: "stale root" })
|
||||
const root = yield* session.create({ location, title: "root" })
|
||||
const children = yield* Effect.forEach(Array.from({ length: 60 }), (_, index) =>
|
||||
session.create({ parentID: root.id, title: `child ${index}` }),
|
||||
)
|
||||
|
||||
yield* Effect.forEach(children, (item, index) =>
|
||||
db
|
||||
.update(SessionTable)
|
||||
.set({ time_created: index + 100, time_updated: index + 20_000 })
|
||||
.where(eq(SessionTable.id, item.id))
|
||||
.run(),
|
||||
)
|
||||
yield* db
|
||||
.update(SessionTable)
|
||||
.set({ time_created: 2, time_updated: 5_000 })
|
||||
.where(eq(SessionTable.id, staleRoot.id))
|
||||
.run()
|
||||
yield* db
|
||||
.update(SessionTable)
|
||||
.set({ time_created: 1, time_updated: 10_000 })
|
||||
.where(eq(SessionTable.id, root.id))
|
||||
.run()
|
||||
|
||||
const page = yield* session.list({ directory: location.directory, parentID: null, limit: 1, order: "desc" })
|
||||
|
||||
expect(page.data.map((item) => item.id)).toEqual([root.id])
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("filters direct child sessions by parent ID", () =>
|
||||
Effect.gen(function* () {
|
||||
const session = yield* SessionV2.Service
|
||||
const parent = yield* session.create({ location, title: "parent" })
|
||||
const child = yield* session.create({ parentID: parent.id, title: "child" })
|
||||
yield* session.create({ location, title: "other root" })
|
||||
|
||||
const page = yield* session.list({ parentID: parent.id })
|
||||
|
||||
expect(page.data.map((item) => item.id)).toEqual([child.id])
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("forks a session by replaying a durable fork event into copied projected rows", () =>
|
||||
Effect.gen(function* () {
|
||||
const session = yield* SessionV2.Service
|
||||
|
||||
Reference in New Issue
Block a user