diff --git a/src/route-handlers/list-workflows-basic/list-workflows-basic.ts b/src/route-handlers/list-workflows-basic/list-workflows-basic.ts index 5497be70..5b704a65 100644 --- a/src/route-handlers/list-workflows-basic/list-workflows-basic.ts +++ b/src/route-handlers/list-workflows-basic/list-workflows-basic.ts @@ -1,5 +1,6 @@ import { type NextRequest, NextResponse } from 'next/server'; +import { type ListOpenWorkflowExecutionsRequest__Input } from '@/__generated__/proto-ts/uber/cadence/api/v1/ListOpenWorkflowExecutionsRequest'; import decodeUrlParams from '@/utils/decode-url-params'; import { getHTTPStatusCode, GRPCError } from '@/utils/grpc/grpc-error'; import logger, { type RouteHandlerErrorPayload } from '@/utils/logger'; @@ -38,33 +39,42 @@ export async function listWorkflowsBasic( ); } - try { - const listEndpoint = - queryParams.kind === 'open' - ? ctx.grpcClusterMethods.openWorkflows - : ctx.grpcClusterMethods.closedWorkflows; - - const res = await listEndpoint({ - domain: decodedParams.domain, - pageSize: queryParams.pageSize, - nextPageToken: queryParams.nextPage, - startTimeFilter: { - earliestTime: queryParams.timeRangeStart, - latestTime: queryParams.timeRangeEnd, - }, + const baseParams = { + domain: decodedParams.domain, + pageSize: queryParams.pageSize, + nextPageToken: queryParams.nextPage, + startTimeFilter: { + earliestTime: queryParams.timeRangeStart, + latestTime: queryParams.timeRangeEnd, + }, + ...((queryParams.workflowId || queryParams.runId) && { + filters: 'executionFilter', executionFilter: { workflowId: queryParams.workflowId, runId: queryParams.runId, }, + }), + ...(queryParams.workflowType && { + filters: 'typeFilter', typeFilter: { name: queryParams.workflowType, }, - ...(queryParams.kind === 'closed' && { - statusFilter: { - status: queryParams.closeStatus, - }, - }), - }); + }), + } satisfies ListOpenWorkflowExecutionsRequest__Input; + + try { + const res = + queryParams.kind === 'closed' + ? await ctx.grpcClusterMethods.closedWorkflows({ + ...baseParams, + ...(queryParams.closeStatus && { + filters: 'statusFilter', + statusFilter: { + status: queryParams.closeStatus, + }, + }), + }) + : await ctx.grpcClusterMethods.openWorkflows({ ...baseParams }); const response: ListWorkflowsBasicResponse = { workflows: mapExecutionsToWorkflows(res.executions), diff --git a/src/route-handlers/list-workflows-basic/schemas/list-workflows-basic-query-params-schema.ts b/src/route-handlers/list-workflows-basic/schemas/list-workflows-basic-query-params-schema.ts index 51ec6254..509d4f3f 100644 --- a/src/route-handlers/list-workflows-basic/schemas/list-workflows-basic-query-params-schema.ts +++ b/src/route-handlers/list-workflows-basic/schemas/list-workflows-basic-query-params-schema.ts @@ -4,25 +4,44 @@ import getGrpcTimestampFromIso from '@/utils/datetime/get-grpc-timestamp-from-is import isWorkflowStatus from '@/views/shared/workflow-status-tag/helpers/is-workflow-status'; import { type WorkflowStatus } from '@/views/shared/workflow-status-tag/workflow-status-tag.types'; -const listWorkflowsBasicQueryParamsSchema = z.object({ - kind: z.enum(['open', 'closed']), - pageSize: z - .string() - .transform((val) => parseInt(val, 10)) - .pipe( - z.number().positive({ message: 'Page size must be a positive integer' }) - ), - workflowId: z.string().optional(), - workflowType: z.string().optional(), - runId: z.string().optional(), - closeStatus: z - .custom(isWorkflowStatus, { - message: 'Invalid workflow status', - }) - .optional(), - timeRangeStart: z.string().datetime().transform(getGrpcTimestampFromIso), - timeRangeEnd: z.string().datetime().transform(getGrpcTimestampFromIso), - nextPage: z.string().optional(), -}); +const listWorkflowsBasicQueryParamsSchema = z + .object({ + kind: z.enum(['open', 'closed']), + pageSize: z + .string() + .transform((val) => parseInt(val, 10)) + .pipe( + z.number().positive({ message: 'Page size must be a positive integer' }) + ), + workflowId: z.string().optional(), + workflowType: z.string().optional(), + runId: z.string().optional(), + closeStatus: z + .custom(isWorkflowStatus, { + message: 'Invalid workflow status', + }) + .optional(), + timeRangeStart: z.string().datetime().transform(getGrpcTimestampFromIso), + timeRangeEnd: z.string().datetime().transform(getGrpcTimestampFromIso), + nextPage: z.string().optional(), + }) + .refine((params) => { + let definedFiltersCount = 0; + // Execution filter + if (params.workflowId || params.runId) { + definedFiltersCount += 1; + } + // Type filter + if (params.workflowType) { + definedFiltersCount += 1; + } + // Status filter + if (params.closeStatus) { + definedFiltersCount += 1; + } + + return definedFiltersCount <= 1; + // TODO @adhitya.mamallan - If we add RunID back, add it in the message below + }, 'Only one of the following filters is allowed - Workflow ID, Workflow Type, Close Status'); export default listWorkflowsBasicQueryParamsSchema;