@rt-tools/agent-kit 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. package/README.md +194 -30
  2. package/assets/agents/business-analyst.md +74 -0
  3. package/assets/agents/project-manager.md +70 -0
  4. package/assets/agents/qa-engineer.md +72 -0
  5. package/assets/agents/skill-curator.md +110 -0
  6. package/assets/agents/spec-critic.md +44 -0
  7. package/assets/agents/spec-writer.md +50 -0
  8. package/assets/checks/board.github.mjs +329 -0
  9. package/assets/checks/check-board.github.mjs +181 -0
  10. package/assets/checks/check-doc-paths.mjs +163 -0
  11. package/assets/checks/check-dupes.mjs +277 -0
  12. package/assets/checks/check-lib-layers.mjs +573 -0
  13. package/assets/checks/check-reuse.mjs +208 -0
  14. package/assets/checks/check-schema-drift.mjs +186 -0
  15. package/assets/checks/check-specs.mjs +1086 -0
  16. package/assets/checks/check-styles.mjs +109 -0
  17. package/assets/checks/rt-kit-checks.config.mjs +134 -0
  18. package/assets/checks/task-new.github.mjs +198 -0
  19. package/assets/commands/skill-curator.md +70 -0
  20. package/assets/defaults/gate-map.sh +106 -0
  21. package/assets/defaults/project.sh +204 -0
  22. package/assets/hooks/browser-device-id.sh +0 -0
  23. package/assets/hooks/browser-guard-device-id.sh +2 -1
  24. package/assets/hooks/browser-guard-no-asking.sh +27 -0
  25. package/assets/hooks/browser-guard-no-listing.sh +2 -1
  26. package/assets/hooks/browser-guard-no-other-drivers.sh +2 -1
  27. package/assets/hooks/browser-guard-require-select.sh +2 -1
  28. package/assets/hooks/commit-msg.sh +1 -1
  29. package/assets/hooks/constitution-index.sh +5 -4
  30. package/assets/hooks/dev-server-guard.sh +8 -6
  31. package/assets/hooks/docs-guard.sh +223 -37
  32. package/assets/hooks/git-guard-delivery.sh +171 -31
  33. package/assets/hooks/git-guard-main.sh +1 -0
  34. package/assets/hooks/git-guard-push-tests.sh +34 -13
  35. package/assets/hooks/glossary-load.sh +23 -0
  36. package/assets/hooks/grill-gate.sh +96 -0
  37. package/assets/hooks/lint-after-edit.sh +155 -30
  38. package/assets/hooks/qa-dataid-guard.sh +72 -32
  39. package/assets/hooks/reuse-first-guard.sh +105 -34
  40. package/assets/hooks/skill-gate-rearm.sh +1 -0
  41. package/assets/hooks/skill-gate.sh +75 -15
  42. package/assets/hooks/skill-loaded.sh +1 -0
  43. package/assets/hooks/sql-guard.sh +606 -56
  44. package/assets/hooks/task-context-load.sh +100 -0
  45. package/assets/hooks/task-flow-guard.sh +118 -0
  46. package/assets/laws/{access.md → application/access.md} +1 -4
  47. package/assets/laws/{locales.md → application/locales.md} +1 -3
  48. package/assets/laws/application/money.md +41 -0
  49. package/assets/laws/application/ownership.md +32 -0
  50. package/assets/laws/{search-visibility.md → application/search-visibility.md} +1 -1
  51. package/assets/laws/code-structure.md +7 -6
  52. package/assets/laws/delivery.md +53 -3
  53. package/assets/laws/entity-editing.md +49 -55
  54. package/assets/laws/entity-models.md +4 -14
  55. package/assets/laws/frontend-application.md +5 -5
  56. package/assets/laws/lib-imports.md +14 -1
  57. package/assets/laws/lists.md +33 -0
  58. package/assets/laws/navigation.md +40 -0
  59. package/assets/laws/project-documentation.md +27 -8
  60. package/assets/laws/reuse-first.md +26 -21
  61. package/assets/laws/shared-code.md +13 -1
  62. package/assets/laws/verifiability.md +30 -1
  63. package/assets/laws/work-conduct.md +59 -0
  64. package/assets/patterns/admin-lists-screen.md +131 -0
  65. package/assets/patterns/admin-nav-item.md +71 -0
  66. package/assets/patterns/angular-patterns-state.md +29 -22
  67. package/assets/patterns/api-layer-pair.md +40 -30
  68. package/assets/patterns/browser-verification-measure.md +41 -38
  69. package/assets/patterns/browser-verification-stand.md +106 -42
  70. package/assets/patterns/component-structure-new.md +33 -32
  71. package/assets/patterns/dependencies-upgrade.md +65 -0
  72. package/assets/patterns/doc-style-sweep.md +65 -28
  73. package/assets/patterns/doc-style-write.md +36 -33
  74. package/assets/patterns/entity-aside.md +136 -0
  75. package/assets/patterns/entity-models-new.md +124 -0
  76. package/assets/patterns/entity-store.md +91 -0
  77. package/assets/patterns/git-workflow-commit.azure.md +259 -0
  78. package/assets/patterns/git-workflow-commit.github.md +337 -0
  79. package/assets/patterns/git-workflow-commit.gitlab.md +283 -0
  80. package/assets/patterns/git-workflow-merge.md +42 -25
  81. package/assets/patterns/git-workflow-migration.md +61 -31
  82. package/assets/patterns/git-workflow-restart.md +20 -20
  83. package/assets/patterns/lib-layers-move.md +50 -32
  84. package/assets/patterns/lib-layers-new.md +41 -29
  85. package/assets/patterns/ownership-scope-resolve.md +69 -0
  86. package/assets/patterns/permissions-procedure.md +35 -33
  87. package/assets/patterns/platform-access-di.md +39 -25
  88. package/assets/patterns/pricing-quote.md +71 -0
  89. package/assets/patterns/reuse-first-extend.md +22 -22
  90. package/assets/patterns/seo-page.md +52 -40
  91. package/assets/patterns/seo-verify.md +48 -29
  92. package/assets/patterns/shared-code-new.md +37 -31
  93. package/assets/patterns/spec-driven-domain.md +60 -37
  94. package/assets/patterns/spec-driven-rule.md +55 -40
  95. package/assets/patterns/styling-bem-component.md +43 -32
  96. package/assets/patterns/styling-bem-layout.md +30 -24
  97. package/assets/patterns/task-flow-close.md +154 -0
  98. package/assets/patterns/task-flow-resume.md +94 -0
  99. package/assets/patterns/task-flow-start.md +129 -0
  100. package/assets/patterns/testing-e2e.md +53 -51
  101. package/assets/patterns/testing-unit.md +70 -46
  102. package/assets/patterns/translations-key.md +32 -19
  103. package/assets/patterns/ts-procedure.md +24 -25
  104. package/assets/rules/angular-patterns.md +50 -27
  105. package/assets/rules/api-layer.md +46 -28
  106. package/assets/rules/browser-verification.md +67 -48
  107. package/assets/rules/component-structure.md +43 -27
  108. package/assets/rules/dependencies.md +66 -0
  109. package/assets/rules/doc-style.md +95 -39
  110. package/assets/rules/entity-conventions.md +78 -0
  111. package/assets/rules/entity-models.md +70 -0
  112. package/assets/rules/git-workflow.azure.md +116 -0
  113. package/assets/rules/git-workflow.github.md +123 -0
  114. package/assets/rules/git-workflow.gitlab.md +113 -0
  115. package/assets/rules/lib-layers.md +56 -30
  116. package/assets/rules/lists.md +73 -0
  117. package/assets/rules/navigation.md +78 -0
  118. package/assets/rules/ownership-scope.md +63 -0
  119. package/assets/rules/permissions.md +43 -25
  120. package/assets/rules/platform-access.md +57 -29
  121. package/assets/rules/pricing.md +64 -0
  122. package/assets/rules/reuse-first.md +57 -43
  123. package/assets/rules/seo.md +51 -30
  124. package/assets/rules/shared-code.md +51 -26
  125. package/assets/rules/spec-driven.md +107 -51
  126. package/assets/rules/styling-bem.md +54 -39
  127. package/assets/rules/task-flow.md +150 -0
  128. package/assets/rules/testing.md +78 -47
  129. package/assets/rules/translations.md +48 -31
  130. package/assets/rules/typescript-conventions.md +57 -27
  131. package/assets/skills/agent-kit.md +85 -0
  132. package/assets/skills/write-a-skill.md +108 -0
  133. package/assets/templates/gate-map.sh +23 -15
  134. package/assets/templates/implementation.md +14 -8
  135. package/assets/templates/pattern.md +1 -1
  136. package/assets/templates/project.sh +32 -19
  137. package/assets/templates/rule.md +2 -2
  138. package/assets/variants.json +20 -0
  139. package/assets/workflows/feature.js +134 -0
  140. package/assets/workflows/plan.js +150 -0
  141. package/bin/agent-kit.d.ts.map +1 -1
  142. package/bin/agent-kit.js +78 -5
  143. package/bin/agent-kit.js.map +1 -1
  144. package/bin/prompt.d.ts +5 -0
  145. package/bin/prompt.d.ts.map +1 -1
  146. package/bin/prompt.js +19 -7
  147. package/bin/prompt.js.map +1 -1
  148. package/index.d.ts +1 -0
  149. package/index.d.ts.map +1 -1
  150. package/index.js +1 -0
  151. package/index.js.map +1 -1
  152. package/lib/assets.d.ts +8 -3
  153. package/lib/assets.d.ts.map +1 -1
  154. package/lib/assets.js +13 -3
  155. package/lib/assets.js.map +1 -1
  156. package/lib/catalog.d.ts +52 -5
  157. package/lib/catalog.d.ts.map +1 -1
  158. package/lib/catalog.js +104 -16
  159. package/lib/catalog.js.map +1 -1
  160. package/lib/commands.d.ts +22 -1
  161. package/lib/commands.d.ts.map +1 -1
  162. package/lib/commands.js +202 -14
  163. package/lib/commands.js.map +1 -1
  164. package/lib/companion.d.ts +5 -1
  165. package/lib/companion.d.ts.map +1 -1
  166. package/lib/companion.js +29 -2
  167. package/lib/companion.js.map +1 -1
  168. package/lib/config.d.ts +26 -9
  169. package/lib/config.d.ts.map +1 -1
  170. package/lib/config.js +41 -15
  171. package/lib/config.js.map +1 -1
  172. package/lib/freshness.d.ts +14 -0
  173. package/lib/freshness.d.ts.map +1 -0
  174. package/lib/freshness.js +116 -0
  175. package/lib/freshness.js.map +1 -0
  176. package/lib/hooks-map.d.ts +27 -0
  177. package/lib/hooks-map.d.ts.map +1 -0
  178. package/lib/hooks-map.js +77 -0
  179. package/lib/hooks-map.js.map +1 -0
  180. package/lib/integrity.d.ts +36 -0
  181. package/lib/integrity.d.ts.map +1 -0
  182. package/lib/integrity.js +44 -0
  183. package/lib/integrity.js.map +1 -0
  184. package/lib/picker.d.ts +11 -1
  185. package/lib/picker.d.ts.map +1 -1
  186. package/lib/picker.js +44 -6
  187. package/lib/picker.js.map +1 -1
  188. package/lib/sync.d.ts +26 -0
  189. package/lib/sync.d.ts.map +1 -1
  190. package/lib/sync.js +59 -4
  191. package/lib/sync.js.map +1 -1
  192. package/lib/variants.d.ts +44 -0
  193. package/lib/variants.d.ts.map +1 -0
  194. package/lib/variants.js +82 -0
  195. package/lib/variants.js.map +1 -0
  196. package/package.json +1 -1
  197. package/rt-tools-agent-kit-0.5.0.tgz +0 -0
  198. package/assets/laws/admin-lists.md +0 -35
  199. package/assets/laws/admin-navigation.md +0 -38
  200. package/assets/patterns/git-workflow-commit.md +0 -175
  201. package/assets/rules/git-workflow.md +0 -106
  202. package/rt-tools-agent-kit-0.3.0.tgz +0 -0
@@ -2,35 +2,36 @@
2
2
  name: git-workflow-merge
3
3
  kind: pattern
4
4
  rule: git-workflow
5
- description: Паттерн правила git-workflow. Брать, когда главная ветка вливается в ветку задачи и разрешается конфликт — порядок слияния, разбор конфликта по роду файла, сверка дописанного веткой с очередью работ, проверки после разрешения, перечитывание тела уже открытого PR. Не брать для заведения ветки, коммита и PR — это паттерн git-workflow-commit.
5
+ description: Паттерн правила git-workflow. Брать, когда главная ветка вливается в ветку задачи и разрешается конфликт — порядок мержа, разбор конфликта по роду файла, сверка дописанного веткой с очередью работ, проверки после разрешения, перечитывание тела уже открытого PR. Не брать для заведения ветки, коммита и PR — это паттерн git-workflow-commit.
6
6
  ---
7
7
 
8
- # Вливание главной ветки в ветку задачи
8
+ # Мерж главной ветки в ветку задачи
9
9
 
10
- Паттерн правила `git-workflow`. Что при этом должно быть верно — закон `{{lawsDir}}/delivery.md`.
10
+ Паттерн правила `git-workflow`. Что при этом должно быть верно — закон
11
+ `docs/constitution/delivery.md`.
11
12
 
12
13
  ## Когда брать
13
14
 
14
15
  - PR отмечен конфликтующим, и его надо вернуть к сливаемому состоянию.
15
16
  - Главная ветка ушла вперёд, и ветку задачи надо подтянуть до проверок.
16
- - Коммит переносится отдельным выбором.
17
+ - Коммит переносится черри-пиком.
17
18
 
18
19
  ## Порядок
19
20
 
20
21
  ```bash
21
22
  git fetch origin
22
- git merge origin/<главная ветка> --no-edit
23
+ git merge origin/main --no-edit
23
24
  git diff --name-only --diff-filter=U # что встало конфликтом
24
25
  ```
25
26
 
26
27
  Список конфликтов читается целиком до первого разрешения: род файла решает приём, и разные
27
- файлы одного слияния разрешаются по-разному.
28
+ файлы одного мержа разрешаются по-разному.
28
29
 
29
- | Что встало конфликтом | Как разрешается |
30
- | --------------------- | ------------------------------------------------------------------------------ |
31
- | код | ловушка правила `git-workflow` про сторону-удаление; после — проверка повторов |
32
- | спек домена | сохранением обеих сторон — правило `spec-driven`; после — проверка спеков |
33
- | накопительный список | признаком отбора — паттерн `doc-style-sweep` |
30
+ | Что встало конфликтом | Как разрешается |
31
+ | -------------------------------- | ---------------------------------------------------------------------------------- |
32
+ | код | ловушка правила `git-workflow` про сторону-удаление; после — `npm run check:dupes` |
33
+ | спек в `docs/specs/` | сохранением обеих сторон — правило `spec-driven`; после — `npm run check:specs` |
34
+ | список работ (`docs/BACKLOG.md`) | признаком отбора — паттерн `doc-style-sweep` |
34
35
 
35
36
  ## Что дописала ветка, видно только от точки расхождения
36
37
 
@@ -38,22 +39,27 @@ git diff --name-only --diff-filter=U # что встало конфликт
38
39
  всем, что лежало в файле до неё.
39
40
 
40
41
  ```bash
41
- git diff "$(git merge-base origin/<главная ветка> HEAD)" HEAD -- <файл>
42
+ git diff "$(git merge-base origin/main HEAD)" HEAD -- docs/BACKLOG.md
42
43
  ```
43
44
 
44
45
  ## Дописанное веткой сверяется с очередью работ, а не переносится по умолчанию
45
46
 
46
- Раздел, который ветка дописала в накопительный список, к моменту слияния обычно уже стоит
47
- задачей: ветка живёт неделями, а замеченный по ходу дефект заводится задачей сразу. Перенести
48
- его второй раз — завести вторую запись об одной работе.
47
+ Раздел, который ветка дописала в список работ, к моменту мержа обычно уже стоит задачей:
48
+ ветка живёт неделями, а замеченный по ходу дефект заводится задачей сразу. Перенести его
49
+ второй раз — завести вторую запись об одной работе.
49
50
 
50
- Когда задача несёт то же содержание, сторона ветки не переносится:
51
+ ```bash
52
+ /opt/homebrew/bin/gh issue list --state all --limit 400 --search '<слова из раздела>' \
53
+ --json number,title,state
54
+ ```
55
+
56
+ Задача несёт то же содержание — сторона ветки не переносится:
51
57
 
52
58
  ```bash
53
- git checkout --theirs <файл> && git add <файл>
59
+ git checkout --theirs docs/BACKLOG.md && git add docs/BACKLOG.md
54
60
  ```
55
61
 
56
- При слиянии `--theirs` — влитая главная ветка, а `--ours` — ветка задачи; при перебазировании
62
+ В мерже `--theirs` — влитая главная ветка, а `--ours` — ветка задачи; при перебазировании
57
63
  стороны меняются местами. Взятая не та сторона стирает работу молча.
58
64
 
59
65
  ## Проверки после разрешения
@@ -62,21 +68,32 @@ git checkout --theirs <файл> && git add <файл>
62
68
 
63
69
  ```bash
64
70
  grep -rn '^<<<<<<< \|^>>>>>>> ' --exclude-dir=node_modules --exclude-dir=.git .
71
+ npm run check:docs && npm run check:specs && npm run check:dupes && npm run check:board
72
+ bash .claude/hooks/tests/run.sh # если конфликт задел хуки
65
73
  ```
66
74
 
67
- Следом гоняются проверки текстов, раскладки, повторов и очереди работ, а если конфликт задел
68
- хуки их сценарии. Коммит слияния подписывается так же, как любой другой, — паттерн
69
- `git-workflow-commit`. После пуша состояние читается у самого PR, а не по своему дереву.
75
+ Коммит мержа подписывается ботом тем же способом, что и любой другой, паттерн
76
+ `git-workflow-commit`. После пуша состояние читается у самого PR, а не по своему дереву:
70
77
 
71
- ## Тело открытого PR перечитывается после слияния
78
+ ```bash
79
+ /opt/homebrew/bin/gh pr view <номер> --json mergeable,mergeStateStatus
80
+ ```
72
81
 
73
- Отчёт описывал дерево на день, когда его написали. Вливание главной ветки меняет то, о чём он
74
- утверждает: тело говорит про записи, которые главная ветка к тому времени уже разобрала.
82
+ ## Тело открытого PR перечитывается после мержа
83
+
84
+ Отчёт описывал дерево на день, когда его написали. Мерж главной ветки меняет то, о чём он
85
+ утверждает: тело говорило, что оба дефекта заведены в `docs/BACKLOG.md`, а главная ветка этот
86
+ список к тому времени разобрала. Правится тело вызовом REST — `gh pr edit` в этом репозитории
87
+ отвечает отказом про Projects (classic) и до правки не доходит:
88
+
89
+ ```bash
90
+ /opt/homebrew/bin/gh api -X PATCH repos/<владелец>/<репозиторий>/pulls/<номер> -f body="$(cat тело.md)"
91
+ ```
75
92
 
76
93
  ## Частые промахи
77
94
 
78
95
  - «Сохранить обе стороны» применено ко всем файлам одинаково: в спеке это верно, в коде и в
79
- накопительном списке — нет.
96
+ списке работ — нет.
80
97
  - Сторона ветки перенесена без сверки с очередью работ: одна работа стала двумя записями.
81
98
  - После разрешения прогнана сборка, а проверки текстов — нет: конфликта в них сборке не видно.
82
99
  - Тело PR оставлено прежним: ревьювер читает утверждение о дереве, которого больше нет.
@@ -2,57 +2,87 @@
2
2
  name: git-workflow-migration
3
3
  kind: pattern
4
4
  rule: git-workflow
5
- description: Паттерн правила git-workflow. Брать при правке схемы хранилища и каталога миграций прогон цепочки на одноразовом хранилище, написание файла миграции разницей, догон локального хранилища. Не брать для коммита и PR — это паттерн git-workflow-commit.
5
+ description: Паттерн правила git-workflow. Брать при правке prisma/schema.prisma и prisma/migrations/**готовые команды одноразового контейнера, написание файла миграции через migrate diff, накат локальной базы. Не брать для коммита и PR — это паттерн git-workflow-commit.
6
6
  ---
7
7
 
8
8
  # Миграция и прогон цепочки
9
9
 
10
- Паттерн правила `git-workflow`. Что при этом должно быть верно — закон `{{lawsDir}}/delivery.md`.
10
+ Паттерн правила `git-workflow`. Что при этом должно быть верно — закон
11
+ `docs/constitution/delivery.md`.
11
12
 
12
13
  ## Когда брать
13
14
 
14
- - Правится схема хранилища.
15
- - Заводится или переименовывается каталог миграции.
16
- - Ветка с новой миграцией готовится к слиянию.
15
+ - Правится `prisma/schema.prisma`.
16
+ - Заводится или переименовывается каталог в `prisma/migrations/`.
17
+ - Ветка с новой миграцией готовится к мержу.
17
18
 
18
- ## Цепочка гоняется на одноразовом хранилище
19
+ ## Цепочка гоняется одной командой
19
20
 
20
- Линтеры, тесты и сборки порядок миграций не трогают вовсе, а проверка соответствия схемы идёт
21
- уже после слияния. Поэтому ветка прогоняется до слияния на пустом хранилище:
21
+ Локальные `lint`, `test`, `check:all` и сборки порядок миграций не трогают вовсе, а шаг
22
+ `Migrations match schema` в `.github/workflows/deploy.yml` идёт уже после мержа. Проверка
23
+ стоит гейтом пуша и зовётся руками:
22
24
 
23
25
  ```bash
24
- docker run -d --rm --name <проба> -e <пароль> -p <порт>:<порт> <образ хранилища>
25
- docker exec <проба> <проверка готовности> # накат до готовности падает на соединении
26
- <адрес хранилища> npx <инструмент> migrate deploy
27
- <адрес хранилища> npx <инструмент> migrate diff --from-config-datasource --to-schema <схема> --exit-code
28
- docker stop <проба>
26
+ npm run check:schema
29
27
  ```
30
28
 
31
- Одноразовое хранилище, а не своё: гард запросов отбивает схемные команды, и завести базу под
32
- проверку иначе нечем. Адрес ставится префиксом самой команды экспорт между вызовами не живёт.
29
+ Она накатывает цепочку на теневую базу ту же, что рабочая, с суффиксом `_gate_shadow`, —
30
+ сравнивает её со схемой и сносит. Своя база при этом не трогается: сверка с ней судила бы о
31
+ состоянии машины, а не репозитория. Погашенный докер и боевой адрес проверка пропускает
32
+ молча.
33
33
 
34
- ## Файл миграции пишется тем же хранилищем
34
+ Когда базы под рукой нет вовсе, та же цепочка гоняется на одноразовом контейнере:
35
35
 
36
- Команда разработчика для миграций не запускается: любое расхождение состояния она лечит
37
- предложением сбросить хранилище, а в локальном лежат данные владельца. Файл берётся разницей
38
- между накатанной цепочкой и схемой.
36
+ ```bash
37
+ docker run -d --rm --name <префикс>-migcheck -e POSTGRES_PASSWORD=migcheck -p 55432:5432 postgres:16-alpine
38
+ docker exec <префикс>-migcheck pg_isready -U postgres # накат до готовности падает на соединении
39
+ DATABASE_URL=postgresql://postgres:migcheck@localhost:55432/postgres npx prisma migrate deploy
40
+ DATABASE_URL=postgresql://postgres:migcheck@localhost:55432/postgres npx prisma migrate diff \
41
+ --from-config-datasource --to-schema prisma/schema.prisma --exit-code
42
+ docker stop <префикс>-migcheck
43
+ ```
44
+
45
+ Адрес ставится префиксом самой команды — `export` между вызовами не живёт.
46
+
47
+ ## Файл миграции пишется тем же контейнером
48
+
49
+ `prisma migrate dev` не запускается ни командой, ни через `npm run prisma:migrate`: любое
50
+ расхождение состояния он лечит предложением сбросить базу, а в локальной базе лежат объекты и
51
+ брони владельца. Файл берётся разницей между накатанной цепочкой и схемой:
52
+
53
+ ```bash
54
+ DATABASE_URL=postgresql://postgres:migcheck@localhost:55432/postgres npx prisma migrate diff \
55
+ --from-config-datasource --to-schema prisma/schema.prisma --script \
56
+ > prisma/migrations/<метка>_<имя>/migration.sql
57
+ ```
58
+
59
+ Каталог заводится **после** наката цепочки: пустой каталог, попавший в `migrate deploy`,
60
+ помечается применённым, и его содержимое на этот контейнер уже не встанет.
39
61
 
40
- Каталог заводится **после** наката цепочки: пустой каталог, попавший в накат, помечается
41
- применённым, и его содержимое на это хранилище уже не встанет.
62
+ ## Локальная база догоняет ветку
42
63
 
43
- ## Локальное хранилище догоняет ветку
64
+ ```bash
65
+ npx prisma migrate deploy
66
+ ```
44
67
 
45
- Переименованная миграция остаётся в нём под прежним именем, и накат падает на «объект уже
46
- существует». Состояние правится отметкой о применении, повторный накат его не чинит.
68
+ Переименованная миграция остаётся в ней под прежним именем, и накат падает на
69
+ `relation already exists`. Состояние правится, повторный накат его не чинит:
70
+
71
+ ```bash
72
+ npx prisma migrate resolve --applied <новое имя>
73
+ ```
47
74
 
48
75
  ## Частые промахи
49
76
 
50
77
  - Метку времени ставит момент создания, а порядок применения лексикографический: миграция из
51
- ветки, начатой раньше, встаёт перед той, от которой зависит. На существующем хранилище это
78
+ ветки, начатой раньше, встаёт перед той, от которой зависит. На существующей базе это
52
79
  незаметно — падает только накат с нуля.
53
- - Флаги инструмента не те, что в примерах из сети, и на неизвестный флаг он печатает справку, а
54
- не строку ошибки. Какие флаги есть сейчас, смотрят в его собственной справке.
55
- - Запись в боевое хранилище запрещена совсем: схема меняется миграцией через выкатку, данные
56
- через интерфейс.
57
- - Строки адресуются по первичному ключу, а не по маске: удаление по маске уносит вместе с
58
- пробными записями настоящие.
80
+ - Флаги `prisma migrate diff` не те, что в примерах из сети: `--from-url`, `--to-url`,
81
+ `--shadow-database-url` и `--to-schema-datamodel` сняты, а `prisma db execute` адреса
82
+ базы не принимает вовсе и берёт его из `prisma.config.ts`. На неизвестный флаг обе команды
83
+ печатают справку, и промах виден только в ней. Какие флаги есть сейчас, смотрят в
84
+ `prisma migrate diff --help`, а не в этом тексте.
85
+ - Запись в боевую базу (порт 15432, прод-хост) запрещена совсем: схема меняется миграцией
86
+ через деплой, данные — через админку.
87
+ - Строки адресуются по первичному ключу, а не по маске: удаление по маске почты однажды унесло
88
+ вместе с тестовыми записями демонстрационные брони владельца.
@@ -2,48 +2,48 @@
2
2
  name: git-workflow-restart
3
3
  kind: pattern
4
4
  rule: git-workflow
5
- description: Паттерн правила git-workflow. Брать при ручном перезапуске прода — после правки окружения прода, при разборе выкатки, при подъёме контейнера на сервере. Команда с явным тегом образа по хешу коммита, способ узнать выкаченный хеш и чем сверять результат. Не брать для коммита и миграций — это паттерны git-workflow-commit и git-workflow-migration.
5
+ description: Паттерн правила git-workflow. Брать при ручном перезапуске прода — после правки .env.prod, при разборе выкатки, при подъёме контейнера на сервере. Готовые команды с IMAGE_TAG по sha, способ узнать выкаченный sha и чем сверять результат. Не брать для коммита и миграций — это паттерны git-workflow-commit и git-workflow-migration.
6
6
  ---
7
7
 
8
8
  # Ручной перезапуск прода
9
9
 
10
- Паттерн правила `git-workflow`. Что при этом должно быть верно — закон `{{lawsDir}}/delivery.md`.
10
+ Паттерн правила `git-workflow`. Что при этом должно быть верно — закон
11
+ `docs/constitution/delivery.md`.
11
12
 
12
13
  ## Когда брать
13
14
 
14
- - Правилось окружение прода, и контейнер надо поднять заново.
15
+ - Правился `.env.prod` и контейнер надо поднять заново.
15
16
  - Разбирается, что именно сейчас выкачено.
16
- - Контейнер поднимается на сервере руками, мимо выкатки по слиянию.
17
+ - Контейнер поднимается на сервере руками, мимо выкатки по мержу.
17
18
 
18
- ## Команда обязана нести хеш коммита
19
+ ## Команда обязана нести sha
19
20
 
20
- Выкатка ставит образы по хешу коммита. Без явного тега подъём контейнера подставляет умолчание
21
- «последний», а оно в реестре отстаёт от главной ветки — прод молча откатывается на старый образ
22
- и при этом отвечает:
21
+ `.github/workflows/deploy.yml` выкатывает образы по sha коммита. Без переменной `docker
22
+ compose` подставляет умолчание `latest`, а `latest` в реестре отстаёт от главной ветки — прод
23
+ молча откатывается на старый образ и при этом отвечает:
23
24
 
24
25
  ```bash
25
- IMAGE_TAG='<хеш>' docker compose -f <состав прода> --env-file <окружение> pull <службы>
26
- IMAGE_TAG='<хеш>' docker compose -f <состав прода> --env-file <окружение> up -d --no-build --remove-orphans
26
+ IMAGE_TAG='<sha>' docker compose -f docker-compose.prod.yml --env-file .env.prod pull migrate api ssr web
27
+ IMAGE_TAG='<sha>' docker compose -f docker-compose.prod.yml --env-file .env.prod up -d --no-build --remove-orphans
27
28
  ```
28
29
 
29
- ## Хеш берётся до перезапуска
30
+ ## Sha берётся до перезапуска
30
31
 
31
- У выкаченного контейнера или у последнего слияния в главную ветку:
32
+ У выкаченного контейнера или у последнего мержа в главную ветку:
32
33
 
33
34
  ```bash
34
35
  docker inspect <контейнер> --format '{{.Config.Image}}'
35
36
  ```
36
37
 
37
- ## Сверка идёт по журналу, а не по коду ответа
38
+ ## Сверка идёт по логу, а не по коду ответа
38
39
 
39
- Подмена образа видна только по пропавшим строкам нового кода: сводка запуска из журнала
40
- исчезает, хотя строка «приложение поднялось» остаётся на месте. После перезапуска — тот же
41
- осмотр образа и наличие ожидаемых строк в журнале.
40
+ Подмена образа видна только по пропавшим строкам нового кода: сводка `startup` с
41
+ `integrations` из логов исчезает, хотя `API is running` остаётся на месте. После перезапуска —
42
+ тот же `inspect` и наличие ожидаемых строк в логе.
42
43
 
43
44
  ## Частые промахи
44
45
 
45
46
  - Вывод «прод жив, значит выкатилось» — код ответа подмену образа не показывает.
46
- - Переменные окружения, секреты и записи имён ставятся **до** слияния: слияние выкатывает
47
- сразу, и ветка, зависящая от новой переменной, встаёт на проде до того, как переменную
48
- заведут.
49
- - Заход на сервер в автоматическом режиме режется правилом — нужен обычный.
47
+ - Переменные окружения, секреты и записи имён ставятся **до** мержа: мерж выкатывает сразу,
48
+ и ветка, зависящая от новой переменной, встаёт на проде до того, как переменную заведут.
49
+ - Заход на сервер по ssh в автоматическом режиме режется правилом — нужен обычный режим.
@@ -2,12 +2,13 @@
2
2
  name: lib-layers-move
3
3
  kind: pattern
4
4
  rule: lib-layers
5
- description: Паттерн правила lib-layers. Брать при переносе кода или символа между либами — с чего начинать, в каком порядке двигать домены, куда кладётся общее, что делать с границами, импортами и README обеих либ, чем проверять. Заведение и удаление самой либы — паттерн lib-layers-new.
5
+ description: Паттерн правила lib-layers. Брать при переносе кода или символа между либами — с чего начинать, в каком порядке двигать домены, что делать с границами, импортами и README обеих либ, и чем проверять. Заведение и удаление самой либы — паттерн lib-layers-new.
6
6
  ---
7
7
 
8
8
  # Перенести код между либами
9
9
 
10
- Паттерн правила `lib-layers`. Что при этом должно быть верно — закон `{{lawsDir}}/lib-imports.md`.
10
+ Паттерн правила `lib-layers`. Что при этом должно быть верно — закон
11
+ `docs/constitution/lib-imports.md`.
11
12
 
12
13
  ## Когда брать
13
14
 
@@ -15,63 +16,80 @@ description: Паттерн правила lib-layers. Брать при пер
15
16
  - Домен переносится в новую раскладку.
16
17
  - Общий код собирается из копий в одно место.
17
18
 
18
- ## Начинать с планов
19
-
20
- Решение о том, куда переезжает код, часто уже принято и записано, а принятое заново с ним
21
- расходится — и откатывать приходится целиком. Поиск по документам делается до первой правки:
19
+ ## Начинать с `docs/plans/`
22
20
 
23
21
  ```bash
24
- grep -rn "<имя либы>" <каталог планов>/
22
+ grep -rn "<имя либы>" docs/
25
23
  ```
26
24
 
25
+ Решение о том, куда переезжает код, часто уже принято и записано, а принятое заново с ним
26
+ расходится. Перенос утилит списка из-за этого делался дважды: первая редакция положила их в
27
+ `libs/common/util`, что запрещено первым же пунктом того самого плана, и её пришлось
28
+ откатывать целиком.
29
+
27
30
  ## Порядок задаёт граф зависимостей, а не список в плане
28
31
 
29
32
  Домен переносится после всех, от кого он зависит. Списки доменов в планах отсортированы по
30
- важности, и следование им в лоб заставляет временно расширять границы — а каждая временная
31
- строка в границах и есть та механическая проверка, ради которой нарезка затевалась.
33
+ важности, и следование им в лоб заставляет временно расширять границы.
32
34
 
33
35
  ```bash
34
- grep -rn "<алиас домена>" <каталоги кода> | sed 's/:.*//' | sort -u
36
+ grep -rn "@<область>/<семья>/<домен>" libs/ apps/ | sed 's/:.*//' | sort -u
35
37
  ```
36
38
 
37
- Рёбра выписываются поиском по алиасам домена и сортируются топологически.
39
+ Рёбра выписываются грепом по алиасам домена и сортируются топологически. Каждая временная
40
+ строка в границах — это ослабленная механическая проверка, ради которой нарезка и затевалась.
38
41
 
39
42
  ## Куда именно кладётся общее
40
43
 
41
44
  Своя либа заводится тогда, когда ни одна существующая код не видит.
42
45
 
43
- | Кому нужно | Куда |
44
- | ---------------------------------------------- | ------------------------------------------------------------- |
45
- | серверной стороне и фронту, без каркаса фронта | общая либа утилит |
46
- | только фронтам, тянет каркас | либа платформы служба и токен, либа общих компонентов вид |
47
- | предмету, у которого уже есть либа | в неё |
48
- | всем доменам одной семьи | основание семейства |
49
- | всей серверной стороне | тот слой утилит, что уже перечислен у каждого домена |
46
+ | Кому нужно | Куда |
47
+ | -------------------------------------- | ----------------------------------------------------------- |
48
+ | бэкенду или обоим фронтам, без Angular | `libs/common/util` |
49
+ | только фронтам, тянет Angular | `common/platform`сервис и токен, `common/ui`компонент |
50
+ | предмету, у которого уже есть либа | в неё: `site-routing`, `i18n`, `photo`, `captcha` |
51
+ | всем доменам одной семьи | основание семейства `<семья>/core` |
52
+ | всему бэкенду | тот слой `util`, что уже перечислен у каждого домена |
50
53
 
51
- Новых строк в границах при таком переезде не появляется — кроме права видеть контракт, если код
52
- его читает.
54
+ Новых строк в границах при таком переезде не появляется — кроме права видеть контракт, если
55
+ код его читает.
53
56
 
54
57
  ## После переезда
55
58
 
56
59
  1. **README обеих либ.** У той, откуда файл ушёл, и у той, куда пришёл: README перечисляет, что
57
60
  в либе лежит и кто её зовёт. Ни одна проверка эти тексты не читает.
58
- 2. **Порядок импортов.** Переезд алиаса его ломает, и приходит это ошибкой линтера, а не
59
- сборки. Автоправка есть только у линтера — в общий прогон с тестами и сборкой её флаг
60
- передавать нельзя, падает весь вызов.
61
- 3. **Линтер по всем затронутым проектам, а не по одному приложению.** Скрипт ошибается молча и
62
- не так, как человек: строка импорта не переписывается, а исчезает целиком. Сборка одного
63
- приложения до таких файлов не доходит — их находит только прогон по списку проектов.
61
+ 2. **Порядок импортов.** Переезд алиаса его ломает, и приходит это ошибкой `prettier/prettier`
62
+ из линта, а не из сборки:
63
+
64
+ ```bash
65
+ npx nx lint <project> --fix
66
+ ```
67
+
68
+ Флага `--fix` нет у `test` и `build`, поэтому в `run-many -t lint test` его передавать
69
+ нельзя — падает весь вызов.
70
+
71
+ 3. **Линт по всем затронутым проектам, а не по одному приложению.** Скрипт ошибается молча и не
72
+ так, как человек: строка импорта не переписывается, а исчезает целиком. При переносе утилит
73
+ списка так пропали импорты в шести файлах из восьми, и нашёл их прогон по списку проектов —
74
+ сборка одного приложения до этих файлов не дошла.
75
+
76
+ ```bash
77
+ npx nx run-many -t lint --projects=<список по изменённым файлам>
78
+ ```
64
79
 
65
80
  ## Проверить
66
81
 
67
- Проверка раскладки — и обязательно проверка повторов: перенос и есть тот момент, когда копия
68
- остаётся на старом месте.
82
+ ```bash
83
+ npm run check:layers
84
+ npm run check:dupes
85
+ ```
86
+
87
+ Второе обязательно: перенос и есть тот момент, когда копия остаётся на старом месте.
69
88
 
70
89
  ## Частые промахи
71
90
 
72
- - Новый адрес выбран без чтения планов — расходится с уже принятым решением.
91
+ - Новый адрес выбран без чтения `docs/plans/` — расходится с уже принятым решением.
73
92
  - Порядок переноса взят из списка в плане — приходится временно расширять границы.
74
93
  - README поправлен только у одной либы.
75
- - Линтер прогнан по приложению, а не по списку затронутых проектов — пропавшие импорты не
76
- видно.
77
- - Копия осталась на старом месте, а проверка повторов не гонялась.
94
+ - Линт прогнан по приложению, а не по списку затронутых проектов — пропавшие импорты не видно.
95
+ - Копия осталась на старом месте, а `check:dupes` не гонялся.
@@ -2,12 +2,13 @@
2
2
  name: lib-layers-new
3
3
  kind: pattern
4
4
  rule: lib-layers
5
- description: Паттерн правила lib-layers. Брать при заведении, переименовании или удалении либы — нужна ли либа вообще, генератор вместо голого вызова каркаса, тег, алиас, барель, README, чем добивать удаление. Перенос кода между уже существующими либами — паттерн lib-layers-move.
5
+ description: Паттерн правила lib-layers. Брать при заведении, переименовании или удалении либы — генератор вместо голого nx g, тег, алиас, барель, README, и чем добивать удаление. Перенос кода между уже существующими либами — паттерн lib-layers-move.
6
6
  ---
7
7
 
8
8
  # Завести или удалить либу
9
9
 
10
- Паттерн правила `lib-layers`. Что при этом должно быть верно — закон `{{lawsDir}}/lib-imports.md`.
10
+ Паттерн правила `lib-layers`. Что при этом должно быть верно — закон
11
+ `docs/constitution/lib-imports.md`.
11
12
 
12
13
  ## Когда брать
13
14
 
@@ -20,25 +21,29 @@ description: Паттерн правила lib-layers. Брать при зав
20
21
  У домена есть экраны, состояние и запросы. Механика, общая нескольким доменам, доменом не
21
22
  заводится: слои под неё останутся пустыми навсегда.
22
23
 
23
- Признак: если ни слой экранов, ни слой состояния, ни слой обращения к серверу наполнить не из
24
- чего — это утилиты, и им место в либе, которой они уже видны. У фронта такая либа есть всегда —
25
- основание семейства; у серверной стороны — тот слой утилит, что уже перечислен у каждого
26
- домена.
24
+ Признак: если ни `feature`, ни `data-access`, ни `api` наполнить не из чего это утилиты, и
25
+ им место в либе, которой они уже видны. У фронта такая либа есть всегда — основание семейства;
26
+ у бэкенда — тот слой `util`, что уже перечислен у каждого домена.
27
27
 
28
- Домен, заведённый под механику, живёт девятью либами на три файла кода: семь из них пустые, и у
29
- каждой свой манифест, свой конфиг прогонщика, барель, тег и алиас.
28
+ Так домен `list` жил девятью либами на три файла кода: семь либ пустых, и у каждой свои
29
+ `project.json`, `vitest.config.mts`, барель, тег и алиас.
30
30
 
31
- ## Заводится генератором, а не голым вызовом каркаса
31
+ ## Заводится генератором, а не голым `nx g`
32
32
 
33
- Генератор кладёт манифест, конфиг типов, конфиг прогонщика и барель разом. Голый вызов каркаса
34
- даёт конфиг прогонщика без настройки «успех при отсутствии тестов», и либа, у которой спек ещё
35
- нет, роняет общий прогон строкой «файлов тестов не найдено». Проверка раскладки смотрит на
36
- наличие файла, а не на его содержимое, поэтому такую либу она пропустит.
33
+ ```bash
34
+ node tools/generate-domain-lib.mjs
35
+ ```
36
+
37
+ Генератор кладёт `project.json`, `tsconfig.json`, `vitest.config.mts` и барель. Голый `nx g`
38
+ даёт конфиг vitest без `passWithNoTests`, и либа, у которой спек ещё нет, роняет
39
+ `nx run-many -t test` строкой «No test files found». Проверка раскладки смотрит на наличие
40
+ файла, а не на его содержимое, поэтому такую либу она пропустит.
37
41
 
38
42
  ## Что дописывается руками
39
43
 
40
- 1. Тег в конфиге границ домена — один на либу, равный имени и пути.
41
- 2. Алиас в конфиге путей.
44
+ 1. Тег в `eslint/boundaries/domains/<семья>-<домен>.config.mjs` — один на либу, равный имени и
45
+ пути.
46
+ 2. Алиас в `tsconfig.base.json`.
42
47
  3. README либы: что в ней лежит и кто её зовёт.
43
48
 
44
49
  Права на чужие либы выписываются строками с комментарием, зачем. Импорт, который «просто
@@ -46,25 +51,32 @@ description: Паттерн правила lib-layers. Брать при зав
46
51
 
47
52
  ## Удаление
48
53
 
49
- Удаление средствами гита оставляет за собой то, что гит не отслеживал, — кэш сборщика внутри
50
- удаляемого каталога, и проверка раскладки продолжает видеть его как домен без слоёв.
51
- Добивается обычным удалением каталога.
54
+ ```bash
55
+ git rm -r libs/<семья>/<домен>/<слой>
56
+ rm -rf libs/<семья>/<домен>/<слой>
57
+ ```
58
+
59
+ `git rm -r` оставляет за собой `node_modules/.vite` внутри удаляемого каталога, и проверка
60
+ раскладки продолжает видеть его как домен без слоёв. Добивать `rm -rf`.
52
61
 
53
62
  Следом снимаются тег, алиас и строки прав у тех, кто либу видел.
54
63
 
55
64
  ## Проверить
56
65
 
57
- Проверка раскладки смотрит слои, единственный тег, равный имени и пути, алиас, наличие
58
- манифеста, конфига прогонщика и бареля, пустой список зависимостей у общей либы, границы
59
- основания семейства и реэкспорты. Она стоит секунды — гоняется после любого создания,
60
- переименования или удаления.
66
+ ```bash
67
+ npm run check:layers
68
+ ```
69
+
70
+ Проверка смотрит слои, единственный тег = имя = путь, алиас, наличие `project.json`,
71
+ `vitest.config.mts` и `src/index.ts`, пустой список зависимостей у `common/util`, границы
72
+ основания семейства и реэкспорты. Секунды — гонять после любого создания, переименования или
73
+ удаления.
61
74
 
62
75
  ## Частые промахи
63
76
 
64
- - **Либа заведена под механику:** слои пустые и заполнять их нечем.
65
- - **Голый вызов каркаса** — конфиг прогонщика без настройки «успех при отсутствии тестов», и
66
- общий прогон краснеет.
67
- - **Удаление без добивания каталога** проверка видит призрак домена без слоёв.
68
- - **Либа, которую никто не импортирует, не проверена ничем.** Линтер и тесты проверяют её саму,
69
- а не договор с потребителем. Первый импортёр и есть первая проверка: слой моделей принимается
70
- после сборки и живого прогона сценария, а не по зелёному линтеру с тестами.
77
+ - Либа заведена под механику: слои пустые и заполнять их нечем.
78
+ - Голый `nx g` — конфиг vitest без `passWithNoTests`, и общий прогон тестов краснеет.
79
+ - Удаление без `rm -rf` — проверка видит призрак домена без слоёв.
80
+ - **Либа, которую никто не импортирует, не проверена ничем.** `nx lint` и `nx test` проверяют
81
+ её саму, а не договор с потребителем. Первый импортёр и есть первая проверка: слой моделей
82
+ принимается после `nx build` и живого прогона сценария, а не по зелёному `lint test`.