feat: month, year, and discovery endpoints #134

Merged
manlycucumber merged 1 commit from feature/8-calendar-endpoints into develop 2026-07-03 05:39:43 +00:00
manlycucumber commented 2026-07-03 05:38:48 +00:00 (Migrated from github.com)

Completes the calendar endpoints (epic #8) on top of the #133 skeleton — the read surface the Ordo plugin and Site consume for the R2 / 3mi.org release.

What's here

  • GET /v1/month/{year-month} (#10) and GET /v1/year/{year} (#11) — an ordered list of day contracts (each self-describing via its own date) with meta.count. The gateway resolves the civil year once (memoised per year+calendar) and reads every day off that index, so a whole year is a single Core resolution.
  • GET /v1/meta (#12) — discovery: supported systems (1962roman:rubricae-1960), calendars (universal + the sspx particular with its overlay descriptor), languages (la), and the resolved date range (1583–2200). Every value is derived from Core, not hardcoded, so it stays correct as 1954/1955 and FSSP/ICKSP land.
  • GET /v1/day/{date} (#9) shipped in #133 as the skeleton's anchor; this PR rounds out its siblings.
  • Gateway unification: CoreGateway now resolves through CalendarCatalog + DayContract directly — one resolution path for single day and ranges — and gains systemsDetail()/calendarsDetail(). QueryParser gains parseMonth/parseYear (shared year-range check); RangeQuery carries the validated span + its echo.

Verification

  • composer check green: phpcs 27/27, PHPStan [OK], PHPUnit 48 tests / 176 assertions.
  • Real HTTP smoke: /v1/meta lists universal,sspx; /v1/month/2026-09 = 30 days (Sep 3 first-class under ?calendar=sspx); /v1/year/2024 = 366 (leap).

Refs #8 #9 #10 #11 #12

Completes the **calendar endpoints** (epic #8) on top of the #133 skeleton — the read surface the Ordo plugin and Site consume for the R2 / 3mi.org release. ## What's here - **`GET /v1/month/{year-month}`** (#10) and **`GET /v1/year/{year}`** (#11) — an ordered list of day contracts (each self-describing via its own `date`) with `meta.count`. The gateway resolves the civil year **once** (memoised per year+calendar) and reads every day off that index, so a whole year is a single Core resolution. - **`GET /v1/meta`** (#12) — discovery: supported **systems** (`1962` → `roman:rubricae-1960`), **calendars** (`universal` + the `sspx` particular with its overlay descriptor), **languages** (`la`), and the resolved **date range** (1583–2200). Every value is derived from Core, not hardcoded, so it stays correct as 1954/1955 and FSSP/ICKSP land. - **`GET /v1/day/{date}`** (#9) shipped in #133 as the skeleton's anchor; this PR rounds out its siblings. - **Gateway unification:** `CoreGateway` now resolves through `CalendarCatalog` + `DayContract` directly — one resolution path for single day and ranges — and gains `systemsDetail()`/`calendarsDetail()`. `QueryParser` gains `parseMonth`/`parseYear` (shared year-range check); `RangeQuery` carries the validated span + its echo. ## Verification - `composer check` green: phpcs 27/27, PHPStan `[OK]`, **PHPUnit 48 tests / 176 assertions**. - Real HTTP smoke: `/v1/meta` lists `universal,sspx`; `/v1/month/2026-09` = 30 days (Sep 3 first-class under `?calendar=sspx`); `/v1/year/2024` = 366 (leap). Refs #8 #9 #10 #11 #12
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Directorium/Api!134
No description provided.