fix: enforce stable shadow snapshot boundaries

This commit is contained in:
zgw
2026-09-03 15:07:37 +08:00
parent 935d7af43d
commit d77fac1d56
12 changed files with 256 additions and 88 deletions

View File

@@ -86,6 +86,24 @@ class JdbcWarehouseRepositoryTest {
assertThat(space(lanes, "OUT-INNER").state().zoneCode()).isEqualTo("FLEX");
}
@Test
void publishedReadModelJoinsDoNotCrossWarehouseBoundaries() throws Exception {
execute("INSERT INTO BAS_CARGO_SPACE VALUES ('SHARED-SPACE','W1','R','A','Shared id',9,90,1,'2','',"
+ "'TRAY-W1','SHARED-LANE','1')");
execute("INSERT INTO ALG_INVENTORY_ITEM_SNAPSHOT (WAREHOUSE_ID, STOCK_ID, SPACE_ID, TRAY_CODE, "
+ "PROJECT_NO, PRODUCT_NO, LOT_NO, INBOUND_TIME_RAW, INBOUND_AT, QUANTITY, OUT_QUANTITY) "
+ "VALUES ('W2','CROSS-W2','SHARED-SPACE',NULL,'PROJECT-W2','SKU-W2','LOT-W2',"
+ "'2026-09-03 00:00:00',TIMESTAMP '2026-09-03 00:00:00',1,0)");
rebuildTopology("W1");
List<LaneSnapshot> lanes = repository.loadLaneSnapshots("W1", List.of("SHARED-LANE"));
assertThat(space(lanes, "SHARED-SPACE").inventory()).isEmpty();
assertThat(repository.searchOutboundStock("W1", OutboundStockSearch.project("PROJECT-W2", null)))
.isEmpty();
assertThat(repository.countProjectPallets("W1", "PROJECT-W2")).isZero();
}
@Test
void statusFourPhysicalOuterPalletIsPreservedAndMakesDeepOutboundWait() throws Exception {
execute("INSERT INTO BAS_CARGO_SPACE VALUES ('ALLOC-TARGET','W1','RA','A','Target',7,21,2,'2','',"

View File

@@ -208,6 +208,25 @@ class ShadowSqlServerMigrationScriptTest {
"snapshot_generation = @snapshot_generation");
}
@Test
void refreshPreservesRawRequestWarehouseUnderAuthoritativeSnapshotWarehouse() throws IOException {
for (String script : new String[]{"db/sqlserver/install-shadow.sql",
"db/sqlserver/upgrade-shadow-v2-to-v3.sql"}) {
String refresh = normalize(resource(script));
refresh = refresh.substring(refresh.indexOf("create procedure alg.usp_refresh_shadow_snapshot"));
assertThat(refresh).as(script).contains(
"select @warehouse_id, isnull(task_no, ''), isnull(tray_code, ''), request_id, raw_warehouse_id",
"select @warehouse_id, outbound.stockout_detail_id, outbound.warehouse_id",
"left join dbo.bas_warehouse warehouse with (nolock)",
"nullif(ltrim(rtrim(warehouse.project_no)), '')",
"job.finish_time is null or ltrim(rtrim(job.finish_time)) = ''",
"isnull(outbound.quantity, 0) > isnull(outbound.allot_quantity, 0)");
assertThat(refresh).as(script).doesNotContain(
"select outbound.warehouse_id, outbound.stockout_detail_id, outbound.warehouse_id, null");
}
}
@Test
void plannerViewsContainOnlyGenerationQualifiedAlgSnapshots() throws IOException {
String install = normalize(resource("db/sqlserver/install-shadow.sql"));

View File

@@ -178,6 +178,7 @@ $$;
CREATE VIEW ALG_V_INVENTORY_ITEM AS
SELECT
WAREHOUSE_ID, CAST(0 AS BIGINT) AS SNAPSHOT_GENERATION,
STOCK_ID, SPACE_ID, TRAY_CODE, PROJECT_NO, PRODUCT_NO, LOT_NO,
INBOUND_TIME_RAW, INBOUND_AT, QUANTITY, OUT_QUANTITY
FROM ALG_INVENTORY_ITEM_SNAPSHOT;
@@ -281,6 +282,7 @@ LANE_GAPS AS (
SELECT
C.CARGO_SPACE_ID AS SPACE_ID,
C.WAREHOUSE_ID,
CAST(0 AS BIGINT) AS SNAPSHOT_GENERATION,
C.GROUP_CODING_NO AS LANE_CODE,
C.CARGO_AREA_ID AS AREA_ID,
CASE