bot: модель данных и миграции #5

Closed
opened 2026-10-12 19:32:41 +03:00 by Eleboba · 1 comment
Owner

Описание

Таблицы из ARCHITECTURE §2.10 (v2): users, invites, access_attempts, fsm_state, drafts, draft_changes, pushes, pipeline_runs, container_snapshots, alerts, alert_deliveries, log_queries, agent_requests.

Желаемый результат

  • Alembic-миграция создаёт все таблицы; применяется при старте контейнера.
  • Async-сессии; Postgres в проде, SQLite в тестах.

Подзадачи

  • app/bot/fsm_storage.py — FSM-хранилище aiogram поверх таблицы fsm_state (перенесено из #4), подключить в app/bot/fsm.py::make_storage; тест: состояние переживает пересоздание Dispatcher
  • app/db/models.py
  • app/db/session.py
  • Alembic: alembic.ini, app/db/migrations/, первая ревизия
  • Индексы: invites.token_hash, pushes.sha, alerts(kind, service, resolved_at)
  • Тест миграции up/down на SQLite

Анализ

Затрагиваемые файлы

Файл Что меняется
app/db/ новый пакет
alembic.ini новый

Ограничения и риски

tg_id — BIGINT. Содержимое черновика — BYTEA (≤ 100 КБ на файл). TTL-таблицы (container_snapshots, черновики) чистит фоновая задача.

Как проверить

make test; alembic upgrade head && alembic downgrade base на чистой БД.


Лог выполнения

2026-10-13

  • Задача переписана под SPEC v2 (QR-доступ, меню из 4 разделов, командная модель — ADR-011…013).

2026-10-14

  • app/db/models.py — 13 таблиц; перечисления VARCHAR + CHECK (create_constraint=True — в SQLAlchemy 2 без этого CHECK не создаётся), JSON → JSONB на Postgres, BIGINT/INTEGER-ключи. В pipeline_runs поле stage (ci/cd) вместо workflow: в tgit-uploads CI и CD — задачи одного workflow (ARCHITECTURE поправлен).
  • Миграция 0001 автогенерацией + ручная чистка: импорт sa.Text для JSONB, удалены 18 дублей CHECK (колонка Enum создаёт свой).
  • Миграции применяются при старте бота программно (app.db.migrate, script_location = app.db:migrations — работает из site-packages). CLI: alembic.ini.
  • SqlStorage — FSM поверх fsm_state (перенесено из #4), подключён в make_storage. Тест поймал баг: state.clear() на несуществующий ключ пытался удалить несохранённую строку — /start упал бы в проде.
  • cleanup_loop раз в час: истёкшие черновики, снимки контейнеров и попытки входа старше суток.
  • Тесты (30, покрытие 89 %): upgrade/downgrade, дрейф моделей ↔ миграций, CHECK, CASCADE, FSM переживает новое хранилище, чистка.
  • Postgres 16 из Compose (в образе бота): 13 таблиц, CHECK ck_users_role отклоняет root, jsonb/bigint, дрейфа нет, downgrade base → upgrade head ✅.
## Описание Таблицы из [ARCHITECTURE](https://gitea.24studbank.ru/HSE/tgit/src/branch/dev/docs/ARCHITECTURE.md) §2.10 (v2): users, invites, access_attempts, fsm_state, drafts, draft_changes, pushes, pipeline_runs, container_snapshots, alerts, alert_deliveries, log_queries, agent_requests. ## Желаемый результат - Alembic-миграция создаёт все таблицы; применяется при старте контейнера. - Async-сессии; Postgres в проде, SQLite в тестах. ## Подзадачи - [x] `app/bot/fsm_storage.py` — FSM-хранилище aiogram поверх таблицы `fsm_state` (перенесено из #4), подключить в `app/bot/fsm.py::make_storage`; тест: состояние переживает пересоздание Dispatcher - [x] `app/db/models.py` - [x] `app/db/session.py` - [x] Alembic: `alembic.ini`, `app/db/migrations/`, первая ревизия - [x] Индексы: `invites.token_hash`, `pushes.sha`, `alerts(kind, service, resolved_at)` - [x] Тест миграции up/down на SQLite ## Анализ ### Затрагиваемые файлы | Файл | Что меняется | |------|--------------| | `app/db/` | новый пакет | | `alembic.ini` | новый | ### Ограничения и риски `tg_id` — BIGINT. Содержимое черновика — BYTEA (≤ 100 КБ на файл). TTL-таблицы (`container_snapshots`, черновики) чистит фоновая задача. ## Как проверить `make test`; `alembic upgrade head && alembic downgrade base` на чистой БД. --- ## Лог выполнения ### 2026-10-13 - Задача переписана под SPEC v2 (QR-доступ, меню из 4 разделов, командная модель — ADR-011…013). ### 2026-10-14 - `app/db/models.py` — 13 таблиц; перечисления VARCHAR + CHECK (`create_constraint=True` — в SQLAlchemy 2 без этого CHECK не создаётся), JSON → JSONB на Postgres, BIGINT/INTEGER-ключи. В `pipeline_runs` поле `stage` (`ci`/`cd`) вместо `workflow`: в `tgit-uploads` CI и CD — задачи одного workflow (ARCHITECTURE поправлен). - Миграция `0001` автогенерацией + ручная чистка: импорт `sa.Text` для JSONB, удалены 18 дублей CHECK (колонка Enum создаёт свой). - Миграции применяются при старте бота программно (`app.db.migrate`, `script_location = app.db:migrations` — работает из site-packages). CLI: `alembic.ini`. - `SqlStorage` — FSM поверх `fsm_state` (перенесено из #4), подключён в `make_storage`. Тест поймал баг: `state.clear()` на несуществующий ключ пытался удалить несохранённую строку — `/start` упал бы в проде. - `cleanup_loop` раз в час: истёкшие черновики, снимки контейнеров и попытки входа старше суток. - Тесты (30, покрытие 89 %): upgrade/downgrade, **дрейф моделей ↔ миграций**, CHECK, CASCADE, FSM переживает новое хранилище, чистка. - **Postgres 16 из Compose** (в образе бота): 13 таблиц, CHECK `ck_users_role` отклоняет `root`, `jsonb`/`bigint`, дрейфа нет, downgrade base → upgrade head ✅.
Eleboba added this to the M1 · MVP: загрузка → коммит → CI milestone 2026-10-12 19:32:41 +03:00
Eleboba added the botfeaturesize/1 labels 2026-10-12 19:32:41 +03:00
Eleboba self-assigned this 2026-10-12 19:32:41 +03:00
Eleboba changed title from bot: модель данных, миграции и доступ по белому списку to bot: модель данных и миграции 2026-10-13 22:52:27 +03:00
Author
Owner

Смержено в dev через PR #32 (282920e) — закрываю.

Смержено в `dev` через PR #32 (282920e) — закрываю.
Sign in to join this conversation.