# Postgresql Persistence Adapter Documentation Writing

> Проектирование и ведение аналитической Markdown-документации PostgreSQL persistence-адаптера в сервисах с гексагональной архитектурой: application-портов, mapping, Unit of Work, транзакций, optimistic locking, ошибок, миграционных пакетов, таблиц, колонок, ограничений, связей и обоснованных индексов. Использовать при создании, адаптации или ревью паспорта PostgreSQL-адаптера и схемы БД, особенно когда каждая физическая таблица должна иметь отдельный файл и таблицу колонок, а изменения схемы — версионированные каталоги. Не использовать для реализации кода или SQL/yoyo-миграций, определения domain/application-требований, других типов хранилищ и общей документации репозитория.

- Skill: `nemagu/postgresql-persistence-adapter-documentation-writing` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add nemagu/postgresql-persistence-adapter-documentation-writing`
- Raw SKILL.md: https://api.skillmd.com/api/skills/nemagu/postgresql-persistence-adapter-documentation-writing/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Data & Analytics
- Author: Nemagu (https://skillmd.com/u/nemagu)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/nemagu/postgresql-persistence-adapter-documentation-writing

---


# Документирование адаптера хранения PostgreSQL

Проектировать документацию requirements-first. Разделять паспорт адаптера,
актуальную физическую схему и append-only историю изменений.

## Граница ответственности

- Application владеет портами, транзакционными требованиями и исходами.
- Domain владеет бизнес-инвариантами.
- Адаптер владеет mapping, SQL-согласованностью и классификацией ошибок БД.
- Документация схемы владеет принятыми физическими таблицами, связями и индексами.
- Скил документирует решения, но не создаёт код, SQL, yoyo-миграции и не применяет
  изменения к PostgreSQL.

Не включать генерацию идентификаторов в порт хранилища. Это отдельная смысловая
возможность application.

## Источники и статус сведений

Использовать приоритет:

1. ответы пользователя;
2. документы владеющего domain/application/внешнего контракта;
3. существующие документы адаптера и схемы;
4. предложения, явно подтверждённые пользователем.

Использовать документацию для сбора исходных сведений и подготовки предложений.
При противоречии документов показать его пользователю, не выбирать вариант
самостоятельно.

По умолчанию запрещено читать код репозитория, SQL, yoyo-миграции и фактическую
БД. Это допустимо только при адаптации существующей документации после отдельного
разрешения пользователя. Использовать найденное только как материал для
предложений, которые становятся целевым требованием после подтверждения.
Не включать в нормативный комплект фактическое состояние реализации, сравнение с
целевой схемой или реестр расхождений.

## Обязательная структура результата

Перед созданием документов полностью прочитать
[структуру репозитория](references/repository-structure.md).

Поддерживать в канонической структуре общего скила:

- паспорт `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.

Работать последовательно:

1. определить целевую схему по подтверждённым требованиям;
2. согласовать глобальный подход адаптера и миграций;
3. пройти группы таблиц по агрегатам;
4. для таблицы согласовать назначение, колонки, PK, NULL и defaults;
5. предложить FK, UNIQUE, CHECK и другие ограничения;
6. предложить индексы по документированным операциям;
7. согласовать связи и ER-схему;
8. оформить change package, применение и rollback;
9. обновить `current` и навигацию.

Группировать вопросы по одной теме:

- короткие независимые — до 5;
- средние — до 3;
- крупные архитектурные — 1–2.

Если ответ влияет на последующие вопросы, сначала получить его. Не включать
предложение в нормативную схему до подтверждения.

Использовать статусы `proposed`, `accepted`, `rejected`, `deferred`. В `current`
попадают только `accepted`; `deferred` остаётся открытым вопросом.

## Паспорт адаптера

Перед созданием или изменением паспорта полностью прочитать
[шаблон паспорта](references/adapter-passport-template.md).

Не указывать версию 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-разделы допустимы только перед `Готовность`.
`Открытые вопросы` всегда последний. Не пересказывать классы и методы и не
копировать схему в паспорт; ссылаться на каталог схемы.

## Файл физической таблицы

Перед созданием или изменением файла прочитать
[шаблон таблицы](references/table-document-template.md).

Каждый файл обязан содержать:

- точное имя и назначение;
- отдельную таблицу колонок с 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 показывать локальную диаграмму только затронутой части. При
изменении связей показывать состояния до и после.

## Пакеты изменений

Перед созданием пакета полностью прочитать
[шаблон изменения](references/change-package-template.md).

Каждое логическое изменение создаёт новый каталог
`postgresql-persistence/changes/<sequence>-<meaningful-name>`. Один пакет может ссылаться на несколько
yoyo-миграций. Применённый пакет не переписывать; исправление оформлять новым.

Статусы: `planned`, `ready`, `applied`, `superseded`. При `applied` обновлять
`current`, полную ER-схему и навигацию.

## Миграция с остановкой сервиса

Не требовать одновременной совместимости двух версий приложения. Документировать
окно обслуживания:

1. maintenance и остановка всех процессов;
2. проверка активных транзакций и preflight;
3. backup при риске для данных;
4. применение миграций;
5. post-migration проверки;
6. запуск новой версии и readiness;
7. завершение maintenance.

Фиксировать длительность, блокировки, backfill, backup и point of no return.
Rollback до запуска новой версии возвращает исходную схему и старое приложение.
После запуска сначала учитывать новые записанные данные.

## Обновление документации

После принятого изменения:

1. создать новый change package;
2. описать дельту, применение и rollback;
3. обновить затронутые файлы `current`;
4. обновить полную ER-схему и навигацию;
5. обновить паспорт только при изменении портов, mapping, транзакций или ошибок;
6. не менять предыдущие 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`.

