Files
CrazeAnalytix/types.ts
T
Christian Vidal WolfandQwen-Coder f93d92da0b Add complete Experiments tracking system
New Features:
- Experiments tab with full CRUD operations
- Create experiments by ASIN or product line groups
- Track pricing, advertising, content, and promotion experiments
- Performance analytics with baseline vs experiment comparison
- Visual experiment badges in Weekly Sales grid
- Experiment detail view with metrics and learnings

Technical Changes:
- Add Supabase experiments table migration
- New services/experiments.ts for CRUD + calculations
- New components: ExperimentsView, ExperimentDetail, ExperimentForm, ExperimentBadge
- Integrate experiment indicators in WeeklyGrid
- Add navigation tab (desktop + mobile)
- Type definitions in types.ts

Usage:
1. Run SQL migration in Supabase
2. Navigate to Experiments tab
3. Create experiments with ASINs, dates, hypothesis
4. View performance lift after completion
5. See active experiments marked in Weekly Sales

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-02-20 19:31:44 +01:00

354 lines
8.5 KiB
TypeScript

export interface SalesRecord {
id: string;
customer: string;
year: number;
month: string; // "Apr-23"
week?: number;
asin: string;
sku: string;
title: string; // Added Product Title
articleName: string; // Kept for backward compatibility if mixed files used
units: number;
sellOut: number; // Parsed numeric value
line: string;
}
export interface FilterState {
customer: string[];
year: string[];
month: string[];
line: string[];
asin: string[];
sku: string[];
title: string[]; // Added Title filter
week: string[]; // Added Week filter
stock: string[]; // Added Stock filter
vendorStock: string[]; // Added Vendor Stock filter
woc: string[]; // Added Weeks of Coverage filter
bulkSearch: string; // Added Bulk Search support
columnFilters: Record<string, ColumnFilterCondition>; // Added Excel-style column filters
}
export interface ColumnFilterCondition {
textFilter?: {
operator: 'equals' | 'notEquals' | 'contains' | 'notContains' | 'startsWith' | 'notStartsWith' | 'endsWith' | 'notEndsWith' | 'gt' | 'lt' | 'gte' | 'lte';
value: string;
};
selectedValues?: string[];
sort?: 'asc' | 'desc';
}
export interface GrowthMetric {
line: string;
currentYearSellOut: number;
previousYearSellOut: number;
sellOutGrowthValue: number;
sellOutGrowthPercentage: number;
currentYearUnits: number;
previousYearUnits: number;
unitsGrowthValue: number;
unitsGrowthPercentage: number;
}
export type LineGrowthMetric = GrowthMetric;
export interface ItemGrowthMetric {
sku: string;
asin: string;
title: string;
line: string;
currentYearSellOut: number;
previousYearSellOut: number;
sellOutGrowthValue: number;
sellOutGrowthPercentage: number;
currentYearUnits: number;
previousYearUnits: number;
unitsGrowthValue: number;
unitsGrowthPercentage: number;
}
export interface SeasonalityPoint {
name: string; // "Jan", "Feb", etc.
[year: string]: number | string; // Dynamic keys for years: "2023": 500, "2024": 600
}
export interface YearlySplitData {
name: string;
// Dynamic keys like "2023", "2024" or "2023_value", "2023_units"
[key: string]: number | string;
}
export interface AggregatedData {
totalSellOut: number;
totalUnits: number;
totalsByYear: Record<string, { sellOut: number; units: number }>;
byLine: { name: string; value: number; units: number }[];
byCustomer: { name: string; value: number }[];
seasonality: SeasonalityPoint[];
seasonalityUnits: SeasonalityPoint[];
availableYears: string[];
topMovers: GrowthMetric[];
bottomMovers: GrowthMetric[];
comparisonPeriods: { current: string; previous: string };
topLinesSplit: YearlySplitData[];
byCustomerSplit: YearlySplitData[];
byLineOverviewSplit: YearlySplitData[];
}
export interface ChatMessage {
role: 'user' | 'model';
text: string;
timestamp: Date;
}
// New Interfaces for Dynamic Pivot Grid
export interface YearlyData {
sellOut: number;
units: number;
}
export interface MonthlyPivot {
monthIndex: number;
byYear: Record<string, YearlyData>;
}
export interface PivotRow {
id: string;
customer: string;
line: string;
title: string; // Added Title
articleName: string;
sku: string;
asin: string;
// Dynamic buckets
totalsByYear: Record<string, YearlyData>;
months: MonthlyPivot[]; // Always 12 elements
// Ads data (optional, aggregated by ASIN)
adsByYear?: Record<string, {
adSpend: number;
attributedSales: number;
acos: number;
tacos: number;
}>;
}
export interface TimeSeriesData {
name: string; // e.g., "Apr '23" or "W21 '23"
sellOut: number;
units: number;
}
export interface ComparisonTimeSeriesPoint {
week: number;
name: string; // "W1", "W2", etc.
[key: string]: number | string; // Dynamic keys like "2023_sellOut", "2024_units"
}
export interface AdsRecord {
country: string; // Marketplace (Amazon DE, IT, ES, FR, UK)
year: number; // Year extracted from sheet name
week: number; // Week number (1-52)
asin: string;
cost: number; // Ad spend €
clicks: number;
impressions: number;
cpc: number; // Cost per click €
ctr: number; // Click-through rate %
acos: number; // Advertising cost of sale %
conversions: number; // Attributed conversions (30d)
attributedUnits30d: number;
attributedSales30d: number;
}
export interface TrafficRecord {
country: string; // Marketplace (DE, UK, etc.)
year: number;
week: number;
asin: string;
glanceViews: number; // Page views
}
export interface CombinedKPIs {
id: string;
marketplace: string;
customer: string; // Added for consistency with SalesRecord
month: string;
week: number; // Added for weekly analysis
year: number;
asin: string;
title: string;
line: string;
sku: string;
salesTotal: number;
unitsTotal: number;
salesAds: number;
unitsAds: number;
cost: number;
clicks: number;
impressions: number;
conversions: number;
salesOrganic: number;
unitsOrganic: number;
paidSalesShare: number;
organicSalesShare: number;
acos: number;
tacos: number;
roas: number;
ctr: number;
cpc: number;
cvrUnits: number;
glanceViews: number; // Traffic / page views
avgWeeklySales?: number; // Added for Weeks of Coverage
}
export interface ForecastRecord {
asin: string;
annualForecast: number;
sku?: string;
title?: string;
line?: string;
}
export interface MonthlyForecastPoint {
month: string;
forecastUnits: number;
actualUnits: number;
}
export interface ProductForecastData {
asin: string;
sku: string;
title: string;
line: string;
annualForecast: number;
actualUnits: number;
forecastUnits: number;
accuracy: number;
avgWeeklySales: number; // Added for Weeks of Coverage
monthlyData: Record<string, MonthlyForecastPoint>;
}
export interface BuyBoxLostData {
asin: string;
countries: string[]; // ['DE', 'FR', 'IT', 'UK', 'ES']
reasons: Record<string, string>; // { DE: 'Amazon', FR: 'Unknown' }
}
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 VendorCSVRow {
Date: string;
Market: string;
ASIN: string;
'Product Title': string;
Tags: string;
'Top Level Category (Rank)': string;
'Top Level Category (Name)': string;
'Detail Level Category (Rank)': string;
'Detail Level Category (Name)': string;
'Average Rating': string;
'Number of Reviews': string;
'Buybox Seller Name': string;
'Buybox Price': string;
'Amazon Has Buybox': string;
'Glance Views': string;
}
// Experiment Tracking Types
export type ExperimentType = 'pricing' | 'advertising' | 'content' | 'promotion';
export type ExperimentStatus = 'planned' | 'active' | 'completed' | 'paused';
export type ExperimentMetric = 'units' | 'revenue' | 'acos' | 'ctr' | 'cvr' | 'bsr';
export interface Experiment {
id: string;
name: string;
description?: string;
type: ExperimentType;
status: ExperimentStatus;
asins: string[];
marketplace: string;
start_date: string;
end_date?: string;
created_at: string;
updated_at: string;
hypothesis?: string;
primary_metric: ExperimentMetric;
target_lift_percent?: number;
// Results
baseline_units?: number;
baseline_revenue?: number;
experiment_units?: number;
experiment_revenue?: number;
actual_lift_percent?: number;
statistical_significance?: number;
learnings?: string;
owner?: string;
}
export interface ExperimentCreateInput {
name: string;
description?: string;
type: ExperimentType;
asins: string[];
marketplace: string;
start_date: string;
end_date?: string;
hypothesis?: string;
primary_metric: ExperimentMetric;
target_lift_percent?: number;
owner?: string;
}
export interface ExperimentListItem {
id: string;
name: string;
type: ExperimentType;
status: ExperimentStatus;
asin_count: number;
marketplace: string;
start_date: string;
end_date?: string;
progress_percent: number;
actual_lift_percent?: number;
owner?: string;
}
export interface ActiveExperiment {
asin: string;
experiment_id: string;
experiment_name: string;
type: ExperimentType;
status: ExperimentStatus;
start_date: string;
end_date?: string;
days_remaining?: number;
}