Skip to content

refactor from main - #1570

Merged
nopivnick merged 36 commits into
feat/form-refactor-polishfrom
main
Aug 29, 2026
Merged

nopivnick merged 36 commits into
feat/form-refactor-polishfrom
main

Conversation

@nopivnick

Copy link
Copy Markdown
Member

Summary of Changes

Schema Changes

  • No tenant schema changes
  • Schema changed (describe below)

Checklist

  • I linked relevant issue(s) in the Development section
  • I checked for existing implementations and confirmed there is no duplication
  • I thoroughly tested this feature locally
  • I added or updated unit tests (or explained why not in the PR description)
  • I attached screenshots or a video demonstrating the feature (or explained why not in the PR description)
  • I reviewed all High and Medium severity comments from Claude's code review, and replied to every High severity comment (a reply is required for High), then marked conversations as resolved
  • I confirmed my PR passed all unit and end-to-end (E2E) tests
  • I confirmed there are no conflicts
  • I requested a code review from at least one other teammate

Screenshots / Video

n3xta and others added 30 commits July 21, 2026 10:41
…en't crowded out

The paginated bookings fetch orders by startDate descending with a 500-row
limit. The liaison view's default "All Future" range is open-ended, so once
a semester's bulk bookings push the future count past 500, the window holds
only far-future rows and near-term REQUESTED bookings never reach the
client — the approval table renders empty while approval emails still go
out. Let the client pass a sortDirection and have the liaison All Future
view fetch ascending (nearest first).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011qR68PCSFw39F5yCxBaDRR
Annex (auxiliary space) resources in the tenant schema can now declare
parentResourceId. Such resources are hidden from the top-level room list,
their annex checkbox options are derived from the child resources (with
fallback to services.annex options for unmigrated tenants), selecting one
invites its calendar to the booking's calendar event (create/edit/
modification), and the bookings API rejects them as standalone rooms.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Remove the faculty/staff-only gate on auxiliary spaces: the annex
checkboxes now render for every role and the bookings API no longer
strips annexByRoom for students. Drops the now-unused
canRequestAuxiliarySpaces helper.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Selected annex spaces now render their own availability column next to
the parent room on the room selection page. Extracted the schema
resource → RoomSetting conversion into a shared helper.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat: add date range to booking CSV export
Fetch the liaison All Future queue ascending so near-term requests aren't crowded out
The new-reservation bar renders on the first room in the rooms prop and
stretches rightward across the remaining columns, so the array must be
in the same numeric order as the sorted columns. Appending annex rooms
after selectedRooms broke that for annex spaces sorting left of their
parent (e.g. 1200L-6 next to 1201).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Remove the annex sections from MC_SERVICES_BY_ROOM (103, 202, 1201) —
annex options, labels, and calendar invites all derive from
parentResourceId child resources now. The services.annex fallback path
stays for unmigrated tenant documents. Tests updated to the
child-resource model.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Email (booking_detail) and MoreInfoModal now merge selected auxiliary
  spaces into the Room(s) list (numeric order) and the email gains an
  Auxiliary Spaces row, matching the calendar description.
- serverGetRoomCalendarIds now splits comma-joined roomId lists
  ("202, 1201"); the exact-string match returned no calendars for
  multi-room bookings, so approval never invited the requester or
  secondary contact (e.g. request #5287).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… table

The REQUESTED approver email path in the bookings API stringified every
contents value, turning annexByRoom into "[object Object]" so the email
showed neither merged Room(s) nor the Auxiliary Spaces row. Keep the
object form. Also merge annex spaces into the Room(s) column of the
bookings table.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Structure annex spaces as parent-child resources with calendar invites
Per team decision, auxiliary spaces stay faculty/staff-only: restore the
canRequestAuxiliarySpaces gate on the annex checkboxes and the
annexByRoom strip in the bookings API.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Form/JSON toggle is gone; the schema editor is JSON-only now. Drops
the form section components (BasicInfo, FeatureToggles, Policy,
Resources, Attestations, Mappings, CalendarConfig, EmailMessages), the
ResourceEditor unit test, and the getByPath/setNestedValue helpers that
only the form mode used. Diff confirmation dialog, unconfigured-fields
banner, save/reset, and backup-on-save behavior are unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYFYUMogwYCpkJ19qZ9H7H
Hide auxiliary spaces from students (follow-up to #1563)
The Schema Diff tab computed the Difference table with the recursive
computeDiff (leaf-level dot-paths) while the sync dry-run endpoint used a
separate top-level-only computeDiffSummary. A field missing from the
target inside a nested object or array item showed up in Difference but
collapsed into a single "changed" parent row in the dry-run report, so
the missing fields were invisible there.

- lib/utils/schemaDiff.ts is now the single diff implementation
  (computeDiff + formatValue, moved from super/schemaEditorUtils.ts);
  computeDiffSummary is removed.
- sync route returns diff as DiffEntry[] with the same orientation the UI
  uses (old = target, new = source).
- schemaCompare renders Difference and dry-run with one SchemaDiffTable,
  so both show identical rows for identical input.
- SchemaDriftBanner counts leaf-level diffs.
- Tests moved to schema-diff.unit.test.ts with nested/array parity cases;
  sync dry-run test asserts the new shape.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FYFYUMogwYCpkJ19qZ9H7H
…es schema

Adds a `toggle` field to service section and staffing configs so a room can
lock a service switch on or off. Locked-on switches write their value on
mount (shared fields resolve across selected rooms: any on wins, off only
when all rooms lock off); locked-off switches clear stale values and render
description only. Schema locks take precedence over the dynamic
catering→cleaning and large-event security rules.

Refs #1567

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WX3zGJEULDkmiBNP7rcvEo
Schema editor JSON-only; unify schema diff so sync dry-run matches Difference table
A locked-on equipment switch with no details field cannot produce an
equipment request (detection is value-based), so treat a toggled section
as having a details field.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WX3zGJEULDkmiBNP7rcvEo
…riven equipment requests

- Staffing: while the switch is on (user or locked), every section must have
  a selection; sections without a defaultValue no longer submit empty.
- Equipment requests that only carry details (schema-driven sections) were
  saved but hidden: the booking details modal, calendar description, CSV
  export and calendar sync summary gated on the legacy equipmentServices
  list. They now also honor equipmentServicesDetails(ByRoom).
- Tenant schema normalization accepts boolean flags saved as "true"/"false"
  strings by the schema editor (showDetailsField, forceCleaning, required).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WX3zGJEULDkmiBNP7rcvEo
Rooms whose setup service is not offered to the requester store nothing,
so the booking details modal and calendar description rendered
"Room Setup: none". Skip the row instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WX3zGJEULDkmiBNP7rcvEo
rlho and others added 5 commits August 26, 2026 18:41
…r an off lock

- The staffing switch is rendered under the first staffing room only, so
  its lock is now resolved by the parent across every selected room and
  passed down; a later room's lock is no longer ignored.
- A schema security toggle of "off" no longer defeats the mandatory
  security for 75+ attendee events: the large-event rule keeps the switch
  forced on and the dynamic auto-enable still runs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WX3zGJEULDkmiBNP7rcvEo
Mirrors the equipment rule: a furnishings section with a details field
must have per-room details filled in while the switch is yes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WX3zGJEULDkmiBNP7rcvEo
Rooms with services: {} (e.g. 260, no services offered) were classified
as legacy because the check counted config keys, so the tenant-level
showSetup flag rendered the generic Room Setup switch (and other legacy
switches) for them. Any object services config now means schema-driven;
the generic switch only appears for legacy rooms or switch-mode setup
sections.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WX3zGJEULDkmiBNP7rcvEo
… room

- FormInput's legacy equipment UI and BookingFormResourceServices used
  inverse copies of the same rule; a toggle-only equipment config matched
  neither consistently and rendered both UIs. Both now use
  isSchemaDrivenEquipmentSection.
- The required-details validation error for equipment and furniture is
  form-wide; render it only under rooms that are actually missing details.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WX3zGJEULDkmiBNP7rcvEo
Add lockable service toggles (on / off / optional) to the MC booking form
@nopivnick
nopivnick merged commit 1bd836b into feat/form-refactor-polish Aug 29, 2026
49 checks passed

This branch was previously deployed

3 inactive deployments
production — 82b222d4 Deployed Aug 30, 2026 by rlho via trigger-auto-checkout (production) #16134
staging — 82b222d4 Deployed Aug 30, 2026 by rlho via trigger-auto-checkout (staging) #16134
dev — 82b222d4 Deployed Aug 27, 2026 by rlho via deploy #756
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.

3 participants