"""Token value objects — framework-free. The auth flow issues a short-lived *access* token and a long-lived *refresh* token (offline-first: clients may stay disconnected for weeks). Refresh tokens are persisted and revocable (see :class:`~app.domain.ports.RefreshTokenRepository`); access tokens are stateless and verified by signature + expiry alone. """ import datetime as dt import enum import uuid from dataclasses import dataclass class TokenType(enum.StrEnum): ACCESS = "access" REFRESH = "refresh" @dataclass(frozen=True, slots=True) class TokenClaims: """Decoded, verified claims from a JWT.""" subject: uuid.UUID # user id (``sub``) token_type: TokenType jti: uuid.UUID expires_at: dt.datetime @dataclass(frozen=True, slots=True) class IssuedToken: """A freshly minted token: the encoded string plus the metadata needed to persist/track it (jti, expiry).""" encoded: str jti: uuid.UUID expires_at: dt.datetime @dataclass(frozen=True, slots=True) class TokenPair: """The access + refresh pair returned to clients on login/refresh.""" access: IssuedToken refresh: IssuedToken