Replace BPS Excel stub with multi-client calendar template.
Official download now generates a blank workbook with catalog autofill, notas_internas ignored on import, and the same template for every tenant. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
55
src/app/api/calendar/template/route.ts
Normal file
55
src/app/api/calendar/template/route.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { createClient } from '@/lib/supabase/server';
|
||||
import { resolveActiveTenant } from '@/lib/tenant-context';
|
||||
import { isAgencyRole, userRole } from '@/lib/agency';
|
||||
import {
|
||||
buildOfficialCsv,
|
||||
buildOfficialXlsx,
|
||||
} from '@/lib/calendar-template';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
export const runtime = 'nodejs';
|
||||
|
||||
/**
|
||||
* GET /api/calendar/template?format=xlsx|csv
|
||||
* Official blank multi-client template (NOT a filled BPS calendar).
|
||||
*/
|
||||
export async function GET(req: NextRequest) {
|
||||
const supabase = await createClient();
|
||||
const {
|
||||
data: { user },
|
||||
} = await supabase.auth.getUser();
|
||||
if (!user) {
|
||||
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
||||
}
|
||||
if (!isAgencyRole(userRole(user))) {
|
||||
return NextResponse.json({ error: 'Solo agencia' }, { status: 403 });
|
||||
}
|
||||
|
||||
const ctx = await resolveActiveTenant(user);
|
||||
const label =
|
||||
ctx.tenantId && !ctx.portfolioWide ? ctx.label || 'CLIENTE' : 'CLIENTE';
|
||||
|
||||
const format = (req.nextUrl.searchParams.get('format') || 'xlsx').toLowerCase();
|
||||
if (format === 'csv') {
|
||||
const csv = buildOfficialCsv(label);
|
||||
return new NextResponse(csv, {
|
||||
headers: {
|
||||
'Content-Type': 'text/csv; charset=utf-8',
|
||||
'Content-Disposition':
|
||||
'attachment; filename="plantilla-calendario-4ventures.csv"',
|
||||
'Cache-Control': 'no-store',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const { buffer, filename } = await buildOfficialXlsx(label);
|
||||
return new NextResponse(new Uint8Array(buffer), {
|
||||
headers: {
|
||||
'Content-Type':
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'Content-Disposition': `attachment; filename="${filename}"`,
|
||||
'Cache-Control': 'no-store',
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -9,11 +9,11 @@ import {
|
||||
} from '@/lib/agency';
|
||||
import {
|
||||
parseJsonCalendar,
|
||||
SAMPLE_CSV,
|
||||
sheetsToPlans,
|
||||
type ImportResult,
|
||||
type SheetRows,
|
||||
} from '@/lib/calendar-import';
|
||||
import { buildOfficialCsv } from '@/lib/calendar-template';
|
||||
import type { RrssMonthPlan } from '@/components/RrssMonthView';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
@@ -21,12 +21,14 @@ export const runtime = 'nodejs';
|
||||
|
||||
const MAX_BYTES = 8 * 1024 * 1024;
|
||||
|
||||
/** @deprecated Prefer GET /api/calendar/template?format=csv */
|
||||
export async function GET() {
|
||||
return new NextResponse(SAMPLE_CSV, {
|
||||
return new NextResponse(buildOfficialCsv('CLIENTE'), {
|
||||
headers: {
|
||||
'Content-Type': 'text/csv; charset=utf-8',
|
||||
'Content-Disposition':
|
||||
'attachment; filename="plantilla-calendario-4ventures.csv"',
|
||||
'Cache-Control': 'no-store',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user