AppViewModel.startDestination chose onboarding-vs-mailbox purely by
account count, so a user upgrading from a pre-#172 install (accounts
present, licenseAccepted=false) went straight to the mailbox and never
saw the license screen — the license is only the onboarding graph's
start destination. Route to ONBOARDING whenever the license is
unaccepted, even when accounts exist; only an accepted user with an
account lands on the mailbox.
Once such a user accepts, send them straight to their inbox rather than
ONBOARDING_WELCOME ("add your first account"), which would strand a user
who already has accounts. AppViewModel now also exposes hasAccounts for
that post-accept routing decision.
Also guard the pendingCompose mailto/share deep-link with the same
start != ONBOARDING check pendingOpenMessageId already uses, so a
deep-link can't jump past the license gate either.
From the post-batch security review, refs #172.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>