# 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/`.