# Oficina Calendar for Apple platforms

Calendar provides calendar filtering, month navigation, a selected-day agenda, event detail and single-event creation/editing. It preserves event wall-clock time and IANA zone, and uses the existing personal-calendar default. Recurring events and bookings open the web editor.

The SwiftUI client supports macOS 14+, iOS 17+ and iPadOS 17+. Mac uses a split
window with a sidebar, toolbar and form sheets; iPhone collapses navigation into
native columns and sheets. iPad uses the wider split layout. Both appearances
use system typography and controls. Credentials stay in the per-app Keychain;
responses and generated answers are held in memory.

Build Mac with `native/scripts/build-mac.sh`; build the simulator app with
`native/scripts/build-iphone.sh`. For a physical device use
`OFICINA_DEVELOPMENT_TEAM=<team> native/scripts/build-iphone.sh device`. Generate
the iOS project with `xcodegen generate --spec native/ios/project.yml`, then build
`CalendarPhone` in Xcode. Physical devices require your development team.
The generated projects and build products are ignored.

The Swift and Go dependencies pin Rastrillo Native main `2a5d07b2c8d3dfb3fd8526dc7e1c802f97865c67`.

Browser sign-in requires the new backend `/native/` routes. A server that has
not received this update reports that native support is unavailable.

`CalendarReview` is a test-only executable: it accepts a loopback fixture
credential over stdin, renders the real workspace and captures its window.
Set NATIVE_REVIEW_BINARY and NATIVE_REVIEW_OUTPUT when running `go test
./internal/calendar -run TestNative` to exercise it against the app's real test
server. It is never included in the Mac or iOS app bundle.

The native API adds GET `/api/native/session`, GET `/api/native/events` with a
maximum 62-day half-open range, and POST `/api/native/events[/{id}]`. Existing
person, calendar-grant and event-store checks remain authoritative. Recurrence
expansion stays on the server. All-day ends are exclusive dates. The UI uses the
person's saved week start and time zone, not the device's implicit formatting zone.

For XCTest interaction checks against the isolated authenticated fixture, set
`NATIVE_REVIEW_SIMULATOR=<UDID> NATIVE_REVIEW_UI_TESTS=1` with a writable
`NATIVE_REVIEW_OUTPUT` PNG path when running the native Go fixture test. First
build/install the separate ReviewPhone target. The UI tests create and inspect
fixture events and never connect to a real account. Xcode result bundles
are under `native/build/ios/Logs/Test`. Review credentials enter only the isolated
review app's Documents directory and are removed when the fixture exits.

## Quick-add, menu bar and time zones

Use Quick add (Command-K on Mac) and type a sentence such as “Lunch tomorrow at
1pm for an hour”. Review the understood date, time, calendar, recurrence and
assumptions, then choose Add event (Command-Return on Mac). The server's existing
Go parser is the only natural-language implementation. Saving uses the concrete
preview dates, so midnight cannot reinterpret tomorrow. Attendees are recorded;
no invitations are sent. Saved-event warnings stay visible instead of inviting
a duplicate retry.

The Mac menu-bar calendar stays available after the main window closes. It
shares the selected date and filter, shows a compact month and day agenda, and
contains quick-add. Open Calendar returns to the full window; Quit Calendar
ends the app. It does not register itself to launch at login.

Native Calendar follows this device's system time zone by default. Calendar
settings offers Use system time zone or an explicit local override. On Mac use
the app's Settings menu or the gear in the menu-bar panel; on iPhone use Settings
in the calendar sidebar. The choice controls viewing ranges, new events and
quick-add interpretation. Existing events retain their stored wall clock/IANA
zone, and all-day entries remain civil dates. The server account's web preference
is not rewritten by a device setting.

The feature adds protected POST `/api/native/quick/parse` and
POST `/api/native/quick`; GET `/api/native/events` accepts an optional viewing
`zone`. Clients without that query retain the previous server-preference behavior.
Preview bodies are bounded; create uses the existing grant checks and event store.

Review: `/root/canary_release_review`, dispatched gpt-6-astra/high (runtime
identity not independently verified), approved source after delayed-save
sign-out, lost-confirmation and zone-encoding findings were fixed. Its isolated
post-response-guard mutation failed four Swift assertions and was restored;
all five Swift tests and the Go quick-add/viewing-zone tests passed. iPhone
XCTest created an event through the actual parser/preview/save flow. The menu
content was rendered against an authenticated fixture and inspected.
