# AGENTS.md — backend ## Module & Layout Go module: `github.com/XingfenD/yoresee_doc` (rooted at `backend/`). ``` cmd/main.go — API server entry (Connect RPC) cmd/migrate/ — GORM AutoMigrate (runs first on startup) cmd/db_init/ — seed data (admin user, default groups, templates…) cmd/es_init/ — Elasticsearch index setup cmd/notification-worker/ — RabbitMQ consumer cmd/search-sync-worker/ — RabbitMQ consumer cmd/snapshot-worker/ — RabbitMQ consumer (Yjs snapshot persistence) internal/ bootstrap/ — chain-style Initializer (config → infra → repos → services) config/ — Viper TOML loader; GlobalConfig singleton transport/connectserver/ — HTTP mux, Connect RPC handler wiring, auth interceptor, CORS transport/grpcserver/ — per-service RPC implementations (calls into service layer) service/_service/ — business logic; package-level singletons (*Svc) service/interface/ — service interfaces + MQ consumer contract service/mq_service/ — MQ abstraction init (RabbitMQ) repository/_repo/ — GORM queries; constructed via repository.NewRepositories() model/ — GORM model definitions (16 models) dto/ mapper/ types/ — transfer objects, mapping helpers, domain types status/ — typed error codes (status.GenErrWithCustomMsg) pkg/ storage/ — infra clients: DB, KVS (Redis), MinioClient, ES, Consul (package-level globals) mq/ — MQ interface + RabbitMQ impl cache/ lock/ key/ — shared cache keys, distributed lock, cache helpers errs/ constant/ — shared errors and constants gen/ — GENERATED protobuf Go stubs (gitignored) ``` ## Build & Run ```bash # Full dev stack (from repo root): bash deploy/script/start.sh dev up # Run backend only (after infra is up): go run ./cmd/main.go # Run individual workers: go run ./cmd/snapshot-worker go run ./cmd/notification-worker go run ./cmd/search-sync-worker # Migrate + seed (runs automatically in container): go run ./cmd/migrate && go run ./cmd/db_init && go run ./cmd/es_init ``` No Makefile, no tests, no linter config. Verify with `go build ./...` and `go vet ./...`. ## Config - File: `config.toml` (gitignored) — generated from `config.toml.tmpl` by `deploy/script/prepare.sh` - Format: TOML, loaded by Viper with `${ENV_VAR}` substitution - Env vars defined in `deploy/.env` (template: `deploy/.env.example`) - Access via `config.GlobalConfig.*` ## Startup Order Container CMD: `migrate → db_init → es_init → main` Workers are separate binaries with their own bootstrap chains. ## Key Patterns - **Connect RPC** (not raw gRPC server): handlers in `connectserver/handlers.go` wrap `grpcserver/*` implementations - **Two HTTP listeners**: gRPC on `grpc_port` (9090), gRPC-web on `grpc_web_port` (8080); both use h2c - **Auth interceptor**: JWT-based; allowlist for Login, Register, Health, SystemInfo - **Service singletons**: `auth_service.AuthSvc`, `document_service.DocumentSvc`, etc. — set in `service.Init()` - **Global infra**: `storage.DB`, `storage.KVS`, `storage.MinioClient`, `storage.ES`, `storage.Consul` - **Migration**: GORM `AutoMigrate` (schema from model structs) + raw SQL for Postgres extensions (`ltree`) and indexes - **DB seeding**: `cmd/db_init/` creates admin user, default permissions, templates, user groups - **Elasticsearch**: optional — `InitElasticsearchAllowFail` degrades gracefully - **Consul**: required — `RequireConsulEnabled` fatals if disabled - **MQ**: RabbitMQ via `pkg/mq`; workers consume topics registered through `mq_service` ## Protobuf Codegen Single proto: `proto/yoresee_doc/v1/yoresee_doc.proto` Generated Go code: `pkg/gen/` (gitignored) Regenerate: `bash deploy/script/gen_proto.sh` (from repo root) ## Health Endpoints - `/health` — liveness - `/readyz` — readiness (checks DB + Redis) - `/livez` — liveness alias