feat(category): 类目树、类目属性、属性字典维护系统构建完成

This commit is contained in:
R524809
2026-09-20 15:11:32 +08:00
parent 388429dbd0
commit 880e441bc6
48 changed files with 5127 additions and 1159 deletions
+69 -4
View File
@@ -56,6 +56,8 @@ export type ProductEditorCategoryOption = {
};
export type ProductAttributeSchema = {
/** Atlas 平台属性定义 UUID,用于精确限定同一类型下的字典作用域。 */
attribute_id: string;
platform_attribute_id: string;
complex_id: string;
name: string;
@@ -75,11 +77,46 @@ export type ProductAttributeSchema = {
| null;
};
export type ProductCatalogCacheStatus =
'fresh' | 'stale' | 'expired' | 'missing';
export type ProductCatalogCacheMetadata = {
status: ProductCatalogCacheStatus;
last_success_at: string | null;
fresh_until: string | null;
expires_at: string | null;
is_complete: boolean;
refresh_run_id: string | null;
refresh_status: string | null;
retry_after_ms: number | null;
};
export type ProductCatalogRefreshRun = {
id: string;
platform_id: string;
scope: string;
status: string;
trigger_kind: string;
priority: 'high' | 'low';
created_at: string;
};
export type ProductAttributeSchemaResult = {
items: ProductAttributeSchema[];
cache: ProductCatalogCacheMetadata;
};
export type ProductAttributeDictionaryValue = {
value_id: string;
value: string;
};
export type ProductAttributeDictionaryResult = {
items: ProductAttributeDictionaryValue[];
next_cursor: string | null;
cache: ProductCatalogCacheMetadata;
};
export type ProductEditorValidationIssue = {
code: string;
field: string;
@@ -102,10 +139,22 @@ export type ProductEditorValidation = {
}>;
};
/**
* M3.0 editor entry and read-model contracts. Draft mutation, pricing, and
* publishing DTOs intentionally stay out of this first editor slice.
*/
export type ProductPublishPreflight = {
status: 'ready' | 'blocked' | 'refreshing';
validation: ProductEditorValidation;
catalog: {
schema: ProductCatalogCacheMetadata;
dictionaries: Array<{
attribute_id: string;
platform_attribute_id: string;
name: string;
cache: ProductCatalogCacheMetadata;
}>;
};
refresh_runs: ProductCatalogRefreshRun[];
};
/** 商品编辑入口与完整读模型;真正的发布 job DTO 仍在后续纵向任务中定义。 */
export type ProductEditorContext = {
collection_item_id: string;
product_id: string;
@@ -369,6 +418,20 @@ export const productAiSourceMaterialOverridesSchema =
.partial()
.strict();
export const productPublishPreflightRequestSchema = z
.object({
variant_ids: z
.array(uuid)
.min(1)
.max(100)
.refine((ids) => new Set(ids).size === ids.length, 'SKU 不能重复'),
})
.strict();
export type ProductPublishPreflightRequest = z.infer<
typeof productPublishPreflightRequestSchema
>;
/** M3.1 intentionally covers editable product/profile/SKU fundamentals. */
export const saveProductEditorDraftRequestSchema = z
.object({
@@ -399,6 +462,8 @@ export const saveProductEditorDraftRequestSchema = z
title: nullableText(1_000),
description: nullableText(100_000),
tags: z.array(z.string().trim().min(1).max(100)).max(30),
platform_product_category_id: uuid.nullable().optional(),
/** 旧客户端过渡字段;服务端会按外部 ID 映射到平台类目。 */
store_product_category_id: uuid.nullable().optional(),
category_source: z
.enum(['source_capture', 'ai_suggestion', 'manual'])