Imported from JFeng2048/museflow (
AGENTS.md). Install upstream withnpx skills add JFeng2048/museflow. Copyright stays with the author.
Repository Guidelines
Contributor guide for MuseFlow, an AI-powered novel generation platform. The backend is a Go microservices monorepo (gRPC + Gin), and the frontend is Vue 3 + TypeScript + Vite.
Project Structure & Module Organization
Monorepo with a Go Workspace (go.work) at the repo root. Each service and each shared package has its own go.mod (referenced via replace directives in go.work). No root go.mod.
pkg/— shared Go libraries, each an independent module:envloader/— service-local.envloading (system env > service.env> defaults). Service-prefixed keys viaGet, shared keys viaGetCommon(e.g.JWT_SECRET,REDIS_*,DB_*).errcode/— unified error codes (2000+) with bilingual (zh/en) messages driven byAccept-Language;SuccessGin/ErrorGinfor HTTP, gRPC status mapping in handlers.logger/—slog+lumberjacklogger withConfig(level/format/output/path/rotation),Init, context and field helpers (logger.Err,logger.UserUUID,logger.WithTraceID).
proto/user/— shared gRPC contract (user.proto+ generateduser.pb.go/user_grpc.pb.go), independent module.services/user-service/— gRPC user service (:5002):internal/config— loadsUSER_(service),DB_*/REDIS_*/JWT_SECRET(shared viaNew("DB",...)/New("REDIS",...)),LOG_*(viaGetCommon).internal/handler— gRPC handlers; convert proto ↔ service layer; mapauth.Err*to gRPC status codes.internal/service— business logic, split into subpackages:auth(AuthService),token(TokenManager/claims/fingerprint),dto(Device,TokenPair). No import cycle:auth→token+dto;token/dtodepend on nothing internal.internal/repository— GORM data access + Redis token store (TokenStore);model.Useruses fixed tableuser_svc.users.internal/model— GORM entityUser(password nullable for SSO users).
services/api-gateway/— HTTP gateway (:5001, Gin):internal/config(GATEWAY_+ shared),router,middleware(CORS/auth/access-log/request-id),handler(dto ↔ proto),client(user-service gRPC client),dto(HTTP request/response structs for Swagger).
services/user-service/database/user_svc.sql— PostgreSQL DDL; creates schemauser_svcand tableuser_svc.users(schema is fixed, not driven by config).web/— Vue 3 + TS + Vite frontend.docs/cn/develop/双令牌认证系统设计文档.md— dual-token auth design reference.- Each microservice owns its
.env(gitignored) and.env.example(committed); there is no repository-root.envconfiguration layer.
Build, Test, and Development Commands
Go uses a workspace; there is no root go.mod. From the repo root (Windows; make is not available, use go directly or Go module dirs):
go work sync— (re)resolve the workspace modules. Run after adding modules.- Build a service:
cd services/user-service && go build ./cmd/server(orapi-gateway). Use rootMakefilemake buildon non-Windows. - Run a service:
cd services/user-service && go run ./cmd/server(starts gRPC on:5002). Gateway:cd services/api-gateway && go run ./cmd/server. - Vet all:
go vet ./...(run from a module dir so the workspace resolves, e.g.cd services/user-service). - Test all:
go test ./...inside a service dir. Single test:go test ./internal/service/auth/ -run TestLoginIssuesUsableTokenPair -v. - Regenerate gRPC:
bash scripts/gen-proto.sh(needsprotoc29.3 +protoc-gen-go+protoc-gen-go-grpc). - Swagger (gateway):
cd services/api-gateway && swag init -g cmd/server/main.go -o docs. - Frontend (
web/):pnpm install,pnpm dev,pnpm build(vue-tsc + vite),pnpm preview. Runpnpm buildbefore commit.
Hot reload: install air (go install github.com/air-verse/air@latest). Root entry points start every service at once — dev.bat (Windows, one window per service) or ./dev.sh (Linux/macOS, tmux when available): dev.bat, dev.bat gateway|user|worker|web|full|help. Granular usage: cd services/user-service && air (or gateway); the worker uses its own config, cd services/user-service && air -c .air.worker.toml.
Air config rules (v1.67+), all three .air.toml already follow them — violating any one produces misleading failures:
build.cmdmust build only (go build -o ./tmp/x ./cmd/...), nevergo run.go runcompiles and runs, so a service exiting non-zero (DB/Redis not up) is misreported asfailed to build, and air then tries to run a binary that was never produced.- Use
build.entrypoint(["./tmp/x"]);build.binis deprecated and warns. - Set
stop_on_error = true, otherwise a failed build silently runs a stale binary. - On Windows the binary must end in
.exe; declare it via the[build.windows]platform override so Linux/macOS keep extensionless binaries. rerun = true+rerun_delay = 3000so a service that fails fast on a not-yet-ready DB/Redis recovers on its own afterdev.batstarts everything at once.
Line endings: *.bat files must stay CRLF — cmd.exe truncates lines and garbles output on LF. *.sh must stay LF. Check after generating scripts with editors/AI tools that default to LF.
Coding Style & Naming Conventions
Go: standard gofmt/go vet; exported PascalCase, files snake_case.go. Errors: business errors defined as errors.New in the auth package and mapped to gRPC status in handlers; never return raw errors across the gRPC boundary. Config reads go through envloader (no direct os.Getenv). Logging through pkg/logger, prefer logger.WithTraceID/logger.Err field helpers over string formatting.
Frontend: Vue 3 <script setup> SFCs, strict TS (@vue/tsconfig), 2-space indent.
Encoded Conventions (团队编码习惯)
These conventions are mandatory for contributions to this repo:
- 提交信息中英双语:Commit 主题行(subject)采用 Conventional Commits 规范(
type(scope): 中文主题 / English subject),类型如feat/fix/refactor/docs/chore/build/test;正文(body)可选,用中文说明「为什么改」。示例:
复杂改动按功能原子分拆为多个提交,而非一次性大提交。feat(user-service): 拆分 auth/token/dto 子包 / split auth/token/dto subpackages - 配置分层与环境变量:所有配置统一走
envloader,禁止直接使用os.Getenv。共享键无前缀(JWT_SECRET、REDIS_*、DB_*),通过envloader.New("REDIS",...)+GetCommon读取;服务专属键使用前缀(USER_、GATEWAY_、LOG_),通过Get读取。分层优先级:系统环境变量 > 服务自身.env> 默认值。 - 注释与文案用中文:代码注释、文档(如
*.md)、日志文案以中文为主;变量名/函数名等标识符仍用英文,保持gofmt/go vet规范。 - 无循环依赖分层:
service内部按auth/token/dto子包拆分,依赖单向、禁止循环:auth→token+dto;token/dto不反向依赖auth或任何内部包。跨层调用同样保持单向(handler → service → repository)。
Testing Guidelines
Backend: *_test.go with the standard testing package, placed beside the code in its package (e.g. internal/service/auth/auth_service_test.go uses in-memory repository.UserRepository/TokenStore fakes). auth package has the primary coverage; keep tests isolated via fakes. Frontend: Vitest *.spec.ts beside source. Always run go test ./... and go vet ./... for the changed module before committing.
Commit & Pull Request Guidelines
Commit messages follow Conventional Commits with bilingual subject lines (see 编码习惯 above): type(scope): 中文主题 / English subject. Subject lines stay concise (ideally under 50 chars per language); add a Chinese "why" body when the change is non-obvious. Split large changes into focused atomic commits per feature/module.
PRs should link the related issue, describe the change and motivation, and include screenshots for UI changes. The README references a CONTRIBUTING.md that does not yet exist; until then, follow these guidelines and keep PRs focused.
Security & Configuration Tips
Never commit secrets. Each service owns a gitignored .env and a committed .env.example; supply production configuration through environment variables or Kubernetes secrets. Shared secrets use unprefixed keys: JWT_SECRET (gateway + user-service sign/verify), REDIS_* (token whitelist/blacklist), DB_* (PostgreSQL). Per-service config uses prefixes USER_, GATEWAY_, LOG_. Build artifacts (dist/, bin/, *.test, coverage.*) are excluded from version control. go.work is gitignored by default — keep go.work.use listing all modules.