Conventions
Concurrency
Section titled “Concurrency”- Service methods — take
context.Contextas first arg; cancel on context expiry. - CLI commands — synchronous cobra
RunEbodies; long-running work goroutined inside viaerrgroup. - API handlers — synchronous
http.HandlerFuncbodies; long-running work uses the operation registry + SSE. - Database operations —
*sql.DBis goroutine-safe; queries thread the request context so cancellation propagates.
// Servicetype Service struct{ /* … */ }
func (s *Service) CreateBackup(ctx context.Context, stack string) (*BackupModel, error) { // …}
// CLI handlerfunc newBackupCommand() *cobra.Command { return &cobra.Command{ Use: "backup <stack>", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { return runBackup(cmdCtx(cmd), args[0]) }, }}Type naming
Section titled “Type naming”- Request types —
*Requestor*Create/*Updatesuffix - Response types —
*Responsesuffix - Internal model types —
*Modelsuffix - Wire envelopes — capitalised generic alias on
api.MethodResponse[T]/api.DocResponse[T]
type BackupCreate struct { StackName string `json:"stack_name"` IncludeVault bool `json:"include_vault,omitempty"`}
type BackupResponse struct { ID string `json:"id"` CreatedAt time.Time `json:"created_at"` SizeBytes int64 `json:"size_bytes"`}DB models
Section titled “DB models”- Table names — singular, lowercase (
deployment,backup) - Go model names —
*Modelsuffix - Always include —
created_at,updated_atcolumns (Atlas generates both)
type DeploymentModel struct { ID int `json:"id"` Name string `json:"name"` TenantName string `json:"tenant_name"` // ... CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"`}API routes
Section titled “API routes”- Method-style endpoints —
POST /api/method/shc.{module}.{operation} - Resource-style endpoints —
GET|POST|PUT|DELETE /api/resource/{Resource}[/{id}]
| Method | Pattern | Example |
|---|---|---|
| List | shc.{module}.list | shc.backup.list |
| Get | shc.{module}.get | shc.backup.get |
| Create | shc.{module}.create | shc.backup.create |
| Delete | shc.{module}.delete | shc.backup.delete |
Configuration
Section titled “Configuration”- YAML files — Use
snake_casefor all keys - Environment vars — Use
SHC_prefix,SCREAMING_CASE - CLI flags — Use
--kebab-case
# config.yaml (snake_case)log_level: debugmax_backup_size: 10G# CLI (kebab-case)shc backup create --include-vault --max-size 10GImports
Section titled “Imports”gofmt enforces three groups separated by blank lines: stdlib, third-party, internal.
package backup
import ( "context" "fmt" "time"
"github.com/go-chi/chi/v5"
"gitlab.com/bitspur/selfhosted-cloud/ce/core/coded" "gitlab.com/bitspur/selfhosted-cloud/ce/core/validation")shc@docs:~$