oficina / calendar Public

Merge branch 'feat/home-sso' into main

claude agent, operated by paul@keymail.dev pushed by paul@keymail.dev 9400eb010880328be02eb11099e6494385b3b2ca parent ecb0df9parent 6874345
186 files changed, +26605 −312
  • .gitignore +3 −0
  • .impeccable/config.json +17 −0
  • .impeccable/hook.cache.json +1 −0
  • AGENTS.md +261 −73
  • Makefile +14 −1
  • PRODUCT.md +150 −0
  • README.md +149 −15
  • cmd/calendar/main.go +131 −25
  • docs/superpowers/brainstorms/2026-09-02-calendar-brainstorm.md +1053 −0
  • docs/superpowers/plans/2026-09-07-booking-plan.md +589 −0
  • docs/superpowers/specs/2026-09-02-calendar-design.md +309 −0
  • docs/superpowers/specs/2026-09-02-quick-add-design.md +177 −0
  • docs/superpowers/specs/2026-09-07-booking-design.md +1004 −0
  • go.mod +13 −3
  • go.sum +22 −10
  • internal/calendar/app.go +163 −42
  • internal/calendar/auth.go +283 −0
  • internal/calendar/avail.go +249 −0
  • internal/calendar/avail_describe.go +88 −0
  • internal/calendar/booking_ics.go +51 −0
  • internal/calendar/booking_mail.go +172 −0
  • internal/calendar/booking_public.go +105 −0
  • internal/calendar/clock.go +194 −0
  • internal/calendar/config.go +146 −0
  • internal/calendar/funcs.go +141 −0
  • internal/calendar/handlers.go +94 −8
  • internal/calendar/handlers_booking_form.go +145 −0
  • internal/calendar/handlers_booking_manage.go +236 −0
  • internal/calendar/handlers_booking_public.go +283 −0
  • internal/calendar/handlers_booking_settings.go +72 −0
  • internal/calendar/handlers_booking_util.go +210 −0
  • internal/calendar/handlers_event_delete.go +79 −0
  • internal/calendar/handlers_event_form.go +122 −0
  • internal/calendar/handlers_events.go +270 −0
  • internal/calendar/handlers_jobs.go +260 −0
  • internal/calendar/handlers_jobs_budget.go +49 −0
  • internal/calendar/handlers_misc.go +258 −0
  • internal/calendar/handlers_quick.go +197 −0
  • internal/calendar/handlers_settings.go +58 −0
  • internal/calendar/handlers_views.go +203 −0
  • internal/calendar/home.go +97 −0
  • internal/calendar/home_router_test.go +251 −0
  • internal/calendar/home_security_test.go +43 −0
  • internal/calendar/ics_export.go +230 −0
  • internal/calendar/ics_import.go +269 −0
  • internal/calendar/ics_parse.go +101 −0
  • internal/calendar/logsafe.go +60 −0
  • internal/calendar/logsafe_test.go +44 −0
  • internal/calendar/mail_bounded.go +97 −0
  • internal/calendar/mail_bounded_test.go +48 −0
  • internal/calendar/migrations.go +13 −16
  • internal/calendar/migrations/0001_create_people.sql +4 −0
  • internal/calendar/migrations/0001_init.sql +0 −2
  • internal/calendar/migrations/0002_alter_people.sql +58 −0
  • internal/calendar/migrations/0003_alter_reminders.sql +2 −0
  • internal/calendar/migrations/0004_create_attendees.sql +6 −0
  • internal/calendar/migrations/0005_alter_people.sql +36 −0
  • internal/calendar/migrations/0006_alter_reminder_queues.sql +4 −0
  • internal/calendar/migrations/schema.sql +93 −1
  • internal/calendar/models.go +169 −16
  • internal/calendar/models_attendee.go +37 −0
  • internal/calendar/models_booking.go +187 −0
  • internal/calendar/models_event.go +259 −0
  • internal/calendar/occurrences.go +155 −0
  • internal/calendar/occurrences_step.go +172 −0
  • internal/calendar/pack.go +156 −0
  • internal/calendar/person.go +78 −0
  • internal/calendar/quickadd.go +261 −0
  • internal/calendar/quickadd_range.go +115 −0
  • internal/calendar/quickadd_when.go +224 −0
  • internal/calendar/quickadd_who.go +141 −0
  • internal/calendar/recur.go +296 −0
  • internal/calendar/render.go +140 −26
  • internal/calendar/repeat.go +248 −0
  • internal/calendar/routes.go +185 −0
  • internal/calendar/seal/fingerprint.go +35 −0
  • internal/calendar/seal/seal.go +159 −0
  • internal/calendar/slots.go +182 −0
  • internal/calendar/static/booking.js +103 −0
  • internal/calendar/static/calendar.css +541 −0
  • internal/calendar/static/quickadd.js +151 −0
  • internal/calendar/store.go +102 −0
  • internal/calendar/store_attendee.go +136 −0
  • internal/calendar/store_booking_cancel.go +158 −0
  • internal/calendar/store_booking_confirm.go +185 −0
  • internal/calendar/store_booking_flow.go +244 −0
  • internal/calendar/store_booking_handle.go +140 −0
  • internal/calendar/store_booking_hold_util.go +88 −0
  • internal/calendar/store_booking_mail.go +183 −0
  • internal/calendar/store_booking_page.go +227 −0
  • internal/calendar/store_booking_page_read.go +127 −0
  • internal/calendar/store_booking_read.go +172 −0
  • internal/calendar/store_booking_sweep.go +173 −0
  • internal/calendar/store_calendar.go +239 −0
  • internal/calendar/store_drain.go +291 −0
  • internal/calendar/store_event.go +188 −0
  • internal/calendar/store_event_read.go +68 −0
  • internal/calendar/store_event_write.go +157 −0
  • internal/calendar/store_feed.go +199 −0
  • internal/calendar/store_override.go +252 −0
  • internal/calendar/store_range.go +280 −0
  • internal/calendar/store_reminder.go +256 −0
  • internal/calendar/store_reminder_next.go +86 −0
  • internal/calendar/store_slots.go +94 −0
  • internal/calendar/summary.go +185 −0
  • internal/calendar/templates/_bookingpane.html +25 −0
  • internal/calendar/templates/_chip.html +19 −0
  • internal/calendar/templates/_quickadd.html +50 −0
  • internal/calendar/templates/_quickpane.html +56 −0
  • internal/calendar/templates/agenda.html +42 −0
  • internal/calendar/templates/book_gone.html +11 −0
  • internal/calendar/templates/book_hold.html +22 −0
  • internal/calendar/templates/book_manage.html +27 −0
  • internal/calendar/templates/book_page.html +77 −0
  • internal/calendar/templates/book_sent.html +16 −0
  • internal/calendar/templates/booking_page_form.html +69 −0
  • internal/calendar/templates/booking_pages.html +67 −0
  • internal/calendar/templates/calendars.html +24 −0
  • internal/calendar/templates/day.html +69 −0
  • internal/calendar/templates/errors.html +2 −1
  • internal/calendar/templates/event.html +114 −0
  • internal/calendar/templates/event_delete.html +41 −0
  • internal/calendar/templates/event_form.html +133 −0
  • internal/calendar/templates/home.html +1 −0
  • internal/calendar/templates/import.html +34 −0
  • internal/calendar/templates/import_done.html +41 −0
  • internal/calendar/templates/index.html +0 −3
  • internal/calendar/templates/layout.html +68 −6
  • internal/calendar/templates/mail/cancelled_booker.txt +3 −0
  • internal/calendar/templates/mail/cancelled_host.txt +5 −0
  • internal/calendar/templates/mail/confirmed.txt +9 −0
  • internal/calendar/templates/mail/hold.txt +7 −0
  • internal/calendar/templates/mail/rescheduled_booker.txt +7 −0
  • internal/calendar/templates/mail/rescheduled_host.txt +3 −0
  • internal/calendar/templates/month.html +57 −0
  • internal/calendar/templates/settings.html +61 −0
  • internal/calendar/templates/share.html +52 −0
  • internal/calendar/templates/signin.html +31 −0
  • internal/calendar/templates/week.html +66 −0
  • internal/calendar/testing.go +215 −0
  • internal/calendar/theme.go +106 −0
  • internal/calendar/validate.go +118 −0
  • internal/calendar/viewdata.go +244 −0
  • internal/calendar/viewer.go +29 −0
  • internal/calendar/viewmonth.go +249 −0
  • internal/calendar/zones.go +131 −0
  • internal/calendartest/auth_test.go +146 −0
  • internal/calendartest/avail_test.go +225 −0
  • internal/calendartest/booking_abuse_test.go +106 −0
  • internal/calendartest/booking_flow_test.go +290 −0
  • internal/calendartest/booking_handle_test.go +64 −0
  • internal/calendartest/booking_host_test.go +189 −0
  • internal/calendartest/booking_http_test.go +279 −0
  • internal/calendartest/booking_mail_test.go +238 −0
  • internal/calendartest/booking_review2_test.go +263 −0
  • internal/calendartest/booking_review_test.go +92 −0
  • internal/calendartest/booking_settings_test.go +181 −0
  • internal/calendartest/booking_store_test.go +261 −0
  • internal/calendartest/booking_sweep_test.go +124 −0
  • internal/calendartest/browser_test.go +114 −23
  • internal/calendartest/clock_test.go +128 −0
  • internal/calendartest/delivery_test.go +298 −0
  • internal/calendartest/events_test.go +262 −0
  • internal/calendartest/harness_test.go +47 −27
  • internal/calendartest/ics_test.go +215 −0
  • internal/calendartest/index_test.go +19 −14
  • internal/calendartest/migrate_test.go +70 −0
  • internal/calendartest/occurrence_strict_test.go +154 −0
  • internal/calendartest/occurrence_test.go +265 −0
  • internal/calendartest/playwright_booking_test.go +93 −0
  • internal/calendartest/playwright_test.go +134 −0
  • internal/calendartest/quickadd_http_test.go +200 −0
  • internal/calendartest/quickadd_test.go +285 −0
  • internal/calendartest/recur_engine_test.go +144 −0
  • internal/calendartest/recur_test.go +206 −0
  • internal/calendartest/reminder_test.go +183 −0
  • internal/calendartest/slots_busy_test.go +125 −0
  • internal/calendartest/slots_dst_test.go +105 −0
  • internal/calendartest/slots_test.go +176 −0
  • internal/calendartest/summary_test.go +115 −0
  • internal/calendartest/tick_test.go +65 −0
  • internal/calendartest/zone_test.go +51 −0
  • internal/guardstest/guards_test.go +254 −0
  • package.json +12 −0
  • test/browser/booking.mjs +115 −0
  • test/browser/quickadd.mjs +210 −0

CI passed — run details

.gitignore

Loading diff…

.impeccable/config.json

Loading diff…

.impeccable/hook.cache.json

Loading diff…

AGENTS.md

Loading diff…

Makefile

Loading diff…

PRODUCT.md

Loading diff…

README.md

Loading diff…

cmd/calendar/main.go

Loading diff…

docs/superpowers/brainstorms/2026-09-02-calendar-brainstorm.md

Loading diff…

docs/superpowers/plans/2026-09-07-booking-plan.md

Loading diff…

docs/superpowers/specs/2026-09-02-calendar-design.md

Loading diff…

docs/superpowers/specs/2026-09-02-quick-add-design.md

Loading diff…

docs/superpowers/specs/2026-09-07-booking-design.md

Loading diff…

go.mod

Loading diff…

go.sum

Loading diff…

internal/calendar/app.go

Loading diff…

internal/calendar/auth.go

Loading diff…

internal/calendar/avail.go

Loading diff…

internal/calendar/avail_describe.go

Loading diff…

internal/calendar/booking_ics.go

Loading diff…

internal/calendar/booking_mail.go

Loading diff…

internal/calendar/booking_public.go

Loading diff…

internal/calendar/clock.go

Loading diff…

internal/calendar/config.go

Loading diff…

internal/calendar/funcs.go

Loading diff…

internal/calendar/handlers.go

Loading diff…

internal/calendar/handlers_booking_form.go

Loading diff…

internal/calendar/handlers_booking_manage.go

Loading diff…

internal/calendar/handlers_booking_public.go

Loading diff…

internal/calendar/handlers_booking_settings.go

Loading diff…

internal/calendar/handlers_booking_util.go

Loading diff…

internal/calendar/handlers_event_delete.go

Loading diff…

internal/calendar/handlers_event_form.go

Loading diff…

internal/calendar/handlers_events.go

Loading diff…

internal/calendar/handlers_jobs.go

Loading diff…

internal/calendar/handlers_jobs_budget.go

Loading diff…

internal/calendar/handlers_misc.go

Loading diff…

internal/calendar/handlers_quick.go

Loading diff…

internal/calendar/handlers_settings.go

Loading diff…

internal/calendar/handlers_views.go

Loading diff…

internal/calendar/home.go

Loading diff…

internal/calendar/home_router_test.go

Loading diff…

internal/calendar/home_security_test.go

Loading diff…

internal/calendar/ics_export.go

Loading diff…

internal/calendar/ics_import.go

Loading diff…

internal/calendar/ics_parse.go

Loading diff…

internal/calendar/logsafe.go

Loading diff…

internal/calendar/logsafe_test.go

Loading diff…

internal/calendar/mail_bounded.go

Loading diff…

internal/calendar/mail_bounded_test.go

Loading diff…

internal/calendar/migrations.go

Loading diff…

internal/calendar/migrations/0001_create_people.sql

Loading diff…

internal/calendar/migrations/0001_init.sql

Loading diff…

internal/calendar/migrations/0002_alter_people.sql

Loading diff…

internal/calendar/migrations/0003_alter_reminders.sql

Loading diff…

internal/calendar/migrations/0004_create_attendees.sql

Loading diff…

internal/calendar/migrations/0005_alter_people.sql

Loading diff…

internal/calendar/migrations/0006_alter_reminder_queues.sql

Loading diff…

internal/calendar/migrations/schema.sql

Loading diff…

internal/calendar/models.go

Loading diff…

internal/calendar/models_attendee.go

Loading diff…

internal/calendar/models_booking.go

Loading diff…

internal/calendar/models_event.go

Loading diff…

internal/calendar/occurrences.go

Loading diff…

internal/calendar/occurrences_step.go

Loading diff…

internal/calendar/pack.go

Loading diff…

internal/calendar/person.go

Loading diff…

internal/calendar/quickadd.go

Loading diff…

internal/calendar/quickadd_range.go

Loading diff…

internal/calendar/quickadd_when.go

Loading diff…

internal/calendar/quickadd_who.go

Loading diff…

internal/calendar/recur.go

Loading diff…

internal/calendar/render.go

Loading diff…

internal/calendar/repeat.go

Loading diff…

internal/calendar/routes.go

Loading diff…

internal/calendar/seal/fingerprint.go

Loading diff…

internal/calendar/seal/seal.go

Loading diff…

internal/calendar/slots.go

Loading diff…

internal/calendar/static/booking.js

Loading diff…

internal/calendar/static/calendar.css

Loading diff…

internal/calendar/static/quickadd.js

Loading diff…

internal/calendar/store.go

Loading diff…

internal/calendar/store_attendee.go

Loading diff…

internal/calendar/store_booking_cancel.go

Loading diff…

internal/calendar/store_booking_confirm.go

Loading diff…

internal/calendar/store_booking_flow.go

Loading diff…

internal/calendar/store_booking_handle.go

Loading diff…

internal/calendar/store_booking_hold_util.go

Loading diff…

internal/calendar/store_booking_mail.go

Loading diff…

internal/calendar/store_booking_page.go

Loading diff…

internal/calendar/store_booking_page_read.go

Loading diff…

internal/calendar/store_booking_read.go

Loading diff…

internal/calendar/store_booking_sweep.go

Loading diff…

internal/calendar/store_calendar.go

Loading diff…

internal/calendar/store_drain.go

Loading diff…

internal/calendar/store_event.go

Loading diff…

internal/calendar/store_event_read.go

Loading diff…

internal/calendar/store_event_write.go

Loading diff…

internal/calendar/store_feed.go

Loading diff…

internal/calendar/store_override.go

Loading diff…

internal/calendar/store_range.go

Loading diff…

internal/calendar/store_reminder.go

Loading diff…

internal/calendar/store_reminder_next.go

Loading diff…

internal/calendar/store_slots.go

Loading diff…

internal/calendar/summary.go

Loading diff…

internal/calendar/templates/_bookingpane.html

Loading diff…

internal/calendar/templates/_chip.html

Loading diff…

internal/calendar/templates/_quickadd.html

Loading diff…

internal/calendar/templates/_quickpane.html

Loading diff…

internal/calendar/templates/agenda.html

Loading diff…

internal/calendar/templates/book_gone.html

Loading diff…

internal/calendar/templates/book_hold.html

Loading diff…

internal/calendar/templates/book_manage.html

Loading diff…

internal/calendar/templates/book_page.html

Loading diff…

internal/calendar/templates/book_sent.html

Loading diff…

internal/calendar/templates/booking_page_form.html

Loading diff…

internal/calendar/templates/booking_pages.html

Loading diff…

internal/calendar/templates/calendars.html

Loading diff…

internal/calendar/templates/day.html

Loading diff…

internal/calendar/templates/errors.html

Loading diff…

internal/calendar/templates/event.html

Loading diff…

internal/calendar/templates/event_delete.html

Loading diff…

internal/calendar/templates/event_form.html

Loading diff…

internal/calendar/templates/home.html

Loading diff…

internal/calendar/templates/import.html

Loading diff…

internal/calendar/templates/import_done.html

Loading diff…

internal/calendar/templates/index.html

Loading diff…

internal/calendar/templates/layout.html

Loading diff…

internal/calendar/templates/mail/cancelled_booker.txt

Loading diff…

internal/calendar/templates/mail/cancelled_host.txt

Loading diff…

internal/calendar/templates/mail/confirmed.txt

Loading diff…

internal/calendar/templates/mail/hold.txt

Loading diff…

internal/calendar/templates/mail/rescheduled_booker.txt

Loading diff…

internal/calendar/templates/mail/rescheduled_host.txt

Loading diff…

internal/calendar/templates/month.html

Loading diff…

internal/calendar/templates/settings.html

Loading diff…

internal/calendar/templates/share.html

Loading diff…

internal/calendar/templates/signin.html

Loading diff…

internal/calendar/templates/week.html

Loading diff…

internal/calendar/testing.go

Loading diff…

internal/calendar/theme.go

Loading diff…

internal/calendar/validate.go

Loading diff…

internal/calendar/viewdata.go

Loading diff…

internal/calendar/viewer.go

Loading diff…

internal/calendar/viewmonth.go

Loading diff…

internal/calendar/zones.go

Loading diff…

internal/calendartest/auth_test.go

Loading diff…

internal/calendartest/avail_test.go

Loading diff…

internal/calendartest/booking_abuse_test.go

Loading diff…

internal/calendartest/booking_flow_test.go

Loading diff…

internal/calendartest/booking_handle_test.go

Loading diff…

internal/calendartest/booking_host_test.go

Loading diff…

internal/calendartest/booking_http_test.go

Loading diff…

internal/calendartest/booking_mail_test.go

Loading diff…

internal/calendartest/booking_review2_test.go

Loading diff…

internal/calendartest/booking_review_test.go

Loading diff…

internal/calendartest/booking_settings_test.go

Loading diff…

internal/calendartest/booking_store_test.go

Loading diff…

internal/calendartest/booking_sweep_test.go

Loading diff…

internal/calendartest/browser_test.go

Loading diff…

internal/calendartest/clock_test.go

Loading diff…

internal/calendartest/delivery_test.go

Loading diff…

internal/calendartest/events_test.go

Loading diff…

internal/calendartest/harness_test.go

Loading diff…

internal/calendartest/ics_test.go

Loading diff…

internal/calendartest/index_test.go

Loading diff…

internal/calendartest/migrate_test.go

Loading diff…

internal/calendartest/occurrence_strict_test.go

Loading diff…

internal/calendartest/occurrence_test.go

Loading diff…

internal/calendartest/playwright_booking_test.go

Loading diff…

internal/calendartest/playwright_test.go

Loading diff…

internal/calendartest/quickadd_http_test.go

Loading diff…

internal/calendartest/quickadd_test.go

Loading diff…

internal/calendartest/recur_engine_test.go

Loading diff…

internal/calendartest/recur_test.go

Loading diff…

internal/calendartest/reminder_test.go

Loading diff…

internal/calendartest/slots_busy_test.go

Loading diff…

internal/calendartest/slots_dst_test.go

Loading diff…

internal/calendartest/slots_test.go

Loading diff…

internal/calendartest/summary_test.go

Loading diff…

internal/calendartest/tick_test.go

Loading diff…

internal/calendartest/zone_test.go

Loading diff…

internal/guardstest/guards_test.go

Loading diff…

package.json

Loading diff…

test/browser/booking.mjs

Loading diff…

test/browser/quickadd.mjs

Loading diff…