feat(portal): complete masterplan with deterministic budget simulator, RAG assistant, agency cross-tenant view and multi-tenant middleware

This commit is contained in:
Marcos Fargas
2026-09-21 01:51:50 +02:00
parent 3298e4154f
commit f728c33533
7 changed files with 516 additions and 1 deletions

43
src/middleware.ts Normal file
View File

@@ -0,0 +1,43 @@
import { NextRequest, NextResponse } from 'next/server';
export function middleware(req: NextRequest) {
const url = req.nextUrl.clone();
const hostname = req.headers.get('host') || '';
// 1. Extraer slug desde subdominio (ej: acme.4ventures.es)
let tenantSlug = '4ventures-hub';
const parts = hostname.split('.');
if (parts.length > 2) {
const sub = parts[0].toLowerCase();
if (sub !== 'app' && sub !== 'git' && sub !== 'supabase' && sub !== 'n8n' && sub !== 'www') {
tenantSlug = sub;
}
}
// 2. Override opcional vía query param ?tenant=slug
const queryTenant = url.searchParams.get('tenant');
if (queryTenant) {
tenantSlug = queryTenant.toLowerCase();
} else {
const cookieTenant = req.cookies.get('4v_tenant')?.value;
if (cookieTenant) {
tenantSlug = cookieTenant;
}
}
const response = NextResponse.next({
request: {
headers: new Headers(req.headers)
}
});
response.headers.set('x-tenant-slug', tenantSlug);
response.cookies.set('4v_tenant', tenantSlug, { path: '/', maxAge: 60 * 60 * 24 * 30 });
return response;
}
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico|_4v_attr.js).*)']
};