letopis 1.4.2 → 3.0.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 (123) hide show
  1. package/AGENT-CHEATSHEET.md +516 -398
  2. package/CHANGELOG.md +739 -0
  3. package/LICENSE +75 -21
  4. package/LICENSE-COMMERCIAL.md +49 -0
  5. package/README.md +1312 -1190
  6. package/api-contract.json +381 -0
  7. package/dist/acl.d.ts +81 -1
  8. package/dist/acl.js +281 -13
  9. package/dist/admin.d.ts +11 -141
  10. package/dist/admin.js +28 -186
  11. package/dist/auth.d.ts +20 -5
  12. package/dist/auth.js +80 -21
  13. package/dist/cache.d.ts +8 -1
  14. package/dist/cache.js +30 -8
  15. package/dist/chain.d.ts +46 -48
  16. package/dist/chain.js +556 -223
  17. package/dist/cli.js +73 -96
  18. package/dist/demo/booking.d.ts +352 -36
  19. package/dist/describe.d.ts +47 -0
  20. package/dist/describe.js +195 -0
  21. package/dist/errors.d.ts +77 -13
  22. package/dist/errors.js +231 -30
  23. package/dist/index.d.ts +62 -74
  24. package/dist/index.js +312 -155
  25. package/dist/internal.d.ts +7 -0
  26. package/dist/jsonschema.js +18 -17
  27. package/dist/load.d.ts +29 -17
  28. package/dist/load.js +235 -190
  29. package/dist/log.d.ts +121 -0
  30. package/dist/log.js +633 -0
  31. package/dist/mcp.d.ts +5 -7
  32. package/dist/mcp.js +194 -225
  33. package/dist/messages/access.d.ts +90 -0
  34. package/dist/messages/access.js +113 -0
  35. package/dist/messages/api.d.ts +237 -0
  36. package/dist/messages/api.js +304 -0
  37. package/dist/messages/boot.d.ts +201 -0
  38. package/dist/messages/boot.js +256 -0
  39. package/dist/messages/codes.d.ts +172 -0
  40. package/dist/messages/codes.js +173 -0
  41. package/dist/messages/index.d.ts +98 -0
  42. package/dist/messages/index.js +121 -0
  43. package/dist/messages/log.d.ts +229 -0
  44. package/dist/messages/log.js +102 -0
  45. package/dist/messages/mcp.d.ts +306 -0
  46. package/dist/messages/mcp.js +387 -0
  47. package/dist/messages/model.d.ts +256 -0
  48. package/dist/messages/model.js +314 -0
  49. package/dist/messages/query.d.ts +141 -0
  50. package/dist/messages/query.js +171 -0
  51. package/dist/messages/sql-access.d.ts +70 -0
  52. package/dist/messages/sql-access.js +87 -0
  53. package/dist/messages/sql-core.d.ts +164 -0
  54. package/dist/messages/sql-core.js +198 -0
  55. package/dist/messages/sql-time.d.ts +86 -0
  56. package/dist/messages/sql-time.js +111 -0
  57. package/dist/messages/sql-write.d.ts +246 -0
  58. package/dist/messages/sql-write.js +270 -0
  59. package/dist/messages/time.d.ts +23 -0
  60. package/dist/messages/time.js +29 -0
  61. package/dist/messages/types.d.ts +27 -0
  62. package/dist/messages/types.js +5 -0
  63. package/dist/messages/write.d.ts +452 -0
  64. package/dist/messages/write.js +572 -0
  65. package/dist/model.d.ts +77 -60
  66. package/dist/model.js +43 -34
  67. package/dist/ops.d.ts +35 -0
  68. package/dist/ops.js +101 -0
  69. package/dist/pglite.d.ts +0 -9
  70. package/dist/pglite.js +3 -1
  71. package/dist/registry.d.ts +3 -19
  72. package/dist/registry.js +3 -16
  73. package/dist/signals.d.ts +1 -5
  74. package/dist/signals.js +1 -5
  75. package/dist/sql.d.ts +9 -1
  76. package/dist/sql.js +175 -107
  77. package/dist/sync.d.ts +10 -4
  78. package/dist/sync.js +90 -17
  79. package/dist/tx.d.ts +21 -2
  80. package/dist/tx.js +76 -13
  81. package/dist/typed.d.ts +252 -53
  82. package/dist/types.d.ts +93 -90
  83. package/dist/types.js +17 -14
  84. package/dist/up.d.ts +56 -35
  85. package/dist/up.js +229 -83
  86. package/dist/uuid.d.ts +8 -0
  87. package/dist/uuid.js +14 -6
  88. package/dist/validate.d.ts +13 -1
  89. package/dist/validate.js +82 -33
  90. package/dist/watch.d.ts +10 -16
  91. package/dist/watch.js +36 -77
  92. package/dist/write.d.ts +87 -17
  93. package/dist/write.js +441 -206
  94. package/llms.txt +48 -31
  95. package/package.json +13 -14
  96. package/sql/10-core.sql +7 -50
  97. package/sql/15-errors.sql +64 -10
  98. package/sql/20-context.sql +18 -9
  99. package/sql/30-validate.sql +79 -30
  100. package/sql/40-class.sql +41 -115
  101. package/sql/50-acl.sql +8 -13
  102. package/sql/60-write.sql +220 -676
  103. package/sql/70-read.sql +11 -13
  104. package/sql/80-auth.sql +109 -42
  105. package/sql/90-time.sql +108 -947
  106. package/sql/95-seed.system.sql +7 -14
  107. package/sql/99-revision.sql +6 -1
  108. package/sql/README.md +32 -24
  109. package/sql/migrate/0009-restore-rev.tenants-name.sql +10 -0
  110. package/sql/migrate/0010-impersonation-no-account.sql +5 -0
  111. package/sql/migrate/0011-key-lock.otp-enabled.sql +7 -0
  112. package/sql/migrate/README.md +18 -0
  113. package/AGENT-CHEATSHEET.en.md +0 -488
  114. package/MIGRATION.md +0 -190
  115. package/README.en.md +0 -2910
  116. package/dist/import.d.ts +0 -185
  117. package/dist/import.js +0 -820
  118. package/dist/project.d.ts +0 -359
  119. package/dist/project.js +0 -1258
  120. package/sql/75-history.sql +0 -436
  121. package/sql/88-derived.sql +0 -1236
  122. package/sql/migrate/0006-changed-paths.sql +0 -3
  123. package/sql/migrate/0007-secret-account-fk.sql +0 -12
@@ -0,0 +1,256 @@
1
+ export declare const model: {
2
+ 'model.end_no_targets': {
3
+ code: "invalid_class";
4
+ ru: string;
5
+ };
6
+ 'model.class_name_invalid': {
7
+ code: "invalid_class";
8
+ ru: string;
9
+ };
10
+ 'model.hub_name_reserved': {
11
+ code: "invalid_class";
12
+ ru: string;
13
+ hint: string;
14
+ };
15
+ 'model.field_name_dollar': {
16
+ code: "invalid_class";
17
+ ru: string;
18
+ };
19
+ 'model.end_name_invalid': {
20
+ code: "invalid_class";
21
+ ru: string;
22
+ };
23
+ 'model.key_field_type': {
24
+ code: "invalid_class";
25
+ ru: string;
26
+ };
27
+ 'model.key_end_type': {
28
+ code: "invalid_class";
29
+ ru: string;
30
+ };
31
+ 'model.key_unknown_name': {
32
+ code: "invalid_class";
33
+ ru: string;
34
+ };
35
+ 'model.unset_required_end': {
36
+ code: "invalid_class";
37
+ ru: string;
38
+ };
39
+ 'model.schema_default_where': {
40
+ code: "invalid_class";
41
+ ru: string;
42
+ };
43
+ 'model.schema_ref_unsupported': {
44
+ code: "invalid_class";
45
+ ru: string;
46
+ };
47
+ 'model.schema_recursive': {
48
+ code: "invalid_class";
49
+ ru: string;
50
+ };
51
+ 'model.schema_def_not_found': {
52
+ code: "invalid_class";
53
+ ru: string;
54
+ };
55
+ 'model.schema_node_not_object': {
56
+ code: "invalid_class";
57
+ ru: string;
58
+ };
59
+ 'model.schema_keyword_unsupported': {
60
+ code: "invalid_class";
61
+ ru: string;
62
+ };
63
+ 'model.schema_format_unsupported': {
64
+ code: "invalid_class";
65
+ ru: string;
66
+ };
67
+ 'model.schema_field_dollar': {
68
+ code: "invalid_class";
69
+ ru: string;
70
+ };
71
+ 'model.pattern_trailing_backslash': {
72
+ code: "invalid_class";
73
+ ru: string;
74
+ };
75
+ 'model.pattern_escape_in_set': {
76
+ code: "invalid_class";
77
+ ru: string;
78
+ };
79
+ 'model.pattern_word_boundary': {
80
+ code: "invalid_class";
81
+ ru: string;
82
+ };
83
+ 'model.pattern_unicode_property': {
84
+ code: "invalid_class";
85
+ ru: string;
86
+ };
87
+ 'model.pattern_backreference': {
88
+ code: "invalid_class";
89
+ ru: string;
90
+ };
91
+ 'model.pattern_named_group': {
92
+ code: "invalid_class";
93
+ ru: string;
94
+ };
95
+ 'model.validator_node_not_object': {
96
+ code: "invalid_class";
97
+ ru: string;
98
+ };
99
+ 'model.validator_keyword_unsupported': {
100
+ code: "invalid_class";
101
+ ru: string;
102
+ };
103
+ 'model.validator_unknown_type': {
104
+ code: "invalid_class";
105
+ ru: string;
106
+ };
107
+ 'model.validator_enum_objects_in_any_of': {
108
+ code: "invalid_class";
109
+ ru: string;
110
+ };
111
+ 'model.validator_bad_pattern': {
112
+ code: "invalid_class";
113
+ ru: string;
114
+ };
115
+ 'model.validator_format_unsupported': {
116
+ code: "invalid_class";
117
+ ru: string;
118
+ };
119
+ 'model.validator_format_in_any_of': {
120
+ code: "invalid_class";
121
+ ru: string;
122
+ };
123
+ 'model.validator_string_length_in_any_of': {
124
+ code: "invalid_class";
125
+ ru: string;
126
+ };
127
+ 'model.validator_unique_items_in_any_of': {
128
+ code: "invalid_class";
129
+ ru: string;
130
+ };
131
+ 'model.validator_min_properties_in_any_of': {
132
+ code: "invalid_class";
133
+ ru: string;
134
+ };
135
+ 'model.issue_enum': {
136
+ code: "invalid_data";
137
+ ru: string;
138
+ };
139
+ 'model.issue_additional': {
140
+ code: "invalid_data";
141
+ ru: string;
142
+ };
143
+ 'model.issue_date': {
144
+ code: "invalid_data";
145
+ ru: string;
146
+ };
147
+ 'model.issue_string_too_short': {
148
+ code: "invalid_data";
149
+ ru: string;
150
+ };
151
+ 'model.issue_string_too_long': {
152
+ code: "invalid_data";
153
+ ru: string;
154
+ };
155
+ 'model.issue_unique_items': {
156
+ code: "invalid_data";
157
+ ru: string;
158
+ };
159
+ 'model.issue_property_count': {
160
+ code: "invalid_data";
161
+ ru: string;
162
+ };
163
+ 'model.issue_rule': {
164
+ code: "invalid_data";
165
+ ru: string;
166
+ };
167
+ 'model.class_not_found': {
168
+ code: "invalid_class";
169
+ ru: string;
170
+ };
171
+ 'model.sync_hub_name_reserved': {
172
+ code: "invalid_class";
173
+ ru: string;
174
+ hint: string;
175
+ };
176
+ 'model.end_role_system': {
177
+ code: "invalid_class";
178
+ ru: string;
179
+ hint: string;
180
+ };
181
+ 'model.end_role_taken': {
182
+ code: "invalid_class";
183
+ ru: string;
184
+ hint: string;
185
+ };
186
+ 'model.models_cycle': {
187
+ code: "invalid_class";
188
+ ru: string;
189
+ };
190
+ 'model.types_class_name': {
191
+ code: "invalid_class";
192
+ ru: string;
193
+ };
194
+ 'model.v5_namespace_not_uuid': {
195
+ code: "invalid_data";
196
+ ru: string;
197
+ hint: string;
198
+ };
199
+ 'model.class_no_key': {
200
+ code: "no_key";
201
+ ru: string;
202
+ };
203
+ 'model.key_part_not_string': {
204
+ code: "invalid_data";
205
+ ru: string;
206
+ hint: string;
207
+ };
208
+ 'model.key_end_not_uuid': {
209
+ code: "invalid_data";
210
+ ru: string;
211
+ hint: string;
212
+ };
213
+ 'model.mcp_api_key_refused': {
214
+ code: "user_session_required";
215
+ ru: string;
216
+ hint: string;
217
+ };
218
+ 'model.mcp_token_required': {
219
+ code: "user_session_required";
220
+ ru: string;
221
+ hint: string;
222
+ };
223
+ 'model.cli_sync_dry_run': {
224
+ code: "invalid_query";
225
+ ru: string;
226
+ };
227
+ 'model.cli_sync_applied': {
228
+ code: "invalid_query";
229
+ ru: string;
230
+ };
231
+ 'model.cli_sync_list_create': {
232
+ code: "invalid_query";
233
+ ru: string;
234
+ };
235
+ 'model.cli_sync_list_update': {
236
+ code: "invalid_query";
237
+ ru: string;
238
+ };
239
+ 'model.cli_sync_list_system': {
240
+ code: "invalid_query";
241
+ ru: string;
242
+ };
243
+ 'model.cli_sync_lost': {
244
+ code: "invalid_query";
245
+ ru: string;
246
+ };
247
+ 'model.types_header': {
248
+ code: "invalid_query";
249
+ ru: string;
250
+ };
251
+ 'model.transform_unsupported': {
252
+ code: "invalid_class";
253
+ ru: string;
254
+ hint: string;
255
+ };
256
+ };
@@ -0,0 +1,314 @@
1
+ export const model = {
2
+ // model.ts, End: конец без классов цели — one() или many() без целей
3
+ 'model.end_no_targets': {
4
+ code: 'invalid_class',
5
+ ru: 'у конца должен быть хотя бы один класс цели',
6
+ },
7
+ // model.ts, makeModel: имя класса — не буквы, цифры и _ (до 63 знаков, не с цифры)
8
+ 'model.class_name_invalid': {
9
+ code: 'invalid_class',
10
+ ru: 'имя класса {name} недопустимо',
11
+ },
12
+ // model.ts, makeModel: имя хаба — из RESERVED_CLASS_NAMES (план 2.0, этап 4, п. 2; 7.10 №3)
13
+ 'model.hub_name_reserved': {
14
+ code: 'invalid_class',
15
+ ru: 'hub(): имя {name} занято методом цепочки или корня db — шаг с таким именем до класса не дойдёт',
16
+ hint: 'дать классу другое имя: зарезервированные имена — в README, «Справочник API → Зарезервированные имена»',
17
+ },
18
+ // model.ts, makeModel: поле модели начинается с $
19
+ 'model.field_name_dollar': {
20
+ code: 'invalid_class',
21
+ ru: '{cls}: имя поля {field} начинается с $ — так загрузчик помечает служебные ключи',
22
+ },
23
+ // model.ts, makeModel: роль конца — не буквы, цифры и _
24
+ 'model.end_name_invalid': {
25
+ code: 'invalid_class',
26
+ ru: '{cls}: имя конца {role} недопустимо',
27
+ },
28
+ // model.ts, makeModel: поле ключа — не строка или необязательное
29
+ 'model.key_field_type': {
30
+ code: 'invalid_class',
31
+ ru: '{cls}: поле ключа {field} должно быть обязательной строкой',
32
+ },
33
+ // model.ts, makeModel: конец ключа множественный или необязательный
34
+ 'model.key_end_type': {
35
+ code: 'invalid_class',
36
+ ru: '{cls}: конец ключа {end} должен быть обязательным и одиночным',
37
+ },
38
+ // model.ts, makeModel: в key — имя, которого нет ни среди полей, ни среди концов (с предками)
39
+ 'model.key_unknown_name': {
40
+ code: 'invalid_class',
41
+ ru: '{cls}: ключ ссылается на неизвестное поле или конец {name}',
42
+ },
43
+ // model.ts, makeModel: onDelete unset у обязательного конца (или у конца с min больше нуля)
44
+ 'model.unset_required_end': {
45
+ code: 'invalid_class',
46
+ ru: '{cls}: onDelete unset недопустим для обязательного конца {end}',
47
+ },
48
+ // jsonschema.ts, normalizeSchema: имя в начале текста ошибок, когда where не задан (часть текста, не ошибка)
49
+ 'model.schema_default_where': {
50
+ code: 'invalid_class',
51
+ ru: 'модель',
52
+ },
53
+ // jsonschema.ts, normalizeSchema: $ref не на определение из $defs (definitions)
54
+ 'model.schema_ref_unsupported': {
55
+ code: 'invalid_class',
56
+ ru: '{where}: ссылка {ref} не поддерживается (только #/$defs/…)',
57
+ },
58
+ // jsonschema.ts, normalizeSchema: $ref по кругу; cycle — имена определений через стрелку
59
+ 'model.schema_recursive': {
60
+ code: 'invalid_class',
61
+ ru: '{where}: рекурсивная модель через {cycle}',
62
+ },
63
+ // jsonschema.ts, normalizeSchema: $ref на определение, которого нет
64
+ 'model.schema_def_not_found': {
65
+ code: 'invalid_class',
66
+ ru: '{where}: определение {name} не найдено',
67
+ },
68
+ // jsonschema.ts, normalizeSchema: узел описания — не объект и не true; node — путь вида $.a.b
69
+ 'model.schema_node_not_object': {
70
+ code: 'invalid_class',
71
+ ru: '{where}: описание узла {node} — не объект',
72
+ },
73
+ // jsonschema.ts, normalizeSchema: ключевое слово JSON Schema вне подмножества базы
74
+ 'model.schema_keyword_unsupported': {
75
+ code: 'invalid_class',
76
+ ru: '{where}: ключевое слово {keyword} не поддерживается (узел {node})',
77
+ },
78
+ // jsonschema.ts, normalizeSchema: format не из uuid, date, date-time, email
79
+ 'model.schema_format_unsupported': {
80
+ code: 'invalid_class',
81
+ ru: '{where}: format {format} не поддерживается (узел {node})',
82
+ },
83
+ // jsonschema.ts, normalizeSchema с topLevel: поле верхнего уровня начинается с $
84
+ 'model.schema_field_dollar': {
85
+ code: 'invalid_class',
86
+ ru: '{where}: имя поля {field} начинается с $ — так загрузчик помечает служебные ключи',
87
+ },
88
+ // jsonschema.ts, translatePattern: обратная косая черта последним знаком шаблона
89
+ 'model.pattern_trailing_backslash': {
90
+ code: 'invalid_class',
91
+ ru: '{where}: шаблон {pattern} несовместим с регулярными выражениями PostgreSQL (обратная косая черта в конце шаблона)',
92
+ },
93
+ // jsonschema.ts, translatePattern: \D, \W, \S внутри [ ]; escape — сама последовательность
94
+ 'model.pattern_escape_in_set': {
95
+ code: 'invalid_class',
96
+ ru: '{where}: шаблон {pattern} несовместим с регулярными выражениями PostgreSQL ({escape} внутри набора [ ] не переводится)',
97
+ },
98
+ // jsonschema.ts, translatePattern: \b, \B; escape — сама последовательность
99
+ 'model.pattern_word_boundary': {
100
+ code: 'invalid_class',
101
+ ru: '{where}: шаблон {pattern} несовместим с регулярными выражениями PostgreSQL ({escape} в PostgreSQL значит другое)',
102
+ },
103
+ // jsonschema.ts, translatePattern: \p и \P
104
+ 'model.pattern_unicode_property': {
105
+ code: 'invalid_class',
106
+ ru: '{where}: шаблон {pattern} несовместим с регулярными выражениями PostgreSQL (\\p{…} не поддерживается)',
107
+ },
108
+ // jsonschema.ts, translatePattern: \k и \1–\9
109
+ 'model.pattern_backreference': {
110
+ code: 'invalid_class',
111
+ ru: '{where}: шаблон {pattern} несовместим с регулярными выражениями PostgreSQL (обратные ссылки не поддерживаются)',
112
+ },
113
+ // jsonschema.ts, translatePattern: именованная группа (?<имя>…)
114
+ 'model.pattern_named_group': {
115
+ code: 'invalid_class',
116
+ ru: '{where}: шаблон {pattern} несовместим с регулярными выражениями PostgreSQL (именованные группы не поддерживаются)',
117
+ },
118
+ // validate.ts, compileValidator: узел описания — не объект и не true; node — путь узла массивом JSON
119
+ 'model.validator_node_not_object': {
120
+ code: 'invalid_class',
121
+ ru: 'описание узла {node} — не объект (узел {node})',
122
+ },
123
+ // validate.ts, compileValidator: ключевое слово вне подмножества (не x-…)
124
+ 'model.validator_keyword_unsupported': {
125
+ code: 'invalid_class',
126
+ ru: 'ключевое слово {keyword} не поддерживается (узел {node})',
127
+ },
128
+ // validate.ts, compileValidator: type не из integer, number, string, boolean, object, array, null
129
+ 'model.validator_unknown_type': {
130
+ code: 'invalid_class',
131
+ ru: 'неизвестный тип в узле {node} (узел {node})',
132
+ },
133
+ // validate.ts, compileValidator: enum или const с объектами внутри ветки anyOf или oneOf
134
+ 'model.validator_enum_objects_in_any_of': {
135
+ code: 'invalid_class',
136
+ ru: 'перечисление объектов внутри anyOf не поддерживается (узел {node})',
137
+ },
138
+ // validate.ts, compileValidator: pattern неверен уже для JavaScript; pattern — шаблон в JSON
139
+ 'model.validator_bad_pattern': {
140
+ code: 'invalid_class',
141
+ ru: 'pattern {pattern} — неверное регулярное выражение (узел {node})',
142
+ },
143
+ // validate.ts, compileValidator: format не из uuid, date, date-time, email
144
+ 'model.validator_format_unsupported': {
145
+ code: 'invalid_class',
146
+ ru: 'format {format} не поддерживается (узел {node})',
147
+ },
148
+ // validate.ts, compileValidator: format date или date-time внутри ветки anyOf или oneOf
149
+ 'model.validator_format_in_any_of': {
150
+ code: 'invalid_class',
151
+ ru: 'format {format} внутри anyOf не поддерживается (узел {node})',
152
+ },
153
+ // validate.ts, compileValidator: minLength или maxLength внутри ветки anyOf или oneOf
154
+ 'model.validator_string_length_in_any_of': {
155
+ code: 'invalid_class',
156
+ ru: 'длина строки внутри anyOf не поддерживается (узел {node})',
157
+ },
158
+ // validate.ts, compileValidator: uniqueItems внутри ветки anyOf или oneOf
159
+ 'model.validator_unique_items_in_any_of': {
160
+ code: 'invalid_class',
161
+ ru: 'uniqueItems внутри anyOf не поддерживается (узел {node})',
162
+ },
163
+ // validate.ts, compileValidator: minProperties или maxProperties внутри ветки anyOf или oneOf
164
+ 'model.validator_min_properties_in_any_of': {
165
+ code: 'invalid_class',
166
+ ru: 'minProperties внутри anyOf не поддерживается (узел {node})',
167
+ },
168
+ // validate.ts, compileValidator: сообщения нарушений issues[].message — тексты не для ошибки (lmsg), те же, что у базы
169
+ 'model.issue_enum': {
170
+ code: 'invalid_data',
171
+ ru: 'значение не из перечисления: допустимо {values}',
172
+ },
173
+ // лишний ключ объекта (additionalProperties: false); keys — имена лишних ключей через запятую
174
+ 'model.issue_additional': {
175
+ code: 'invalid_data',
176
+ ru: 'лишний ключ {keys}',
177
+ },
178
+ 'model.issue_date': {
179
+ code: 'invalid_data',
180
+ ru: 'такой даты не бывает',
181
+ },
182
+ // minLength, maxLength: limit — граница из описания (длина в символах)
183
+ 'model.issue_string_too_short': {
184
+ code: 'invalid_data',
185
+ ru: 'длина строки меньше {limit}',
186
+ },
187
+ 'model.issue_string_too_long': {
188
+ code: 'invalid_data',
189
+ ru: 'длина строки больше {limit}',
190
+ },
191
+ 'model.issue_unique_items': {
192
+ code: 'invalid_data',
193
+ ru: 'элементы повторяются',
194
+ },
195
+ 'model.issue_property_count': {
196
+ code: 'invalid_data',
197
+ ru: 'число ключей вне границ',
198
+ },
199
+ 'model.issue_rule': {
200
+ code: 'invalid_data',
201
+ ru: 'нарушено правило {keyword}',
202
+ },
203
+ // registry.ts, Registry.resolve: класса нет в реестре сессии ни по имени, ни по алиасу
204
+ 'model.class_not_found': {
205
+ code: 'invalid_class',
206
+ ru: 'класс {name} не найден',
207
+ },
208
+ // sync.ts, syncModels: модель хаба с именем из RESERVED_CLASS_NAMES, собранная мимо hub() (план 2.0, этап 4, п. 2;
209
+ // 7.10 №3) — отказ до записи
210
+ 'model.sync_hub_name_reserved': {
211
+ code: 'invalid_class',
212
+ ru: 'syncModels: имя хаба {name} занято методом цепочки или корня db — шаг с таким именем до класса не дойдёт',
213
+ hint: 'дать классу другое имя: зарезервированные имена — в README, «Справочник API → Зарезервированные имена»',
214
+ },
215
+ // sync.ts, syncModels: роль конца модели занята системным классом (member: User, Tenant → Account; rule: Group,
216
+ // Object → Resource) и ведёт на другой класс — отказ до записи (база отклонила бы sql-write.end_other_class)
217
+ 'model.end_role_system': {
218
+ code: 'invalid_class',
219
+ ru: 'syncModels: имя роли {end} в классе {model} занято системным классом {cls} (там {end} ведёт на {target}) — выберите другое имя роли, например Team вместо Group',
220
+ hint: 'переименовать роль конца: имена ролей User, Tenant (системный класс member, ведут на Account), Group, Object (системный класс rule, ведут на Resource) можно брать, только если конец ведёт туда же; список — в README, «Зарезервированные имена»',
221
+ },
222
+ // sync.ts, syncModels: роль конца модели уже ведёт на другой класс в другом классе арендатора (или в другой модели
223
+ // того же вызова) — отказ до записи (база отклонила бы sql-write.end_other_class)
224
+ 'model.end_role_taken': {
225
+ code: 'invalid_class',
226
+ ru: 'syncModels: роль {end} в классе {model} ведёт на {mine}, а в классе {cls} — на {target}: имя роли одно на арендатора (это имя шага цепочки)',
227
+ hint: 'дать роли другое имя или направить её на тот же класс, что и в другом классе',
228
+ },
229
+ // sync.ts, syncModels: родители замыкают круг; cycle — имена моделей через стрелку
230
+ 'model.models_cycle': {
231
+ code: 'invalid_class',
232
+ ru: 'syncModels: модели зависят друг от друга по кругу: {cycle} — родителя база ждёт раньше класса',
233
+ },
234
+ // sync.ts, generateTypes: имя класса (например, созданного данными) — не идентификатор TypeScript
235
+ 'model.types_class_name': {
236
+ code: 'invalid_class',
237
+ ru: 'types: имя класса {name} не годится для идентификатора TypeScript',
238
+ },
239
+ // uuid.ts, uuidv5: пространство имён (арендатор) — не uuid
240
+ 'model.v5_namespace_not_uuid': {
241
+ code: 'invalid_data',
242
+ ru: 'пространство имён v5 — не uuid: {ns}',
243
+ hint: 'пространство имён v5 — id арендатора (uuid): idOf(класс, ключ, { tenant })',
244
+ },
245
+ // uuid.ts, idOf: у класса нет ключа
246
+ 'model.class_no_key': {
247
+ code: 'no_key',
248
+ ru: 'у класса {cls} нет ключа: id выдаёт база при создании',
249
+ },
250
+ // uuid.ts, idOf: часть ключа не задана или не строка; detail.key — части ключа класса
251
+ 'model.key_part_not_string': {
252
+ code: 'invalid_data',
253
+ ru: 'idOf({cls}): часть ключа {part} должна быть строкой',
254
+ hint: 'передать каждую часть ключа строкой (части — в detail.key): у поля — его значение, у конца — id цели',
255
+ },
256
+ // uuid.ts, idOf: значение конца в ключе — не uuid
257
+ 'model.key_end_not_uuid': {
258
+ code: 'invalid_data',
259
+ ru: 'idOf({cls}): конец {end} — не uuid',
260
+ hint: 'значение конца в ключе — id цели (uuid)',
261
+ },
262
+ // cli.ts, mcp: letopis mcp с ключом сервиса (--api-key)
263
+ 'model.mcp_api_key_refused': {
264
+ code: 'user_session_required',
265
+ ru: 'letopis mcp принимает только токен сессии пользователя (--token или LETOPIS_TOKEN): ключ сервиса даёт все права auth.* и не должен лежать на машине агента',
266
+ hint: 'убрать --api-key и передать токен сессии пользователя: --token или LETOPIS_TOKEN',
267
+ },
268
+ // cli.ts, mcp: letopis mcp без токена — ни --token, ни LETOPIS_TOKEN
269
+ 'model.mcp_token_required': {
270
+ code: 'user_session_required',
271
+ ru: 'letopis mcp — нужен токен сессии пользователя: --token или LETOPIS_TOKEN',
272
+ hint: 'передать токен сессии пользователя: --token или LETOPIS_TOKEN',
273
+ },
274
+ // cli.ts, main: отчёт letopis sync (lmsg) — тексты не для ошибки, код не печатается. Итог: сухой прогон и с --apply;
275
+ // числа классов по группам
276
+ 'model.cli_sync_dry_run': {
277
+ code: 'invalid_query',
278
+ ru: 'сухой прогон: создать {created}, изменить {updated}, без изменений {unchanged}, системных {skipped}',
279
+ },
280
+ 'model.cli_sync_applied': {
281
+ code: 'invalid_query',
282
+ ru: 'применено: создать {created}, изменить {updated}, без изменений {unchanged}, системных {skipped}',
283
+ },
284
+ // строки групп; names — классы через запятую
285
+ 'model.cli_sync_list_create': {
286
+ code: 'invalid_query',
287
+ ru: 'создать: {names}',
288
+ },
289
+ 'model.cli_sync_list_update': {
290
+ code: 'invalid_query',
291
+ ru: 'изменить: {names}',
292
+ },
293
+ 'model.cli_sync_list_system': {
294
+ code: 'invalid_query',
295
+ ru: 'системные (меняет установка): {names}',
296
+ },
297
+ // правило Zod (refine, transform), которого нет в базе; kind — вид правила, path — где оно
298
+ 'model.cli_sync_lost': {
299
+ code: 'invalid_query',
300
+ ru: 'правило {kind} в {path} проверяется только в библиотеке — в базе его нет',
301
+ },
302
+ // sync.ts, generateTypes: пометка в первой строке файла типов (после «// ») — текст не для ошибки
303
+ 'model.types_header': {
304
+ code: 'invalid_query',
305
+ ru: 'Сгенерировано letopis types — не править руками.',
306
+ },
307
+ // sync.ts, syncModels: в модели есть преобразование Zod (.trim(), .toLowerCase(), .transform(), z.preprocess …) — база
308
+ // и валидатор letopis его не исполняют, данные записались бы как есть; rules — пути и виды через запятую
309
+ 'model.transform_unsupported': {
310
+ code: 'invalid_class',
311
+ ru: 'преобразования Zod не исполняются при записи: {rules}',
312
+ hint: 'привести значение до записи в коде сервиса (например, value.trim()) и убрать преобразование из модели; проверку без изменения значения дают .regex(), .min(), .refine()',
313
+ },
314
+ };