fix(intake): support comma-separated status filter in GET /intake/jobs — fixes mobile polling contract mismatch
This commit is contained in:
parent
e5f287c7ea
commit
338e80fc33
@ -56,16 +56,29 @@ export async function getIntakeJob(id: string, userId: string): Promise<IntakeJo
|
||||
export async function listIntakeJobs(
|
||||
userId: string,
|
||||
productId: string,
|
||||
options?: { status?: IntakeJobStatus; since?: string; limit?: number; offset?: number },
|
||||
options?: { statuses?: IntakeJobStatus[]; since?: string; limit?: number; offset?: number },
|
||||
): Promise<IntakeJobDoc[]> {
|
||||
const filter: FilterMap = { userId, productId };
|
||||
if (options?.status) filter.status = options.status;
|
||||
return jobsCollection().findMany({
|
||||
// If a single status is provided, use it as a direct filter for efficiency
|
||||
if (options?.statuses && options.statuses.length === 1) {
|
||||
filter.status = options.statuses[0];
|
||||
}
|
||||
const limit = options?.limit ?? 20;
|
||||
// Fetch more if we need to filter client-side for multiple statuses
|
||||
const fetchLimit = options?.statuses && options.statuses.length > 1 ? Math.min(limit * 3, 100) : limit;
|
||||
let jobs = await jobsCollection().findMany({
|
||||
filter,
|
||||
sort: { startedAt: -1 },
|
||||
limit: options?.limit ?? 20,
|
||||
limit: fetchLimit,
|
||||
offset: options?.offset ?? 0,
|
||||
});
|
||||
// Client-side filter for multiple statuses
|
||||
if (options?.statuses && options.statuses.length > 1) {
|
||||
const statusSet = new Set(options.statuses);
|
||||
jobs = jobs.filter((j) => statusSet.has(j.status));
|
||||
jobs = jobs.slice(0, limit);
|
||||
}
|
||||
return jobs;
|
||||
}
|
||||
|
||||
export async function updateIntakeJob(
|
||||
|
||||
@ -23,7 +23,7 @@ import {
|
||||
UpdateIntakeRuleSchema,
|
||||
ListIntakeJobsQuerySchema,
|
||||
} from './types.js';
|
||||
import type { IntakeRuleDoc } from './types.js';
|
||||
import type { IntakeRuleDoc, IntakeJobStatus } from './types.js';
|
||||
|
||||
// ── Rate limiter (simple in-memory) ──────────────────────────────
|
||||
|
||||
@ -249,8 +249,12 @@ export async function intakeRoutes(app: FastifyInstance): Promise<void> {
|
||||
const userId = getUserId(req);
|
||||
const productId = getRequestProductId(req);
|
||||
const query = ListIntakeJobsQuerySchema.parse(req.query);
|
||||
// Support comma-separated statuses (e.g. "queued,extracting,processing")
|
||||
const statuses = query.status
|
||||
? query.status.split(',').map((s) => s.trim()).filter(Boolean) as IntakeJobStatus[]
|
||||
: undefined;
|
||||
const jobs = await repo.listIntakeJobs(userId, productId, {
|
||||
status: query.status,
|
||||
statuses,
|
||||
since: query.since,
|
||||
limit: query.limit,
|
||||
offset: query.offset,
|
||||
|
||||
@ -86,7 +86,7 @@ export const IntakeRequestSchema = z.object({
|
||||
export type IntakeRequest = z.infer<typeof IntakeRequestSchema>;
|
||||
|
||||
export const ListIntakeJobsQuerySchema = z.object({
|
||||
status: z.enum(INTAKE_JOB_STATUSES).optional(),
|
||||
status: z.string().max(200).optional(),
|
||||
since: z.string().max(64).optional(),
|
||||
limit: z.coerce.number().int().min(1).max(100).default(20),
|
||||
offset: z.coerce.number().int().min(0).default(0),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user