Files
route-commerce/src/actions/reports.ts
T

159 lines
4.6 KiB
TypeScript

"use server";
import { getAdminUser } from "@/lib/admin-permissions";
import { svcHeaders } from "@/lib/svc-headers";
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!;
const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;
export type DateRange = { start: string; end: string };
// ── Types ────────────────────────────────────────────────────────────────────
export type ReportsSummary = {
gross_sales: number;
total_orders: number;
avg_order_value: number;
pickup_orders: number;
shipping_orders: number;
pending_pickups: number;
completed_pickups: number;
contacts_added: number;
campaigns_sent: number;
messages_logged: number;
};
export type OrderByStop = {
stop_name: string;
city: string;
state: string;
date: string;
order_count: number;
gross_sales: number;
pending_count: number;
completed_count: number;
};
export type SalesByProduct = {
product_name: string;
units_sold: number;
gross_revenue: number;
avg_price: number;
};
export type FulfillmentRow = {
fulfillment_type: string;
order_count: number;
revenue: number;
pct_of_total: number;
};
export type PickupStatusByStop = {
stop_name: string;
city: string;
date: string;
total_orders: number;
pending: number;
completed: number;
canceled: number;
};
export type ContactGrowthRow = {
date: string;
new_contacts: number;
imports: number;
total: number;
};
export type CampaignActivityRow = {
campaign_name: string;
status: string;
campaign_type: string;
sent_at: string | null;
messages_logged: number;
};
// ── Internal fetch helper ────────────────────────────────────────────────────
async function reportRPC<T>(
rpcName: string,
params: { p_start_date: string; p_end_date: string },
forceBrandId: string | null
): Promise<T> {
const adminUser = await getAdminUser();
if (!adminUser) throw new Error("Not authenticated");
// brand_admin: always enforce their assigned brand (ignore UI selection)
// platform_admin: use forceBrandId (null = all brands)
const brandId = adminUser.role === "brand_admin"
? adminUser.brand_id
: forceBrandId;
const response = await fetch(`${supabaseUrl}/rest/v1/rpc/${rpcName}`, {
method: "POST",
headers: { ...svcHeaders(supabaseKey), "Content-Type": "application/json" },
body: JSON.stringify({
p_brand_id: brandId,
p_start_date: params.p_start_date,
p_end_date: params.p_end_date,
}),
});
if (!response.ok) {
const err = await response.text();
throw new Error(`RPC ${rpcName} failed: ${err}`);
}
return response.json() as Promise<T>;
}
// ── Report actions ──────────────────────────────────────────────────────────
export async function getReportsSummary(range: DateRange, brandId: string | null = null) {
return reportRPC<ReportsSummary>("get_reports_summary", {
p_start_date: range.start,
p_end_date: range.end,
}, brandId);
}
export async function getOrdersByStopReport(range: DateRange, brandId: string | null = null) {
return reportRPC<OrderByStop[]>("get_orders_by_stop_report", {
p_start_date: range.start,
p_end_date: range.end,
}, brandId);
}
export async function getSalesByProductReport(range: DateRange, brandId: string | null = null) {
return reportRPC<SalesByProduct[]>("get_sales_by_product_report", {
p_start_date: range.start,
p_end_date: range.end,
}, brandId);
}
export async function getFulfillmentReport(range: DateRange, brandId: string | null = null) {
return reportRPC<FulfillmentRow[]>("get_fulfillment_report", {
p_start_date: range.start,
p_end_date: range.end,
}, brandId);
}
export async function getPickupStatusByStop(range: DateRange, brandId: string | null = null) {
return reportRPC<PickupStatusByStop[]>("get_pickup_status_by_stop", {
p_start_date: range.start,
p_end_date: range.end,
}, brandId);
}
export async function getContactGrowthReport(range: DateRange, brandId: string | null = null) {
return reportRPC<ContactGrowthRow[]>("get_contact_growth_report", {
p_start_date: range.start,
p_end_date: range.end,
}, brandId);
}
export async function getCampaignActivityReport(range: DateRange, brandId: string | null = null) {
return reportRPC<CampaignActivityRow[]>("get_campaign_activity_report", {
p_start_date: range.start,
p_end_date: range.end,
}, brandId);
}