# Project layout

Find any Zever package fast: core interfaces, adapter modules, shared helpers, container, ORM, compiler, and CLI.

Zever is a Go multi-module monorepo (`go 1.27.0`). Your application imports `core` interfaces, the adapter modules you choose, and `container/`. It never imports `dsl/`.

## The four roles

```text
core/<b>          battery interface + Register/Open registry (container resolves)
adapters/<b>/<a>  one Go module per adapter; Register() wires it into its core registry
shared/*          SDK-free helpers (codec, redisclient, s3opts, retry, ...)
wiring            config/ container/    layered config + lazy resolver
language          dsl/                  .zen compiler frontend (compile time only)
surface           orm/ cmd/zever/       typed queries, CLI
```

- `go.work` at the repo root resolves every workspace module locally (176 `use` entries; `examples/external-sms` and `docs/examples` stay outside by design), so `go build/test ./...` from the root works. CI runs per-module commands with `GOWORK=off`.
- Releases are lockstep: one version, with per-module tags `<path>/vX.Y.Z` made by `tools/tag-release.sh`.
- `config/` owns decoding (`defaults < file < env`, strict snake_case keys, `RedactedServices`); `container/` owns construction, caching, retry, and close. Load errors belong to `config/`, resolution errors to `container/`.

## Package map

| Path | Role | Runtime? |
|---|---|---|
| `config/` | `Default()` zero-infra, strict `Load(path)`, best-effort env, `RedactedServices` | yes |
| `container/` | `New(cfg)` (nil valid), lazy accessors, retry on error, `Close(ctx)` in dependency order | yes |
| `core/<b>` | Battery interface plus `Register`/`Open` registry (for example `core/cache`, `core/db`) | yes (interfaces) |
| `adapters/<b>/<a>` | One module per adapter (for example `adapters/cache/redis`) | yes (picked ones) |
| `shared/*` | SDK-free helpers (`codec`, `redisclient`, `redisopt`, `s3opts`, `retry`, ...) | yes |
| `orm/` | `NewTable` / `NewColumn` / `From`, dialect per call, fail-closed errors | yes |
| `core/router` | `fiber` / `stdhttp` adapters over `http.HandlerFunc` | yes (interface) |
| `core/middleware` | HTTP middleware and gRPC interceptors, no registry | yes |
| `dsl/` | `lexer -> parser -> ast -> resolver -> ir.Schema`, `compile -> backend.Generate` | no (compile time) |
| `cmd/zever/` | Flags-only CLI, `dev` watch, dev-only `tinker` | no (tool binary) |
| `tools/` | Dev tooling modules (`gengrammar`, `modgraph`, `errscan`, `affected`, `zever-lsp`, `zever-mcp`) plus scripts such as the `tag-release.sh` lockstep tagger | no |
| `docs/` | Starlight site (npm, not Go) | no |
| `examples/` | Runnable skeletons with schema, server, worker, seed | reference |

Batteries under `core/`: agent, ai, analytics, auth, authz, billing, cache, crypto, db, document, eval, eventbus, flag, geo, i18n, idempotency, job, lock, log, mailer, media, notification, observability, outbox, password, payment, permission, queue, rag, ratelimit, resilience, scheduler, search, secrets, session, storage, tenant, vectorstore, webhook, workflow. `core/middleware` and `core/router` are HTTP plumbing.

## Resolve a service from the container

`container/` is the only resolver. Application code never constructs adapters directly:

```go title="main.go" check
package main

import (
	"fmt"

	"github.com/zenta-dev/zever/adapters/db/sqlite"
	"github.com/zenta-dev/zever/config"
	"github.com/zenta-dev/zever/container"
)

func main() {
	sqlite.Register()
	c := container.New(config.Default())
	db, err := c.DB()
	if err != nil {
		panic(err)
	}
	fmt.Println("db:", db.Dialect())
}
```

Expected output:

```text
db: sqlite
```

The dialect comes per call from `conn.Dialect()`, so the same query code prints `postgres` in production.

## Conventions for contributors

- No globals and no `init()` wiring. `ctx` is the first argument of IO functions and is never stored in a struct.
- Exported identifiers need a doc comment starting with the name. `goimports` local prefix is `github.com/zenta-dev/zever`; `depguard` denies `github.com/pkg/errors` and `io/ioutil`.
- Do not add methods to a public service interface: it breaks every implementer. Add a new interface instead.
- New service shape: interface plus `Register`/`Open` registry in `core/<b>`, one module per adapter in `adapters/<b>/<a>` with a `Register()` call, shared SDK-free code in `shared/*`, and a `README.md` with an adapter table.
- Timeouts and intervals are `time.Duration` (cookie `MaxAge` int seconds excepted); pool options use the `MaxConn*` prefix order. File-decoded Options need snake_case `json`/`toml`/`yaml` tags.
- Tests stay deterministic: no `time.Sleep` sync, no network, no unseeded randomness. File suffixes (`cover`, `live`, `bench`, `internal`, `race`, `closure`) encode purpose; helpers use `stub*`, `must*`, `freshAdapter`.
- Shutdown is a deploy contract: one container per process, closed in dependency order with a timeout parent (see [Lifecycle](https://zenta-dev.github.io/zever/concepts/lifecycle/)).

## Troubleshooting

<details>
<summary>A service package imports `dsl`</summary>

Cause: the compiler frontend leaked into runtime. Fix: remove the import and consume generated output (ORM, routes, stubs). See [compiler boundary](https://zenta-dev.github.io/zever/concepts/compiler-boundary/).
</details>

<details>
<summary>A new interface method breaks every adapter</summary>

Cause: a public interface grew a method. Fix: revert it and add a new interface.
</details>

<details>
<summary>`go build ./...` passes but the docs site fails</summary>

Cause: `docs/` is npm, not Go. Fix: run `npm run dev` under `docs/` with Node 22.12+.
</details>

<details>
<summary>A new service has no adapter table</summary>

Cause: scaffolding skipped the package README. Fix: add the interface, per-adapter subdirectories, registration, and a `README.md` with the adapter table.
</details>

## Related

- [Lifecycle](https://zenta-dev.github.io/zever/concepts/lifecycle/): The four process phases.
- [Container](https://zenta-dev.github.io/zever/concepts/container/): Accessors and close order.
- [Providers and adapters](https://zenta-dev.github.io/zever/concepts/providers-adapters/): Interface and swap rules.
- [Deployment](https://zenta-dev.github.io/zever/guides/operate/deployment/): Production builds and shutdown wiring.
