Документирование адаптера хранения PostgreSQL
Проектировать документацию requirements-first. Разделять паспорт адаптера, актуальную физическую схему и append-only историю изменений.
Граница ответственности
- Application владеет портами, транзакционными требованиями и исходами.
- Domain владеет бизнес-инвариантами.
- Адаптер владеет mapping, SQL-согласованностью и классификацией ошибок БД.
- Документация схемы владеет принятыми физическими таблицами, связями и индексами.
- Скил документирует решения, но не создаёт код, SQL, yoyo-миграции и не применяет изменения к PostgreSQL.
Не включать генерацию идентификаторов в порт хранилища. Это отдельная смысловая возможность application.
Источники и статус сведений
Использовать приоритет:
- ответы пользователя;
- документы владеющего domain/application/внешнего контракта;
- существующие документы адаптера и схемы;
- предложения, явно подтверждённые пользователем.
Использовать документацию для сбора исходных сведений и подготовки предложений. При противоречии документов показать его пользователю, не выбирать вариант самостоятельно.
По умолчанию запрещено читать код репозитория, SQL, yoyo-миграции и фактическую БД. Это допустимо только при адаптации существующей документации после отдельного разрешения пользователя. Использовать найденное только как материал для предложений, которые становятся целевым требованием после подтверждения. Не включать в нормативный комплект фактическое состояние реализации, сравнение с целевой схемой или реестр расхождений.
Обязательная структура результата
Перед созданием документов полностью прочитать структуру репозитория.
Поддерживать в канонической структуре общего скила:
- паспорт
docs/adapters/outgoing/postgresql-persistence.md; - соседний каталог
docs/adapters/outgoing/postgresql-persistence/; currentс актуальным снимком;changesс неизменяемой историей логических пакетов изменений.
Корень docs в путях означает принятый корень исходных Markdown-файлов, например
docs/src. Скил формирует только поддерево исходящего PostgreSQL-адаптера и его
фрагмент навигации. Главный скил размещает раздел «Паспорта адаптеров» в
глобальном SUMMARY.md; этот скил не меняет порядок корневых разделов.
Технические имена файлов и каталогов сохранять на английском в kebab-case.
Все отображаемые в браузере названия — заголовки документов, подписи ссылок в
SUMMARY.md и README, названия разделов — писать на языке документа. Для
русскоязычной документации использовать, например, «Хранилище PostgreSQL»,
«Текущий снимок», «История изменений», «Состав пакета» и «Откат», а не
PostgreSQL persistence, current, changes, Manifest и Rollback.
Один файл current описывает ровно одну физическую таблицу. Каждая таблица имеет
собственную Markdown-таблицу колонок. Запрещено объединять физические таблицы в
сводную строку, скрывать version/outbox-таблицы общей схемой или хранить всю
историю миграций в одном файле.
Интервью и принятие решений
Стабильные обозначения
Использовать схему
<контекст>.adapters.outgoing.postgresql.<категория>.<объект>.<уточнение>.
Категория, физический объект и уточнение являются отдельными смысловыми
сегментами; не склеивать таблицу с операцией и не пропускать объект. Одинаковый
паспорт, пакет изменения, таблица, ограничение или индекс во всех документах
имеет одно обозначение независимо от имени файла и физического имени PostgreSQL.
Работать последовательно:
- определить целевую схему по подтверждённым требованиям;
- согласовать глобальный подход адаптера и миграций;
- пройти группы таблиц по агрегатам;
- для таблицы согласовать назначение, колонки, PK, NULL и defaults;
- предложить FK, UNIQUE, CHECK и другие ограничения;
- предложить индексы по документированным операциям;
- согласовать связи и ER-схему;
- оформить change package, применение и rollback;
- обновить
currentи навигацию.
Группировать вопросы по одной теме:
- короткие независимые — до 5;
- средние — до 3;
- крупные архитектурные — 1–2.
Если ответ влияет на последующие вопросы, сначала получить его. Не включать предложение в нормативную схему до подтверждения.
Использовать статусы proposed, accepted, rejected, deferred. В current
попадают только accepted; deferred остаётся открытым вопросом.
Паспорт адаптера
Перед созданием или изменением паспорта полностью прочитать шаблон паспорта.
Не указывать версию PostgreSQL по умолчанию. Добавлять её только по явному требованию пользователя или когда подтверждённая версия влияет на доступные возможности, совместимость, миграцию либо эксплуатационные гарантии. В таком случае рядом фиксировать причину, по которой версия значима.
Использовать обязательные разделы общего скила в заданном порядке. PostgreSQL- специфичные сведения распределять внутри них:
Границы ответственности— обязанности и явно исключённые возможности;Контракты— application-порты и документы-источники;Внешняя система— подтверждённые свойства PostgreSQL;Преобразования— mapping domain/application ↔ строки БД и восстановление;Гарантии взаимодействия— Unit of Work, commit/rollback, optimistic locking, batching, история и outbox;Ошибочные исходы— not found, conflict, transient и corrupted data;Совместимость и внешние объекты— схема, migration packages и offline migration;Проверка интеграции— гарантии, подлежащие проверке;КонфигурацияиНаблюдаемость— параметры без секретов и необходимые сигналы.
Не удалять неприменимый обязательный раздел: писать Не применимо с причиной.
Дополнительные PostgreSQL-разделы допустимы только перед Готовность.
Открытые вопросы всегда последний. Не пересказывать классы и методы и не
копировать схему в паспорт; ссылаться на каталог схемы.
Файл физической таблицы
Перед созданием или изменением файла прочитать шаблон таблицы.
Каждый файл обязан содержать:
- точное имя и назначение;
- отдельную таблицу колонок с PostgreSQL-типом, NULL, default, ключами/ссылками и смыслом;
- ограничения уровня таблицы;
- входящие и исходящие связи с кардинальностью и referential actions;
- индексы этой таблицы;
- связанные application-порты и виды операций;
- особенности целостности и открытые вопросы.
Ограничения БД
Предлагать пользователю применимые NOT NULL, FK, UNIQUE, CHECK, EXCLUDE и
referential actions на основании согласованных документов. Для предложения
показывать пользу, последствия, миграционный риск и дублирование гарантии
domain/application. Пользователь решает, включать ли ограничение.
Для принятого UNIQUE фиксировать явное стабильное имя constraint-а. В разделе
индексов указывать создаваемый им constraint-backed индекс под тем же именем и не
добавлять дублирующий явный уникальный индекс.
Не переносить каждый domain-инвариант в БД автоматически.
Для согласованной полиморфной связи описывать реестр допустимых источников, физический FK на запись реестра и логическую часть ссылки отдельно. Если порт уже располагает идентификатором и версией бизнес-объекта, не требовать физический идентификатор строки только ради outbox. Явно фиксировать отсутствие физического FK для полиморфной части и транзакционную гарантию её целостности.
Для единого outbox согласовывать операции постановки, стабильной выборки и всех
терминальных переходов состояния. Предлагать CHECK согласованности статуса со
временем обработки, уникальность логического источника и частичный индекс только
ожидающих записей. Допускать два последовательных чтения внутри адаптера — сначала
outbox-записи, затем конкретного источника — когда это делает SQL проще и
соответствует контракту порта; не выдавать сложный полиморфный JOIN за
обязательное решение.
Если принят общий реестр физических таблиц, перечислять его полный состав в актуальном снимке и документировать lifecycle записей миграциями. Реестр создавать до зависимых таблиц; при требовании полного состава регистрировать и сам реестр сразу после создания. Создание или переименование таблицы должно в той же миграции добавить либо изменить точное имя, а откат — сначала устранить полиморфные ссылки и удалить запись, затем удалить таблицу. Общий реестр удалять последним. Не распространять это правило на проекты, где согласован реестр только допустимых полиморфных источников.
Индексы
Предлагать индексы только для документированных фильтров, сортировки, join, поиска, optimistic update, outbox или принятого ограничения.
Для каждого индекса обязательно фиксировать:
- поддерживаемую операцию;
- конкретную причину добавления;
- ключи/выражения и обоснование их порядка;
- тип, уникальность и predicate;
- источник: constraint-backed или явный;
- стоимость записи и возможное пересечение;
- статус решения;
- проверялся ли
EXPLAIN, либо эффективность только предполагается.
Фраза «для повышения производительности» без операции и причины недопустима.
Не считать FK автоматически индексированным или автоматически требующим индекс.
Не заявлять доказанную эффективность без фактического EXPLAIN.
Индексы хранить рядом с физической таблицей. Глобальный дублирующий реестр не создавать.
ER-схемы
В postgresql-persistence/current/README.md поддерживать полную Mermaid
erDiagram всех физических
таблиц без колонок. Показывать реальные FK, кардинальность, version- и
publication/outbox-таблицы. Точные колонки и действия оставлять файлам таблиц.
В change package показывать локальную диаграмму только затронутой части. При изменении связей показывать состояния до и после.
Пакеты изменений
Перед созданием пакета полностью прочитать шаблон изменения.
Каждое логическое изменение создаёт новый каталог
postgresql-persistence/changes/<sequence>-<meaningful-name>. Один пакет может ссылаться на несколько
yoyo-миграций. Применённый пакет не переписывать; исправление оформлять новым.
Статусы: planned, ready, applied, superseded. При applied обновлять
current, полную ER-схему и навигацию.
Миграция с остановкой сервиса
Не требовать одновременной совместимости двух версий приложения. Документировать окно обслуживания:
- maintenance и остановка всех процессов;
- проверка активных транзакций и preflight;
- backup при риске для данных;
- применение миграций;
- post-migration проверки;
- запуск новой версии и readiness;
- завершение maintenance.
Фиксировать длительность, блокировки, backfill, backup и point of no return. Rollback до запуска новой версии возвращает исходную схему и старое приложение. После запуска сначала учитывать новые записанные данные.
Обновление документации
После принятого изменения:
- создать новый change package;
- описать дельту, применение и rollback;
- обновить затронутые файлы
current; - обновить полную ER-схему и навигацию;
- обновить паспорт только при изменении портов, mapping, транзакций или ошибок;
- не менять предыдущие applied-пакеты.
Готовность и проверка
Перед завершением убедиться, что:
- каждая физическая таблица имеет отдельный файл и таблицу колонок;
- состав
currentсовпадает с подтверждённой схемой; - типы, NULL, defaults, PK, FK, UNIQUE, CHECK и referential actions указаны;
- каждый принятый индекс имеет конкретное обоснование;
- PK/UQ индексы отделены от явных, FK без индекса видимы;
- Mermaid ER-схема соответствует принятым FK;
- каждый change package связан с логическим изменением и, после разрешённой реализации, с yoyo-файлами;
- offline rollout и rollback определены;
- порты не смешаны с PostgreSQL-реализацией;
- локальные ссылки разрешаются;
- после сборки все страницы схемы и истории существуют, а браузерные ссылки не
ведут на отсутствующий
README.html; - видимые заголовки и подписи навигации написаны на языке документа;
- документы описывают целевую схему и не содержат реестр расхождений реализации;
- каждый документ заканчивается
## Открытые вопросы.
Если проверка недоступна, перечислить проверенное вручную и непроверенное. Если
вопросов нет, писать Открытых вопросов нет..
При запросе реализации передать работу отдельному скилу
python-psycopg-yoyo-persistence-writing.