ResearchGo
PróximamenteUna plataforma para el CIBES Research Centre que lleva un artículo académico desde el envío hasta la publicación. Terminada y en las últimas comprobaciones antes del lanzamiento.
- Mi papel
- Arquitectura y desarrollo
- Año
- 2026
- Hecho con
- Next.js · Supabase (EU) · Python · FastAPI · GROBID · OpenAlex · Stripe
Desplázate en horizontal para ver el diagrama completo.
El problema
Los envíos académicos se gestionan con cadenas de correos y hojas de cálculo. Las versiones, los comentarios de los revisores y los requisitos de las revistas se desincronizan en cuanto interviene más de una persona, y los editores responden a mano las mismas preguntas cada vez: ¿qué versión es esta?, ¿qué ha cambiado?, ¿cuadran las referencias?, ¿qué revista encaja?
Cómo está construido
Una app de Next.js sobre Supabase, con todos los datos alojados en la UE. Los autores inician sesión con ORCID o con su correo y suben un manuscrito en PDF o Word. Un worker en Python (FastAPI) lo parsea en cuanto llega, los PDF a través de GROBID, y devuelve el texto estructurado mediante un callback firmado y con marca de tiempo que rechaza los jobs falsificados o repetidos. Cada parseo correcto se convierte en una nueva versión, guardada cifrada, pero solo si el texto ha cambiado de verdad. Los editores comparan dos versiones cualesquiera con control de cambios al estilo de Word, contrastan las citas del texto con la lista de referencias y reciben sugerencias de revistas ordenadas por significado, con embeddings calculados en nuestro propio worker y datos de revistas de OpenAlex. Los pagos se gestionan con Stripe.
Decisiones importantes
Sin modelos de lenguaje donde basta una regla
El control de cambios y la comprobación de referencias son código determinista, sin IA de por medio. Un editor tiene que poder fiarse de un diff, y una regla da siempre la misma respuesta.
Los manuscritos nunca salen de nuestros servidores
El matching de revistas calcula el embedding del artículo en nuestro propio worker, así que ningún texto del manuscrito llega a terceros. La ordenación es pura similitud. Los datos de indexación, acceso abierto y tasas se muestran como etiquetas y nunca cambian el orden.
Cada job va firmado
Los jobs entre la app web y el worker llevan una firma HMAC y una marca de tiempo. Un job falsificado o repetido se rechaza, y si un worker se cae a mitad de un job, el manuscrito no pierde su sitio.
Código del repositorio
function diffParagraphPair(before: string, after: string): DiffSegment[] {
return diffWordsWithSpace(before, after).map((part) => ({1
op: part.added ? "ins" : part.removed ? "del" : "equal",
text: part.value,
}));
}
export function diffManuscripts(before: string, after: string): DiffResult {
const a = splitParagraphs(before);
const b = splitParagraphs(after);
// …
const parts = diffArrays(a, b);2
let i = 0;
while (i < parts.length) {
const part = parts[i];
if (!part) break;
if (!part.added && !part.removed) {
// …
i++;
continue;
}
const next = parts[i + 1];
const paired = Boolean(part.removed && next?.added);3
const removedList = part.removed ? part.value : [];
const addedList = part.added ? part.value : paired && next ? next.value : [];
const pairs = Math.min(removedList.length, addedList.length);
for (let k = 0; k < pairs; k++) {
const segments = diffParagraphPair(removedList[k] as string, addedList[k] as string);
paragraphs.push({ kind: "changed", segments });
// …
}
// …
i += paired ? 2 : 1;
}
return { paragraphs, summary };
}
Línea 2. Dentro de un párrafo modificado, el diff va palabra por palabra y conserva los espacios, así que se lee como el control de cambios de Word.
Línea 12. Primera pasada: un diff de subsecuencia común más larga sobre párrafos enteros encuentra qué se mantuvo, qué se añadió y qué se eliminó.
Línea 23. Una eliminación seguida directamente de una adición es un único párrafo editado, no dos cambios separados.
En qué punto está
Terminada y en las últimas comprobaciones. Saldrá en cuanto terminen.