docs(blockchain-service): 完善架构设计以兼容其他微服务
- 添加 modules/ 分层模块文件结构 (api/application/domain/infrastructure) - 抽取 AggregateRoot 聚合根基类,统一领域事件管理 - 补充 BlockNumber、TxHash 值对象的完整定义 - 添加值对象导出索引文件 - 新增第16章架构兼容性说明: - 与其他服务的架构对比表 - 依赖倒置原则和六边形架构端口适配器说明 - 命名约定规范 - Symbol Token 注入规范 - 更新文档版本至 1.1.0 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
08541f1d8d
commit
cd4fba96ed
|
|
@ -97,6 +97,12 @@ blockchain-service/
|
|||
├── prisma/
|
||||
│ └── schema.prisma
|
||||
├── src/
|
||||
│ ├── modules/ # NestJS 模块定义 (与其他服务保持一致)
|
||||
│ │ ├── api.module.ts # API 层模块
|
||||
│ │ ├── application.module.ts # 应用层模块
|
||||
│ │ ├── domain.module.ts # 领域层模块
|
||||
│ │ └── infrastructure.module.ts # 基础设施层模块
|
||||
│ │
|
||||
│ ├── api/ # 入站适配器 (Driving Adapters)
|
||||
│ │ ├── controllers/
|
||||
│ │ │ ├── health.controller.ts
|
||||
|
|
@ -131,6 +137,7 @@ blockchain-service/
|
|||
│ │
|
||||
│ ├── domain/ # 领域层 (核心业务)
|
||||
│ │ ├── aggregates/
|
||||
│ │ │ ├── aggregate-root.base.ts # 聚合根基类 (统一事件管理)
|
||||
│ │ │ ├── deposit-transaction/
|
||||
│ │ │ │ ├── deposit-transaction.aggregate.ts
|
||||
│ │ │ │ ├── deposit-transaction.factory.ts
|
||||
|
|
@ -184,7 +191,9 @@ blockchain-service/
|
|||
│ │ │ │ ├── monitored-address.repository.impl.ts
|
||||
│ │ │ │ └── block-checkpoint.repository.impl.ts
|
||||
│ │ │ └── mappers/
|
||||
│ │ │ └── deposit-transaction.mapper.ts
|
||||
│ │ │ ├── deposit-transaction.mapper.ts
|
||||
│ │ │ ├── monitored-address.mapper.ts
|
||||
│ │ │ └── transaction-request.mapper.ts
|
||||
│ │ ├── kafka/
|
||||
│ │ │ ├── event-publisher.service.ts
|
||||
│ │ │ ├── event-consumer.controller.ts
|
||||
|
|
@ -239,6 +248,198 @@ blockchain-service/
|
|||
└── DEVELOPMENT_GUIDE.md
|
||||
```
|
||||
|
||||
### 2.3 模块化设计 (与其他服务保持一致)
|
||||
|
||||
为了与 identity-service、wallet-service、leaderboard-service 等服务保持架构一致性,采用分层模块化设计:
|
||||
|
||||
```typescript
|
||||
// src/modules/infrastructure.module.ts
|
||||
import { Global, Module } from '@nestjs/common';
|
||||
import { PrismaService } from '@/infrastructure/persistence/prisma/prisma.service';
|
||||
import { RedisService } from '@/infrastructure/redis/redis.service';
|
||||
import { EvmProviderAdapter } from '@/infrastructure/blockchain/evm-provider.adapter';
|
||||
import { EventPublisherService } from '@/infrastructure/kafka/event-publisher.service';
|
||||
import { WalletClientService } from '@/infrastructure/external/wallet-service/wallet-client.service';
|
||||
import { IdentityClientService } from '@/infrastructure/external/identity-service/identity-client.service';
|
||||
|
||||
@Global()
|
||||
@Module({
|
||||
providers: [
|
||||
PrismaService,
|
||||
RedisService,
|
||||
EvmProviderAdapter,
|
||||
EventPublisherService,
|
||||
WalletClientService,
|
||||
IdentityClientService,
|
||||
],
|
||||
exports: [
|
||||
PrismaService,
|
||||
RedisService,
|
||||
EvmProviderAdapter,
|
||||
EventPublisherService,
|
||||
WalletClientService,
|
||||
IdentityClientService,
|
||||
],
|
||||
})
|
||||
export class InfrastructureModule {}
|
||||
```
|
||||
|
||||
```typescript
|
||||
// src/modules/domain.module.ts
|
||||
import { Module } from '@nestjs/common';
|
||||
import { InfrastructureModule } from './infrastructure.module';
|
||||
import {
|
||||
DEPOSIT_TRANSACTION_REPOSITORY,
|
||||
MONITORED_ADDRESS_REPOSITORY,
|
||||
BLOCK_CHECKPOINT_REPOSITORY,
|
||||
} from '@/domain/repositories';
|
||||
import { DepositTransactionRepositoryImpl } from '@/infrastructure/persistence/repositories/deposit-transaction.repository.impl';
|
||||
import { MonitoredAddressRepositoryImpl } from '@/infrastructure/persistence/repositories/monitored-address.repository.impl';
|
||||
import { BlockCheckpointRepositoryImpl } from '@/infrastructure/persistence/repositories/block-checkpoint.repository.impl';
|
||||
import { ConfirmationPolicyService } from '@/domain/services/confirmation-policy.service';
|
||||
import { ChainConfigService } from '@/domain/services/chain-config.service';
|
||||
|
||||
@Module({
|
||||
imports: [InfrastructureModule],
|
||||
providers: [
|
||||
// 仓储实现 (依赖倒置)
|
||||
{
|
||||
provide: DEPOSIT_TRANSACTION_REPOSITORY,
|
||||
useClass: DepositTransactionRepositoryImpl,
|
||||
},
|
||||
{
|
||||
provide: MONITORED_ADDRESS_REPOSITORY,
|
||||
useClass: MonitoredAddressRepositoryImpl,
|
||||
},
|
||||
{
|
||||
provide: BLOCK_CHECKPOINT_REPOSITORY,
|
||||
useClass: BlockCheckpointRepositoryImpl,
|
||||
},
|
||||
// 领域服务
|
||||
ConfirmationPolicyService,
|
||||
ChainConfigService,
|
||||
],
|
||||
exports: [
|
||||
DEPOSIT_TRANSACTION_REPOSITORY,
|
||||
MONITORED_ADDRESS_REPOSITORY,
|
||||
BLOCK_CHECKPOINT_REPOSITORY,
|
||||
ConfirmationPolicyService,
|
||||
ChainConfigService,
|
||||
],
|
||||
})
|
||||
export class DomainModule {}
|
||||
```
|
||||
|
||||
```typescript
|
||||
// src/modules/application.module.ts
|
||||
import { Module } from '@nestjs/common';
|
||||
import { DomainModule } from './domain.module';
|
||||
import { InfrastructureModule } from './infrastructure.module';
|
||||
import { DepositDetectionService } from '@/application/services/deposit-detection.service';
|
||||
import { BalanceQueryService } from '@/application/services/balance-query.service';
|
||||
import { TransactionBroadcastService } from '@/application/services/transaction-broadcast.service';
|
||||
import { AddressRegistryService } from '@/application/services/address-registry.service';
|
||||
import { AddressCacheService } from '@/infrastructure/redis/address-cache.service';
|
||||
import { EventListenerService } from '@/infrastructure/blockchain/event-listener.service';
|
||||
import { BlockScannerService } from '@/infrastructure/blockchain/block-scanner.service';
|
||||
|
||||
@Module({
|
||||
imports: [DomainModule, InfrastructureModule],
|
||||
providers: [
|
||||
// 应用服务
|
||||
DepositDetectionService,
|
||||
BalanceQueryService,
|
||||
TransactionBroadcastService,
|
||||
AddressRegistryService,
|
||||
// 基础设施服务 (需要应用层依赖)
|
||||
AddressCacheService,
|
||||
EventListenerService,
|
||||
BlockScannerService,
|
||||
],
|
||||
exports: [
|
||||
DepositDetectionService,
|
||||
BalanceQueryService,
|
||||
TransactionBroadcastService,
|
||||
AddressRegistryService,
|
||||
AddressCacheService,
|
||||
],
|
||||
})
|
||||
export class ApplicationModule {}
|
||||
```
|
||||
|
||||
```typescript
|
||||
// src/modules/api.module.ts
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ApplicationModule } from './application.module';
|
||||
import { HealthController } from '@/api/controllers/health.controller';
|
||||
import { BalanceController } from '@/api/controllers/balance.controller';
|
||||
import { InternalController } from '@/api/controllers/internal.controller';
|
||||
import { EventConsumerController } from '@/infrastructure/kafka/event-consumer.controller';
|
||||
|
||||
@Module({
|
||||
imports: [ApplicationModule],
|
||||
controllers: [
|
||||
HealthController,
|
||||
BalanceController,
|
||||
InternalController,
|
||||
EventConsumerController,
|
||||
],
|
||||
})
|
||||
export class ApiModule {}
|
||||
```
|
||||
|
||||
```typescript
|
||||
// src/app.module.ts
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import { ScheduleModule } from '@nestjs/schedule';
|
||||
import { ApiModule } from '@/modules/api.module';
|
||||
import appConfig from '@/config/app.config';
|
||||
import databaseConfig from '@/config/database.config';
|
||||
import kafkaConfig from '@/config/kafka.config';
|
||||
import redisConfig from '@/config/redis.config';
|
||||
import chainConfig from '@/config/chain.config';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
ConfigModule.forRoot({
|
||||
isGlobal: true,
|
||||
load: [appConfig, databaseConfig, kafkaConfig, redisConfig, chainConfig],
|
||||
}),
|
||||
ScheduleModule.forRoot(),
|
||||
ApiModule,
|
||||
],
|
||||
})
|
||||
export class AppModule {}
|
||||
```
|
||||
|
||||
**模块依赖关系图:**
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ AppModule │
|
||||
│ ┌───────────────────────────────────────────────────────┐ │
|
||||
│ │ ApiModule │ │
|
||||
│ │ Controllers: Health, Balance, Internal, EventConsumer │ │
|
||||
│ └───────────────────────┬───────────────────────────────┘ │
|
||||
│ │ imports │
|
||||
│ ┌───────────────────────▼───────────────────────────────┐ │
|
||||
│ │ ApplicationModule │ │
|
||||
│ │ Services: DepositDetection, BalanceQuery, ... │ │
|
||||
│ └───────────────────────┬───────────────────────────────┘ │
|
||||
│ │ imports │
|
||||
│ ┌───────────────────────▼───────────────────────────────┐ │
|
||||
│ │ DomainModule │ │
|
||||
│ │ Repositories (interfaces → impl), Domain Services │ │
|
||||
│ └───────────────────────┬───────────────────────────────┘ │
|
||||
│ │ imports │
|
||||
│ ┌───────────────────────▼───────────────────────────────┐ │
|
||||
│ │ InfrastructureModule (@Global) │ │
|
||||
│ │ Prisma, Redis, Kafka, EVM Provider, External Clients │ │
|
||||
│ └───────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 数据模型设计
|
||||
|
|
@ -424,11 +625,66 @@ model BlockchainEvent {
|
|||
|
||||
## 4. 领域层设计
|
||||
|
||||
### 4.1 聚合根:DepositTransaction
|
||||
### 4.1 聚合根基类 (与其他服务保持一致)
|
||||
|
||||
为了与 authorization-service、wallet-service 等服务保持架构一致性,抽取统一的聚合根基类:
|
||||
|
||||
```typescript
|
||||
// src/domain/aggregates/aggregate-root.base.ts
|
||||
|
||||
import { DomainEvent } from '@/domain/events/domain-event.base';
|
||||
|
||||
/**
|
||||
* 聚合根基类
|
||||
*
|
||||
* 所有聚合根都应继承此基类,统一管理领域事件的收集和清理。
|
||||
* 参考: authorization-service/src/domain/aggregates/aggregate-root.base.ts
|
||||
*/
|
||||
export abstract class AggregateRoot<TId = bigint> {
|
||||
private readonly _domainEvents: DomainEvent[] = [];
|
||||
|
||||
/**
|
||||
* 聚合根唯一标识
|
||||
*/
|
||||
abstract get id(): TId | undefined;
|
||||
|
||||
/**
|
||||
* 获取所有待发布的领域事件
|
||||
*/
|
||||
get domainEvents(): ReadonlyArray<DomainEvent> {
|
||||
return [...this._domainEvents];
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加领域事件
|
||||
* @param event 领域事件
|
||||
*/
|
||||
protected addDomainEvent(event: DomainEvent): void {
|
||||
this._domainEvents.push(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空领域事件(在事件发布后调用)
|
||||
*/
|
||||
clearDomainEvents(): void {
|
||||
this._domainEvents.length = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否有待发布的领域事件
|
||||
*/
|
||||
hasDomainEvents(): boolean {
|
||||
return this._domainEvents.length > 0;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 聚合根:DepositTransaction
|
||||
|
||||
```typescript
|
||||
// src/domain/aggregates/deposit-transaction/deposit-transaction.aggregate.ts
|
||||
|
||||
import { AggregateRoot } from '../aggregate-root.base';
|
||||
import { DomainEvent, DepositDetectedEvent, DepositConfirmedEvent } from '@/domain/events';
|
||||
import { ChainType, TxHash, EvmAddress, TokenAmount, BlockNumber } from '@/domain/value-objects';
|
||||
import { DepositStatus } from '@/domain/enums';
|
||||
|
|
@ -455,10 +711,10 @@ export interface DepositTransactionProps {
|
|||
updatedAt?: Date;
|
||||
}
|
||||
|
||||
export class DepositTransaction {
|
||||
private readonly _domainEvents: DomainEvent[] = [];
|
||||
|
||||
private constructor(private props: DepositTransactionProps) {}
|
||||
export class DepositTransaction extends AggregateRoot<bigint> {
|
||||
private constructor(private props: DepositTransactionProps) {
|
||||
super();
|
||||
}
|
||||
|
||||
// Getters
|
||||
get id(): bigint | undefined { return this.props.id; }
|
||||
|
|
@ -569,13 +825,7 @@ export class DepositTransaction {
|
|||
this.props.lastNotifyError = error;
|
||||
}
|
||||
|
||||
private addDomainEvent(event: DomainEvent): void {
|
||||
this._domainEvents.push(event);
|
||||
}
|
||||
|
||||
clearDomainEvents(): void {
|
||||
this._domainEvents.length = 0;
|
||||
}
|
||||
// 注意:addDomainEvent 和 clearDomainEvents 方法已在 AggregateRoot 基类中定义
|
||||
|
||||
toProps(): DepositTransactionProps {
|
||||
return { ...this.props };
|
||||
|
|
@ -583,7 +833,9 @@ export class DepositTransaction {
|
|||
}
|
||||
```
|
||||
|
||||
### 4.2 值对象
|
||||
### 4.3 值对象
|
||||
|
||||
#### 4.3.1 EVM 地址值对象
|
||||
|
||||
```typescript
|
||||
// src/domain/value-objects/evm-address.vo.ts
|
||||
|
|
@ -618,6 +870,8 @@ export class EvmAddress {
|
|||
}
|
||||
```
|
||||
|
||||
#### 4.3.2 代币金额值对象
|
||||
|
||||
```typescript
|
||||
// src/domain/value-objects/token-amount.vo.ts
|
||||
|
||||
|
|
@ -664,6 +918,8 @@ export class TokenAmount {
|
|||
}
|
||||
```
|
||||
|
||||
#### 4.3.3 链类型值对象
|
||||
|
||||
```typescript
|
||||
// src/domain/value-objects/chain-type.vo.ts
|
||||
|
||||
|
|
@ -721,7 +977,165 @@ export class ChainType {
|
|||
}
|
||||
```
|
||||
|
||||
### 4.3 领域事件
|
||||
#### 4.3.4 区块号值对象
|
||||
|
||||
```typescript
|
||||
// src/domain/value-objects/block-number.vo.ts
|
||||
|
||||
/**
|
||||
* 区块号值对象
|
||||
*
|
||||
* 封装区块号,确保类型安全和业务规则验证
|
||||
*/
|
||||
export class BlockNumber {
|
||||
private constructor(private readonly _value: bigint) {}
|
||||
|
||||
get value(): bigint {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建区块号值对象
|
||||
* @param value 区块号(支持 number 或 bigint)
|
||||
* @throws Error 如果区块号为负数
|
||||
*/
|
||||
static create(value: number | bigint): BlockNumber {
|
||||
const bn = BigInt(value);
|
||||
if (bn < 0n) {
|
||||
throw new Error(`Invalid block number: ${value}. Block number cannot be negative.`);
|
||||
}
|
||||
return new BlockNumber(bn);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算两个区块之间的差值
|
||||
*/
|
||||
diff(other: BlockNumber): bigint {
|
||||
return this._value - other._value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否大于另一个区块号
|
||||
*/
|
||||
greaterThan(other: BlockNumber): boolean {
|
||||
return this._value > other._value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否小于另一个区块号
|
||||
*/
|
||||
lessThan(other: BlockNumber): boolean {
|
||||
return this._value < other._value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加上指定数量的区块
|
||||
*/
|
||||
add(blocks: number | bigint): BlockNumber {
|
||||
return new BlockNumber(this._value + BigInt(blocks));
|
||||
}
|
||||
|
||||
/**
|
||||
* 减去指定数量的区块
|
||||
*/
|
||||
subtract(blocks: number | bigint): BlockNumber {
|
||||
const result = this._value - BigInt(blocks);
|
||||
if (result < 0n) {
|
||||
throw new Error('Block number cannot be negative after subtraction');
|
||||
}
|
||||
return new BlockNumber(result);
|
||||
}
|
||||
|
||||
equals(other: BlockNumber): boolean {
|
||||
return this._value === other._value;
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return this._value.toString();
|
||||
}
|
||||
|
||||
toNumber(): number {
|
||||
return Number(this._value);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.3.5 交易哈希值对象
|
||||
|
||||
```typescript
|
||||
// src/domain/value-objects/tx-hash.vo.ts
|
||||
|
||||
/**
|
||||
* 交易哈希值对象
|
||||
*
|
||||
* 封装 EVM 交易哈希,确保格式正确(0x + 64位十六进制字符)
|
||||
*/
|
||||
export class TxHash {
|
||||
private static readonly PATTERN = /^0x[a-fA-F0-9]{64}$/;
|
||||
|
||||
private constructor(private readonly _value: string) {}
|
||||
|
||||
get value(): string {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取标准化(小写)的哈希值
|
||||
*/
|
||||
get normalized(): string {
|
||||
return this._value.toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建交易哈希值对象
|
||||
* @param hash 交易哈希字符串
|
||||
* @throws Error 如果哈希格式无效
|
||||
*/
|
||||
static create(hash: string): TxHash {
|
||||
if (!this.isValid(hash)) {
|
||||
throw new Error(`Invalid transaction hash: ${hash}. Expected format: 0x + 64 hex characters.`);
|
||||
}
|
||||
// 统一存储为小写格式
|
||||
return new TxHash(hash.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证交易哈希格式是否有效
|
||||
*/
|
||||
static isValid(hash: string): boolean {
|
||||
return this.PATTERN.test(hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缩短显示格式 (0x1234...abcd)
|
||||
*/
|
||||
toShortString(prefixLength = 6, suffixLength = 4): string {
|
||||
return `${this._value.slice(0, prefixLength + 2)}...${this._value.slice(-suffixLength)}`;
|
||||
}
|
||||
|
||||
equals(other: TxHash): boolean {
|
||||
return this._value === other._value;
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return this._value;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.3.6 值对象导出索引
|
||||
|
||||
```typescript
|
||||
// src/domain/value-objects/index.ts
|
||||
|
||||
export { ChainType, ChainTypeEnum } from './chain-type.vo';
|
||||
export { EvmAddress } from './evm-address.vo';
|
||||
export { TokenAmount } from './token-amount.vo';
|
||||
export { BlockNumber } from './block-number.vo';
|
||||
export { TxHash } from './tx-hash.vo';
|
||||
```
|
||||
|
||||
### 4.4 领域事件
|
||||
|
||||
```typescript
|
||||
// src/domain/events/deposit-detected.event.ts
|
||||
|
|
@ -790,7 +1204,7 @@ export class DepositConfirmedEvent extends DomainEvent {
|
|||
}
|
||||
```
|
||||
|
||||
### 4.4 仓储接口 (Ports)
|
||||
### 4.5 仓储接口 (Ports)
|
||||
|
||||
```typescript
|
||||
// src/domain/repositories/deposit-transaction.repository.interface.ts
|
||||
|
|
@ -1873,5 +2287,99 @@ for db in rwa_identity rwa_wallet ... rwa_blockchain; do
|
|||
|
||||
---
|
||||
|
||||
*文档版本: 1.0.0*
|
||||
## 16. 架构兼容性说明
|
||||
|
||||
### 16.1 与其他服务的架构对比
|
||||
|
||||
本服务严格遵循与其他微服务相同的 **DDD + 六边形架构 + 微服务** 设计原则:
|
||||
|
||||
| 特性 | blockchain-service | identity-service | wallet-service | admin-service |
|
||||
|-----|-------------------|------------------|----------------|---------------|
|
||||
| **DDD 分层** | ✅ | ✅ | ✅ | ✅ |
|
||||
| **六边形架构** | ✅ | ✅ | ✅ | ✅ |
|
||||
| **模块化设计** | ✅ (modules/) | ✅ | ✅ | ✅ |
|
||||
| **聚合根基类** | ✅ (AggregateRoot) | ✅ | ✅ | ✅ |
|
||||
| **值对象** | 5个 (ChainType, EvmAddress, TokenAmount, BlockNumber, TxHash) | 2个+ | 5个+ | 7个+ |
|
||||
| **领域事件** | ✅ | ❌ | ✅ | ❌ |
|
||||
| **CQRS** | ✅ | ✅ | ✅ | ✅ |
|
||||
| **Kafka 集成** | ✅ | ✅ | ❌ | ❌ |
|
||||
| **Redis 缓存** | ✅ | ✅ | ❌ | ❌ |
|
||||
| **定时任务** | ✅ (@Cron) | ❌ | ❌ | ❌ |
|
||||
|
||||
### 16.2 关键架构原则
|
||||
|
||||
#### 依赖倒置原则 (Dependency Inversion)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Domain Layer │
|
||||
│ ┌─────────────────────────────────────────────────┐ │
|
||||
│ │ Repository Interfaces (Ports) │ │
|
||||
│ │ - IDepositTransactionRepository │ │
|
||||
│ │ - IMonitoredAddressRepository │ │
|
||||
│ └─────────────────────────────────────────────────┘ │
|
||||
│ ▲ │
|
||||
│ │ 依赖 │
|
||||
│ │ │
|
||||
│ ┌─────────────────────────────────────────────────┐ │
|
||||
│ │ Infrastructure Layer │ │
|
||||
│ │ Repository Implementations │ │
|
||||
│ │ - DepositTransactionRepositoryImpl │ │
|
||||
│ │ - MonitoredAddressRepositoryImpl │ │
|
||||
│ └─────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 六边形架构端口与适配器
|
||||
|
||||
| 类型 | 端口 (Port) | 适配器 (Adapter) |
|
||||
|------|------------|------------------|
|
||||
| **入站 (Driving)** | Controllers | HTTP API |
|
||||
| **入站 (Driving)** | Kafka Consumer | Event Handler |
|
||||
| **出站 (Driven)** | Repository Interfaces | Prisma Repositories |
|
||||
| **出站 (Driven)** | Cache Interface | Redis Cache |
|
||||
| **出站 (Driven)** | Event Publisher | Kafka Producer |
|
||||
| **出站 (Driven)** | External Services | HTTP Clients |
|
||||
|
||||
### 16.3 命名约定
|
||||
|
||||
为与其他服务保持一致,请遵循以下命名约定:
|
||||
|
||||
| 类型 | 命名规则 | 示例 |
|
||||
|------|---------|------|
|
||||
| **聚合根** | `*.aggregate.ts` | `deposit-transaction.aggregate.ts` |
|
||||
| **值对象** | `*.vo.ts` | `chain-type.vo.ts`, `block-number.vo.ts` |
|
||||
| **领域事件** | `*.event.ts` | `deposit-detected.event.ts` |
|
||||
| **仓储接口** | `*.repository.interface.ts` | `deposit-transaction.repository.interface.ts` |
|
||||
| **仓储实现** | `*.repository.impl.ts` | `deposit-transaction.repository.impl.ts` |
|
||||
| **映射器** | `*.mapper.ts` | `deposit-transaction.mapper.ts` |
|
||||
| **模块** | `*.module.ts` | `api.module.ts`, `domain.module.ts` |
|
||||
|
||||
### 16.4 Symbol Token 注入规范
|
||||
|
||||
使用 Symbol 作为依赖注入 Token,与其他服务保持一致:
|
||||
|
||||
```typescript
|
||||
// 定义 (domain/repositories/index.ts)
|
||||
export const DEPOSIT_TRANSACTION_REPOSITORY = Symbol('DEPOSIT_TRANSACTION_REPOSITORY');
|
||||
export const MONITORED_ADDRESS_REPOSITORY = Symbol('MONITORED_ADDRESS_REPOSITORY');
|
||||
export const BLOCK_CHECKPOINT_REPOSITORY = Symbol('BLOCK_CHECKPOINT_REPOSITORY');
|
||||
|
||||
// 注册 (modules/domain.module.ts)
|
||||
{
|
||||
provide: DEPOSIT_TRANSACTION_REPOSITORY,
|
||||
useClass: DepositTransactionRepositoryImpl,
|
||||
}
|
||||
|
||||
// 注入 (application/services/*.ts)
|
||||
constructor(
|
||||
@Inject(DEPOSIT_TRANSACTION_REPOSITORY)
|
||||
private readonly depositRepo: IDepositTransactionRepository,
|
||||
) {}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*文档版本: 1.1.0*
|
||||
*最后更新: 2025-12-03*
|
||||
*变更说明: 添加模块化设计、聚合根基类、完整值对象定义、架构兼容性说明*
|
||||
|
|
|
|||
Loading…
Reference in New Issue