feat(bot): модель данных, миграции Alembic, FSM в БД, TTL-чистка

- app/db/models.py: 13 таблиц (ARCHITECTURE §2.10); перечисления — VARCHAR + CHECK,
  JSON → JSONB на Postgres, BIGINT/INTEGER-ключи для SQLite
- миграция 0001 (автогенерация + ручная чистка: импорт sa.Text, дубли CHECK)
- миграции применяются при старте бота программно (app.db.migrate), script_location из пакета
- SqlStorage: FSM aiogram поверх fsm_state — состояние переживает рестарт (перенесено из #4)
- cleanup_loop: истёкшие черновики, снимки контейнеров и попытки входа старше суток
- тесты: upgrade/downgrade, дрейф моделей и миграций, CHECK, CASCADE, FSM, чистка

Refs #5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-15 18:45:16 +03:00
co-authored by Claude Opus 5.5
parent b70797c805
commit 282920e06b
24 changed files with 1071 additions and 16 deletions
+3 -2
View File
@@ -4,6 +4,7 @@ from aiogram.types import InlineKeyboardMarkup, ReplyKeyboardMarkup
from app.bot.menu import Nav, NavAction
from app.config import Settings
from app.db.session import SessionMaker
from app.main import build_dispatcher
from app.texts import Texts
from tests.conftest import ADMIN, OUTSIDER
@@ -11,8 +12,8 @@ from tests.fakes import TgClient
@pytest.fixture
def tg(settings: Settings, texts: Texts) -> TgClient:
return TgClient(build_dispatcher(settings, texts))
def tg(settings: Settings, texts: Texts, sessions: SessionMaker) -> TgClient:
return TgClient(build_dispatcher(settings, texts, sessions))
def buttons(markup: ReplyKeyboardMarkup) -> list[str]: