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(
|
export async function listIntakeJobs(
|
||||||
userId: string,
|
userId: string,
|
||||||
productId: string,
|
productId: string,
|
||||||
options?: { status?: IntakeJobStatus; since?: string; limit?: number; offset?: number },
|
options?: { statuses?: IntakeJobStatus[]; since?: string; limit?: number; offset?: number },
|
||||||
): Promise<IntakeJobDoc[]> {
|
): Promise<IntakeJobDoc[]> {
|
||||||
const filter: FilterMap = { userId, productId };
|
const filter: FilterMap = { userId, productId };
|
||||||
if (options?.status) filter.status = options.status;
|
// If a single status is provided, use it as a direct filter for efficiency
|
||||||
return jobsCollection().findMany({
|
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,
|
filter,
|
||||||
sort: { startedAt: -1 },
|
sort: { startedAt: -1 },
|
||||||
limit: options?.limit ?? 20,
|
limit: fetchLimit,
|
||||||
offset: options?.offset ?? 0,
|
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(
|
export async function updateIntakeJob(
|
||||||
|
|||||||
@ -23,7 +23,7 @@ import {
|
|||||||
UpdateIntakeRuleSchema,
|
UpdateIntakeRuleSchema,
|
||||||
ListIntakeJobsQuerySchema,
|
ListIntakeJobsQuerySchema,
|
||||||
} from './types.js';
|
} from './types.js';
|
||||||
import type { IntakeRuleDoc } from './types.js';
|
import type { IntakeRuleDoc, IntakeJobStatus } from './types.js';
|
||||||
|
|
||||||
// ── Rate limiter (simple in-memory) ──────────────────────────────
|
// ── Rate limiter (simple in-memory) ──────────────────────────────
|
||||||
|
|
||||||
@ -249,8 +249,12 @@ export async function intakeRoutes(app: FastifyInstance): Promise<void> {
|
|||||||
const userId = getUserId(req);
|
const userId = getUserId(req);
|
||||||
const productId = getRequestProductId(req);
|
const productId = getRequestProductId(req);
|
||||||
const query = ListIntakeJobsQuerySchema.parse(req.query);
|
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, {
|
const jobs = await repo.listIntakeJobs(userId, productId, {
|
||||||
status: query.status,
|
statuses,
|
||||||
since: query.since,
|
since: query.since,
|
||||||
limit: query.limit,
|
limit: query.limit,
|
||||||
offset: query.offset,
|
offset: query.offset,
|
||||||
|
|||||||
@ -86,7 +86,7 @@ export const IntakeRequestSchema = z.object({
|
|||||||
export type IntakeRequest = z.infer<typeof IntakeRequestSchema>;
|
export type IntakeRequest = z.infer<typeof IntakeRequestSchema>;
|
||||||
|
|
||||||
export const ListIntakeJobsQuerySchema = z.object({
|
export const ListIntakeJobsQuerySchema = z.object({
|
||||||
status: z.enum(INTAKE_JOB_STATUSES).optional(),
|
status: z.string().max(200).optional(),
|
||||||
since: z.string().max(64).optional(),
|
since: z.string().max(64).optional(),
|
||||||
limit: z.coerce.number().int().min(1).max(100).default(20),
|
limit: z.coerce.number().int().min(1).max(100).default(20),
|
||||||
offset: z.coerce.number().int().min(0).default(0),
|
offset: z.coerce.number().int().min(0).default(0),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user