优化
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
|
||||
| 目标 | 入口 |
|
||||
|---|---|
|
||||
| 内部模块化基线与依赖分析 | `docs/firstleg-internal-modularization-baseline.md`、`scripts/analyze-firstleg-dependencies.mjs`、`scripts/analyze-firstleg-dependencies.test.mjs`、`src/test/resources/architecture/firstleg-slice-dependencies.json`;只约束本服务内部包依赖,不改变部署单元或数据库边界 |
|
||||
| 履约任务/分配 | `controller/PlatformFulfillmentAssignmentController.java`、`service/FulfillmentTaskService.java` |
|
||||
| 入库单查询/聚合 | `controller/PlatformInboundOrderController.java`、`service/InboundOrderQueryService.java` |
|
||||
| 平台测量/OCR | `controller/PlatformInboundMeasurementController.java`、`service/InboundMeasurementService.java`、`service/CartonMeasurementService.java`;手工单箱测量也从该 Controller 与 `CartonMeasurementService` 进入 |
|
||||
@@ -22,6 +23,7 @@
|
||||
| 客户费用查询 | `controller/MerchantInboundBillingController.java`、`service/MerchantInboundBillingService.java` |
|
||||
| 客户运营统计/在途柜量 | `customerstatistics/controller/PlatformCustomerTransitStatisticsController.java`、`customerstatistics/service/CustomerTransitStatisticsService.java`;契约见 `src/main/resources/openapi/customer-statistics-v1.yaml` |
|
||||
| 费用项目与价格簿 | `controller/PlatformFeeItemController.java`、`PlatformPriceBookController.java`、`MerchantPriceBookController.java` |
|
||||
| 价格簿查询内部切片 | `pricebookquery/application/port/in/PriceBookQueryUseCase.java`、`application/PriceBookQueryService.java`、`application/port/out/PriceBookQueryReader.java`、`adapter/out/persistence/PriceBookQueryMapper.java`;查询行模型位于 `application/model/PriceBookQueryRows.java` |
|
||||
| 财务费用来源快照 | `controller/InternalFinanceFeeSourceController.java`;入库费用与柜次费用分别按来源 ID、版本向 Finance 提供不可变快照 |
|
||||
| 柜次费用明细 | `controller/PlatformContainerFeeDetailController.java`、`service/ContainerFeeDetailService.java`、`dto/ContainerFeeDetailDtos.java`;Admin 消费端见 `../../apps/admin-web/src/modules/loading-lists/api/containerFees.ts` |
|
||||
| 财务整柜成本分摊快照 | `loading/controller/InternalFinanceCostSnapshotController.java`、`loading/service/FinanceCostSnapshotService.java` |
|
||||
@@ -44,7 +46,9 @@
|
||||
|
||||
## 修改约束
|
||||
|
||||
- 移动包、拆分端口/适配器或引入新的跨切片依赖时,先核对内部模块化基线并运行 `node --test scripts/analyze-firstleg-dependencies.test.mjs`;确需更新依赖基线时必须说明稳定边界变化,不能把临时循环依赖登记为长期豁免。
|
||||
- 平台接口必须校验目标客户、权限、乐观锁、幂等键、历史和审计;商户查询只能使用登录态客户。
|
||||
- 价格簿查询消费者依赖 `PriceBookQueryUseCase` 或稳定查询端口,不得反向依赖持久化 Mapper;移动旧查询类时同步更新生产调用、测试、Mock 与 import,避免同一职责在根 `repository/mapper` 和 `pricebookquery/` 双写。
|
||||
- 第三方回传必须签名、时间窗、防重放、请求哈希,并绑定订单货物和 File 证据;不得信任外部客户字段。
|
||||
- 稳定箱码映射以入库快照和 Order 货物明细为事实;订单审核创建入库单时必须幂等生成,打印接口只复用或补齐同一映射,用户是否下载箱唛不得决定箱码有效性。手工测量、墨家设备和 PDA 扫码统一通过 `InboundCartonLabelService` 校验客户、入库单、货物明细、总箱数/下标和有效批次,不得在测量时临时伪造箱码或接受跨客户、跨入库箱码。
|
||||
- 测量审核通过后直接进入 `WAIT_SPLIT`,费用仅作为独立初算和人工维护结果,不得阻塞或回退订单主流程;计费量、单价和附加费调整必须版本化并由服务端重算金额。状态或 DTO 变更时逐个检查 Order/Warehouse/File/Integration 消费者。
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Firstleg 内部模块化基线与首切片方案
|
||||
# Firstleg 内部模块化基线与切片实施记录
|
||||
|
||||
## 1. 范围与生成方式
|
||||
|
||||
@@ -198,3 +198,53 @@ mvn -pl firstleg -am -Dtest=CustomerTransitStatisticsServiceTest,CustomerTransit
|
||||
- 根 Mapper 扫描只把旧精确包替换为新精确包,没有扩大扫描范围或增加兼容 Bean。
|
||||
- 验证结果:Node 合同 3/3;`test-compile` 成功;客户统计加根扫描定向测试 7/7;`mvn -pl firstleg -am test` 共 854 个测试,0 失败、0 错误、3 跳过,构建成功。
|
||||
- 首次并发执行 `test-compile` 时,其他专项同时写入共享 `target/classes` 导致若干无关 class 文件瞬时缺失;源符号核对正常,独立重跑 `test-compile` 与完整测试均成功。
|
||||
|
||||
## 12. 第二切片:价格簿只读查询
|
||||
|
||||
### 12.1 选择证据
|
||||
|
||||
第二切片选择 `pricebook-query`,而没有选择报关、拖车、出仓或船节点:
|
||||
|
||||
- 原实现只有 `PriceBookQueryRows`、`PriceBookQueryRepository`、`PriceBookQueryMapper` 三个核心文件,全部为只读查询,不承载 Controller、权限或状态机。
|
||||
- `PriceBookQueryMapper -> repository.PriceBookQueryRows` 是主源码唯一 `mapper -> repository` 反向依赖,也是物理包 SCC `mapper <-> repository` 的唯一成因。
|
||||
- 报关和拖车均涉及 MultipartFile、Feign、装柜或出仓门禁;出仓和船节点属于当前业务热点,风险高于只读价格簿查询。
|
||||
- 本切片不触碰 `LoadingPickService`、客户尺寸初始化、IAM 解环、POM、CI、AGENTS、SQL 或部署配置。
|
||||
|
||||
### 12.2 目标结构与依赖方向
|
||||
|
||||
```text
|
||||
pricebookquery/
|
||||
application/
|
||||
PriceBookQueryService.java
|
||||
model/PriceBookQueryRows.java
|
||||
port/in/PriceBookQueryUseCase.java
|
||||
port/out/PriceBookQueryReader.java
|
||||
adapter/out/persistence/
|
||||
PriceBookQueryMapper.java
|
||||
```
|
||||
|
||||
依赖由“多个业务 Service -> 全局 Repository -> 全局 Mapper -> Repository Rows”改为:
|
||||
|
||||
```text
|
||||
业务消费者 -> PriceBookQueryUseCase
|
||||
PriceBookQueryService -> PriceBookQueryReader
|
||||
PriceBookQueryMapper -> PriceBookQueryReader + PriceBookQueryRows
|
||||
```
|
||||
|
||||
消费者只能访问 In Port 和只读模型;application 不依赖 Spring MVC、MyBatis、MyBatis-Plus 或其他 Firstleg 切片。Mapper 的七段 `@Select` SQL 文本和方法参数保持不变。
|
||||
|
||||
### 12.3 依赖图变化
|
||||
|
||||
- 主源码由 430 类/949 条内部依赖/67 包变为 432 类/953 条内部依赖/72 包;新增项为 In Port、Out Port 和 Application Service,原 Repository 被删除。
|
||||
- 物理包多节点 SCC 从 1 个降为 0 个。
|
||||
- `pricebook-query` 是零出向边的叶子,不进入逻辑 SCC;显式入向仅为订舱、测量计价、分柜装柜三个消费者切片。
|
||||
- 原 `split-loading -> measurement-pricing` 两条价格簿引用被替换为显式 `split-loading -> pricebook-query`;Node 合同没有简单放宽旧边。
|
||||
- 既有 88 条跨切片 Entity/DTO 泄漏和 31 条 Mapper 泄漏均未增加。
|
||||
|
||||
### 12.4 棘轮与回滚边界
|
||||
|
||||
- Node 合同锁定五个目标类位置、application 依赖禁令、零出向/三类入向和消费者只能访问 In Port/模型,并断言物理包 SCC 为空。
|
||||
- `PriceBookQueryArchitectureTest` 用 ArchUnit 执行同等边界,持久化 Mapper 必须实现 Out Port。
|
||||
- 回滚仅恢复原三文件及消费者类型引用;不涉及 URI、权限、JSON、SQL、表结构、业务状态或环境配置。
|
||||
- 只读模型仍保留原 Lombok 可变 Bean 形态以维持 MyBatis 映射行为;本轮不顺带改造成不可变领域对象。
|
||||
- 验证结果:七段 `@Select` SQL 文本逐块完全一致;Node 合同 5/5;`test-compile` 成功;价格簿、ArchUnit、根扫描及三个消费者切片定向测试 78/78;Firstleg 聚合全量 878 个测试,0 失败、0 错误、3 跳过,构建成功。
|
||||
|
||||
@@ -13,6 +13,7 @@ const internalPrefix = 'com.baiyue.firstleg.';
|
||||
|
||||
const sliceRules = [
|
||||
['customer-statistics', /(?:^|\.)(?:customerstatistics)(?:\.|$)/],
|
||||
['pricebook-query', /(?:^|\.)(?:pricebookquery)(?:\.|$)/],
|
||||
['finance-integration', /(?:InternalFinance|FinanceFeeSource|FinanceCostSnapshot|FeePaymentVoucher|FeePaymentSnapshot|ContainerFeeSourceSnapshot)/],
|
||||
['shipping-nodes', /(?:CarrierScheduleQuery|CarrierScheduleNode|CarrierScheduleAdapter|CarrierScheduleAttempt|CarrierScheduleException)/],
|
||||
['booking-customs-trucking', /(?:^|\.)(?:oceanbooking|customs)(?:\.|$)|(?:TruckAppointment|WarehouseSupplier|PortSchedule|DispatchGate)/],
|
||||
@@ -273,8 +274,9 @@ function checkContract(report, contractPath) {
|
||||
if (!actualClass) violations.push(`required class missing: ${fqcn}`);
|
||||
else if (actualClass.file !== expectedFile) violations.push(`class location changed: ${fqcn} (${actualClass.file})`);
|
||||
}
|
||||
const applicationRule = contract.applicationDependencyRule;
|
||||
if (applicationRule) {
|
||||
const applicationRules = contract.applicationDependencyRules
|
||||
?? (contract.applicationDependencyRule ? [contract.applicationDependencyRule] : []);
|
||||
for (const applicationRule of applicationRules) {
|
||||
const applicationClasses = report.classes.filter(entry => entry.packageName.startsWith(applicationRule.packagePrefix));
|
||||
for (const entry of applicationClasses) {
|
||||
for (const imported of entry.imports) {
|
||||
@@ -291,6 +293,15 @@ function checkContract(report, contractPath) {
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const exposureRule of contract.sliceExposureRules ?? []) {
|
||||
for (const edge of report.classDependencies) {
|
||||
if (!edge.source.startsWith(exposureRule.slicePrefix)
|
||||
&& edge.target.startsWith(exposureRule.slicePrefix)
|
||||
&& !(exposureRule.allowedTargetPrefixes ?? []).some(prefix => edge.target.startsWith(prefix))) {
|
||||
violations.push(`forbidden slice implementation dependency: ${edge.source} -> ${edge.target}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const [slice, rule] of Object.entries(contract.sliceSpecificRules ?? {})) {
|
||||
const outgoing = report.sliceEdges.filter(edge => edge.source === slice).map(edge => edge.target).sort();
|
||||
const incoming = report.sliceEdges.filter(edge => edge.target === slice).map(edge => edge.source).sort();
|
||||
|
||||
@@ -52,3 +52,43 @@ test('customer statistics application layer only depends inward', () => {
|
||||
&& edge.target.startsWith('com.baiyue.firstleg.') && !edge.target.startsWith(prefix));
|
||||
assert.deepEqual(outwardDependencies, []);
|
||||
});
|
||||
|
||||
test('price book query is a leaf slice and removes the package cycle', () => {
|
||||
const report = analyze();
|
||||
const classes = report.classes.filter(entry => entry.slice === 'pricebook-query');
|
||||
assert.deepEqual(classes.map(entry => entry.fqcn).sort(), [
|
||||
'com.baiyue.firstleg.pricebookquery.adapter.out.persistence.PriceBookQueryMapper',
|
||||
'com.baiyue.firstleg.pricebookquery.application.PriceBookQueryService',
|
||||
'com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows',
|
||||
'com.baiyue.firstleg.pricebookquery.application.port.in.PriceBookQueryUseCase',
|
||||
'com.baiyue.firstleg.pricebookquery.application.port.out.PriceBookQueryReader',
|
||||
]);
|
||||
assert.deepEqual(report.sliceEdges.filter(edge => edge.source === 'pricebook-query'), []);
|
||||
assert.deepEqual(report.sliceEdges.filter(edge => edge.target === 'pricebook-query')
|
||||
.map(edge => edge.source).sort(), ['booking-customs-trucking', 'measurement-pricing', 'split-loading']);
|
||||
assert.equal(report.sliceSccs.some(component => component.includes('pricebook-query')), false);
|
||||
assert.deepEqual(report.packageSccs, []);
|
||||
});
|
||||
|
||||
test('price book query application and consumers respect ports', () => {
|
||||
const report = analyze();
|
||||
const prefix = 'com.baiyue.firstleg.pricebookquery.application';
|
||||
const applicationClasses = report.classes.filter(entry => entry.packageName.startsWith(prefix));
|
||||
assert.equal(applicationClasses.length, 4);
|
||||
for (const entry of applicationClasses) {
|
||||
assert.equal(entry.imports.some(imported => imported.startsWith('org.springframework.web')), false);
|
||||
assert.equal(entry.imports.some(imported => imported.startsWith('org.apache.ibatis')), false);
|
||||
assert.equal(entry.imports.some(imported => imported.startsWith('com.baomidou.mybatisplus')), false);
|
||||
}
|
||||
const outwardDependencies = report.classDependencies.filter(edge => edge.source.startsWith(prefix)
|
||||
&& edge.target.startsWith('com.baiyue.firstleg.') && !edge.target.startsWith(prefix));
|
||||
assert.deepEqual(outwardDependencies, []);
|
||||
const allowedTargets = [
|
||||
'com.baiyue.firstleg.pricebookquery.application.model.',
|
||||
'com.baiyue.firstleg.pricebookquery.application.port.in.',
|
||||
];
|
||||
const implementationLeaks = report.classDependencies.filter(edge => !edge.source.startsWith('com.baiyue.firstleg.pricebookquery.')
|
||||
&& edge.target.startsWith('com.baiyue.firstleg.pricebookquery.')
|
||||
&& !allowedTargets.some(prefixValue => edge.target.startsWith(prefixValue)));
|
||||
assert.deepEqual(implementationLeaks, []);
|
||||
});
|
||||
|
||||
@@ -18,7 +18,8 @@ import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
"com.baiyue.firstleg.outbound.dispatch.mapper",
|
||||
"com.baiyue.firstleg.portschedule.mapper",
|
||||
"com.baiyue.firstleg.customs.mapper",
|
||||
"com.baiyue.firstleg.customerstatistics.adapter.out.persistence"
|
||||
"com.baiyue.firstleg.customerstatistics.adapter.out.persistence",
|
||||
"com.baiyue.firstleg.pricebookquery.adapter.out.persistence"
|
||||
})
|
||||
@EnableFeignClients(basePackages = "com.baiyue.firstleg")
|
||||
@EnableScheduling
|
||||
|
||||
+4
-4
@@ -11,9 +11,9 @@ import com.baiyue.firstleg.domain.ContainerSpecificationCatalog;
|
||||
import com.baiyue.firstleg.oceanbooking.dto.OceanBookingDtos.*;
|
||||
import com.baiyue.firstleg.oceanbooking.entity.*;
|
||||
import com.baiyue.firstleg.oceanbooking.repository.OceanBookingRepository;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRepository;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.ChannelRow;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.ChannelTaxModeRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelTaxModeRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.port.in.PriceBookQueryUseCase;
|
||||
import com.baiyue.firstleg.service.WarehouseSupplierSnapshotService;
|
||||
import com.baiyue.firstleg.service.FirstlegDocumentNumberGenerator;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
@@ -39,7 +39,7 @@ public class OceanBookingService {
|
||||
private static final Set<OceanBookingStatus> OPERATIONAL_LIST_STATUSES = Set.of(
|
||||
OceanBookingStatus.DRAFT, OceanBookingStatus.RELEASED);
|
||||
@Resource private OceanBookingRepository repository;
|
||||
@Resource private PriceBookQueryRepository priceBooks;
|
||||
@Resource private PriceBookQueryUseCase priceBooks;
|
||||
@Resource private ObjectMapper objectMapper;
|
||||
@Resource private WarehouseSupplierSnapshotService suppliers;
|
||||
@Resource private WarehouseMasterDataClient warehouses;
|
||||
|
||||
+7
-6
@@ -1,9 +1,10 @@
|
||||
package com.baiyue.firstleg.mapper;
|
||||
package com.baiyue.firstleg.pricebookquery.adapter.out.persistence;
|
||||
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.ChannelRow;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.ChannelTaxModeRow;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.RateRow;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.ChannelPrefixRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelTaxModeRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.RateRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelPrefixRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.port.out.PriceBookQueryReader;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
@@ -12,7 +13,7 @@ import java.util.List;
|
||||
|
||||
/** Dedicated read model for merchant channel selection and reference estimates. */
|
||||
@Mapper
|
||||
public interface PriceBookQueryMapper {
|
||||
public interface PriceBookQueryMapper extends PriceBookQueryReader {
|
||||
@Select("""
|
||||
SELECT channel_code AS channelCode, inbound_code_prefix AS inboundCodePrefix,
|
||||
overseas_inbound_code_prefix AS overseasInboundCodePrefix
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package com.baiyue.firstleg.pricebookquery.application;
|
||||
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelPrefixRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelTaxModeRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.RateRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.port.in.PriceBookQueryUseCase;
|
||||
import com.baiyue.firstleg.pricebookquery.application.port.out.PriceBookQueryReader;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class PriceBookQueryService implements PriceBookQueryUseCase {
|
||||
@Resource private PriceBookQueryReader reader;
|
||||
|
||||
@Override public Long activeVersionId() { return reader.findActiveVersionId(); }
|
||||
@Override public List<ChannelRow> channels(long versionId, long originWarehouseId) {
|
||||
return reader.findChannels(versionId, originWarehouseId);
|
||||
}
|
||||
@Override public List<ChannelTaxModeRow> channelTaxModes(long versionId, long originWarehouseId) {
|
||||
return reader.findChannelTaxModes(versionId, originWarehouseId);
|
||||
}
|
||||
@Override public List<RateRow> fbaRates(long versionId, long originWarehouseId, String channelCode,
|
||||
String destinationCode, String pricingTaxMode) {
|
||||
return reader.findFbaRates(versionId, originWarehouseId, channelCode, destinationCode, pricingTaxMode);
|
||||
}
|
||||
@Override public List<RateRow> overseasRates(long versionId, long originWarehouseId, String channelCode,
|
||||
long destinationWarehouseId, String pricingTaxMode) {
|
||||
return reader.findOverseasRates(versionId, originWarehouseId, channelCode, destinationWarehouseId,
|
||||
pricingTaxMode);
|
||||
}
|
||||
@Override public List<RateRow> regionTiers(long versionId, long originWarehouseId, String channelCode,
|
||||
String regionCode, String pricingTaxMode) {
|
||||
return reader.findRegionTiers(versionId, originWarehouseId, channelCode, regionCode, pricingTaxMode);
|
||||
}
|
||||
@Override public boolean channelAvailable(long versionId, long originWarehouseId, String channelCode) {
|
||||
return channels(versionId, originWarehouseId).stream()
|
||||
.anyMatch(channel -> channelCode.equals(channel.getChannelCode()));
|
||||
}
|
||||
@Override public ChannelPrefixRow channelPrefix(String channelCode) {
|
||||
return reader.findChannelPrefix(channelCode);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.baiyue.firstleg.repository;
|
||||
package com.baiyue.firstleg.pricebookquery.application.model;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.baiyue.firstleg.pricebookquery.application.port.in;
|
||||
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelPrefixRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelTaxModeRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.RateRow;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface PriceBookQueryUseCase {
|
||||
Long activeVersionId();
|
||||
List<ChannelRow> channels(long versionId, long originWarehouseId);
|
||||
List<ChannelTaxModeRow> channelTaxModes(long versionId, long originWarehouseId);
|
||||
List<RateRow> fbaRates(long versionId, long originWarehouseId, String channelCode,
|
||||
String destinationCode, String pricingTaxMode);
|
||||
List<RateRow> overseasRates(long versionId, long originWarehouseId, String channelCode,
|
||||
long destinationWarehouseId, String pricingTaxMode);
|
||||
List<RateRow> regionTiers(long versionId, long originWarehouseId, String channelCode,
|
||||
String regionCode, String pricingTaxMode);
|
||||
boolean channelAvailable(long versionId, long originWarehouseId, String channelCode);
|
||||
ChannelPrefixRow channelPrefix(String channelCode);
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.baiyue.firstleg.pricebookquery.application.port.out;
|
||||
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelPrefixRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelTaxModeRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.RateRow;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface PriceBookQueryReader {
|
||||
Long findActiveVersionId();
|
||||
List<ChannelRow> findChannels(long versionId, long originWarehouseId);
|
||||
List<ChannelTaxModeRow> findChannelTaxModes(long versionId, long originWarehouseId);
|
||||
List<RateRow> findFbaRates(long versionId, long originWarehouseId, String channelCode,
|
||||
String destinationCode, String pricingTaxMode);
|
||||
List<RateRow> findOverseasRates(long versionId, long originWarehouseId, String channelCode,
|
||||
long destinationWarehouseId, String pricingTaxMode);
|
||||
List<RateRow> findRegionTiers(long versionId, long originWarehouseId, String channelCode,
|
||||
String regionCode, String pricingTaxMode);
|
||||
ChannelPrefixRow findChannelPrefix(String channelCode);
|
||||
}
|
||||
@@ -7,9 +7,9 @@ import com.baiyue.firstleg.domain.PriceRegion;
|
||||
import com.baiyue.firstleg.domain.PricingDestinationType;
|
||||
import com.baiyue.firstleg.domain.PricingTaxMode;
|
||||
import com.baiyue.firstleg.dto.PriceBookDtos.EstimateRequest;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRepository;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.ChannelRow;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.RateRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.RateRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.port.in.PriceBookQueryUseCase;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -21,7 +21,7 @@ import java.util.Locale;
|
||||
/** Single active-price-book lookup used by merchant estimates and inbound automatic billing. */
|
||||
@Component
|
||||
public class ActivePriceBookEstimator {
|
||||
@Resource private PriceBookQueryRepository repository;
|
||||
@Resource private PriceBookQueryUseCase repository;
|
||||
@Resource private FbaWarehouseRateEstimator fbaEstimator;
|
||||
@Resource private RegionWeightTierEstimator regionEstimator;
|
||||
@Resource private PriceBookWarehouseRegionResolver warehouseRegionResolver;
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.baiyue.firstleg.pricing;
|
||||
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.RateRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.RateRow;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.baiyue.firstleg.pricing;
|
||||
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.RateRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.RateRow;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
package com.baiyue.firstleg.repository;
|
||||
|
||||
import com.baiyue.firstleg.mapper.PriceBookQueryMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public class PriceBookQueryRepository {
|
||||
@Resource
|
||||
private PriceBookQueryMapper mapper;
|
||||
|
||||
public Long activeVersionId() {
|
||||
return mapper.findActiveVersionId();
|
||||
}
|
||||
|
||||
public List<PriceBookQueryRows.ChannelRow> channels(long versionId, long originWarehouseId) {
|
||||
return mapper.findChannels(versionId, originWarehouseId);
|
||||
}
|
||||
|
||||
public List<PriceBookQueryRows.ChannelTaxModeRow> channelTaxModes(long versionId, long originWarehouseId) {
|
||||
return mapper.findChannelTaxModes(versionId, originWarehouseId);
|
||||
}
|
||||
|
||||
public List<PriceBookQueryRows.RateRow> fbaRates(long versionId, long originWarehouseId,
|
||||
String channelCode, String destinationCode,
|
||||
String pricingTaxMode) {
|
||||
return mapper.findFbaRates(versionId, originWarehouseId, channelCode, destinationCode, pricingTaxMode);
|
||||
}
|
||||
|
||||
public List<PriceBookQueryRows.RateRow> overseasRates(long versionId, long originWarehouseId,
|
||||
String channelCode, long destinationWarehouseId,
|
||||
String pricingTaxMode) {
|
||||
return mapper.findOverseasRates(versionId, originWarehouseId, channelCode, destinationWarehouseId,
|
||||
pricingTaxMode);
|
||||
}
|
||||
|
||||
public List<PriceBookQueryRows.RateRow> regionTiers(long versionId, long originWarehouseId,
|
||||
String channelCode, String regionCode,
|
||||
String pricingTaxMode) {
|
||||
return mapper.findRegionTiers(versionId, originWarehouseId, channelCode, regionCode, pricingTaxMode);
|
||||
}
|
||||
|
||||
public boolean channelAvailable(long versionId, long originWarehouseId, String channelCode) {
|
||||
return channels(versionId, originWarehouseId).stream()
|
||||
.anyMatch(channel -> channelCode.equals(channel.getChannelCode()));
|
||||
}
|
||||
|
||||
public PriceBookQueryRows.ChannelPrefixRow channelPrefix(String channelCode) {
|
||||
return mapper.findChannelPrefix(channelCode);
|
||||
}
|
||||
}
|
||||
@@ -22,8 +22,8 @@ import com.baiyue.firstleg.mapper.ContainerTransportHistoryMapper;
|
||||
import com.baiyue.firstleg.repository.ContainerRepository;
|
||||
import com.baiyue.firstleg.repository.LoadingPickRepository;
|
||||
import com.baiyue.firstleg.repository.SmartLoadingRepository;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRepository;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.ChannelRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.port.in.PriceBookQueryUseCase;
|
||||
import com.baiyue.firstleg.oceanbooking.repository.OceanBookingRepository;
|
||||
import com.baiyue.firstleg.oceanbooking.entity.OceanBookingEntity;
|
||||
import com.baiyue.firstleg.oceanbooking.entity.OceanBookingContainerRequirementEntity;
|
||||
@@ -44,7 +44,7 @@ public class ContainerService {
|
||||
@Resource private SmartLoadingRepository smartLoadingRepository;
|
||||
@Resource private LoadingPickRepository loadingPickRepository;
|
||||
@Resource private LoadingPickService loadingPickService;
|
||||
@Resource private PriceBookQueryRepository priceBooks;
|
||||
@Resource private PriceBookQueryUseCase priceBooks;
|
||||
@Resource private OceanBookingRepository oceanBookings;
|
||||
@Resource private WarehouseSupplierSnapshotService suppliers;
|
||||
@Resource private FirstlegDocumentNumberGenerator documentNumbers;
|
||||
|
||||
@@ -14,7 +14,7 @@ import com.baiyue.firstleg.entity.InboundFeeItemEntity;
|
||||
import com.baiyue.firstleg.entity.InboundPricingEntity;
|
||||
import com.baiyue.firstleg.entity.InboundPricingIdempotencyEntity;
|
||||
import com.baiyue.firstleg.pricing.ActivePriceBookEstimator;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.RateRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.RateRow;
|
||||
import com.baiyue.firstleg.repository.FbaPricingRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -9,9 +9,9 @@ import com.baiyue.firstleg.dto.PriceBookDtos.EstimateRequest;
|
||||
import com.baiyue.firstleg.dto.PriceBookDtos.EstimateResponse;
|
||||
import com.baiyue.firstleg.dto.PriceBookChannelValidation.Response;
|
||||
import com.baiyue.firstleg.pricing.ActivePriceBookEstimator;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRepository;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.ChannelRow;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.ChannelTaxModeRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelTaxModeRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.port.in.PriceBookQueryUseCase;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -26,7 +26,7 @@ import java.util.Map;
|
||||
public class MerchantPriceBookService {
|
||||
public static final String DISCLAIMER = "仅供参考,不含附加费,最终以实际结算为准";
|
||||
|
||||
@Resource private PriceBookQueryRepository repository;
|
||||
@Resource private PriceBookQueryUseCase repository;
|
||||
@Resource private ActivePriceBookEstimator estimator;
|
||||
|
||||
public List<CurrentChannel> channels(long merchantTenantId, long originWarehouseId) {
|
||||
|
||||
@@ -21,6 +21,7 @@ class BaiyueFirstlegApplicationContractTest {
|
||||
.contains("com.baiyue.firstleg.portschedule.mapper")
|
||||
.contains("com.baiyue.firstleg.customs.mapper")
|
||||
.contains("com.baiyue.firstleg.customerstatistics.adapter.out.persistence")
|
||||
.contains("com.baiyue.firstleg.pricebookquery.adapter.out.persistence")
|
||||
.doesNotContain("com.baiyue.firstleg.customerstatistics.mapper");
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import com.baiyue.firstleg.domain.PriceModel;
|
||||
import com.baiyue.firstleg.domain.PricingTaxMode;
|
||||
import com.baiyue.firstleg.domain.PricingDestinationType;
|
||||
import com.baiyue.firstleg.dto.PriceBookDtos;
|
||||
import com.baiyue.firstleg.mapper.PriceBookQueryMapper;
|
||||
import com.baiyue.firstleg.pricebookquery.adapter.out.persistence.PriceBookQueryMapper;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
+3
-3
@@ -9,8 +9,8 @@ import com.baiyue.firstleg.oceanbooking.entity.OceanBookingContainerRequirementE
|
||||
import com.baiyue.firstleg.oceanbooking.entity.OceanBookingEntity;
|
||||
import com.baiyue.firstleg.oceanbooking.entity.OceanBookingOperationEntity;
|
||||
import com.baiyue.firstleg.oceanbooking.repository.OceanBookingRepository;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRepository;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.ChannelRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.port.in.PriceBookQueryUseCase;
|
||||
import com.baiyue.firstleg.service.WarehouseSupplierSnapshotService;
|
||||
import com.baiyue.firstleg.service.FirstlegDocumentNumberGenerator;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@@ -33,7 +33,7 @@ import static org.mockito.Mockito.*;
|
||||
|
||||
class OceanBookingServiceTest {
|
||||
@Mock private OceanBookingRepository repository;
|
||||
@Mock private PriceBookQueryRepository priceBooks;
|
||||
@Mock private PriceBookQueryUseCase priceBooks;
|
||||
@Mock private WarehouseSupplierSnapshotService suppliers;
|
||||
@Mock private WarehouseMasterDataClient warehouses;
|
||||
@Mock private FirstlegDocumentNumberGenerator documentNumbers;
|
||||
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
package com.baiyue.firstleg.pricebookquery;
|
||||
|
||||
import com.baiyue.firstleg.pricebookquery.application.port.out.PriceBookQueryReader;
|
||||
import com.tngtech.archunit.core.domain.JavaClasses;
|
||||
import com.tngtech.archunit.core.importer.ClassFileImporter;
|
||||
import com.tngtech.archunit.core.importer.ImportOption;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static com.tngtech.archunit.core.domain.JavaClass.Predicates.resideInAPackage;
|
||||
import static com.tngtech.archunit.core.domain.JavaClass.Predicates.resideOutsideOfPackage;
|
||||
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
|
||||
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
|
||||
|
||||
class PriceBookQueryArchitectureTest {
|
||||
private static final String FIRSTLEG = "com.baiyue.firstleg..";
|
||||
private static final String SLICE = "com.baiyue.firstleg.pricebookquery..";
|
||||
private static final String APPLICATION = "com.baiyue.firstleg.pricebookquery.application..";
|
||||
private static final String INPUT_PORT = "com.baiyue.firstleg.pricebookquery.application.port.in..";
|
||||
private static final String OUTPUT_PORT = "com.baiyue.firstleg.pricebookquery.application.port.out..";
|
||||
private static final String MODEL = "com.baiyue.firstleg.pricebookquery.application.model..";
|
||||
private static final String PERSISTENCE = "com.baiyue.firstleg.pricebookquery.adapter.out.persistence..";
|
||||
|
||||
private static final JavaClasses PRODUCTION_CLASSES = new ClassFileImporter()
|
||||
.withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS)
|
||||
.withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_JARS)
|
||||
.importPackages("com.baiyue.firstleg");
|
||||
|
||||
@Test
|
||||
void applicationStaysFreeOfWebAndPersistenceFrameworks() {
|
||||
noClasses().that().resideInAPackage(APPLICATION)
|
||||
.should().dependOnClassesThat().resideInAnyPackage(
|
||||
"org.springframework.web..",
|
||||
"org.apache.ibatis..",
|
||||
"com.baomidou.mybatisplus..")
|
||||
.check(PRODUCTION_CLASSES);
|
||||
}
|
||||
|
||||
@Test
|
||||
void applicationOnlyDependsOnItsOwnSliceWithinFirstleg() {
|
||||
classes().that().resideInAPackage(APPLICATION)
|
||||
.should().onlyDependOnClassesThat(
|
||||
resideOutsideOfPackage(FIRSTLEG).or(resideInAPackage(APPLICATION)))
|
||||
.check(PRODUCTION_CLASSES);
|
||||
}
|
||||
|
||||
@Test
|
||||
void persistenceAdapterCollaboratesThroughTheOutputPortAndModel() {
|
||||
classes().that().resideInAPackage(PERSISTENCE)
|
||||
.should().onlyDependOnClassesThat(
|
||||
resideOutsideOfPackage(SLICE)
|
||||
.or(resideInAPackage(PERSISTENCE))
|
||||
.or(resideInAPackage(OUTPUT_PORT))
|
||||
.or(resideInAPackage(MODEL)))
|
||||
.andShould().beAssignableTo(PriceBookQueryReader.class)
|
||||
.check(PRODUCTION_CLASSES);
|
||||
}
|
||||
|
||||
@Test
|
||||
void consumersOnlySeeTheInputPortAndReadModel() {
|
||||
noClasses().that().resideOutsideOfPackage(SLICE)
|
||||
.should().dependOnClassesThat(
|
||||
resideInAPackage(SLICE)
|
||||
.and(resideOutsideOfPackage(INPUT_PORT))
|
||||
.and(resideOutsideOfPackage(MODEL)))
|
||||
.check(PRODUCTION_CLASSES);
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package com.baiyue.firstleg.pricebookquery;
|
||||
|
||||
import com.baiyue.firstleg.pricebookquery.application.PriceBookQueryService;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelPrefixRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.port.out.PriceBookQueryReader;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class PriceBookQueryServiceTest {
|
||||
@Mock private PriceBookQueryReader reader;
|
||||
@InjectMocks private PriceBookQueryService service;
|
||||
|
||||
@Test
|
||||
void delegatesStableReadOperationsToTheOutputPort() {
|
||||
ChannelPrefixRow prefix = new ChannelPrefixRow("SEA", "IN", "OUT");
|
||||
when(reader.findActiveVersionId()).thenReturn(9L);
|
||||
when(reader.findChannelPrefix("SEA")).thenReturn(prefix);
|
||||
|
||||
assertThat(service.activeVersionId()).isEqualTo(9L);
|
||||
assertThat(service.channelPrefix("SEA")).isSameAs(prefix);
|
||||
verify(reader).findActiveVersionId();
|
||||
verify(reader).findChannelPrefix("SEA");
|
||||
}
|
||||
|
||||
@Test
|
||||
void keepsChannelAvailabilityAsApplicationLogic() {
|
||||
ChannelRow channel = new ChannelRow();
|
||||
channel.setChannelCode("SEA");
|
||||
when(reader.findChannels(9L, 3L)).thenReturn(List.of(channel));
|
||||
|
||||
assertThat(service.channelAvailable(9L, 3L, "SEA")).isTrue();
|
||||
assertThat(service.channelAvailable(9L, 3L, "AIR")).isFalse();
|
||||
verify(reader, org.mockito.Mockito.times(2)).findChannels(9L, 3L);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package com.baiyue.firstleg.pricing;
|
||||
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.RateRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.RateRow;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package com.baiyue.firstleg.pricing;
|
||||
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.RateRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.RateRow;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@@ -17,8 +17,8 @@ import com.baiyue.firstleg.mapper.ContainerTransportHistoryMapper;
|
||||
import com.baiyue.firstleg.repository.ContainerRepository;
|
||||
import com.baiyue.firstleg.repository.LoadingPickRepository;
|
||||
import com.baiyue.firstleg.repository.SmartLoadingRepository;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRepository;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.ChannelRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.port.in.PriceBookQueryUseCase;
|
||||
import com.baiyue.firstleg.oceanbooking.repository.OceanBookingRepository;
|
||||
import com.baiyue.firstleg.oceanbooking.entity.OceanBookingEntity;
|
||||
import com.baiyue.firstleg.oceanbooking.entity.OceanBookingContainerAllocationEntity;
|
||||
@@ -51,7 +51,7 @@ class ContainerServiceTest {
|
||||
@MockBean private SmartLoadingRepository smartLoadingRepository;
|
||||
@MockBean private LoadingPickRepository loadingPickRepository;
|
||||
@MockBean private LoadingPickService loadingPickService;
|
||||
@MockBean private PriceBookQueryRepository priceBooks;
|
||||
@MockBean private PriceBookQueryUseCase priceBooks;
|
||||
@MockBean private OceanBookingRepository oceanBookings;
|
||||
@MockBean private WarehouseSupplierSnapshotService suppliers;
|
||||
@MockBean private FirstlegDocumentNumberGenerator documentNumbers;
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ import com.baiyue.firstleg.domain.CustomerDimensionBoxType;
|
||||
import com.baiyue.firstleg.entity.CustomerDimensionConfigEntity;
|
||||
import com.baiyue.firstleg.pricing.FbaWarehouseRateEstimator;
|
||||
import com.baiyue.firstleg.repository.CustomerDimensionConfigRepository;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.RateRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.RateRow;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@@ -11,7 +11,7 @@ import com.baiyue.firstleg.entity.InboundPricingEntity;
|
||||
import com.baiyue.firstleg.entity.InboundPricingIdempotencyEntity;
|
||||
import com.baiyue.firstleg.pricing.ActivePriceBookEstimator;
|
||||
import com.baiyue.firstleg.repository.FbaPricingRepository;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.RateRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.RateRow;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
+6
-6
@@ -13,11 +13,11 @@ import com.baiyue.firstleg.pricing.FbaWarehouseRateEstimator;
|
||||
import com.baiyue.firstleg.pricing.PriceBookWarehouseRegionResolver;
|
||||
import com.baiyue.firstleg.pricing.PriceRegionResolver;
|
||||
import com.baiyue.firstleg.pricing.RegionWeightTierEstimator;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRepository;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.ChannelRow;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.ChannelTaxModeRow;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.ChannelPrefixRow;
|
||||
import com.baiyue.firstleg.repository.PriceBookQueryRows.RateRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelTaxModeRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.ChannelPrefixRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows.RateRow;
|
||||
import com.baiyue.firstleg.pricebookquery.application.port.in.PriceBookQueryUseCase;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
@@ -38,7 +38,7 @@ import static org.mockito.Mockito.when;
|
||||
PriceBookWarehouseRegionResolver.class})
|
||||
@TestPropertySource(properties = "baiyue.security.internal-service-token=internal-token")
|
||||
class MerchantPriceBookServiceTest {
|
||||
@MockBean private PriceBookQueryRepository repository;
|
||||
@MockBean private PriceBookQueryUseCase repository;
|
||||
@MockBean private PriceBookWarehouseClient warehouses;
|
||||
@Resource private MerchantPriceBookService service;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"booking-customs-trucking->inbound",
|
||||
"booking-customs-trucking->measurement-pricing",
|
||||
"booking-customs-trucking->outbound",
|
||||
"booking-customs-trucking->pricebook-query",
|
||||
"booking-customs-trucking->shared-technical",
|
||||
"booking-customs-trucking->split-loading",
|
||||
"customer-statistics->shared-technical",
|
||||
@@ -19,6 +20,7 @@
|
||||
"measurement-pricing->booking-customs-trucking",
|
||||
"measurement-pricing->finance-integration",
|
||||
"measurement-pricing->inbound",
|
||||
"measurement-pricing->pricebook-query",
|
||||
"measurement-pricing->shared-technical",
|
||||
"outbound->booking-customs-trucking",
|
||||
"outbound->shared-technical",
|
||||
@@ -35,8 +37,8 @@
|
||||
"shipping-nodes->split-loading",
|
||||
"split-loading->booking-customs-trucking",
|
||||
"split-loading->inbound",
|
||||
"split-loading->measurement-pricing",
|
||||
"split-loading->outbound",
|
||||
"split-loading->pricebook-query",
|
||||
"split-loading->shared-technical"
|
||||
],
|
||||
"requiredClassLocations": {
|
||||
@@ -44,21 +46,50 @@
|
||||
"com.baiyue.firstleg.customerstatistics.adapter.out.persistence.CustomerTransitStatisticsMapper": "src/main/java/com/baiyue/firstleg/customerstatistics/adapter/out/persistence/CustomerTransitStatisticsMapper.java",
|
||||
"com.baiyue.firstleg.customerstatistics.application.CustomerTransitStatisticsService": "src/main/java/com/baiyue/firstleg/customerstatistics/application/CustomerTransitStatisticsService.java",
|
||||
"com.baiyue.firstleg.customerstatistics.application.model.CustomerTransitStatisticsDtos": "src/main/java/com/baiyue/firstleg/customerstatistics/application/model/CustomerTransitStatisticsDtos.java",
|
||||
"com.baiyue.firstleg.customerstatistics.application.port.out.CustomerTransitStatisticsReader": "src/main/java/com/baiyue/firstleg/customerstatistics/application/port/out/CustomerTransitStatisticsReader.java"
|
||||
},
|
||||
"applicationDependencyRule": {
|
||||
"packagePrefix": "com.baiyue.firstleg.customerstatistics.application",
|
||||
"allowedInternalPrefix": "com.baiyue.firstleg.customerstatistics.application",
|
||||
"forbiddenImportPrefixes": [
|
||||
"org.springframework.web",
|
||||
"org.apache.ibatis",
|
||||
"com.baomidou.mybatisplus"
|
||||
]
|
||||
"com.baiyue.firstleg.customerstatistics.application.port.out.CustomerTransitStatisticsReader": "src/main/java/com/baiyue/firstleg/customerstatistics/application/port/out/CustomerTransitStatisticsReader.java",
|
||||
"com.baiyue.firstleg.pricebookquery.adapter.out.persistence.PriceBookQueryMapper": "src/main/java/com/baiyue/firstleg/pricebookquery/adapter/out/persistence/PriceBookQueryMapper.java",
|
||||
"com.baiyue.firstleg.pricebookquery.application.PriceBookQueryService": "src/main/java/com/baiyue/firstleg/pricebookquery/application/PriceBookQueryService.java",
|
||||
"com.baiyue.firstleg.pricebookquery.application.model.PriceBookQueryRows": "src/main/java/com/baiyue/firstleg/pricebookquery/application/model/PriceBookQueryRows.java",
|
||||
"com.baiyue.firstleg.pricebookquery.application.port.in.PriceBookQueryUseCase": "src/main/java/com/baiyue/firstleg/pricebookquery/application/port/in/PriceBookQueryUseCase.java",
|
||||
"com.baiyue.firstleg.pricebookquery.application.port.out.PriceBookQueryReader": "src/main/java/com/baiyue/firstleg/pricebookquery/application/port/out/PriceBookQueryReader.java"
|
||||
},
|
||||
"applicationDependencyRules": [
|
||||
{
|
||||
"packagePrefix": "com.baiyue.firstleg.customerstatistics.application",
|
||||
"allowedInternalPrefix": "com.baiyue.firstleg.customerstatistics.application",
|
||||
"forbiddenImportPrefixes": [
|
||||
"org.springframework.web",
|
||||
"org.apache.ibatis",
|
||||
"com.baomidou.mybatisplus"
|
||||
]
|
||||
},
|
||||
{
|
||||
"packagePrefix": "com.baiyue.firstleg.pricebookquery.application",
|
||||
"allowedInternalPrefix": "com.baiyue.firstleg.pricebookquery.application",
|
||||
"forbiddenImportPrefixes": [
|
||||
"org.springframework.web",
|
||||
"org.apache.ibatis",
|
||||
"com.baomidou.mybatisplus"
|
||||
]
|
||||
}
|
||||
],
|
||||
"sliceExposureRules": [
|
||||
{
|
||||
"slicePrefix": "com.baiyue.firstleg.pricebookquery.",
|
||||
"allowedTargetPrefixes": [
|
||||
"com.baiyue.firstleg.pricebookquery.application.model.",
|
||||
"com.baiyue.firstleg.pricebookquery.application.port.in."
|
||||
]
|
||||
}
|
||||
],
|
||||
"sliceSpecificRules": {
|
||||
"customer-statistics": {
|
||||
"allowedOutgoing": ["shared-technical"],
|
||||
"allowedIncoming": []
|
||||
},
|
||||
"pricebook-query": {
|
||||
"allowedOutgoing": [],
|
||||
"allowedIncoming": ["booking-customs-trucking", "measurement-pricing", "split-loading"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user