Структура README сервиса
README сервис-репозитория — это источник истины по сервис-специфичным
контрактам: HTTP endpoints, публикуемые и потребляемые события, data
model, конфигурация, ports. Handbook ссылается на README, а не
дублирует его содержимое: в
services-catalog — directory и префиксы,
детали — в README.
Без единого шаблона README расходятся по структуре, ревьюер каждый
раз заново ищет нужный раздел, а ссылки handbook → README ломаются
при первом же refactor’е. Эта страница фиксирует обязательную
структуру, которой следует каждый сервис в
services-catalog.
Содержание
- Обязательные секции README
- Опциональные секции
- Правила поддержки
- CI-проверка обязательных заголовков
- Пример минимального README
Обязательные секции README
README сервиса (файл README.md в корне сервис-репо) обязан содержать
перечисленные ниже заголовки ## — в том же написании, в том же
порядке.
## Overview
1–2 параграфа: что делает сервис, где находится в архитектуре. Ссылка
на architecture-overview handbook’а —
чтобы читатель мог быстро восстановить контекст.
## Ownership
Owner-роль (например, «lead-инженер backend»), канал связи (ссылка на
onboarding/04-who-owns-what в
handbook или локальная копия ролей в том же сервис-репо). Имена и
контакты конкретных людей — не сюда: держим handbook и README
prescriptive по ролям, не по людям.
## HTTP API
Таблица endpoint’ов. Внешние (через Gateway, префикс /v1/*) и
/internal/* разделены на две подсекции:
| method | path | purpose | req schema | resp schema | error codes |
|---|
req schema/resp schema— ссылка на Go-тип в коде сервиса или на OpenAPI-компонент, не inline-таблица с полями.error codes— список стабильныхcodeизconventions/http-api(not_found,invalid_input, …).
Правила формата request/response, middleware, пагинация — общие для
всех сервисов, см. conventions/http-api. README не
дублирует правила, только перечисляет endpoint’ы.
## Events published
Таблица:
| topic | envelope schema ref | payload schema file | business meaning | producer location in code |
|---|
envelope schema ref— ссылка наevent-catalog#envelopehandbook’а.payload schema file— путь к JSON-schema или Go-типу в том же репо.producer location in code— путь до функции, которая формирует и публикует событие (internal/event/publisher.go,internal/service/<X>.go#Foo).
Если сервис не публикует события (consumer-only), эта секция присутствует со значением «—».
## Events consumed
Таблица:
| topic | handler location | idempotency strategy | DLQ topic |
|---|
idempotency strategy— upsert / unique constraint / Deduplicator с TTL — см.patterns/idempotent-consumer.DLQ topic—<topic>.dlq, см.event-catalog#dlq-naming.
## Data model
Короткое описание таблиц и связей, не детальный ERD. Цель — чтобы
ревьюер мог сориентироваться: «где лежит entity X, с чем связана».
Детали — в migrations/.
## Configuration
Перечень env-переменных сервиса (с префиксом
<SERVICE_PREFIX>_* — см.
conventions/configuration). Таблица:
| var | default | required | purpose |
|---|
Значения default — placeholder’ы (change_me, _dev_), не боевые
секреты.
## Ports
Таблица «permanent» портов сервиса:
| port | purpose |
|---|---|
e.g. 8001 | HTTP (/v1/*, /internal/*, /healthz, /readyz) |
e.g. 9001 | metrics (/metrics), profiling (/debug/pprof) |
Закреплённые за сервисом порты стоит держать тут, чтобы при локальном запуске нескольких сервисов порты не конфликтовали.
## Runbooks
Ссылки на:
- Сервис-специфичные runbook’и в репо (
docs/runbooks/*.md). - Общие runbook’и в handbook (
troubleshooting/).
Alert → runbook — ссылка в alert-правиле должна вести на рабочий якорь.
## Development
Как запустить локально. Типичный минимум: docker compose up, make migrate, make run, make test. Ссылка на
onboarding/03-local-stack — чтобы
не дублировать общий стек.
## Migrations
Ссылка на директорию migrations/ в том же репо + политика:
forward-only, down-файлы на случай отката последней миграции. Общий
процесс — how-to/add-migration.
Опциональные секции
Эти секции появляются по необходимости; отсутствие — не дефект, но если секция есть, имя заголовка фиксировано.
## SLOs
Если сервис имеет sharable SLO-definitions (HTTP availability, p99
latency, consumer lag). Общий формат — в
conventions/slo-and-budget.
## Dependencies
Внешние downstream: другие сервисы, сторонние HTTP API, object storage. Имеет смысл, если не все зависимости очевидны из архитектуры.
## Architecture decisions
Архитектурный лог — простые записи формата «дата — решение — причина». Без формата с номерами и шаблонными полями; handbook их не использует.
Правила поддержки
- Breaking change в HTTP API или событиях → README обновляется в том же PR, что и код. Если PR меняет endpoint или payload, но таблицы в README остались старые — ревьюер блокирует merge.
- README — источник истины. Handbook (
services-catalog,event-catalog) ссылается на README иdocs/events.md; если данные разошлись — источник истины README сервиса, handbook правится следом. - Ссылки handbook → README ведут на стабильные якоря. Заголовки из списка выше не переименовываются; изменения заголовка — breaking change в документации, требует обновления handbook и (если есть) сервис-специфичных alert’ов, которые ссылаются на runbook.
- CI в сервис-репо обязан иметь markdownlint для
README.mdиscripts/check-readme.sh(см. ниже), проверяющий наличие обязательных заголовков.
CI-проверка обязательных заголовков
В сервис-репо добавляется scripts/check-readme.sh:
#!/usr/bin/env bash
set -euo pipefail
required=(
"## Overview"
"## Ownership"
"## HTTP API"
"## Events published"
"## Events consumed"
"## Data model"
"## Configuration"
"## Ports"
"## Runbooks"
"## Development"
"## Migrations"
)
missing=()
for h in "${required[@]}"; do
if ! grep -qF "$h" README.md; then
missing+=("$h")
fi
done
if [ ${#missing[@]} -gt 0 ]; then
printf 'FAIL README.md missing required section: %s\n' "${missing[@]}"
exit 1
fi
echo "OK: все обязательные разделы README на месте"Скрипт вызывается отдельным job в CI сервис-репо (рядом с
golangci-lint / go test). Один failing job — PR не мержится.
Пример минимального README
# review-service
## Overview
Сервис отзывов: CRUD, реакции, реплаи владельца места, SSE-поток
гистограммы рейтинга. Часть архитектуры backend — см.
`backend-handbook/architecture-overview`.
## Ownership
Owner-роль: lead-инженер backend. Канал связи и ротация —
`backend-handbook/onboarding/04-who-owns-what`.
## HTTP API
### Public (`/v1/*`)
| method | path | purpose | req schema | resp schema | error codes |
|---|---|---|---|---|---|
| POST | /v1/reviews | создать отзыв | `CreateReviewRequest` | `Review` | `invalid_input`, `unauthorized` |
### Internal (`/internal/*`)
| method | path | purpose | req schema | resp schema | error codes |
|---|---|---|---|---|---|
| GET | /internal/reviews/{id} | lookup для других сервисов | — | `Review` | `not_found` |
## Events published
| topic | envelope | payload schema | business meaning | producer |
|---|---|---|---|---|
| `review.created` | `docs/envelope.md` | `docs/events/review.created.json` | отзыв создан | `internal/service/review.go#Create` |
## Events consumed
| topic | handler | idempotency | DLQ |
|---|---|---|---|
| — | — | — | — |
## Data model
Таблицы: `reviews`, `reactions`, `replies`, `outbox`. Ключи и связи —
`migrations/`.
## Configuration
| var | default | required | purpose |
|---|---|---|---|
| `REVIEW_HTTP_ADDR` | `:8007` | yes | HTTP listener |
## Ports
| port | purpose |
|---|---|
| 8007 | HTTP |
| 9007 | metrics / pprof |
## Runbooks
- `docs/runbooks/histogram-stream-stuck.md` — SSE поток завис.
- `backend-handbook/troubleshooting/kafka-consumer-stuck` — общий
runbook для Kafka consumer'ов.
## Development
docker compose up, make migrate, make run, make test.
## Migrations
`migrations/`. Политика — forward-only, см.
`backend-handbook/how-to/add-migration`.См. также
../services-catalog— directory сервисов, который ссылается на README каждого.../event-catalog— directory топиков, который ссылается наdocs/events.mdрепо publisher’а.configuration— правила env-переменных.http-api— формат HTTP endpoint’ов, которые описывает README.events— правила публикации и потребления событий, которые описывает README.../checklists/production-ready— проверка соответствия README шаблону перед включением prod-трафика.