← back to Handbag Auth Nextjs
src/types/database.ts
209 lines
/**
* Database Type Definitions
* Replaces 'any' types with proper TypeScript types for type safety
*/
// Prisma Where Clause Types
export interface ListingWhereClause {
isActive?: number
isNew?: number
OR?: Array<{
title?: { contains: string; mode: 'insensitive' }
brand?: { contains: string; mode: 'insensitive' }
model?: { contains: string; mode: 'insensitive' }
seller?: { contains: string; mode: 'insensitive' }
location?: { contains: string; mode: 'insensitive' }
condition?: { contains: string; mode: 'insensitive' }
source?: { contains: string; mode: 'insensitive' }
externalId?: { contains: string; mode: 'insensitive' }
productUrl?: { contains: string; mode: 'insensitive' }
dealAnalysis?: {
aiNotes?: { contains: string; mode: 'insensitive' }
}
}>
brand?: { contains: string; mode: 'insensitive' } | string
model?: { contains: string; mode: 'insensitive' }
listingType?: string
priceUsd?: {
gte?: number
lte?: number
}
dealAnalysis?: {
isDeal?: number
dealPercentage?: {
gte?: number
}
}
}
export interface ListingOrderBy {
crawledAt?: 'asc' | 'desc'
priceUsd?: 'asc' | 'desc'
dealAnalysis?: {
dealPercentage?: 'asc' | 'desc'
}
}
export interface PriceAlertWhereClause {
listingId?: number
externalId?: string
userEmail?: string
}
export interface PriceHistoryWhereClause {
externalId?: string
listingId?: number
}
// API Response Types
export interface ApiResponse<T = unknown> {
success: boolean
error?: string
details?: unknown
data?: T
}
export interface PaginatedResponse<T> extends ApiResponse<T[]> {
count: number
total: number
page: number
totalPages: number
}
// Listing Types
export interface ListingFilters {
search?: string
brand?: string
model?: string
minPrice?: number
maxPrice?: number
type?: string
dealOnly?: boolean
showNew?: boolean
minDeal?: number
sort?: 'deal' | 'price-high' | 'price-low' | 'date'
limit?: number
page?: number
}
// Stats Types
export interface DatabaseStats {
totalListings: number
totalBrands: number
avgPrice: number
lastCrawl: string
}
export interface BrandStats {
brand: string
count: number
avgPrice: number
minPrice: number
maxPrice: number
}
// Crawler Types
export interface CrawlerStats {
totalListings: number
brands: number
merchants: number
newToday: number
brandProgress: Record<string, number>
}
export interface CrawlerStatus {
isRunning: boolean
logs: string[]
stats: CrawlerStats
}
// Price Alert Types
export interface CreatePriceAlertInput {
listingId: number
externalId: string
userEmail?: string
targetPrice: number
alertType?: 'below' | 'above' | 'change'
}
// Price History Types
export interface PriceHistoryRecord {
id: number
listingId: number
externalId: string
source: string
priceJpy: number
priceUsd?: number
condition?: string
listingType?: string
recordedAt: string
isAvailable: number
priceChange?: number | null
priceChangePercent?: number | null
}
// Admin Dashboard Types
export interface AdminStats {
totalGMV: number
monthlyGMV: number
totalUsers: number
activeInvestors: number
premiumSubscribers: number
totalRevenue: number
affiliateRevenue: number
fractionalRevenue: number
subscriptionRevenue: number
avgLTV: number
avgCAC: number
ltvcac: number
}
export interface GMVHistory {
month: string
gmv: number
revenue: number
}
// eBay API Types
export interface EbaySoldListing {
item_id: string
title: string
price_usd: number
currency: string
condition: string
end_time: string
location: string
url: string
image_url: string
}
export interface EbayStats {
count: number
avg_price: number
median_price: number
min_price: number
max_price: number
}
// Image Analysis Types
export interface ImageAnalysisResult {
brand: string
model: string
style: string
material: string
color: string
hardware: string
condition: string
hardware_condition: string
issues: string
authenticity_confidence: string
authenticity_markers: string
red_flags: string
estimated_value_low: number
estimated_value_high: number
current_market_value: number
best_platforms: string
market_notes: string
investment_rating: string
demand_level: string
}