Skip to content

Read the calendar as days, weeks and years - #112

Merged
monorkin merged 1 commit into
mainfrom
calendar-periods
Aug 22, 2026
Merged

Read the calendar as days, weeks and years#112
monorkin merged 1 commit into
mainfrom
calendar-periods

Conversation

@monorkin

@monorkin monorkin commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

A calendar's recordings and a period's are not the same answer. A calendar lists what it
holds, and a recurring event is one row in it; a day, a week or a year expands that row
into the occurrences that fall inside its window. Draw a week from a calendar's recordings
and a weekly meeting shows up once, on the day it was created.

So there are five reads here rather than one, plus the toggle that decides what they cover:

Operation Route Answers
CalendarPeriods().Day(date) GET /calendar/days/{date}.json one day — now works as the date
CalendarPeriods().Days(startsAt) GET /calendar/days.json the window of days from a date
CalendarPeriods().Week(date) GET /calendar/weeks/{date}.json the week a date falls in
CalendarPeriods().Weeks(startsAt, centeredAt) GET /calendar/weeks.json nine weeks
CalendarPeriods().Year(date) GET /calendar/years/{date}.json the year's grid
Calendars().Toggle(id) POST /calendars/{id}/toggle.json the selection it left behind

Every period read is scoped to the calendars the reader has switched on, which is what the
toggle changes — and why the toggle answers the selection rather than nothing, so a client
learns what its next period read will cover without reading the calendars again.

A year is the odd one out on purpose. It answers the grid it is drawn as — one entry per
day, plus the events that span more than one — because a year of expanded occurrences is
not what opening a year asks for.

Notes for review

No .json in the modelled URIs for the three date-terminated routes. Smithy refuses
{day}.json — a literal segment cannot contain braces. Those operations are modelled
without the extension and pick it up from withJSONExtension per request, like the other
label-terminated routes already do. The tests assert the wire path, extension included.

Six exclusions dropped from spec/excluded-routes.json, all of them "phase-2".
GET /calendar/days/now stays excluded and its reason is rewritten: it is the same action
as the day read, reachable by passing now as the date.

The route snapshot and the API version stay pinned where they were. These routes were
already in the snapshot — they served HTML — and what changed is that they answer JSON now.
Re-pinning would pull in every unrelated route added since the pinned SHA and ask this PR
to write exclusions for work it knows nothing about. AGENTS.md ties the service version
date to the snapshot pin, so that stays put too.

Bumped to 0.16.0 — #111 took 0.15.0 while this was open.

Copilot AI balanced review requested due to automatic review settings August 22, 2026 14:52

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

A calendar's recordings and a period's are not the same answer. A calendar lists
what it holds, and a recurring event is one row in it; a day, a week or a year
expands that row into the occurrences that fall inside its window. Draw a week
from a calendar's recordings and a weekly meeting shows up once, on the day it
was created.

So there are five reads here rather than one: a day, the window of days after a
date, a week, the nine weeks around one, and a year. Every one of them is scoped
to the calendars the reader has switched on, which is what ToggleCalendar
changes -- and why it answers the selection it left behind, so a client does not
have to read the calendars again to know what its next period read will cover.

A year is the odd one out on purpose. It answers the grid it is drawn as -- one
entry per day, plus the events that span more than one -- because a year of
expanded occurrences is not what opening a year asks for.

Every path here ends in a date, which Smithy cannot follow with `.json` inside
one URI segment, so the operations are modelled without it and pick it up from
withJSONExtension like the other label-terminated routes.

The routes were already in the pinned route snapshot, serving HTML; what changed
is that they answer JSON now. The pin and the API version stay where they are.
@monorkin
monorkin merged commit 2fcf04c into main Aug 22, 2026
18 checks passed
@monorkin
monorkin deleted the calendar-periods branch August 22, 2026 14:59
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.

2 participants