Compare commits
2 Commits
0db85586be
...
ff0860c6db
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff0860c6db | ||
|
|
9a1331109f |
8
.dockerignore
Normal file
8
.dockerignore
Normal file
@ -0,0 +1,8 @@
|
||||
.git
|
||||
.gitignore
|
||||
target
|
||||
tmp
|
||||
bin
|
||||
dist
|
||||
coverage
|
||||
**/.DS_Store
|
||||
67
AGENT.md
Normal file
67
AGENT.md
Normal file
@ -0,0 +1,67 @@
|
||||
# chatapp3-golang Agent Guide
|
||||
|
||||
## 目标
|
||||
- 这个仓库现在按模块组织,新增功能时不要再把代码堆回平铺目录。
|
||||
- 路由、业务、工具函数、共享类型要分层放置,优先保持“一个文件只表达一个明确职责”。
|
||||
|
||||
## 目录约定
|
||||
- `cmd/api`
|
||||
- 仅负责启动、依赖组装、优雅退出。
|
||||
- `cmd/consumer`
|
||||
- 仅负责事件消费任务启动、优雅退出。
|
||||
- 当前只承接 `registerreward` Redis Stream 与 `weekstar` RocketMQ 消费。
|
||||
- `internal/bootstrap`
|
||||
- 负责配置加载、存储初始化、Java 网关装配。
|
||||
- `api` 与 `consumer` 统一复用,不要重复写一份启动拼装逻辑。
|
||||
- `internal/router`
|
||||
- 只负责 HTTP 路由注册、请求绑定、中间件、统一响应。
|
||||
- 每个模块单独一个 `*_routes.go` 文件。
|
||||
- `internal/service/<module>`
|
||||
- 每个业务模块一个目录。
|
||||
- `types.go` 放服务结构体、常量、DTO、内部类型。
|
||||
- 模块内辅助函数不要再统一塞进 `utils.go`,而是按语义放进 `normalize.go`、`stream.go`、`mapper.go`、`convert.go` 这类文件。
|
||||
- 业务按职责拆文件,例如 `config.go`、`page.go`、`callback.go`、`reward.go`、`consumer.go`。
|
||||
- 一个文件只保留一类逻辑,不要再出现“一个文件承接整个模块所有流程”的写法。
|
||||
- `internal/common`
|
||||
- 放跨模块共享的类型,比如 `AppError`、`AuthUser`。
|
||||
- `internal/utils`
|
||||
- 放跨模块复用的通用工具函数。
|
||||
- `internal/model`
|
||||
- 只放 Gorm 模型和表结构映射。
|
||||
- 模型按业务模块拆文件,例如 `invite_models.go`、`weekstar_models.go`、`luckygift_models.go`。
|
||||
- `internal/integration`
|
||||
- 只放外部系统调用封装。
|
||||
- `integration.Client` 已按职责包装成多个 gateway,新增下游能力时优先按网关语义扩展。
|
||||
- `internal/repo`
|
||||
- 只放基础存储初始化和仓储级装配。
|
||||
- 不要再把 schema 自动修正逻辑塞回启动流程,数据库变更统一走 `migrations/`。
|
||||
|
||||
## 编码规则
|
||||
- 新增 helper 时,优先判断是不是“辅助函数”:
|
||||
- 模块内使用:放对应模块目录下有语义的文件名里,不要新增 `utils.go`
|
||||
- 跨模块复用:放 `internal/utils`
|
||||
- 不要在 router 里写业务判断,不要在 service 里拼 HTTP 响应。
|
||||
- 不要把不同模块的 request / response / callback DTO 混放到一个文件里。
|
||||
- 不要把配置查询、榜单查询、MQ 消费、发奖、回调处理重新揉回一个文件。
|
||||
- 新增路由时,先在 `internal/router` 下新建模块路由文件,再在 `router.go` 里挂载。
|
||||
- `weekstar` 自动结算和自动发奖已经迁到 `chatapp-cron`,不要在这个仓库重新引入任何 scheduler/settlement runner。
|
||||
|
||||
## 提交前检查
|
||||
- `goimports -w` 涉及 Go 文件
|
||||
- `gofmt -w` 涉及文件
|
||||
- `go test ./...`
|
||||
- 确认没有把模块 helper 又写回逻辑文件
|
||||
|
||||
## 当前模块
|
||||
- `invite`
|
||||
- `baishun`
|
||||
- `luckygift`
|
||||
- `registerreward`
|
||||
- `weekstar`
|
||||
|
||||
## 运行边界
|
||||
- `chatapp3-golang`
|
||||
- 负责 HTTP API 与事件消费。
|
||||
- 不负责 `weekstar` 周期结算扫描、快照冻结、自动发奖、失败补发执行。
|
||||
- `chatapp-cron`
|
||||
- 是 `weekstar` 结算、自动发奖、失败补发执行的唯一执行方。
|
||||
22
Dockerfile
Normal file
22
Dockerfile
Normal file
@ -0,0 +1,22 @@
|
||||
FROM golang:1.24 AS builder
|
||||
|
||||
ARG APP_VERSION="dev"
|
||||
ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64
|
||||
|
||||
WORKDIR /src
|
||||
COPY . .
|
||||
RUN go build -trimpath -ldflags="-s -w" -o /out/chatapp3-golang ./cmd/api
|
||||
|
||||
FROM alpine:3.20
|
||||
|
||||
ARG APP_VERSION="dev"
|
||||
RUN apk add --no-cache ca-certificates wget
|
||||
|
||||
WORKDIR /application
|
||||
COPY --from=builder /out/chatapp3-golang /application/service
|
||||
|
||||
LABEL org.opencontainers.image.version="${APP_VERSION}"
|
||||
|
||||
RUN chmod +x /application/service
|
||||
|
||||
ENTRYPOINT ["/application/service"]
|
||||
180
README.md
Normal file
180
README.md
Normal file
@ -0,0 +1,180 @@
|
||||
# chatapp3-golang
|
||||
|
||||
## 现在的结构
|
||||
|
||||
项目已经从平铺结构调整为按模块组织,并把运行职责拆成了 `api` 与 `consumer` 两个入口:
|
||||
|
||||
```text
|
||||
cmd/api
|
||||
cmd/consumer
|
||||
internal/bootstrap
|
||||
internal/common
|
||||
internal/config
|
||||
internal/integration
|
||||
internal/model
|
||||
internal/repo
|
||||
internal/router
|
||||
internal/service/baishun
|
||||
internal/service/invite
|
||||
internal/service/luckygift
|
||||
internal/service/registerreward
|
||||
internal/service/weekstar
|
||||
internal/utils
|
||||
```
|
||||
|
||||
每个业务模块都已经拆成独立目录,router 也改成模块化注册,不再把所有处理器和平铺 service 混在一起。`weekstar` 的自动结算、自动发奖和失败补发执行已经迁到 `chatapp-cron`,当前仓库只保留 API、实时积分消费、查询和失败补发任务投递能力。
|
||||
|
||||
## 分层说明
|
||||
|
||||
### 1. `cmd/api`
|
||||
- 只做启动和依赖装配。
|
||||
- 不承担业务逻辑。
|
||||
- 不启动任何 `weekstar` 结算 goroutine。
|
||||
|
||||
### 2. `cmd/consumer`
|
||||
- 只做事件消费任务启动和优雅退出。
|
||||
- 当前承接:
|
||||
- `registerreward` 的 Redis Stream 消费
|
||||
- `weekstar` 的 RocketMQ 消费
|
||||
|
||||
### 3. `internal/bootstrap`
|
||||
- 统一完成配置加载、存储初始化、依赖探活、Java 网关装配。
|
||||
- `cmd/api` 与 `cmd/consumer` 共用这层,避免两份入口各自维护初始化逻辑。
|
||||
|
||||
### 4. `internal/router`
|
||||
- 路由按模块拆分。
|
||||
- `router.go` 只负责创建 Gin Engine 和统一挂载模块路由。
|
||||
- `invite_routes.go`、`week_star_routes.go`、`baishun_routes.go`、`lucky_gift_routes.go` 分别负责各自模块。
|
||||
- `middleware.go`、`response.go` 放公共中间件和统一响应。
|
||||
|
||||
### 5. `internal/service/<module>`
|
||||
- 每个业务模块一个目录,避免所有逻辑堆在同一个 `service` 包里。
|
||||
- `types.go` 只放服务结构、常量、DTO、内部类型。
|
||||
- 业务层只依赖模块自己的 DB/Redis/gateway ports,不再直接依赖大一统 `repo.Repository` 或 `integration.Client`。
|
||||
- 业务流程按职责继续拆文件,例如:
|
||||
- `weekstar/config.go`
|
||||
- `weekstar/page.go`
|
||||
- `weekstar/reward_retry.go`
|
||||
- `registerreward/consumer.go`
|
||||
- `baishun/callback.go`
|
||||
- `invite/recharge.go`
|
||||
- 当前模块:
|
||||
- `invite`
|
||||
- `baishun`
|
||||
- `luckygift`
|
||||
- `registerreward`
|
||||
- `weekstar`
|
||||
|
||||
### 6. `internal/common`
|
||||
- 放跨模块共享结构。
|
||||
- 当前包含:
|
||||
- `AppError`
|
||||
- `AuthUser`
|
||||
|
||||
### 7. `internal/utils`
|
||||
- 放跨模块通用工具。
|
||||
- 当前保留雪花 ID 生成器。
|
||||
|
||||
### 8. `internal/model`
|
||||
- 只放表结构映射,不再维护跨模块大文件。
|
||||
- 当前已经按模块拆分:
|
||||
- `common_models.go`
|
||||
- `invite_models.go`
|
||||
- `registerreward_models.go`
|
||||
- `weekstar_models.go`
|
||||
- `luckygift_models.go`
|
||||
- `baishun_models.go`
|
||||
|
||||
### 9. `internal/integration`
|
||||
- Java 调用已经从单一 `Client` 继续下沉为多个职责网关:
|
||||
- `Auth`
|
||||
- `Device`
|
||||
- `InviteCode`
|
||||
- `RewardDispatch`
|
||||
- `RewardQuery`
|
||||
- `Profile`
|
||||
- `Wallet`
|
||||
|
||||
## 路由装配方式
|
||||
|
||||
在 `cmd/api/main.go` 里先通过 `bootstrap` 组装基础依赖,再创建 service,通过 `router.Services` 统一注入:
|
||||
|
||||
```go
|
||||
engine := router.NewRouter(app.Config, app.Repository, &app.Gateways, router.Services{
|
||||
Invite: inviteService,
|
||||
Baishun: baishunService,
|
||||
LuckyGift: luckyGiftService,
|
||||
WeekStar: weekStarService,
|
||||
})
|
||||
```
|
||||
|
||||
这样做的好处是:
|
||||
- 入口依赖一眼可见
|
||||
- router 不再直接依赖平铺 service 包
|
||||
- 后续拆模块时不会改爆主入口
|
||||
|
||||
## 现在的拆分原则
|
||||
|
||||
- `router`
|
||||
- 一个模块一个路由文件
|
||||
- 公共响应、鉴权、中间件单独放公共文件
|
||||
- `service`
|
||||
- 一个模块一个目录
|
||||
- 一个文件只负责一类逻辑
|
||||
- 模块内辅助函数使用有语义的文件名,不再新增 `utils.go`
|
||||
- `common`
|
||||
- 放跨模块共享对象,例如 `AppError`、`AuthUser`
|
||||
- `utils`
|
||||
- 只放跨模块通用工具,不放业务逻辑
|
||||
|
||||
## 当前模块文件示例
|
||||
|
||||
```text
|
||||
internal/service/weekstar/
|
||||
aliases.go
|
||||
config.go
|
||||
cycle.go
|
||||
event.go
|
||||
lifecycle.go
|
||||
mapper.go
|
||||
page.go
|
||||
reward_retry.go
|
||||
types.go
|
||||
|
||||
internal/service/invite/
|
||||
bind.go
|
||||
home.go
|
||||
landing.go
|
||||
normalize.go
|
||||
recharge.go
|
||||
reward.go
|
||||
store.go
|
||||
task.go
|
||||
types.go
|
||||
```
|
||||
|
||||
## 运行职责
|
||||
|
||||
- `chatapp3-golang`
|
||||
- 负责 HTTP API
|
||||
- 负责事件消费
|
||||
- 负责 `weekstar` 配置、实时榜单、快照/发奖记录查询、失败补发任务投递
|
||||
- `chatapp-cron`
|
||||
- 是 `weekstar` 周期结算扫描、快照冻结、自动发奖、失败补发执行的唯一执行方
|
||||
|
||||
因此当前仓库里不要再新增任何 `scheduler`、`settlement loop`、`start settlement worker` 之类的运行职责。
|
||||
|
||||
## 本地检查
|
||||
|
||||
```bash
|
||||
$(go env GOPATH)/bin/goimports -w cmd internal
|
||||
go test ./...
|
||||
```
|
||||
|
||||
如果有结构调整,提交前建议再跑一遍:
|
||||
|
||||
```bash
|
||||
$(go env GOPATH)/bin/goimports -w cmd internal
|
||||
gofmt -w cmd internal
|
||||
go test ./...
|
||||
```
|
||||
15
ci/build-image.sh
Executable file
15
ci/build-image.sh
Executable file
@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
IMAGE_REF="${1:-}"
|
||||
APP_VERSION="${APP_VERSION:-${2:-dev}}"
|
||||
DOCKER_PLATFORM="${DOCKER_PLATFORM:-linux/amd64}"
|
||||
|
||||
if [ -z "${IMAGE_REF}" ]; then
|
||||
echo "usage: ci/build-image.sh <image-ref> [app-version]" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "${ROOT_DIR}"
|
||||
docker build --platform "${DOCKER_PLATFORM}" --build-arg "APP_VERSION=${APP_VERSION}" -t "${IMAGE_REF}" .
|
||||
Loading…
x
Reference in New Issue
Block a user