feat(messages): счётчики упоминаний, квота приглашений и read state автора
- упоминания в сообщении увеличивают счётчик упоминаний комнаты у упомянутых (store.BumpMentionCount) и отправляют им READ_STATE_UPDATE на все устройства; - отправка сообщения отмечает его прочитанным для автора; - подтверждение прочтения сбрасывает упоминания; - суточная квота 10 приглашений на пользователя (AGENT.md 8.6), администратор инстанса её обходит; httpx.NewRateLimiterWindow для произвольных окон; - тест на рост и сброс счётчика упоминаний.
This commit is contained in:
@@ -274,6 +274,24 @@ func (s *Store) SetReadState(ctx context.Context, userID, channelID, lastMessage
|
||||
return err
|
||||
}
|
||||
|
||||
// BumpMentionCount увеличивает счётчик упоминаний пользователя в комнате и
|
||||
// возвращает новое значение (AGENT.md 7.16).
|
||||
func (s *Store) BumpMentionCount(ctx context.Context, userID, channelID uint64) (int, error) {
|
||||
var count int
|
||||
err := s.writer.QueryRowContext(ctx, `
|
||||
INSERT INTO channel_read_states (user_id, channel_id, last_message_id, mention_count, updated_at)
|
||||
VALUES (?, ?, 0, 1, ?)
|
||||
ON CONFLICT (user_id, channel_id) DO UPDATE SET
|
||||
mention_count = channel_read_states.mention_count + 1,
|
||||
updated_at = excluded.updated_at
|
||||
RETURNING mention_count`,
|
||||
int64(userID), int64(channelID), s.Now()).Scan(&count)
|
||||
if err != nil {
|
||||
return 0, mapError(err)
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// ListReadStates отдаёт состояния прочтения пользователя (для READY).
|
||||
func (s *Store) ListReadStates(ctx context.Context, userID uint64) ([]ReadState, error) {
|
||||
rows, err := s.reader.QueryContext(ctx, `
|
||||
|
||||
Reference in New Issue
Block a user