feat(brandkit): permitir subir PDF y DOCX como fuentes
Extrae texto del PDF/DOCX en Fuentes del kit de marca para no depender de pegar el contenido a mano. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* POST multipart: file (.txt/.md/.csv) or JSON { text, filename }
|
||||
* POST multipart: file (.txt/.md/.csv/.json/.pdf/.docx) or JSON { text, filename }
|
||||
* Appends source excerpt into the tenant brandbook.
|
||||
*/
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
@@ -15,8 +15,13 @@ import {
|
||||
parseBrandbook,
|
||||
type Brandbook,
|
||||
} from '@/lib/brandbook';
|
||||
import {
|
||||
detectSourceExt,
|
||||
extractSourceText,
|
||||
} from '@/lib/extract-document-text';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
export const maxDuration = 60;
|
||||
|
||||
async function loadBook(tenantId: string, label: string): Promise<{
|
||||
id: string | null;
|
||||
@@ -68,22 +73,42 @@ export async function POST(req: NextRequest) {
|
||||
} else if (!url && file && typeof file === 'object' && 'arrayBuffer' in file) {
|
||||
const f = file as File;
|
||||
filename = f.name || 'upload.txt';
|
||||
const lower = filename.toLowerCase();
|
||||
if (
|
||||
!lower.endsWith('.txt') &&
|
||||
!lower.endsWith('.md') &&
|
||||
!lower.endsWith('.csv') &&
|
||||
!lower.endsWith('.json')
|
||||
) {
|
||||
const ext = detectSourceExt(filename, f.type);
|
||||
if (!ext) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error:
|
||||
'Por ahora sube .txt, .md, .csv o .json. PDF/DOCX: pega el texto en el campo.',
|
||||
'Formatos admitidos: .pdf, .docx, .txt, .md, .csv, .json. Si el PDF es escaneado, pega el texto.',
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
try {
|
||||
const buf = Buffer.from(await f.arrayBuffer());
|
||||
if (buf.byteLength > 25 * 1024 * 1024) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Archivo demasiado grande (máx. 25 MB)' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
const extracted = await extractSourceText({
|
||||
filename,
|
||||
mime: f.type,
|
||||
buffer: buf,
|
||||
});
|
||||
text = extracted.text;
|
||||
filename = extracted.filename;
|
||||
} catch (e) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error:
|
||||
e instanceof Error
|
||||
? e.message
|
||||
: 'No se pudo leer el archivo',
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
text = await f.text();
|
||||
}
|
||||
} else {
|
||||
const body = (await req.json().catch(() => ({}))) as {
|
||||
|
||||
Reference in New Issue
Block a user