# Development Policy

This document gives developers and LLM coding agents the concrete workflow for
changing `weatherapi` safely. Architecture invariants are defined in
[`docs/policy/architecture.md`](architecture.md).

## Repository Layout

| Path | Purpose |
| --- | --- |
| `cmd/weatherapi` | executable composition root |
| `internal/app` | read use cases, repository port, current-conditions model |
| `internal/adapters/inbound/httpapi` | route definitions, query binding, handlers |
| `internal/adapters/inbound/httpapi/presenter` | response payload shaping |
| `internal/adapters/outbound/postgres` | SQL reads and row mapping |
| `templates` | text response templates |
| `docs` | current documentation, policy, internals, integrations, roadmap |
| `examples` | copyable config and request examples |

## Build and Test Commands

Build:

```sh
go build ./cmd/weatherapi
```

Run all tests:

```sh
go test ./...
```

Focused tests:

```sh
go test ./internal/app
go test ./internal/adapters/inbound/httpapi
go test ./internal/adapters/inbound/httpapi/presenter
go test ./internal/adapters/outbound/postgres
```

Private module access is required for `feedapi` and `weatherfeeder` downloads.
If tests fail because Go cannot fetch a private module, fix module access before
treating package tests as behavior failures.

## Coding Conventions

- Keep `cmd/weatherapi` thin.
- Keep application use cases independent of HTTP, SQL, renderers, and templates.
- Keep query validation in the HTTP adapter.
- Keep unit conversion, rounding, timezone presentation, and payload copy
  behavior in presenters.
- Keep SQL text, row structs, null handling, and UTC normalization in the
  Postgres adapter.
- Prefer small focused changes over broad refactors.
- Preserve contextual error wrapping in repository and runtime code.

## Dependency Policy

Current direct dependencies are:

- `feedapi` for config, DB registry, endpoint definitions, renderers,
  middleware, templates, and HTTP runtime;
- `weatherfeeder` for canonical model and standards types;
- `github.com/lib/pq` for the Postgres driver.

Do not add dependencies for small conveniences. New dependencies need a clear
adapter or domain purpose and should not leak through application boundaries
unless they are the explicit boundary contract.

## Adding or Changing Endpoints

1. Add or update the `Service` method in `internal/adapters/inbound/httpapi` if
   the handler needs a new application read.
2. Add or update the application repository port in `internal/app`.
3. Implement the read in the Postgres adapter if needed.
4. Add the endpoint definition and binder in `internal/adapters/inbound/httpapi`.
5. Add presenter behavior in `presenter` instead of shaping payloads in handlers.
6. Add or update text templates when `format=text` should be supported.
7. Add endpoint tests for registration, query validation, formats, errors,
   `data: null`, and representative payload behavior.
8. Update [`docs/api.md`](../api.md) and examples when the public HTTP contract changes.

## Changing Query Parameters

- Update binder functions and endpoint tests together.
- Preserve strict unknown-parameter rejection unless the route explicitly allows
  a new parameter.
- Keep timezone parsing limited to route families that support it.
- Keep precision range validation aligned with presenter rounding support.
- Update [`docs/api.md`](../api.md) for public query behavior changes.

## Adding Config Fields

Config shape is loaded by feedapi. When `weatherapi` starts using a new config
field:

1. update runtime composition or the relevant adapter;
2. update [`docs/config.md`](../config.md);
3. update examples under `examples/` if operators need to set it;
4. add config/runtime tests where practical;
5. avoid committing real credentials or private infrastructure details.

## Adding CLI Flags

The executable currently supports only `-config`. If adding a flag:

1. keep parsing in `cmd/weatherapi`;
2. avoid putting business logic in `cmd`;
3. document precedence with environment variables if applicable;
4. update [`docs/cli.md`](../cli.md);
5. add tests when flag behavior is not trivial.

## Changing Repository Reads

- Keep SQL in `*_queries.go`.
- Keep row DTOs in `*_rows.go`.
- Keep mapping/null handling in `*_mapper.go`.
- Return `nil, nil` for missing latest parent rows.
- Normalize timestamps to UTC in mappers.
- Preserve child ordering from stored index columns.
- Update [`docs/internal/postgres-repository.md`](../internal/postgres-repository.md)
  and [`docs/integrations/weatherfeeder-postgres.md`](../integrations/weatherfeeder-postgres.md)
  when table or column assumptions change.

## Changing Presenters or Templates

- Copy input values before conversion, rounding, or timezone changes.
- Preserve nil pointer and `omitempty` behavior.
- Keep text-template helper fields out of JSON/XML when they are not public API
  fields.
- Check `templates/*.txt.tmpl` for field references.
- Update presenter tests and endpoint text tests.
- Update [`docs/api.md`](../api.md) when response shape changes.

## Updating Examples

Examples must be copyable, valid, and free of secrets.

- Config examples belong under `examples/config.*.yml`.
- HTTP examples belong in `examples/requests.http`.
- Do not include unimplemented routes.
- Re-run YAML syntax checks or config loading tests when config examples change.

## Documentation Checklist

When behavior changes, update the canonical doc in the same change:

- README for project orientation and shortest useful command;
- `docs/api.md` for public HTTP behavior;
- `docs/config.md` for YAML config;
- `docs/cli.md` for executable flags and environment variables;
- `docs/operations.md` and `docs/troubleshooting.md` for operator behavior;
- `docs/internal/` for implementation boundaries;
- `docs/integrations/` for external storage/runtime contracts;
- `docs/roadmap/` only for unimplemented work.

Do not describe unimplemented behavior outside `docs/roadmap/`.
