Repository navigation
feat(api): year-partitioned markdown event records - #216
Merged
Merged
Conversation
Mirrors codeforphilly-data #17 (empty) byte-for-byte: events live at events/<YYYY>/<slug>.md with the description as the markdown body (gitsheets' native `${{ startsAt: YYYY }}` bucket, UTC year), series at event-series/<slug>.md likewise, RSVPs at event-rsvps/<YYYY>/<eventSlug>/<personSlug>.toml. Monthly events accrete forever; a flat directory would not. The RSVP sheet's `year` joins the write-injected path fields in the config guard test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SNuYr7DujdhkHoY2h3yYgu
Write path for the new layout (specs/behaviors/storage.md#sheet-layout): - RSVP records carry the event's partition year next to eventSlug and personSlug. The year is the UTC year of startsAt, which equals what gitsheets renders for the event sheet's own bucket because every stored timestamp is a `Z` string. The purge cascade computes it the same way. - An update whose startsAt crosses a year boundary now moves the event file and every RSVP file in the same commit, exactly as a slug rename does; slug history is written only for the rename, since the partition never shows in a URL. - Markdown-bodied upserts opt in to a missing body: an event or series without a description is normal, and our upserts always carry the full record so the erase-guard adds nothing. A body-less file reads back as '' and the serializers present that as null. - `/events/<handle>` for a live series slug with no event of that slug, and the old segment URLs, 301 to `/events/series/<handle>` — a laddr "event" was a whole program (specs/behaviors/events.md#legacy-urls). Tests cover the on-disk paths, the markdown round trip, and a Dec 31 → Jan 1 move. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SNuYr7DujdhkHoY2h3yYgu
… bucket
The spec and plan still described the year partition as a slice
expression; the configs use gitsheets' native `${{ startsAt: YYYY }}`
bucket, which also lets range filters prune partitions.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SNuYr7DujdhkHoY2h3yYgu
themightychris
force-pushed
the
feat/events-storage-layout
branch
from
October 14, 2026 04:54
491e353 to
429619d
Compare
Shipped with codeforphilly-data #17–#19. Notes record the gitsheets body-less upsert opt-in, the '' read-back and trailing-newline normalization, and the shared partitionYear helper; the backfill plan inherits the upsert option. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TGqwPjt3v4eMfiHpPmCKnR
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements plan
events-storage-layout(specs from #215). No schema or contract change.events/<YYYY>/<slug>.md(native${{ startsAt: YYYY }}bucket, description as the markdown body),event-series/<slug>.md,event-rsvps/<YYYY>/<eventSlug>/<personSlug>.toml.startsAtcrosses a year boundary moves the event file and its RSVP files in one commit, like a slug rename (slug history only for the rename). Purge cascade computes the year the same way.'', which the serializers present asnull. gitsheets trims the body's trailing newline; everything else round-trips byte-for-byte./events/<handle>(live series slug, no event) and segment URLs 301 to/events/series/<handle>.Merge with
codeforphilly-data #17 (empty), #18 (fixture), #19 (legacy-import) — merge together so
check:sheet-configsstays green.publishedis adopted by the release session in lockstep with the release.Validation
check:sheet-configs --ref=events-layout-emptymatches🤖 Generated with Claude Code
https://claude.ai/code/session_01SNuYr7DujdhkHoY2h3yYgu