mirror of
https://github.com/christianvidalwolf-prog/CrazeAnalytix.git
synced 2026-08-03 12:15:23 +02:00
115 lines
2.8 KiB
TypeScript
115 lines
2.8 KiB
TypeScript
|
|||
|
|
import { createClient } from '@supabase/supabase-js';
|
||
|
|
|
||
|
|
const supabaseUrl = process.env.SUPABASE_URL || '';
|
||
|
|
const supabaseAnonKey = process.env.SUPABASE_ANON_KEY || '';
|
||
|
|
|
||
|
|
export const supabase = createClient(supabaseUrl, supabaseAnonKey);
|
||
|
|
|
||
|
|
export interface VendorDailyRow {
|
||
|
|
id?: number;
|
||
|
|
date: string;
|
||
|
|
market: string;
|
||
|
|
asin: string;
|
||
|
|
product_title: string | null;
|
||
|
|
tags: string | null;
|
||
|
|
bsr_top_rank: number | null;
|
||
|
|
bsr_top_category: string | null;
|
||
|
|
bsr_detail_rank: number | null;
|
||
|
|
bsr_detail_category: string | null;
|
||
|
|
avg_rating: number | null;
|
||
|
|
num_reviews: number | null;
|
||
|
|
buybox_owner: string | null;
|
||
|
|
buybox_price: number | null;
|
||
|
|
amazon_has_buybox: boolean | null;
|
||
|
|
glance_views: number | null;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface VendorFilters {
|
||
|
|
markets?: string[];
|
||
|
|
tags?: string[];
|
||
|
|
asins?: string[];
|
||
|
|
dateFrom?: string;
|
||
|
|
dateTo?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export const fetchVendorData = async (filters: VendorFilters): Promise<VendorDailyRow[]> => {
|
||
|
|
const allRows: VendorDailyRow[] = [];
|
||
|
|
let offset = 0;
|
||
|
|
const pageSize = 1000;
|
||
|
|
let hasMore = true;
|
||
|
|
|
||
|
|
while (hasMore) {
|
||
|
|
let query = supabase
|
||
|
|
.from('vendor_daily_data')
|
||
|
|
.select('*')
|
||
|
|
.order('date', { ascending: true })
|
||
|
|
.range(offset, offset + pageSize - 1);
|
||
|
|
|
||
|
|
if (filters.markets?.length) {
|
||
|
|
query = query.in('market', filters.markets);
|
||
|
|
}
|
||
|
|
if (filters.tags?.length) {
|
||
|
|
query = query.in('tags', filters.tags);
|
||
|
|
}
|
||
|
|
if (filters.asins?.length) {
|
||
|
|
query = query.in('asin', filters.asins);
|
||
|
|
}
|
||
|
|
if (filters.dateFrom) {
|
||
|
|
query = query.gte('date', filters.dateFrom);
|
||
|
|
}
|
||
|
|
if (filters.dateTo) {
|
||
|
|
query = query.lte('date', filters.dateTo);
|
||
|
|
}
|
||
|
|
|
||
|
|
const { data, error } = await query;
|
||
|
|
if (error) throw error;
|
||
|
|
if (data) {
|
||
|
|
allRows.push(...data);
|
||
|
|
hasMore = data.length === pageSize;
|
||
|
|
offset += pageSize;
|
||
|
|
} else {
|
||
|
|
hasMore = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return allRows;
|
||
|
|
};
|
||
|
|
|
||
|
|
export const fetchVendorFilterOptions = async (): Promise<{
|
||
|
|
markets: string[];
|
||
|
|
tags: string[];
|
||
|
|
dateRange: { min: string; max: string } | null;
|
||
|
|
}> => {
|
||
|
|
const { data: marketData } = await supabase
|
||
|
|
.from('vendor_daily_data')
|
||
|
|
.select('market');
|
||
|
|
|
||
|
|
const { data: tagData } = await supabase
|
||
|
|
.from('vendor_daily_data')
|
||
|
|
.select('tags');
|
||
|
|
|
||
|
|
const { data: dateMin } = await supabase
|
||
|
|
.from('vendor_daily_data')
|
||
|
|
.select('date')
|
||
|
|
.order('date', { ascending: true })
|
||
|
|
.limit(1);
|
||
|
|
|
||
|
|
const { data: dateMax } = await supabase
|
||
|
|
.from('vendor_daily_data')
|
||
|
|
.select('date')
|
||
|
|
.order('date', { ascending: false })
|
||
|
|
.limit(1);
|
||
|
|
|
||
|
|
const markets = [...new Set((marketData || []).map(r => r.market))].sort();
|
||
|
|
const tags = [...new Set((tagData || []).map(r => r.tags).filter(Boolean))].sort();
|
||
|
|
|
||
|
|
return {
|
||
|
|
markets,
|
||
|
|
tags,
|
||
|
|
dateRange: dateMin?.[0] && dateMax?.[0]
|
||
|
|
? { min: dateMin[0].date, max: dateMax[0].date }
|
||
|
|
: null,
|
||
|
|
};
|
||
|
|
};
|