Coding style
Formatting
Section titled “Formatting”- gofmt for all Go formatting — the canonical tool, no per-project width override (gofmt has no width setting on purpose).
- No manual formatting — let gofmt handle it.
- Run
make formatbefore committing;make lintrejects diffs.
Naming conventions
Section titled “Naming conventions”Go’s own conventions are the floor. SHC project additions:
| Type | Convention | Example |
|---|---|---|
| Packages | lowercase, no _ | backup, internalrpc |
| Exported types | PascalCase | BackupService, StackModel |
| Exported functions | PascalCase | NewService, CreateBackup |
| Unexported types/funcs | camelCase | stackRow, parseMoveEntry |
| Variables | camelCase | backupPath |
| Constants | PascalCase / camelCase per visibility | DefaultTimeout, defaultTickInterval |
| Coded error factories | X######CCCCCC | X404908STKNFD |
| Coded errors specs | same code, X######CCCCCC | {Code: "X404908STKNFD", ...} |
| Type parameters | single capital | T, K, V |
Coded error factories use the verbatim X######CCCCCC form
(6 digits + 6+ uppercase letters). No ErrXxx aliases, no dual
naming. Validate at module-init() time via
coded.Register, which panics on bad shape.
Code organization
Section titled “Code organization”Module structure
Section titled “Module structure”Every feature module under modules/{module}/ (ce module; ee-only modules under modules/) follows the
same skeleton:
modules/{module}/├── service.go # business logic — *Service struct + methods├── router.go # HTTP routes (chi)├── types.go # request/response shapes (Go structs + validate tags)├── errors.go # X######CCCCCC factories + spec slice + init()├── events.go # event handler registrations (if applicable)├── register.go # init() side-effects (router builder, command builder, runtime singleton)└── commands/ # cobra subcommand surface (if module exposes CLI verbs)File structure
Section titled “File structure”// 1. Package + comment// Package backup implements the snapshot orchestrator.package backup
// 2. Imports (stdlib first, then third-party, then internal — each// group separated by a blank line; gofmt enforces this)import ( "context" "fmt"
"github.com/go-chi/chi/v5"
"gitlab.com/bitspur/selfhosted-cloud/ce/core/coded")
// 3. Constants (typed when not implicit)const ( DefaultBackupTimeout = 30 * time.Minute backupModeIncremental = "incremental")
// 4. Typestype Service struct{ /* ... */ }
// 5. Constructorsfunc NewService(opts ServiceOptions) *Service { /* ... */ }
// 6. Methods (group by receiver, public before private)func (s *Service) CreateBackup(ctx context.Context, req BackupCreate) (*BackupModel, error) { /* ... */ }User-visible text (errors, logs, CLI, API descriptions)
Section titled “User-visible text (errors, logs, CLI, API descriptions)”Use the same rules as error message formatting for any string a human reads in normal operation:
- Lowercase start — imperative or factual phrase, not Title Case or sentence case with a leading capital (except proper nouns, acronyms, and literal codes like
X404908STKNFD). - One line where practical.
- No colons — prefer a comma to separate clauses (same as errors).
- Applies to:
coded.Newtemplate strings, eventMessage,corelog/loggerDebug/Infomessage arguments (WARN+ carries a*coded.CodedError, so its text lives in the factory template), cobraShort:/Long:help, and validator-derived OpenAPI descriptions.
Code identifiers and structured keys are unchanged; this rule is for natural-language fragments.
Best practices
Section titled “Best practices”- Small functions — single responsibility, easy to test.
- Errors are values — return
*coded.CodedErrorfrom internal surfaces;errors.Newandfmt.Errorfare forbidden byforbidigo. Wrap external errors withcoded.FromExternal(err). - No dead code —
golangci-lintrunsunusedand will refuse the build. Delete unused imports, functions, comments. - DRY — extract common logic into reusable functions, but only after two concrete call sites demand it (§2.7 of the engineering standards).
- No backward-compatibility code unless explicitly required.
See Also
Section titled “See Also”shc@docs:~$