Self-hosted платформа генерации валидных данных для российского финтеха и госсектора.
Validum создаёт вымышленные данные для тестовых стендов. Совпадения с реальными людьми или организациями случайны: пространство ИНН, ФИО и адресов конечно, а справочники взяты из открытых источников. Не загружайте результат в продуктивные системы и не используйте как основание для юридически значимых решений.
Государственные справочники (ED807/ED808, КЛАДР, ОКВЭД-2, коды ЦБ) персональных данных не содержат. Соответствие требованиям 152-ФЗ обеспечивается тем, что в контуре нет боевых данных клиентов, — но ответственность за то, что вы генерируете и куда кладёте, остаётся на операторе.
Три команды — от нуля до данных. Нужен только JDK 21 (или Docker).
# 1. Справочник участников ЦБ (обязателен: 1380 участников, 370 банков)
java -jar validum.jar fetch-bik -o data/ED807.xml
# 2. Профиль клиента с реквизитами, банком и счётом
java -jar validum.jar generate individual --seed 42
# 3. Тысяча клиентов в CSV / SQL / JSON
java -jar validum.jar generate individual --seed 42 -n 1000 --format csv -o clients.csv
java -jar validum.jar generate individual --seed 42 -n 1000 --format sql --dialect postgres -o seed.sqlСобрать jar: ./gradlew :validum-cli:shadowJar → validum-cli/build/libs/validum.jar.
Тесты jar не пересобирают. После правок кода
./gradlew testобновит только тесты, аjava -jarпродолжит запускать старую сборку. Перед запуском CLI после изменений —./gradlew build(он включаетshadowJar) или точечно./gradlew :validum-cli:shadowJar. Признак устаревшего jar:Unknown options: '--…'на опции, которая в коде уже есть.
Пошаговые сценарии под конкретные задачи — в docs/recipes/
(фикстуры в JUnit, заливка в БД, нерезиденты, ДУЛ, ED807/ED808, детерминизм, Docker).
- Быстрый старт
- Зачем нужен Validum
- Ключевые свойства
- Что уже работает
- Четыре способа использовать
- Готовые сценарии
- Каскадные дефолты
- Пакетная генерация (Batch)
- Валидация (Validation API)
- Экспорт (CSV / JSON Array)
- CLI (P3.1)
- Allure Extension (P3.2)
- Явный выбор банка (P3.3)
- Юрлица и ИП
- Полный справочник ЦБ РФ
- Быстрый старт
- REST API
- Java-библиотека
- Архитектура
- Структура репозитория
- Сборка и тесты
- CI
- Docker
- Roadmap
- Для контрибьюторов
- Лицензия
Тестирование банковских систем (АБС) требует данных, которые проходят валидацию:
- ИНН — контрольные разряды по алгоритму ФНС;
- СНИЛС — контрольное число по алгоритму ПФР;
- ОГРН / ОГРНИП — контрольная цифра по алгоритму ФНС;
- КПП, ОКПО — по алгоритмам ФНС/Росстата;
- ОКВЭД-2 — из полного справочника ОК 029-2014 (3069 позиций) вместе с наименованием;
- Расчётные счета — контрольный ключ по Положению Банка России № 809-П;
- БИК и корсчета — из справочника ЦБ РФ.
Проблема:
- Обычные генераторы (
Faker,Mockaroo) выдают поверхностные данные — контрольные суммы не сходятся. - Боевые данные нельзя — нарушение 152-ФЗ.
- Облачные SaaS нельзя в закрытом контуре банка.
Validum решает:
- Генерирует валидные данные — контрольные суммы сходятся.
- Работает внутри периметра —
docker compose upи никаких внешних вызовов. - Обеспечивает воспроизводимость — фиксированный
seed. - Поддерживает каскадные дефолты.
- Пакетную генерацию — до 10 000 профилей.
- 8 эндпоинтов валидации.
- Экспорт — JSON, JSON-массив, CSV.
- CLI без Spring — fat JAR на Picocli (P3.1).
- Allure Extension для JUnit 5 (P3.2).
- Явный выбор банка —
.bik/.bank(P3.3).
| Свойство | Что это значит |
|---|---|
| Валидность | Все данные проходят контрольные суммы ФНС, ПФР, Росстата, ЦБ РФ |
| Связанность | ФИО ↔ пол ↔ паспорт ↔ счёт ↔ БИК ↔ адреса ↔ КПП ↔ email |
| Воспроизводимость | Один seed → идентичный набор данных |
| Каскадные дефолты | Задаёшь age=16 — система сама делает несовершеннолетнего |
| Три типа субъектов | ФЛ, ИП, ЮЛ (7 ОПФ) |
| Четыре способа использовать | REST API · CLI · Java-библиотека · Allure Extension |
| Пакетная генерация | 3 эндпоинта /batch, до 10 000 профилей |
| Валидация | 8 эндпоинтов + 8 типов в CLI |
| Экспорт | JSON, JSON Array, CSV с UTF-8 BOM. CsvExporter — в core |
| Явный банк (P3.3) | .bik / .bank для ФЛ и ИП. Невалидный → 400 / exit 2 |
| Self-hosted | В закрытом контуре, без интернета |
| Zero-dependency core | Никаких Spring / Datafaker в ядре |
| CI-ready | GitHub Actions, зелёный билд |
| Zero LLM | Только детерминированные алгоритмы |
| Генератор / Валидатор | Что делает |
|---|---|
InnGenerator / InnCorruptor |
ИНН ФЛ (12) / ЮЛ (10) + порча |
SnilsGenerator / SnilsCorruptor |
СНИЛС (11) + порча |
OgrnGenerator |
ОГРН (13), ОГРНИП (15) |
KppGenerator / OkpoGenerator |
КПП / ОКПО |
BikGenerator |
БИК, корсчёт, банк (из справочника ED807) |
AccountGenerator |
Счета по 809-П (40817, 40702, 40802, 40807) |
NameGenerator |
ФИО — 3.8 млн (P0.1) |
PassportGenerator |
Паспорт РФ / FOREIGN (14/20/45) |
AddressGenerator |
Адреса из КЛАДР: 90 субъектов, ~125 тыс. населённых пунктов, ~2 млн улиц (P0.2, ГАР) |
ContactGenerator |
Мобильные + email из ФИО (P0.3) |
IndividualProfileGenerator |
Профиль ФЛ + .bik / .bank (P3.3) |
IpProfileGenerator |
Профиль ИП — композиция ФЛ + ОГРНИП |
OrganizationProfileGenerator |
Профиль ЮЛ (7 ОПФ, P2.2) + ОКВЭД-2 |
OkvedGenerator / OkvedRegistry |
ОКВЭД-2: 3069 позиций, код + наименование |
CsvExporter + 3 флаттенера |
Плоский CSV (P3.1a). Общий для API, CLI, Allure |
| 7 валидаторов | ИНН, СНИЛС, ОГРН, ОГРНИП, КПП, ОКПО, БИК |
- Генерация:
POST /api/v1/generate/{individual,ip,organization},GET/POST /scenarios/*. - Батчи (P1.2):
POST /generate/{individual,ip,organization}/batch. - Валидация (P1.3 + P2.3): 8 эндпоинтов
/validate/*. - Экспорт (P1.4):
?format=json|json-array|csv. - P3.3:
bikв DTO,GlobalExceptionHandler → 400наIllegalArgumentException.
Fat JAR на Picocli, без Spring (~15 МБ вместе со справочниками КЛАДР и ОКВЭД, старт ~300 мс).
| Команда | Что |
|---|---|
validum generate individual [...] |
Профиль(и) ФЛ + --bik (P3.3) |
validum generate ip [...] |
Профиль(и) ИП + --bik (P3.3) |
validum generate organization [...] |
Профиль(и) ЮЛ (без --bik) |
validum validate <type> <value> |
Валидация (8 типов), exit 0/1 |
validum fetch-bik [--offline] |
Справочник ЦБ |
validum scenarios / version |
Утилиты |
JUnit 5 Extension. @ValidumSeed / @ValidumGenerate → плоский JSON в Allure-отчёте. Только ФЛ.
| Способ | Когда нужен | Как |
|---|---|---|
| REST API | Автотесты (JUnit + REST Assured), Swagger UI | docker compose up → POST /api/v1/generate/... |
| CLI | Скрипты сетапа, CI-пайплайны, «100 профилей в CSV» | java -jar validum.jar generate individual --count 100 --format csv -o profiles.csv |
| Allure Extension | JUnit 5: attach профиля в Allure-отчёт | @ValidumSeed(42) / @ValidumGenerate(...) |
| Java-библиотека | Свой генератор поверх core | <dependency>io.github.validum-tech:validum-core:0.1.0</dependency> |
| Slug | Возраст | Категория | Пакет | Счёт |
|---|---|---|---|---|
adult-resident-with-account |
19 | КЛИЕНТ | БАЗОВЫЙ | ✅ |
adult-resident-without-account |
19 | КЛИЕНТ | БАЗОВЫЙ | — |
pensioner-male |
65 | ПЕНСИОНЕР | ПЕНСИОННЫЙ | ✅ |
pensioner-female |
60 | ПЕНСИОНЕР | ПЕНСИОННЫЙ | ✅ |
salary-client |
35 | ЗАРПЛАТНИК | ЗАРПЛАТНЫЙ | ✅ |
non-resident-with-residence-permit |
32 | НЕРЕЗИДЕНТ | БАЗОВЫЙ | ✅ |
foreigner-with-visa |
28 | НЕРЕЗИДЕНТ | БАЗОВЫЙ | ✅ |
serviceman |
20 | КЛИЕНТ | БАЗОВЫЙ | ✅ |
minor |
16 | КЛИЕНТ | БАЗОВЫЙ | ✅ |
Документы ДУЛ в этих сценариях: нерезидент с ВНЖ — паспорт иностранного гражданина (10) + вид на жительство (12); иностранец с визой — паспорт (10) + виза; военнослужащий — паспорт РФ (21) + военный билет (07); несовершеннолетний — паспорт РФ (21).
# REST — список сценариев
curl http://localhost:8080/api/v1/scenarios
# REST — пакет из 100 профилей ФЛ в Москве
curl -X POST http://localhost:8080/api/v1/generate/individual/batch \
-H "Content-Type: application/json" \
-d '{"count":100,"seed":42,"region":"MOSCOW"}'# CLI — 100 профилей ФЛ в CSV
java -jar validum.jar generate individual --seed 42 --count 100 --format csv -o profiles.csv
java -jar validum.jar generate individual --seed 42 --as-of 2026-01-01 --format csv -o reproducible.csv
# CLI — 10 ЮЛ типа ГУП в Москве → JSON-массив
java -jar validum.jar generate organization --seed 42 --count 10 --type SE --region MOSCOW --format json-array -o gup.json// Java-библиотека
IndividualProfile adult = IndividualScenarios.createAdultResidentWithAccount(42L);
IpProfile ip = IpProfileGenerator.generate(
IndividualProfileGenerator.builder().seed(42L).age(35).build(), 42L);
OrganizationProfile gup = OrganizationProfileGenerator.builder()
.seed(42L).organizationType(OrganizationType.SE).region(Region.MOSCOW)
.build().generate();Фишка Validum: вместо хардкоженных негативных сценариев — ортогональные параметры с умными дефолтами.
| Ты задал | Что получаешь |
|---|---|
| (ничего) | 19 лет, паспорт в 14, действ. до 20, РФ, КЛИЕНТ, счёт, email из ФИО |
age=16 |
Несовершеннолетний, паспорт в 14, действительный, SINGLE |
age=23 |
Паспорт менялся в 20, действ. до 45 |
age=23 + passportWasExchanged=false |
Паспорт в 14, просрочен в 20 |
age=50 |
Паспорт бессрочный, выдан в 45 |
age=16 + region=MOSCOW |
Несовершеннолетний + Москва + серия 77xx |
residencyCountry=TJ |
Все РФ-поля → TJ + иностранный паспорт |
categoryClient=ЗАРПЛАТНИК |
Пакет автоматически «ЗАРПЛАТНЫЙ» |
organizationType=LLC |
Префикс «ООО», OKOPF=65, OKFS=16 |
organizationType=SE |
Префикс «ГУП», OKOPF=61, OKFS=14, бюджетная |
emailDomainMode=REALISTIC |
Email на yandex.ru / mail.ru |
bik="044525225" (P3.3) |
Банк Сбербанк, все его реквизиты |
bik="000000000" (P3.3) |
400 / exit 2 с понятным сообщением |
- Валидность — дефолт. Порча — только явным параметром.
- Явное значение всегда побеждает auto.
- Параметры ортогональны.
- Мягкие каскады.
age=16+familyStatus=MARRIED→ MARRIED. - Детерминизм с seed. Один
seed→ один набор данных. - Детерминизм между днями —
asOf. Возраст и сроки документов считаются от даты расчёта:--as-of 2026-01-01(CLI) или"asOf": "2026-01-01"(REST). Одинseed+ одна дата дают одинаковый профиль в любой день; безasOfдатой считается сегодняшняя. - P3.3:
bank>bik> случайный; невалидный БИК — явная ошибка, не откат.
Один запрос — до 10 000 профилей. Первый использует seed, второй seed+1 и т.д.
POST /api/v1/generate/individual/batch
{
"count": 100,
"seed": 42,
"region": "MOSCOW",
"categoryClient": "ЗАРПЛАТНИК"
}P3.3: в батч можно добавить "bik": "044525225" — все профили в пакете получат этот банк.
Ответ (по умолчанию json): { "count": 100, "seed": 42, "profiles": [...] }.
Ограничение: count 1–10 000. Вне — 400 Bad Request.
8 эндпоинтов (P1.3 + P2.3).
# ИНН
curl -X POST http://localhost:8080/api/v1/validate/inn \
-H "Content-Type: application/json" -d '{"inn":"500100732259"}'
# → { "valid": true, "type": "INDIVIDUAL", "details": "Valid INN checksum" }
# Счёт по 809-П — контрольный ключ зависит от БИК, поэтому передаём оба поля.
# Пара счёт + БИК взята из официального справочника ЦБ (ED807).
curl -X POST http://localhost:8080/api/v1/validate/account \
-H "Content-Type: application/json" \
-d '{"account":"30101810145250000440","bik":"044525000"}'
# → { "valid": true, "type": "RUB", "details": "Valid account checksum (письмо 515 / 809-П)" }
#
# Без "bik" проверить нельзя — в ответе будет
# { "valid": false, "details": "Укажите BIK: контрольный ключ зависит от БИК банка" }
# БИК (с названием банка; нужен справочник БИК — шаг 1 быстрого старта)
curl -X POST http://localhost:8080/api/v1/validate/bik \
-H "Content-Type: application/json" -d '{"bik":"044525225"}'
# → { "valid": true, "type": "BANK", "details": "<название банка из справочника ED807>" }
# ОКПО (P2.3)
curl -X POST http://localhost:8080/api/v1/validate/okpo \
-H "Content-Type: application/json" -d '{"okpo":"12345676"}'
# ОГРНИП (P2.3)
curl -X POST http://localhost:8080/api/v1/validate/ogrnip \
-H "Content-Type: application/json" -d '{"ogrnip":"304500116000157"}'Коды ответа: 200 — проверка выполнена (смотрите valid); 400 — {"error":"invalid_argument","message":"…"} на некорректное значение; 503 — {"error":"bik_source_missing","message":"…"}, если справочник БИК не настроен.
Или из CLI (exit 0/1):
java -jar validum.jar validate inn 500100732259
# → {"valid":true,"type":"INDIVIDUAL","details":"Valid INN checksum"} → exit 0format |
Content-Type | Кому |
|---|---|---|
json (дефолт) |
application/json |
Автотесты, обёртка {count, seed, profiles} |
json-array |
application/json |
Скрипты (Python, JS) |
csv |
text/csv;charset=UTF-8 |
Excel, импорт в БД |
curl -OJ -X POST "http://localhost:8080/api/v1/generate/individual/batch?format=csv" \
-H "Content-Type: application/json" -d '{"count":100,"seed":42}'
# → validum-individual-2026-10-22.csvЧто внутри:
- UTF-8 BOM — Excel откроет кириллицу корректно.
- Плоская структура —
passportSeries,registrationCity,bankBik, ... - Экранирование — RFC 4180.
Архитектурно (P3.1a): CsvExporter + 3 флаттенера живут в core (ru.validum.core.export) — используются REST API, CLI и Allure.
Плоская таблица + INSERT для PostgreSQL / Oracle / MySQL — один файл сразу заливается в тестовую БД.
java -jar validum.jar generate individual --format sql --dialect postgres --table clients \
-n 1000 -o seed.sql
# psql -h localhost -U qa -d testdb -f seed.sql
# Oracle: --dialect oracle → CREATE TABLE "clients" ("inn" VARCHAR2(400) ...)
# MySQL: --dialect mysql → CREATE TABLE `clients` (`inn` VARCHAR(400) ...)
# --no-ddl → только INSERT, если таблица уже естьТип колонки выводится из имени: terrorist и blocked — логический (BOOLEAN / TINYINT(1) / NUMBER(1)), age — целое, остальное — текст, чтобы ИНН, СНИЛС и счёт сохраняли ведущие нули. Апострофы экранируются (' → ''), null пишется как NULL. Архитектурно — ru.validum.core.sql (SqlDialect, SqlExporter), без внешних зависимостей.
Fat JAR на Picocli. Без Spring. ~15 МБ со справочниками, старт ~300 мс.
.\gradlew :validum-cli:shadowJar
# → validum-cli/build/libs/validum.jarjava -jar validum.jar --help
java -jar validum.jar version
java -jar validum.jar scenarios# 1 профиль ФЛ в stdout (JSON)
java -jar validum.jar generate individual --seed 42
# 100 профилей ФЛ в CSV
java -jar validum.jar generate individual --seed 42 --count 100 --format csv -o profiles.csv
# 10 ИП в Москве → JSON-массив
java -jar validum.jar generate ip --seed 1 --count 10 --region MOSCOW --format json-array -o ip.json
# 5 ЮЛ типа ГУП
java -jar validum.jar generate organization --seed 42 --count 5 --type SE --region MOSCOW --format csv -o gup.csvjava -jar validum.jar validate inn 500100732259 # → exit 0
java -jar validum.jar validate inn 500100732258 # → exit 1
java -jar validum.jar validate ogrnip 304500116000157Паттерн в скрипте:
if ((& java -jar validum.jar validate inn $inn) -and ($LASTEXITCODE -eq 0)) {
Write-Host "OK: $inn"
}# Online: скачивает ZIP с cbr.ru, распаковывает
java -jar validum.jar fetch-bik -o data/ED807.xml
# Offline (банковский контур, нет доступа к cbr.ru)
java -jar validum.jar fetch-bik --offline
# → инструкция + exit 0, ничего не скачивает--formatявный. Не угадываем по расширению.- Плоский JSON. Те же поля, что CSV. Нужен 1:1 REST — используй REST.
fetch-bik --offline. Для банковских контуров.- UTF-8 stdout. Windows-консоль по умолчанию cp866 — форсим UTF-8 в
main(). --outputне зависит от консоли. Даже без фикса кодовой страницы файл пишется в UTF-8.
testImplementation("io.github.validum-tech:validum-allure:0.1.0")@ExtendWith(ValidumExtension.class)
class ClientCreationTest {
@Test
@ValidumSeed(42)
void testCreateClient() {
// Attachment "Validum Profile" (application/json) в отчёте
}
@Test
@ValidumGenerate(seed = 42, age = 16, region = "MOSCOW")
void testMinorClient() {
// Профиль age=16, Москва — в отчёте
}
}Что в attachment'е: плоский JSON, те же поля, что CSV (fullName, passportSeries, registrationCity, bankBik, ...). Переиспользуется IndividualProfileFlattener.
Ограничения:
- Только ФЛ (ИП/ЮЛ — P3.2b, если попросят).
- Без Spring. Зависимости:
validum-core+allure-jupiter:2.35.3+junit-jupiter-api+ Jackson. - Best-effort attach. Без Allure runtime — warning в stderr, тест не падает.
По умолчанию банк выбирается случайно из справочника. QA хотят фиксировать «тест со Сбербанком» — теперь это возможно.
// По БИК
IndividualProfile sber = IndividualProfileGenerator.builder()
.seed(42L)
.bik("044525225")
.build().generate();
// Готовый Bank
Bank vtb = BikSources.resolve("data/ED807.xml").findByBik("044525187").orElseThrow();
IndividualProfile vtbProfile = IndividualProfileGenerator.builder()
.seed(42L)
.bank(vtb)
.build().generate();
// ИП наследует через IndividualProfile
IpProfile ip = IpProfileGenerator.generate(
IndividualProfileGenerator.builder()
.seed(42L).age(35).bik("044525225").build(), 42L);# OK → банк Сбербанк
curl -X POST http://localhost:8080/api/v1/generate/individual \
-H "Content-Type: application/json" \
-d '{"seed":42,"bik":"044525225"}'
# → { ..., "bank": { "bik": "044525225", "name": "ПАО Сбербанк", ... } }
# 400 → БИК не найден
curl -X POST http://localhost:8080/api/v1/generate/individual \
-H "Content-Type: application/json" \
-d '{"seed":42,"bik":"000000000"}'
# → 400 { "error": "invalid_argument", "message": "БИК не найден в справочнике: 000000000..." }# OK → все профили в CSV с банком Сбербанк
java -jar validum.jar generate individual --seed 42 --count 10 --bik 044525225 --format csv -o sber.csv
# exit 2 → невалидный БИК
java -jar validum.jar generate individual --bik 000000000 --format csv
# → stderr: "Ошибка: БИК не найден в справочнике: 000000000..."- Приоритет:
bank>bik> случайный. - Невалидный БИК — явная ошибка. Не откатываемся на случайный: REST 400, CLI exit 2.
- ЮЛ с банком.
OrganizationProfileсодержитbank(БИК из ED807) иaccount(40702, ключ по 515) —--bank-bik/bik/.bank(...). - Справочник обязателен. Источник — файл ED807 через
BikSources; встроенного демо-набора нет.
ОПФ (7 типов, P2.2):
| Значение | Префикс | OKOPF | OKFS | Бюджет |
|---|---|---|---|---|
LLC |
ООО | 65 | 16 | Небюджетная |
JSC |
АО | 47 | 16 | Небюджетная |
PJSC |
ПАО | 47 | 16 | Небюджетная |
NCO |
НКО | 85 | 16 | Некоммерческая |
FOUNDATION |
Фонд | 88 | 16 | Некоммерческая |
SE |
ГУП | 61 | 14 | Бюджетная |
ME |
МУП | 62 | 13 | Бюджетная |
Композиция над IndividualProfile:
- Всё как у ФЛ (ФИО, паспорт, ИНН 12, СНИЛС, адреса, счёт)
- Отчество — фиксированное «ИП Автотеста»
- ОГРНИП — 15 цифр, валидный по ФНС
- Детерминизм:
seed=42→ тот же ОГРНИП - P3.3:
bikработает через base
Справочник обязателен: встроенного демо-набора в продукте нет. Если файла ED807 нет,
генерация банковских реквизитов возвращает понятную ошибку (REST 503 bik_source_missing,
CLI exit 2), а не подставляет чужие реквизиты.
# CLI (P3.1)
java -jar validum.jar fetch-bik -o data/ED807.xml
# Вручную
curl.exe -o data\newbik.zip "http://www.cbr.ru/s/newbik"
Expand-Archive -Path data\newbik.zip -DestinationPath data\
Rename-Item data\*.xml data\ED807.xmlПарсер: WINDOWS-1251, namespace urn:cbr-ru:ed:v2.0, фильтры PtType="20", PSAC, CRSA, ACAC. Из ~1380 участников — 370 банков (все участники — participants --file).
Одна цепочка на API и CLI (ru.validum.core.bank.BikSources):
- явный путь —
--file, свойствоvalidum.bik.file; - переменная окружения
VALIDUM_BIK_FILE; - системное свойство
validum.bik.file; data/ED807.xml.
P3.3: .bik("044525225") ищет банк в загруженном справочнике; не найдено — явная ошибка.
- JDK 21 (Temurin, Corretto, OpenJDK)
- Gradle Wrapper (в репо)
- Docker Desktop (опционально)
git clone https://github.com/Validum-Tech/validum.git
cd validum
./gradlew buildНа Windows:
.\gradlew.bat build.\gradlew :validum-cli:shadowJar
java -jar .\validum-cli\build\libs\validum.jar generate individual --seed 42 --format csv -o profile.csv./gradlew :validum-api:bootRun- Swagger UI: http://localhost:8080/swagger-ui.html
- Health: http://localhost:8080/actuator/health
Запрос (полный):
{
"seed": 42,
"gender": "MALE",
"age": 23,
"passportWasExchanged": false,
"residencyCountry": "TJ",
"passportType": "FOREIGN",
"fioScript": "LATIN",
"corrupt": ["INN"],
"region": "MOSCOW",
"categoryClient": "ЗАРПЛАТНИК",
"accountPackage": "VIP",
"familyStatus": "MARRIED",
"email": "custom@corp.ru",
"emailDomainMode": "REALISTIC",
"secretWord": "СЛОН",
"personalManager": "СЗА02",
"terrorist": false,
"blocked": false,
"bik": "044525225"
}Ответ (фрагмент):
{
"fullName": "Кузнецов Александр Владимирович",
"gender": "MALE",
"birthDate": "1988-03-12",
"age": 38,
"inn": "500100732259",
"snils": "12345678900",
"bank": { "bik": "044525225", "name": "ПАО Сбербанк", "corrAccount": "30101810400000000225" },
"account": "40817810123456789012"
}- Батчи:
POST /generate/{individual,ip,organization}/batch,count1–10 000, P3.3:bik. - Валидация: 8 эндпоинтов
/validate/*. - Экспорт:
?format=json-array/?format=csv. - Сценарии:
GET /scenarios,POST /scenarios/{name}?seed=42.
curl -X POST http://localhost:8080/api/v1/generate/individual \
-H "Content-Type: application/json" -d '{"seed":42}'Один и тот же seed даёт идентичный ответ при каждом запросе.
validum-core — чистая Java-библиотека без Spring и внешних зависимостей.
// ФЛ — фасады
IndividualProfile adult = IndividualScenarios.createAdultResidentWithAccount(42L);
IndividualProfile pensioner = IndividualScenarios.createPensionerMale(42L);
// ФЛ — каскады
IndividualProfile minor = IndividualProfileGenerator.builder()
.age(16).seed(42L).build().generate();
// ФЛ — с конкретным банком (P3.3)
IndividualProfile sber = IndividualProfileGenerator.builder()
.seed(42L).bik("044525225").build().generate();
// ИП — с детерминизмом
IpProfile ip = IpProfileGenerator.generate(
IndividualProfileGenerator.builder().seed(42L).age(35).build(), 42L);
// ЮЛ (7 ОПФ)
OrganizationProfile gup = OrganizationProfileGenerator.builder()
.seed(42L).organizationType(OrganizationType.SE).region(Region.MOSCOW)
.build().generate();
// Экспорт в CSV (P3.1a)
String csv = CsvExporter.toCsv(IndividualProfileFlattener.flattenAll(List.of(sber)));
// Валидация (P1.3 + P2.3)
boolean innOk = InnValidator.isValidIndividual("500100732259");
boolean ogrnipOk = OgrnipValidator.isValid("304500116000157");
boolean okpoOk = OkpoValidator.isValid("12345676");┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐
│ validum-api │ │ validum-cli │ │ validum-allure │
│ (Spring Boot 3.5) │ │ (Picocli, ~15 МБ) │ │ (JUnit 5 Extension) │
│ 19 REST-эндпоинтов │ │ 8 команд │ │ @ValidumSeed │
└──────────┬───────────┘ └──────────┬───────────┘ └──────────┬───────────┘
│ │ │
└─────────────────────────┼─────────────────────────┘
│ зависит от
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ validum-core (чистая Java, ZERO-DEP) │
│ │
│ ФЛ (.bik / .bank) · ЮЛ (7 ОПФ) · ИП (композиция) │
│ │
│ Экспорт: CsvExporter + 3 флаттенера → API, CLI, Allure │
│ Валидация: Inn, Snils, Ogrn, Ogrnip, Kpp, Okpo, Bik │
│ Стратегии: BikSource · AddressStrategy · FiasMode │
│ Каскады: age → passport, region → addresses, category → package │
│ АБС-специфика: AbsDefaults │
└─────────────────────────────────────────────────────────────────────────┘
Принцип: validum-core не зависит от Spring, БД, сети и внешних библиотек.
| Паттерн | Что решает |
|---|---|
BikSource |
Один интерфейс, источник — файл ED807 |
AddressStrategy / FiasMode |
Три адреса в одно / полный FIAS |
| Каскадные дефолты | Задаёшь одно — согласуется всё остальное |
| Композиция ИП | ИП = ФЛ + ОГРНИП |
IndividualScenarios |
Именованные сценарии → стабильный контракт |
CsvExporter + флаттенеры в core |
Один CSV-код для REST, CLI, Allure |
.bik / .bank (P3.3) |
Явный выбор банка, приоритет bank > bik > случайный |
validum/
├── validum-core/ ← 567 тестов (zero-dep)
│ ├── src/main/java/ru/validum/core/
│ │ ├── random/ · common/ · abs/ · inn/ · snils/ · ogrn/
│ │ ├── bank/ · account/ · name/ · passport/ · address/ · contact/
│ │ ├── profile/ ← IndividualProfileGenerator + .bik / .bank
│ │ ├── organization/
│ │ ├── export/ ← CsvExporter + 3 флаттенера
│ │ └── validation/ ← 7 валидаторов
│ └── src/main/resources/ ← names/ · addresses/ · emails/ · secret_words.txt · managers.txt
│
├── validum-api/ ← 80 тестов (Spring Boot)
│ └── src/main/java/ru/validum/api/
│ ├── config/ · controller/ (+GlobalExceptionHandler — P3.3)
│ ├── service/ · mapper/ · dto/
│
├── validum-cli/ ← 55 тестов (Picocli, без Spring)
│ └── src/main/java/ru/validum/cli/
│ ├── ValidumCli · OutputFormat · OutputWriter · BikSourceResolver
│ ├── Generate{Individual,Ip,Organization}Command (+ --bik в individual/ip)
│ └── ValidateCommand · FetchBikCommand · ScenariosCommand · VersionCommand
│
├── validum-allure/ ← 19 тестов (JUnit 5 Extension, без Spring)
│ └── src/main/java/ru/validum/allure/
│ ├── ValidumSeed · ValidumGenerate · ValidumExtension
│
├── data/ED807.xml ← Справочник ЦБ, НЕ коммитится
├── docs/ ← README · SCENARIOS · ROADMAP · RELEASING · recipes/
├── docker-compose.yml
└── gradle/libs.versions.toml
./gradlew build # всё
./gradlew test # только тестыНа Windows:
.\gradlew.bat build --rerun-tasksОтчёты: build/reports/tests/test/index.html (тесты) и
*/build/reports/jacoco/test/html/index.html (покрытие).
CLI fat JAR:
.\gradlew :validum-cli:shadowJar
# → validum-cli/build/libs/validum.jar| Модуль | Тестов |
|---|---|
validum-core |
567 |
validum-api |
80 |
validum-cli |
55 |
validum-allure |
19 |
| Итого | 721 |
Покрытие строк по jacoco (прогон 30.10.2026): validum-core — 91,4% (2360/2581), validum-api — 92,2% (404/438), validum-cli — 65,8% (325/494). Слабейшие пакеты core: validation, common, address; полностью покрыты passport, snils, ogrn, random. HTML-отчёт — validum-core/build/reports/jacoco/test/html/index.html.
GitHub Actions на каждый push / PR в main:
- Ubuntu + JDK 21 (Corretto), кэш Gradle
./gradlew build --no-daemon— тесты всех четырёх модулей- Сводка в Summary: тесты по модулям + покрытие строк (jacoco) для
validum-core,validum-apiиvalidum-cli - Артефакты: HTML-отчёты тестов (14 дней), покрытие jacoco, готовый
validum.jar(30 дней)
docker compose up -d
# → Swagger UI: http://localhost:8080/swagger-ui.html- Multi-stage build:
gradle:8.14-jdk21→eclipse-temurin:21-jre-alpine - Non-root user, container-aware JVM
- Справочник ЦБ монтируется как volume:
./data:/app/data:ro - Healthcheck:
/actuator/health - Размер: ~250–350 МБ
DNS (Windows Docker Desktop): если UnknownHostException — Settings → Docker Engine → "dns": ["8.8.8.8", "1.1.1.1"].
- Фундамент, ИНН/СНИЛС/ОГРН/ФИО/паспорта/адреса/счета/БИК
- REST API + Swagger UI + Actuator + Docker
- Каскадные дефолты, флаги, ЮЛ/ИП
- P0.1–P0.3 — ФИО (3,8 млн), адреса из КЛАДР (90 субъектов, 1,99 млн улиц), email/слова/менеджеры
- P1.2–P1.4 — batch, validation, экспорт
- P2.2–P2.3 — 7 ОПФ, ОКПО/ОГРНИП, расширенный КПП
- P3.1 — CLI + CSV в core
- P3.2 — Allure Extension
- P3.3 —
.bik/.bank
- 0.2 — транзакции (ED101, выписки ED210/211), справочники ГАР/ОКАТО, OpenAPI + SDK
- P1.1 — первая публикация в Maven Central (код готов, нужны секреты — см.
docs/RELEASING.md) - P2.1 — Транзакции
- P3.4 — Mock API по OpenAPI (3–5 дней)
- P4.2–P4.4 — Иностранные паспорта, Web UI, ML-датасеты
P2.4 — Банк для ЮЛ— сделано (30.10.2026)- P3.2b — Allure для ИП/ЮЛ (если попросят)
| Что | Где взять |
|---|---|
Fat jar validum.jar (+ .sha256) |
GitHub Releases |
Java-библиотеки (validum-core, validum-allure) |
GitHub Packages: io.github.validum-tech:*:0.1.0 |
| Контейнер API | docker compose up локально; Docker Hub — после 0.2 |
| Исходники | git clone → ./gradlew build |
Как выпускается версия (тег, секреты, Maven Central) — docs/RELEASING.md.
- JDK 21, Gradle Wrapper, IntelliJ IDEA / VS Code
- Java 21 Records, immutable, каскадные дефолты
- Фасады только для 3+ связанных полей
- Тесты:
src/test/, имя файла = имя класса,@DisplayNameна русском - Core — zero-dep, CLI и Allure — без Spring
- CSV и флаттенеры — в core
- P3.3: невалидный БИК → явное исключение
- Форк → ветка
feature/my-feature - Тесты до реализации
./gradlew build— все 721 зелёные, покрытие не падает- PR — CI прогонит сборку на Linux и Windows
Подробности и чек-лист — CONTRIBUTING.md.
Уязвимости — не в Issues, а на security@validum.tech (SECURITY.md).
Apache License 2.0 — см. LICENSE.
- GitHub Issues: github.com/Validum-Tech/validum/issues
- Домен: validum.tech
- Организация: Validum-Tech
Validum — данные, которые проходят валидацию. 721 тест. 370 банков. REST API + CLI + Java-библиотека + Allure. P0.1–P0.3, P1.2–P1.4, P2.2, P2.3, P3.1–P3.3, P4.1 закрыты, ДУЛ (11 видов) — в профиле, REST и CLI. 9 КУС-сценариев, экспорт ED807/ED808, Docker.