Skip to content

feat: allow non-creative edits to SGA Space bookings past advance notice (#94), and bump to v1.14.1 - #98

Merged
pataniaeli merged 2 commits into
devfrom
feat/issue-94-spaces-shrink-edits
Sep 9, 2026
Merged

feat: allow non-creative edits to SGA Space bookings past advance notice (#94), and bump to v1.14.1#98
pataniaeli merged 2 commits into
devfrom
feat/issue-94-spaces-shrink-edits

Conversation

@pataniaeli

@pataniaeli pataniaeli commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

Closes #94.

The rule

Advance notice exists so that time is claimed a set number of hours before it is used. So the thing to test is the time an edit newly claims, not whether the start moved — which is what the PATCH route tested. Shortening a booking, pushing its start later, renaming it or cancelling it all release time or leave it alone, and none of them needs notice.

lib/spaces-advance-notice.ts works out the earliest instant an edit newly claims, and refuses only that:

shape the block being claimed starts at
start moved earlier the new start
end moved later the old end
moved clear of the old interval the new start

The middle row is your parenthetical: extending a booking whose end is still outside the window is allowed, because the time being added begins where the booking already ended. The third row means relocating a booking wholesale to next week is allowed and is not treated as an extension — while sliding it two hours later tonight still is one, because it claims tonight's time.

Creation claims its whole interval, so the POST route reduces to exactly the test it already ran, and now shares the rule rather than keeping a second copy.

It measures from Boston wall clock, not Date.now()

Rebased onto #89 partway through, which is how I found this. A space booking's start_time holds Boston wall-clock digits with a Z on the end, so measuring it against a real instant makes every booking look an offset earlier than it is — that is #87, fixed in 1e3d894, and a shared rule defaulting to Date.now() would have quietly reintroduced it on both paths at once.

now therefore defaults to bostonWallClockNow() inside the rule rather than at each call site, because the browser is a caller too and its clock is in whatever zone the viewer is sitting in — a student on co-op in California would otherwise see a different answer from the server's.

The actual blocker

The server was already half-right — it only checked when start_time changed, and DELETE never checked at all. What made these bookings untouchable was space-calendar.tsx: the notice-zone guard in the click handler returned before the "is this a booking I own?" branch, so a booking sitting inside the window could not be opened, let alone shortened or cancelled. Your own booking is now reached first, in both the click and the hover handler, since opening a booking you already hold claims nothing. The hover affordance and the click target now agree, which they did not before.

The edit modal runs the same rule as the form changes, so a change that would be refused says so up front instead of after a round trip:

Adding time to a booking needs at least 24 hours of notice. You can still shorten this booking, start it later, rename it, or cancel it.

Verification

npm run build, tsc and eslint clean (the one space-calendar.tsx warning is pre-existing and untouched).

The rule was exercised directly across 22 cases — shortening both ends, renaming only, both extension shapes, a booking straddling the cutoff, relocation near and far, creation either side, minHours: 0, and the wall-clock cases above, including one that is correctly allowed under Boston wall clock and would be wrongly refused under Date.now().

I could not click through this in a browser: the dev server is behind a login wall. Worth someone exercising the calendar click on a booking inside the notice window before merge.

🤖 Generated with Claude Code

@vercel

vercel Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
chambers Ready Ready Preview Sep 9, 2026 11:51pm UTC

…#94)

Advance notice exists so that time is *claimed* a set number of hours
before it is used, so the thing to test is the time an edit newly claims
-- not whether the start moved, which is what the PATCH route tested.
Shortening a booking, pushing its start later, renaming it or cancelling
it release time or leave it alone, and none of them needs notice.

lib/spaces-advance-notice.ts works out the earliest instant an edit newly
claims and refuses only that. Extending the end of a booking whose end is
still outside the window is therefore allowed, as the issue asks, because
the block being claimed starts at the old end. Relocating a booking
wholesale to a date past the cutoff is allowed for the same reason, and
is not treated as an extension. Creation claims its whole interval, so the
POST route reduces to the test it already ran and now shares the rule.

`now` defaults to bostonWallClockNow() and not to Date.now(). A space
booking's start_time holds Boston wall-clock digits with a Z on the end,
so measuring it against a real instant makes every booking look an offset
earlier than it is -- issue #87, fixed in 1e3d894, which this would
otherwise have reintroduced. The default belongs in the rule rather than
at each call site because the browser is a caller too, and its clock is in
whatever zone the viewer happens to be sitting in.

The real blocker was in the calendar: the notice-zone guard in the click
handler returned before the "is this a booking I own?" branch, so a
booking sitting inside the window could not be opened at all, let alone
shortened or cancelled. Your own booking is now reached first, in both the
click and the hover handler, since opening a booking you already hold
claims nothing.

The edit modal runs the same rule as the form changes, so a change that
would be refused says so before it is submitted rather than after a round
trip.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@pataniaeli
pataniaeli force-pushed the feat/issue-94-spaces-shrink-edits branch 2 times, most recently from fbf8a25 to 8523418 Compare September 9, 2026 22:37
package.json, the lockfile's two root entries, and the sidebar label.

Only lines 3 and 9 of package-lock.json belong to the project; a find-and-replace
across the file would bump a dependency to a version that does not exist and
break npm ci.

A patch rather than a minor: this release only fixes things. It carries the
weekly update emails and alerts pointing at the week that actually moved (#91),
Senate session-type preferences applying to emails and alerts rather than only
to the My Rooms list (#92, #93), and SGA Space bookings inside the advance
notice window becoming editable again (#94) -- which relaxes a restriction
rather than adding a capability.

The FAQ entry is written for members: what changed for someone using Chambers.
None of it is administrator-only this time, so nothing is named as such. The
v1.15.0 placeholder stays where it is and keeps pointing forward.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@pataniaeli pataniaeli changed the title feat: allow non-creative edits to SGA Space bookings past advance notice (#94) feat: allow non-creative edits to SGA Space bookings past advance notice (#94), and bump to v1.14.1 Sep 9, 2026
@pataniaeli pataniaeli self-assigned this Sep 9, 2026
@pataniaeli pataniaeli added the enhancement New feature or request label Sep 9, 2026
@pataniaeli
pataniaeli merged commit 0cb53fd into dev Sep 9, 2026
4 checks passed
@pataniaeli
pataniaeli deleted the feat/issue-94-spaces-shrink-edits branch September 9, 2026 23:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Non-creative edits should be allowed to SGA Space bookings by users when past advance notice

1 participant