优化结构
This commit is contained in:
+54
-50
@@ -1,66 +1,70 @@
|
||||
# `app/system` 到 `pkg` 复用性审查
|
||||
|
||||
审查范围:`app/system` 下全部 Go 文件,以及现有 `pkg` 目录。判断标准是:
|
||||
公共包只能提供跨模块稳定的机制、协议或纯函数,不能依赖 `app/*/internal`,
|
||||
也不承载 system 的业务表、用例、provider 生命周期或运行时配置。
|
||||
审查原则:公共包只提供跨模块稳定的机制、协议或无状态纯函数;不能依赖
|
||||
`app/*/internal`,也不承载 system 的业务表、用例、provider 客户端或运行时
|
||||
配置。
|
||||
|
||||
## 本轮已抽取
|
||||
## 已抽取到 `pkg`
|
||||
|
||||
| 原位置 | 公共位置 | 结论 |
|
||||
|---|---|---|
|
||||
| `internal/transport/httpx/response.go` | `pkg/httpx/response.go` | `Response`、`PageResult`、状态码和 Gin 响应助手是跨模块 HTTP 契约。system 原包保留别名/转发,兼容既有调用方。 |
|
||||
| `internal/utils/configutil/json.go` | `pkg/protoutil/json.go` | protobuf JSON 局部合并、snake_case 到 lowerCamel 归一化与 system 业务无关,已由 system wrapper 转发。 |
|
||||
| `internal/biz/payment.go` provider 常量 | `pkg/paymentkit/provider.go` | provider 标识、支付模式和支持列表是跨业务支付边界,system `biz` 保留兼容常量。 |
|
||||
| `internal/biz/payment.go` 回调应答 | `pkg/paymentkit/callback.go` | 回调 ACK、回调错误和默认 provider 应答是跨模块协议,已由 system 类型别名兼容。 |
|
||||
| 能力 | 公共位置 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| HTTP JSON 响应契约 | `pkg/httpx` | `Response`、`PageResult`、状态码和 Gin 响应助手;`server/httpx/response.go` 仅保留 system 适配。 |
|
||||
| protobuf JSON 局部合并 | `pkg/protoutil` | 与业务无关的字段归一化和局部反序列化;初始化直接使用公共包。 |
|
||||
| 支付 provider/mode 标识 | `pkg/paymentkit` | provider 常量、支持列表、金额/签名/JSON 等跨模块协议;system `biz` 只保留兼容别名。 |
|
||||
| 支付回调 ACK | `pkg/paymentkit` | 回调应答、失败包装和默认 provider 应答;具体渠道 SDK 仍留在 system integration。 |
|
||||
| WebSocket 通用收发 | `pkg/websocket` | Melody 的连接、事件、点对点发送、广播和会话查询封装;system integration 管理配置与生命周期。 |
|
||||
| 消息队列 | `pkg/mq` | Broker 无关的发布、订阅、JSON 和 QoS 接口;EMQX/Paho 客户端由 system integration 管理。 |
|
||||
| 模块、任务和迁移协议 | `pkg/module`、`pkg/task`、`pkg/database/migration` | 供不同业务模块注册贡献,不带 system 业务语义。 |
|
||||
|
||||
## `app/system` 逐目录结论
|
||||
## system 内部保留边界
|
||||
|
||||
| 目录 | 结论 | 代表文件/原因 |
|
||||
|---|---|---|
|
||||
| `cmd` | 保留 system | `main.go`、`wire.go` 是组合根和启动生命周期,不能下沉。 |
|
||||
| `internal/app`、`internal/module` | 保留 system | `catalog.go`、`definition.go` 绑定 system 迁移、菜单、路由和任务贡献。公共协议已在 `pkg/module`。 |
|
||||
| `internal/biz` | 大部分保留;仅抽公共支付边界 | 用户、权限、菜单、审计、任务、支付订单和系统配置都是领域模型/用例;`payment.go` 中 provider 与 ACK 已兼容转发。 |
|
||||
| `internal/conf` | 保留 system | 配置 proto 由 system 运行时和生成代码拥有,不能成为跨模块配置模型。 |
|
||||
| `internal/data` | 保留 system | 数据库连接、迁移、PO、system 表、支付持久化和配置 watcher 都是 system 数据层。通用迁移/分页/GORM 能力已在 `pkg/database`。 |
|
||||
| `internal/dto` | 保留 system | DTO 与 system API 形状绑定,不应跨模块共享。 |
|
||||
| `internal/initialize` | 保留 system | 首次安装、兼容迁移、配置持久化和种子编排具有 system 语义。 |
|
||||
| `internal/integration/cache` | 保留 system | Redis/cache 客户端生命周期和运行时配置属于 integration,不是 stateless utils。 |
|
||||
| `internal/integration/email` | 保留 system | 邮件 provider 配置和发送生命周期属于 system integration。 |
|
||||
| `internal/integration/payment` | 保留 system | `alipay.go`、`wechat_v3.go`、`paypal.go` 等是具体 provider SDK 适配器;不能搬到通用 pkg。纯金额、JSON、签名、状态函数已经在 `pkg/paymentkit`。 |
|
||||
| `internal/integration/storage` | 保留 system | OSS/S3/本地存储客户端、重载和配置绑定属于 integration。 |
|
||||
| `internal/repository` | 保留 system | 仓储实现、PO、Casbin、system 表和事务边界都不能跨模块复用。 |
|
||||
| `internal/routeinfo` | 保留 system | 路由元数据包含 system 初始化与菜单语义。 |
|
||||
| `internal/security/adminauth` | 保留 system | JWT claims、签发和后台认证策略属于 system 安全边界。 |
|
||||
| `internal/service` | 保留 system | DTO 与 system DO 的转换和服务编排,不可放入公共包。 |
|
||||
| `internal/transport/handler` | 保留 system | 每个 handler 都依赖 system service/DTO;只有 HTTP 响应协议抽到 `pkg/httpx`。 |
|
||||
| `internal/transport/httpx` | 兼容层 | `response.go` 已转发到 `pkg/httpx`;`cookie.go` 的 token cookie 名称和认证策略仍是 system 专属。 |
|
||||
| `internal/transport/middleware` | 保留 system | 审计、认证、数据权限、限流、system 错误记录和请求采集均带业务/配置语义。 |
|
||||
| `internal/transport/router` | 保留 system | 路由注册指向 system handlers。 |
|
||||
| `internal/utils/configutil` | 兼容层 | `json.go` 已转发到 `pkg/protoutil`;其余 system 专用工具应留在本目录。 |
|
||||
| `internal/worker` | 保留 system | 任务执行器依赖 system task repo、runtime、日志和业务方法。跨模块任务注册协议已在 `pkg/task`。 |
|
||||
- `app`:组合根,绑定 system 的迁移、菜单、路由和任务贡献。
|
||||
- `biz`:用户、权限、菜单、审计、任务、支付订单和系统配置等领域模型与用例。
|
||||
- `conf`:system 配置 proto、运行时快照和生成代码。
|
||||
- `data`:数据库连接、PO、仓储、system 表、支付持久化和配置 watcher。
|
||||
- `initialize`:首次安装、配置迁移、种子编排和运行时重载。
|
||||
- `integration`:Redis、邮件、存储、支付、WebSocket 和 EMQX 的 provider 生命周期。
|
||||
- `security`:JWT claims、签发/解析和后台安全实现。
|
||||
- `service`:HTTP DTO(`service/dto`)、DTO 与 DO 转换、应用服务和路由元数据。
|
||||
- `server`:Gin 生命周期;handler、middleware、router、HTTP 适配按子包维护。
|
||||
- `worker`:任务调度、执行器、SSE 订阅及其并发状态。
|
||||
|
||||
## 现有 `pkg` 复核
|
||||
这些代码都带有 system 的 API、配置、数据表或生命周期语义,不应为了减少
|
||||
文件数量搬到 `pkg`。
|
||||
|
||||
- `pkg/database/*`:边界正确,继续保留。
|
||||
- `pkg/logging/*`:边界正确,继续保留。
|
||||
- `pkg/module/*`:跨模块迁移/路由/元数据协议,边界正确。
|
||||
- `pkg/task/*`:跨模块任务注册协议,边界正确。
|
||||
- `pkg/paymentkit/*`:本轮补齐 provider 与 callback 协议;具体渠道 SDK 仍留在 system。
|
||||
- 新增 `pkg/httpx`、`pkg/protoutil`:均不引用 `app/*/internal`。
|
||||
## 目录分类约定
|
||||
|
||||
## 暂不抽取的后续候选
|
||||
```text
|
||||
internal/
|
||||
app/ # 组合根和模块定义
|
||||
biz/ # DO、usecase、repo interface
|
||||
conf/ # 配置 proto/runtime
|
||||
data/ # PO、repo、数据库和迁移
|
||||
initialize/ # 首次安装和配置编排
|
||||
integration/ # 外部 I/O provider
|
||||
security/ # JWT 和安全实现
|
||||
server/ # Gin 生命周期,内部按 handler/middleware/router/httpx 分类
|
||||
service/ # 应用服务;DTO 集中在 dto 子包
|
||||
worker/ # 任务运行时
|
||||
```
|
||||
|
||||
1. `internal/transport/httpx/cookie.go`:只有在多个 app 统一 token cookie 名称、SameSite 和反向代理策略后,才适合抽成公共 HTTP cookie 包。
|
||||
2. `internal/transport/middleware/capture.go`:包含 operation-audit 脱敏字段和 system context key,当前不是通用中间件。
|
||||
3. `internal/biz/pagination.go`:依赖 AIP filtering/ordering,且目前只服务 system 的仓储接口;若其他模块形成同样 DO 查询协议,再独立设计 `pkg/query`,不要直接搬 biz 类型。
|
||||
4. `internal/biz/errors.go` 及认证/安全错误:错误 reason 与 system API 语义绑定,不应公共化。
|
||||
技术角色使用子目录表达,子目录内部使用资源名,例如 `handler/payment.go`、
|
||||
`router/payment.go`、`dto/payment.go`。只有少量代码且没有独立边界时不建立
|
||||
新包;同一角色文件较多时也不应全部堆在父目录。
|
||||
|
||||
## 暂不抽取的候选
|
||||
|
||||
1. token cookie 名称、SameSite 和反向代理策略:目前是 system 认证策略。
|
||||
2. operation-audit 脱敏和请求采集:包含 system context key 与审计字段。
|
||||
3. biz 查询选项和错误:当前绑定 system 的领域接口及 API reason。
|
||||
|
||||
只有当其他模块出现相同、稳定且不带 system 语义的契约时,才新增公共包;不要
|
||||
直接把单个 system 类型搬到 `pkg`。
|
||||
|
||||
## 验证
|
||||
|
||||
已运行:
|
||||
|
||||
```text
|
||||
go test ./pkg/... ./app/system/...
|
||||
go test ./...
|
||||
```
|
||||
|
||||
结果:全部通过。
|
||||
当前全仓测试通过,且未发现对已删除旧路径的 Go import。
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
# `app/system/internal` 目录结构优化结论
|
||||
|
||||
参考 Go Kratos 的分层方式,顶层保留 `app`、`biz`、`conf`、`data`、
|
||||
`initialize`、`integration`、`security`、`server`、`service`、`worker` 十个
|
||||
稳定职责。目录不是越少越好:同一技术角色文件较多时,应在所属层下分组,避免
|
||||
一个目录堆积几十个文件。
|
||||
|
||||
## 当前结构
|
||||
|
||||
```text
|
||||
internal/
|
||||
app/ # 组合根、模块 catalog 和 definition
|
||||
biz/ # DO、usecase、repo interface
|
||||
conf/ # 配置 proto/runtime
|
||||
data/ # PO、repo、数据库和迁移
|
||||
initialize/ # 首次安装和配置编排
|
||||
integration/ # 外部 I/O provider
|
||||
security/ # JWT 和安全实现
|
||||
server/
|
||||
handler/ # Gin handler,按资源命名
|
||||
middleware/ # 认证、审计、限流、恢复等中间件
|
||||
router/ # 各资源路由及 Routes 聚合
|
||||
httpx/ # system HTTP 响应和 cookie 适配
|
||||
service/
|
||||
dto/ # HTTP 请求、响应和查询 DTO,按模块命名
|
||||
worker/ # 任务运行时
|
||||
```
|
||||
|
||||
## 本次调整
|
||||
|
||||
- DTO 从 `service` 根目录归档到 `service/dto`。
|
||||
- handler、middleware、router、HTTP helper 分别归档到 `server` 子包。
|
||||
- 子目录内文件直接使用资源名,例如 `handler/payment.go`、
|
||||
`router/payment.go`、`dto/payment.go`,不保留重复角色前缀。
|
||||
- Wire 直接装配 `handler.ProviderSet` 和 `router.ProviderSet`,server 根目录只
|
||||
负责 Gin/Swagger 生命周期。
|
||||
- `security/adminauth/token.go` 合并为 `security/token.go`;单文件子包没有
|
||||
独立边界时不继续拆分。
|
||||
- 删除只转发 `pkg/protoutil` 的 `utils/configutil`。
|
||||
|
||||
## `internal/app` 为什么只有两个文件
|
||||
|
||||
`app/catalog.go` 和 `app/definition.go` 是有意保留的组合根。`catalog.go` 负责
|
||||
组装模块、任务注册与运行时;`definition.go` 声明 system 提供的迁移、管理面
|
||||
和默认定时任务。它们依赖多个层,只能位于应用组合边界,不能并入 `biz`、
|
||||
`service` 或 `data`。
|
||||
|
||||
## 其他目录审查
|
||||
|
||||
- `data` 与 `integration` 已按仓储或 provider 分类,边界和生命周期明确。
|
||||
- `biz`、`service` 根目录采用一资源一文件;进一步拆成资源子包会改变 Go 包
|
||||
边界并容易引入循环依赖,本次不做纯视觉拆分。
|
||||
- `security` 当前只有一个文件,但安全实现是明确的依赖边界,后续认证机制也会
|
||||
在此扩展,因此保留顶层包。
|
||||
|
||||
新增目录应至少满足独立依赖方向、状态生命周期或稳定技术角色之一。不要回到
|
||||
一文件一目录,也不要为了减少目录数量把大量不同角色重新铺平。
|
||||
Reference in New Issue
Block a user