From 6fee15d4aa76a69bae1b1aff46d002afef98eae7 Mon Sep 17 00:00:00 2001 From: WuYongJie Date: Tue, 2 Jun 2026 21:53:34 +0800 Subject: [PATCH] =?UTF-8?q?fix(data-foundation):=20=E6=94=BE=E8=A1=8C?= =?UTF-8?q?=E9=9D=9E=E9=9B=86=E6=88=90=20SKU=20=E5=86=B2=E7=AA=81=E8=B4=A8?= =?UTF-8?q?=E9=87=8F=E7=8A=B6=E6=80=81=E7=BA=A6=E6=9D=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migration.sql | 8 ++++++++ .../sql/check-internal-master-data-foundation.sql | 10 ++++++++++ .../scripts/verify-master-data-foundation.js | 6 ++++-- .../scripts/verify-master-data-foundation.test.js | 6 ++++-- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/furniture-3d-system/prisma/migrations/20260531143000_add_intake_master_data_check_constraints/migration.sql b/furniture-3d-system/prisma/migrations/20260531143000_add_intake_master_data_check_constraints/migration.sql index 4b4bac55..ebc51c92 100644 --- a/furniture-3d-system/prisma/migrations/20260531143000_add_intake_master_data_check_constraints/migration.sql +++ b/furniture-3d-system/prisma/migrations/20260531143000_add_intake_master_data_check_constraints/migration.sql @@ -83,6 +83,14 @@ BEGIN OR cardinality("missingRequiredFields") > 0 ) ) + OR + ( + "dataQualityStatus" = 'CONFLICT' + AND ( + NULLIF(btrim("skuCode"), '') IS NOT NULL + OR NULLIF(btrim("barcode"), '') IS NOT NULL + ) + ) ); END IF; END $$; diff --git a/furniture-3d-system/scripts/sql/check-internal-master-data-foundation.sql b/furniture-3d-system/scripts/sql/check-internal-master-data-foundation.sql index 6c417ba4..ad034b81 100644 --- a/furniture-3d-system/scripts/sql/check-internal-master-data-foundation.sql +++ b/furniture-3d-system/scripts/sql/check-internal-master-data-foundation.sql @@ -926,6 +926,7 @@ SELECT FROM "IntakeNonIntegratedSkuItem" sku JOIN "IntakeNonIntegratedProduct" product ON product."id" = sku."productId" WHERE product."deletedAt" IS NULL + AND sku."dataQualityStatus" = 'READY' AND NULLIF(btrim(sku."skuCode"), '') IS NOT NULL GROUP BY upper(btrim(sku."skuCode")) HAVING COUNT(*) > 1 @@ -938,11 +939,20 @@ SELECT FROM "IntakeNonIntegratedSkuItem" sku JOIN "IntakeNonIntegratedProduct" product ON product."id" = sku."productId" WHERE product."deletedAt" IS NULL + AND sku."dataQualityStatus" = 'READY' AND NULLIF(btrim(sku."barcode"), '') IS NOT NULL GROUP BY upper(btrim(sku."barcode")) HAVING COUNT(*) > 1 ORDER BY duplicate_count DESC, upper(btrim(sku."barcode")); +SELECT + 'intake_non_integrated_conflict_sku_risk' AS check_name, + COUNT(*)::integer AS row_count +FROM "IntakeNonIntegratedSkuItem" sku +JOIN "IntakeNonIntegratedProduct" product ON product."id" = sku."productId" +WHERE product."deletedAt" IS NULL + AND sku."dataQualityStatus" = 'CONFLICT'; + SELECT 'intake_non_integrated_incomplete_sku_risk' AS check_name, COUNT(*)::integer AS row_count diff --git a/furniture-3d-system/scripts/verify-master-data-foundation.js b/furniture-3d-system/scripts/verify-master-data-foundation.js index 7ce66251..ff0c046a 100644 --- a/furniture-3d-system/scripts/verify-master-data-foundation.js +++ b/furniture-3d-system/scripts/verify-master-data-foundation.js @@ -644,7 +644,7 @@ const REQUIRED_DATABASE_GUARDS = [ name: 'IntakeNonIntegratedSkuItem_quality_state_required_fields', relationName: 'IntakeNonIntegratedSkuItem', expressionPattern: 'dataQualityStatus', - purpose: '非集成 SKU 的 READY/INCOMPLETE 状态必须和必填字段、缺失字段数组一致。', + purpose: '非集成 SKU 的 READY/INCOMPLETE/CONFLICT 状态必须和必填字段、缺失字段数组、冲突身份一致。', }, { type: 'partial-unique-index', @@ -3111,7 +3111,8 @@ async function getStructuredSkuSummary(client) { SELECT COUNT(*)::integer AS total, COUNT(*) FILTER (WHERE "dataQualityStatus" = 'READY')::integer AS ready, - COUNT(*) FILTER (WHERE "dataQualityStatus" = 'INCOMPLETE')::integer AS incomplete + COUNT(*) FILTER (WHERE "dataQualityStatus" = 'INCOMPLETE')::integer AS incomplete, + COUNT(*) FILTER (WHERE "dataQualityStatus" = 'CONFLICT')::integer AS conflict FROM "IntakeNonIntegratedSkuItem" sku JOIN "IntakeNonIntegratedProduct" product ON product."id" = sku."productId" WHERE product."deletedAt" IS NULL @@ -3149,6 +3150,7 @@ async function getDuplicateGroupCount(client, columnName) { FROM "IntakeNonIntegratedSkuItem" sku JOIN "IntakeNonIntegratedProduct" product ON product."id" = sku."productId" WHERE product."deletedAt" IS NULL + AND sku."dataQualityStatus" = 'READY' AND NULLIF(btrim("${columnName}"), '') IS NOT NULL GROUP BY upper(btrim("${columnName}")) HAVING COUNT(*) > 1 diff --git a/furniture-3d-system/tests/scripts/verify-master-data-foundation.test.js b/furniture-3d-system/tests/scripts/verify-master-data-foundation.test.js index e5331331..c07c657c 100644 --- a/furniture-3d-system/tests/scripts/verify-master-data-foundation.test.js +++ b/furniture-3d-system/tests/scripts/verify-master-data-foundation.test.js @@ -1324,16 +1324,18 @@ describe('verify-master-data-foundation', () => { expect(query).toContain('product."deletedAt" IS NULL') if (query.includes('duplicate_groups')) { expect(query).toContain('upper(btrim("skuCode"))') + expect(query).toContain('sku."dataQualityStatus" = \'READY\'') return Promise.resolve({ rows: [{ duplicate_groups: 0 }] }) } - return Promise.resolve({ rows: [{ total: 3, ready: 2, incomplete: 1 }] }) + return Promise.resolve({ rows: [{ total: 4, ready: 2, incomplete: 1, conflict: 1 }] }) }), } await expect(getStructuredSkuSummary(client)).resolves.toEqual({ - total: 3, + total: 4, ready: 2, incomplete: 1, + conflict: 1, }) await expect(getDuplicateGroupCount(client, 'skuCode')).resolves.toBe(0) })