Первый коммит: модульный монолит ядра (.NET 10) и gRPC-сервисы ai/ml/telegram, фронтенд Vue 3/Vite/Tailwind, документация (ТЗ, инструкция пользователя, техдокументация, код-стайл), бэклог, скрипты развёртывания и архив прототипа LeadRadar.
34 lines
1.6 KiB
Markdown
34 lines
1.6 KiB
Markdown
### Task 2: BanGuard (квоты, паузы, flood)
|
|
|
|
**Files:**
|
|
- Create: `backend/app/services/ban_guard.py`
|
|
|
|
**Interfaces:**
|
|
- Consumes: `store`, настройки из Task 1.
|
|
- Produces:
|
|
- `def joins_today_auto() -> int` — авто-вступления за текущие UTC-сутки (считает `disc_log` event='join_auto', `created_at >= начало суток`).
|
|
- `def can_auto_join() -> bool` — лимит не исчерпан И нет flood-блокировки на сегодня И нет глобальной паузы.
|
|
- `async def wait_join_delay() -> None` — `asyncio.sleep(random.uniform(min, max))`.
|
|
- `def note_flood() -> None` — `store.set_setting("discFloodDay", <start_of_day_ms>)`.
|
|
- `def flood_today() -> bool`
|
|
- `def global_paused() -> bool` / `def set_global_pause(v: bool) -> None` (setting `discPaused`)
|
|
- `def search_pause() -> float` — `random.uniform(2.0, 4.0)`.
|
|
|
|
- [ ] **Step 1: Реализовать модуль** (~60 строк; начало суток — UTC: `datetime.now(timezone.utc).replace(hour=0,minute=0,second=0,microsecond=0)` → ms).
|
|
|
|
- [ ] **Step 2: Проверить на временной БД в контейнере**
|
|
|
|
```bash
|
|
docker compose run --rm --no-deps -e PYTHONPATH=/srv -e LEADRADAR_DATA=/tmp/lr_bg --entrypoint python app -c "
|
|
from app.db import store; store.init()
|
|
from app.services import ban_guard as bg
|
|
assert bg.can_auto_join() is True
|
|
assert bg.joins_today_auto() == 0
|
|
bg.note_flood(); assert bg.flood_today() is True
|
|
bg.set_global_pause(True); assert bg.can_auto_join() is False
|
|
print('BANGUARD OK')
|
|
"
|
|
```
|
|
|
|
---
|