Caso de Estudio de Ingeniería
⚠El Problema
La conciliación bancaria manual es lenta, propensa a errores humanos y carece de mecanismos de seguridad frente a condiciones de carrera cuando múltiples usuarios procesan datos simultáneamente. Las soluciones existentes no ofrecen aislamiento estricto entre organizaciones ni recuperación inteligente ante fallos de OCR clásico en imágenes de baja calidad.
✓La Solución
Zentral es un SaaS Multi-tenant construido sobre Next.js (App Router) que implementa aislamiento lógico estricto en MongoDB. Cada organización opera en su propio workspace, gobernado por un middleware criptográfico en el Edge que valida cookies httpOnly y bloquea accesos cruzados. Además, integra un pipeline de extracción de datos financieros con un sistema de fallback híbrido entre OCR clásico e inteligencia artificial (Gemini 2.0 Flash).
- ✓Multi-tenancy real con headers inyectados por Edge
- ✓OCR + Gemini con conmutación en caliente
- ✓Mutaciones atómicas con $expr (sin race conditions)
- ✓19 feature toggles con bypass de superadmin
⚙Retos de Ingeniería
Aislamiento Multi-tenant (Edge Middleware)
Middleware en el Edge de Next.js que, usando la librería criptográfica jose, valida cookies httpOnly firmadas. Inyecta el header seguro x-workspace-id en cada request, garantizando que ninguna organización acceda a datos de otra. La cabecera nunca acepta el ID del cliente; siempre viene del proxy validado.
// proxy.ts — Edge Middleware Multi-tenant
import { jwtVerify } from "jose";
export async function middleware(request) {
const token = request.cookies.get("session")?.value;
if (!token) return NextResponse.redirect("/login");
const { payload } = await jwtVerify(
token,
new TextEncoder().encode(process.env.JWT_SECRET)
);
const headers = new Headers(request.headers);
headers.set("x-workspace-id", payload.workspaceId);
headers.set("x-user-role", payload.role);
return NextResponse.next({ request: { headers } });
}Mutaciones Atómicas (Concurrencia)
Uso de findOneAndUpdate con expresiones $expr para prevenir race conditions en el consumo de cuotas de APIs de terceros. La validación y el incremento ocurren en una única operación atómica a nivel de motor de BD.
// Atomic quota consumption — prevents race conditions
await ModuleSubscription.findOneAndUpdate(
{
workspace: workspaceId,
moduleKey,
status: "active",
$expr: { $lt: ["$usedQuota", "$monthlyQuota"] }
},
{ $inc: { usedQuota: 1 } },
{ new: true, projection: { _id: 1 } }
);IA Resiliente (Fallback Híbrido)
Pipeline de extracción con conmutación en caliente: primero intenta OCR clásico (OCR.space); si la certeza es baja o el servicio falla, conmuta automáticamente a Gemini 2.0 Flash procesando el documento como buffer Base64 en memoria, sin persistir archivos en disco.
// Hybrid AI pipeline with hot fallback
async function extractFinancialData(buffer: Buffer) {
// 1) OCR clásico (rápido y económico)
const ocr = await ocrSpaceParse(buffer);
if (ocr.certainty > 0.85) return ocr.data;
// 2) Fallback a Gemini 2.0 Flash (en memoria)
const base64 = buffer.toString("base64");
const gemini = new GoogleGenerativeAI(process.env.GEMINI_KEY);
const model = gemini.getGenerativeModel({
model: "gemini-2.0-flash",
generationConfig: { responseMimeType: "application/json" }
});
const result = await model.generateContent([
"Extract financial data as JSON.",
{ inlineData: { mimeType: "image/png", data: base64 } }
]);
return JSON.parse(result.response.text());
}🗃Diagrama de Arquitectura
Flujo de request multi-tenant · el workspace ID nunca viaja del cliente



