Flutter client posts FlutterTimezone.getLocalTimezone() to
PUT /api/me/timezone on every setSession (login / register success)
and on every AuthController.build (app cold-start with valid
session), when the locally-stored tz_last_sent_at is >7 days old.
Cadence tracked in flutter_secure_storage so it survives app
restarts.
Failures swallowed: the server's UTC default + last-known value
keep the scheduler functioning until the next attempt.
Completes the client side of #392 Half B (per-user timezone
scheduling).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Cold launch flow: no server-url -> /server-url. URL set, no token ->
/login. Token present -> /home with shell. VersionGate runs once when
the URL changes, hits /healthz, blocks if min_client_version > package
version. /home is a placeholder until Task 14.
Replaces Navigator.pushReplacementNamed in server_url_screen +
login_screen with context.go now that go_router owns the routes.
Login uses a non-authenticated dio (token resolver returns null) since
we don't have one yet. On success, setSession persists token + user
into secure storage and the AuthController state flips, which the
router watches to navigate.
AuthController is an AsyncNotifier holding the currently-logged-in
User. server_url, session_token, current_user all live in
flutter_secure_storage. ServerUrlScreen probes /healthz before saving
the URL so we don't store a bogus base.