Files
weatherapi/docs/policy/development.md

5.9 KiB

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.

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:

go build ./cmd/weatherapi

Run all tests:

go test ./...

Focused tests:

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 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 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;
  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;
  5. add tests when flag behavior is not trivial.

Changing Repository Reads

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