Projects · Used at work · 2026
svcgen
A CLI that scaffolds a production-shaped Go service in one command and keeps extending it: fx wiring, Fiber router, optional Postgres, Redis and partner clients, Dockerfile, GitLab CI and Sonar config. Used at Icon Plus to start new integrator services.
Go · Fiber · fx · GitLab CI
SourceProblem
Every new integrator service at work started as a copy of the last one. Folder layout drifted, CI files diverged, and the first day of a new service went to boilerplate instead of the integration itself.
What I built
svcgen generates a service with the structure the team already runs in production, then adds to it over time: `svcgen new` for the project, `svcgen add external` for a partner client, `svcgen add feature` for a router + controller + usecase + DTO wired into fx.
Architecture
- cmd/svcgenCLI entrypoint with interactive prompts that can also be piped for CI
- internal/generator/templatestext/template files embedded in the binary; generated Go is gofmt-ed
- Generated servicefx modules for router, controller, usecase, repository; Fiber HTTP; config from YAML + env
- external/<partner>HTTP client with SUCCESS / PENDING / FAILED classification and timeout mapping
- /healthzliveness probe outside /api/v1 with version and uptime, for Kubernetes
Decisions and trade-offs
01
Generate the shape of production, not a toy
The templates mirror a service already running at work (Dockerfile, .gitlab-ci.yml, sonar-project.properties, request filter for signature headers), so a generated repo is deployable on day one instead of being a starting point to rewrite.
02
Leave no trace in the generated repo
The generated project has no svcgen markers. `svcgen add` inserts code by recognising stable anchors in the existing structure (`fx.Provide(`, `var serviceCodeByPath`), which keeps the output readable for people who never use the tool, at the cost of a few names that must not be renamed.
03
Opt-in dependencies at generation time
Postgres, Redis and partner clients are questions, not defaults. A service that does not need a database runs without one, and data sources can still be switched on later through env, so the generator never forces infrastructure a service does not use.
04
Classify partner responses explicitly
Every generated partner client maps responses to SUCCESS, PENDING or FAILED and turns timeouts into a typed error. Payment-style integrations are mostly about handling the ambiguous middle, so the client makes that state visible instead of hiding it in an HTTP status.
Evidence
- Template changes are verified by `go test ./...` plus generating a throwaway service and building it.
- Prompts accept piped answers (`printf 'y\nn\ny' | svcgen new my-svc`) so CI can generate services unattended.
- Used at Icon Plus for new integrator services; the README documents the private module path the generated code depends on.
Status · Actively used and extended