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) })