Таблицы и состояния
На этой странице
В экспортированной структуре 8 таблиц, 193 столбца и 22 индекса. Четыре Data Tables хранят материалы, подборки, карточки и захваты статей. Четыре таблицы collaboration хранят участников, регистрации, аудит и отдельные доставки.
Общий материал и отдельные копии
owner_chat_id остаётся владельцем проекта. created_by_user_id обозначает создателя, operation_actor_user_id/chat_id — инициатора текущей операции, feedback_actor_user_id/feedback_chat_id — держателя сессии правки. Получатель конкретной копии хранится в журнале доставок.
| Объект | Состояния и смысл |
|---|---|
| Готовая версия | awaiting_approval допускает решение актуального участника |
| Доработка | awaiting_feedback закрепляет приглашение за одним участником; новая версия делает прежнюю superseded |
| Публикация | Общий захват publishing предшествует отправке; подтверждение Telegram даёт published |
| Отклонение | rejected сохраняет историю без публикации |
| Доставка | sending до сети; затем sent, rejected, unknown, revoked или not_sent |
Уникальная пара draft/version и ключ исходного события предотвращают повторное создание. Уникальная комбинация purpose/entity_key/recipient_user_id защищает отдельную доставку. Одна транзакция не может одновременно зафиксировать PostgreSQL и Telegram: неизвестный исход требует сверки, а не слепого повтора.
Справочник ниже описывает структуру. Реальных строк материалов, участников или журнала в публичной документации нет.
Актуальные определения получены из information_schema/pg_indexes, пользовательские строки в экспорт не включены. Четыре прежние бизнес-таблицы сохранены; добавлено четыре таблицы совместной работы и 6+3 nullable-колонки Data Tables. В этом исправлении DDL и права БД не менялись. Прежние строки сверены до восстановления; затем изменялась только подтверждённая исходная версия и штатные журналы исполнения/доставки. Актуальные агрегаты см. verification.json.
owner_chat_id — владелец проекта. created_by_user_id — создатель, operation_actor_user_id/chat_id — участник текущей операции, feedback_actor_user_id/chat_id — держатель сессии, delivery_tracking=multiuser_v1 — новый учёт копий. Для старых строк допустим fallback к владельцу.
| Объект | Логическая связь |
|---|---|
| Подборка | Предлагает карточки новостей. |
| Выбор статьи | Закрепляет canonical_url и связывает статью с материалом. |
| Версия материала | Хранит источник, факты, родительскую версию и результат согласования. |
| Исходная иллюстрация | Может использоваться при сборке нескольких обложек. |
| Публикация | Подтверждается message_id в записи версии. |
Связи логические; SQL foreign keys на материалы не добавлялись. Доставка сверяет recipient_user_id + chat_id + message_id + материал/версию. Unique(purpose, entity_key, recipient_user_id) резервирует одну сетевую отправку. Unique role допускает одного владельца и одного редактора. Active=false проверяется заново до внешних действий. Регистрация сама не назначает роль.
Статусы материалов и правила retry/resume сохранены. Ключевые переходы: awaiting_approval → publishing → published / publication_outcome_unknown; awaiting_approval → awaiting_feedback → superseded + новая версия; awaiting_approval → rejected. Переключение пользователя не отменяет guards неизвестного результата. Статусы доставки: sending → sent / rejected / unknown / revoked / not_sent. Состояние sending после аварии также требует сверки, а не повторной отправки.
bfl_collab_audit
| Столбец | Тип | Nullable | Default |
|---|---|---|---|
| id | bigint | NO | — |
| actor_user_id | bigint | YES | — |
| action | text | NO | — |
| draft_key | text | YES | — |
| version | integer | YES | — |
| batch_key | text | YES | — |
| item_key | text | YES | — |
| event_key | text | NO | — |
| result | text | NO | — |
| details | jsonb | NO | '{}'::jsonb |
| created_at | timestamp with time zone | NO | now() |
Индексы:
CREATE INDEX bfl_collab_audit_event ON public.bfl_collab_audit USING btree (event_key);
CREATE UNIQUE INDEX bfl_collab_audit_pkey ON public.bfl_collab_audit USING btree (id);
bfl_collab_deliveries
| Столбец | Тип | Nullable | Default |
|---|---|---|---|
| id | bigint | NO | — |
| purpose | text | NO | — |
| entity_key | text | NO | — |
| recipient_user_id | bigint | NO | — |
| chat_id | bigint | NO | — |
| message_id | bigint | YES | — |
| draft_key | text | YES | — |
| version | integer | YES | — |
| batch_key | text | YES | — |
| item_key | text | YES | — |
| operation_id | text | YES | — |
| actor_user_id | bigint | NO | — |
| event_key | text | NO | — |
| request_hash | text | NO | — |
| state | text | NO | — |
| result | jsonb | YES | — |
| error_code | text | NO | ''::text |
| attempts | integer | NO | 1 |
| buttons_removed | boolean | NO | false |
| created_at | timestamp with time zone | NO | now() |
| updated_at | timestamp with time zone | NO | now() |
Индексы:
CREATE UNIQUE INDEX bfl_collab_deliveries_pkey ON public.bfl_collab_deliveries USING btree (id);
CREATE UNIQUE INDEX bfl_collab_deliveries_purpose_entity_key_recipient_user_id_key ON public.bfl_collab_deliveries USING btree (purpose, entity_key, recipient_user_id);
CREATE INDEX bfl_collab_delivery_copy ON public.bfl_collab_deliveries USING btree (chat_id, message_id) WHERE (state = 'sent'::text);
CREATE INDEX bfl_collab_delivery_draft ON public.bfl_collab_deliveries USING btree (draft_key, version);
bfl_collab_members
| Столбец | Тип | Nullable | Default |
|---|---|---|---|
| telegram_user_id | bigint | NO | — |
| private_chat_id | bigint | NO | — |
| role | text | NO | — |
| active | boolean | NO | false |
| username | text | NO | ''::text |
| receive_batches | boolean | NO | true |
| receive_previews | boolean | NO | true |
| verified_update_id | bigint | YES | — |
| verified_at | timestamp with time zone | NO | now() |
| updated_at | timestamp with time zone | NO | now() |
Индексы:
CREATE UNIQUE INDEX bfl_collab_members_pkey ON public.bfl_collab_members USING btree (telegram_user_id);
CREATE UNIQUE INDEX bfl_collab_members_private_chat_id_key ON public.bfl_collab_members USING btree (private_chat_id);
CREATE UNIQUE INDEX bfl_collab_one_role ON public.bfl_collab_members USING btree (role);
bfl_collab_registrations
| Столбец | Тип | Nullable | Default |
|---|---|---|---|
| telegram_user_id | bigint | NO | — |
| private_chat_id | bigint | NO | — |
| username | text | NO | ''::text |
| update_id | bigint | NO | — |
| seen_at | timestamp with time zone | NO | now() |
| execution_id | text | NO | ''::text |
Индексы:
CREATE UNIQUE INDEX bfl_collab_registrations_pkey ON public.bfl_collab_registrations USING btree (telegram_user_id);
data_table_user_BFLNewsBatchV04
| Столбец | Тип | Nullable | Default |
|---|---|---|---|
| id | integer | NO | — |
| batch_key | text | YES | — |
| owner_chat_id | text | YES | — |
| event_key | text | YES | — |
| origin | text | YES | — |
| topic | text | YES | — |
| window_json | text | YES | — |
| status | text | YES | — |
| created_at | text | YES | — |
| expires_at | text | YES | — |
| response_id | text | YES | — |
| search_urls_json | text | YES | — |
| actual_sources_json | text | YES | — |
| diagnostics_json | text | YES | — |
| status_message_id | text | YES | — |
| operation_id | text | YES | — |
| notification_text | text | YES | — |
| notification_lock | text | YES | — |
| notification_error | text | YES | — |
| notification_state | text | YES | — |
| notification_history | text | YES | — |
| notification_rank | double precision | YES | — |
| notification_retry_after | double precision | YES | — |
| days | double precision | YES | — |
| candidate_count | double precision | YES | — |
| read_count | double precision | YES | — |
| accepted_count | double precision | YES | — |
| partial | double precision | YES | — |
| createdAt | timestamp with time zone | NO | CURRENT_TIMESTAMP(3) |
| updatedAt | timestamp with time zone | NO | CURRENT_TIMESTAMP(3) |
| created_by_user_id | text | YES | — |
| operation_actor_user_id | text | YES | — |
| operation_actor_chat_id | text | YES | — |
Индексы:
CREATE UNIQUE INDEX "PK_8c0793b6be01a7559a9b4cee145" ON public."data_table_user_BFLNewsBatchV04" USING btree (id);
CREATE UNIQUE INDEX bfl_news_batch_event_unique ON public."data_table_user_BFLNewsBatchV04" USING btree (event_key);
CREATE UNIQUE INDEX bfl_news_batch_key_unique ON public."data_table_user_BFLNewsBatchV04" USING btree (batch_key);
data_table_user_BFLNewsClaimV04
| Столбец | Тип | Nullable | Default |
|---|---|---|---|
| id | integer | NO | — |
| selection_key | text | YES | — |
| canonical_url | text | YES | — |
| item_key | text | YES | — |
| batch_key | text | YES | — |
| owner_chat_id | text | YES | — |
| draft_key | text | YES | — |
| stage | text | YES | — |
| source_event_key | text | YES | — |
| createdAt | timestamp with time zone | NO | CURRENT_TIMESTAMP(3) |
| updatedAt | timestamp with time zone | NO | CURRENT_TIMESTAMP(3) |
Индексы:
CREATE UNIQUE INDEX "PK_990ef810376ed844bb58fdfb782" ON public."data_table_user_BFLNewsClaimV04" USING btree (id);
CREATE UNIQUE INDEX bfl_news_claim_item_unique ON public."data_table_user_BFLNewsClaimV04" USING btree (batch_key, item_key);
CREATE UNIQUE INDEX bfl_news_claim_selection_unique ON public."data_table_user_BFLNewsClaimV04" USING btree (selection_key);
CREATE UNIQUE INDEX bfl_news_claim_url_unique ON public."data_table_user_BFLNewsClaimV04" USING btree (canonical_url);
data_table_user_BFLNewsItemV04
| Столбец | Тип | Nullable | Default |
|---|---|---|---|
| id | integer | NO | — |
| item_key | text | YES | — |
| batch_key | text | YES | — |
| owner_chat_id | text | YES | — |
| canonical_url | text | YES | — |
| fact_pack | text | YES | — |
| status | text | YES | — |
| message_id | text | YES | — |
| selected_draft_id | text | YES | — |
| error_code | text | YES | — |
| createdAt | timestamp with time zone | NO | CURRENT_TIMESTAMP(3) |
| updatedAt | timestamp with time zone | NO | CURRENT_TIMESTAMP(3) |
Индексы:
CREATE UNIQUE INDEX "PK_e4887149ef82ffc44e25ac9dc30" ON public."data_table_user_BFLNewsItemV04" USING btree (id);
CREATE UNIQUE INDEX bfl_news_item_key_unique ON public."data_table_user_BFLNewsItemV04" USING btree (batch_key, item_key);
data_table_user_KszG5ycOvocFLwHW
| Столбец | Тип | Nullable | Default |
|---|---|---|---|
| id | integer | NO | — |
| draft_key | text | YES | — |
| version | double precision | YES | — |
| topic | text | YES | — |
| text | text | YES | — |
| status | text | YES | — |
| owner_chat_id | text | YES | — |
| source_event_key | text | YES | — |
| approval_message_id | text | YES | — |
| feedback_prompt_message_id | text | YES | — |
| feedback | text | YES | — |
| published_message_id | text | YES | — |
| last_event_key | text | YES | — |
| createdAt | timestamp with time zone | NO | CURRENT_TIMESTAMP(3) |
| updatedAt | timestamp with time zone | NO | CURRENT_TIMESTAMP(3) |
| cover_title | text | YES | — |
| cover_subtitle | text | YES | — |
| cover_category | text | YES | — |
| cover_image_id | text | YES | — |
| asset_id | text | YES | — |
| sha256 | text | YES | — |
| template_version | text | YES | — |
| template_fingerprint | text | YES | — |
| cover_request_sha256 | text | YES | — |
| cover_asset_path | text | YES | — |
| telegram_file_id | text | YES | — |
| preview_photo_message_id | text | YES | — |
| preview_text_message_id | text | YES | — |
| channel_photo_message_id | text | YES | — |
| channel_text_message_id | text | YES | — |
| channel_send_mode | text | YES | — |
| channel_caption | text | YES | — |
| channel_text | text | YES | — |
| channel_photo_state | text | YES | — |
| channel_text_state | text | YES | — |
| preview_photo_state | text | YES | — |
| preview_text_state | text | YES | — |
| publication_event_key | text | YES | — |
| cover_width | double precision | YES | — |
| cover_height | double precision | YES | — |
| format | text | YES | — |
| caption | text | YES | — |
| image_prompt | text | YES | — |
| image_model | text | YES | — |
| image_settings | text | YES | — |
| image_usage | text | YES | — |
| image_request_prompt | text | YES | — |
| source_image_id | text | YES | — |
| image_state | text | YES | — |
| image_request_key | text | YES | — |
| image_response_id | text | YES | — |
| image_binary_ref | text | YES | — |
| error_stage | text | YES | — |
| error_code | text | YES | — |
| error_http_status | text | YES | — |
| channel_message_id | text | YES | — |
| caption_length | double precision | YES | — |
| shortening_attempts | double precision | YES | — |
| image_attempts | double precision | YES | — |
| editorial_notes | text | YES | — |
| previous_caption | text | YES | — |
| exact_revision_json | text | YES | — |
| recovery_of_event | text | YES | — |
| recovery_reason | text | YES | — |
| operation_id | text | YES | — |
| status_message_id | text | YES | — |
| notification_text | text | YES | — |
| notification_lock | text | YES | — |
| notification_error | text | YES | — |
| notification_state | text | YES | — |
| notification_history | text | YES | — |
| parent_version | double precision | YES | — |
| cover_origin_version | double precision | YES | — |
| notification_rank | double precision | YES | — |
| notification_retry_after | double precision | YES | — |
| origin | text | YES | — |
| news_item_id | text | YES | — |
| news_batch_id | text | YES | — |
| source_url | text | YES | — |
| fact_pack | text | YES | — |
| body | text | YES | — |
| news_validation | text | YES | — |
| body_limit | double precision | YES | — |
| created_by_user_id | text | YES | — |
| operation_actor_user_id | text | YES | — |
| operation_actor_chat_id | text | YES | — |
| feedback_actor_user_id | text | YES | — |
| feedback_chat_id | text | YES | — |
| delivery_tracking | text | YES | — |
Индексы:
CREATE UNIQUE INDEX "PK_e7f7c93ff982283653c0ebe3aeb" ON public."data_table_user_KszG5ycOvocFLwHW" USING btree (id);
CREATE UNIQUE INDEX bfl_draft_version_unique ON public."data_table_user_KszG5ycOvocFLwHW" USING btree (draft_key, version);
CREATE UNIQUE INDEX bfl_source_event_unique ON public."data_table_user_KszG5ycOvocFLwHW" USING btree (source_event_key) WHERE ((source_event_key IS NOT NULL) AND (source_event_key <> ''::text));