Skip to content

feat(api): resolve match construction period by year - #31

Merged
jravani merged 1 commit into
mainfrom
feat/match-construction-period-by-year
Sep 4, 2026
Merged

jravani merged 1 commit into
mainfrom
feat/match-construction-period-by-year

Conversation

@jravani

@jravani jravani commented Sep 4, 2026

Copy link
Copy Markdown
Member

What

GET /api/v1/variants/{cc}/match now accepts year as an alternative to period. Exactly one of the two is required; both or neither is a 400. With year, ignis selects the period whose construction-year band contains it, scoped to the requested building type, then returns the same refurbishment-variant list as the period path. period is unchanged and backward compatible.

New GET /api/v1/periods/{cc} returns a country's bands as [{ period, year_from, year_to }], oldest first. year_from 0 and year_to 9999 are passed through as the open-ended sentinels.

How

  • TabulaReader.ResolvePeriodByYear(tableName, typePrefix, year) and ListPeriods(tableName) read Code_ConstructionYearClass, Year1_Building, Year2_Building. These are already DB columns: build_db creates one per workbook header, so no loader change was needed.
  • The Year1_Building = 0 / Year2_Building = 9999 open-ended bands need no special case; a plain Year1 <= year <= Year2 comparison covers them. Verified against real rows (e.g. AT.01 = 0..1918, SI.06 = 2009..9999).
  • Year resolution is scoped to CC.N.TYPE, so a year with no archetype for that type (e.g. DE terraced houses have no pre-1860 band) returns an empty match list, not an error.

Tests

  • Repository integration tests: band resolution including both boundaries, the open-ended newest band, and a type that lacks a band; ListPeriods ordering and sentinel passthrough.
  • Handler tests: the year path, the both/neither 400, non-integer year, the empty-list case, and repo error to 500; ListPeriods success, unknown country, repo error.
  • go test ./..., go test -tags integration ./internal/db/..., go vet ./..., make schema-check, and redocly lint on the OpenAPI spec all pass.

Docs

OpenAPI spec (year param, /periods path, PeriodsResponse / ConstructionPeriod schemas) and docs/api.md updated.

Closes #29

https://claude.ai/code/session_01JBfY6ZG2W52imgy2M1JGYo

GET /api/v1/variants/{cc}/match now accepts a construction year as an
alternative to the TABULA period code. Callers holding a build year no
longer hardcode each country's period-year bands: exactly one of period
or year is required, and ignis maps the year to the period whose band
contains it, scoped to the requested building type.

Year resolution reads Code_ConstructionYearClass, Year1_Building and
Year2_Building, which build_db already loads from the workbook. The
Year1 0 and Year2 9999 open-ended sentinels need no special case, a
plain range comparison covers them. A year with no archetype of that
type returns an empty match list rather than an error.

New GET /api/v1/periods/{cc} lists a country's bands as
{ period, year_from, year_to }, oldest first, for callers that want to
present the choices.

Adds TabulaReader.ResolvePeriodByYear and ListPeriods with integration
coverage, handler tests for the year path and the both/neither 400, and
updates the OpenAPI spec and docs/api.md.

Closes #29

Claude-Session: https://claude.ai/code/session_01JBfY6ZG2W52imgy2M1JGYo
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.41176% with 9 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/db/repository/tabula_repository.go 80.43% 5 Missing and 4 partials ⚠️

📢 Thoughts on this report? Let us know!

@jravani
jravani merged commit c2f8e2f into main Sep 4, 2026
6 checks passed
@jravani
jravani deleted the feat/match-construction-period-by-year branch September 4, 2026 15:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Match construction period by year on GET /variants/:cc/match

2 participants