Skip to content

探索项目整体架构和 DDD 层结构

探索这个 Java DDD 项目的整体架构。我需要了解:

  1. 项目模块结构(各个 maven module 是什么)
  2. DDD 分层目录结构(domain / infrastructure / trigger / api / types 等)
  3. 各个领域(auth / activity / user / matching / notification) 的 domain 层现有代码情况
  4. 重点看 domain 层各模块有哪些 port/in(应用服务接口)、port/out(仓储接口)、model(聚合根/实体/值对象)

请列出每个模块的关键文件路径和主要内容概述。先从项目根 pom.xml 开始,看清楚 module 划分。

下面是基于根 pom.xmltour-mate-platform-domain 等模块源码的架构梳理(只读扫描)。


1. Maven 模块划分(根 pom.xml

根工程:/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/pom.xmlpackaging=pom,声明 6 个子模块(第 10–17 行):

模块 artifactId目录角色(与文档一致)
`tour-mate-platform-types'/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/tour-mate-platform-types枚举、异常、常量等共享类型
tour-mate-platform-api.../tour-mate-platform-api对外 HTTP 契约(Request/Response/DTO)
tour-mate-platform-domain.../tour-mate-platform-domainDDD 领域:聚合、端口、领域服务、事件、Saga
tour-mate-platform-infrastructure.../tour-mate-platform-infrastructure仓储实现、PO、Adapter、Gateway
tour-mate-platform-app.../tour-mate-platform-appSpring Boot 启动、全局配置、少量应用服务装配(如支付回调、Saga 恢复)
tour-mate-platform-trigger.../tour-mate-platform-triggerController、定时任务、Listener(边缘适配)

说明:domainpom.xml 还依赖了 tour-mate-platform-api(注释写明「认证模块需要」),因此领域层与 API DTO 存在一定耦合,与纯 DDD 中「domain 不依赖 api」的理想形态略有出入。


2. DDD 分层在仓库里的落位

  • Types com.alisunxin.api.types — 约 5 个 Java 文件(AppExceptionResponseCodeConstants 等)。
  • API com.alisunxin.api.api.*com.alisunxin.api.dto.* — Request/Response/DTO(认证、活动、匹配、通知 DTO 等)。
  • Domain(核心) 根包:com.alisunxin.api.domain,按限界上下文再分子包,典型子目录包括:
    • port/in:应用服务接口(输入端口)
    • port/out:仓储、外部网关、通知等(输出端口)
    • model/aggregatemodel/entity
    • valobjeventservice(应用服务实现或领域服务)、sagaspecificationdto/query(领域内查询对象)
  • Infrastructure com.alisunxin.api.infrastructureadapter/(repository、payment、notification 等)、dao/(po、jpa repository、converter、specification)、gateway/service/(锁、缓存、JWT 等)。
  • Trigger com.alisunxin.api.triggerhttp/(REST)、job/listener/
  • App com.alisunxin.apiApplication.javaconfig/*、以及 service/payment/*service/saga/SagaRecoveryApplicationService 等。
  • Shared(跨域) com.alisunxin.api.domain.shared:事件(DomainEventIDomainEventPublisher 等)、Saga 基座(AbstractSagaISaga)、规格、通用值对象(如 Money)。

另外还有独立领域包:chatcontentpostsecurity(与安全/会话相关,与 auth 登录编排常一起用)。


3. 各域 Domain 现状概要

auth.../domain/auth

类别路径与内容
port/in/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/tour-mate-platform-domain/src/main/java/com/alisunxin/api/domain/auth/port/in/IAuthApplicationService.java — 微信登录、刷新 token、登出
port/outIWechatGateway.java(微信)、IJwtService.javaITokenExtractor.javaIUserPort.java(与用户域协作)
model本包 无 聚合根/实体;逻辑在 service/AuthApplicationService.java 中编排
valobjWechatUserInfo.java

认证与「安全聚合」拆在 security 包(见下)。


activity(最完整,含 CQRS 与 Saga)

类别关键路径与概述
port/inIActivityApplicationService.java — 创建/发布/取消/报名/退出/开始/完成等活动写操作;IActivityQueryApplicationService.java — 查询;IActivityMemberApplicationService.java — 成员相关命令;IPaymentCallbackApplicationService.javaIRefundRetryApplicationService.java — 支付/退款编排入口(接口在 domain,部分实现在 app/infrastructure)
port/outIActivityAggregateRepository.javaIActivityMemberRepository.javaIPaymentPort.javaIUserCreditPort.javaIAlertPort.java;通知:IActivityNotificationPort.java(领域事件/聚合驱动,Saga 使用)与 ActivityNotificationPort.java(另一套按 ID/Location 等参数的接口,内容上属于同类能力的另一形态)
modelmodel/aggregate/ActivityAggregate.javamodel/entity/ActivityMemberEntity.java
其它valobj/(含 ActivityIdLocation、支付/退款/信用等);event/(创建、取消、开始、完成、成员进退、退款成功等);saga/(报名、取消、完成、退出、PartialRefundSaga 等);service/ActivityApplicationServiceActivityQueryApplicationServiceActivityMemberApplicationService 及多项事务服务)

user

类别关键路径与概述
port/inport/in/package-info.java 标明 IUserApplicationService 等待添加,当前 无 正式应用服务接口
port/outIUserRepository.java(聚合持久化);IUserInterestRepository.javaUserNotificationPort.java(欢迎邮件、验证码、安全通知等)
modelUserAggregate.java(含 UserEntity、兴趣列表与领域事件收集);entity/UserEntity.javaUserInterestEntity.java
其它valobj/UserId.javaEmail.javaPhoneNumber.javaservice/UserRegistrationServiceUserAuthenticationService);specification/UserSpecifications.javaevent/UserRegisteredEvent.java

matching

类别关键路径与概述
port/inport/in/package-info.java 标明 IMatchingApplicationService 等待添加,当前 无 正式应用服务接口
port/outIMatchingAggregateRepository.javaIMatchResultRepository.javaIUserPreferenceRepository.javaMatchingAlgorithmPort.java(内嵌 MatchResult 嵌套类,与聚合里的结果列表命名需留意区分)
modelMatchingAggregate.javaMatchRequestIdMatchingCriteria、状态、结果列表、领域事件);entity/MatchRequestEntity.javaMatchResultEntity.javaUserPreferenceEntity.java
其它service/MatchingService.javaRecommendationService.javaspecification/MatchingSpecifications.javadto/query/*

notification(独立领域包)

  • 不存在目录:.../domain/notification(0 个文件)。

  • 能力分布

    • 活动侧:activity/port/out/IActivityNotificationPort.java(及 ActivityNotificationPort.java)— 创建/取消/开始/完成/成员进退等通知。
    • 用户侧:user/port/out/UserNotificationPort.java — 邮件/短信/安全类通知。
    • 接入层占位:.../tour-mate-platform-trigger/.../NotificationController.java/api/v1/notifications,注释里写明服务未注入,偏脚手架。
  • 基础设施:例如 .../infrastructure/adapter/notification/AlertAdapter.javadao 侧有 NotificationJpaRepositoryNotificationPoSpecs 等,支撑通知持久化/告警,但领域层没有单独的「Notification 聚合」包。


与「认证」强相关的 security(建议一并理解)

类别关键路径与概述
port/inpackage-info — 应用服务接口待添加
port/outISecurityAggregateRepository.javaIUserSessionRepository.javaIRoleRepository.javaIUserRoleRepository.javaITokenValidationPort.java
modelSecurityAggregate.java;实体 UserSessionEntityRoleEntityUserRoleEntity
serviceAuthenticationServiceAuthorizationServiceEncryptionService;事件 UserLoginEventUserLogoutEvent

4. 其它 Domain 子包(便于对照仓库全貌)

  • chatport/in 待扩展;port/outIChatMemberRepositoryIMessageRepositoryMessageDeliveryPort;含 ChatMemberService、事件 MessageSentEvent 等。
  • content / post:内容聚合、审核端口、帖子实体等(与活动/社交内容相关)。
  • sharedeventsaga(含 ISagaRecoveryApplicationService)、specificationvalobj/BaseIdMoney 等。

5. 小结

  • 模块:根 POM 固定为 6 个 Maven 子模块(types → api → domain ← infrastructure;app 组装;trigger 暴露 HTTP/Job)。
  • DDD 目录:领域代码集中在 com.alisunxin.api.domain.{context},按 port/in|outmodelserviceeventsaga 等拆分;infrastructure 用 adapter + dao 实现端口。
  • 你关心的五块:activity 最完整(含 in/out/model 与 Saga);auth 有明确 IAuthApplicationService 但无本包聚合;user / matching 模型与 out 端口较全,in 端口在 package-info 中仍标为待办;notification 没有独立 domain/notification 包,由 activity/user 的 Notification Port + infrastructure adapter(及 Trigger 占位接口)承担。

若你需要,我可以再按「从 Controller 到某个用例」画一条具体调用链(例如微信登录或活动报名)只做只读追溯。

查看现有数据库表和 Cursor 规则

请查找以下内容: 1. 搜索项目中所有 *.sql 文件(建表语句、migration 等) 2. 读取 .cursor/rules/ddd-core.mdc 文件 3. 读取 .cursor/rules/ports-naming.mdc 文件 4. 读取 .cursor/rules/saga-event.mdc 文件 5. 读取 CLAUDE.md 文件 6. 查看 docs/ 目录下有没有数据库设计文档或 ER 图 7. 搜索项目中的 JPA Entity 类(搜索 @Entity 注解),列出所有已有的数据库实体 请把这些信息都整理出来。

1. 项目中所有 *.sql 文件(共 7 个)

绝对路径
/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/docs/dev-ops/docker/mysql/sql/init.sql
/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/docs/dev-ops/docker-simple/mysql/sql/init.sql
/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/docs/migrations/000_full_schema_snapshot.sql
/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/docs/migrations/001_create_users_table.sql
/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/docs/migrations/002_wechat_login_migration.sql
/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/docs/migrations/003_domain_event_record_table.sql
/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/docs/migrations/004_saga_state_table.sql

说明:docs/migrations/ 下为增量迁移与全量快照;两处 init.sql 对应 Docker / docker-simple 的 MySQL 初始化。


2. .cursor/rules/ddd-core.mdc 要点

  • Front matter:针对 **/*.java,描述为 DDD 六边形核心分层与编码规范。
  • 分层:Domain(充血模型、Port)、Infrastructure(Repository/PO/Adapter)、App(编排与组装)、API(契约)、Trigger(Controller/Job/Listener)、Types(枚举/异常等)。
  • 依赖:允许 Trigger→Domain/API、Domain→Types、Infrastructure→Domain、App→各层;禁止 Trigger 直接依赖 Infrastructure、Domain 依赖 Infrastructure 等。
  • 转换链:Request→Command→Entity→PO→DB;逆向 Response←DTO←Entity←PO。
  • 流程:先 Domain,再 Infra、App、API、Trigger。
  • 编码:Lombok、AppExceptionResponse<T>、公共方法 JavaDoc。

3. .cursor/rules/ports-naming.mdc 要点

  • Input Port:IXxxApplicationServicedomain/xxx/port/in/,App 实现、Trigger 调用。
  • Output Port:仓储 IXxxRepository、外部 IXxxPortdomain/xxx/port/out/,Infra 实现。
  • Adapter:仓储实现类名 XxxRepository(无 Adapter 后缀),infrastructure/adapter/repository/;外部 XxxAdapter;事件 DomainEventPublisherAdapter
  • API:XxxRequest / XxxResponse
  • 原则:Port 用领域对象;Adapter 只做技术实现、异常转 AppException、关键操作幂等。

4. .cursor/rules/saga-event.mdc 要点

  • 领域事件:Domain 中 DomainEvent 基类 + XxxEvent(过去时);聚合根收集事件;ApplicationService 通过 IDomainEventPublisher 发布;Infrastructure 里 @Async + @TransactionalEventListener(AFTER_COMMIT) 监听。
  • Saga:ISaga<C>SagaStatus;示例 ActivityCancellationSaga:持久化状态、分步执行、失败补偿逆序、步骤幂等。
  • 事务:聚合内同一事务;跨聚合用事件或 Saga;监听器 AFTER_COMMIT + 异步。

5. CLAUDE.md 要点

与根目录项目说明一致:Java 17、Spring Boot 3.4.3、MySQL、MyBatis + Spring Data JPA、Redis;六层模块名(trigger/app/domain/infrastructure/api/types);调用链 HTTP→Controller→ApplicationService→聚合→Repository→DB;依赖倒置、统一异常与响应、充血模型、事件驱动、Saga;命名速查表;并指向上述三条 .mdc 规则。


6. docs/ 下数据库设计 / ER 图

  • 未发现 专用 ER 图文件:全仓库未匹配到 *.puml*.mmd*.drawio*.dbml*.erd 等常见 ER 载体。

  • 与“数据库设计 / 表结构”相关的 Markdown

    (多为业务文档章节,非统一 ER 文档)例如:

    • /Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/docs/需求文档/微信登录/uni-app 前端对接文档/微信登录实现总结.md(含「数据库设计」)
    • /Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/docs/需求文档/微信登录/后端对接文档/微信登录实现总结-后端.md
    • /Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/docs/需求文档/微信登录/后端对接文档/微信登录快速开始.md(「数据库表结构」)
    • /Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/docs/需求文档/微信登录/uni-app 前端对接文档/微信登录后端接入要求.md
    • /Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/docs/活动退款场景/PARTIAL_REFUND_IMPLEMENTATION.md(标注「数据库设计(待创建)」)
  • 结构性参考:/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/docs/README.md/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/docs/开发工作流指南.md/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/docs/项目结构说明.mddocs/migrations/000_full_schema_snapshot.sql 作为全量建表快照与维护约定。

结论:没有集中的 ER 图文档;实际表结构以 docs/migrations/(尤其 000_full_schema_snapshot.sql)和部分需求文档章节为主。


7. 带 @Entity 的 JPA 实体(Infrastructure PO,共 13 个)

均在 tour-mate-platform-infrastructurecom.alisunxin.api.infrastructure.dao.po 包下:

类文件绝对路径
/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/tour-mate-platform-infrastructure/src/main/java/com/alisunxin/api/infrastructure/dao/po/ActivityMemberPO.java
/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/tour-mate-platform-infrastructure/src/main/java/com/alisunxin/api/infrastructure/dao/po/ActivityPO.java
/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/tour-mate-platform-infrastructure/src/main/java/com/alisunxin/api/infrastructure/dao/po/ChatPO.java
/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/tour-mate-platform-infrastructure/src/main/java/com/alisunxin/api/infrastructure/dao/po/DomainEventRecordPO.java
/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/tour-mate-platform-infrastructure/src/main/java/com/alisunxin/api/infrastructure/dao/po/MatchRequestPO.java
/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/tour-mate-platform-infrastructure/src/main/java/com/alisunxin/api/infrastructure/dao/po/MatchResultPO.java
/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/tour-mate-platform-infrastructure/src/main/java/com/alisunxin/api/infrastructure/dao/po/NotificationPO.java
/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/tour-mate-platform-infrastructure/src/main/java/com/alisunxin/api/infrastructure/dao/po/PostPO.java
/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/tour-mate-platform-infrastructure/src/main/java/com/alisunxin/api/infrastructure/dao/po/RolePO.java
/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/tour-mate-platform-infrastructure/src/main/java/com/alisunxin/api/infrastructure/dao/po/SagaStatePO.java
/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/tour-mate-platform-infrastructure/src/main/java/com/alisunxin/api/infrastructure/dao/po/UserPO.java
/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/tour-mate-platform-infrastructure/src/main/java/com/alisunxin/api/infrastructure/dao/po/UserRolePO.java
/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/tour-mate-platform-infrastructure/src/main/java/com/alisunxin/api/infrastructure/dao/po/UserSessionPO.java

如需某份 .sql 的表清单对照上述 PO,可在 Agent 模式下让我逐文件拆解 CREATE TABLE

分析 Activity 模块已实现的 DDD 完整链路

分析 Activity 模块作为 "已实现" 的参考模板。我需要了解其完整 DDD 调用链,以便后续其他模块(User / Matching / Notification)参照实现。请检查:

  1. Domain 层: - tour-mate-platform-domainactivity 包内的所有文件 - 聚合根 ActivityAggregate - 端口定义 port/in(应用服务接口)和 port/out(仓储接口) - 值对象、枚举
  2. Infrastructure 层: - tour-mate-platform-infrastructure 下 activity 相关的 Repository 实现 - JPA Entity 定义 - Entity ↔ Domain 转换器
  3. API / DTO 层: - tour-mate-platform-apitour-mate-platform-types 下的 request/response DTO - Converter 转换器

请给出 Activity 模块的完整文件清单和关键代码结构,作为后续开发的参考模板。

下面是对当前仓库里 Activity 模块 的梳理结果(只读检索结论),可作为 User / Matching / Notification 对齐实现的参照。注意:本项目里多数 Activity「应用服务」实现放在 tour-mate-platform-domainactivity/service 包并标注 @Service,与文档里「App 层独占 ApplicationService」的叙述不一致;只有少数接口(如退款重试、支付回调)在 tour-mate-platform-app 实现。


1. 完整调用链(HTTP → 持久化 / 出站)

典型链路与 ActivityController 注释一致:

HTTP → Trigger(Controller)→ Domain port/in(应用服务接口)→ Domain 应用服务实现(@Service,位于 domain 模块)→ ActivityAggregate / Saga / 领域服务 → Domain port/out(仓储与网关)→ Infrastructure(Repository / Adapter)→ DB / 外部系统

触发层示例:

ActivityController.javaLines 44-57

 * 完整调用链:
 * HTTP请求 → ActivityController (Trigger)
 *          ↓
 *          IActivityApplicationService (Domain接口)
 *          ↓
 *          ActivityApplicationService (Domain实现) - 事务管理 / 业务编排
 *          ↓
 *          ActivityAggregate (Domain) - 业务逻辑
 *          ↓
 *          IActivityAggregateRepository (Domain接口)
 *          ↓
 *          ActivityAggregateRepository (Infrastructure) - 数据持久化
 *          ↓
 *          Database

CQRS:写操作走 IActivityApplicationService,读操作走 IActivityQueryApplicationService,成员相关另有 IActivityMemberApplicationService

事件 / 通知:事务提交后由 Infrastructure 的 ActivityEventListener 监听领域事件,再调用 IActivityNotificationPort(由 ActivityNotificationAdapter 实现)。

混合 App 层:RefundRetryApplicationService/tour-mate-platform-app/...)实现 IRefundRetryApplicationService,注释写明属于 App 层编排。


2. Domain 层:tour-mate-platform-domain/.../domain/activity(共 56 个 .java

根路径:/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/tour-mate-platform-domain/src/main/java/com/alisunxin/api/domain/activity/

2.1 聚合根与实体

路径(相对 domain/activity说明
model/aggregate/ActivityAggregate.java聚合根;内含 ActivityStatusCostType 枚举
model/entity/ActivityMemberEntity.java成员实体
model/entity/package-info.java包说明

2.2 Port In(应用服务接口,port/in

文件职责概要
IActivityApplicationService.java命令侧:创建/发布/取消/开始/完成/报名/退款申请等
IActivityQueryApplicationService.java查询侧
IActivityMemberApplicationService.java成员侧命令
IPaymentCallbackApplicationService.java支付回调入口契约
IRefundRetryApplicationService.java退款重试契约(实现在 app 模块)

2.3 Port Out(仓储与外部端口,port/out

文件说明
IActivityAggregateRepository.java活动聚合仓储(含 Specification、search、场景查询等)
IActivityMemberRepository.java成员仓储
IPaymentPort.java支付出站端口
IUserCreditPort.java用户信用出站端口
IAlertPort.java告警出站端口
IActivityNotificationPort.java事件驱动通知(方法参数多为领域事件)
ActivityNotificationPort.java另一套通知抽象(参数多为 ActivityId/UserId/Location 等);与 IActivityNotificationPort 并存,命名风格不统一,后续模块建议统一为一种
package-info.java包说明

2.4 应用服务 / 事务服务实现(均在 Domain 模块,service/

文件角色
ActivityApplicationService.javaIActivityApplicationService 实现,编排 Saga、仓储、事件发布
ActivityQueryApplicationService.java查询应用服务
ActivityMemberApplicationService.java成员应用服务
ActivityTransactionService.java事务相关领域编排
ActivityRegistrationTransactionService.java报名事务
ActivityQuitTransactionService.java退出事务
RefundApplicationTransactionService.java退款申请事务
package-info.java包说明

2.5 Saga / Command

文件
saga/ActivityCancellationCommand.java, ActivityCancellationSaga.java
saga/ActivityCompletionCommand.java, ActivityCompletionSaga.java
saga/ActivityQuitCommand.java, ActivityQuitSaga.java
saga/ActivityRegistrationCommand.java, ActivityRegistrationSaga.java
saga/PartialRefundCommand.java, PartialRefundSaga.java

2.6 领域事件(event/

文件
ActivityCreatedEvent.java, ActivityCancelledEvent.java, ActivityStartedEvent.java, ActivityCompletedEvent.java
MemberJoinedEvent.java, MemberQuitEvent.java
RefundSuccessEvent.java

2.7 规格与查询 DTO

文件
specification/ActivitySpecifications.java
dto/query/ActivitySearchCriteria.java, dto/query/ActivitySearchResult.java

2.8 值对象与枚举(含 payment/credit)

路径类型
valobj/ActivityId.java, Location.java, RegistrationResult.java值对象
valobj/payment/OrderRequest.java, OrderResult.java, OrderStatus enum, RefundRecord.java, RefundReason.java, RefundResult.java, RefundStatus enum订单/退款相关
valobj/credit/CreditAddReason.java, CreditDeductionReason.java信用原因枚举

聚合内枚举(非独立文件):ActivityAggregate.ActivityStatusActivityAggregate.CostType


3. Infrastructure 层(Activity 相关)

根:/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/tour-mate-platform-infrastructure/src/main/java/com/alisunxin/api/infrastructure/

绝对路径职责
.../adapter/repository/ActivityAggregateRepository.java实现 IActivityAggregateRepositoryActivityConverter + ActivityJpaRepository
.../adapter/repository/ActivityMemberRepository.java实现 IActivityMemberRepository,Entity ↔ PO 转换写在仓储类内部(entityToPO / poToEntity
.../dao/po/ActivityPO.javaJPA 实体 / 表 activities
.../dao/po/ActivityMemberPO.java成员 PO
.../dao/repository/ActivityJpaRepository.javaSpring Data JPA
.../dao/repository/ActivityMemberJpaRepository.java成员 JPA
.../dao/converter/ActivityConverter.javaAggregate ↔ ActivityPO
.../dao/specification/ActivityPoSpecs.javaPO 层 JPA Specification
.../adapter/notification/ActivityNotificationAdapter.java实现 IActivityNotificationPort
.../adapter/event/listener/ActivityEventListener.java@TransactionalEventListener + @Async,对接通知端口

支付相关(Activity 流程会用到):.../adapter/payment/PaymentAdapter.javaEmptyPaymentAdapter.java


4. API / DTO / Converter(及 Trigger)

4.1 tour-mate-platform-api

根:/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/tour-mate-platform-api/src/main/java/com/alisunxin/api/

Request(api/request/

  • CreateActivityRequest.java, PublishActivityRequest.java, CancelActivityRequest.java
  • JoinActivityRequest.java, RegisterActivityRequest.java
  • StartActivityRequest.java, CompleteActivityRequest.java

Response(api/response/

  • ActivityResponse.java, ActivityDetailResponse.java, ActivityMemberResponse.java

DTO

  • api/dto/activity/ActivityDTO.java
  • dto/activity/ActivitySearchRequest.java, dto/activity/ActivitySearchResponse.java(与 Domain 的 ActivitySearchCriteria / ActivitySearchResult 在 Controller 里组合使用)

统一响应外壳:api/response/Response.java(Controller 中使用)。

4.2 Trigger 层转换器

绝对路径
/Users/sunxin/IdeaProjects/skeeter/tour-mate-platform/tour-mate-platform-trigger/src/main/java/com/alisunxin/api/trigger/converter/ActivityResponseConverter.java

职责:ActivityAggregateActivityResponse(Trigger 层防腐)。

4.3 tour-mate-platform-types(与 Activity 直接相关)

绝对路径
.../types/exception/ActivityQueryException.java
.../types/exception/ActivityRepositoryException.java

5. 模板化时可对齐的「关键结构」要点

  1. 分层契约:Trigger 只依赖 Domain port/in + API DTO;仓储与外部系统依赖 Domain port/out,实现在 Infrastructure。
  2. 两套持久化映射:活动聚合用独立 ActivityConverter;成员仓储把 Entity ↔ PO 放在 ActivityMemberRepository 内(新模块可二选一统一风格)。
  3. 枚举位置:核心业务状态可在聚合根内(如 ActivityStatus);支付子域可用独立 enum 文件(如 OrderStatus)。
  4. CQRS:命令 / 查询拆接口;Controller 注释已写明分工。
  5. 与本仓库文档的差异:Activity 的 ActivityApplicationService 等在 domain 模块,复制模板时不要强行把所有应用服务塞进 app,除非你打算重构现有约定。
  6. 通知端口:存在 ActivityNotificationPortIActivityNotificationPort 两套命名;当前适配器实现的是 IActivityNotificationPort

若你希望后续模块严格对齐「应用服务只在 App 模块」,需要先约定是否对 Activity 做一次物理迁移;若以现状为准,新模块可直接沿用「domain 模块内的 @Service 应用服务 + trigger 注入接口」这一套。


小结:已列出 Domain 下 activity 共 56 个 Java 文件的分类清单、Infrastructure/API/Types/Trigger 相关路径,并说明了 HTTP→仓储→事件的调用链及与本项目文档不一致的应用服务放置方式(便于你拷贝模板时少走弯路)。

看了你的项目结构文档,你的设计意图很清晰。我来回答你的架构问题

应用服务放 Domain 层 vs App 层

你现在的做法是完全合理的,而且对你这个项目来说是更好的选择。原因如下:

DDD 社区对此有两种主流实践,不是非此即彼:

方案 A:应用服务放 App 层(Vaughn Vernon 风格)

  • App 层负责事务协调、用例编排
  • Domain 层只有聚合根、实体、领域服务、Port 接口
  • 优点:Domain 模块极其纯粹,零 Spring 依赖
  • 代价:App 层会变得很重,且需要与 Domain 层频繁跨模块交互

方案 B:应用服务放 Domain 层(你的做法,也是很多实际项目的选择)

  • Domain 的 service/ 下放 XxxApplicationService,实现 port/in 中定义的接口
  • App 层只负责组装(启动类、配置、跨域编排如 Saga 恢复)
  • 优点:一个领域包内自包含——模型、端口、实现、事件、Saga 都在一起,改一个功能不用跨模块跳转
  • 代价:Domain 模块会依赖 Spring @Service/@Transactional 注解

从你的代码来看,方案 B 更适合你:

  1. 你的 Activity 模块已经稳定运行,ActivityApplicationServicedomain/activity/service/ 下,与聚合根、Saga、事件放在一起,改动时上下文完整
  2. App 层 service/ 只放了真正的"跨域编排"——payment/saga/SagaRecoveryApplicationService,这恰好是该层该做的事
  3. 你的 CLAUDE.mdddd-core.mdc 虽然文字上写了"App 层放 ApplicationService",但实际代码约定是方案 B,代码即文档,以代码为准

结论:新模块(User/Matching/Notification/Security)的应用服务全部放在 Domain 层的 service/ 包下,与 Activity 模块保持一致。计划不需要修改。

Powered by VitePress