diff --git a/pkg/clients/mocks/Clients.go b/pkg/clients/mocks/Clients.go
index bfeb7e946a1fe50d044479ba785aac15f484ac31..f82320372fe227f84b9b5e49e306a7564aa1177f 100644
--- a/pkg/clients/mocks/Clients.go
+++ b/pkg/clients/mocks/Clients.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.7.4. DO NOT EDIT.
+// Code generated by mockery v2.15.0. DO NOT EDIT.
 
 package mocks
 
@@ -6,6 +6,7 @@ import (
 	context "context"
 
 	clients "git.perx.ru/perxis/perxis-go/pkg/clients"
+
 	mock "github.com/stretchr/testify/mock"
 )
 
@@ -147,3 +148,18 @@ func (_m *Clients) Update(ctx context.Context, client *clients.Client) error {
 
 	return r0
 }
+
+type mockConstructorTestingTNewClients interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewClients creates a new instance of Clients. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewClients(t mockConstructorTestingTNewClients) *Clients {
+	mock := &Clients{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/clients/mocks/Middleware.go b/pkg/clients/mocks/Middleware.go
new file mode 100644
index 0000000000000000000000000000000000000000..b3b45df720893370e26363da2e9209f59163e091
--- /dev/null
+++ b/pkg/clients/mocks/Middleware.go
@@ -0,0 +1,45 @@
+// Code generated by mockery v2.15.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	clients "git.perx.ru/perxis/perxis-go/pkg/clients"
+
+	mock "github.com/stretchr/testify/mock"
+)
+
+// Middleware is an autogenerated mock type for the Middleware type
+type Middleware struct {
+	mock.Mock
+}
+
+// Execute provides a mock function with given fields: _a0
+func (_m *Middleware) Execute(_a0 clients.Clients) clients.Clients {
+	ret := _m.Called(_a0)
+
+	var r0 clients.Clients
+	if rf, ok := ret.Get(0).(func(clients.Clients) clients.Clients); ok {
+		r0 = rf(_a0)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(clients.Clients)
+		}
+	}
+
+	return r0
+}
+
+type mockConstructorTestingTNewMiddleware interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewMiddleware creates a new instance of Middleware. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewMiddleware(t mockConstructorTestingTNewMiddleware) *Middleware {
+	mock := &Middleware{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/collaborators/mocks/Collaborators.go b/pkg/collaborators/mocks/Collaborators.go
index 6bcd7fb1c462ae85ef01ca50efa6145ce2f8d591..c3fb5291d2d4fdb4781f951677bbc3bd0f01ac5b 100644
--- a/pkg/collaborators/mocks/Collaborators.go
+++ b/pkg/collaborators/mocks/Collaborators.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.7.4. DO NOT EDIT.
+// Code generated by mockery v2.15.0. DO NOT EDIT.
 
 package mocks
 
@@ -6,6 +6,7 @@ import (
 	context "context"
 
 	collaborators "git.perx.ru/perxis/perxis-go/pkg/collaborators"
+
 	mock "github.com/stretchr/testify/mock"
 )
 
@@ -14,8 +15,8 @@ type Collaborators struct {
 	mock.Mock
 }
 
-// Get provides a mock function with given fields: ctx, spaceId, userId
-func (_m *Collaborators) Get(ctx context.Context, spaceId, subject string) (string, error) {
+// Get provides a mock function with given fields: ctx, spaceId, subject
+func (_m *Collaborators) Get(ctx context.Context, spaceId string, subject string) (string, error) {
 	ret := _m.Called(ctx, spaceId, subject)
 
 	var r0 string
@@ -58,7 +59,7 @@ func (_m *Collaborators) ListCollaborators(ctx context.Context, spaceId string)
 	return r0, r1
 }
 
-// ListSpaces provides a mock function with given fields: ctx, userId
+// ListSpaces provides a mock function with given fields: ctx, subject
 func (_m *Collaborators) ListSpaces(ctx context.Context, subject string) ([]*collaborators.Collaborator, error) {
 	ret := _m.Called(ctx, subject)
 
@@ -81,8 +82,8 @@ func (_m *Collaborators) ListSpaces(ctx context.Context, subject string) ([]*col
 	return r0, r1
 }
 
-// Remove provides a mock function with given fields: ctx, spaceId, userId
-func (_m *Collaborators) Remove(ctx context.Context, spaceId, subject string) error {
+// Remove provides a mock function with given fields: ctx, spaceId, subject
+func (_m *Collaborators) Remove(ctx context.Context, spaceId string, subject string) error {
 	ret := _m.Called(ctx, spaceId, subject)
 
 	var r0 error
@@ -95,8 +96,8 @@ func (_m *Collaborators) Remove(ctx context.Context, spaceId, subject string) er
 	return r0
 }
 
-// Set provides a mock function with given fields: ctx, spaceId, userId, role
-func (_m *Collaborators) Set(ctx context.Context, spaceId, subject, role string) error {
+// Set provides a mock function with given fields: ctx, spaceId, subject, role
+func (_m *Collaborators) Set(ctx context.Context, spaceId string, subject string, role string) error {
 	ret := _m.Called(ctx, spaceId, subject, role)
 
 	var r0 error
@@ -108,3 +109,18 @@ func (_m *Collaborators) Set(ctx context.Context, spaceId, subject, role string)
 
 	return r0
 }
+
+type mockConstructorTestingTNewCollaborators interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewCollaborators creates a new instance of Collaborators. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewCollaborators(t mockConstructorTestingTNewCollaborators) *Collaborators {
+	mock := &Collaborators{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/collaborators/mocks/Middleware.go b/pkg/collaborators/mocks/Middleware.go
new file mode 100644
index 0000000000000000000000000000000000000000..c3fa37385c431b4584703566c33ea6fea3e0ac95
--- /dev/null
+++ b/pkg/collaborators/mocks/Middleware.go
@@ -0,0 +1,45 @@
+// Code generated by mockery v2.15.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	collaborators "git.perx.ru/perxis/perxis-go/pkg/collaborators"
+
+	mock "github.com/stretchr/testify/mock"
+)
+
+// Middleware is an autogenerated mock type for the Middleware type
+type Middleware struct {
+	mock.Mock
+}
+
+// Execute provides a mock function with given fields: _a0
+func (_m *Middleware) Execute(_a0 collaborators.Collaborators) collaborators.Collaborators {
+	ret := _m.Called(_a0)
+
+	var r0 collaborators.Collaborators
+	if rf, ok := ret.Get(0).(func(collaborators.Collaborators) collaborators.Collaborators); ok {
+		r0 = rf(_a0)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(collaborators.Collaborators)
+		}
+	}
+
+	return r0
+}
+
+type mockConstructorTestingTNewMiddleware interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewMiddleware creates a new instance of Middleware. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewMiddleware(t mockConstructorTestingTNewMiddleware) *Middleware {
+	mock := &Middleware{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/collections/mocks/Collections.go b/pkg/collections/mocks/Collections.go
index e52dffabfd0c8764ab1edd08979b873666d1935e..e8bf9f486093a284dcdcb9d7034cb54c8bf26996 100644
--- a/pkg/collections/mocks/Collections.go
+++ b/pkg/collections/mocks/Collections.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.14.0. DO NOT EDIT.
+// Code generated by mockery v2.15.0. DO NOT EDIT.
 
 package mocks
 
@@ -6,8 +6,10 @@ import (
 	context "context"
 
 	collections "git.perx.ru/perxis/perxis-go/pkg/collections"
-	schema "git.perx.ru/perxis/perxis-go/pkg/schema"
+
 	mock "github.com/stretchr/testify/mock"
+
+	schema "git.perx.ru/perxis/perxis-go/pkg/schema"
 )
 
 // Collections is an autogenerated mock type for the Collections type
diff --git a/pkg/collections/mocks/Middleware.go b/pkg/collections/mocks/Middleware.go
new file mode 100644
index 0000000000000000000000000000000000000000..a0be631888dca02fadc204d3c256f57e9466eb5d
--- /dev/null
+++ b/pkg/collections/mocks/Middleware.go
@@ -0,0 +1,45 @@
+// Code generated by mockery v2.15.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	collections "git.perx.ru/perxis/perxis-go/pkg/collections"
+
+	mock "github.com/stretchr/testify/mock"
+)
+
+// Middleware is an autogenerated mock type for the Middleware type
+type Middleware struct {
+	mock.Mock
+}
+
+// Execute provides a mock function with given fields: _a0
+func (_m *Middleware) Execute(_a0 collections.Collections) collections.Collections {
+	ret := _m.Called(_a0)
+
+	var r0 collections.Collections
+	if rf, ok := ret.Get(0).(func(collections.Collections) collections.Collections); ok {
+		r0 = rf(_a0)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(collections.Collections)
+		}
+	}
+
+	return r0
+}
+
+type mockConstructorTestingTNewMiddleware interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewMiddleware creates a new instance of Middleware. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewMiddleware(t mockConstructorTestingTNewMiddleware) *Middleware {
+	mock := &Middleware{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/delivery/mocks/Delivery.go b/pkg/delivery/mocks/Delivery.go
index 5cd13757a86e0ee7cf7c3180053e65299558178a..1f8d05f53b9b07737cee4c505069060cf3b2c647 100644
--- a/pkg/delivery/mocks/Delivery.go
+++ b/pkg/delivery/mocks/Delivery.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.7.4. DO NOT EDIT.
+// Code generated by mockery v2.15.0. DO NOT EDIT.
 
 package mocks
 
@@ -6,9 +6,13 @@ import (
 	context "context"
 
 	collections "git.perx.ru/perxis/perxis-go/pkg/collections"
+
 	environments "git.perx.ru/perxis/perxis-go/pkg/environments"
+
 	items "git.perx.ru/perxis/perxis-go/pkg/items"
+
 	locales "git.perx.ru/perxis/perxis-go/pkg/locales"
+
 	mock "github.com/stretchr/testify/mock"
 )
 
@@ -17,6 +21,36 @@ type Delivery struct {
 	mock.Mock
 }
 
+// Aggregate provides a mock function with given fields: ctx, spaceId, envId, collectionId, filter, options
+func (_m *Delivery) Aggregate(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.AggregatePublishedOptions) (map[string]interface{}, error) {
+	_va := make([]interface{}, len(options))
+	for _i := range options {
+		_va[_i] = options[_i]
+	}
+	var _ca []interface{}
+	_ca = append(_ca, ctx, spaceId, envId, collectionId, filter)
+	_ca = append(_ca, _va...)
+	ret := _m.Called(_ca...)
+
+	var r0 map[string]interface{}
+	if rf, ok := ret.Get(0).(func(context.Context, string, string, string, *items.Filter, ...*items.AggregatePublishedOptions) map[string]interface{}); ok {
+		r0 = rf(ctx, spaceId, envId, collectionId, filter, options...)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(map[string]interface{})
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(context.Context, string, string, string, *items.Filter, ...*items.AggregatePublishedOptions) error); ok {
+		r1 = rf(ctx, spaceId, envId, collectionId, filter, options...)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
 // FindItems provides a mock function with given fields: ctx, spaceId, envId, collectionId, filter, options
 func (_m *Delivery) FindItems(ctx context.Context, spaceId string, envId string, collectionId string, filter *items.Filter, options ...*items.FindPublishedOptions) ([]*items.Item, int, error) {
 	_va := make([]interface{}, len(options))
@@ -198,3 +232,18 @@ func (_m *Delivery) ListLocales(ctx context.Context, spaceId string) ([]*locales
 
 	return r0, r1
 }
+
+type mockConstructorTestingTNewDelivery interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewDelivery creates a new instance of Delivery. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewDelivery(t mockConstructorTestingTNewDelivery) *Delivery {
+	mock := &Delivery{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/environments/mocks/Environments.go b/pkg/environments/mocks/Environments.go
index 8c8d099f32cbcbd7cd1edf377b3d46e6756a1d72..cfd1ef59a95c18881afa675ef92a12d3bf455fd7 100644
--- a/pkg/environments/mocks/Environments.go
+++ b/pkg/environments/mocks/Environments.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.14.0. DO NOT EDIT.
+// Code generated by mockery v2.15.0. DO NOT EDIT.
 
 package mocks
 
diff --git a/pkg/environments/mocks/Middleware.go b/pkg/environments/mocks/Middleware.go
new file mode 100644
index 0000000000000000000000000000000000000000..3620aacf4a16f9ecf159bd56508e7db27f72625d
--- /dev/null
+++ b/pkg/environments/mocks/Middleware.go
@@ -0,0 +1,45 @@
+// Code generated by mockery v2.15.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	environments "git.perx.ru/perxis/perxis-go/pkg/environments"
+
+	mock "github.com/stretchr/testify/mock"
+)
+
+// Middleware is an autogenerated mock type for the Middleware type
+type Middleware struct {
+	mock.Mock
+}
+
+// Execute provides a mock function with given fields: _a0
+func (_m *Middleware) Execute(_a0 environments.Environments) environments.Environments {
+	ret := _m.Called(_a0)
+
+	var r0 environments.Environments
+	if rf, ok := ret.Get(0).(func(environments.Environments) environments.Environments); ok {
+		r0 = rf(_a0)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(environments.Environments)
+		}
+	}
+
+	return r0
+}
+
+type mockConstructorTestingTNewMiddleware interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewMiddleware creates a new instance of Middleware. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewMiddleware(t mockConstructorTestingTNewMiddleware) *Middleware {
+	mock := &Middleware{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/files/mocks/Downloader.go b/pkg/files/mocks/Downloader.go
index 39bb7567df9916136706ffd1aa2c6634c29e9494..99c3e32cb685b311c4e66827ce6f9eef615f73d4 100644
--- a/pkg/files/mocks/Downloader.go
+++ b/pkg/files/mocks/Downloader.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.7.4. DO NOT EDIT.
+// Code generated by mockery v2.15.0. DO NOT EDIT.
 
 package mocks
 
@@ -6,6 +6,7 @@ import (
 	io "io"
 
 	files "git.perx.ru/perxis/perxis-go/pkg/files"
+
 	mock "github.com/stretchr/testify/mock"
 )
 
@@ -27,3 +28,18 @@ func (_m *Downloader) Download(dst io.Writer, file *files.File) error {
 
 	return r0
 }
+
+type mockConstructorTestingTNewDownloader interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewDownloader creates a new instance of Downloader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewDownloader(t mockConstructorTestingTNewDownloader) *Downloader {
+	mock := &Downloader{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/files/mocks/Files.go b/pkg/files/mocks/Files.go
index c6cdc0fa17f4674b98fb4c966d6ad7f87203276b..fa78a1809f968dbc21a10e4154284c07261a90ce 100644
--- a/pkg/files/mocks/Files.go
+++ b/pkg/files/mocks/Files.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.7.4. DO NOT EDIT.
+// Code generated by mockery v2.15.0. DO NOT EDIT.
 
 package mocks
 
@@ -156,3 +156,18 @@ func (_m *Files) Upload(ctx context.Context, file *files.File) (*files.Upload, e
 
 	return r0, r1
 }
+
+type mockConstructorTestingTNewFiles interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewFiles creates a new instance of Files. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewFiles(t mockConstructorTestingTNewFiles) *Files {
+	mock := &Files{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/files/mocks/Uploader.go b/pkg/files/mocks/Uploader.go
index 66624feef8b3e988ab06d9f73e416fc1afe0fea9..4ae80e348de2001158ff9e93c9a65180a06c9165 100644
--- a/pkg/files/mocks/Uploader.go
+++ b/pkg/files/mocks/Uploader.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.7.4. DO NOT EDIT.
+// Code generated by mockery v2.15.0. DO NOT EDIT.
 
 package mocks
 
@@ -6,6 +6,7 @@ import (
 	io "io"
 
 	files "git.perx.ru/perxis/perxis-go/pkg/files"
+
 	mock "github.com/stretchr/testify/mock"
 )
 
@@ -27,3 +28,18 @@ func (_m *Uploader) Upload(src io.Reader, upload *files.Upload) error {
 
 	return r0
 }
+
+type mockConstructorTestingTNewUploader interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewUploader creates a new instance of Uploader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewUploader(t mockConstructorTestingTNewUploader) *Uploader {
+	mock := &Uploader{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/images/mocks/Images.go b/pkg/images/mocks/Images.go
index 250fa5d0b8ef4c0a6993c2a318bea8f82cd24e6a..baf57ae6c35baeb19c45ba6046833ba0d41868f9 100644
--- a/pkg/images/mocks/Images.go
+++ b/pkg/images/mocks/Images.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.7.4. DO NOT EDIT.
+// Code generated by mockery v2.15.0. DO NOT EDIT.
 
 package mocks
 
@@ -7,6 +7,7 @@ import (
 
 	files "git.perx.ru/perxis/perxis-go/pkg/files"
 	images "git.perx.ru/perxis/perxis-go/pkg/images"
+
 	mock "github.com/stretchr/testify/mock"
 )
 
@@ -37,3 +38,18 @@ func (_m *Images) Get(ctx context.Context, source *files.File, opts *images.GetO
 
 	return r0, r1
 }
+
+type mockConstructorTestingTNewImages interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewImages creates a new instance of Images. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewImages(t mockConstructorTestingTNewImages) *Images {
+	mock := &Images{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/invitations/mocks/Invitations.go b/pkg/invitations/mocks/Invitations.go
index 610f9fff80d4867b35b80ff464bcf2a8a9d0e764..9484c62f6c3580ca114ad81bc0be1e14b8e263a2 100644
--- a/pkg/invitations/mocks/Invitations.go
+++ b/pkg/invitations/mocks/Invitations.go
@@ -1,13 +1,14 @@
-// Code generated by mockery v2.7.4. DO NOT EDIT.
+// Code generated by mockery v2.15.0. DO NOT EDIT.
 
 package mocks
 
 import (
-	"context"
+	context "context"
 
-	"git.perx.ru/perxis/perxis-go/pkg/invitations"
-	"git.perx.ru/perxis/perxis-go/pkg/options"
-	"github.com/stretchr/testify/mock"
+	invitations "git.perx.ru/perxis/perxis-go/pkg/invitations"
+	mock "github.com/stretchr/testify/mock"
+
+	options "git.perx.ru/perxis/perxis-go/pkg/options"
 )
 
 // Invitations is an autogenerated mock type for the Invitations type
@@ -118,3 +119,18 @@ func (_m *Invitations) Get(ctx context.Context, invitationId string) (*invitatio
 
 	return r0, r1
 }
+
+type mockConstructorTestingTNewInvitations interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewInvitations creates a new instance of Invitations. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewInvitations(t mockConstructorTestingTNewInvitations) *Invitations {
+	mock := &Invitations{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/invitations/mocks/Middleware.go b/pkg/invitations/mocks/Middleware.go
new file mode 100644
index 0000000000000000000000000000000000000000..608fa496bdef66615292c5426d5778942cf0ccad
--- /dev/null
+++ b/pkg/invitations/mocks/Middleware.go
@@ -0,0 +1,45 @@
+// Code generated by mockery v2.15.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	invitations "git.perx.ru/perxis/perxis-go/pkg/invitations"
+
+	mock "github.com/stretchr/testify/mock"
+)
+
+// Middleware is an autogenerated mock type for the Middleware type
+type Middleware struct {
+	mock.Mock
+}
+
+// Execute provides a mock function with given fields: _a0
+func (_m *Middleware) Execute(_a0 invitations.Invitations) invitations.Invitations {
+	ret := _m.Called(_a0)
+
+	var r0 invitations.Invitations
+	if rf, ok := ret.Get(0).(func(invitations.Invitations) invitations.Invitations); ok {
+		r0 = rf(_a0)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(invitations.Invitations)
+		}
+	}
+
+	return r0
+}
+
+type mockConstructorTestingTNewMiddleware interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewMiddleware creates a new instance of Middleware. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewMiddleware(t mockConstructorTestingTNewMiddleware) *Middleware {
+	mock := &Middleware{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/items/mocks/Items.go b/pkg/items/mocks/Items.go
index 1d3ea35f22d13e65afc70e6c7cc847c60aa0f8a7..1070cc78c9861e1d5613191b5b36c0fd7cffabd5 100644
--- a/pkg/items/mocks/Items.go
+++ b/pkg/items/mocks/Items.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.14.0. DO NOT EDIT.
+// Code generated by mockery v2.15.0. DO NOT EDIT.
 
 package mocks
 
@@ -6,8 +6,9 @@ import (
 	context "context"
 
 	items "git.perx.ru/perxis/perxis-go/pkg/items"
-	schema "git.perx.ru/perxis/perxis-go/pkg/schema"
 	mock "github.com/stretchr/testify/mock"
+
+	schema "git.perx.ru/perxis/perxis-go/pkg/schema"
 )
 
 // Items is an autogenerated mock type for the Items type
diff --git a/pkg/items/mocks/Middleware.go b/pkg/items/mocks/Middleware.go
new file mode 100644
index 0000000000000000000000000000000000000000..7830ca7447342c08772a78b63dbbe8ffbdc5591f
--- /dev/null
+++ b/pkg/items/mocks/Middleware.go
@@ -0,0 +1,45 @@
+// Code generated by mockery v2.15.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	items "git.perx.ru/perxis/perxis-go/pkg/items"
+
+	mock "github.com/stretchr/testify/mock"
+)
+
+// Middleware is an autogenerated mock type for the Middleware type
+type Middleware struct {
+	mock.Mock
+}
+
+// Execute provides a mock function with given fields: _a0
+func (_m *Middleware) Execute(_a0 items.Items) items.Items {
+	ret := _m.Called(_a0)
+
+	var r0 items.Items
+	if rf, ok := ret.Get(0).(func(items.Items) items.Items); ok {
+		r0 = rf(_a0)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(items.Items)
+		}
+	}
+
+	return r0
+}
+
+type mockConstructorTestingTNewMiddleware interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewMiddleware creates a new instance of Middleware. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewMiddleware(t mockConstructorTestingTNewMiddleware) *Middleware {
+	mock := &Middleware{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/items/mocks/PreSaver.go b/pkg/items/mocks/PreSaver.go
index 6010e17bd14db83518507ac53ab35076a6cbc5bf..2a78120e30ea79dd3a73750dd409641f72304b73 100644
--- a/pkg/items/mocks/PreSaver.go
+++ b/pkg/items/mocks/PreSaver.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.14.0. DO NOT EDIT.
+// Code generated by mockery v2.15.0. DO NOT EDIT.
 
 package mocks
 
diff --git a/pkg/items/mocks/ProcessDataFunc.go b/pkg/items/mocks/ProcessDataFunc.go
new file mode 100644
index 0000000000000000000000000000000000000000..5aa99801f9ea5479de292a590c9ce27c79d25620
--- /dev/null
+++ b/pkg/items/mocks/ProcessDataFunc.go
@@ -0,0 +1,54 @@
+// Code generated by mockery v2.15.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	context "context"
+
+	mock "github.com/stretchr/testify/mock"
+
+	schema "git.perx.ru/perxis/perxis-go/pkg/schema"
+)
+
+// ProcessDataFunc is an autogenerated mock type for the ProcessDataFunc type
+type ProcessDataFunc struct {
+	mock.Mock
+}
+
+// Execute provides a mock function with given fields: ctx, sch, data
+func (_m *ProcessDataFunc) Execute(ctx context.Context, sch *schema.Schema, data map[string]interface{}) (map[string]interface{}, error) {
+	ret := _m.Called(ctx, sch, data)
+
+	var r0 map[string]interface{}
+	if rf, ok := ret.Get(0).(func(context.Context, *schema.Schema, map[string]interface{}) map[string]interface{}); ok {
+		r0 = rf(ctx, sch, data)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(map[string]interface{})
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(context.Context, *schema.Schema, map[string]interface{}) error); ok {
+		r1 = rf(ctx, sch, data)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+type mockConstructorTestingTNewProcessDataFunc interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewProcessDataFunc creates a new instance of ProcessDataFunc. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewProcessDataFunc(t mockConstructorTestingTNewProcessDataFunc) *ProcessDataFunc {
+	mock := &ProcessDataFunc{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/locales/mocks/Locales.go b/pkg/locales/mocks/Locales.go
index 3e63dfedfff975f52f886d19e1e8982bccb96b7e..491406c5c3fa577050ee0f1a097b89419b17bf42 100644
--- a/pkg/locales/mocks/Locales.go
+++ b/pkg/locales/mocks/Locales.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.7.4. DO NOT EDIT.
+// Code generated by mockery v2.15.0. DO NOT EDIT.
 
 package mocks
 
@@ -73,3 +73,18 @@ func (_m *Locales) List(ctx context.Context, spaceId string) ([]*locales.Locale,
 
 	return r0, r1
 }
+
+type mockConstructorTestingTNewLocales interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewLocales creates a new instance of Locales. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewLocales(t mockConstructorTestingTNewLocales) *Locales {
+	mock := &Locales{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/locales/mocks/Middleware.go b/pkg/locales/mocks/Middleware.go
new file mode 100644
index 0000000000000000000000000000000000000000..bab6711d69138d1b72529c89c979f9e03dd47cd1
--- /dev/null
+++ b/pkg/locales/mocks/Middleware.go
@@ -0,0 +1,45 @@
+// Code generated by mockery v2.15.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	locales "git.perx.ru/perxis/perxis-go/pkg/locales"
+
+	mock "github.com/stretchr/testify/mock"
+)
+
+// Middleware is an autogenerated mock type for the Middleware type
+type Middleware struct {
+	mock.Mock
+}
+
+// Execute provides a mock function with given fields: _a0
+func (_m *Middleware) Execute(_a0 locales.Locales) locales.Locales {
+	ret := _m.Called(_a0)
+
+	var r0 locales.Locales
+	if rf, ok := ret.Get(0).(func(locales.Locales) locales.Locales); ok {
+		r0 = rf(_a0)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(locales.Locales)
+		}
+	}
+
+	return r0
+}
+
+type mockConstructorTestingTNewMiddleware interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewMiddleware creates a new instance of Middleware. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewMiddleware(t mockConstructorTestingTNewMiddleware) *Middleware {
+	mock := &Middleware{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/members/mocks/Members.go b/pkg/members/mocks/Members.go
index 2adeaac705bf18a17eb06f7932d5d3769de1b50f..894bc76d5652c37559e1c77e6f0d290b3551497a 100644
--- a/pkg/members/mocks/Members.go
+++ b/pkg/members/mocks/Members.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.7.4. DO NOT EDIT.
+// Code generated by mockery v2.15.0. DO NOT EDIT.
 
 package mocks
 
@@ -122,3 +122,18 @@ func (_m *Members) Set(ctx context.Context, orgId string, userId string, role me
 
 	return r0
 }
+
+type mockConstructorTestingTNewMembers interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewMembers creates a new instance of Members. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewMembers(t mockConstructorTestingTNewMembers) *Members {
+	mock := &Members{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/members/mocks/Middleware.go b/pkg/members/mocks/Middleware.go
new file mode 100644
index 0000000000000000000000000000000000000000..22b7a5dd3f3a42862b9899e6554b049c4595835c
--- /dev/null
+++ b/pkg/members/mocks/Middleware.go
@@ -0,0 +1,45 @@
+// Code generated by mockery v2.15.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	members "git.perx.ru/perxis/perxis-go/pkg/members"
+
+	mock "github.com/stretchr/testify/mock"
+)
+
+// Middleware is an autogenerated mock type for the Middleware type
+type Middleware struct {
+	mock.Mock
+}
+
+// Execute provides a mock function with given fields: _a0
+func (_m *Middleware) Execute(_a0 members.Members) members.Members {
+	ret := _m.Called(_a0)
+
+	var r0 members.Members
+	if rf, ok := ret.Get(0).(func(members.Members) members.Members); ok {
+		r0 = rf(_a0)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(members.Members)
+		}
+	}
+
+	return r0
+}
+
+type mockConstructorTestingTNewMiddleware interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewMiddleware creates a new instance of Middleware. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewMiddleware(t mockConstructorTestingTNewMiddleware) *Middleware {
+	mock := &Middleware{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/members/mocks/Observer.go b/pkg/members/mocks/Observer.go
new file mode 100644
index 0000000000000000000000000000000000000000..f2feb9607c89babdb3e27262a8095d47bc209873
--- /dev/null
+++ b/pkg/members/mocks/Observer.go
@@ -0,0 +1,52 @@
+// Code generated by mockery v2.15.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	context "context"
+
+	collaborators "git.perx.ru/perxis/perxis-go/pkg/collaborators"
+
+	mock "github.com/stretchr/testify/mock"
+)
+
+// Observer is an autogenerated mock type for the Observer type
+type Observer struct {
+	mock.Mock
+}
+
+// OnCollaboratorSet provides a mock function with given fields: ctx, collaborator
+func (_m *Observer) OnCollaboratorSet(ctx context.Context, collaborator *collaborators.Collaborator) (string, error) {
+	ret := _m.Called(ctx, collaborator)
+
+	var r0 string
+	if rf, ok := ret.Get(0).(func(context.Context, *collaborators.Collaborator) string); ok {
+		r0 = rf(ctx, collaborator)
+	} else {
+		r0 = ret.Get(0).(string)
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(context.Context, *collaborators.Collaborator) error); ok {
+		r1 = rf(ctx, collaborator)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+type mockConstructorTestingTNewObserver interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewObserver creates a new instance of Observer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewObserver(t mockConstructorTestingTNewObserver) *Observer {
+	mock := &Observer{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/members/observer/middleware/error_logging_middleware.go b/pkg/members/observer/middleware/error_logging_middleware.go
new file mode 100644
index 0000000000000000000000000000000000000000..b7184b475d626a0f4a2a53cd427a672841b38249
--- /dev/null
+++ b/pkg/members/observer/middleware/error_logging_middleware.go
@@ -0,0 +1,41 @@
+package middleware
+
+// Code generated by gowrap. DO NOT EDIT.
+// template: ../../../../assets/templates/middleware/error_log
+// gowrap: http://github.com/hexdigest/gowrap
+
+//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/members/observer -i Observer -t ../../../../assets/templates/middleware/error_log -o error_logging_middleware.go -l ""
+
+import (
+	"context"
+
+	"git.perx.ru/perxis/perxis-go/pkg/collaborators"
+	"git.perx.ru/perxis/perxis-go/pkg/members/observer"
+	"go.uber.org/zap"
+)
+
+// errorLoggingMiddleware implements observer.Observer that is instrumented with logging
+type errorLoggingMiddleware struct {
+	logger *zap.Logger
+	next   observer.Observer
+}
+
+// ErrorLoggingMiddleware instruments an implementation of the observer.Observer with simple logging
+func ErrorLoggingMiddleware(logger *zap.Logger) Middleware {
+	return func(next observer.Observer) observer.Observer {
+		return &errorLoggingMiddleware{
+			next:   next,
+			logger: logger,
+		}
+	}
+}
+
+func (m *errorLoggingMiddleware) OnCollaboratorSet(ctx context.Context, collaborator *collaborators.Collaborator) (delayedTaskID string, err error) {
+	logger := m.logger
+	defer func() {
+		if err != nil {
+			logger.Warn("response error", zap.Error(err))
+		}
+	}()
+	return m.next.OnCollaboratorSet(ctx, collaborator)
+}
diff --git a/pkg/members/observer/middleware/logging_middleware.go b/pkg/members/observer/middleware/logging_middleware.go
new file mode 100644
index 0000000000000000000000000000000000000000..09f203fd21f3a3d2ecabd3279c3d1ca2a323194d
--- /dev/null
+++ b/pkg/members/observer/middleware/logging_middleware.go
@@ -0,0 +1,72 @@
+package middleware
+
+// Code generated by gowrap. DO NOT EDIT.
+// template: ../../../../assets/templates/middleware/access_log
+// gowrap: http://github.com/hexdigest/gowrap
+
+//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/members/observer -i Observer -t ../../../../assets/templates/middleware/access_log -o logging_middleware.go -l ""
+
+import (
+	"context"
+	"fmt"
+	"time"
+
+	"git.perx.ru/perxis/perxis-go/pkg/auth"
+	"git.perx.ru/perxis/perxis-go/pkg/collaborators"
+	"git.perx.ru/perxis/perxis-go/pkg/members/observer"
+	"go.uber.org/zap"
+	"go.uber.org/zap/zapcore"
+)
+
+// loggingMiddleware implements observer.Observer that is instrumented with logging
+type loggingMiddleware struct {
+	logger *zap.Logger
+	next   observer.Observer
+}
+
+// LoggingMiddleware instruments an implementation of the observer.Observer with simple logging
+func LoggingMiddleware(logger *zap.Logger) Middleware {
+	return func(next observer.Observer) observer.Observer {
+		return &loggingMiddleware{
+			next:   next,
+			logger: logger,
+		}
+	}
+}
+
+func (m *loggingMiddleware) OnCollaboratorSet(ctx context.Context, collaborator *collaborators.Collaborator) (delayedTaskID string, err error) {
+	begin := time.Now()
+	var fields []zapcore.Field
+	for k, v := range map[string]interface{}{
+		"ctx":          ctx,
+		"collaborator": collaborator} {
+		if k == "ctx" {
+			fields = append(fields, zap.String("principal", fmt.Sprint(auth.GetPrincipal(ctx))))
+			continue
+		}
+		fields = append(fields, zap.Reflect(k, v))
+	}
+
+	m.logger.Debug("OnCollaboratorSet.Request", fields...)
+
+	delayedTaskID, err = m.next.OnCollaboratorSet(ctx, collaborator)
+
+	fields = []zapcore.Field{
+		zap.Duration("time", time.Since(begin)),
+	}
+
+	for k, v := range map[string]interface{}{
+		"delayedTaskID": delayedTaskID,
+		"err":           err} {
+		if k == "err" {
+			err, _ := v.(error)
+			fields = append(fields, zap.Error(err))
+			continue
+		}
+		fields = append(fields, zap.Reflect(k, v))
+	}
+
+	m.logger.Debug("OnCollaboratorSet.Response", fields...)
+
+	return delayedTaskID, err
+}
diff --git a/pkg/members/observer/middleware/middleware.go b/pkg/members/observer/middleware/middleware.go
new file mode 100644
index 0000000000000000000000000000000000000000..f68b58c7398b341f8f3850ddb96538027a58d354
--- /dev/null
+++ b/pkg/members/observer/middleware/middleware.go
@@ -0,0 +1,28 @@
+package middleware
+
+// Code generated by gowrap. DO NOT EDIT.
+// template: ../../../../assets/templates/middleware/middleware
+// gowrap: http://github.com/hexdigest/gowrap
+
+//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/members/observer -i Observer -t ../../../../assets/templates/middleware/middleware -o middleware.go -l ""
+
+import (
+	"git.perx.ru/perxis/perxis-go/pkg/members/observer"
+	"go.uber.org/zap"
+)
+
+type Middleware func(observer.Observer) observer.Observer
+
+func WithLog(s observer.Observer, logger *zap.Logger, log_access bool) observer.Observer {
+	if logger == nil {
+		logger = zap.NewNop()
+	}
+
+	logger = logger.Named("Observer")
+	s = ErrorLoggingMiddleware(logger)(s)
+	if log_access {
+		s = LoggingMiddleware(logger)(s)
+	}
+	s = RecoveringMiddleware(logger)(s)
+	return s
+}
diff --git a/pkg/members/observer/middleware/recovering_middleware.go b/pkg/members/observer/middleware/recovering_middleware.go
new file mode 100644
index 0000000000000000000000000000000000000000..bd576ecd2699dea927925b935bc024630420f997
--- /dev/null
+++ b/pkg/members/observer/middleware/recovering_middleware.go
@@ -0,0 +1,44 @@
+package middleware
+
+// Code generated by gowrap. DO NOT EDIT.
+// template: ../../../../assets/templates/middleware/recovery
+// gowrap: http://github.com/hexdigest/gowrap
+
+//go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/members/observer -i Observer -t ../../../../assets/templates/middleware/recovery -o recovering_middleware.go -l ""
+
+import (
+	"context"
+	"fmt"
+
+	"git.perx.ru/perxis/perxis-go/pkg/collaborators"
+	"git.perx.ru/perxis/perxis-go/pkg/members/observer"
+	"go.uber.org/zap"
+)
+
+// recoveringMiddleware implements observer.Observer that is instrumented with logging
+type recoveringMiddleware struct {
+	logger *zap.Logger
+	next   observer.Observer
+}
+
+// RecoveringMiddleware instruments an implementation of the observer.Observer with simple logging
+func RecoveringMiddleware(logger *zap.Logger) Middleware {
+	return func(next observer.Observer) observer.Observer {
+		return &recoveringMiddleware{
+			next:   next,
+			logger: logger,
+		}
+	}
+}
+
+func (m *recoveringMiddleware) OnCollaboratorSet(ctx context.Context, collaborator *collaborators.Collaborator) (delayedTaskID string, err error) {
+	logger := m.logger
+	defer func() {
+		if r := recover(); r != nil {
+			logger.Error("panic", zap.Error(fmt.Errorf("%v", r)))
+			err = fmt.Errorf("%v", r)
+		}
+	}()
+
+	return m.next.OnCollaboratorSet(ctx, collaborator)
+}
diff --git a/pkg/members/observer/mocks/Middleware.go b/pkg/members/observer/mocks/Middleware.go
new file mode 100644
index 0000000000000000000000000000000000000000..b953cf79d8239ef8da125e809bd29e1cf0a649f0
--- /dev/null
+++ b/pkg/members/observer/mocks/Middleware.go
@@ -0,0 +1,44 @@
+// Code generated by mockery v2.15.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	observer "git.perx.ru/perxis/perxis-go/pkg/members/observer"
+	mock "github.com/stretchr/testify/mock"
+)
+
+// Middleware is an autogenerated mock type for the Middleware type
+type Middleware struct {
+	mock.Mock
+}
+
+// Execute provides a mock function with given fields: _a0
+func (_m *Middleware) Execute(_a0 observer.Observer) observer.Observer {
+	ret := _m.Called(_a0)
+
+	var r0 observer.Observer
+	if rf, ok := ret.Get(0).(func(observer.Observer) observer.Observer); ok {
+		r0 = rf(_a0)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(observer.Observer)
+		}
+	}
+
+	return r0
+}
+
+type mockConstructorTestingTNewMiddleware interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewMiddleware creates a new instance of Middleware. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewMiddleware(t mockConstructorTestingTNewMiddleware) *Middleware {
+	mock := &Middleware{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/members/observer/mocks/Observer.go b/pkg/members/observer/mocks/Observer.go
index dd236a90fcc00410e57457eddb57e16a40245b92..d0e34ba31f431fe891a1bebf230aee9f72447283 100644
--- a/pkg/members/observer/mocks/Observer.go
+++ b/pkg/members/observer/mocks/Observer.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.7.4. DO NOT EDIT.
+// Code generated by mockery v2.15.0. DO NOT EDIT.
 
 package mocks
 
@@ -18,12 +18,34 @@ type Observer struct {
 func (_m *Observer) OnCollaboratorSet(ctx context.Context, collaborator *collaborators.Collaborator) (string, error) {
 	ret := _m.Called(ctx, collaborator)
 
-	var r0 error
-	if rf, ok := ret.Get(0).(func(context.Context, *collaborators.Collaborator) error); ok {
+	var r0 string
+	if rf, ok := ret.Get(0).(func(context.Context, *collaborators.Collaborator) string); ok {
 		r0 = rf(ctx, collaborator)
 	} else {
-		r0 = ret.Error(0)
+		r0 = ret.Get(0).(string)
 	}
 
-	return "", r0
+	var r1 error
+	if rf, ok := ret.Get(1).(func(context.Context, *collaborators.Collaborator) error); ok {
+		r1 = rf(ctx, collaborator)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+type mockConstructorTestingTNewObserver interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewObserver creates a new instance of Observer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewObserver(t mockConstructorTestingTNewObserver) *Observer {
+	mock := &Observer{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
 }
diff --git a/pkg/organizations/mocks/Middleware.go b/pkg/organizations/mocks/Middleware.go
new file mode 100644
index 0000000000000000000000000000000000000000..5ff2ac9d9bda88225394cdc0e3b80115e3078196
--- /dev/null
+++ b/pkg/organizations/mocks/Middleware.go
@@ -0,0 +1,44 @@
+// Code generated by mockery v2.15.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	organizations "git.perx.ru/perxis/perxis-go/pkg/organizations"
+	mock "github.com/stretchr/testify/mock"
+)
+
+// Middleware is an autogenerated mock type for the Middleware type
+type Middleware struct {
+	mock.Mock
+}
+
+// Execute provides a mock function with given fields: _a0
+func (_m *Middleware) Execute(_a0 organizations.Organizations) organizations.Organizations {
+	ret := _m.Called(_a0)
+
+	var r0 organizations.Organizations
+	if rf, ok := ret.Get(0).(func(organizations.Organizations) organizations.Organizations); ok {
+		r0 = rf(_a0)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(organizations.Organizations)
+		}
+	}
+
+	return r0
+}
+
+type mockConstructorTestingTNewMiddleware interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewMiddleware creates a new instance of Middleware. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewMiddleware(t mockConstructorTestingTNewMiddleware) *Middleware {
+	mock := &Middleware{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/organizations/mocks/Organizations.go b/pkg/organizations/mocks/Organizations.go
index 7b7255897b5f33f44202ef8e79255a93ea7ee429..ec0015ae2989bc8b090f95ba515fd0a09a2c45fe 100644
--- a/pkg/organizations/mocks/Organizations.go
+++ b/pkg/organizations/mocks/Organizations.go
@@ -1,13 +1,14 @@
-// Code generated by mockery v2.7.4. DO NOT EDIT.
+// Code generated by mockery v2.15.0. DO NOT EDIT.
 
 package mocks
 
 import (
 	context "context"
 
-	organizations "git.perx.ru/perxis/perxis-go/pkg/organizations"
-	services "git.perx.ru/perxis/perxis-go/pkg/options"
+	options "git.perx.ru/perxis/perxis-go/pkg/options"
 	mock "github.com/stretchr/testify/mock"
+
+	organizations "git.perx.ru/perxis/perxis-go/pkg/organizations"
 )
 
 // Organizations is an autogenerated mock type for the Organizations type
@@ -53,11 +54,11 @@ func (_m *Organizations) Delete(ctx context.Context, orgId string) error {
 }
 
 // Find provides a mock function with given fields: ctx, filter, opts
-func (_m *Organizations) Find(ctx context.Context, filter *organizations.Filter, opts *services.FindOptions) ([]*organizations.Organization, int, error) {
+func (_m *Organizations) Find(ctx context.Context, filter *organizations.Filter, opts *options.FindOptions) ([]*organizations.Organization, int, error) {
 	ret := _m.Called(ctx, filter, opts)
 
 	var r0 []*organizations.Organization
-	if rf, ok := ret.Get(0).(func(context.Context, *organizations.Filter, *services.FindOptions) []*organizations.Organization); ok {
+	if rf, ok := ret.Get(0).(func(context.Context, *organizations.Filter, *options.FindOptions) []*organizations.Organization); ok {
 		r0 = rf(ctx, filter, opts)
 	} else {
 		if ret.Get(0) != nil {
@@ -66,14 +67,14 @@ func (_m *Organizations) Find(ctx context.Context, filter *organizations.Filter,
 	}
 
 	var r1 int
-	if rf, ok := ret.Get(1).(func(context.Context, *organizations.Filter, *services.FindOptions) int); ok {
+	if rf, ok := ret.Get(1).(func(context.Context, *organizations.Filter, *options.FindOptions) int); ok {
 		r1 = rf(ctx, filter, opts)
 	} else {
 		r1 = ret.Get(1).(int)
 	}
 
 	var r2 error
-	if rf, ok := ret.Get(2).(func(context.Context, *organizations.Filter, *services.FindOptions) error); ok {
+	if rf, ok := ret.Get(2).(func(context.Context, *organizations.Filter, *options.FindOptions) error); ok {
 		r2 = rf(ctx, filter, opts)
 	} else {
 		r2 = ret.Error(2)
@@ -118,3 +119,18 @@ func (_m *Organizations) Update(ctx context.Context, org *organizations.Organiza
 
 	return r0
 }
+
+type mockConstructorTestingTNewOrganizations interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewOrganizations creates a new instance of Organizations. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewOrganizations(t mockConstructorTestingTNewOrganizations) *Organizations {
+	mock := &Organizations{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/references/mocks/Middleware.go b/pkg/references/mocks/Middleware.go
new file mode 100644
index 0000000000000000000000000000000000000000..6a7c665a9b0dc1043eec278b60561c993448d9c5
--- /dev/null
+++ b/pkg/references/mocks/Middleware.go
@@ -0,0 +1,44 @@
+// Code generated by mockery v2.15.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	references "git.perx.ru/perxis/perxis-go/pkg/references"
+	mock "github.com/stretchr/testify/mock"
+)
+
+// Middleware is an autogenerated mock type for the Middleware type
+type Middleware struct {
+	mock.Mock
+}
+
+// Execute provides a mock function with given fields: _a0
+func (_m *Middleware) Execute(_a0 references.References) references.References {
+	ret := _m.Called(_a0)
+
+	var r0 references.References
+	if rf, ok := ret.Get(0).(func(references.References) references.References); ok {
+		r0 = rf(_a0)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(references.References)
+		}
+	}
+
+	return r0
+}
+
+type mockConstructorTestingTNewMiddleware interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewMiddleware creates a new instance of Middleware. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewMiddleware(t mockConstructorTestingTNewMiddleware) *Middleware {
+	mock := &Middleware{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/references/mocks/References.go b/pkg/references/mocks/References.go
index c1ead2b49f11fd6492e3ce8f9eb5319cf3b208bc..40329c6d0bcf9f291fa594f81116d7b6985a273e 100644
--- a/pkg/references/mocks/References.go
+++ b/pkg/references/mocks/References.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.14.0. DO NOT EDIT.
+// Code generated by mockery v2.15.0. DO NOT EDIT.
 
 package mocks
 
@@ -6,8 +6,9 @@ import (
 	context "context"
 
 	items "git.perx.ru/perxis/perxis-go/pkg/items"
-	references "git.perx.ru/perxis/perxis-go/pkg/references"
 	mock "github.com/stretchr/testify/mock"
+
+	references "git.perx.ru/perxis/perxis-go/pkg/references"
 )
 
 // References is an autogenerated mock type for the References type
diff --git a/pkg/roles/mocks/Middleware.go b/pkg/roles/mocks/Middleware.go
new file mode 100644
index 0000000000000000000000000000000000000000..35f4f9798cdb83f05ded631cf0b23f1815fe0b47
--- /dev/null
+++ b/pkg/roles/mocks/Middleware.go
@@ -0,0 +1,44 @@
+// Code generated by mockery v2.15.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	roles "git.perx.ru/perxis/perxis-go/pkg/roles"
+	mock "github.com/stretchr/testify/mock"
+)
+
+// Middleware is an autogenerated mock type for the Middleware type
+type Middleware struct {
+	mock.Mock
+}
+
+// Execute provides a mock function with given fields: _a0
+func (_m *Middleware) Execute(_a0 roles.Roles) roles.Roles {
+	ret := _m.Called(_a0)
+
+	var r0 roles.Roles
+	if rf, ok := ret.Get(0).(func(roles.Roles) roles.Roles); ok {
+		r0 = rf(_a0)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(roles.Roles)
+		}
+	}
+
+	return r0
+}
+
+type mockConstructorTestingTNewMiddleware interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewMiddleware creates a new instance of Middleware. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewMiddleware(t mockConstructorTestingTNewMiddleware) *Middleware {
+	mock := &Middleware{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/roles/mocks/Roles.go b/pkg/roles/mocks/Roles.go
index d7e61236e36d2a5f544950f0634c5204d4a30a3e..1fc212541053dcfa1a05bdcd2d0b528d3f95fc34 100644
--- a/pkg/roles/mocks/Roles.go
+++ b/pkg/roles/mocks/Roles.go
@@ -1,12 +1,12 @@
-// Code generated by mockery v2.7.4. DO NOT EDIT.
+// Code generated by mockery v2.15.0. DO NOT EDIT.
 
 package mocks
 
 import (
-	"context"
+	context "context"
 
 	roles "git.perx.ru/perxis/perxis-go/pkg/roles"
-	"github.com/stretchr/testify/mock"
+	mock "github.com/stretchr/testify/mock"
 )
 
 // Roles is an autogenerated mock type for the Roles type
@@ -110,3 +110,18 @@ func (_m *Roles) Update(ctx context.Context, role *roles.Role) error {
 
 	return r0
 }
+
+type mockConstructorTestingTNewRoles interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewRoles creates a new instance of Roles. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewRoles(t mockConstructorTestingTNewRoles) *Roles {
+	mock := &Roles{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/spaces/mocks/Middleware.go b/pkg/spaces/mocks/Middleware.go
new file mode 100644
index 0000000000000000000000000000000000000000..0979e72e453c18aafb52448768f6f78fa54495c4
--- /dev/null
+++ b/pkg/spaces/mocks/Middleware.go
@@ -0,0 +1,44 @@
+// Code generated by mockery v2.15.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	spaces "git.perx.ru/perxis/perxis-go/pkg/spaces"
+	mock "github.com/stretchr/testify/mock"
+)
+
+// Middleware is an autogenerated mock type for the Middleware type
+type Middleware struct {
+	mock.Mock
+}
+
+// Execute provides a mock function with given fields: _a0
+func (_m *Middleware) Execute(_a0 spaces.Spaces) spaces.Spaces {
+	ret := _m.Called(_a0)
+
+	var r0 spaces.Spaces
+	if rf, ok := ret.Get(0).(func(spaces.Spaces) spaces.Spaces); ok {
+		r0 = rf(_a0)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(spaces.Spaces)
+		}
+	}
+
+	return r0
+}
+
+type mockConstructorTestingTNewMiddleware interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewMiddleware creates a new instance of Middleware. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewMiddleware(t mockConstructorTestingTNewMiddleware) *Middleware {
+	mock := &Middleware{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/spaces/mocks/Spaces.go b/pkg/spaces/mocks/Spaces.go
index e272ebceb87c26a672a3aaf5f7dde3dd4858991e..c052825a1d2bcf71be359eccc0f69cf7eb9800b9 100644
--- a/pkg/spaces/mocks/Spaces.go
+++ b/pkg/spaces/mocks/Spaces.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.22.1. DO NOT EDIT.
+// Code generated by mockery v2.15.0. DO NOT EDIT.
 
 package mocks
 
@@ -14,25 +14,22 @@ type Spaces struct {
 	mock.Mock
 }
 
-// Create provides a mock function with given fields: ctx, _a1
-func (_m *Spaces) Create(ctx context.Context, _a1 *spaces.Space) (*spaces.Space, error) {
-	ret := _m.Called(ctx, _a1)
+// Create provides a mock function with given fields: ctx, space
+func (_m *Spaces) Create(ctx context.Context, space *spaces.Space) (*spaces.Space, error) {
+	ret := _m.Called(ctx, space)
 
 	var r0 *spaces.Space
-	var r1 error
-	if rf, ok := ret.Get(0).(func(context.Context, *spaces.Space) (*spaces.Space, error)); ok {
-		return rf(ctx, _a1)
-	}
 	if rf, ok := ret.Get(0).(func(context.Context, *spaces.Space) *spaces.Space); ok {
-		r0 = rf(ctx, _a1)
+		r0 = rf(ctx, space)
 	} else {
 		if ret.Get(0) != nil {
 			r0 = ret.Get(0).(*spaces.Space)
 		}
 	}
 
+	var r1 error
 	if rf, ok := ret.Get(1).(func(context.Context, *spaces.Space) error); ok {
-		r1 = rf(ctx, _a1)
+		r1 = rf(ctx, space)
 	} else {
 		r1 = ret.Error(1)
 	}
@@ -59,10 +56,6 @@ func (_m *Spaces) Get(ctx context.Context, spaceId string) (*spaces.Space, error
 	ret := _m.Called(ctx, spaceId)
 
 	var r0 *spaces.Space
-	var r1 error
-	if rf, ok := ret.Get(0).(func(context.Context, string) (*spaces.Space, error)); ok {
-		return rf(ctx, spaceId)
-	}
 	if rf, ok := ret.Get(0).(func(context.Context, string) *spaces.Space); ok {
 		r0 = rf(ctx, spaceId)
 	} else {
@@ -71,6 +64,7 @@ func (_m *Spaces) Get(ctx context.Context, spaceId string) (*spaces.Space, error
 		}
 	}
 
+	var r1 error
 	if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
 		r1 = rf(ctx, spaceId)
 	} else {
@@ -85,10 +79,6 @@ func (_m *Spaces) List(ctx context.Context, orgId string) ([]*spaces.Space, erro
 	ret := _m.Called(ctx, orgId)
 
 	var r0 []*spaces.Space
-	var r1 error
-	if rf, ok := ret.Get(0).(func(context.Context, string) ([]*spaces.Space, error)); ok {
-		return rf(ctx, orgId)
-	}
 	if rf, ok := ret.Get(0).(func(context.Context, string) []*spaces.Space); ok {
 		r0 = rf(ctx, orgId)
 	} else {
@@ -97,6 +87,7 @@ func (_m *Spaces) List(ctx context.Context, orgId string) ([]*spaces.Space, erro
 		}
 	}
 
+	var r1 error
 	if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
 		r1 = rf(ctx, orgId)
 	} else {
@@ -106,13 +97,13 @@ func (_m *Spaces) List(ctx context.Context, orgId string) ([]*spaces.Space, erro
 	return r0, r1
 }
 
-// Update provides a mock function with given fields: ctx, _a1
-func (_m *Spaces) Update(ctx context.Context, _a1 *spaces.Space) error {
-	ret := _m.Called(ctx, _a1)
+// Update provides a mock function with given fields: ctx, space
+func (_m *Spaces) Update(ctx context.Context, space *spaces.Space) error {
+	ret := _m.Called(ctx, space)
 
 	var r0 error
 	if rf, ok := ret.Get(0).(func(context.Context, *spaces.Space) error); ok {
-		r0 = rf(ctx, _a1)
+		r0 = rf(ctx, space)
 	} else {
 		r0 = ret.Error(0)
 	}
diff --git a/pkg/users/mocks/Middleware.go b/pkg/users/mocks/Middleware.go
new file mode 100644
index 0000000000000000000000000000000000000000..7a8e59c7ce2ef43db52d15457ac0c57494bb383a
--- /dev/null
+++ b/pkg/users/mocks/Middleware.go
@@ -0,0 +1,44 @@
+// Code generated by mockery v2.15.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	users "git.perx.ru/perxis/perxis-go/pkg/users"
+	mock "github.com/stretchr/testify/mock"
+)
+
+// Middleware is an autogenerated mock type for the Middleware type
+type Middleware struct {
+	mock.Mock
+}
+
+// Execute provides a mock function with given fields: _a0
+func (_m *Middleware) Execute(_a0 users.Users) users.Users {
+	ret := _m.Called(_a0)
+
+	var r0 users.Users
+	if rf, ok := ret.Get(0).(func(users.Users) users.Users); ok {
+		r0 = rf(_a0)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(users.Users)
+		}
+	}
+
+	return r0
+}
+
+type mockConstructorTestingTNewMiddleware interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewMiddleware creates a new instance of Middleware. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewMiddleware(t mockConstructorTestingTNewMiddleware) *Middleware {
+	mock := &Middleware{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/users/mocks/Users.go b/pkg/users/mocks/Users.go
index 6e54f18c4dfc78d8473e5499262eb7d65c783e4d..124cc3c5096fbd00a9554c5e182610236e162574 100644
--- a/pkg/users/mocks/Users.go
+++ b/pkg/users/mocks/Users.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.7.4. DO NOT EDIT.
+// Code generated by mockery v2.15.0. DO NOT EDIT.
 
 package mocks
 
@@ -6,8 +6,9 @@ import (
 	context "context"
 
 	options "git.perx.ru/perxis/perxis-go/pkg/options"
-	users "git.perx.ru/perxis/perxis-go/pkg/users"
 	mock "github.com/stretchr/testify/mock"
+
+	users "git.perx.ru/perxis/perxis-go/pkg/users"
 )
 
 // Users is an autogenerated mock type for the Users type
@@ -52,13 +53,13 @@ func (_m *Users) Delete(ctx context.Context, userId string) error {
 	return r0
 }
 
-// Find provides a mock function with given fields: ctx, filter, options
-func (_m *Users) Find(ctx context.Context, filter *users.Filter, opts *options.FindOptions) ([]*users.User, int, error) {
-	ret := _m.Called(ctx, filter, opts)
+// Find provides a mock function with given fields: ctx, filter, _a2
+func (_m *Users) Find(ctx context.Context, filter *users.Filter, _a2 *options.FindOptions) ([]*users.User, int, error) {
+	ret := _m.Called(ctx, filter, _a2)
 
 	var r0 []*users.User
 	if rf, ok := ret.Get(0).(func(context.Context, *users.Filter, *options.FindOptions) []*users.User); ok {
-		r0 = rf(ctx, filter, opts)
+		r0 = rf(ctx, filter, _a2)
 	} else {
 		if ret.Get(0) != nil {
 			r0 = ret.Get(0).([]*users.User)
@@ -67,14 +68,14 @@ func (_m *Users) Find(ctx context.Context, filter *users.Filter, opts *options.F
 
 	var r1 int
 	if rf, ok := ret.Get(1).(func(context.Context, *users.Filter, *options.FindOptions) int); ok {
-		r1 = rf(ctx, filter, opts)
+		r1 = rf(ctx, filter, _a2)
 	} else {
 		r1 = ret.Get(1).(int)
 	}
 
 	var r2 error
 	if rf, ok := ret.Get(2).(func(context.Context, *users.Filter, *options.FindOptions) error); ok {
-		r2 = rf(ctx, filter, opts)
+		r2 = rf(ctx, filter, _a2)
 	} else {
 		r2 = ret.Error(2)
 	}
@@ -141,3 +142,18 @@ func (_m *Users) Update(ctx context.Context, update *users.User) error {
 
 	return r0
 }
+
+type mockConstructorTestingTNewUsers interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewUsers creates a new instance of Users. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewUsers(t mockConstructorTestingTNewUsers) *Users {
+	mock := &Users{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/version/mocks/Versions.go b/pkg/version/mocks/Versions.go
index e4572bac6ac23903d7ad0bdd94e2f7044f9fa7e3..a030dfb92c6b3055e2d6b564d1b2277e4eabfc11 100644
--- a/pkg/version/mocks/Versions.go
+++ b/pkg/version/mocks/Versions.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.7.4. DO NOT EDIT.
+// Code generated by mockery v2.15.0. DO NOT EDIT.
 
 package mocks
 
@@ -36,3 +36,18 @@ func (_m *Versions) Get(ctx context.Context) (*version.Version, error) {
 
 	return r0, r1
 }
+
+type mockConstructorTestingTNewVersions interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewVersions creates a new instance of Versions. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewVersions(t mockConstructorTestingTNewVersions) *Versions {
+	mock := &Versions{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}