Init
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
# GitLab CI/CD for `pcp-ballistics-service`
|
||||
|
||||
This document describes the pilot GitLab CI/CD setup for `pcp-ballistics-service`.
|
||||
It is intentionally scoped to one service so the same structure can be reused later for other services in this monorepo.
|
||||
|
||||
## Pipeline behavior
|
||||
|
||||
The root pipeline is defined in [.gitlab-ci.yml](/home/emelianovan/WORK/Kotlin/pcp/.gitlab-ci.yml) and includes the service-specific jobs from [.gitlab/ci/pcp-ballistics-service.yml](/home/emelianovan/WORK/Kotlin/pcp/.gitlab/ci/pcp-ballistics-service.yml).
|
||||
|
||||
Pipeline creation is limited by `workflow: rules`:
|
||||
|
||||
- merge request: create a pipeline only when `pcp-ballistics-service` or its dependencies changed
|
||||
- push to `dev`: create a pipeline only when `pcp-ballistics-service` or its dependencies changed
|
||||
- push to `master`: create a pipeline only when `pcp-ballistics-service` or its dependencies changed
|
||||
|
||||
No deploy jobs are created for merge requests.
|
||||
|
||||
## Jobs
|
||||
|
||||
The pilot flow has four stages:
|
||||
|
||||
1. `ballistics:test`
|
||||
Runs `:services:pcp-ballistics-service:test` outside Docker.
|
||||
Publishes JUnit and HTML/JaCoCo reports.
|
||||
|
||||
2. `ballistics:build`
|
||||
Runs `:services:pcp-ballistics-service:bootJar` outside Docker.
|
||||
Publishes `build/libs/*.jar` as an artifact.
|
||||
|
||||
3. `ballistics:image`
|
||||
Builds and pushes the Docker image with Kaniko using the jar artifact from the previous stage.
|
||||
Tags:
|
||||
- `${CI_COMMIT_SHORT_SHA}`
|
||||
- `${CI_COMMIT_REF_SLUG}-${CI_COMMIT_SHORT_SHA}`
|
||||
|
||||
4. deploy jobs
|
||||
- `ballistics:deploy:dev`
|
||||
- `ballistics:deploy:master`
|
||||
|
||||
Both are manual and use Helm:
|
||||
`helm upgrade --install --wait --atomic --timeout`.
|
||||
|
||||
## Branch behavior
|
||||
|
||||
### `dev`
|
||||
|
||||
Push to `dev`:
|
||||
|
||||
- runs test, build and image jobs
|
||||
- exposes a manual deploy button to the `dev` environment
|
||||
|
||||
### `master`
|
||||
|
||||
Push to `master`:
|
||||
|
||||
- runs test, build and image jobs
|
||||
- exposes a manual deploy button to the `master` environment
|
||||
|
||||
### merge request
|
||||
|
||||
Merge request pipeline:
|
||||
|
||||
- runs test and build only
|
||||
- does not create deploy jobs
|
||||
|
||||
## `rules:changes` scope
|
||||
|
||||
The pilot dependency map for `pcp-ballistics-service` includes:
|
||||
|
||||
- `services/pcp-ballistics-service/**/*`
|
||||
- `libs/pcp-types-lib/**/*`
|
||||
- `libs/ballistics-lib/**/*`
|
||||
- `config-repo/pcp-ballistics-service.yaml`
|
||||
- `config-repo/application*.yaml`
|
||||
- Gradle root files and wrapper
|
||||
- CI files
|
||||
- `charts/pcp-ballistics-service/**/*`
|
||||
|
||||
This is the pattern to reuse later for other services: service directory + direct shared libraries + service config + CI/Helm files.
|
||||
|
||||
## Helm deploy model
|
||||
|
||||
The chart lives in [charts/pcp-ballistics-service](/home/emelianovan/WORK/Kotlin/pcp/charts/pcp-ballistics-service).
|
||||
|
||||
The deployment model is kubeconfig-based, not GitLab Agent-based.
|
||||
This keeps the pilot setup simple and practical. A later migration to GitLab Agent is still possible because deploy logic is already isolated in dedicated jobs.
|
||||
|
||||
## Required GitLab CI/CD variables
|
||||
|
||||
Registry auth uses standard GitLab registry variables:
|
||||
|
||||
- `CI_REGISTRY`
|
||||
- `CI_REGISTRY_USER`
|
||||
- `CI_REGISTRY_PASSWORD`
|
||||
|
||||
Deploy jobs require:
|
||||
|
||||
- `BALLISTICS_KUBE_CONFIG_DEV`
|
||||
- `BALLISTICS_KUBE_NAMESPACE_DEV`
|
||||
- `BALLISTICS_CONFIG_SERVER_URI_DEV`
|
||||
- `BALLISTICS_KUBE_CONTEXT_DEV` optional
|
||||
- `BALLISTICS_CONFIG_LABEL_DEV` optional, defaults to `master`
|
||||
- `BALLISTICS_SPRING_PROFILE_DEV` optional, defaults to `dev`
|
||||
|
||||
- `BALLISTICS_KUBE_CONFIG_MASTER`
|
||||
- `BALLISTICS_KUBE_NAMESPACE_MASTER`
|
||||
- `BALLISTICS_CONFIG_SERVER_URI_MASTER`
|
||||
- `BALLISTICS_KUBE_CONTEXT_MASTER` optional
|
||||
- `BALLISTICS_CONFIG_LABEL_MASTER` optional, defaults to `master`
|
||||
- `BALLISTICS_SPRING_PROFILE_MASTER` optional, defaults to `dev`
|
||||
|
||||
`BALLISTICS_KUBE_CONFIG_*` must contain base64-encoded kubeconfig content.
|
||||
|
||||
## Config server and Vault
|
||||
|
||||
Runtime secrets are not duplicated in GitLab CI.
|
||||
|
||||
The Helm chart only passes bootstrap parameters needed by Spring Cloud Config:
|
||||
|
||||
- `CONFIG_SERVER_URI`
|
||||
- `SPRING_PROFILES_ACTIVE`
|
||||
- `SPRING_CLOUD_CONFIG_LABEL`
|
||||
- `CONFIG_SERVER_FAIL_FAST`
|
||||
|
||||
`pcp-ballistics-service` continues to obtain runtime configuration and secrets through `spring-cloud-config-server` and Vault at runtime.
|
||||
|
||||
## How to scale this to other services
|
||||
|
||||
To onboard another service later:
|
||||
|
||||
1. create a dedicated `.gitlab/ci/<service>.yml`
|
||||
2. define that service's `rules:changes`
|
||||
3. add a dedicated Helm chart
|
||||
4. keep the same stage structure:
|
||||
`test -> build -> image -> manual deploy`
|
||||
5. keep config-service/Vault integration at runtime, without copying secrets into GitLab
|
||||
@@ -0,0 +1,103 @@
|
||||
# CHECKLIST.md
|
||||
|
||||
## Назначение
|
||||
|
||||
Этот документ содержит краткие checklists для review/merge, Definition of Done, обязательных тестов и validation.
|
||||
|
||||
Пункты ниже применяются по принципу **where relevant**:
|
||||
- для обычных Kotlin/Spring-изменений достаточно общего checklist;
|
||||
- для изменений в BPM / Zeebe / Camunda / Kafka / retries / DLQ / compensation / schema evolution дополнительно применяются профильные пункты;
|
||||
- для критичных процессов глубина проверок и тестов должна быть пропорциональна риску изменения.
|
||||
|
||||
---
|
||||
|
||||
## Review checklist
|
||||
|
||||
### Для всех нетривиальных изменений
|
||||
|
||||
Перед merge необходимо подтвердить:
|
||||
- запрошенное поведение реализовано;
|
||||
- решение осталось в корректной архитектурной границе;
|
||||
- существующие публичные контракты не сломаны без явного запроса;
|
||||
- добавлены или обновлены релевантные тесты;
|
||||
- не внесено несвязанных правок;
|
||||
- validation выполнен по правилам `AGENTS.md`, либо пропуски явно объяснены.
|
||||
|
||||
### Дополнительно для BPM / Kafka / Zeebe / external integration изменений
|
||||
|
||||
Перед merge необходимо подтвердить, где это релевантно:
|
||||
- business key определён и используется консистентно;
|
||||
- operation id принимается от вызывающей стороны и используется для dedup;
|
||||
- ошибки классифицированы семантически;
|
||||
- side effects идемпотентны или явно компенсируются;
|
||||
- доменные события публикуются через Outbox;
|
||||
- logs / metrics / traces содержат обязательные поля корреляции;
|
||||
- тесты покрывают duplicate delivery и retry behavior;
|
||||
- изменения деплоя и конфигурации трассируемы в VCS.
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
Задача считается завершённой только если одновременно выполнено всё ниже, где это релевантно:
|
||||
|
||||
### Общее
|
||||
1. Запрошенное поведение реализовано.
|
||||
2. Решение осталось в корректной архитектурной границе.
|
||||
3. Нужные тесты добавлены или обновлены.
|
||||
4. Нужный validation выполнен, либо невозможность запуска объяснена.
|
||||
5. Не внесено несвязанных правок.
|
||||
|
||||
### Для BPM / Kafka / Zeebe / external integration
|
||||
6. BPM остаётся только оркестратором, если BPM участвует.
|
||||
7. Доменные правила остаются внутри сервисной границы.
|
||||
8. Flows остаются безопасными при at-least-once delivery.
|
||||
9. Идемпотентность обеспечена.
|
||||
10. `operation_id` сохранён или добавлен, где это требуется контрактом.
|
||||
11. Outbox сохранён или использован, где операция меняет состояние и публикует события.
|
||||
12. Retries ограничены и управляемы.
|
||||
13. DLQ handling сохранён для критичных consumers.
|
||||
14. Versioning / backward compatibility сохранены.
|
||||
15. Observability сохранена или улучшена.
|
||||
|
||||
---
|
||||
|
||||
## Обязательные тесты для значимых изменений
|
||||
|
||||
### Базовый минимум
|
||||
Как минимум покрывать, где применимо:
|
||||
- happy path;
|
||||
- изменённые ветки branching / validation logic;
|
||||
- regression scenario для bug fix.
|
||||
|
||||
### Дополнительно для BPM / Kafka / Zeebe / external integration
|
||||
Покрывать, где применимо:
|
||||
- retryable failure с последующим успехом;
|
||||
- исчерпание retries;
|
||||
- ветку business error;
|
||||
- обработку timeout;
|
||||
- сценарий compensation;
|
||||
- duplicate delivery / duplicate event handling;
|
||||
- contract compatibility;
|
||||
- schema compatibility.
|
||||
|
||||
### Для критичных процессов и high-risk изменений
|
||||
Покрывать пропорционально риску изменения через automated tests и/или явный resilience test plan:
|
||||
- перезапуск воркера во время выполнения;
|
||||
- временную недоступность БД;
|
||||
- временную недоступность внешней зависимости;
|
||||
- разрыв связности Kafka / BPM;
|
||||
- сценарий load / lag recovery.
|
||||
|
||||
---
|
||||
|
||||
## Validation
|
||||
|
||||
Следуй разделу `Validation commands` из `AGENTS.md`.
|
||||
|
||||
Если для изменения есть module-specific команды, используй минимальный релевантный прогон, а затем более широкий, когда это необходимо.
|
||||
|
||||
Если какая-либо команда не была запущена:
|
||||
- точно укажи, какая именно команда не запускалась;
|
||||
- объясни почему;
|
||||
- опиши остаточный риск.
|
||||
@@ -0,0 +1,303 @@
|
||||
# PLATFORM_STANDARD.md
|
||||
|
||||
## Назначение
|
||||
|
||||
Этот документ задаёт платформенные требования для сервисов, работающих в BPM / Kafka / Zeebe-среде.
|
||||
|
||||
Документ определяет:
|
||||
- архитектурные инварианты;
|
||||
- требования к идемпотентности и надёжности;
|
||||
- правила BPM / Kafka интеграции;
|
||||
- требования к observability, compatibility, retry / DLQ, compensation и rollout safety.
|
||||
|
||||
Это **внутренний платформенный стандарт**. Некоторые правила ниже являются осознанной инженерной политикой команды и не должны трактоваться как универсальная истина для всей отрасли.
|
||||
|
||||
---
|
||||
|
||||
## Архитектурные инварианты
|
||||
|
||||
- BPM — только оркестратор процесса.
|
||||
- Доменное состояние и бизнес-правила принадлежат сервису, а не BPM.
|
||||
- BPM не должен использоваться как master data store для доменных данных.
|
||||
- BPM может хранить только идентификаторы, ссылки и технические метаданные, необходимые для оркестрации.
|
||||
- Везде предполагается at-least-once доставка. Повторная доставка — норма, а не исключение.
|
||||
- Exactly-once не предполагается; корректность достигается через идемпотентность, dedup, Outbox и управляемые retries.
|
||||
- Каждый обработчик обязан быть идемпотентным.
|
||||
|
||||
---
|
||||
|
||||
## Правила использования BPM
|
||||
|
||||
- BPM использовать только для операторских / регламентных процессов и long-running orchestration.
|
||||
- Не использовать BPM для высокочастотных near-real-time streaming-потоков.
|
||||
- Каждый BPM service task должен представлять ровно одну атомарную доменную операцию.
|
||||
- Логика ожидания, таймаутов, ретраев, эскалаций и компенсаций должна моделироваться явно в BPM, а не быть скрыта внутри сервиса.
|
||||
- BPMN flow не должен становиться местом владения бизнес-логикой.
|
||||
|
||||
---
|
||||
|
||||
## Camunda 8 / Zeebe
|
||||
|
||||
### Граница интеграции
|
||||
|
||||
- BPM-to-service-task интеграция должна идти через Zeebe gRPC Job Worker.
|
||||
- Для нашей платформы использование REST connector для service task считается **не рекомендуемым и по умолчанию запрещённым**, если нет отдельного архитектурного согласования.
|
||||
- Нельзя изменять `jobType`, пока существуют активные инстансы процесса.
|
||||
|
||||
### Обязательные поля корреляции
|
||||
|
||||
Каждый service task обязан принимать / обрабатывать:
|
||||
- `businessKey`
|
||||
- `operationId`
|
||||
- `correlationId`
|
||||
- `processInstanceKey`
|
||||
- `traceId` или `traceparent`
|
||||
|
||||
### Контракт воркера
|
||||
|
||||
Для каждого Zeebe worker:
|
||||
- читать входные данные только из process / job variables;
|
||||
- валидировать обязательные поля корреляции до начала обработки;
|
||||
- проверять dedup store по `operationId` до выполнения side effects;
|
||||
- возвращать семантические результаты:
|
||||
- `SUCCESS` -> `CompleteJob`
|
||||
- `RETRYABLE_ERROR` -> `FailJob` с retry / backoff
|
||||
- `BUSINESS_ERROR` -> `ThrowError`
|
||||
- `FATAL_ERROR` -> ветка инцидента или обработка через исчерпание retries
|
||||
- никогда не генерировать `operationId` внутри сервиса для входящих оркестрируемых вызовов;
|
||||
- вызывать `CompleteJob` только после commit доменной транзакции.
|
||||
|
||||
---
|
||||
|
||||
## Идемпотентность
|
||||
|
||||
Все операции, вызываемые из BPM, и все Kafka consumers обязаны быть идемпотентными.
|
||||
|
||||
Обязательные правила:
|
||||
- `operationId` должен приходить от вызывающей стороны / оркестратора;
|
||||
- dedup storage должен обеспечивать atomic check-and-write semantics;
|
||||
- dedup storage должен защищать от race conditions;
|
||||
- повторный вызов с тем же `operationId` должен возвращать тот же семантический результат и не должен повторять side effects;
|
||||
- для записей dedup должен быть документирован TTL в соответствии с бизнес-окном возможного повтора;
|
||||
- non-atomic реализация идемпотентности запрещена.
|
||||
|
||||
Дополнительное обязательное правило:
|
||||
- повторный вызов с тем же `operationId`, но с другим `businessKey` или семантически иным payload / параметрами, считается конфликтом контракта, а не валидным retry; такой случай должен приводить к явной ошибке / инциденту и быть достаточно залогирован для расследования.
|
||||
|
||||
Рекомендуемая реализация:
|
||||
- таблица в доменной БД, например `idempotency_keys(operation_id, business_key, status, result_hash, created_at)`.
|
||||
|
||||
---
|
||||
|
||||
## Порядок транзакции и публикации событий
|
||||
|
||||
Когда операция изменяет доменное состояние и публикует события:
|
||||
|
||||
1. Выполнить доменную операцию.
|
||||
2. Записать событие(я) в outbox в рамках той же транзакции.
|
||||
3. Сделать commit транзакции.
|
||||
4. Только после этого подтверждать BPM (`CompleteJob`) или внешний success.
|
||||
|
||||
Публикация событий вне Outbox запрещена.
|
||||
|
||||
Это правило одинаково применяется к:
|
||||
- синхронным сервисным операциям;
|
||||
- Zeebe workers;
|
||||
- Kafka consumers, которые меняют состояние и публикуют новые события.
|
||||
|
||||
---
|
||||
|
||||
## Process variables
|
||||
|
||||
- Process variables должны быть минимальными.
|
||||
- Хранить только ID, ссылки, routing data и небольшие технические метаданные.
|
||||
- Не хранить файлы, большие JSON payload, большие массивы в process variables.
|
||||
- Большие payload должны храниться в доменной БД или object storage; в process variables должны храниться только ссылки.
|
||||
- Process variables должны быть версионированы и документированы.
|
||||
- Для long-running процессов изменения набора или формы variables должны оставаться совместимыми с уже запущенными инстансами, либо сопровождаться явной migration strategy.
|
||||
- Для нашей платформы безопасным внутренним ориентиром считается бюджет **50–100 KB на один process instance**. Это не технический максимум платформы, а engineering guardrail для управляемости и надёжности процессов.
|
||||
|
||||
---
|
||||
|
||||
## Семантика результатов
|
||||
|
||||
Каждая операция должна возвращать семантическую классификацию результата, а не только transport status codes.
|
||||
|
||||
Допустимые классы результатов:
|
||||
- `SUCCESS`
|
||||
- `RETRYABLE_ERROR`
|
||||
- `BUSINESS_ERROR`
|
||||
- `FATAL_ERROR`
|
||||
|
||||
Каждая long-running операция должна иметь:
|
||||
- явно заданный SLA / timeout;
|
||||
- async processing model, где это нужно;
|
||||
- status lookup по `operationId`;
|
||||
- определённое поведение cancel, если отмена поддерживается.
|
||||
|
||||
---
|
||||
|
||||
## Kafka / event-driven
|
||||
|
||||
### Базовые правила
|
||||
|
||||
- Базовое предположение по доставке — at-least-once.
|
||||
- Consumers должны быть идемпотентными по `event_id` и / или `operation_id`.
|
||||
- Нельзя размещать бизнес-логику напрямую в consumer / listener классах.
|
||||
- Consumers / listeners должны делегировать в application / domain services.
|
||||
- Сохранять текущую retry / DLQ-стратегию, если явно не запрошено её изменение.
|
||||
|
||||
### Семантика `event_id` и `operation_id`
|
||||
|
||||
- `event_id` используется для dedup повторной доставки **одного и того же опубликованного события**.
|
||||
- `operation_id` используется для dedup повторного выполнения **одной и той же бизнес-операции**, если этот идентификатор протягивается через события и обработчики.
|
||||
- Если в сообщении присутствуют оба идентификатора, обработчик обязан явно понимать и документировать, какой из них используется для какой семантики dedup.
|
||||
|
||||
### Контракты событий
|
||||
|
||||
Требования ниже относятся прежде всего к **domain events**. Для технических, retry, DLQ, compacted state и других служебных топиков может использоваться отдельная документированная конвенция.
|
||||
|
||||
Для domain events:
|
||||
- именование топиков должно следовать шаблону `<domain>.<entity>.<event>.v<major>`;
|
||||
- partition key должен сохранять порядок событий по одной сущности через `business_key`;
|
||||
- каждое событие должно содержать как минимум:
|
||||
- `event_id`
|
||||
- `event_type`
|
||||
- `event_version`
|
||||
- `occurred_at`
|
||||
- `producer`
|
||||
- `business_key`
|
||||
- `correlation_id`
|
||||
- `trace_id`, если доступен
|
||||
- `process_instance_id`, если применимо
|
||||
- предпочтительны Avro / Protobuf со Schema Registry;
|
||||
- строго валидируемая JSON Schema допустима только если это согласовано платформой.
|
||||
|
||||
### Что нельзя менять без явного запроса
|
||||
|
||||
- topic names
|
||||
- event schema
|
||||
- key semantics
|
||||
- partition assumptions
|
||||
- serialization format
|
||||
- retry topology
|
||||
- DLQ routing rules
|
||||
|
||||
---
|
||||
|
||||
## Schema evolution и совместимость
|
||||
|
||||
- Breaking changes требуют новой major-версии.
|
||||
- Добавление optional fields с default значениями допустимо.
|
||||
- Удаление или переименование полей требует новой major-версии.
|
||||
- По умолчанию consumers должны оставаться совместимыми как минимум с текущей схемой и согласованной политикой совместимости платформы. Если для конкретного домена зафиксировано правило поддержки текущей и предыдущей minor-версии, оно должно быть явно указано в контракте этого домена.
|
||||
|
||||
Для BPM, messaging и public APIs:
|
||||
- сохранять backward compatibility, если явно не запрошен breaking change;
|
||||
- учитывать rolling deployment compatibility;
|
||||
- учитывать coexistence старых и новых consumers;
|
||||
- избегать изменений, требующих lockstep deployment, если это явно не запрошено.
|
||||
|
||||
---
|
||||
|
||||
## Retry / DLQ
|
||||
|
||||
Retries должны быть управляемыми и конечными.
|
||||
|
||||
Рекомендуемая политика:
|
||||
- `RETRYABLE_ERROR`: ограниченные retries с exponential backoff и jitter
|
||||
- `BUSINESS_ERROR`: никаких слепых retries; отправка в operator handling / parking lot / DLQ
|
||||
- `FATAL_ERROR`: никаких слепых retries; создание инцидента и маршрутизация в DLQ, где применимо
|
||||
|
||||
Обязательные правила:
|
||||
- бесконечные retries запрещены;
|
||||
- отключение DLQ для критичных consumer flows запрещено;
|
||||
- replay из DLQ без установленной причины запрещён;
|
||||
- Zeebe retries и Kafka retries должны рассматриваться как два независимых контура управления.
|
||||
|
||||
---
|
||||
|
||||
## Compensation
|
||||
|
||||
Если операция имеет side effects, должно быть явно определено одно из следующего:
|
||||
- compensating operation;
|
||||
- явное указание, что компенсация невозможна;
|
||||
- ветка operator / manual remediation.
|
||||
|
||||
Компенсация должна быть:
|
||||
- идемпотентной;
|
||||
- детерминированной;
|
||||
- семантически классифицированной;
|
||||
- залогированной с `businessKey`, `operationId`, причиной и результатом.
|
||||
|
||||
---
|
||||
|
||||
## Observability
|
||||
|
||||
Структурированные JSON-логи обязательны.
|
||||
|
||||
Каждый log / event / span должен содержать, где применимо:
|
||||
- `correlation_id`
|
||||
- `trace_id`
|
||||
- `process_instance_id`
|
||||
- `business_key`
|
||||
- `operation_id`
|
||||
- `service_name`
|
||||
- `env`
|
||||
|
||||
Обязательная телеметрия:
|
||||
- latency (`p50/p95/p99`)
|
||||
- error rate по семантическим классам
|
||||
- retry rate / attempts histogram
|
||||
- active process instances / stuck instances
|
||||
- consumer lag / DLQ rate
|
||||
- compensation rate
|
||||
|
||||
Трассировка:
|
||||
- OpenTelemetry обязателен
|
||||
- каждый шаг процесса должен создавать span
|
||||
- span attributes должны содержать `process_instance_id`, `business_key`, `operation_id`, `step_name`
|
||||
|
||||
Если меняется Kafka / BPM / external integration logic:
|
||||
- сохранить или добавить correlation identifiers;
|
||||
- сохранить или добавить `operation_id`, где это релевантно;
|
||||
- логировать достаточно для дебага retries, duplicates и compensations;
|
||||
- никогда не логировать секреты или sensitive payloads.
|
||||
|
||||
---
|
||||
|
||||
## Backpressure и runtime load
|
||||
|
||||
- Воркеры должны явно ограничивать `maxJobsActive` и concurrency.
|
||||
- Нельзя использовать рост timeout или retry как механизм масштабирования.
|
||||
- Backpressure должен управляться через масштабирование воркеров и управление пропускной способностью.
|
||||
- Предположения о throughput воркеров должны быть документированы.
|
||||
- CPU / RAM saturation должна наблюдаться и иметь алерты.
|
||||
|
||||
---
|
||||
|
||||
## Безопасность и аудит
|
||||
|
||||
- Сервисы должны поддерживать JWT / OAuth2 там, где это применимо.
|
||||
- Административные операции должны быть защищены role-based или attribute-based access control.
|
||||
- Секреты нельзя хранить в репозитории.
|
||||
- Административные действия, такие как retry / cancel / compensate / migrate, должны быть аудитируемыми.
|
||||
|
||||
---
|
||||
|
||||
## CI / CD и production safety
|
||||
|
||||
Минимально обязательные гейты **для изменений, где это релевантно**:
|
||||
- unit tests
|
||||
- coverage threshold
|
||||
- static analysis
|
||||
- API compatibility checks
|
||||
- schema compatibility checks
|
||||
- BPM + worker integration tests
|
||||
- resilience tests для поведения timeout / retry / DLQ
|
||||
|
||||
Правила деплоя:
|
||||
- деплой BPMN только через pipeline;
|
||||
- деплой воркеров только через pipeline;
|
||||
- ручной деплой BPMN в production запрещён;
|
||||
- критичные изменения retry / timeout / jobType не должны вноситься только через UI без трассируемости в VCS.
|
||||
Reference in New Issue
Block a user