model-generator-kit 0.1.0__py3-none-any.whl

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 (68) hide show
  1. model_generator/__init__.py +6 -0
  2. model_generator/generate.py +1030 -0
  3. model_generator/generators/__init__.py +38 -0
  4. model_generator/generators/api.py +287 -0
  5. model_generator/generators/constraints.py +176 -0
  6. model_generator/generators/database.py +147 -0
  7. model_generator/generators/enums.py +88 -0
  8. model_generator/generators/infrastructure.py +679 -0
  9. model_generator/generators/migrations.py +146 -0
  10. model_generator/py.typed +0 -0
  11. model_generator/schema/model.schema.json +758 -0
  12. model_generator/stacks/python-fastapi/config.yaml +403 -0
  13. model_generator/stacks/python-fastapi/templates/_shared/_base.j2 +26 -0
  14. model_generator/stacks/python-fastapi/templates/_shared/_entity.j2 +48 -0
  15. model_generator/stacks/python-fastapi/templates/_shared/_examples.j2 +50 -0
  16. model_generator/stacks/python-fastapi/templates/_shared/_fields.j2 +48 -0
  17. model_generator/stacks/python-fastapi/templates/_shared/_tests.j2 +143 -0
  18. model_generator/stacks/python-fastapi/templates/api/init.py.j2 +55 -0
  19. model_generator/stacks/python-fastapi/templates/api/pagination.py.j2 +79 -0
  20. model_generator/stacks/python-fastapi/templates/api/request.py.j2 +448 -0
  21. model_generator/stacks/python-fastapi/templates/api/response.py.j2 +222 -0
  22. model_generator/stacks/python-fastapi/templates/api/route.py.j2 +507 -0
  23. model_generator/stacks/python-fastapi/templates/database/constraints.py.j2 +439 -0
  24. model_generator/stacks/python-fastapi/templates/database/enums.py.j2 +55 -0
  25. model_generator/stacks/python-fastapi/templates/database/factory.py.j2 +265 -0
  26. model_generator/stacks/python-fastapi/templates/database/init.py.j2 +37 -0
  27. model_generator/stacks/python-fastapi/templates/database/model.py.j2 +476 -0
  28. model_generator/stacks/python-fastapi/templates/infrastructure/auth_router.py.j2 +434 -0
  29. model_generator/stacks/python-fastapi/templates/infrastructure/base.py.j2 +16 -0
  30. model_generator/stacks/python-fastapi/templates/infrastructure/csrf.py.j2 +121 -0
  31. model_generator/stacks/python-fastapi/templates/infrastructure/database_init.py.j2 +12 -0
  32. model_generator/stacks/python-fastapi/templates/infrastructure/encrypted_bytes.py.j2 +62 -0
  33. model_generator/stacks/python-fastapi/templates/infrastructure/engine.py.j2 +51 -0
  34. model_generator/stacks/python-fastapi/templates/infrastructure/errors.py.j2 +74 -0
  35. model_generator/stacks/python-fastapi/templates/infrastructure/gitignore.j2 +48 -0
  36. model_generator/stacks/python-fastapi/templates/infrastructure/main.py.j2 +94 -0
  37. model_generator/stacks/python-fastapi/templates/infrastructure/pyproject.toml.j2 +92 -0
  38. model_generator/stacks/python-fastapi/templates/infrastructure/rate_limit.py.j2 +41 -0
  39. model_generator/stacks/python-fastapi/templates/infrastructure/types.py.j2 +94 -0
  40. model_generator/stacks/python-fastapi/templates/infrastructure/utils.py.j2 +50 -0
  41. model_generator/stacks/python-fastapi/templates/infrastructure/validators.py.j2 +126 -0
  42. model_generator/stacks/python-fastapi/templates/migrations/env.py.j2 +125 -0
  43. model_generator/stacks/python-fastapi/templates/migrations/ini.j2 +109 -0
  44. model_generator/stacks/python-fastapi/templates/migrations/script.py.mako.j2 +35 -0
  45. model_generator/stacks/python-fastapi/templates/tests/conftest_root.py.j2 +122 -0
  46. model_generator/stacks/python-fastapi/templates/tests/contract.py.j2 +1860 -0
  47. model_generator/utils/__init__.py +31 -0
  48. model_generator/utils/conftest_generator.py +683 -0
  49. model_generator/utils/constants.py +6 -0
  50. model_generator/utils/loaders.py +292 -0
  51. model_generator/utils/parser.py +129 -0
  52. model_generator/utils/quality.py +43 -0
  53. model_generator/utils/templates.py +128 -0
  54. model_generator/validate.py +219 -0
  55. model_generator/wizard/__init__.py +10 -0
  56. model_generator/wizard/actions/__init__.py +1 -0
  57. model_generator/wizard/actions/clean.py +55 -0
  58. model_generator/wizard/actions/generate.py +166 -0
  59. model_generator/wizard/actions/project_setup.py +142 -0
  60. model_generator/wizard/actions/test_runner.py +60 -0
  61. model_generator/wizard/menu.py +43 -0
  62. model_generator/wizard/prompts.py +80 -0
  63. model_generator_kit-0.1.0.dist-info/METADATA +143 -0
  64. model_generator_kit-0.1.0.dist-info/RECORD +68 -0
  65. model_generator_kit-0.1.0.dist-info/WHEEL +5 -0
  66. model_generator_kit-0.1.0.dist-info/entry_points.txt +3 -0
  67. model_generator_kit-0.1.0.dist-info/licenses/LICENSE +21 -0
  68. model_generator_kit-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,758 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://model-generator/model.schema.json",
4
+ "title": "Multi-Entity Model Definition Schema",
5
+ "description": "Schema for defining multiple related database entities in a single domain file",
6
+ "type": "object",
7
+ "required": [
8
+ "domain",
9
+ "entities"
10
+ ],
11
+ "additionalProperties": false,
12
+ "properties": {
13
+ "$schema": {
14
+ "type": "string",
15
+ "description": "Reference to this schema for validation"
16
+ },
17
+ "domain": {
18
+ "type": "string",
19
+ "pattern": "^[a-z][a-z0-9_]*$",
20
+ "description": "Domain name in snake_case (e.g., users, orders, invoices)"
21
+ },
22
+ "description": {
23
+ "type": "string",
24
+ "description": "Human-readable description of the domain"
25
+ },
26
+ "section_header": {
27
+ "type": "string",
28
+ "pattern": "^[A-Z][A-Z0-9 &_]*$",
29
+ "description": "Section header in ALL CAPS (e.g., USER & AUTHENTICATION MODELS)"
30
+ },
31
+ "enum_definitions": {
32
+ "type": "object",
33
+ "description": "Enums to define for this domain. Key is enum name (PascalCase), value is definition.",
34
+ "additionalProperties": {
35
+ "$ref": "#/definitions/enum_definition"
36
+ }
37
+ },
38
+ "entities": {
39
+ "type": "object",
40
+ "additionalProperties": {
41
+ "$ref": "#/definitions/entity"
42
+ },
43
+ "minProperties": 1,
44
+ "description": "Map of entity names to their definitions"
45
+ },
46
+ "dependencies": {
47
+ "type": "array",
48
+ "items": { "type": "string" },
49
+ "description": "Extra pip dependencies required by this domain (e.g., bcrypt>=4.0.0)"
50
+ }
51
+ },
52
+ "definitions": {
53
+ "enum_definition": {
54
+ "type": "object",
55
+ "required": [
56
+ "values"
57
+ ],
58
+ "additionalProperties": false,
59
+ "description": "Enum type definition",
60
+ "properties": {
61
+ "description": {
62
+ "type": "string",
63
+ "description": "Human-readable description of the enum"
64
+ },
65
+ "values": {
66
+ "type": "array",
67
+ "items": {
68
+ "oneOf": [
69
+ {
70
+ "type": "string"
71
+ },
72
+ {
73
+ "type": "object",
74
+ "required": [
75
+ "name",
76
+ "value"
77
+ ],
78
+ "additionalProperties": false,
79
+ "properties": {
80
+ "name": {
81
+ "type": "string",
82
+ "description": "Enum member name (UPPER_CASE)"
83
+ },
84
+ "value": {
85
+ "type": "string",
86
+ "description": "Enum string value (lowercase)"
87
+ },
88
+ "description": {
89
+ "type": "string",
90
+ "description": "Member description (for inline comments)"
91
+ }
92
+ }
93
+ }
94
+ ]
95
+ },
96
+ "minItems": 1,
97
+ "description": "List of enum values. Can be strings (auto-lowercased) or objects with name/value/description."
98
+ }
99
+ }
100
+ },
101
+ "entity": {
102
+ "type": "object",
103
+ "required": [
104
+ "table",
105
+ "fields"
106
+ ],
107
+ "additionalProperties": false,
108
+ "description": "Single entity definition",
109
+ "properties": {
110
+ "table": {
111
+ "type": "string",
112
+ "pattern": "^[a-z][a-z0-9_]*$",
113
+ "description": "snake_case database table name (e.g., users, user_sessions)"
114
+ },
115
+ "description": {
116
+ "type": "string",
117
+ "description": "Human-readable description of the entity"
118
+ },
119
+ "mutability": {
120
+ "type": "string",
121
+ "enum": [
122
+ "mutable",
123
+ "immutable"
124
+ ],
125
+ "default": "mutable",
126
+ "description": "mutable: has updated_at, supports PUT/DELETE. immutable: append-only"
127
+ },
128
+ "fields": {
129
+ "type": "object",
130
+ "additionalProperties": {
131
+ "$ref": "#/definitions/field"
132
+ },
133
+ "minProperties": 1
134
+ },
135
+ "timestamps": {
136
+ "type": "object",
137
+ "additionalProperties": false,
138
+ "properties": {
139
+ "created": {
140
+ "type": "boolean",
141
+ "default": true
142
+ },
143
+ "updated": {
144
+ "type": "boolean",
145
+ "default": true
146
+ }
147
+ }
148
+ },
149
+ "relationships": {
150
+ "type": "object",
151
+ "additionalProperties": {
152
+ "$ref": "#/definitions/relationship"
153
+ }
154
+ },
155
+ "indexes": {
156
+ "type": "array",
157
+ "items": {
158
+ "$ref": "#/definitions/index"
159
+ }
160
+ },
161
+ "constraints": {
162
+ "type": "array",
163
+ "items": {
164
+ "$ref": "#/definitions/table_constraint"
165
+ }
166
+ },
167
+ "foreign_keys": {
168
+ "type": "array",
169
+ "description": "Composite foreign keys spanning multiple columns. Use when the target entity has a composite primary key.",
170
+ "items": {
171
+ "$ref": "#/definitions/composite_foreign_key"
172
+ }
173
+ },
174
+ "cross_field_constraints": {
175
+ "type": "array",
176
+ "description": "Constraints that involve relationships between multiple fields",
177
+ "items": {
178
+ "$ref": "#/definitions/cross_field_constraint"
179
+ }
180
+ },
181
+ "api": {
182
+ "$ref": "#/definitions/api_config"
183
+ },
184
+ "tests": {
185
+ "$ref": "#/definitions/tests_config"
186
+ }
187
+ }
188
+ },
189
+ "field": {
190
+ "type": "object",
191
+ "required": [
192
+ "type"
193
+ ],
194
+ "additionalProperties": false,
195
+ "properties": {
196
+ "type": {
197
+ "type": "string",
198
+ "enum": [
199
+ "uuid",
200
+ "financial",
201
+ "percentage",
202
+ "counter",
203
+ "integer",
204
+ "text",
205
+ "longtext",
206
+ "boolean",
207
+ "binary",
208
+ "datetime",
209
+ "enum",
210
+ "json_object",
211
+ "json_array",
212
+ "reference"
213
+ ]
214
+ },
215
+ "description": {
216
+ "type": "string"
217
+ },
218
+ "required": {
219
+ "type": "boolean",
220
+ "default": false
221
+ },
222
+ "nullable": {
223
+ "type": "boolean",
224
+ "default": true
225
+ },
226
+ "primary_key": {
227
+ "type": "boolean",
228
+ "default": false
229
+ },
230
+ "auto_generate": {
231
+ "type": "boolean",
232
+ "default": false
233
+ },
234
+ "unique": {
235
+ "type": "boolean",
236
+ "default": false
237
+ },
238
+ "index": {
239
+ "type": "boolean",
240
+ "default": false
241
+ },
242
+ "default": {
243
+ "oneOf": [
244
+ {
245
+ "type": "string"
246
+ },
247
+ {
248
+ "type": "number"
249
+ },
250
+ {
251
+ "type": "boolean"
252
+ },
253
+ {
254
+ "type": "null"
255
+ }
256
+ ]
257
+ },
258
+ "server_default": {
259
+ "oneOf": [
260
+ {
261
+ "type": "string"
262
+ },
263
+ {
264
+ "type": "boolean"
265
+ }
266
+ ]
267
+ },
268
+ "min_length": {
269
+ "type": "integer",
270
+ "minimum": 1,
271
+ "description": "Minimum length for text fields (API validation)"
272
+ },
273
+ "max_length": {
274
+ "type": "integer",
275
+ "minimum": 1
276
+ },
277
+ "precision": {
278
+ "type": "integer",
279
+ "minimum": 1,
280
+ "default": 20
281
+ },
282
+ "scale": {
283
+ "type": "integer",
284
+ "minimum": 0,
285
+ "default": 8
286
+ },
287
+ "enum_name": {
288
+ "type": "string"
289
+ },
290
+ "enum_values": {
291
+ "type": "array",
292
+ "items": {
293
+ "type": "string"
294
+ }
295
+ },
296
+ "enum_existing": {
297
+ "type": "boolean",
298
+ "default": false
299
+ },
300
+ "reference_table": {
301
+ "type": "string"
302
+ },
303
+ "reference_column": {
304
+ "type": "string",
305
+ "default": "id"
306
+ },
307
+ "on_delete": {
308
+ "type": "string",
309
+ "enum": [
310
+ "CASCADE",
311
+ "SET NULL",
312
+ "RESTRICT",
313
+ "NO ACTION"
314
+ ],
315
+ "default": "CASCADE"
316
+ },
317
+ "constraints": {
318
+ "type": "array",
319
+ "items": {
320
+ "$ref": "#/definitions/field_constraint"
321
+ }
322
+ },
323
+ "api_exclude_create": {
324
+ "type": "boolean",
325
+ "default": false
326
+ },
327
+ "api_exclude_update": {
328
+ "type": "boolean",
329
+ "default": false
330
+ },
331
+ "api_exclude_response": {
332
+ "type": "boolean",
333
+ "default": false
334
+ },
335
+ "api_readonly": {
336
+ "type": "boolean",
337
+ "default": false
338
+ },
339
+ "api_field_name": {
340
+ "type": "string",
341
+ "description": "Rename field in API (e.g., password_hash -> password)"
342
+ },
343
+ "list_type": {
344
+ "type": "string",
345
+ "description": "For json_array: element type (e.g., 'str', 'int')"
346
+ },
347
+ "timestamp_after": {
348
+ "type": "string",
349
+ "description": "For datetime fields: validate this timestamp >= referenced field (e.g., 'created_at')"
350
+ }
351
+ }
352
+ },
353
+ "field_constraint": {
354
+ "type": "object",
355
+ "required": [
356
+ "type"
357
+ ],
358
+ "additionalProperties": false,
359
+ "properties": {
360
+ "type": {
361
+ "type": "string",
362
+ "enum": [
363
+ "non_negative",
364
+ "non_negative_or_null",
365
+ "positive",
366
+ "positive_or_null",
367
+ "range",
368
+ "range_or_null",
369
+ "length",
370
+ "pattern",
371
+ "unique",
372
+ "timestamp_after"
373
+ ]
374
+ },
375
+ "name": {
376
+ "type": "string",
377
+ "description": "Custom constraint name"
378
+ },
379
+ "after": {
380
+ "type": "string",
381
+ "description": "For timestamp_after: field name to compare against"
382
+ },
383
+ "min": {
384
+ "description": "Minimum value"
385
+ },
386
+ "min_ref": {
387
+ "type": "string",
388
+ "description": "Reference to constraint constant (e.g., 'USERNAME_MIN_LENGTH')"
389
+ },
390
+ "max": {
391
+ "description": "Maximum value"
392
+ },
393
+ "max_ref": {
394
+ "type": "string",
395
+ "description": "Reference to constraint constant for max value"
396
+ },
397
+ "regex": {
398
+ "type": "string",
399
+ "description": "Regex pattern"
400
+ },
401
+ "regex_ref": {
402
+ "type": "string",
403
+ "description": "Reference to pattern constant (e.g., 'EMAIL_PATTERN')"
404
+ },
405
+ "message": {
406
+ "type": "string",
407
+ "description": "Custom error message"
408
+ }
409
+ }
410
+ },
411
+ "table_constraint": {
412
+ "type": "object",
413
+ "required": [
414
+ "type"
415
+ ],
416
+ "additionalProperties": false,
417
+ "properties": {
418
+ "type": {
419
+ "type": "string",
420
+ "enum": [
421
+ "check",
422
+ "unique",
423
+ "depends"
424
+ ]
425
+ },
426
+ "name": {
427
+ "type": "string"
428
+ },
429
+ "fields": {
430
+ "type": "array",
431
+ "items": {
432
+ "type": "string"
433
+ }
434
+ },
435
+ "expression": {
436
+ "type": "string"
437
+ },
438
+ "field": {
439
+ "type": "string"
440
+ },
441
+ "operator": {
442
+ "type": "string",
443
+ "enum": [
444
+ ">=",
445
+ ">",
446
+ "<=",
447
+ "<",
448
+ "==",
449
+ "!="
450
+ ]
451
+ },
452
+ "other_field": {
453
+ "type": "string"
454
+ }
455
+ }
456
+ },
457
+ "cross_field_constraint": {
458
+ "type": "object",
459
+ "required": [
460
+ "type",
461
+ "fields"
462
+ ],
463
+ "additionalProperties": false,
464
+ "description": "Constraints involving multiple fields (arithmetic or comparison relationships)",
465
+ "properties": {
466
+ "type": {
467
+ "type": "string",
468
+ "enum": [
469
+ "sum_equals",
470
+ "product_equals",
471
+ "difference_equals",
472
+ "quotient_equals",
473
+ "modulo_equals",
474
+ "field_equal",
475
+ "field_not_equal",
476
+ "field_less_than",
477
+ "field_less_than_or_equal",
478
+ "field_greater_than",
479
+ "field_greater_than_or_equal"
480
+ ],
481
+ "description": "Type of cross-field constraint"
482
+ },
483
+ "name": {
484
+ "type": "string",
485
+ "description": "Custom constraint name"
486
+ },
487
+ "fields": {
488
+ "type": "array",
489
+ "items": {
490
+ "type": "string"
491
+ },
492
+ "minItems": 2,
493
+ "description": "Fields involved in the constraint (order matters for non-commutative operations)"
494
+ },
495
+ "target_value": {
496
+ "description": "Target value for arithmetic constraints (e.g., sum_equals target)"
497
+ },
498
+ "target_field": {
499
+ "type": "string",
500
+ "description": "Target field for arithmetic constraints (e.g., field_a + field_b = field_c)"
501
+ },
502
+ "message": {
503
+ "type": "string",
504
+ "description": "Custom error message"
505
+ },
506
+ "description": {
507
+ "type": "string",
508
+ "description": "Human-readable description of the constraint"
509
+ }
510
+ }
511
+ },
512
+ "relationship": {
513
+ "type": "object",
514
+ "required": [
515
+ "type",
516
+ "target"
517
+ ],
518
+ "additionalProperties": false,
519
+ "properties": {
520
+ "type": {
521
+ "type": "string",
522
+ "enum": [
523
+ "one_to_many",
524
+ "many_to_one",
525
+ "one_to_one",
526
+ "one_to_one_inverse",
527
+ "many_to_many"
528
+ ]
529
+ },
530
+ "target": {
531
+ "type": "string"
532
+ },
533
+ "back_populates": {
534
+ "type": "string"
535
+ },
536
+ "cascade": {
537
+ "type": "string",
538
+ "default": "all, delete-orphan"
539
+ },
540
+ "foreign_keys": {
541
+ "type": "array",
542
+ "items": {
543
+ "type": "string"
544
+ }
545
+ },
546
+ "uselist": {
547
+ "type": "boolean"
548
+ }
549
+ }
550
+ },
551
+ "index": {
552
+ "type": "object",
553
+ "required": [
554
+ "fields"
555
+ ],
556
+ "additionalProperties": false,
557
+ "properties": {
558
+ "name": {
559
+ "type": "string"
560
+ },
561
+ "fields": {
562
+ "type": "array",
563
+ "items": {
564
+ "type": "string"
565
+ },
566
+ "minItems": 1
567
+ },
568
+ "unique": {
569
+ "type": "boolean",
570
+ "default": false
571
+ }
572
+ }
573
+ },
574
+ "composite_foreign_key": {
575
+ "type": "object",
576
+ "required": [
577
+ "fields",
578
+ "references_table",
579
+ "references_columns"
580
+ ],
581
+ "additionalProperties": false,
582
+ "properties": {
583
+ "fields": {
584
+ "type": "array",
585
+ "items": {
586
+ "type": "string"
587
+ },
588
+ "minItems": 2
589
+ },
590
+ "references_table": {
591
+ "type": "string"
592
+ },
593
+ "references_columns": {
594
+ "type": "array",
595
+ "items": {
596
+ "type": "string"
597
+ },
598
+ "minItems": 2
599
+ },
600
+ "on_delete": {
601
+ "type": "string",
602
+ "enum": [
603
+ "CASCADE",
604
+ "SET NULL",
605
+ "RESTRICT",
606
+ "NO ACTION"
607
+ ],
608
+ "default": "CASCADE"
609
+ }
610
+ }
611
+ },
612
+ "api_config": {
613
+ "type": "object",
614
+ "additionalProperties": false,
615
+ "properties": {
616
+ "enabled": {
617
+ "type": "boolean",
618
+ "default": true
619
+ },
620
+ "prefix": {
621
+ "type": "string"
622
+ },
623
+ "endpoints": {
624
+ "type": "array",
625
+ "items": {
626
+ "type": "string",
627
+ "enum": [
628
+ "list",
629
+ "create",
630
+ "get",
631
+ "update",
632
+ "delete"
633
+ ]
634
+ },
635
+ "default": [
636
+ "list",
637
+ "create",
638
+ "get",
639
+ "update",
640
+ "delete"
641
+ ]
642
+ },
643
+ "validators": {
644
+ "type": "object",
645
+ "additionalProperties": false,
646
+ "properties": {
647
+ "create": {
648
+ "type": "array",
649
+ "items": {
650
+ "type": "string"
651
+ }
652
+ },
653
+ "update": {
654
+ "type": "array",
655
+ "items": {
656
+ "type": "string"
657
+ }
658
+ },
659
+ "response": {
660
+ "type": "array",
661
+ "items": {
662
+ "type": "string"
663
+ }
664
+ }
665
+ }
666
+ },
667
+ "pagination": {
668
+ "type": "boolean",
669
+ "default": true
670
+ },
671
+ "filters": {
672
+ "type": "array",
673
+ "items": {
674
+ "type": "string"
675
+ }
676
+ },
677
+ "scope": {
678
+ "type": "object",
679
+ "additionalProperties": false,
680
+ "properties": {
681
+ "owner_field": {
682
+ "type": "string",
683
+ "description": "Field name that holds the owner user ID"
684
+ },
685
+ "inject_from": {
686
+ "type": "string",
687
+ "default": "current_user",
688
+ "description": "Parameter name to inject from Depends()"
689
+ },
690
+ "miss_status": {
691
+ "type": "integer",
692
+ "default": 404,
693
+ "description": "Status code when ownership check fails"
694
+ }
695
+ },
696
+ "required": [
697
+ "owner_field"
698
+ ]
699
+ }
700
+ }
701
+ },
702
+ "tests_config": {
703
+ "type": "object",
704
+ "additionalProperties": false,
705
+ "properties": {
706
+ "enabled": {
707
+ "type": "boolean",
708
+ "default": true
709
+ },
710
+ "scenarios": {
711
+ "type": "array",
712
+ "items": {
713
+ "type": "string",
714
+ "enum": [
715
+ "list_success",
716
+ "list_pagination",
717
+ "list_filters",
718
+ "create_success",
719
+ "create_minimal",
720
+ "create_missing_required",
721
+ "create_duplicate_unique",
722
+ "create_invalid_fk",
723
+ "get_success",
724
+ "get_not_found",
725
+ "update_success",
726
+ "update_partial",
727
+ "update_not_found",
728
+ "update_immutable_field",
729
+ "delete_success",
730
+ "delete_not_found",
731
+ "field_validation"
732
+ ]
733
+ }
734
+ },
735
+ "field_validations": {
736
+ "type": "array",
737
+ "items": {
738
+ "type": "object",
739
+ "required": [
740
+ "field",
741
+ "invalid_value"
742
+ ],
743
+ "additionalProperties": false,
744
+ "properties": {
745
+ "field": {
746
+ "type": "string"
747
+ },
748
+ "invalid_value": {},
749
+ "expected_error": {
750
+ "type": "string"
751
+ }
752
+ }
753
+ }
754
+ }
755
+ }
756
+ }
757
+ }
758
+ }