- Restore 60s baseline polling (was regressed to false)
- Extract getConnectionMeta helper to eliminate 5 inline casts
- Remove unnecessary containerTags intersection casts
- Deduplicate provider title maps into shared PROVIDER_DISPLAY_NAMES
- Fix formatRelativeTime: handle future dates, add minutes tier
- Preserve auth/expired state in SyncStatusBadge (red Disconnected)
- Disable sync button for expired connections
- Fix mobile width overflow on sync history sheet
- Add smart polling to useSyncRuns when a run is running
- Add clarifying comment on connectionId in useTriggerSync
- Replace z.any() with z.unknown() for import endpoint output
- Remove unnecessary 'use client' from sync-status-badge
- Add SyncStatusBadge component showing syncing/synced/idle status
- Add SyncHistorySheet with sync run history (status, trigger, items, errors)
- Add useSyncRuns and useTriggerSync hooks
- Add sync-runs and import endpoints to API schema
- Update ConnectionRow with sync status, sync now button, history button
- Add conditional polling (5s when syncing, stop when idle)
- Extract shared formatRelativeTime utility
The subscription check on plugins, connections, and usage pages was hardcoded to only look at `api_pro`. Users on scale or enterprise plans saw "Upgrade to Pro" and couldn't create plugin keys or manage connections.
Also, the check only looked at product `status` but not the `allowed` flag from autumn — so users who downgraded but were still in their billing period got locked out early.