Сиды (наполнение БД)
Каталог сидов: apps/core-api/prisma/seeds.
| Файл | Что делает |
|---|---|
init.seed.ts | точка входа: порядок запуска и границы транзакций |
platform-role.seed.ts | PlatformRoleSeeder — пять строк roles по детерминированным id |
geo.seed.ts | GeoSeeder — гео-справочник: таймзоны, страны, локации, связки |
geo-data.transformer.ts | загрузка и нормализация данных RestCountries (без обращения к БД) |
dev-fixtures.seed.ts | DevFixturesSeeder — пользователи, команда и проекты для разработки |
Сиды — не «тестовые данные для удобства»: без PlatformRoleSeeder на чистой базе нельзя создать ни
одного пользователя, включая платформенных, потому что строки roles перестали заводиться на лету
при регистрации.
Как запускается
Заголовок раздела «Как запускается»nx run core-api:prisma:seed:runПод капотом — ts-node -r tsconfig-paths/register --project tsconfig.app.json prisma/seeds/init.seed.ts
(рабочая директория apps/core-api). Таргет поддерживает конфигурации development, stage и
production с соответствующими env-файлами.
Все сиды идемпотентны: работают через upsert по детерминированным ключам, повторный прогон не
плодит дублей.
init.seed.ts — порядок и границы транзакций
Заголовок раздела «init.seed.ts — порядок и границы транзакций»PlatformRoleSeeder— своя транзакция, идёт первым.GeoSeeder— отдельная транзакция, обёрнута вtry/catch.DevFixturesSeeder— только приAPP_ENV ∈ {development, stage}(по умолчаниюdevelopment).
Транзакции разделены намеренно: GeoSeeder ходит во внешний API, и его сбой не имеет права забрать
с собой роли. Параметры транзакций — { maxWait: 5000, timeout: 300000 }; большой таймаут нужен
из-за объёма гео-данных.
Внешний источник справочника стран (
restcountriesv3.1) объявлен устаревшим и отдаёт заглушку вместо массива, поэтомуGeoSeederсейчас падает на любой машине. Ошибка печатается и не роняет прогон — роли и dev-фикстуры создаются. Практическое следствие: после сидирования справочникиcountries/locations/timezonesпусты, аProfile.timezoneIdиProfile.locationIdзаполнить нечем. URL источника переопределяется переменнойRESTCOUNTRIES_URL.
PlatformRoleSeeder — роли платформы
Заголовок раздела «PlatformRoleSeeder — роли платформы»Заводит пять строк roles по фиксированным id: CUSTOMER, EMPLOYEE, ADMIN, OPERATOR,
ARBITER. Id берутся из констант, а не генерируются:
| Роль | Источник id |
|---|---|
CUSTOMER, EMPLOYEE | CUSTOMER_ROLE, EMPLOYEE_ROLE — apis/providers/user-api/data-access |
ADMIN, OPERATOR, ARBITER | ADMIN_ROLE_ID, OPERATOR_ROLE_ID, ARBITER_ROLE_ID — apis/shared |
Три платформенных id продублированы ещё и в предикате частичного индекса
users_on_roles_single_platform_role (см. migrations). Менять их можно только
вместе с миграцией, пересоздающей индекс.
GeoSeeder — гео-справочник
Заголовок раздела «GeoSeeder — гео-справочник»Наполняет timezones, countries, locations, countries_timezones, locations_timezones из
RestCountries. Порядок работы:
fetchRestCountries()— HTTP-загрузка с retry (3 попытки, пауза 1 с); URL — изRESTCOUNTRIES_URL, иначеhttps://restcountries.com/v3.1/all?fields=cca2,cca3,name,timezones. Ответ обязан быть массивом, иначе ошибка.transformToGeoData(raw)— чистая нормализация в структуруGeoData: набор таймзон (со смещением, разобранным из строк видаUTC+01:00), плоские записи стран, дерево локацийREGION → SUBREGION → COUNTRY → CITYи списки связок.upsertTimezones→upsertCountries(поcca2) →upsertLocations→upsertCountryTimezones→upsertLocationTimezones. Локации создаются по возрастанию уровня, чтобы родитель существовал раньше потомка; из-заNULLвparent_idвместоupsertиспользуется параfindFirst+update/create.
Шаги связаны строковыми ключами, которые сидер превращает в реальные UUID.
DevFixturesSeeder — фикстуры разработки
Заголовок раздела «DevFixturesSeeder — фикстуры разработки»Опорный набор данных, из которого можно войти каждой ролью и увидеть проект в двух состояниях.
Все id детерминированы (d0000000-…, d1000000-…, d2000000-…).
Пользователи платформы
Заголовок раздела «Пользователи платформы»| Роль | Вход | |
|---|---|---|
admin@crewsforge.com | ADMIN | одноразовый код admin-api; пароля нет (passwordHash = null) |
operator@crewsforge.com | OPERATOR | то же |
arbiter@crewsforge.com | ARBITER | то же |
Домен crewsforge.com обязан входить в ADMIN_ALLOWED_DOMAINS — иначе admin-api отвергнет и
регистрацию, и вход по allowlist’у домена. Значение по умолчанию совпадает с dokploy/.env.example.
Каждому пользователю выдаётся ровно одна платформенная роль: вторая физически отвергается
частичным уникальным индексом БД.
Клиентские пользователи
Заголовок раздела «Клиентские пользователи»Домен example.com — намеренно не платформенный: в админку эти учётки попадать не должны. Пароль у
всех один — DevPassword123!; пишется только при создании (соль bcrypt случайна, перезапись хеша на
каждом прогоне ломала бы идемпотентность строки).
| Кто | Членство в команде | |
|---|---|---|
founder@example.com | заказчик (Customer + CustomerProfile) | — |
team.lead@example.com | сотрудник, 96 мес. опыта, FULL_TIME | role = ADMIN, canSign = true, canSubmit = false |
team.engineer@example.com | сотрудник, 48 мес. опыта, CONTRACT | role = VIEWER, canSign = false, canSubmit = true |
Двое участников команды разведены по осям намеренно: role — это уровень доступа, canSign /
canSubmit — полномочия, и фикстура показывает, что они независимы. Команда — Forge Crew
(slug forge-crew, статус ACTIVE, проставлен verifiedAt).
Проекты
Заголовок раздела «Проекты»| Проект | Статус | Чем полезен |
|---|---|---|
Internal knowledge base | DRAFT | черновик: описание есть, бюджет и категория не заданы |
Marketplace payouts revamp | TEAM_MATCHING | опорная точка мэтчинга: категория WEB_DEVELOPMENT, валюта USD, вилка бюджета $20 000 – $35 000 в минорных единицах, teamId ещё пуст |
Что засевается, а что нет
Заголовок раздела «Что засевается, а что нет»- Засевается: роли платформы (всегда), гео-справочник (пока внешний источник отдаёт данные),
а на
development/stage— шесть пользователей, команда и два проекта. - Не засевается: навыки, специализации, языки, спецификации, планы, этапы, деньги, задачи очереди — эти таблицы наполняет только код сервисов.
Применимость сидов на живой БД проверяется интеграционным тестом
apps/core-api-e2e/src/schema/seed-data.integration.spec.ts.