src/features/catalog/query.ts
Linked repository file from this build.
import { z } from "zod";
import type { queryCatalog } from "@/lib/db/catalog-store";
import type { Actor } from "@/features/reviews/types";
export function queueStates(actor: Actor): string[] {
return actor.role === "pec"
? ["awaiting_pec_approval"]
: actor.role === "program_manager"
? ["awaiting_review", "awaiting_manager", "awaiting_cao_response"]
: ["awaiting_review"];
}
export const catalogQuerySchema = z.object({
queue: z.enum(["true", "false"]).default("false"),
includeBranches: z.enum(["true", "false"]).default("true"),
examiner: z.string().max(200).optional(),
year: z.coerce.number().int().min(1900).max(9999).optional(),
month: z
.string()
.regex(/^\d{4}-(0[1-9]|1[0-2])$/)
.optional(),
category: z
.enum([
"",
"new_active",
"awaiting_review",
"awaiting_pec_approval",
"awaiting_manager",
"awaiting_cao_response",
"released_to_reporting",
"needs_changes",
"dropped",
])
.default(""),
sort: z.enum(["newest", "oldest", "sender", "unread", "flagged", "category"]).default("newest"),
page: z.coerce.number().int().min(0).max(1_000_000).default(0),
pageSize: z.coerce.number().int().min(1).max(100).default(10),
});
export type CatalogQuery = z.infer<typeof catalogQuerySchema>;
/** Response body of /api/catalog, inferred from the query that builds it. */
export type CatalogResponse = Awaited<ReturnType<typeof queryCatalog>>;
export type CatalogReview = CatalogResponse["reviews"][number];
export type CatalogBranch = CatalogResponse["branches"][number];
export const categoryLabels: Record<string, string> = {
new_active: "Active",
awaiting_review: "Awaiting supervisor",
awaiting_manager: "Awaiting manager",
awaiting_cao_response: "Awaiting CAO response",
released_to_reporting: "Released to reporting",
awaiting_pec_approval: "Routed to PEC",
needs_changes: "Returned",
dropped: "Dropped",
};
export function fiscalYear(month: string) {
return Number(month.slice(0, 4)) + (Number(month.slice(5, 7)) >= 10 ? 1 : 0);
}