architecture · git:20260324.7a91f3b · 2026-03-24 · sha256 eee522c2d571ecc2
architecture git:20260324.7a91f3bA
Immutable. This exact content is served forever at /api/v1/blob/eee522c2d571ecc2.
---
description: Architecture and coding conventions for AI Lamp OpenClaw
alwaysApply: true
---
# Architecture Rules
## Package Structure
- **Handlers** go in `server/<domain>/delivery/http/handler.go`
- **Services** go in `internal/<domain>/service.go`
- **Domain types** go in `domain/<type>.go`
- **Wire providers** go in `server/wire.go` and `bootstrap/wire.go`
- **Shared libraries** go in `lib/`
## Dependency Injection
- Use **Google Wire** for compile-time DI — no runtime reflection
- After changing any provider signature: run `make generate`
- Never manually edit `wire_gen.go` files
## API Conventions
- All responses use `serializers.ResponseSuccess(data)` or `serializers.ResponseError(err)`
- Response format: `{"status": 1|0, "data": <payload>|null, "message": null|"error"}`
- Validate requests with `go-playground/validator` at handler level
- Return early on validation failure with `http.StatusBadRequest`
## Error Handling
- Always wrap errors with context: `fmt.Errorf("operation: %w", err)`
- Log with component prefix: `log.Println("[led] starting engine")`
- Never swallow errors silently
## Goroutines & Concurrency
- Always pass `context.Context` for cancellation
- Background goroutines must select on `ctx.Done()`
- Use `sync.Mutex` for shared state, not channels (unless fan-out pattern)
## Configuration
- Config in `config/config.json` managed by `server/config/config.go`
- Use notification channel for propagating config changes to services
- Never hardcode secrets — load from config file
## Build
- Cross-compile target: `GOOS=linux GOARCH=arm64`
- Version injected via ldflags — never commit binaries
- Lint with `golangci-lint run` before committing