Files
asin-check/src/types.ts
Victor Noguera 923ebbaec5 Refactor supplier analysis and product handling
- Updated `SupplierAnalysisResult` to include a `product` field and modified related tests.
- Refactored `addRowsSheet` to accommodate changes in the product structure.
- Enhanced UPC file analysis to utilize a new `toSupplierInputRecord` function for cleaner record creation.
- Introduced new types for supplier input records and product observations.
- Updated frontend components to handle new product details and analysis history.
- Improved database writing functions to streamline run completion and error handling.
- Added new API endpoints for product details and adjusted routing in the frontend.
2026-05-25 12:27:41 -04:00

220 lines
4.7 KiB
TypeScript

export interface ProductRecord {
asin: string;
name: string;
unitCost: number;
brand?: string;
category?: string;
amazonRank?: number;
avgPrice90FromSheet?: number;
sellingPriceFromSheet?: number;
fbaNet?: number;
grossProfit?: number;
grossProfitPct?: number;
netProfitFromSheet?: number;
roiFromSheet?: number;
moq?: number;
moqCost?: number;
totalQtyAvail?: number;
link?: string;
asinLink?: string;
sourceUrl?: string;
supplier?: string;
promoCouponCode?: string;
notes?: string;
leadDate?: string;
[key: string]: unknown;
}
export interface KeepaData {
currentPrice: number | null;
avgPrice90: number | null;
minPrice90: number | null;
maxPrice90: number | null;
salesRank: number | null;
salesRankAvg90: number | null;
salesRankDrops30: number | null;
salesRankDrops90: number | null;
sellerCount: number | null;
amazonIsSeller: boolean | null;
amazonBuyboxSharePct90d: number | null;
buyBoxSeller: string | null;
buyBoxPrice: number | null;
buyBoxAvg90?: number | null;
monthlySold: number | null;
categoryTree: string[];
}
export type KeepaUpcLookupStatus =
| "found"
| "invalid_upc"
| "not_found"
| "multiple_asins"
| "request_failed";
export interface KeepaUpcLookupDetail {
requestedUpc: string;
normalizedUpc: string;
status: KeepaUpcLookupStatus;
asin: string | null;
candidateAsins: string[];
keepaData: KeepaData | null;
provider?: "sp_api" | "keepa";
reason?: string;
}
export type UpcLookupDetail = KeepaUpcLookupDetail;
export type SellabilityInfo = {
canSell: boolean | null;
sellabilityStatus: "available" | "restricted" | "not_available" | "unknown";
sellabilityReason?: string;
};
export interface SpApiData extends SellabilityInfo {
fbaFee: number;
fbmFee: number;
referralFeePercent: number;
estimatedSalePrice: number;
}
export interface EnrichedProduct {
record: ProductRecord;
keepa: KeepaData | null;
spApi: SpApiData;
fetchedAt: string;
}
export interface LlmVerdict {
asin: string;
verdict: "FBA" | "FBM" | "SKIP";
confidence: number;
reasoning: string;
}
export interface AnalysisResult {
product: EnrichedProduct;
verdict: LlmVerdict;
}
export type SupplierVerdict = "BUY" | "WATCH" | "SKIP";
export interface SupplierScore {
salePrice: number | null;
fbaFee: number | null;
profit: number | null;
margin: number | null;
roi: number | null;
demandScore: number;
competitionPenalty: number;
score: number;
verdict: SupplierVerdict;
reason: string;
}
export interface SupplierAnalysisResult {
upc: string;
rowNumber?: number;
record: SupplierInputRecord;
product: ProductRecord | null;
lookup: UpcLookupDetail;
keepa: KeepaData | null;
spApi: SpApiData | null;
score: SupplierScore;
fetchedAt: string;
}
export interface SupplierInputRecord {
name: string;
unitCost: number;
brand?: string;
category?: string;
}
export interface Product {
asin: string;
name: string | null;
brand: string | null;
category: string | null;
firstSeenAt: string;
lastSeenAt: string;
}
export interface ProductObservation {
id: number;
productAsin: string;
runId: number;
source: string;
fetchedAt: string;
}
export interface Run {
id: number;
type:
| "lead_analysis"
| "category_analysis"
| "supplier_upc"
| "stalker"
| "stalker_analysis";
parentRunId?: number | null;
status: string;
}
export interface RunItem {
id: number;
runId: number;
productAsin: string | null;
sourceRow?: number | null;
}
export interface AnalysisRevision {
id: number;
runItemId: number;
decision: "FBA" | "FBM" | "BUY" | "WATCH" | "SKIP";
confidence: number | null;
reasoning: string | null;
analyzedAt: string;
}
export interface CategoryRunSummaryDb {
categoryId: number;
categoryLabel: string;
runTimestamp: string;
topAsinsChecked: number;
availableAsins: number;
fbaCount: number;
fbmCount: number;
skipCount: number;
status: "ok" | "empty" | "failed";
errorMessage?: string;
}
export interface ProductAnalysisResultDb {
asin: string;
runId: number;
name: string;
brand?: string;
category?: string;
unitCost?: number;
currentPrice?: number;
avgPrice90d?: number;
avgPrice90dSheet?: number;
sellingPriceSheet?: number;
salesRank?: number;
salesRankAvg90d?: number;
sellerCount?: number;
monthlySold?: number;
rankDrops30d?: number;
rankDrops90d?: number;
fbaFee?: number;
fbmFee?: number;
referralPercent?: number;
canSell?: string;
sellabilityStatus?: string;
sellabilityReason?: string;
verdict: string;
confidence: number;
reasoning?: string;
fetchedAt: string;
}