First commit in the session-expiration-policy series (see
docs/plans/2026-05-13-session-expiration-policy.md). No behavior change
yet — this lays the schema + settings groundwork only.
- Settings: SESSION_IDLE_MINUTES_DEFAULT=4320 (3d),
SESSION_ABSOLUTE_MINUTES_DEFAULT=20160 (14d), plus MIN/MAX bounds
so account overrides have envelopes (15min..30d idle, 1h..90d
absolute).
- accounts table: nullable session_idle_minutes and
session_absolute_minutes columns (NULL = use system default), plus
a CHECK constraint that rejects idle > absolute when both are set.
Partial-override validation lives at the app layer because the DB
cannot read Settings.
Subsequent commits will: distinguish idle vs invalid-token expiry on
the wire, embed auth_time/idle_max/abs_max in refresh JWTs, enforce
the absolute cap in /auth/refresh, add the owner-only policy +
bulk-revoke endpoints, and surface everything in an AccountSecurity
settings page with a session-expiry toast.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>