# Runtime Composition

This document describes how the `weatherapi` executable wires configuration,
database handles, application services, HTTP endpoints, renderers, and shutdown.
It is development-facing; operator commands belong in
[`docs/operations.md`](../operations.md), and configuration fields belong in
[`docs/config.md`](../config.md).

## Purpose

`cmd/weatherapi/main.go` is the composition root. It should stay thin and only
connect already-implemented packages. Endpoint logic, SQL, presentation logic,
and business read behavior belong outside `cmd`.

## Inputs and Outputs

Inputs:

- config path from `-config`, `WEATHERAPI_CONFIG`, or `config.yml`;
- feedapi YAML config containing `server`, `databases`, and `templates`;
- OS cancellation signals;
- database handles opened by feedapi.

Outputs:

- a configured feedapi HTTP server;
- registered `weatherapi` endpoint definitions;
- process logs for fatal startup errors and database close errors.

## Composition Flow

The executable:

1. sets standard logger flags with microsecond precision;
2. resolves the config path;
3. creates a context canceled by `os.Interrupt` or `SIGTERM`;
4. loads config with `feedapi/config.Load`;
5. requires at least one configured database;
6. opens all configured databases with `feedapi/db.OpenAll`;
7. selects the first configured database name as the primary store;
8. constructs `postgres.Repository` with the primary `*sql.DB`;
9. constructs `app.Service` over the repository;
10. builds HTTP endpoint definitions with `httpapi.Definitions`;
11. constructs a feedapi app with the DB registry and endpoints;
12. starts feedapi with the signal-aware context.

## Config Fields Used

Runtime composition uses:

- `server`: consumed by feedapi for HTTP runtime settings and default format;
- `databases`: opened by feedapi, with the first entry selected as primary;
- `templates`: consumed by feedapi for text-template loading.

Do not duplicate the config field reference here. Keep it in
[`docs/config.md`](../config.md).

## External Adapters Used

- `feedapi/config`: YAML loading.
- `feedapi/db`: database registry and lifecycle.
- `feedapi/app`: HTTP runtime construction and startup.
- `internal/adapters/outbound/postgres`: weather read repository.
- `internal/adapters/inbound/httpapi`: endpoint definition registry.
- `github.com/lib/pq`: Postgres driver registration through blank import.

## State and Lifecycle

`weatherapi` owns no durable weather state. Runtime state is limited to loaded
configuration, database pools, endpoint definitions, renderer/template
registries managed by feedapi, and the running HTTP server.

Database handles are closed with a deferred registry close. Close errors are
logged but do not change response behavior because they occur during shutdown.

## Failure Behavior

`run` wraps startup errors with operation context:

- `load config`
- `config.databases requires at least one entry`
- `open databases`
- `select primary database`
- `build app`

Errors returned by `a.Start(ctx)` are returned to `main`, which logs a fatal
`weatherapi failed: ...` message. Feedapi owns graceful HTTP shutdown after the
context is canceled.

## Tests to Inspect Before Changing

- `internal/app/service_test.go` for service wiring expectations.
- `internal/adapters/inbound/httpapi/endpoints_test.go` for endpoint registry
  and runtime adapter expectations.
- Full `go test ./...` when runtime wiring, config behavior, or feedapi
  integration changes.

## Invariants

- Keep `cmd/weatherapi` as composition code only.
- Preserve config path precedence: `-config`, `WEATHERAPI_CONFIG`, `config.yml`.
- Preserve first configured database as the primary weather store.
- Keep generic HTTP runtime behavior in feedapi.
- Keep endpoint definitions in the HTTP adapter.
- Keep SQL and row mapping in the Postgres adapter.
