APIs and backends

Holidays and business days API in Go

Low-latency Go API for holiday and business-day calculations across 60 countries, with reviewed yearly data, tiered rate limits and caching.

gonet-httpgo-embedlrurate-limiting

Built 1 time, downloaded 0 times.

Install from your terminal

Run this in your project folder. It signs you in, shows what changes and asks before it overwrites a file.

npx claude-lab add holidays-and-business-days-api-in-go-c46a18
10 filesDownload zip
CLAUDE.md
# Holidays and business days API (Go)

## Purpose

Public holidays and business-day math for 60 countries. Low-latency, read-only JSON API.

Endpoints:
- `GET /v1/business-day`
- `GET /v1/add-business-days`
- `GET /v1/holidays`

Free tier is rate limited by IP. Paid tiers are limited by request volume. No UI, no billing UI, no automatic data sourcing.

## Stack

- Go (latest stable), stdlib first.
- `net/http` with 1.22+ ServeMux patterns. No web framework.
- Yearly data embedded with `go:embed` and loaded into memory at startup.
- Tests: table-driven, `testing` package only.

## Commands

- Build: `go build ./...`
- Test: `go test ./... -race`
- Vet: `go vet ./...`
- Lint: `golangci-lint run`
- Benchmarks: `go test -bench . -benchmem ./internal/calendar`
- Run API: `go run ./cmd/api`
- Check data: `go run ./cmd/datacheck`

## Layout

- `cmd/api`: server entry point.
- `cmd/datacheck`: validates all data files.
- `internal/calendar`: pure date logic, no I/O.
- `internal/data`: embedded loader and validation.
- `internal/api`: HTTP handlers.
- `internal/ratelimit`: token buckets.
- `internal/cache`: in-process LRU.
- `data/<country>/<year>.json`: reviewed yearly files.

## Data rules

- Yearly files are reviewed by hand.
- Never invent or auto-edit holiday dates.
- Change files under `data/` only when asked.
- Every file must pass `cmd/datacheck`: schema, sorted dates, valid region codes, no duplicates.
- Weekend days, regional holidays and observed-day shifts are stored explicitly in data. Do not compute them.
- If a holiday date is missing, ask the user. Do not fill it from memory.

## Business day semantics

- Weekend definition is per country. Some countries use Fri-Sat.
- Regional holidays are filtered by the `region` parameter.
- Add-N-days rule (confirm in SPEC.md if unclear):
  - Negative N moves backward.
  - N=0 returns the input date unchanged.
  - Each step skips non-business days.
- Document these rules in the `internal/calendar` package comment and cover them with table tests.

## Performance rules

- Avoid allocations on the hot path where possible.
- Build a per country-year day index (bitset or sorted slice) at load time.
- No file or database reads per request.
- Benchmarks must not regress. Compare with `bench/baseline.txt`.

## Caching rules

- Responses are deterministic per data version.
- Set `Cache-Control` and `ETag`. The ETag includes the data version.
- Keep an in-process LRU for computed results.
- Design for a CDN in front of the API.

## Rate limits

- Token bucket per API key.
- Free tier by IP when no key is sent.
- Tier limits live in config. Never hardcode them in handlers.
- Return 429 with `Retry-After` and standard `RateLimit` headers.

## Conventions

- Dates are ISO 8601 `YYYY-MM-DD`, civil dates with no time zone.
- Errors are wrapped with `%w`.
- Error JSON shape: `{"error":{"code":"...","message":"..."}}`.

## Gotchas

- Time zones must not shift civil dates. Use `time.Date` in UTC for date-only math.
- Check leap years and year boundaries in add-business-days.
- A year without data returns 404 with code `year_not_available`, not an empty list.

## Secrets

- API keys and billing credentials come only from environment variables.
- Use placeholders such as `YOUR_API_KEY` in docs and examples.
- Never commit `.env`.

## Workflow

1. Explore the code first.
2. Write a short plan.
3. Implement.
4. Run the verify skill before saying done.
5. Use `/clear` between unrelated tasks.

Review criteria for `/code-review`:

@REVIEW.md
Use for my project