feat: gate overseas receiving and harden phase4 workflows

This commit is contained in:
2026-08-25 10:31:04 +08:00
parent cb78bc6b41
commit 52b9fc382f
93 changed files with 2779 additions and 201 deletions
@@ -11,6 +11,8 @@ import com.baiyue.lastleg.security.InternalServiceTokenGuard;
import com.baiyue.lastleg.security.OverseasPermissions;
import com.baiyue.lastleg.service.LastlegOrderService;
import com.baiyue.lastleg.service.LoadingCompletedConsumer;
import com.baiyue.lastleg.shipping.service.ContainerShippingNodeConsumer;
import com.baiyue.common.event.EventTypes;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
@@ -37,17 +39,20 @@ import java.nio.charset.StandardCharsets;
@Tag(name = "Tail-leg orders")
public class LastlegOrderController {
@Resource private LoadingCompletedConsumer consumer;
@Resource private ContainerShippingNodeConsumer shippingNodeConsumer;
@Resource private LastlegOrderService orderService;
@Resource private InternalServiceTokenGuard tokenGuard;
@PostMapping("/internal/lastleg/events")
@Operation(summary = "Receive a first-leg loading-completed event",
description = "V2 orders[].destinationType is FBA or OVERSEAS. FBA may use package counts; OVERSEAS requires one carton mark per loaded package. Legacy events are accepted only when the destination type can be inferred safely.")
@Operation(summary = "Receive a first-leg loading or actual shipping-node event",
description = "Accepts loading-completed V1/V2 and FirstLegContainerShippingNodeRecorded V1 through the internal token boundary; only monotonic actual PICKUP_READY-or-later facts open overseas PDA receiving.")
public ApiResponse<Integer> receive(
@RequestHeader(value = "X-Internal-Service-Token", required = false) String token,
@RequestBody EventEnvelope event) {
tokenGuard.verify(token);
return ApiResponse.success(consumer.consume(event));
int consumed = EventTypes.FIRST_LEG_CONTAINER_SHIPPING_NODE_RECORDED.equals(event.eventType())
? shippingNodeConsumer.consume(event) : consumer.consume(event);
return ApiResponse.success(consumed);
}
@GetMapping("/api/platform/v1/last-leg/orders")