Skip to content

core: door and window casing fields are optional, not defaulted - #1198

Merged
wass08 merged 1 commit into
mainfrom
fix/casing-fields-optional
Oct 30, 2026
Merged

wass08 merged 1 commit into
mainfrom
fix/casing-fields-optional

Conversation

@wass08

@wass08 wass08 commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

What does this PR do?

Door and window casing fields (casingFaceA, casingFaceB, casingWidth, from #1193) were zod defaults, so parsing any saved door or window wrote all three. A scene's load paths then disagreed (the hosted app's client and authority loads compare them), and an untouched opening changed on its next save.

They are now optional, like other recent optional node fields: loading adds nothing. Absent faces are uncased; an absent width reads as 2 in through openingCasingWidth. New doors and windows still write casing on, so behaviour is unchanged.

How to test

  1. Open a scene saved before casing: its doors and windows have no casing, and saving it changes no door or window fields.
  2. Place a new door and window: casing shows on both faces; the panel's Casing section toggles and resizes it.
  3. bun run ci: passes (run locally).

Screenshots / screen recording

N/A — non-visual change

Checklist

  • I've tested this locally with bun dev
  • My code follows the existing code style (run bun check to verify)
  • I've updated relevant documentation (if applicable)
  • This PR targets the main branch

🤖 Generated with Claude Code


Note

Medium Risk
This touches persisted door/window schema and load/save parity across client and authority; wrong handling could still mutate legacy scenes or desync casing on merge/move, though behavior is heavily covered by tests.

Overview
Door and window casing (casingFaceA, casingFaceB, casingWidth) no longer get Zod defaults when a node is parsed, so legacy openings load without those keys and stay uncased until someone turns casing on. Runtime behavior is unchanged: missing faces mean no boards; missing width still resolves to 2 in via openingCasingWidth.

Tests and round-trip expectations were updated (legacy corpus, scene migration, wall merge, floorplan move commit types) so they assert field absence or undefined instead of false / injected defaults. Preview/plan tests now use openingCasingWidth(node) rather than assuming casingWidth is always on the node.

Reviewed by Cursor Bugbot for commit f80ce2c. Bugbot is set up for automated code reviews on this repo. Configure here.

Door and window casing (casingFaceA/B, casingWidth) were zod defaults: parsing
a saved opening wrote all three, so a scene's load paths no longer agreed and
an untouched door changed on save. Like other recent optional fields they are
now optional; readers already treat absent faces as uncased and an absent
width as 2 in (openingCasingWidth). New openings still write casing on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@wass08
wass08 merged commit 7931ef3 into main Oct 30, 2026
5 checks passed
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.

1 participant