initial push
This commit is contained in:
134
src/app/api/strategic-diagnostic/evidence/route.ts
Normal file
134
src/app/api/strategic-diagnostic/evidence/route.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { NextResponse } from "next/server";
|
||||
import { requireAdminApiUser } from "@/lib/auth/admin";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import {
|
||||
MAX_STRATEGIC_EVIDENCE_BYTES,
|
||||
isAllowedEvidenceMimeType,
|
||||
storeStrategicEvidenceFile,
|
||||
} from "@/lib/strategic-diagnostic/evidence-storage";
|
||||
import { mapSectionKeyToEnum, recomputeStrategicDiagnosticFromStoredData } from "@/lib/strategic-diagnostic/server";
|
||||
import { STRATEGIC_SECTION_KEYS, type StrategicSectionKey } from "@/lib/strategic-diagnostic/types";
|
||||
|
||||
function parseSection(value: unknown): StrategicSectionKey | null {
|
||||
if (typeof value !== "string") {
|
||||
return null;
|
||||
}
|
||||
|
||||
const section = value.trim() as StrategicSectionKey;
|
||||
return STRATEGIC_SECTION_KEYS.includes(section) ? section : null;
|
||||
}
|
||||
|
||||
function parseCategory(value: unknown) {
|
||||
if (typeof value !== "string") {
|
||||
return "";
|
||||
}
|
||||
|
||||
return value.trim();
|
||||
}
|
||||
|
||||
function isSchemaNotReadyError(error: unknown) {
|
||||
return error instanceof Prisma.PrismaClientKnownRequestError && (error.code === "P2021" || error.code === "P2022");
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
const user = await requireAdminApiUser();
|
||||
|
||||
if (!user) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
|
||||
try {
|
||||
const formData = await request.formData();
|
||||
const section = parseSection(formData.get("section"));
|
||||
const category = parseCategory(formData.get("category"));
|
||||
const file = formData.get("file");
|
||||
|
||||
if (!section) {
|
||||
return NextResponse.json({ error: "Seccion de evidencia invalida." }, { status: 400 });
|
||||
}
|
||||
|
||||
if (!category) {
|
||||
return NextResponse.json({ error: "Categoria de evidencia requerida." }, { status: 400 });
|
||||
}
|
||||
|
||||
if (!(file instanceof File)) {
|
||||
return NextResponse.json({ error: "Archivo requerido." }, { status: 400 });
|
||||
}
|
||||
|
||||
if (file.size <= 0) {
|
||||
return NextResponse.json({ error: "El archivo esta vacio." }, { status: 400 });
|
||||
}
|
||||
|
||||
if (file.size > MAX_STRATEGIC_EVIDENCE_BYTES) {
|
||||
return NextResponse.json({ error: "El archivo excede el limite de 10MB." }, { status: 400 });
|
||||
}
|
||||
|
||||
if (!isAllowedEvidenceMimeType(file.type)) {
|
||||
return NextResponse.json({ error: "Tipo de archivo no permitido (usa PDF, DOC, DOCX, JPG o PNG)." }, { status: 400 });
|
||||
}
|
||||
|
||||
const organization = await prisma.organization.findUnique({
|
||||
where: { userId: user.id },
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!organization) {
|
||||
return NextResponse.json({ error: "No existe un perfil organizacional para este usuario." }, { status: 400 });
|
||||
}
|
||||
|
||||
const fileBuffer = Buffer.from(await file.arrayBuffer());
|
||||
const stored = await storeStrategicEvidenceFile(user.id, file.name, file.type, fileBuffer);
|
||||
const row = await prisma.strategicDiagnosticEvidenceDocument.create({
|
||||
data: {
|
||||
organizationId: organization.id,
|
||||
userId: user.id,
|
||||
section: mapSectionKeyToEnum(section),
|
||||
category,
|
||||
fileName: stored.fileName,
|
||||
storedFileName: stored.storedFileName,
|
||||
filePath: stored.filePath,
|
||||
mimeType: stored.mimeType,
|
||||
sizeBytes: stored.sizeBytes,
|
||||
checksumSha256: stored.checksumSha256,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
category: true,
|
||||
fileName: true,
|
||||
filePath: true,
|
||||
mimeType: true,
|
||||
sizeBytes: true,
|
||||
createdAt: true,
|
||||
},
|
||||
});
|
||||
|
||||
const snapshot = await recomputeStrategicDiagnosticFromStoredData(user.id);
|
||||
|
||||
return NextResponse.json({
|
||||
ok: true,
|
||||
document: {
|
||||
id: row.id,
|
||||
section,
|
||||
category: row.category,
|
||||
fileName: row.fileName,
|
||||
filePath: row.filePath,
|
||||
mimeType: row.mimeType,
|
||||
sizeBytes: row.sizeBytes,
|
||||
createdAt: row.createdAt.toISOString(),
|
||||
},
|
||||
payload: snapshot,
|
||||
});
|
||||
} catch (error) {
|
||||
if (isSchemaNotReadyError(error)) {
|
||||
return NextResponse.json(
|
||||
{ error: "La base de datos aun no tiene las tablas de evidencias de Modulo 2. Ejecuta prisma migrate para continuar." },
|
||||
{ status: 503 },
|
||||
);
|
||||
}
|
||||
|
||||
return NextResponse.json({ error: "No fue posible subir la evidencia." }, { status: 400 });
|
||||
}
|
||||
}
|
||||
38
src/app/api/strategic-diagnostic/route.ts
Normal file
38
src/app/api/strategic-diagnostic/route.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { NextResponse } from "next/server";
|
||||
import { requireAdminApiUser } from "@/lib/auth/admin";
|
||||
import { saveStrategicDiagnosticData } from "@/lib/strategic-diagnostic/server";
|
||||
|
||||
function isSchemaNotReadyError(error: unknown) {
|
||||
return error instanceof Prisma.PrismaClientKnownRequestError && (error.code === "P2021" || error.code === "P2022");
|
||||
}
|
||||
|
||||
export async function POST(request: Request) {
|
||||
const user = await requireAdminApiUser();
|
||||
|
||||
if (!user) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
|
||||
try {
|
||||
const body = (await request.json()) as Record<string, unknown>;
|
||||
const payload = await saveStrategicDiagnosticData(user.id, body.data, {
|
||||
forceCompleted: body.forceCompleted === true,
|
||||
});
|
||||
|
||||
if (!payload) {
|
||||
return NextResponse.json({ error: "No existe un perfil organizacional para este usuario." }, { status: 400 });
|
||||
}
|
||||
|
||||
return NextResponse.json({ ok: true, payload });
|
||||
} catch (error) {
|
||||
if (isSchemaNotReadyError(error)) {
|
||||
return NextResponse.json(
|
||||
{ error: "La base de datos aun no tiene las tablas de Modulo 2. Ejecuta prisma migrate para continuar." },
|
||||
{ status: 503 },
|
||||
);
|
||||
}
|
||||
|
||||
return NextResponse.json({ error: "No fue posible guardar el Modulo 2." }, { status: 400 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user