--- sidebar_position: 1 --- # 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](https://go.dev/ref/mod#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:** | Package | Purpose | |---|---| | `net/http` | HTTP server / client | | `encoding/json` | JSON serialization | | `database/sql` + `modernc.org/sqlite` | SQLite (dev) | | `github.com/lib/pq` | PostgreSQL / TimescaleDB (prod) | | `github.com/rs/zerolog` | Structured logging | | `github.com/spf13/viper` | Config management | | `github.com/robfig/cron/v3` | Scheduled jobs | | `golang.org/x/sync` | Concurrency 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 ```go // 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) ```makefile 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//` 2. Initialize Go module: `go mod init gitea.lego-cloud.eu/skic-v1-playground/` 3. Add to `go.work`: `use ./` 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//` following C4 structure 7. Add to homepage application table