Skip to article
Documentation

src/app/api/imports/snap-negative/route.ts

Linked repository file from this build.

import { listPolicies } from "@/lib/db/policy-store";
import { apiRoute } from "@/lib/api-route";
import { getActor } from "@/lib/auth/server";
import { AccessError, can } from "@/lib/auth/scope";
import { NextResponse } from "next/server";
import { ReviewStoreUnavailableError } from "@/features/reviews/review-store";
import { isValidReviewNumberFormat } from "@/lib/import/snap-negative";
import { z } from "zod";
import { promoteSnapNegative } from "@/features/reviews/intake-command";
import { reviewStore } from "@/lib/db/review-store";
const schema = z
  .object({
    files: z
      .object({
        closedSuspended: z.string().max(1_000_000),
        rejected: z.string().max(1_000_000),
        fileNames: z
          .object({
            closedSuspended: z.string().max(255).optional(),
            rejected: z.string().max(255).optional(),
          })
          .strict()
          .optional(),
      })
      .strict(),
    identity: z
      .object({
        program: z.literal("SNAP"),
        fiscalYear: z.number().int().min(1900).max(9999),
        reviewNumber: z
          .string()
          .refine(isValidReviewNumberFormat, "Review number format is invalid."),
      })
      .strict(),
    expectedVersion: z.number().int().nonnegative().nullable(),
    requestId: z.string().uuid(),
  })
  .strict();
export const POST = apiRoute("Unable to promote review.", async (request) => {
  const actor = await getActor(request);
  if (!can(actor, "import")) throw new AccessError("This role cannot import reviews.");
  const body = schema.parse(await request.json());
  return NextResponse.json(
    await promoteSnapNegative(
      reviewStore,
      body.files,
      body.identity,
      actor,
      body.expectedVersion,
      body.requestId,
      async () => {
        try {
          return await listPolicies();
        } catch (cause) {
          throw new ReviewStoreUnavailableError(cause);
        }
      },
    ),
  );
});