feat(messages): команды чата, личные сообщения и лимиты

AGENT.md 7.6:

- команды разбираются на сервере: /me (блок действия), /whisper и /wisper
  (шёпот), /scream (громкий блок), «//» экранирует слэш, неизвестная команда
  остаётся обычным текстом, пустой текст у команды — 422;
- /ls <логин> <текст> — личное сообщение: тип private, адресат в mentions,
  получатель проверяется на участие в сервере и доступ к комнате; сообщение не
  отдаётся посторонним ни в истории, ни в поиске (и FTS, и подстрочном) и
  доставляется в Gateway только автору и адресатам;
- лимиты: 10 правок в минуту, 20 уникальных реакций на сообщение, 50
  закреплений на комнату, не более 10 упоминаний, @everyone/@here только с
  MENTION_EVERYONE;
- тесты: команды и экранирование, изоляция личного сообщения (история, поиск,
  третий участник), лимит правок и @everyone.
This commit is contained in:
2026-09-20 11:32:50 +03:00
parent 4c8f888b3e
commit 65d0bafe0e
11 changed files with 1556 additions and 210 deletions
+3
View File
@@ -51,6 +51,8 @@ type Server struct {
messageLimiter *httpx.RateLimiter
typingLimiter *httpx.RateLimiter
searchLimiter *httpx.RateLimiter
// editLimiter — 10 правок сообщений в минуту (AGENT.md 7.6).
editLimiter *httpx.RateLimiter
// inviteLimiter — 10 приглашений в сутки на пользователя (AGENT.md 8.6).
inviteLimiter *httpx.RateLimiter
// slowmode — время последней отправки в комнату для режима медленной
@@ -83,6 +85,7 @@ func New(cfg config.Config, db *database.DB, logger *slog.Logger, deps Deps) *Se
messageLimiter: httpx.NewRateLimiter(60, 10),
typingLimiter: httpx.NewRateLimiter(20, 1),
searchLimiter: httpx.NewRateLimiter(10, 10),
editLimiter: httpx.NewRateLimiter(10, 10),
inviteLimiter: httpx.NewRateLimiterWindow(10, 24*time.Hour, 10),
slowmode: map[string]time.Time{},
presence: map[uint64]time.Time{},