105 lines
3.1 KiB
TypeScript
105 lines
3.1 KiB
TypeScript
import { z } from 'zod';
|
|
|
|
export const listOnlineProductsQuerySchema = z
|
|
.object({
|
|
store_id: z.uuid().optional(),
|
|
cursor: z.string().min(1).optional(),
|
|
limit: z.coerce.number().int().min(1).max(100).default(20),
|
|
q: z.string().trim().max(200).optional(),
|
|
visibility: z
|
|
.enum(['all', 'visible', 'invisible', 'unknown'])
|
|
.default('all'),
|
|
source: z.enum(['atlas_published', 'external_sync']).optional(),
|
|
moderation_status: z.string().trim().max(100).optional(),
|
|
include_archived: z
|
|
.union([
|
|
z.boolean(),
|
|
z
|
|
.enum(['true', 'false'])
|
|
.transform((value) => value === 'true'),
|
|
])
|
|
.default(false),
|
|
})
|
|
.strict();
|
|
|
|
export const onlineProductSyncRequestSchema = z
|
|
.object({
|
|
reason: z.literal('manual_refresh').optional(),
|
|
})
|
|
.strict();
|
|
|
|
export const listOnlineProductSyncRunsQuerySchema = z
|
|
.object({
|
|
cursor: z.string().min(1).optional(),
|
|
limit: z.coerce.number().int().min(1).max(100).default(20),
|
|
})
|
|
.strict();
|
|
|
|
export type ListOnlineProductsQuery = z.infer<
|
|
typeof listOnlineProductsQuerySchema
|
|
>;
|
|
export type ListOnlineProductSyncRunsQuery = z.infer<
|
|
typeof listOnlineProductSyncRunsQuerySchema
|
|
>;
|
|
export type OnlineProductSource = 'atlas_published' | 'external_sync';
|
|
export type OnlineProductSyncStatus =
|
|
'queued' | 'running' | 'succeeded' | 'failed' | 'cancelled';
|
|
|
|
export type OnlineProduct = {
|
|
id: string;
|
|
store_id: string;
|
|
platform_id: string;
|
|
remote_product_id: string;
|
|
offer_id: string;
|
|
remote_sku: string | null;
|
|
name: string | null;
|
|
currency_code: string | null;
|
|
selling_price: string | null;
|
|
list_price: string | null;
|
|
visible: boolean | null;
|
|
remote_state: string | null;
|
|
moderation_status: string | null;
|
|
validation_status: string | null;
|
|
stock_summary: { total: number; has_data: boolean };
|
|
image: {
|
|
url: string | null;
|
|
width_px: number | null;
|
|
height_px: number | null;
|
|
};
|
|
errors: Array<{ code?: string; message: string }>;
|
|
visibility_details: Record<string, unknown>;
|
|
source: OnlineProductSource;
|
|
atlas_origin: {
|
|
collection_item_id: string;
|
|
product_id: string;
|
|
variant_id: string;
|
|
} | null;
|
|
last_synced_at: string;
|
|
missing_since: string | null;
|
|
archived_at: string | null;
|
|
};
|
|
|
|
export type OnlineProductSyncRun = {
|
|
id: string;
|
|
store_id: string;
|
|
status: OnlineProductSyncStatus;
|
|
trigger_source: 'manual' | 'scheduled' | 'recovery';
|
|
cursor_started: string | null;
|
|
cursor_finished: string | null;
|
|
listed_count: number;
|
|
upserted_count: number;
|
|
failed_count: number;
|
|
created_at: string;
|
|
started_at: string | null;
|
|
completed_at: string | null;
|
|
error: { code: string; message: string } | null;
|
|
};
|
|
|
|
export type OnlineProductsMeta = {
|
|
next_cursor: string | null;
|
|
has_more: boolean;
|
|
store: { id: string; name: string };
|
|
last_successful_sync_at: string | null;
|
|
last_sync_status: OnlineProductSyncStatus | null;
|
|
};
|