Skip to main content

Engineering Guidelines

This document defines how applications in SKIC Playground are structured, built, and maintained.

Monorepo Structureโ€‹

All applications live in a monorepo at skic-v1-playground in Gitea. Each application is a top-level directory with its own build system.

skic-v1-playground/
โ”‚
โ”œโ”€โ”€ documentation/ # This Docusaurus site
โ”‚
โ”œโ”€โ”€ stock-market-pro/ # Go application
โ”‚ โ”œโ”€โ”€ cmd/
โ”‚ โ”‚ โ””โ”€โ”€ server/
โ”‚ โ”‚ โ””โ”€โ”€ main.go # Entrypoint
โ”‚ โ”œโ”€โ”€ internal/
โ”‚ โ”‚ โ”œโ”€โ”€ ingestor/ # Data ingestion
โ”‚ โ”‚ โ”œโ”€โ”€ analysis/ # Technical analysis engine
โ”‚ โ”‚ โ”œโ”€โ”€ signals/ # Signal generation
โ”‚ โ”‚ โ””โ”€โ”€ notifier/ # Discord delivery
โ”‚ โ”œโ”€โ”€ pkg/ # Shared public packages
โ”‚ โ”œโ”€โ”€ Dockerfile
โ”‚ โ”œโ”€โ”€ Makefile
โ”‚ โ””โ”€โ”€ go.mod
โ”‚
โ”œโ”€โ”€ shared/ # Cross-app shared libraries (Go modules)
โ”‚ โ”œโ”€โ”€ discord/ # Discord client
โ”‚ โ”œโ”€โ”€ config/ # Config loader
โ”‚ โ””โ”€โ”€ telemetry/ # Logging, metrics, tracing
โ”‚
โ”œโ”€โ”€ infra/ # Infrastructure-as-code
โ”‚ โ”œโ”€โ”€ docker-compose.yml # Local dev stack
โ”‚ โ””โ”€โ”€ gitea-runners/ # CI runner config
โ”‚
โ””โ”€โ”€ Makefile # Root-level make targets (build all, test all)

Go Workspace (go.work)โ€‹

The monorepo uses Go workspaces so all Go modules can reference each other without publishing:

# go.work
go 1.22

use (
./stock-market-pro
./shared/discord
./shared/config
./shared/telemetry
)

This means local changes to shared/ are immediately reflected across all Go apps without replace directives in individual go.mod files.

Tech Stackโ€‹

Applications โ€” Goโ€‹

Go is the primary language for all backend services and autonomous applications.

Why Go:

  • Statically typed, compiled, single binary deployment
  • Excellent concurrency primitives (goroutines, channels) โ€” ideal for market data streams
  • Native cross-compilation
  • Fast build times, clean toolchain
  • Standard library covers most needs (HTTP, JSON, time, crypto)

Standard libraries:

PackagePurpose
net/httpHTTP server / client
encoding/jsonJSON serialization
database/sql + modernc.org/sqliteSQLite (dev)
github.com/lib/pqPostgreSQL / TimescaleDB (prod)
github.com/rs/zerologStructured logging
github.com/spf13/viperConfig management
github.com/robfig/cron/v3Scheduled jobs
golang.org/x/syncConcurrency utilities

Data / Analysis โ€” Pythonโ€‹

Python is used for data science and ML-heavy workloads where the Go ecosystem is thin:

  • pandas, numpy โ€” data manipulation
  • pandas-ta, ta-lib โ€” technical indicators
  • scikit-learn โ€” pattern recognition / ML
  • statsmodels โ€” GARCH, time series

When Python is used, it runs as a sidecar service alongside the Go application, exposing a local HTTP/gRPC API.

Frontend / Docs โ€” TypeScript + Reactโ€‹

  • Docusaurus v3 for documentation
  • React + shadcn/ui + Tailwind for interactive components within docs

Code Conventionsโ€‹

Goโ€‹

  • gofmt โ€” enforced in CI
  • Error handling โ€” always wrap with fmt.Errorf("context: %w", err), never ignore
  • Packages โ€” flat, purposeful. No circular dependencies. internal/ for app-private code
  • Config โ€” environment variables via Viper, validated at startup
  • Logging โ€” structured JSON via zerolog, no fmt.Println in production code
  • Tests โ€” table-driven tests in _test.go files, testify/assert for assertions
// Good โ€” explicit error context
if err := db.Query(ctx, q); err != nil {
return fmt.Errorf("ingestor: fetch candles: %w", err)
}

// Bad โ€” swallowed error
db.Query(ctx, q)

Gitโ€‹

  • Branch naming: feat/description, fix/description, docs/description
  • Commit messages: conventional commits โ€” feat:, fix:, docs:, chore:, refactor:
  • PRs: all changes via PR, even from Jarvis โ€” CI must pass before merge
  • Main is always deployable

Makefile Targets (per app)โ€‹

build: ## Build binary
go build -o bin/server ./cmd/server

test: ## Run tests
go test ./... -race -cover

lint: ## Run linter
golangci-lint run

docker: ## Build Docker image
docker build -t $(APP_NAME):$(VERSION) .

run: ## Run locally with .env
source .env && go run ./cmd/server

Adding a New Applicationโ€‹

  1. Create directory skic-v1-playground/<app-name>/
  2. Initialize Go module: go mod init gitea.lego-cloud.eu/skic-v1-playground/<app-name>
  3. Add to go.work: use ./<app-name>
  4. Create .gitea/workflows/build.yml from the CI template
  5. Create Dockerfile (multi-stage: golang:1.22-alpine โ†’ alpine:3.19)
  6. Add documentation under documentation/docs/products/<app-name>/ following C4 structure
  7. Add to homepage application table