diff --git a/AGENTS.md b/AGENTS.md index af65f56..d47f373 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -38,18 +38,18 @@ ## 2) REPOSITORY LAYOUT & MODULES -| Path | Purpose | -| -------------------------------------------------------------- | --------------------------------------------------------- | -| `backend/cmd/marketplace/product-query-svc` | 进程入口与依赖注入(路由、仓库、配置)。 | -| `apps/product-query-svc/domain` | 领域聚合与不变式(`Product`, `Comment`, `User`)。无 http/sql/env 依赖。 | -| `apps/product-query-svc/application` | 用例编排(实现入站端口),只依赖 `ports` 与 `domain`。 | -| `apps/product-query-svc/adapters` | 入站 HTTP handlers;出站持久化实现。禁止写业务规则。 | +| Path | Purpose | +| -------------------------------------------------- | --------------------------------------------------------- | +| `backend/cmd/product-query-svc` | 进程入口与依赖注入(路由、仓库、配置)。 | +| `apps/product-query-svc/domain` | 领域聚合与不变式(`Product`, `Comment`, `User`)。无 http/sql/env 依赖。 | +| `apps/product-query-svc/application` | 用例编排(实现入站端口),只依赖 `ports` 与 `domain`。 | +| `apps/product-query-svc/adapters` | 入站 HTTP handlers;出站持久化实现。禁止写业务规则。 | | `apps/product-query-svc/adapters/outbound/postgres/migrations` | SQL 迁移(使用 `migrate` 工具)。 | -| `apps/product-query-svc/api/openapi.yaml` | OpenAPI 单一事实源。 | -| `apps/product-query-svc/api/gen` | oapi-codegen 生成物(**禁止手改**)。 | -| `test` | 端到端与集成测试(内存/PG 双路径)。 | -| `scripts`, `Makefile` | 开发脚本、构建、DB 设置、集成流程。 | -| `charts`, `k8s`, `kind` | 部署清单,配置变化时同步。 | +| `apps/product-query-svc/api/openapi.yaml` | OpenAPI 单一事实源。 | +| `apps/product-query-svc/api/gen` | oapi-codegen 生成物(**禁止手改**)。 | +| `test` | 端到端与集成测试(内存/PG 双路径)。 | +| `scripts`, `Makefile` | 开发脚本、构建、DB 设置、集成流程。 | +| `charts`, `k8s`, `kind` | 部署清单,配置变化时同步。 | **分层约定** diff --git a/Dockerfile b/Dockerfile index 0161fb7..a661323 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,7 @@ COPY . . RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \ - go build -o /out/product-query-svc ./backend/cmd/marketplace/product-query-svc + go build -o /out/product-query-svc ./backend/cmd/product-query-svc # Runtime FROM gcr.io/distroless/base-debian12:nonroot diff --git a/Makefile b/Makefile index a793c75..806feb1 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # Makefile for common tasks -.PHONY: gen build run fmt tidy migrate-up migrate-down migrate-create db-init +.PHONY: gen build run fmt tidy migrate-up migrate-down migrate-create db-init test-repo-docker -SERVICE_PKG=./backend/cmd/marketplace/product-query-svc +SERVICE_PKG=./backend/cmd/product-query-svc BIN_DIR=bin BIN=$(BIN_DIR)/product-query-svc @@ -41,6 +41,9 @@ db-init: test-integration-docker: bash scripts/test-integration-docker.sh ./test -run Postgres +test-repo-docker: + go test -tags docker ./apps/product-query-svc/adapters/outbound/postgres -run TestCommentRepository_WithDocker -count=1 + # Notes: # - Requires golang-migrate installed to use migrate-* targets diff --git a/Tiltfile b/Tiltfile index e5d127e..8b14540 100644 --- a/Tiltfile +++ b/Tiltfile @@ -6,7 +6,7 @@ # Many Tilt installs don't provide that ext; omit the load to avoid startup errors. # Settings -namespace = 'marketplace-dev' +namespace = 'gopractice-dev' svc_name = 'product-query-svc' # Starlark (Tiltfile) 不支持 Python f-strings,使用字符串连接 docker_ref = svc_name + ':dev' diff --git a/api/generate.go b/api/generate.go index 7cd3ceb..53b8cb2 100644 --- a/api/generate.go +++ b/api/generate.go @@ -1,2 +1,2 @@ //go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest -config ./oapi-config.yaml ./openapi.yaml -package marketplaceapi +package gopracticeapi diff --git a/api/oapi-config.yaml b/api/oapi-config.yaml index 2f593e7..1238b3e 100644 --- a/api/oapi-config.yaml +++ b/api/oapi-config.yaml @@ -4,4 +4,4 @@ generate: - chi-server # 生成 chi server 接口 - strict-server # 生成严格 server 接口(带类型安全) - spec # 生成 embedded swagger spec -output: ../apps/product-query-svc/adapters/inbound/http/marketplaceapi.gen.go +output: ../apps/product-query-svc/adapters/inbound/http/gopracticeapi.gen.go diff --git a/api/openapi.yaml b/api/openapi.yaml index 7454e97..0055f73 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -1,6 +1,6 @@ openapi: 3.0.0 info: - title: Marketplace Demo API + title: gopractice Demo API version: 1.0.0 tags: - name: Products diff --git a/apps/product-query-svc/README.md b/apps/product-query-svc/README.md index 33c03b2..68748c4 100644 --- a/apps/product-query-svc/README.md +++ b/apps/product-query-svc/README.md @@ -41,7 +41,7 @@ Domain apps/product-query-svc/domain/product.go (实体/校验) Composition Root(组装根) - backend/cmd/marketplace/product-query-svc/main.go + backend/cmd/gopractice/product-query-svc/main.go - 读取配置,选择 inmem 或 postgres 作为 ProductRepository 的实现 - 构造 productapp.Service,并作为 ports/inbound.ProductUseCases 注入 HTTP 适配器 - 启动 HTTP 服务器 diff --git a/backend/cmd/marketplace/product-query-svc/main.go b/backend/cmd/product-query-svc/main.go similarity index 100% rename from backend/cmd/marketplace/product-query-svc/main.go rename to backend/cmd/product-query-svc/main.go diff --git a/charts/product-query-svc/values.yaml b/charts/product-query-svc/values.yaml index 35a56a3..33dcbf1 100644 --- a/charts/product-query-svc/values.yaml +++ b/charts/product-query-svc/values.yaml @@ -18,7 +18,7 @@ resources: env: HTTP_ADDRESS: ":8080" # App listen address; DATABASE_URL now comes from .Values.database.secret when enabled - DATABASE_URL: "postgres://app:app_password@postgres.marketplace-dev.svc.cluster.local:5432/productdb?sslmode=disable" # fallback only + DATABASE_URL: "postgres://app:app_password@postgres.gopractice-dev.svc.cluster.local:5432/productdb?sslmode=disable" # fallback only podAnnotations: {} replicaCount: 1 @@ -37,4 +37,4 @@ database: key: DATABASE_URL create: false # If create=true, a Secret will be created with this URL as stringData.DATABASE_URL - url: "postgres://app:app_password@postgres.marketplace-dev.svc.cluster.local:5432/productdb?sslmode=disable" + url: "postgres://app:app_password@postgres.gopractice-dev.svc.cluster.local:5432/productdb?sslmode=disable" diff --git a/k8s/config-app.yaml b/k8s/config-app.yaml index 6a30e34..41d7cb7 100644 --- a/k8s/config-app.yaml +++ b/k8s/config-app.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: Secret metadata: name: pg-secret - namespace: marketplace-dev + namespace: gopractice-dev stringData: POSTGRES_DB: productdb POSTGRES_USER: app @@ -12,9 +12,9 @@ apiVersion: v1 kind: ConfigMap metadata: name: app-config - namespace: marketplace-dev + namespace: gopractice-dev data: LOG_LEVEL: debug HTTP_ADDRESS: ":8080" - DATABASE_URL: "postgres://app:app_password@postgres.marketplace-dev.svc.cluster.local:5432/productdb?sslmode=disable" + DATABASE_URL: "postgres://app:app_password@postgres.gopractice-dev.svc.cluster.local:5432/productdb?sslmode=disable" diff --git a/k8s/namespace.yaml b/k8s/namespace.yaml index a465f94..6145af0 100644 --- a/k8s/namespace.yaml +++ b/k8s/namespace.yaml @@ -1,5 +1,5 @@ apiVersion: v1 kind: Namespace metadata: - name: marketplace-dev + name: gopractice-dev diff --git a/k8s/postgres.yaml b/k8s/postgres.yaml index 511d3b5..cf71ff3 100644 --- a/k8s/postgres.yaml +++ b/k8s/postgres.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: Service metadata: name: postgres - namespace: marketplace-dev + namespace: gopractice-dev spec: ports: - port: 5432 @@ -14,7 +14,7 @@ apiVersion: apps/v1 kind: StatefulSet metadata: name: postgres - namespace: marketplace-dev + namespace: gopractice-dev spec: selector: matchLabels: diff --git a/k8s/product-query-svc.yaml b/k8s/product-query-svc.yaml index 662d2af..6795cd5 100644 --- a/k8s/product-query-svc.yaml +++ b/k8s/product-query-svc.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: Service metadata: name: product-query-svc - namespace: marketplace-dev + namespace: gopractice-dev spec: selector: app: product-query-svc @@ -16,7 +16,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: product-query-svc - namespace: marketplace-dev + namespace: gopractice-dev spec: replicas: 1 selector: diff --git a/readme.md b/readme.md index b31d927..b1710ed 100644 --- a/readme.md +++ b/readme.md @@ -33,7 +33,7 @@ │ ├── inmem/ # 内存仓储实现(开发/测试) │ └── postgres/ # Postgres 仓储与迁移文件 ├── backend/ -│ └── cmd/marketplace/product-query-svc/ # 可执行入口(main.go),装配路由/依赖 +│ └── cmd/product-query-svc/ # 可执行入口(main.go),装配路由/依赖 ├── charts/product-query-svc/ # 最小 Helm Chart(含迁移 Job 与 ConfigMap) ├── k8s/ # 直接应用的 Kubernetes 清单(Service/Deployment/Postgres) ├── kind/ # kind 本地集群配置 @@ -55,7 +55,7 @@ ## HTTP 适配器设计(Strict Server) -- **代码生成统一使用 `oapi-codegen strict-server`**:`api/oapi-config.yaml` 只保留严格服务输出,避免手写 handler 接口。每次变更 OpenAPI 需执行 `go generate ./api` 重新生成 `marketplaceapi.gen.go`。 +- **代码生成统一使用 `oapi-codegen strict-server`**:`api/oapi-config.yaml` 只保留严格服务输出,避免手写 handler 接口。每次变更 OpenAPI 需执行 `go generate ./api` 重新生成 `gopracticeapi.gen.go`。 - **请求校验前移到 OpenAPI**:所有参数/请求体验证(`minimum`/`maxLength`/`enum` 等)写在 `api` 目录的 schema/parameter 中,由 `github.com/oapi-codegen/nethttp-middleware` 提供的 `OapiRequestValidator` 中间件统一拦截。 - **Handler 职责“三件套”**(`apps/product-query-svc/adapters/inbound/http/handler_*.go`): 1. 从生成的强类型 `RequestObject` 中取出入参(无需重复校验); @@ -180,7 +180,7 @@ bash scripts/test-integration-docker.sh ./test -run Postgres - 使用 `docker run -P` 启动 postgres:16-alpine,随机映射宿主端口,避免与 Tilt 的 5432 冲突。 - 通过 `migrate/migrate` 容器在同一网络命名空间内执行迁移。 - 自动导出 `DATABASE_URL` 为宿主上的随机端口,并运行 go test。 -- 需要单独验证仓储层(含评论 CRUD)的 Docker 集成测试时,可运行 `go test -tags docker ./apps/product-query-svc/adapters/outbound/postgres -run TestCommentRepository_WithDocker -count=1`,确保本机 Docker 可用;若暂不具备条件,可设置 `SKIP_DOCKER_TESTS=1` 跳过。 +- 需要单独验证仓储层(含评论 CRUD)的 Docker 集成测试时,可运行 `make test-repo-docker`(依赖本机 Docker);若暂不具备条件,可设置 `SKIP_DOCKER_TESTS=1 make test-repo-docker` 跳过实际容器启动。 @@ -209,9 +209,9 @@ curl -s http://localhost:8080/products/1 | jq - Pod/日志排查 ```sh -kubectl -n marketplace-dev get pods -kubectl -n marketplace-dev logs deploy/product-query-svc -kubectl -n marketplace-dev logs statefulset/postgres +kubectl -n -dev get pods +kubectl -n -dev logs deploy/product-query-svc +kubectl -n -dev logs statefulset/postgres ``` --- @@ -227,7 +227,7 @@ kubectl -n marketplace-dev logs statefulset/postgres 1. 启动 Postgres(示例): ```sh -docker run --name marketplace-postgres \ +docker run --name -postgres \ -e POSTGRES_USER=app \ -e POSTGRES_PASSWORD=app_password \ -e POSTGRES_DB=productdb \ @@ -245,14 +245,14 @@ export LOG_LEVEL=debug 1. 运行服务(开发): ```sh -cd backend/cmd/marketplace/product-query-svc +cd backend/cmd/product-query-svc go run . ``` 或构建后运行: ```sh -go build -o bin/product-query-svc ./backend/cmd/marketplace/product-query-svc +go build -o bin/product-query-svc ./backend/cmd/product-query-svc ./bin/product-query-svc ``` @@ -313,7 +313,7 @@ psql "postgres://app:app_password@localhost:5432/productdb" - 如需修改连接串,可在 Tiltfile 顶部调整 `MIGRATE_URL`。 - 在 K8s/Helm 中执行(集群内) - - 可选:用 Helm hook 或 Job 在集群内运行 `migrate/migrate`,`DATABASE_URL` 使用集群内 Service(例如 `postgres.marketplace-dev.svc.cluster.local`)。需要的话可以补充该 Job。 + - 可选:用 Helm hook 或 Job 在集群内运行 `migrate/migrate`,`DATABASE_URL` 使用集群内 Service(例如 `postgres.-dev.svc.cluster.local`)。需要的话可以补充该 Job。 常见避坑: @@ -362,7 +362,7 @@ Helm 迁移 Job: docker build -t product-query-svc:dev . ``` -注:Dockerfile 默认构建 backend/cmd/marketplace/product-query-svc 的二进制,用于镜像/部署。 +注:Dockerfile 默认构建 backend/cmd/product-query-svc 的二进制,用于镜像/部署。 --- @@ -380,7 +380,7 @@ go generate ./api # 或者根据 generate.go 的 //go:generate 指定路径 ``` -- 生成后的 `adapters/inbound/http/marketplaceapi.gen.go` **禁止手动修改**;需要调整校验或字段时改 OpenAPI 资源并重新生成。 +- 生成后的 `adapters/inbound/http/api.gen.go` **禁止手动修改**;需要调整校验或字段时改 OpenAPI 资源并重新生成。 - HTTP handler 只能依赖生成的 `StrictServerInterface`,其实现位于 `handler_*.go`,必须配合 `response_helpers.go` 和 `request_mappers.go` 使用。 - `NewAPIHandler` 会自动加载最新的 Swagger 并注册 `OapiRequestValidator` 中间件,生产/测试入口都应通过该函数获取路由。 @@ -431,7 +431,7 @@ go generate ./api
批次 5 — 后端入口 / wiring / router - - 相关文件:backend/cmd/marketplace/product-query-svc、apps/product-query-svc/adapters/inbound/http/ + - 相关文件:backend/cmd/product-query-svc、apps/product-query-svc/adapters/inbound/http/ - 建议 commit message:"chore: add service main and HTTP wiring (router & handlers)"
@@ -460,6 +460,6 @@ go generate ./api - "FATAL: database \"app\" does not exist":确认 Postgres 启动时环境变量 POSTGRES_DB 与服务的 DATABASE_URL 中数据库名一致(示例使用 productdb);或手动创建数据库。 - Docker 构建报 "go.mod: unknown directive: tool":请使用与 go.mod 中 toolchain 对齐的 Go 版本(本项目使用 1.24)。 -- Lens 中看不到资源:确认 Lens 使用的 kubeconfig 与 kubectl 当前上下文一致,并且查看正确命名空间(marketplace-dev)。 +- Lens 中看不到资源:确认 Lens 使用的 kubeconfig 与 kubectl 当前上下文一致,并且查看正确命名空间(-dev)。