Skip to content

Commit 27af3b1

Browse files
fix: version list endpoint respects limit param
1 parent f0da3d6 commit 27af3b1

3 files changed

Lines changed: 500 additions & 17 deletions

File tree

apps/api/src/routes/v1/workspaces/deployments.ts

Lines changed: 56 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,48 @@ function filterDeploymentVersions(
316316
});
317317
}
318318

319+
const CEL_BATCH_SIZE = 500;
320+
const CEL_MAX_SCAN = 100_000;
321+
322+
async function listDeploymentVersionsMatchingCel(
323+
deploymentId: string,
324+
cel: string,
325+
order: "asc" | "desc",
326+
offset: number,
327+
limit: number,
328+
) {
329+
const orderBy =
330+
order === "asc"
331+
? asc(schema.deploymentVersion.createdAt)
332+
: desc(schema.deploymentVersion.createdAt);
333+
334+
const pageEnd = offset + limit;
335+
const items: (typeof schema.deploymentVersion.$inferSelect)[] = [];
336+
let scanned = 0;
337+
let matched = 0;
338+
339+
while (scanned < CEL_MAX_SCAN) {
340+
const batch = await db
341+
.select()
342+
.from(schema.deploymentVersion)
343+
.where(eq(schema.deploymentVersion.deploymentId, deploymentId))
344+
.orderBy(orderBy)
345+
.limit(CEL_BATCH_SIZE)
346+
.offset(scanned);
347+
if (batch.length === 0) break;
348+
349+
for (const version of filterDeploymentVersions(batch, cel)) {
350+
if (matched >= offset && matched < pageEnd) items.push(version);
351+
matched++;
352+
}
353+
354+
scanned += batch.length;
355+
if (batch.length < CEL_BATCH_SIZE) break;
356+
}
357+
358+
return { items, total: matched };
359+
}
360+
319361
const listDeploymentVersions: AsyncTypedHandler<
320362
"/v1/workspaces/{workspaceId}/deployments/{deploymentId}/versions",
321363
"get"
@@ -326,12 +368,12 @@ const listDeploymentVersions: AsyncTypedHandler<
326368
const order = req.query.order ?? "desc";
327369
const { cel } = req.query;
328370

329-
const orderBy =
330-
order === "asc"
331-
? asc(schema.deploymentVersion.createdAt)
332-
: desc(schema.deploymentVersion.createdAt);
333-
334371
if (cel == null) {
372+
const orderBy =
373+
order === "asc"
374+
? asc(schema.deploymentVersion.createdAt)
375+
: desc(schema.deploymentVersion.createdAt);
376+
335377
const { total } = await db
336378
.select({ total: count() })
337379
.from(schema.deploymentVersion)
@@ -358,20 +400,17 @@ const listDeploymentVersions: AsyncTypedHandler<
358400
if (!validResourceSelector(cel))
359401
throw new ApiError("Invalid CEL expression", 400);
360402

361-
// CEL is evaluated in-memory, so cap the candidate set to bound cost.
362-
// Filtering applies to the 1000 most-recent (or oldest, for asc) versions.
363-
const candidates = await db
364-
.select()
365-
.from(schema.deploymentVersion)
366-
.where(eq(schema.deploymentVersion.deploymentId, deploymentId))
367-
.orderBy(orderBy)
368-
.limit(1000);
369-
370-
const filtered = filterDeploymentVersions(candidates, cel);
403+
const { items, total } = await listDeploymentVersionsMatchingCel(
404+
deploymentId,
405+
cel,
406+
order,
407+
offset,
408+
limit,
409+
);
371410

372411
res.status(200).json({
373-
items: filtered.slice(offset, offset + limit).map(formatDeploymentVersion),
374-
total: filtered.length,
412+
items: items.map(formatDeploymentVersion),
413+
total,
375414
limit,
376415
offset,
377416
});

e2e/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
"test:policies": "pnpm exec playwright test tests/api/policies/",
1919
"test:deployments": "pnpm exec playwright test --project=api-tests tests/api/deployments.spec.ts",
2020
"test:deployment-version-deps": "pnpm exec playwright test --project=api-tests tests/api/deployment-version-dependencies.spec.ts",
21+
"test:deployment-version-list": "pnpm exec playwright test --project=api-tests tests/api/deployment-version-list.spec.ts",
22+
"test:deployment-version-list:heavy": "RUN_HEAVY_TESTS=1 pnpm exec playwright test --project=api-tests tests/api/deployment-version-list.spec.ts",
2123
"test:release-targets": "pnpm exec playwright test tests/api/release-targets.spec.ts",
2224
"test:yaml": "pnpm exec playwright test tests/api/yaml-import.spec.ts",
2325
"test:yaml-prefixed": "pnpm exec playwright test tests/api/random-prefix-yaml.spec.ts",

0 commit comments

Comments
 (0)