Calendar sync: user page and developer guide
Two new pages for the tickets -> calendar sync work, following the
usual Foo / Foo-Developer-Guide split.
Ticket-Calendar-Sync.md - the choices, plainly: subscription link vs
Microsoft 365 and what each actually buys, setting up a link and adding
it in Outlook/Google/Apple, the Azure connection and how far
Calendars.ReadWrite really reaches, which mailbox belongs to whom, what
each analyst switches on themselves, changes coming back from Outlook,
the scheduled job compared with notifications and why notifications
never replace it, reading the health strip, and a troubleshooting table.
Ticket-Calendar-Sync-Developer-Guide.md - the file table, the three
tables and two ticket columns, the provider contract and why the two
"missing" exceptions are classes rather than error strings, why the push
reconciles rather than reacts, the three guards on the pull, the
subscription lifecycle, ICS specifics, and the time handling.
The traps worth having written down:
- db_verify creates COLUMNS ONLY. Both new tables need UNIQUE keys for
their ON DUPLICATE KEY UPDATE writes; fresh installs were fine and
upgraded ones silently accumulated duplicates.
- An unguarded new column broke opening ANY ticket pre-db_verify. The
feature you add is not the feature that breaks.
- request_guard.php answers 415 to text/plain, which is exactly what
Graph's subscription handshake sends - so the handshake must run
BEFORE the require lines, and testing it with a GET proves nothing.
- Echo suppression is by comparison, not by marker.
- Naive wall-clock values must never round-trip through toISOString(),
and a timezone assertion written in March cannot fail.
- `let` at a script's top level is not a window property, so a harness
reading it gets undefined - which can read as a PASS.
- dragTicketId cannot guard the drag save; dragend fires on mouse
release, long before the server answers.
Sidebar entry under Tickets, plus cross-links from Tickets.md (the
Calendar section) and Calendar.md (making clear the module and the
ticket scheduling calendar are separate mechanisms).
Every cross-reference verified against an existing page, and every file
named in the developer guide's table verified to exist.