-- Токен: PK — текстовый hash (хеш токена, не сам токен в открытом виде). -- owner_id — владелец/источник (ранее денормализованное поле app_name). -- read_limit — разрешённое число обращений (0 = без лимита); read_used — уже израсходовано. CREATE TABLE token.token ( hash varchar(256) not null primary key, type_id int not null references token.token_type (id), owner_id int not null references token.owner (id), date_created timestamptz not null, date_expired timestamptz not null, date_last_read timestamptz null, data text not null, lifetime_seconds int not null, is_slide_expiration boolean not null, read_limit int not null default 0, read_used int not null default 0, is_active boolean not null, date_revoked timestamptz null, revoke_reason varchar(250) null, CONSTRAINT chk_token_lifetime CHECK (lifetime_seconds > 0), CONSTRAINT chk_token_reads CHECK (read_used >= 0 AND (read_limit = 0 OR read_used <= read_limit)), CONSTRAINT chk_token_expired CHECK (date_expired >= date_created) ); -- Индексы под фильтры token_select и фоновую чистку просроченных. CREATE INDEX ix_token_owner ON token.token (owner_id); CREATE INDEX ix_token_expired ON token.token (date_expired); CREATE INDEX ix_token_active_type ON token.token (is_active, type_id);