diff --git a/pkg/extension/schema_test.go b/pkg/extension/schema_test.go
index 20648678a159b6703d05687530ba8e16ded4c8f2..4b4f235ae6a43bbb7e9c39a56b45c51b530d7103 100644
--- a/pkg/extension/schema_test.go
+++ b/pkg/extension/schema_test.go
@@ -47,6 +47,8 @@ func TestEqualSchema(t *testing.T) {
 		require.NoError(t, err)
 		s2 := schema.New()
 		err = json.Unmarshal(b, s2)
+		s1.ClearState()
+		s2.ClearState()
 		require.NoError(t, err)
 		require.Equal(t, s1.Field, s2.Field)
 	}
diff --git a/pkg/files/field.go b/pkg/files/field.go
index 00659012aac439a835332ae9320fa64f2a03f9f9..ffb315d5522da6995b7a9a81040f47f933310df1 100644
--- a/pkg/files/field.go
+++ b/pkg/files/field.go
@@ -22,6 +22,27 @@ type FileParameters struct {
 
 func (p FileParameters) Type() field.Type                   { return p.t }
 func (p *FileParameters) Clone(reset bool) field.Parameters { return p }
+func (p FileParameters) GetField(f *field.Field, name string) *field.Field {
+	var fld *field.Field
+	switch name {
+	case "id", "name", "mimeType", "url", "key":
+		fld = field.String()
+	case "size":
+		fld = field.Number(field.NumberFormatInt)
+	}
+	return f.SetFieldState(name, fld)
+}
+
+func (p FileParameters) ListFields(f *field.Field, filter ...field.FieldFilterFunc) []*field.Field {
+	return []*field.Field{
+		f.SetFieldState("id", field.String()),
+		f.SetFieldState("name", field.String()),
+		f.SetFieldState("mimeType", field.String()),
+		f.SetFieldState("size", field.Number(field.NumberFormatInt)),
+		f.SetFieldState("url", field.String()),
+		f.SetFieldState("key", field.String()),
+	}
+}
 
 type FileType struct {
 	fs            Files
@@ -145,17 +166,6 @@ func (t *FileType) IsEmpty(v interface{}) bool {
 	return !ok || f.ID == ""
 }
 
-func (p FileParameters) GetField(path string) (fld *field.Field) {
-	switch path {
-	case "id", "name", "mimeType", "url", "key":
-		return field.String()
-	case "size":
-		return field.Number(field.NumberFormatInt)
-	default:
-		return nil
-	}
-}
-
 func init() {
 	// По умолчанию без FS
 	// Если нужны подписанные URL, и загрузка на FS, нужно зарегистрировать корректный типа
diff --git a/pkg/items/item_test.go b/pkg/items/item_test.go
index 2cef5e75414f55e09d3e5f42d4ed4ee56f0cd866..05baa60a3c1e8eaae9534fe9026d7456d78ab36c 100644
--- a/pkg/items/item_test.go
+++ b/pkg/items/item_test.go
@@ -72,6 +72,7 @@ func TestGetField(t *testing.T) {
 		),
 		"arr", field.Array(field.Object("a", field.Time())),
 	)
+	sch.ClearState()
 
 	tests := []struct {
 		name    string
diff --git a/pkg/references/field.go b/pkg/references/field.go
index 85482b9e526c502f24005329522e3690d803c283..905c2d43a1b05f5e19b00a99fcc8fadddd718b61 100644
--- a/pkg/references/field.go
+++ b/pkg/references/field.go
@@ -18,7 +18,6 @@ type ReferenceParameters struct {
 }
 
 func (p ReferenceParameters) Type() field.Type { return &ReferenceType{} }
-
 func (p ReferenceParameters) Clone(reset bool) field.Parameters {
 	if p.AllowedCollections != nil {
 		cols := make([]string, 0, len(p.AllowedCollections))
@@ -27,6 +26,10 @@ func (p ReferenceParameters) Clone(reset bool) field.Parameters {
 	}
 	return &p
 }
+func (p ReferenceParameters) GetField(f *field.Field, name string) *field.Field { return nil }
+func (p ReferenceParameters) ListFields(f *field.Field, filter ...field.FieldFilterFunc) []*field.Field {
+	return nil
+}
 
 type ReferenceType struct{}
 
diff --git a/pkg/schema/field/array.go b/pkg/schema/field/array.go
index 32d6f72f5e9260857dbabb4d46e6e498242fab4d..bf1a4819dd075fc5e3f46fc4d1e289c8bd75cf90 100644
--- a/pkg/schema/field/array.go
+++ b/pkg/schema/field/array.go
@@ -22,6 +22,22 @@ func (p ArrayParameters) Clone(reset bool) Parameters {
 	return &ArrayParameters{Item: p.Item.Clone(reset)}
 }
 
+func (a ArrayParameters) GetField(f *Field, name string) *Field {
+	f.SetFieldState("Item", a.Item)
+
+	if name == "" || name == "Item" {
+		return a.Item
+	}
+
+	return a.Item.GetField(name)
+}
+
+func (a ArrayParameters) ListFields(f *Field, filterFunc ...FieldFilterFunc) []*Field {
+	f.SetFieldState("Item", a.Item)
+
+	return []*Field{a.Item}
+}
+
 type ArrayType struct{}
 
 func (ArrayType) Name() string {
diff --git a/pkg/schema/field/boolean.go b/pkg/schema/field/boolean.go
index 94580541f8e33f9930adad94bff6a5c18915d05b..e06b704d0bb792d02a2f95343d037760fffb6fc7 100644
--- a/pkg/schema/field/boolean.go
+++ b/pkg/schema/field/boolean.go
@@ -10,8 +10,10 @@ var boolType = &BoolType{}
 
 type BoolParameters struct{}
 
-func (b BoolParameters) Type() Type                   { return boolType }
-func (b *BoolParameters) Clone(reset bool) Parameters { return b }
+func (b BoolParameters) Type() Type                                              { return boolType }
+func (b *BoolParameters) Clone(reset bool) Parameters                            { return b }
+func (b BoolParameters) GetField(f *Field, name string) *Field                   { return nil }
+func (b BoolParameters) ListFields(f *Field, filter ...FieldFilterFunc) []*Field { return nil }
 
 type BoolType struct{}
 
diff --git a/pkg/schema/field/field.go b/pkg/schema/field/field.go
index 6edf18f57ce36bc1569446502cc3ba05332252c8..4d2a6771bbe956f07698e52835aca53a2853bd58 100644
--- a/pkg/schema/field/field.go
+++ b/pkg/schema/field/field.go
@@ -49,6 +49,17 @@ type Include struct {
 	Optional bool   `json:"optional,omitempty"`
 }
 
+// State - состояние поля времени выполнения
+type State struct {
+	Name         string
+	DataPath     string
+	SchemaPath   string
+	SingleLocale bool
+	Parent       *Field
+	Inlined      bool
+	HasInline    bool
+}
+
 type Field struct {
 	Title            string        `json:"title,omitempty"`             // Название поля (Например: name)
 	Description      string        `json:"description,omitempty"`       // Описание поле (Например: User name)
@@ -63,6 +74,7 @@ type Field struct {
 	Options          Options       `json:"options,omitempty"`           // Дополнительные опции
 	Condition        string        `json:"condition,omitempty"`         // Условие отображения поля
 	AdditionalValues bool          `json:"additional_values,omitempty"` // Разрешает дополнительные значения вне ограничений правил
+	State            *State        `json:"-"`                           // Состояние поля времени выполнения
 }
 
 // TODO: Replace with Named field???
@@ -84,6 +96,32 @@ func NewField(params Parameters, opts ...interface{}) *Field {
 	return f
 }
 
+// GetState возвращает состояние поля времени выполнения
+func (f Field) GetState() *State {
+	return f.State
+}
+
+// ClearState очищает состояние поля и всех вложенных полей
+//
+// Схемы нельзя сравнивать с активным состоянием с помощью `reflect.DeepEqual` или `assert.Equal`.
+// Предварительно нужно сделать `ClearState`.
+// После очистки состояния полей не будут рассчитываться. Для повторного включения состояния используйте `EnableState`
+func (f *Field) ClearState() *Field {
+	f.State = nil
+	for _, fld := range f.ListFields() {
+		fld.ClearState()
+	}
+	return f
+}
+
+// EnableState включает расчет состояния поля и всех вложенных полей
+//
+// Без включения состояния поля, невозможно получить доступ к данным времени выполнения
+// schema.New включает состояние для схемы при создании
+func (f *Field) EnableState() {
+	f.State = &State{}
+}
+
 func (f Field) GetType() Type {
 	return f.Params.Type()
 }
@@ -164,6 +202,10 @@ func (f Field) SetSingleLocale(r bool) *Field {
 	return &f
 }
 
+func (f Field) IsSingleLocale() bool {
+	return f.SingleLocale || (f.State != nil && f.State.SingleLocale)
+}
+
 func (f Field) SetIndexed(r bool) *Field {
 	f.Indexed = r
 	return &f
@@ -257,46 +299,91 @@ func (f *Field) Prepare() error {
 	return nil
 }
 
-// GetField возвращает поле по строковому пути
-func (f *Field) GetField(path string) *Field {
-	if path == "" {
-		switch params := f.Params.(type) {
-		case *ArrayParameters:
-			// Возвращаем поле Item если путь указан как "arr."
-			return params.Item
-		}
-		return nil
+func (f *Field) SetFieldState(name string, fld *Field) *Field {
+	if f != nil && fld != nil && f.State != nil && fld.State == nil {
+		fld.State = f.getFieldState(name, fld)
 	}
+	return fld
+}
 
-	switch params := f.Params.(type) {
-	case *ObjectParameters:
-		pp := strings.SplitN(path, FieldSeparator, 2)
+// GetFieldState возвращает состояние вложенного поля
+func (f *Field) getFieldState(name string, fld *Field) *State {
+	if f.State == nil {
+		return nil
+	}
 
-		for k, v := range params.Fields {
+	state := State{
+		SchemaPath: name,
+		DataPath:   name,
+		Name:       name,
+	}
 
-			p, ok := v.Params.(*ObjectParameters)
-			if ok && p.Inline {
-				f := v.GetField(path)
-				if f != nil {
-					return f
-				}
-			}
+	dataPath := f.State.DataPath
 
-			if k == pp[0] {
-				if len(pp) == 1 {
-					return v
-				}
-				return v.GetField(pp[1])
+	switch params := f.Params.(type) {
+	case *ObjectParameters:
+		if params.Inline {
+			last := strings.LastIndex(dataPath, ".")
+			if last > 0 {
+				dataPath = dataPath[:last]
+			} else {
+				dataPath = ""
 			}
+			state.Inlined = true
+		}
+		if dataPath != "" {
+			state.DataPath = dataPath + FieldSeparator + state.DataPath
 		}
-	case Fielder:
-		return params.GetField(path)
 
 	case *ArrayParameters:
-		return params.Item.GetField(path)
+		state.DataPath = dataPath // Remove item from path
 	}
 
-	return nil
+	state.SingleLocale = f.IsSingleLocale() || fld.SingleLocale
+
+	if f.State.SchemaPath != "" {
+		state.SchemaPath = f.State.SchemaPath + FieldSeparator + state.SchemaPath
+	}
+	state.Parent = f
+	state.HasInline = f.State.HasInline || state.Inlined
+	return &state
+}
+
+func (f *Field) GetFieldByName(name string) *Field {
+	return f.Params.GetField(f, name)
+}
+
+// GetField возвращает поле по строковому пути
+func (f *Field) GetField(path string) *Field {
+	name := ""
+	parts := strings.SplitN(path, FieldSeparator, 2)
+
+	if len(parts) > 0 {
+		name = parts[0]
+	}
+
+	fld := f.GetFieldByName(name)
+
+	if fld != nil && len(parts) > 1 {
+		return fld.GetField(parts[1])
+	}
+
+	return fld
+}
+
+// ListFields возвращает массив вложенных полей данного поля
+func (f *Field) ListFields(filter ...FieldFilterFunc) []*Field {
+	fields := f.Params.ListFields(f, filter...)
+	return fields
+}
+
+// ListFieldsRecursive возвращает массив всех вложенных полей рекурсивно
+func (f *Field) ListFieldsRecursive(filter ...FieldFilterFunc) []*Field {
+	fields := f.ListFields(filter...)
+	for _, fld := range fields {
+		fields = append(fields, fld.ListFieldsRecursive(filter...)...)
+	}
+	return fields
 }
 
 // GetFieldsPath возвращает полный путь для массива полей
@@ -311,6 +398,8 @@ type FilterFunc func(*Field, string) bool
 
 func GetAll(field *Field, path string) bool { return true }
 
+// GetFields возвращает массив полей с путем???
+// DEPRECATED: использовать ListFields или ListFieldsRecursive
 func (f *Field) GetFields(filterFunc FilterFunc, pathPrefix ...string) (res []PathField) {
 	var path string
 
@@ -382,22 +471,26 @@ func getFieldsObject(path string, params *ObjectParameters, filterFunc FilterFun
 	return res
 }
 
+// GetNestedFields возвращает вложенные поля
+// DEPRECATED: использовать ListFields
 func (f *Field) GetNestedFields() []*Field {
-	switch params := f.Params.(type) {
-	case *ObjectParameters:
-		flds := make([]*Field, 0, len(params.Fields))
-		for _, v := range params.Fields {
-			if v == nil {
-				continue
-			}
-			flds = append(flds, v)
-		}
-		return flds
-	case *ArrayParameters:
-		return []*Field{params.Item}
-	}
-
-	return nil
+	return f.ListFields()
+
+	//switch params := f.Params.(type) {
+	//case *ObjectParameters:
+	//	flds := make([]*Field, 0, len(params.Fields))
+	//	for _, v := range params.Fields {
+	//		if v == nil {
+	//			continue
+	//		}
+	//		flds = append(flds, v)
+	//	}
+	//	return flds
+	//case *ArrayParameters:
+	//	return []*Field{params.Item}
+	//}
+	//
+	//return nil
 }
 
 // Clone создает копию поля
diff --git a/pkg/schema/field/field_json.go b/pkg/schema/field/field_json.go
index dfd7f85aebafe2f6c1008db1c45b40df65c27b9d..170e3d161f87300955b06d21e8cf79e2140f9eb8 100644
--- a/pkg/schema/field/field_json.go
+++ b/pkg/schema/field/field_json.go
@@ -61,6 +61,8 @@ func (f *Field) UnmarshalJSON(b []byte) error {
 		}
 	}
 
+	j.FieldData.State = f.State
+
 	*f = Field(j.FieldData)
 	f.Params = params
 	_ = f.Prepare()
diff --git a/pkg/schema/field/field_test.go b/pkg/schema/field/field_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..d27d74bb473a3303c95d5fb63e927d5b314d9a42
--- /dev/null
+++ b/pkg/schema/field/field_test.go
@@ -0,0 +1,101 @@
+package field
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestField_GetField(t *testing.T) {
+	sch := Object(
+		"f1", Object(
+			"a", String(),
+			"b", String().SetSingleLocale(true),
+		),
+		"f3", Object( // inline object
+			true,
+			"a", String(),
+			"b", Object(true, "c", String()),
+		).SetSingleLocale(true),
+		"f4", Array(Object("a", String())),
+		"f5", Array(String()),
+		"f6", Object(true, "f6", Object("a", String())),
+	)
+
+	sch.EnableState()
+
+	tests := []struct {
+		name string
+		path string
+		want *State
+	}{
+		{"Object", "f1", &State{Name: "f1", DataPath: "f1", SchemaPath: "f1", Parent: sch}},
+		{"Object field", "f1.a", &State{Name: "a", DataPath: "f1.a", SchemaPath: "f1.a", Parent: sch.GetField("f1")}},
+		{"Field with SingleLocale", "f1.b", &State{Name: "b", DataPath: "f1.b", SchemaPath: "f1.b", Parent: sch.GetField("f1"), SingleLocale: true}},
+		{"Object with SingleLocale", "f3", &State{Name: "f3", DataPath: "f3", SchemaPath: "f3", Parent: sch, SingleLocale: true}},
+		{"Inline", "a", &State{Name: "a", DataPath: "a", SchemaPath: "f3.a", Parent: sch.GetField("f3"), SingleLocale: true, Inlined: true, HasInline: true}},
+		{"Inline of inline", "c", &State{Name: "c", DataPath: "c", SchemaPath: "f3.b.c", Parent: sch.GetField("f3.b"), SingleLocale: true, Inlined: true, HasInline: true}},
+		{"Inline of inline (direct)", "f3.b.c", &State{Name: "c", DataPath: "c", SchemaPath: "f3.b.c", Parent: sch.GetField("f3.b"), SingleLocale: true, Inlined: true, HasInline: true}},
+		{"Array of Objects", "f4", &State{Name: "f4", DataPath: "f4", SchemaPath: "f4", Parent: sch}},
+		{"Array of Objects (Item)", "f4.Item", &State{Name: "Item", DataPath: "f4", SchemaPath: "f4.Item", Parent: sch.GetField("f4")}},
+		{"Array of Objects (Item field)", "f4.Item.a", &State{Name: "a", DataPath: "f4.a", SchemaPath: "f4.Item.a", Parent: sch.GetField("f4.Item")}},
+		{"Array of Objects (Item field direct)", "f4.a", &State{Name: "a", DataPath: "f4.a", SchemaPath: "f4.Item.a", Parent: sch.GetField("f4.Item")}},
+		{"Array of Strings", "f5", &State{Name: "f5", DataPath: "f5", SchemaPath: "f5", Parent: sch}},
+		{"Array of Strings (Item)", "f5.Item", &State{Name: "Item", DataPath: "f5", SchemaPath: "f5.Item", Parent: sch.GetField("f5")}},
+		{"Inline Same name not found", "f6.a", nil},
+		{"Inline Same name (direct)", "f6.f6.a", &State{Name: "a", DataPath: "f6.a", SchemaPath: "f6.f6.a", Parent: sch.GetField("f6.f6"), HasInline: true}},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got := sch.GetField(tt.path)
+			var st *State
+			if got != nil {
+				st = got.State
+			}
+
+			assert.Equal(t, tt.want, st)
+			sch.ClearState()
+			sch.EnableState()
+			if got != nil {
+				assert.Nil(t, got.State)
+			}
+		})
+	}
+}
+
+func TestField_ListFieldsRecursive(t *testing.T) {
+	sch := Object(
+		"f1", Object(
+			"f1a", String(),
+			"f1b", String().SetSingleLocale(true),
+		),
+		"f2", String(),
+		"f3", Object( // inline object
+			true,
+			"f3a", String(),
+			"f3b", Object(true, "f3bc", String()),
+		).SetSingleLocale(true),
+		"f4", Array(Object("f4a", String())),
+		"f5", Array(String()),
+		"f6", Object(true, "f6", Object("f6a", String())),
+	)
+
+	sch.EnableState()
+
+	fields := sch.ListFieldsRecursive()
+	assert.Len(t, fields, 16)
+	for _, f := range fields {
+		assert.NotNil(t, f.State)
+		assert.NotEmpty(t, f.State.Name)
+	}
+}
+
+func TestField_CloneWithState(t *testing.T) {
+	f := Object("a", String())
+	fld := f.Clone(false)
+	assert.Nil(t, fld.State)
+	f.EnableState()
+	fld = f.Clone(false)
+	assert.NotNil(t, fld.State)
+}
diff --git a/pkg/schema/field/location.go b/pkg/schema/field/location.go
index d89b3206d091971a123e8842330f4b850838ccdf..97aea3ea8aecbf206325bbd1b49363669ce0436d 100644
--- a/pkg/schema/field/location.go
+++ b/pkg/schema/field/location.go
@@ -14,8 +14,10 @@ var locationType = &LocationType{}
 
 type LocationParameters struct{}
 
-func (p LocationParameters) Type() Type                  { return locationType }
-func (p LocationParameters) Clone(reset bool) Parameters { return &LocationParameters{} }
+func (p LocationParameters) Type() Type                                              { return locationType }
+func (p LocationParameters) Clone(reset bool) Parameters                             { return &LocationParameters{} }
+func (p LocationParameters) GetField(f *Field, name string) *Field                   { return nil }
+func (p LocationParameters) ListFields(f *Field, filter ...FieldFilterFunc) []*Field { return nil }
 
 func (p LocationParameters) GetMongoIndexes(path string, f *Field) []mongo.IndexModel {
 	var add, geo mongo.IndexModel
diff --git a/pkg/schema/field/number.go b/pkg/schema/field/number.go
index 40d9c8167f54d23faaa40666ec1934b451d7a516..dfc8a6635cc0e719bd55e9f680ba23688674edd0 100644
--- a/pkg/schema/field/number.go
+++ b/pkg/schema/field/number.go
@@ -22,8 +22,10 @@ type NumberParameters struct {
 	Format string `json:"format,omitempty"`
 }
 
-func (NumberParameters) Type() Type                    { return numberType }
-func (p NumberParameters) Clone(reset bool) Parameters { return &p }
+func (NumberParameters) Type() Type                                                { return numberType }
+func (p NumberParameters) Clone(reset bool) Parameters                             { return &p }
+func (p NumberParameters) GetField(f *Field, name string) *Field                   { return nil }
+func (p NumberParameters) ListFields(f *Field, filter ...FieldFilterFunc) []*Field { return nil }
 
 type NumberType struct{}
 
diff --git a/pkg/schema/field/object.go b/pkg/schema/field/object.go
index 1f995cceba1816c67454d94771ef3287e86d948c..45bc3e61d835cca2b8ba1a8866636ccd740c48c4 100644
--- a/pkg/schema/field/object.go
+++ b/pkg/schema/field/object.go
@@ -36,6 +36,39 @@ func (p ObjectParameters) Clone(reset bool) Parameters {
 	return &p
 }
 
+func (p ObjectParameters) GetField(f *Field, name string) *Field {
+	// Поиск поля в текущем объекте
+	if fld, ok := p.Fields[name]; ok {
+		return f.SetFieldState(name, fld)
+	}
+
+	// Поиск поля во вложенных Inline объектах
+	for k, v := range p.Fields {
+		if p, ok := v.Params.(*ObjectParameters); ok {
+			if p.Inline {
+				v = f.SetFieldState(k, v)
+				if fld := v.GetFieldByName(name); fld != nil {
+					return fld
+				}
+			}
+		}
+	}
+
+	return nil
+}
+
+func (p ObjectParameters) ListFields(f *Field, filterFunc ...FieldFilterFunc) []*Field {
+	var fields []*Field
+	for k, fld := range p.Fields {
+		f.SetFieldState(k, fld)
+		if !ApplyFilterFunc(filterFunc, fld) {
+			continue
+		}
+		fields = append(fields, fld)
+	}
+	return fields
+}
+
 // IsInlineObject определяет являться ли поле name инлайн объектом
 func (p ObjectParameters) IsInlineObject(name string) bool {
 	fld, ok := p.Fields[name]
diff --git a/pkg/schema/field/primary_key.go b/pkg/schema/field/primary_key.go
index b0b26e16a91cd506231ba46307485290a138bfb8..da40f97eb65c8551b3ca2710a26812ececea616f 100644
--- a/pkg/schema/field/primary_key.go
+++ b/pkg/schema/field/primary_key.go
@@ -12,8 +12,10 @@ var primaryKeyType = &PrimaryKeyType{}
 
 type PrimaryKeyParameters struct{}
 
-func (p PrimaryKeyParameters) Type() Type                   { return primaryKeyType }
-func (p *PrimaryKeyParameters) Clone(reset bool) Parameters { return p }
+func (p PrimaryKeyParameters) Type() Type                                              { return primaryKeyType }
+func (p *PrimaryKeyParameters) Clone(reset bool) Parameters                            { return p }
+func (p PrimaryKeyParameters) GetField(f *Field, name string) *Field                   { return nil }
+func (p PrimaryKeyParameters) ListFields(f *Field, filter ...FieldFilterFunc) []*Field { return nil }
 
 type PrimaryKeyType struct{}
 
diff --git a/pkg/schema/field/string.go b/pkg/schema/field/string.go
index b7e548b65f5c1572cc515cad19192899843ab62f..17b5e7ae086d3fac1b25d8c332c33d83fecedfb8 100644
--- a/pkg/schema/field/string.go
+++ b/pkg/schema/field/string.go
@@ -10,8 +10,10 @@ var stringType = &StringType{}
 
 type StringParameters struct{}
 
-func (s StringParameters) Type() Type                   { return stringType }
-func (s *StringParameters) Clone(reset bool) Parameters { return s }
+func (s StringParameters) Type() Type                                              { return stringType }
+func (s *StringParameters) Clone(reset bool) Parameters                            { return s }
+func (s StringParameters) GetField(f *Field, name string) *Field                   { return nil }
+func (s StringParameters) ListFields(f *Field, filter ...FieldFilterFunc) []*Field { return nil }
 
 type StringType struct{}
 
diff --git a/pkg/schema/field/time.go b/pkg/schema/field/time.go
index 064906f236371d2914a0544c3f6abef83fd77f65..cdb50a4cafc500ea56dd56436faa5babd4793d31 100644
--- a/pkg/schema/field/time.go
+++ b/pkg/schema/field/time.go
@@ -17,8 +17,10 @@ type TimeParameters struct {
 	Layout string `json:"layout,omitempty"`
 }
 
-func (p TimeParameters) Type() Type                  { return timeType }
-func (p TimeParameters) Clone(reset bool) Parameters { return &p }
+func (p TimeParameters) Type() Type                                              { return timeType }
+func (p TimeParameters) Clone(reset bool) Parameters                             { return &p }
+func (p TimeParameters) GetField(f *Field, name string) *Field                   { return nil }
+func (p TimeParameters) ListFields(f *Field, filter ...FieldFilterFunc) []*Field { return nil }
 
 func (p TimeParameters) GetLayout() string {
 	if p.Layout != "" {
diff --git a/pkg/schema/field/timestamp.go b/pkg/schema/field/timestamp.go
index 694d477e0c6a55e5140c4e7d78d26381a31686ae..593218c645c016751d082d1e938d0c966134ebb9 100644
--- a/pkg/schema/field/timestamp.go
+++ b/pkg/schema/field/timestamp.go
@@ -13,8 +13,10 @@ var (
 
 type TimestampParameters struct{}
 
-func (t TimestampParameters) Type() Type                   { return timestampType }
-func (t *TimestampParameters) Clone(reset bool) Parameters { return t }
+func (t TimestampParameters) Type() Type                                              { return timestampType }
+func (t *TimestampParameters) Clone(reset bool) Parameters                            { return t }
+func (t TimestampParameters) GetField(f *Field, name string) *Field                   { return nil }
+func (t TimestampParameters) ListFields(f *Field, filter ...FieldFilterFunc) []*Field { return nil }
 
 type TimestampType struct{}
 
diff --git a/pkg/schema/field/type.go b/pkg/schema/field/type.go
index edae76734d562d2546d3b68e89e125c7a87744a6..984cd59187b8cd1f1380bcc0762d66366d4715ab 100644
--- a/pkg/schema/field/type.go
+++ b/pkg/schema/field/type.go
@@ -10,10 +10,23 @@ var (
 	registry sync.Map
 )
 
+type FieldFilterFunc func(f *Field) bool
+
+func ApplyFilterFunc(filterFunc []FieldFilterFunc, fld *Field) bool {
+	for _, f := range filterFunc {
+		if !f(fld) {
+			return false
+		}
+	}
+	return true
+}
+
 // Parameters - интерфейс который должен реализовывать параметр конкретного типа
 type Parameters interface {
 	Type() Type
 	Clone(reset bool) Parameters
+	GetField(f *Field, name string) *Field
+	ListFields(f *Field, filter ...FieldFilterFunc) []*Field
 }
 
 // Type - тип поля, отвечает за получение, кодирование и декодирование параметров для данного типа
diff --git a/pkg/schema/field/unknown.go b/pkg/schema/field/unknown.go
index ffe412265c18209cbcce8bc442bd6094e0eecf1d..36d0ba97fcd4b917af6e8986074d7f3f40e8654a 100644
--- a/pkg/schema/field/unknown.go
+++ b/pkg/schema/field/unknown.go
@@ -14,8 +14,10 @@ type UnknownParameters struct {
 	Params json.RawMessage `json:"params,omitempty"`
 }
 
-func (UnknownParameters) Type() Type                    { return unknownType }
-func (p UnknownParameters) Clone(reset bool) Parameters { return &p }
+func (UnknownParameters) Type() Type                                                { return unknownType }
+func (p UnknownParameters) Clone(reset bool) Parameters                             { return &p }
+func (p UnknownParameters) GetField(f *Field, name string) *Field                   { return nil }
+func (p UnknownParameters) ListFields(f *Field, filter ...FieldFilterFunc) []*Field { return nil }
 
 type UnknownType struct{}
 
diff --git a/pkg/schema/schema.go b/pkg/schema/schema.go
index 71d872763e886ad91555717d7b1ba86804c58cc5..fdb402b412de15b3ba8aa9d2b0244ea3d22e8f09 100644
--- a/pkg/schema/schema.go
+++ b/pkg/schema/schema.go
@@ -19,7 +19,9 @@ type Schema struct {
 }
 
 func New(kv ...interface{}) *Schema {
-	return &Schema{Field: *field.Object(kv...)}
+	s := &Schema{Field: *field.Object(kv...)}
+	s.Field.EnableState()
+	return s
 }
 
 func NewFromField(f *field.Field) *Schema {
@@ -46,6 +48,11 @@ func (s *Schema) Clone(reset bool) *Schema {
 	}
 }
 
+func (s *Schema) ClearState() *Schema {
+	s.Field.ClearState()
+	return s
+}
+
 func (s *Schema) Equal(sch *Schema) bool {
 	if s == sch {
 		return true
@@ -86,7 +93,10 @@ func (s *Schema) ConvertTypes() error {
 	if err != nil {
 		return errors.Wrap(err, "marshal schema")
 	}
+	// сохраняем состояние cхемы
+	state := s.Field.State
 	*s = *New()
+	s.Field.State = state
 	return errors.Wrap(s.UnmarshalJSON(b), "unmarshal schema")
 }
 
diff --git a/pkg/schema/schema_json_test.go b/pkg/schema/schema_json_test.go
index f9e6be1becbaa336b6aaf6e8ee177042b2cb22ff..31b475168e9e0179328295044a7201517212d4ec 100644
--- a/pkg/schema/schema_json_test.go
+++ b/pkg/schema/schema_json_test.go
@@ -70,6 +70,8 @@ func TestSchema_UnmarshalJSON(t *testing.T) {
 			if err := schema.UnmarshalJSON(tt.b); (err != nil) != tt.wantErr {
 				t.Errorf("UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
 			}
+			schema.ClearState()
+			tt.want.ClearState()
 			assert.Equal(t, tt.want, schema)
 		})
 	}
diff --git a/pkg/schema/test/convert_test.go b/pkg/schema/test/convert_test.go
index 170bee8320b510244923d9c3905c20c17dc1d3f7..5e791570ebfc12c9efc9a4c9295ce5dacced4af5 100644
--- a/pkg/schema/test/convert_test.go
+++ b/pkg/schema/test/convert_test.go
@@ -23,6 +23,9 @@ func TestFromFiles(t *testing.T) {
 
 	t.Run("Success", func(t *testing.T) {
 		schemas, err := schema.FromFS(os.DirFS("assets"))
+		for _, s := range schemas {
+			s.ClearState()
+		}
 		require.NoError(t, err)
 		require.Len(t, schemas, 2, "В директории хранятся две корректные схемы")
 		require.ElementsMatch(t, []*schema.Schema{getPagesSchema(), getPagesSchema()}, schemas, "Cхемы должны соответствовать объекту из функции")
@@ -146,6 +149,7 @@ func getPagesSchema() *schema.Schema {
 	page.Field.UI.Options["collection_icon"] = "ApartmentOutlined/FileTextOutlined"
 
 	_ = page.ConvertTypes()
+	page.ClearState()
 	return page
 }
 
diff --git a/pkg/schema/test/object_test.go b/pkg/schema/test/object_test.go
index f17b64511668ad8b4a86c5d91cb908a781384493..8bf3f82022e8501932e6474a985bcfc9f195e693 100644
--- a/pkg/schema/test/object_test.go
+++ b/pkg/schema/test/object_test.go
@@ -193,6 +193,9 @@ func TestSchema_JSON(t *testing.T) {
 	err = json.Unmarshal(b, res)
 	require.NoError(t, err)
 
+	sch.ClearState()
+	res.ClearState()
+
 	assert.Equal(t, sch, res)
 }
 
@@ -213,6 +216,7 @@ func TestSchemaUI_UnmarshalJSON(t *testing.T) {
 		"name", field.String().WithUI(ui),
 	)
 	schm.UI = ui
+	schm.ClearState()
 
 	j := `{
   "ui": {
@@ -288,6 +292,7 @@ func TestSchemaUI_UnmarshalJSON(t *testing.T) {
 
 	sch := schema.New()
 	err := sch.UnmarshalJSON([]byte(j))
+	sch.ClearState()
 	require.NoError(t, err)
 	assert.Equal(t, sch, schm)
 }
@@ -364,7 +369,7 @@ func TestSchema_GetField_WithInline(t *testing.T) {
 			"a", field.String(),
 			"b", field.String(),
 		),
-		"zz", field.Object(
+		"zzz", field.Object(
 			true,
 			"zz", field.Array(field.Object(
 				"str3", field.String(),
@@ -857,6 +862,7 @@ func TestSchema_UnknownJSON(t *testing.T) {
 		"times", field.Number("int"),
 		"dates", field.Array(field.Time()),
 	)
+	sch.ClearState()
 
 	b, err := json.Marshal(sch)
 	require.NoError(t, err)
@@ -881,6 +887,8 @@ func TestSchema_UnknownJSON(t *testing.T) {
 	require.NoError(t, err)
 	b, err = json.Marshal(s2)
 	require.NoError(t, err)
+	s1.ClearState()
+	s2.ClearState()
 	assert.Equal(t, "unknown", s2.GetType().Name(), "Схема неизвестного типа должна определяться как unknown")
 	assert.Equal(t, s1, s2, "Схема не должна меняться при повторном маршалинге")
 
@@ -888,6 +896,7 @@ func TestSchema_UnknownJSON(t *testing.T) {
 	s3 := schema.New()
 	err = json.Unmarshal(b, s3)
 	require.NoError(t, err)
+	s3.ClearState()
 	assert.Equal(t, "object", s3.GetType().Name(), "Схема должна восстановить тип object при восстановление регистрации типа")
 	assert.Equal(t, sch, s3, "Схема должна восстановиться при восстановление регистрации типа")
 }
diff --git a/pkg/setup/collection_test.go b/pkg/setup/collection_test.go
index 43b450119a0892865486517df1d43a7e92d3dc2d..788314ca8aa15aa9e4bba63ae6c090f0e5662e69 100644
--- a/pkg/setup/collection_test.go
+++ b/pkg/setup/collection_test.go
@@ -35,12 +35,19 @@ func TestSetup_InstallCollections(t *testing.T) {
 			},
 		},
 		{
-			name:        "Install one collection success",
-			collections: []*collections.Collection{{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env", Schema: schema.New("name", field.String())}},
+			name: "Install one collection success",
+			collections: []*collections.Collection{{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env",
+				Schema: schema.New("name", field.String()).ClearState()}},
 			collectionsCall: func(svc *mockscollections.Collections) {
 				svc.On("Get", mock.Anything, "sp", "env", "1").Return(nil, errors.New("not found")).Once()
-				svc.On("Create", mock.Anything, &collections.Collection{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env", Schema: schema.New("name", field.String())}).Return(&collections.Collection{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env", Schema: schema.New("name", field.String())}, nil).Once()
-				svc.On("SetSchema", mock.Anything, "sp", "env", "1", schema.New("name", field.String())).Return(nil).Once()
+				svc.On("Create", mock.Anything,
+					&collections.Collection{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env",
+						Schema: schema.New("name", field.String()).ClearState()}).
+					Return(&collections.Collection{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env",
+						Schema: schema.New("name", field.String()).ClearState()}, nil).Once()
+				svc.On("SetSchema", mock.Anything, "sp", "env", "1",
+					schema.New("name", field.String()).ClearState()).
+					Return(nil).Once()
 			},
 			envsCall: func(svc *envmocks.Environments) {
 				svc.On("Migrate", mock.Anything, "sp", "env").Return(nil).Once()
@@ -123,11 +130,15 @@ func TestSetup_InstallCollections(t *testing.T) {
 		},
 		{
 			name:        "Fail to install collection on migrate",
-			collections: []*collections.Collection{{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env", Schema: schema.New("name", field.String())}},
+			collections: []*collections.Collection{{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env", Schema: schema.New("name", field.String()).ClearState()}},
 			collectionsCall: func(svc *mockscollections.Collections) {
 				svc.On("Get", mock.Anything, "sp", "env", "1").Return(nil, errors.New("not found")).Once()
-				svc.On("Create", mock.Anything, &collections.Collection{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env", Schema: schema.New("name", field.String())}).Return(&collections.Collection{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env", Schema: schema.New("name", field.String())}, nil).Once()
-				svc.On("SetSchema", mock.Anything, "sp", "env", "1", schema.New("name", field.String())).Return(nil).Once()
+				svc.On("Create", mock.Anything, &collections.Collection{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env",
+					Schema: schema.New("name", field.String()).ClearState()}).
+					Return(&collections.Collection{ID: "1", SpaceID: "sp", Name: "space", EnvID: "env",
+						Schema: schema.New("name", field.String()).ClearState()}, nil).Once()
+				svc.On("SetSchema", mock.Anything, "sp", "env", "1",
+					schema.New("name", field.String()).ClearState()).Return(nil).Once()
 			},
 			envsCall: func(svc *envmocks.Environments) {
 				svc.On("Migrate", mock.Anything, "sp", "env").Return(errors.New("migrate error")).Once()