1import { NextRequest, NextResponse } from "next/server";
2import { getRequestContext, validateApiAccess, getStoreApiUrl } from "@/lib/server/sessionUtils";
3import { FieldpineServerApi } from "@/lib/server/fieldpineApi";
6 * Sales Cube API - Multi-dimensional sales analysis
7 * Uses ELINK: retailmax.elink.sale.cube
9 * Security: Retail stores can access this (ELINK endpoint)
11 * Provides flexible sales data aggregation and grouping
13 * - mode: Cube mode (default: 6)
14 * - dimensions: Comma-separated list of dimensions to group by
15 * - measures: Comma-separated list of measures to aggregate
16 * - dateFrom/dateTo: Date range (old format)
17 * - fromDate/toDate: Date range (franchise report format)
18 * - filters: Additional filters as JSON array
20export async function GET(request: NextRequest) {
22 // 1. Get session and store context
23 const context = await getRequestContext(request);
26 return NextResponse.json(
27 { success: false, error: "Unauthorized - Please log in" },
32 // 2. SECURITY: Validate ELINK access (allowed for retail stores)
33 const apiAccessValidation = validateApiAccess(context, 'elink');
34 if (!apiAccessValidation.valid) {
35 console.warn(`[API Security] ELINK access denied: ${apiAccessValidation.error}`);
36 return NextResponse.json(
39 error: apiAccessValidation.error,
40 code: apiAccessValidation.errorCode
46 const { searchParams } = new URL(request.url);
47 const mode = searchParams.get("mode") || "6";
48 const dimensions = searchParams.get("dimensions") || "";
49 const measures = searchParams.get("measures") || "tax_tot";
50 const dateFrom = searchParams.get("dateFrom") || "01-01-2025";
51 const dateTo = searchParams.get("dateTo") || "01-01-2026";
52 const minAmount = searchParams.get("minAmount") || "0";
53 const fromDate = searchParams.get("fromDate");
54 const toDate = searchParams.get("toDate");
56 // 3. Get store-specific API URL for ELINK
57 const apiUrl = getStoreApiUrl(context, 'elink');
58 const api = new FieldpineServerApi(apiUrl);
60 console.log(`[Sales Cube API] Loading for ${context.store.name} (mode: ${mode})`);
62 // Build parameters for sales cube
63 const params: Record<string, string | string[]> = {
64 "3": "retailmax.elink.sale.cube",
65 "100": mode, // Cube mode
66 "101": measures, // Measures to aggregate
70 // Use fromDate/toDate if provided (franchise report format), otherwise dateFrom/dateTo
71 if (fromDate && toDate) {
80 `f1008,5,${minAmount}`
84 // Add dimensions if specified
86 params["102"] = dimensions;
89 console.log(`[Sales Cube API] Fetching cube analysis`, {
90 store: context.store.name,
94 fromDate: fromDate || dateFrom,
95 toDate: toDate || dateTo
98 const result = await api.buckApiCall(params, context.session.apiKey);
100 // Return raw BUCK response for franchise report compatibility
101 return NextResponse.json(result);
102 } catch (error: any) {
103 console.error("[Sales Cube API] Error:", error);
104 return NextResponse.json(
105 { success: false, error: error.message || "Failed to fetch sales cube data" },
106 { status: error.status || 500 }