# Repository Guidelines

## Project Structure & Module Organization
- `cmd/server/main.go` is the Fiber entrypoint that wires config, routes, and startup logging.
- `internal/geo` owns GeoLite2 lookups, IP validation, and response shaping.
- `docker-compose.yml` defines the container entry; `Dockerfile` builds a static binary. `GeoLite2-City.mmdb` sits at the repo root and is mounted to `/data/GeoLite2-City.mmdb`.
- Keep `cmd/server` thin; place new logic in `internal/<domain>` with clear boundaries.

## Build, Test, and Development Commands
- `PORT=8080 GEOIP_DB_PATH=./GeoLite2-City.mmdb go run ./cmd/server` runs the API locally without Docker.
- `docker compose up --build` builds and starts the containerized service (mounts the local database).
- `curl "http://localhost:8080/lookup?ip=1.1.1.1"` exercises the lookup endpoint; omit `ip` to use the caller’s address.
- `go build ./...` validates compilation before pushing changes.

## Coding Style & Naming Conventions
- Go 1.22; always format with `gofmt -w`.
- Favor small packages and dependency injection for services (e.g., pass resolvers, do not use globals).
- Package names are lowercase; exported identifiers use CamelCase; environment variables use UPPER_SNAKE.
- Keep JSON response shapes stable; prefer explicit structs over maps for API outputs.

## Testing Guidelines
- Use Go’s standard testing with `*_test.go` files and run `go test ./...`.
- Prefer table-driven tests for lookup edges (IPv4/IPv6, invalid IP, missing city/region data).
- For integration tests, allow overriding `GEOIP_DB_PATH` with a fixture `.mmdb` to avoid mutating the bundled dataset.

## Commit & Pull Request Guidelines
- Commit titles should be concise, imperative English with an optional scope (`geo`, `server`, `build`).
- Add a short body describing intent and behavioral impact when relevant.
- PR descriptions should list linked issues, test commands executed, and a sample request/response payload when API output changes.
- Keep images lean; avoid adding unused assets or oversized binaries to the image layers.

## Security & Configuration Tips
- GeoLite2 carries licensing; refresh by replacing `GeoLite2-City.mmdb` with the latest download rather than mirroring it elsewhere.
- Validate IP inputs and avoid logging full client IPs with stack traces in sensitive environments.
- Behind proxies, configure trusted proxy headers so `X-Forwarded-For` is respected (Fiber `app.Config.ProxyHeader` can be set if needed).
