diff --git a/.gitignore b/.gitignore
index 34142fe5c91654493d8dd95e68e432b6351f3196..062d8cab55b4f53d3554a92a098ab12811571702 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
 .idea
+.task
+*.bak
 dist/
 release/
\ No newline at end of file
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e4f5e9be9098cd25885506576ca5ddcc317041d6..3a438a1300cd1133cb6d1100a58a7ab63a9618fc 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -18,12 +18,12 @@ run_tests:
       junit: report.xml
 
 lint:
-  image: golangci/golangci-lint:v1.61-alpine
+  image: golangci/golangci-lint:v1.62.2-alpine
   rules:
     - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)'
   stage: test
   script:
-    - golangci-lint run --issues-exit-code 1 --print-issued-lines=false --new-from-rev $CI_MERGE_REQUEST_DIFF_BASE_SHA --out-format code-climate:gl-code-quality-report.json,line-number
+    - golangci-lint run --config .golangci.yml --issues-exit-code 1 --print-issued-lines=false --new-from-rev $CI_MERGE_REQUEST_DIFF_BASE_SHA --out-format code-climate:gl-code-quality-report.json,line-number
   artifacts:
     reports:
       codequality: gl-code-quality-report.json
diff --git a/.golangci.yml b/.golangci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c7dc4a6f94da9338a05f15f453872277a53d4a0d
--- /dev/null
+++ b/.golangci.yml
@@ -0,0 +1,366 @@
+run:
+  # Timeout for analysis, e.g. 30s, 5m.
+  # Default: 1m
+  timeout: 15m
+
+
+# This file contains only configs which differ from defaults.
+# All possible options can be found here https://github.com/golangci/golangci-lint/blob/master/.golangci.reference.yml
+linters-settings:
+  cyclop:
+    # The maximal code complexity to report.
+    # Default: 10
+    max-complexity: 30
+    # The maximal average package complexity.
+    # If it's higher than 0.0 (float) the check is enabled
+    # Default: 0.0
+    package-average: 10.0
+
+  errcheck:
+    # Report about not checking of errors in type assertions: `a := b.(MyStruct)`.
+    # Such cases aren't reported by default.
+    # Default: false
+    check-type-assertions: true
+
+  exhaustive:
+    # Program elements to check for exhaustiveness.
+    # Default: [ switch ]
+    check:
+      - switch
+      - map
+
+  exhaustruct:
+    # List of regular expressions to exclude struct packages and their names from checks.
+    # Regular expressions must match complete canonical struct package/name/structname.
+    # Default: []
+    exclude:
+      # std libs
+      - "^net/http.Client$"
+      - "^net/http.Cookie$"
+      - "^net/http.Request$"
+      - "^net/http.Response$"
+      - "^net/http.Server$"
+      - "^net/http.Transport$"
+      - "^net/url.URL$"
+      - "^os/exec.Cmd$"
+      - "^reflect.StructField$"
+      # public libs
+      - "^github.com/Shopify/sarama.Config$"
+      - "^github.com/Shopify/sarama.ProducerMessage$"
+      - "^github.com/mitchellh/mapstructure.DecoderConfig$"
+      - "^github.com/prometheus/client_golang/.+Opts$"
+      - "^github.com/spf13/cobra.Command$"
+      - "^github.com/spf13/cobra.CompletionOptions$"
+      - "^github.com/stretchr/testify/mock.Mock$"
+      - "^github.com/testcontainers/testcontainers-go.+Request$"
+      - "^github.com/testcontainers/testcontainers-go.FromDockerfile$"
+      - "^golang.org/x/tools/go/analysis.Analyzer$"
+      - "^google.golang.org/protobuf/.+Options$"
+      - "^gopkg.in/yaml.v3.Node$"
+
+  funlen:
+    # Checks the number of lines in a function.
+    # If lower than 0, disable the check.
+    # Default: 60
+    lines: 100
+    # Checks the number of statements in a function.
+    # If lower than 0, disable the check.
+    # Default: 40
+    statements: 50
+    # Ignore comments when counting lines.
+    # Default false
+    ignore-comments: true
+
+  gochecksumtype:
+    # Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed.
+    # Default: true
+    default-signifies-exhaustive: false
+
+  gocognit:
+    # Minimal code complexity to report.
+    # Default: 30 (but we recommend 10-20)
+    min-complexity: 20
+
+  gocritic:
+    # Settings passed to gocritic.
+    # The settings key is the name of a supported gocritic checker.
+    # The list of supported checkers can be find in https://go-critic.github.io/overview.
+    settings:
+      captLocal:
+        # Whether to restrict checker to params only.
+        # Default: true
+        paramsOnly: false
+      underef:
+        # Whether to skip (*x).method() calls where x is a pointer receiver.
+        # Default: true
+        skipRecvDeref: false
+
+  gomodguard:
+    blocked:
+      # List of blocked modules.
+      # Default: []
+      modules:
+        - github.com/golang/protobuf:
+            recommendations:
+              - google.golang.org/protobuf
+            reason: "see https://developers.google.com/protocol-buffers/docs/reference/go/faq#modules"
+        - github.com/satori/go.uuid:
+            recommendations:
+              - github.com/google/uuid
+            reason: "satori's package is not maintained"
+        - github.com/gofrs/uuid:
+            recommendations:
+              - github.com/gofrs/uuid/v5
+            reason: "gofrs' package was not go module before v5"
+
+  govet:
+    # Enable all analyzers.
+    # Default: false
+    enable-all: true
+    # Disable analyzers by name.
+    # Run `go tool vet help` to see all analyzers.
+    # Default: []
+    disable:
+      - fieldalignment # too strict
+    # Settings per analyzer.
+    settings:
+      shadow:
+        # Whether to be strict about shadowing; can be noisy.
+        # Default: false
+        strict: true
+
+  inamedparam:
+    # Skips check for interface methods with only a single parameter.
+    # Default: false
+    skip-single-param: true
+
+  mnd:
+    # List of function patterns to exclude from analysis.
+    # Values always ignored: `time.Date`,
+    # `strconv.FormatInt`, `strconv.FormatUint`, `strconv.FormatFloat`,
+    # `strconv.ParseInt`, `strconv.ParseUint`, `strconv.ParseFloat`.
+    # Default: []
+    ignored-functions:
+      - args.Error
+      - flag.Arg
+      - flag.Duration.*
+      - flag.Float.*
+      - flag.Int.*
+      - flag.Uint.*
+      - os.Chmod
+      - os.Mkdir.*
+      - os.OpenFile
+      - os.WriteFile
+      - prometheus.ExponentialBuckets.*
+      - prometheus.LinearBuckets
+
+  nakedret:
+    # Make an issue if func has more lines of code than this setting, and it has naked returns.
+    # Default: 30
+    max-func-lines: 0
+
+  nolintlint:
+    # Exclude following linters from requiring an explanation.
+    # Default: []
+    allow-no-explanation: [ funlen, gocognit, lll ]
+    # Enable to require an explanation of nonzero length after each nolint directive.
+    # Default: false
+    require-explanation: true
+    # Enable to require nolint directives to mention the specific linter being suppressed.
+    # Default: false
+    require-specific: true
+
+  perfsprint:
+    # Optimizes into strings concatenation.
+    # Default: true
+    strconcat: false
+
+  reassign:
+    # Patterns for global variable names that are checked for reassignment.
+    # See https://github.com/curioswitch/go-reassign#usage
+    # Default: ["EOF", "Err.*"]
+    patterns:
+      - ".*"
+
+  rowserrcheck:
+    # database/sql is always checked
+    # Default: []
+    packages:
+      - github.com/jmoiron/sqlx
+
+  sloglint:
+    # Enforce not using global loggers.
+    # Values:
+    # - "": disabled
+    # - "all": report all global loggers
+    # - "default": report only the default slog logger
+    # https://github.com/go-simpler/sloglint?tab=readme-ov-file#no-global
+    # Default: ""
+    no-global: "all"
+    # Enforce using methods that accept a context.
+    # Values:
+    # - "": disabled
+    # - "all": report all contextless calls
+    # - "scope": report only if a context exists in the scope of the outermost function
+    # https://github.com/go-simpler/sloglint?tab=readme-ov-file#context-only
+    # Default: ""
+    context: "scope"
+
+  tenv:
+    # The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.
+    # Otherwise, only methods that take `*testing.T`, `*testing.B`, and `testing.TB` as arguments are checked.
+    # Default: false
+    all: true
+
+
+linters:
+  disable-all: true
+  enable:
+    ## enabled by default
+    - errcheck # checking for unchecked errors, these unchecked errors can be critical bugs in some cases
+    - gosimple # specializes in simplifying a code
+    - govet # reports suspicious constructs, such as Printf calls whose arguments do not align with the format string
+    - ineffassign # detects when assignments to existing variables are not used
+    - staticcheck # is a go vet on steroids, applying a ton of static analysis checks
+    - typecheck # like the front-end of a Go compiler, parses and type-checks Go code
+    - unused # checks for unused constants, variables, functions and types
+    ## disabled by default
+    - asasalint # checks for pass []any as any in variadic func(...any)
+    - asciicheck # checks that your code does not contain non-ASCII identifiers
+    - bidichk # checks for dangerous unicode character sequences
+    - bodyclose # checks whether HTTP response body is closed successfully
+    - canonicalheader # checks whether net/http.Header uses canonical header
+    - copyloopvar # detects places where loop variables are copied (Go 1.22+)
+    - cyclop # checks function and package cyclomatic complexity
+    - dupl # tool for code clone detection
+    - durationcheck # checks for two durations multiplied together
+    - errname # checks that sentinel errors are prefixed with the Err and error types are suffixed with the Error
+    - errorlint # finds code that will cause problems with the error wrapping scheme introduced in Go 1.13
+    - exhaustive # checks exhaustiveness of enum switch statements
+    - fatcontext # detects nested contexts in loops
+    - forbidigo # forbids identifiers
+    - funlen # tool for detection of long functions
+    - gocheckcompilerdirectives # validates go compiler directive comments (//go:)
+    - gochecknoglobals # checks that no global variables exist
+    - gochecknoinits # checks that no init functions are present in Go code
+    - gochecksumtype # checks exhaustiveness on Go "sum types"
+    - gocognit # computes and checks the cognitive complexity of functions
+    - goconst # finds repeated strings that could be replaced by a constant
+    - gocritic # provides diagnostics that check for bugs, performance and style issues
+    - gocyclo # computes and checks the cyclomatic complexity of functions
+    - godot # checks if comments end in a period
+    - goimports # in addition to fixing imports, goimports also formats your code in the same style as gofmt
+    - gomoddirectives # manages the use of 'replace', 'retract', and 'excludes' directives in go.mod
+    - gomodguard # allow and block lists linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations
+    - goprintffuncname # checks that printf-like functions are named with f at the end
+    - gosec # inspects source code for security problems
+    - iface # checks the incorrect use of interfaces, helping developers avoid interface pollution
+    - intrange # finds places where for loops could make use of an integer range
+    - lll # reports long lines
+    - loggercheck # checks key value pairs for common logger libraries (kitlog,klog,logr,zap)
+    - makezero # finds slice declarations with non-zero initial length
+    - mirror # reports wrong mirror patterns of bytes/strings usage
+    - mnd # detects magic numbers
+    - musttag # enforces field tags in (un)marshaled structs
+    - nakedret # finds naked returns in functions greater than a specified function length
+    - nestif # reports deeply nested if statements
+    - nilerr # finds the code that returns nil even if it checks that the error is not nil
+    - nilnil # checks that there is no simultaneous return of nil error and an invalid value
+    - noctx # finds sending http request without context.Context
+    - nolintlint # reports ill-formed or insufficient nolint directives
+    - nonamedreturns # reports all named returns
+    - nosprintfhostport # checks for misuse of Sprintf to construct a host with port in a URL
+    - perfsprint # checks that fmt.Sprintf can be replaced with a faster alternative
+    - predeclared # finds code that shadows one of Go's predeclared identifiers
+    - protogetter # reports direct reads from proto message fields when getters should be used
+    - reassign # checks that package variables are not reassigned
+    - recvcheck # checks for receiver type consistency
+    - revive # fast, configurable, extensible, flexible, and beautiful linter for Go, drop-in replacement of golint
+    - rowserrcheck # checks whether Err of rows is checked successfully
+    - sloglint # ensure consistent code style when using log/slog
+    - spancheck # checks for mistakes with OpenTelemetry/Census spans
+    - sqlclosecheck # checks that sql.Rows and sql.Stmt are closed
+    - stylecheck # is a replacement for golint
+    - tenv # detects using os.Setenv instead of t.Setenv since Go1.17
+    - testableexamples # checks if examples are testable (have an expected output)
+    - testifylint # checks usage of github.com/stretchr/testify
+    #- testpackage # makes you use a separate _test package
+    - unconvert # removes unnecessary type conversions
+    - unparam # reports unused function parameters
+    - usestdlibvars # detects the possibility to use variables/constants from the Go standard library
+    - wastedassign # finds wasted assignment statements
+    - whitespace # detects leading and trailing whitespace
+
+    ## you may want to enable
+    #- decorder # checks declaration order and count of types, constants, variables and functions
+    #- exhaustruct # [highly recommend to enable] checks if all structure fields are initialized
+    #- gci # controls golang package import order and makes it always deterministic
+    #- ginkgolinter # [if you use ginkgo/gomega] enforces standards of using ginkgo and gomega
+    #- godox # detects FIXME, TODO and other comment keywords
+    #- goheader # checks is file header matches to pattern
+    #- inamedparam # [great idea, but too strict, need to ignore a lot of cases by default] reports interfaces with unnamed method parameters
+    #- interfacebloat # checks the number of methods inside an interface
+    #- ireturn # accept interfaces, return concrete types
+    #- prealloc # [premature optimization, but can be used in some cases] finds slice declarations that could potentially be preallocated
+    #- tagalign # checks that struct tags are well aligned
+    #- varnamelen # [great idea, but too many false positives] checks that the length of a variable's name matches its scope
+    #- wrapcheck # checks that errors returned from external packages are wrapped
+    #- zerologlint # detects the wrong usage of zerolog that a user forgets to dispatch zerolog.Event
+
+    ## disabled
+    #- containedctx # detects struct contained context.Context field
+    #- contextcheck # [too many false positives] checks the function whether use a non-inherited context
+    #- depguard # [replaced by gomodguard] checks if package imports are in a list of acceptable packages
+    #- dogsled # checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())
+    #- dupword # [useless without config] checks for duplicate words in the source code
+    #- err113 # [too strict] checks the errors handling expressions
+    #- errchkjson # [don't see profit + I'm against of omitting errors like in the first example https://github.com/breml/errchkjson] checks types passed to the json encoding functions. Reports unsupported types and optionally reports occasions, where the check for the returned error can be omitted
+    #- exportloopref # [not necessary from Go 1.22] checks for pointers to enclosing loop variables
+    #- forcetypeassert # [replaced by errcheck] finds forced type assertions
+    #- gofmt # [replaced by goimports] checks whether code was gofmt-ed
+    #- gofumpt # [replaced by goimports, gofumports is not available yet] checks whether code was gofumpt-ed
+    #- gosmopolitan # reports certain i18n/l10n anti-patterns in your Go codebase
+    #- grouper # analyzes expression groups
+    #- importas # enforces consistent import aliases
+    #- maintidx # measures the maintainability index of each function
+    #- misspell # [useless] finds commonly misspelled English words in comments
+    #- nlreturn # [too strict and mostly code is not more readable] checks for a new line before return and branch statements to increase code clarity
+    #- paralleltest # [too many false positives] detects missing usage of t.Parallel() method in your Go test
+    #- tagliatelle # checks the struct tags
+    #- thelper # detects golang test helpers without t.Helper() call and checks the consistency of test helpers
+    #- wsl # [too strict and mostly code is not more readable] whitespace linter forces you to use empty lines
+
+
+issues:
+  # Maximum count of issues with the same text.
+  # Set to 0 to disable.
+  # Default: 3
+  max-same-issues: 50
+
+  exclude-rules:
+    - source: "(noinspection|TODO)"
+      linters: [ godot ]
+    - source: "//noinspection"
+      linters: [ gocritic ]
+    - path: "_test\\.go"
+      linters:
+        - bodyclose
+        - dupl
+        - errcheck
+        - funlen
+        - goconst
+        - gosec
+        - noctx
+        - wrapcheck
+        - mnd
+    - path: "_middleware\\.go"
+      linters:
+        - nonamedreturns
+        - revive
+        - stylecheck
+    - path: "test/.*\\.go"
+      linters:
+        - mnd
+    - text: "shadow: declaration of \"(err|ctx)\" shadows declaration at"
+      linters:
+        - govet
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 919b98cf56f75d40166d183305e72c46deaf6027..23ada3bc7ebe4bba71af5b8be75bd14139e46939 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,45 @@
 # Changelog
 
-All notable changes to this project will be documented in this file.
+## [0.32.0] - 2025-02-28
+
+### 🚀 Новые возможности
+
+- **invitations**: Обновлен API Invitations с поддержкой многоразовых приглашений [#2929](https://git.perx.ru/perxis/perxis/-/issues/2929) ([b80739c](https://git.perx.ru/perxis/perxis-go/-/commit/b80739ccdb1c4d0402a6b47e41e84fc20fac04d2))
+- **core**: Добавлен метод для получения объекта из архива GetArchived [#2922](https://git.perx.ru/perxis/perxis/-/issues/2922) ([ed1f360](https://git.perx.ru/perxis/perxis-go/-/commit/ed1f360fff5453263d42d36427e77f8b115aee76))
+- **schema**: Добавлена возможность использования в схеме типов соответствующих данным массива, строки и числа [#2890](https://git.perx.ru/perxis/perxis/-/issues/2890) ([c55180e](https://git.perx.ru/perxis/perxis-go/-/commit/c55180ef69df6577e96b6322963d48618c869592))
+
+### ⚙️ Прочие задачи
+
+- Добавлена спецификация JSON Schema для схемы коллекций ([7cf1e93](https://git.perx.ru/perxis/perxis-go/-/commit/7cf1e93096763f6e204492171fa26ab15c3616a2))
+
+<!-- generated by git-cliff -->
+
+## [0.31.1] - 2024-12-28
+
+### 🐛 Исправлены ошибки
+
+- **files**: Исправлена ошибка при которой временные файлы не перемещались в постоянное хранилище ([87b6304](https://git.perx.ru/perxis/perxis-go/-/commit/87b6304193c2cfb6c53189aaf497bef0215254ca))
+
+<!-- generated by git-cliff -->
+
+## [0.31.0] - 2024-12-19
+
+### 🚀 Новые возможности
+
+- Обновлен сервис Logs после изменений в прото-спецификации сервиса ([a86999a](https://git.perx.ru/perxis/perxis-go/-/commit/a86999a62c4963837032c6cbf86fb6ef7b486b8b))
+- Добавлен возврат общего количества ревизий для метода ListRevisions [#2885](https://git.perx.ru/perxis/perxis/-/issues/2885) ([5671511](https://git.perx.ru/perxis/perxis-go/-/commit/56715111dda38d3d5e62beeebe649d64cf602a4c))
+- **items**: Добавлен метод Items.CheckoutRevision [#2846](https://git.perx.ru/perxis/perxis/-/issues/2846) ([36ffcd0](https://git.perx.ru/perxis/perxis-go/-/commit/36ffcd03014b8b7da3abdc42a4450e2093d5102d))
+- **extensions**: Добавлены поля для передачи клиентских данных при запросах ActionRequest ([e09530b](https://git.perx.ru/perxis/perxis-go/-/commit/e09530b49f4a52155b966c68adbf76d62799f6bd))
+
+### ⚙️ Прочие задачи
+
+- Добавлен фильтр по тегам (tag) в Collections.List ([8d47f17](https://git.perx.ru/perxis/perxis-go/-/commit/8d47f1781c029151163e868e9d9abca531ebce49))
+- Пакет template вынесен в корень проекта ([9093516](https://git.perx.ru/perxis/perxis-go/-/commit/90935168e52dc76a61c78dc40a2c17a953f3d554))
+- Перегенерированы клиенты, моки, middleware  [#2862](https://git.perx.ru/perxis/perxis/-/issues/2862) ([0e67767](https://git.perx.ru/perxis/perxis-go/-/commit/0e67767d112c1f34990c02c64b51c74fbfbbc59c))
+- Добавлена конфигурация для golangci-lint с добавлением дополнительных линтеров [#2953](https://git.perx.ru/perxis/perxis/-/issues/2953) ([c0721ec](https://git.perx.ru/perxis/perxis-go/-/commit/c0721ec476fa0043191bb29f827a8e5ac13c5b13))
+- Обновление Taskfile [#2849](https://git.perx.ru/perxis/perxis/-/issues/2849) ([7ecb191](https://git.perx.ru/perxis/perxis-go/-/commit/7ecb191b8f8716c82ffce6be60b81b688b6d7291))
+
+<!-- generated by git-cliff -->
 
 ## [0.30.0] - 2024-10-22
 
diff --git a/Taskfile.yaml b/Taskfile.yaml
index a75ab1d82db97c1725b2de039d57ab0e8d20b882..4a97ef91b1d1e59c673ccfc8085f5a09a5c7c8aa 100644
--- a/Taskfile.yaml
+++ b/Taskfile.yaml
@@ -2,67 +2,212 @@ version: '3'
 
 vars:
   PROTODIR: perxis-proto/proto
-  PBDIR: pb
-  CURRENT_VERSION:
-    sh: svu current
-  RELEASE_VERSION:
-    sh: svu next
+  PBDIR: proto
+  DATE:
+    sh: date -Idate
 
 tasks:
-  changelog:
+  tools:brew:
+    desc: Установка инструментов через brew
     cmds:
-      - git-cliff > CHANGELOG.md --tag {{ .RELEASE_VERSION }}
+      - brew tap caarlos0/tap
+      - brew install caarlos0/tap/svu
+      - brew install git-cliff
+      - brew install goreleaser
+      - brew install mockery
+      - brew install protoc-gen-go
+      - brew install protoc-gen-go-grpc
 
-# release
-# - Сделать changelog
-# - Закоммитить все изменения
-# - Пометить тэгом версию
-#   пререлиз - `git tag "$(svu pr --pre-release alpha.1 --build 9)"`
-#   пререлиз - `git tag "$(svu next)"`
-# - Запушить код и тэги на сервер (иначе будет непонятная ошибка goreleaser Not found)
-  release:
+  # Тесты
+
+  test:unit:
+    aliases: [tu]
+    desc: Запускает только юнит-тесты
+    cmds:
+      - go test ./...
+
+  test:unit:short:
+    aliases: [tus]
+    desc: Запускает только быстрые юнит-тесты
+    cmds:
+      - go test -short ./...
+
+  test:integration:
+    desc: Запускает только интеграционные тесты
+    cmds:
+      - go test -tags integration ./...
+
+  test:integration:short:
+    desc: Запускает только быстрые интеграционные тесты
+    cmds:
+      - go test -tags integration -short ./...
+
+  test:all:
+    desc: Запускает все тесты (юнит и интеграционные)
+    cmds:
+      - go test -tags all ./...
+
+  test:all:short:
+    desc: Запускает все быстрые тесты (юнит и интеграционные)
+    cmds:
+      - go test -tags all -short ./...
+
+  # Release
+
+  release:changelog:
+    aliases: [cl]
+    desc: "Подготовка CHANGELOG.md"
+    vars:
+      CURRENT_VERSION:
+        sh: svu current
+      RELEASE_VERSION:
+        sh: svu next
     cmds:
       - mkdir -p release
-      - git-cliff {{ .CURRENT_VERSION }}.. --tag {{ .RELEASE_VERSION }}  > release/CHANGELOG.md
+      - git cliff {{ .CURRENT_VERSION }}.. --tag {{ .RELEASE_VERSION }} > release/CHANGELOG.md
+
+  release:prepare:
+    desc: "Подготовка к релизу"
+    cmds:
+      - task: release:changelog
+      - go mod tidy
+#      - sed -i '' 's/ServerVersion.*=.*/ServerVersion = "{{ .RELEASE_VERSION }}"/' internal/version/version.go
+#      - sed -i '' 's/APIVersion.*=.*/APIVersion = "{{ .PERXIS_GO_VERSION }}"/' internal/version/version.go
+
+  release:finalize:
+    desc: "Формирует все необходимые файлы к релизу"
+    vars:
+      CURRENT_VERSION:
+        sh: svu current
+      RELEASE_VERSION:
+        sh: svu next
+      MAJOR_VERSION:
+        sh: VERSION="{{ .RELEASE_VERSION }}"; echo "${VERSION%.*}"
+    cmds:
+      - cp CHANGELOG.md CHANGELOG.md.bak
+      - sed -i '' '/^# Changelog/d' CHANGELOG.md
+      - cat release/CHANGELOG.md CHANGELOG.md > CHANGELOG.md.tmp
+      - mv CHANGELOG.md.tmp CHANGELOG.md
+
+
+  release:version:
+    aliases: [v, ver]
+    desc: Текущие версии релизов
+    silent: true
+    vars:
+      CURRENT_VERSION:
+        sh: svu current
+      RELEASE_VERSION:
+        sh: svu next
+    cmds:
+      - echo 'Current version {{.CURRENT_VERSION}}'
+      - echo 'Release version {{.RELEASE_VERSION}}'
+
+  release:build:
+    desc: Сборка Release
+    summary: |
+      1. Сделать подготовку:
+        - task release:prepare
+      2. Закоммитить все изменения
+      3. Пометить тэгом версию
+        - пререлиз - `git tag "$(svu pr --pre-release alpha.1 --build 9)"`
+        - релиз - `git tag "$(svu next)"`
+      4. Запушить код и тэги на сервер (иначе будет непонятная ошибка goreleaser Not found)
+    vars:
+      CURRENT_VERSION:
+        sh: svu current
+      RELEASE_VERSION:
+        sh: svu next
+    cmds:
       - goreleaser release --clean --release-notes=release/CHANGELOG.md
 
-  mocks:
-    deps:
-      - mocks.proto
-  mocks.proto:
+  gen:proto:
+    desc: "Компилиция .proto файлов в каталоге {{ .PROTODIR }} в код Go"
     sources:
-      - proto/**/*.proto
-    generates:
-      - proto/mocks/*.go
+      - "{{ .PROTODIR }}/**/*.proto"
+      - exclude: "{{ .PROTODIR }}/status/status.proto"
+    cmds:
+      - for: sources
+        task: gen:proto:file
+        vars:
+          FILE: "{{ .ITEM }}"
+        silent: true
+
+  gen:proto:file:
+    desc: "Преобразует переданный .proto файл в код на языке Go для работы с сообщениями protobuf и сервисами gRPC."
     cmds:
-      - mockery --all --dir proto --output proto/mocks
+      - protoc -I={{ .PROTODIR }} --experimental_allow_proto3_optional --go_out={{ .PBDIR }} --go-grpc_out={{ .PBDIR }} --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative {{ .FILE }}
+
 
+  gen:middleware:
+    desc: "Генерирует middleware для всех пакетов"
+    summary: |
+      Команда перегенерирует middleware для всех пакетов.
 
-  proto:
+      Для конфигурации доступны следующие переменные:
+        * DIR - путь до пакета, содержащего уже сгенерированные middleware
+        * MIDDLEWARE_NAME - имя middleware, которое нужно перегенерировать, без указания расширения
+
+      Примеры использования:
+        Перегенерация всех middleware только для пакета items:
+          task regen:middleware DIR=pkg/items
+
+        Перегенерация всех recovery middleware для всех пакетов:
+          task regen:middleware MIDDLEWARE_NAME=recovering_middleware
+
+        Перегенерация middleware телеметрии для пакета collections:
+          task gen:middleware DIR=pkg/collections MIDDLEWARE_NAME=recovering_middleware
+    vars:
+      DIR: '{{ default "**" .DIR }}'
+      MIDDLEWARE_NAME: '{{ default "*" .MIDDLEWARE_NAME }}'
     sources:
-     - '{{ .PROTODIR }}/**/*.proto'
-#    generates:
-#      - '{{ .PBDIR }}/*.go'
-    ignore_error: true # Игнорировать ошибки, из-за status/status.proto
-#    silent: true
+      - "{{ .DIR }}/middleware/{{ .MIDDLEWARE_NAME }}.go"
     cmds:
       - for: sources
-        cmd: echo {{ .ITEM }}
-#        cmd: '[ "{{.FILE}}" != "perxis-proto/proto/status/status.proto" ]'
-#          - protoc --proto_path={{ .PROTODIR }} --experimental_allow_proto3_optional --go_out={{ .PBDIR }} --go-grpc_out={{ .PBDIR }} --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative {{ .FILE }}
+        cmd: go generate {{ .ITEM }}
 
+  gen:mocks:
+    desc: "Генерирует моки"
+    cmds:
+      - task: gen:mocks:proto
+      - task: gen:mocks:services
 
-  #        cmd: protoc --proto_path={{ .PROTODIR }} --experimental_allow_proto3_optional --go_out={{ .PBDIR }} --go-grpc_out={{ .PBDIR }} --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative {{ .ITEM }}
-#        task: proto_file
-#        vars:
-#          FILE: '{{ .ITEM }}'
-#        ignore_error: true
+  gen:mocks:proto:
+    desc: "Команда генерирует моки для всех proto-файлов"
+    sources:
+      - "{{.PBDIR}}/**/*.pb.go"
+    cmds:
+      - mockery --all --dir {{.PBDIR}} --output {{.PBDIR}}/mocks
+
+
+  gen:mocks:services:
+    desc: "Генерирует моки для всех интерфейсов в директориях, где находится файл service.go."
+    sources:
+      - "**/service.go"
+      - exclude: "**/mocks/**"
+    cmds:
+      - for: sources
+        task: gen:mock:dir
+        vars:
+          DIR: "{{ dir .ITEM }}"
 
+  gen:mock:dir:
+    internal: true
+    desc: "Вспомогательная команда для генерации моков"
+    cmds:
+      - mockery --log-level="error" --all --exported --dir "{{ .DIR }}" --output="{{ .DIR }}/mocks"
 
-  proto_file:
+  gen:microgen:all:
+    desc: "Генерирует go-kit для всех файлов service.go. Поддерживается для версии microgen < 1.0.0"
     sources:
-      - '{{ .FILE }}'
+      - "**/service.go"
+    deps:
+      - for: sources
+        task: gen:microgen:file
+        vars:
+          FILE: "{{ .ITEM }}"
+
+  gen:microgen:file:
+    desc: "Вспомогательная команда для генерации go-kit для переданного файла. Выходные файлы сохраняются в директории с входным файлом."
     cmds:
-      - '[ "{{.FILE}}" != "perxis-proto/proto/status/status.proto" ]' # Игнорировать ошибки, из-за status/status.proto
-      - protoc --proto_path={{ .PROTODIR }} --experimental_allow_proto3_optional --go_out={{ .PBDIR }} --go-grpc_out={{ .PBDIR }} --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative {{ .FILE }}
-    silent: true
\ No newline at end of file
+      - microgen -file {{ .FILE }} -out {{ dir .FILE  }}
diff --git a/assets/json-schema/perxis-collection-schema.json b/assets/json-schema/perxis-collection-schema.json
new file mode 100644
index 0000000000000000000000000000000000000000..d5874a92f5909a34f8510cc2487c3d856de25b8d
--- /dev/null
+++ b/assets/json-schema/perxis-collection-schema.json
@@ -0,0 +1,1420 @@
+{
+  "$schema": "https://json-schema.org/draft-07/schema",
+  "title": "Perxis Collection Schema",
+  "$defs": {
+    "view": {
+      "type": "object",
+      "properties": {
+        "widget": {
+          "description": "Виджет для отображения поля в списке",
+          "type": "string"
+        },
+        "options": {
+          "description": "Опции виджета, на усмотрения виджета",
+          "type": "object"
+        }
+      }
+    },
+    "translation": {
+      "type": "object",
+      "properties": {
+        "locale": {
+          "type": "string"
+        },
+        "title": {
+          "type": "string"
+        },
+        "description": {
+          "type": "string"
+        }
+      },
+      "required": [
+        "locale"
+      ]
+    },
+    "include": {
+      "type": "object",
+      "properties": {
+        "ref": {
+          "description": "Идентификатор коллекции подключаемой схемы",
+          "type": "string"
+        },
+        "optional": {
+          "description": "Параметр определяющий обязательность подключение схемы",
+          "type": "boolean"
+        }
+      }
+    },
+    "field": {
+      "type": "object",
+      "properties": {
+        "type": {
+          "description": "Тип поля. Доступные значения: bool, array, file, location, number, object, reference, string, time, timestamp",
+          "type": "string",
+          "enum": [
+            "bool",
+            "array",
+            "file",
+            "location",
+            "number",
+            "object",
+            "reference",
+            "string",
+            "time",
+            "timestamp"
+          ]
+        },
+        "title": {
+          "description": "Заголовок поля",
+          "type": "string"
+        },
+        "description": {
+          "description": "Описание поля",
+          "type": "string"
+        },
+        "translations": {
+          "description": "Локализация заголовка и описания поля",
+          "type": "array",
+          "items": {
+            "$ref": "#/$defs/translation"
+          }
+        },
+        "options": {
+          "description": "Может содержать правила валидации или модификации данных для поля",
+          "type": "object",
+          "properties": {
+            "readonly": {
+              "description": "Только для чтения",
+              "type": "boolean"
+            },
+            "required": {
+              "description": "Обязательно для заполнения. Не учитывается для переводов",
+              "type": "boolean"
+            },
+            "value": {
+              "description": "Формула значения (опционально). В случае если формула указана, то при сохранении значение из данных будет заменено на результат вычисления формулы",
+              "type": "string"
+            }
+          }
+        },
+        "ui": {
+          "description": "Описывает отображение объекта в интерфейсе",
+          "type": "object",
+          "properties": {
+            "widget": {
+              "description": "Виджет для отображения поля",
+              "type": "string"
+            },
+            "placeholder": {
+              "description": "Местозаполнитель для полей",
+              "type": "string"
+            },
+            "options": {
+              "description": "Опции виджета, на усмотрения виджета",
+              "type": "object",
+              "properties": {
+                "title": {
+                  "description": "Поле используемое в качестве заголовка при отображении",
+                  "type": "string"
+                },
+                "key": {
+                  "description": "Поле используемое в качестве ключевого значения",
+                  "type": "string"
+                },
+                "subtitle": {
+                  "description": "Поле используемое в качестве подзаголовков при отображении",
+                  "type": "string"
+                },
+                "description": {
+                  "description": "Поле используемое в качестве описания при отображении",
+                  "type": "string"
+                },
+                "icon": {
+                  "description": "Поле используемое в качестве имени иконки (из библиотеки приложения) при отображении",
+                  "type": "string"
+                },
+                "images": {
+                  "description": "Поля используемые в качестве изображений. Поддерживаются поля типа file и reference. В случае file файл должен должен быть изображением. В случае reference, в схеме коллекции на элемент которой ссылается reference должно быть указано поле ui.options.images которое в свою очередь так же может указывать на поля типа file и reference и.т.д",
+                  "type": "array",
+                  "items": {
+                    "type": "string"
+                  }
+                },
+                "refs": {
+                  "description": "Определяет какие поля (Reference/[]Reference) используются для отображения связанных записей, а так же их порядок",
+                  "type": "array",
+                  "items": {
+                    "type": "object",
+                    "properties": {
+                      "field": {
+                        "description": "Имя поля для отображения",
+                        "type": "string"
+                      },
+                      "expand": {
+                        "description": "Раздел поля раскрыт (по умолчанию отображается свернутым)",
+                        "type": "boolean"
+                      }
+                    }
+                  }
+                },
+                "fields": {
+                  "description": "Порядок следования полей по умолчанию. Параметр указывает только порядок следования",
+                  "type": "array",
+                  "items": {
+                    "type": "string"
+                  }
+                },
+                "color": {
+                  "description": "Поле используемое в качестве цвета фона при отображении записи в таблице и в виджете Block/BlockList. В качестве значения поля используемого для указания цвета может быть: Название цвета antd: magenta, red, volcano, orange, gold, lime, green, cyan, blue, geekblue, purple. Название статуса antd: success, processing, error, warning, default. Любое значение цвета, которое поддерживается библиотекой TinyColor: hex: #ff0000 hex8: #ff0000ff rgb: rgb(255, 0, 0) hsl: hsl(0, 100%, 50%) hsv: hsv(0, 100%, 100%)",
+                  "type": "string"
+                },
+                "collection_icon": {
+                  "description": "Название иконки для отображения коллекции в меню или в списке коллекций",
+                  "type": "string"
+                },
+                "fieldProps": {
+                  "description": "Параметры отображения поля в grid сетке"
+                }
+              }
+            },
+            "read_view": {
+              "description": "Настройки для отображения экрана в режиме просмотра элемента",
+              "$ref": "#/$defs/view"
+            },
+            "edit_view": {
+              "description": "Настройки для отображения экрана в режиме редактирования элемента",
+              "$ref": "#/$defs/view"
+            },
+            "list_view": {
+              "description": "Настройки для отображения экрана в режиме списке элементов",
+              "allOf": [
+                {
+                  "$ref": "#/$defs/view"
+                },
+                {
+                  "properties": {
+                    "options": {
+                      "properties": {
+                        "fields": {
+                          "description": "Список отображаемых полей и порядок их отображения в списке по умолчанию (пользователь может изменить). Если не задан, то используется основной параметр fields",
+                          "type": "array",
+                          "items": {
+                            "type": "string"
+                          }
+                        },
+                        "sort": {
+                          "description": "Настройка сортировки списка по умолчанию",
+                          "type": "array",
+                          "items": {
+                            "type": "string"
+                          }
+                        },
+                        "page_size": {
+                          "description": "Настройка размера страниц по умолчанию",
+                          "type": "integer"
+                        }
+                      }
+                    }
+                  }
+                }
+              ]
+            }
+          },
+          "allOf": [
+            {
+              "if": {
+                "properties": {
+                  "widget": {
+                    "const": "LogViewer"
+                  }
+                }
+              },
+              "then": {
+                "properties": {
+                  "options": {
+                    "type": "object",
+                    "properties": {
+                      "maxHeight": {
+                        "description": "Высота поля, число отображаемых строк",
+                        "type": "integer"
+                      }
+                    }
+                  }
+                }
+              }
+            },
+            {
+              "if": {
+                "properties": {
+                  "widget": {
+                    "const": "RTE"
+                  }
+                }
+              },
+              "then": {
+                "properties": {
+                  "options": {
+                    "type": "object",
+                    "properties": {
+                      "mediaCollections": {
+                        "description": "Список коллекций доступных при вставке изображения",
+                        "type": "array",
+                        "items": {
+                          "type": "string"
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            },
+            {
+              "if": {
+                "properties": {
+                  "widget": {
+                    "const": "CodeEditor"
+                  }
+                }
+              },
+              "then": {
+                "properties": {
+                  "options": {
+                    "type": "object",
+                    "properties": {
+                      "height": {
+                        "description": "Высота редактора, число отображаемых строк",
+                        "type": "integer"
+                      },
+                      "defaultLanguage": {
+                        "description": "Язык по-умолчанию. Доступны для выбора - html, json, markdown, plaintext, yaml. Если не указан, будет выбран plaintext",
+                        "type": "string",
+                        "enum": [
+                          "html",
+                          "json",
+                          "markdown",
+                          "plaintext",
+                          "yaml"
+                        ]
+                      },
+                      "allowChangeLanguage": {
+                        "description": "Активация возможности переключения языка в самом виджете во время редактирования кода",
+                        "type": "boolean"
+                      }
+                    }
+                  }
+                }
+              }
+            },
+            {
+              "if": {
+                "properties": {
+                  "widget": {
+                    "const": "DateTimePicker"
+                  }
+                }
+              },
+              "then": {
+                "properties": {
+                  "list_view": {
+                    "type": "object",
+                    "properties": {
+                      "options": {
+                        "properties": {
+                          "format": {
+                            "description": "Используется метод format библиотеки dayjs https://day.js.org/docs/en/display/format",
+                            "type": "string"
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            },
+            {
+              "if": {
+                "properties": {
+                  "widget": {
+                    "const": "TimestampPicker"
+                  }
+                }
+              },
+              "then": {
+                "properties": {
+                  "list_view": {
+                    "type": "object",
+                    "properties": {
+                      "options": {
+                        "properties": {
+                          "format": {
+                            "description": "Используется метод format библиотеки dayjs https://day.js.org/docs/en/display/format",
+                            "type": "string"
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            },
+            {
+              "if": {
+                "properties": {
+                  "widget": {
+                    "const": "Select"
+                  }
+                }
+              },
+              "then": {
+                "properties": {
+                  "list_view": {
+                    "type": "object",
+                    "properties": {
+                      "options": {
+                        "properties": {
+                          "enum": {
+                            "description": "",
+                            "type": "array",
+                            "items": {
+                              "type": "object",
+                              "properties": {
+                                "value": {
+                                  "type": [
+                                    "string",
+                                    "integer"
+                                  ]
+                                },
+                                "color": {
+                                  "description": "Цвет тега как в документации https://ant.design/components/tag/",
+                                  "type": "string"
+                                }
+                              }
+                            }
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            },
+            {
+              "if": {
+                "properties": {
+                  "widget": {
+                    "const": "SelectList"
+                  }
+                }
+              },
+              "then": {
+                "properties": {
+                  "list_view": {
+                    "type": "object",
+                    "properties": {
+                      "options": {
+                        "properties": {
+                          "enum": {
+                            "type": "array",
+                            "items": {
+                              "type": "object",
+                              "properties": {
+                                "value": {
+                                  "type": [
+                                    "string",
+                                    "integer"
+                                  ]
+                                },
+                                "color": {
+                                  "description": "Цвет тега как в документации https://ant.design/components/tag/",
+                                  "type": "string"
+                                }
+                              }
+                            }
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            },
+            {
+              "if": {
+                "properties": {
+                  "widget": {
+                    "const": "Radio"
+                  }
+                }
+              },
+              "then": {
+                "properties": {
+                  "options": {
+                    "type": "object",
+                    "properties": {
+                      "option_type": {
+                        "description": "Тип переключателей",
+                        "type": "string",
+                        "enum": [
+                          "button",
+                          "default"
+                        ]
+                      }
+                    },
+                    "allOf": [
+                      {
+                        "if": {
+                          "properties": {
+                            "option_type": {
+                              "const": "default"
+                            }
+                          }
+                        },
+                        "then": {
+                          "properties": {
+                            "direction": {
+                              "description": "Вариант отображения переключателей",
+                              "type": "string",
+                              "enum": [
+                                "horizontal",
+                                "vertical"
+                              ]
+                            }
+                          }
+                        }
+                      }
+                    ]
+                  }
+                }
+              }
+            },
+            {
+              "if": {
+                "properties": {
+                  "widget": {
+                    "const": "SpaceSelect"
+                  }
+                }
+              },
+              "then": {
+                "properties": {
+                  "options": {
+                    "type": "object",
+                    "properties": {
+                      "allowSpacesFromAllOrgs": {
+                        "description": "Выбор пространств из всех доступных организаций",
+                        "type": "boolean"
+                      }
+                    }
+                  }
+                }
+              }
+            },
+            {
+              "if": {
+                "properties": {
+                  "widget": {
+                    "const": "Group"
+                  }
+                }
+              },
+              "then": {
+                "properties": {
+                  "options": {
+                    "type": "object",
+                    "properties": {
+                      "group": {
+                        "description": "Разместить поля по grid сетке",
+                        "type": "boolean"
+                      },
+                      "groupProps": {
+                        "description": "Параметры grid сетки, компонент Row",
+                        "type": "object"
+                      }
+                    }
+                  }
+                }
+              }
+            },
+            {
+              "if": {
+                "anyOf": [
+                  {
+                    "properties": {
+                      "widget": {
+                        "const": "Lookup"
+                      }
+                    }
+                  },
+                  {
+                    "properties": {
+                      "widget": {
+                        "const": "LookupList"
+                      }
+                    }
+                  }
+                ]
+              },
+              "then": {
+                "properties": {
+                  "options": {
+                    "type": "object",
+                    "properties": {
+                      "itemsFilter": {
+                        "description": "Дополнительная фильтрация элементов с возможностью подстановки значений из текущего контекста",
+                        "type": "string"
+                      },
+                      "collectionsFilter": {
+                        "description": "Дополнительная фильтрация коллекций с возможностью подстановки значений из текущего контекста. Указывается массив значений для фильтрации по id",
+                        "type": "array"
+                      },
+                      "allowedCollections": {
+                        "type": "array",
+                        "items": {
+                          "type": "object",
+                          "properties": {
+                            "valueField": {
+                              "description": "Имя поля значения",
+                              "type": "string"
+                            },
+                            "collection": {
+                              "description": "ID коллекции",
+                              "type": "string"
+                            },
+                            "titleField": {
+                              "description": "Имя поля заголовка",
+                              "type": "string"
+                            },
+                            "descriptionField": {
+                              "description": "Имя поля описания",
+                              "type": "string"
+                            },
+                            "imageField": {
+                              "description": "Имя поля изображения",
+                              "type": "string"
+                            }
+                          },
+                          "required": [
+                            "valueField",
+                            "collection"
+                          ]
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            },
+            {
+              "if": {
+                "anyOf": [
+                  {
+                    "properties": {
+                      "widget": {
+                        "const": "Block"
+                      }
+                    }
+                  },
+                  {
+                    "properties": {
+                      "widget": {
+                        "const": "BlockList"
+                      }
+                    }
+                  }
+                ]
+              },
+              "then": {
+                "properties": {
+                  "options": {
+                    "type": "object",
+                    "properties": {
+                      "create": {
+                        "description": "Настройки интерфейса создания новых элементов в виджете",
+                        "type": "object",
+                        "properties": {
+                          "disable": {
+                            "description": "Создание элементов отключено (только выбор существующих)",
+                            "type": "boolean"
+                          },
+                          "classes": {
+                            "description": "Классы действий применимые для создания",
+                            "type": "array",
+                            "items": {
+                              "type": "string"
+                            }
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            },
+            {
+              "if": {
+                "anyOf": [
+                  {
+                    "properties": {
+                      "widget": {
+                        "const": "Reference"
+                      }
+                    }
+                  },
+                  {
+                    "properties": {
+                      "widget": {
+                        "const": "ReferenceList"
+                      }
+                    }
+                  }
+                ]
+              },
+              "then": {
+                "properties": {
+                  "list_view": {
+                    "properties": {
+                      "options": {
+                        "properties": {
+                          "allow_preview": {
+                            "description": "Отображение предпросмотра ссылки как Блока во всплывающем окошке при наведении на тег ссылки в таблице элементов",
+                            "type": "boolean"
+                          }
+                        }
+                      }
+                    }
+                  },
+                  "options": {
+                    "type": "object",
+                    "properties": {
+                      "itemsFilter": {
+                        "description": "Дополнительная фильтрация элементов с возможностью подстановки значений из текущего контекста",
+                        "type": "string"
+                      },
+                      "collectionsFilter": {
+                        "description": "Дополнительная фильтрация коллекций с возможностью подстановки значений из текущего контекста",
+                        "type": "array"
+                      }
+                    }
+                  }
+                }
+              }
+            },
+            {
+              "if": {
+                "properties": {
+                  "widget": {
+                    "const": "Media"
+                  }
+                }
+              },
+              "then": {
+                "properties": {
+                  "list_view": {
+                    "type": "object",
+                    "properties": {
+                      "options": {
+                        "type": "object",
+                        "properties": {
+                          "size": {
+                            "description": "Размер изображения",
+                            "type": "string",
+                            "enum": [
+                              "small",
+                              "middle",
+                              "large"
+                            ]
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            },
+            {
+              "if": {
+                "properties": {
+                  "widget": {
+                    "const": "MediaList"
+                  }
+                }
+              },
+              "then": {
+                "properties": {
+                  "list_view": {
+                    "type": "object",
+                    "properties": {
+                      "options": {
+                        "type": "object",
+                        "properties": {
+                          "images_count": {
+                            "description": "Количество отображаемых изображений",
+                            "type": "integer"
+                          },
+                          "size": {
+                            "description": "Размер изображения",
+                            "type": "string",
+                            "enum": [
+                              "small",
+                              "middle",
+                              "large"
+                            ]
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            },
+            {
+              "if": {
+                "properties": {
+                  "widget": {
+                    "const": "Collection"
+                  }
+                }
+              },
+              "then": {
+                "properties": {
+                  "options": {
+                    "type": "object",
+                    "properties": {
+                      "includeHidden": {
+                        "description": "Показывать скрытые коллекции в списке возможных вариантов",
+                        "type": "boolean"
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          ]
+        },
+        "includes": {
+          "description": "Включает в поле другие схемы",
+          "type": "array",
+          "items": {
+            "$ref": "#/$defs/include"
+          }
+        },
+        "single_locale": {
+          "description": "Флаг, показывающий, что данные в поле не могут быть локализованы",
+          "type": "boolean"
+        },
+        "indexed": {
+          "description": "Флаг, определяющий индексацию данных в этом поле для ускорения фильтрации",
+          "type": "boolean"
+        },
+        "unique": {
+          "description": "Флаг, указывающий, что поле может иметь только уникальное значение среди всех записей в коллекции. При попытке добавить дублирующее значение будет возвращена ошибка и отказ сохранить или обновить запись. Для переводов записи на другие языки проверка уникальности осуществляется отдельно для каждого языка",
+          "type": "boolean"
+        },
+        "text_search": {
+          "description": "Флаг, указывающий, что по данному полю должен осуществляться полнотекстовый поиск. Полнотекстовый поиск выполняется по всем полям с данным флагом и их переводам",
+          "type": "boolean"
+        },
+        "condition": {
+          "description": "Формула, результат вычисление определяет видимость поля и присутствия поля данных. Формула должна возвращать булево значение. Если данный параметр не указан, то поле считается видимым",
+          "type": "string"
+        },
+        "additional_values": {
+          "description": "Позволяет указывать дополнительные пользовательские значения вне ограничений наложенных правилами Enum, Lookup и другими правилами ограничивающими значения поля",
+          "type": "boolean"
+        }
+      },
+      "required": [
+        "type"
+      ],
+      "allOf": [
+        {
+          "if": {
+            "properties": {
+              "type": {
+                "const": "bool"
+              }
+            }
+          },
+          "then": {
+            "properties": {
+              "options": {
+                "type": "object",
+                "properties": {
+                  "enum": {
+                    "description": "Выбор из заданных значений",
+                    "type": "array",
+                    "items": {
+                      "type": "object",
+                      "properties": {
+                        "name": {
+                          "type": "string"
+                        },
+                        "value": {
+                          "type": "boolean"
+                        }
+                      }
+                    }
+                  },
+                  "default": {
+                    "type": "boolean"
+                  }
+                }
+              },
+              "ui": {
+                "properties": {
+                  "widget": {
+                    "enum": [
+                      "Lookup",
+                      "Checkbox",
+                      "Switch"
+                    ]
+                  }
+                }
+              }
+            }
+          }
+        },
+        {
+          "if": {
+            "properties": {
+              "type": {
+                "const": "array"
+              }
+            }
+          },
+          "then": {
+            "properties": {
+              "params": {
+                "type": "object",
+                "properties": {
+                  "item": {
+                    "description": "Описание типа поля элементов",
+                    "$ref": "#/$defs/field"
+                  }
+                },
+                "required": [
+                  "item"
+                ]
+              },
+              "options": {
+                "type": "object",
+                "properties": {
+                  "maxItems": {
+                    "description": "Максимальное количество элементов в поле",
+                    "type": "integer"
+                  }
+                }
+              },
+              "ui": {
+                "properties": {
+                  "widget": {
+                    "enum": [
+                      "Lookup",
+                      "SelectList",
+                      "SpaceSelect",
+                      "LocaleSelect",
+                      "List",
+                      "Tags",
+                      "LookupList",
+                      "BlockList",
+                      "ReferenceList",
+                      "MediaList",
+                      "Collection"
+                    ]
+                  }
+                }
+              }
+            },
+            "required": [
+              "params"
+            ]
+          }
+        },
+        {
+          "if": {
+            "properties": {
+              "type": {
+                "const": "file"
+              }
+            }
+          },
+          "then": {
+            "properties": {
+              "options": {
+                "type": "object"
+              },
+              "ui": {
+                "properties": {
+                  "widget": {
+                    "enum": [
+                      "Lookup",
+                      "File"
+                    ]
+                  }
+                }
+              }
+            }
+          }
+        },
+        {
+          "if": {
+            "properties": {
+              "type": {
+                "const": "location"
+              }
+            }
+          },
+          "then": {
+            "properties": {
+              "ui": {
+                "properties": {
+                  "widget": {
+                    "enum": [
+                      "Lookup"
+                    ]
+                  },
+                  "options": {
+                    "type": "object"
+                  }
+                }
+              }
+            }
+          }
+        },
+        {
+          "if": {
+            "properties": {
+              "type": {
+                "const": "number"
+              }
+            }
+          },
+          "then": {
+            "properties": {
+              "params": {
+                "type": "object",
+                "properties": {
+                  "format": {
+                    "description": "Конкретный числовой тип данных",
+                    "type": "string",
+                    "enum": [
+                      "int",
+                      "float"
+                    ]
+                  }
+                },
+                "required": [
+                  "format"
+                ]
+              },
+              "options": {
+                "type": "object",
+                "properties": {
+                  "max": {
+                    "description": "Максимальное значение",
+                    "type": "integer"
+                  },
+                  "min": {
+                    "description": "Минимальное значение",
+                    "type": "integer"
+                  },
+                  "multipleOf": {
+                    "description": "Кратность",
+                    "type": "integer"
+                  },
+                  "enum": {
+                    "description": "Выбор из заданных значений",
+                    "type": "array",
+                    "items": {
+                      "type": "object",
+                      "properties": {
+                        "name": {
+                          "type": "string"
+                        },
+                        "value": {
+                          "type": "integer"
+                        }
+                      }
+                    }
+                  },
+                  "default": {
+                    "description": "Значение по умолчанию",
+                    "type": "integer"
+                  }
+                }
+              },
+              "ui": {
+                "properties": {
+                  "widget": {
+                    "enum": [
+                      "Lookup",
+                      "NumberInput",
+                      "Select",
+                      "SelectList",
+                      "Radio"
+                    ]
+                  }
+                }
+              }
+            },
+            "required": [
+              "params"
+            ]
+          }
+        },
+        {
+          "if": {
+            "properties": {
+              "type": {
+                "const": "object"
+              }
+            }
+          },
+          "then": {
+            "properties": {
+              "options": {
+                "type": "object",
+                "properties": {
+                  "default": {
+                    "description": "Значение по умолчанию",
+                    "type": "object"
+                  }
+                }
+              },
+              "params": {
+                "type": "object",
+                "properties": {
+                  "inline": {
+                    "description": "флаг, указывающий на то что объект является “встроенным” в родительский объект",
+                    "type": "boolean"
+                  },
+                  "fields": {
+                    "description": "Список полей объекта с описанием",
+                    "type": "object",
+                    "patternProperties": {
+                      "^[a-zA-Z0-9._-]+$": {
+                        "$ref": "#/$defs/field"
+                      }
+                    }
+                  }
+                }
+              },
+              "ui": {
+                "properties": {
+                  "widget": {
+                    "enum": [
+                      "Lookup",
+                      "Group",
+                      "Tabs",
+                      "Accordion"
+                    ]
+                  }
+                }
+              }
+            }
+          }
+        },
+        {
+          "if": {
+            "properties": {
+              "type": {
+                "const": "reference"
+              }
+            }
+          },
+          "then": {
+            "properties": {
+              "params": {
+                "type": "object",
+                "properties": {
+                  "allowedCollections": {
+                    "description": "Список коллекций, ссылки на элементы которых могут быть использованы в поле. Поддерживаются glob выражения. Необязательно для заполнения - в случае, если поле не заполнено, разрешен поиск по всем коллекциям",
+                    "type": "array",
+                    "items": {
+                      "type": "string"
+                    },
+                    "uniqueItems": true
+                  }
+                }
+              },
+              "options": {
+                "type": "object",
+                "properties": {
+                  "minItems": {
+                    "description": "Минимальное количество связей в поле",
+                    "type": "integer"
+                  },
+                  "maxItems": {
+                    "description": "Максимальное количество связей в поле",
+                    "type": "integer"
+                  },
+                  "enum": {
+                    "description": "Выбор из заданных значений",
+                    "type": "array",
+                    "items": {
+                      "type": "object",
+                      "properties": {
+                        "name": {
+                          "type": "string"
+                        },
+                        "value": {
+                          "type": "object"
+                        }
+                      }
+                    }
+                  }
+                }
+              },
+              "ui": {
+                "properties": {
+                  "widget": {
+                    "enum": [
+                      "Lookup",
+                      "Block",
+                      "Reference",
+                      "Media"
+                    ]
+                  }
+                }
+              }
+            }
+          }
+        },
+        {
+          "if": {
+            "properties": {
+              "type": {
+                "const": "string"
+              }
+            }
+          },
+          "then": {
+            "properties": {
+              "options": {
+                "properties": {
+                  "maxLength": {
+                    "description": "Максимальное количество символов в тексте",
+                    "type": "integer"
+                  },
+                  "minLength": {
+                    "description": "Минимальное количество символов в тексте",
+                    "type": "integer"
+                  },
+                  "enum": {
+                    "description": "Выбор из заданных значений",
+                    "type": "array",
+                    "items": {
+                      "type": "object",
+                      "properties": {
+                        "name": {
+                          "type": "string"
+                        },
+                        "value": {
+                          "type": "string"
+                        }
+                      }
+                    }
+                  },
+                  "default": {
+                    "description": "Значение по умолчанию",
+                    "type": "string"
+                  },
+                  "trimSpace": {
+                    "description": "Убрать лишние пробелы в начале и конце строки",
+                    "type": "boolean"
+                  }
+                }
+              },
+              "ui": {
+                "properties": {
+                  "widget": {
+                    "enum": [
+                      "Lookup",
+                      "StringInput",
+                      "Textarea",
+                      "LogViewer",
+                      "RTE",
+                      "CodeEditor",
+                      "SchemaEditor",
+                      "Timezone",
+                      "Select",
+                      "Radio",
+                      "Password",
+                      "Icon",
+                      "SpaceSelect",
+                      "LocaleSelect",
+                      "Collection"
+                    ]
+                  }
+                }
+              }
+            }
+          }
+        },
+        {
+          "if": {
+            "properties": {
+              "type": {
+                "const": "time"
+              }
+            }
+          },
+          "then": {
+            "properties": {
+              "params": {
+                "type": "object",
+                "properties": {
+                  "layout": {
+                    "description": "Формат времени. Необязательно к заполнению. По умолчанию предполагается формат времени, описанный RFC3339. Можно указать другой формат. Для описания необходимо использовать конкретную дату Mon Jan 2 15:04:05 MST 2006 (Unix 1136239445)",
+                    "type": "string"
+                  }
+                }
+              },
+              "options": {
+                "properties": {
+                  "default": {
+                    "description": "Значение по умолчанию",
+                    "type": "string"
+                  }
+                }
+              },
+              "ui": {
+                "properties": {
+                  "widget": {
+                    "enum": [
+                      "Lookup",
+                      "DateTimePicker"
+                    ]
+                  }
+                }
+              }
+            }
+          }
+        },
+        {
+          "if": {
+            "properties": {
+              "type": {
+                "const": "timestamp"
+              }
+            }
+          },
+          "then": {
+            "properties": {
+              "options": {
+                "properties": {
+                  "default": {
+                    "description": "Значение по умолчанию",
+                    "type": "integer"
+                  }
+                }
+              }
+            },
+            "ui": {
+              "properties": {
+                "widget": {
+                  "enum": [
+                    "Lookup",
+                    "TimestampPicker"
+                  ]
+                }
+              }
+            }
+          }
+        }
+      ]
+    }
+  },
+  "anyOf": [
+    {
+      "$ref": "#/$defs/field",
+      "properties": {
+        "metadata": {
+          "type": [
+            "object",
+            "null"
+          ],
+          "properties": {
+            "collection_id": {
+              "type": "string"
+            },
+            "collection_name": {
+              "type": "string"
+            },
+            "collection_hidden": {
+              "type": "string"
+            }
+          }
+        }
+      }
+    },
+    {
+      "type": "object",
+      "properties": {
+        "id": {
+          "type": "string"
+        },
+        "name": {
+          "type": "string"
+        },
+        "schema": {
+          "type": "object",
+          "allOf": [
+            {
+              "$ref": "#/$defs/field"
+            }
+          ],
+          "properties": {
+            "loaded": {
+              "type": "boolean"
+            },
+            "metadata": {
+              "type": [
+                "object",
+                "null"
+              ]
+            }
+          }
+        },
+        "no_data": {
+          "description": "Коллекция не содержит данных",
+          "type": "boolean"
+        },
+        "single": {
+          "description": "Коллекция может содержать ровно одну запись",
+          "type": "boolean"
+        },
+        "hidden": {
+          "description": "Скрыть коллекцию в интерфейсе от пользователя",
+          "type": "boolean"
+        },
+        "no_archive": {
+          "description": "Коллекция без архива",
+          "type": "boolean"
+        },
+        "no_publish": {
+          "description": "Коллекция без публикации",
+          "type": "boolean"
+        },
+        "no_revisions": {
+          "description": "Коллекция без истории изменений (ревизии)",
+          "type": "boolean"
+        },
+        "max_revisions": {
+          "description": "Старые ревизии сверх указанного количества будут автоматически удаляться. 0, пусто - без ограничений",
+          "type": "integer"
+        },
+        "revision_ttl": {
+          "description": "Ревизии старше указанного времени хранения будут автоматически удалятся. 0, пусто - без ограничений",
+          "type": "integer"
+        }
+      },
+      "required": [
+        "id",
+        "name",
+        "schema"
+      ],
+      "additionalProperties": false
+    }
+  ]
+}
\ No newline at end of file
diff --git a/assets/templates/middleware/middleware.tmpl b/assets/templates/middleware/middleware.tmpl
index 7a34d393cbe71648913dd708d49118da36da1105..c8eee1489a5a968c260e91d8f294b3136e07a7d9 100755
--- a/assets/templates/middleware/middleware.tmpl
+++ b/assets/templates/middleware/middleware.tmpl
@@ -14,7 +14,7 @@ func WithLog(s {{.Interface.Type}}, logger *zap.Logger, log_access bool) {{.Inte
 	if log_access {
 		s = AccessLoggingMiddleware(logger)(s)
 	}
-	{{- if (has $serviceName (list "Items" "Collections") ) }}
+	{{- if (has $serviceName (list "Items" "Collections" "Spaces" "Roles") ) }}
 		s = LoggingMiddleware(logger)(s)
 	{{ else }}
 		s = ErrorLoggingMiddleware(logger)(s)
diff --git a/cliff.toml b/cliff.toml
index 78b82d95b808fd8b3a85e9013870059b8bb46b13..572bb688ee934586e605d376b6c3bcfddb9ccb94 100644
--- a/cliff.toml
+++ b/cliff.toml
@@ -12,7 +12,6 @@ breaking_always_bump_major = true
 # changelog header
 header = """
 # Changelog\n
-All notable changes to this project will be documented in this file.\n
 """
 # template for the changelog body
 # https://keats.github.io/tera/docs/#introduction
@@ -25,16 +24,16 @@ body = """
 {% for group, commits in commits | group_by(attribute="group") %}
     ### {{ group | striptags | trim | upper_first }}
     {% for commit in commits %}
-        - {% if commit.scope %}*({{ commit.scope }})* {% endif %}\
+        - {% if commit.scope %}**{{ commit.scope }}**: {% endif %}\
             {% if commit.breaking %}[**breaking**] {% endif %}\
             {{ commit.message | upper_first }} \
         {% if commit.links %}\
-       ({% for link in commit.links %}\
-          [{{ link.text }}]({{ link.href }})\
+       {% for link in commit.links %}\
+          [{{ link.text }}]({{ link.href }}) \
           {% if not loop.last %}, {% endif %}\
-        {% endfor %})\
+        {% endfor %}\
         {% endif %}\
-        -([{{ commit.id | truncate(length=7, end="") }}]($REPO/-/commit/{{ commit.id }}))\
+        ([{{ commit.id | truncate(length=7, end="") }}]($REPO/-/commit/{{ commit.id }}))\
     {% endfor %}
 {% endfor %}\n
 """
@@ -69,20 +68,20 @@ commit_preprocessors = [
 ]
 # regex for parsing and grouping commits
 commit_parsers = [
-    { message = "^feat", group = "<!-- 0 -->🚀 Features" },
-    { message = "^fix", group = "<!-- 1 -->🐛 Bug Fixes" },
-    { message = "^doc", group = "<!-- 3 -->📚 Documentation" },
-    { message = "^perf", group = "<!-- 4 -->âš¡ Performance" },
-    { message = "^refactor", group = "<!-- 2 -->🚜 Refactor", skip = true },
+    { message = "^feat", group = "<!-- 0 -->🚀 Новые возможности" },
+    { message = "^fix", group = "<!-- 1 -->🐛 Исправлены ошибки" },
+    { message = "^doc", group = "<!-- 3 -->📚 Документация" },
+    { message = "^perf", group = "<!-- 4 -->⚡ Производительность" },
+    { message = "^refactor", group = "<!-- 2 -->🚜 Рефакторинг", skip = true },
     { message = "^style", group = "<!-- 5 -->🎨 Styling" },
-    { message = "^test", group = "<!-- 6 -->🧪 Testing" },
+    { message = "^test", group = "<!-- 6 -->🧪 Тесты" },
     { message = "^chore\\(release\\): prepare for", skip = true },
     { message = "^chore\\(deps.*\\)", skip = true },
     { message = "^chore\\(pr\\)", skip = true },
     { message = "^chore\\(pull\\)", skip = true },
-    { message = "^chore|^ci", group = "<!-- 7 -->⚙️ Miscellaneous Tasks" },
-    { body = ".*security", group = "<!-- 8 -->🛡️ Security" },
-    { message = "^revert", group = "<!-- 9 -->◀️ Revert" },
+    { message = "^chore|^ci", group = "<!-- 7 -->⚙️ Прочие задачи" },
+    { body = ".*security", group = "<!-- 8 -->🛡️ Безопастность" },
+    { message = "^revert", group = "<!-- 9 -->◀️ Отменены изменения" },
     { message = "^irefac", skip = true },
 ]
 # protect breaking changes from being skipped due to matching a skipping commit_parser
@@ -102,6 +101,12 @@ sort_commits = "oldest"
 # limit the number of commits included in the changelog.
 # limit_commits = 42
 link_parsers = [
+    { pattern = "#(\\d+)", href = "https://git.perx.ru/perxis/perxis/-/issues/$1"},
     { pattern = "#(PRXS-(\\d+))", href = "https://tracker.yandex.ru/$1"},
     { pattern = "RFC(\\d+)", text = "ietf-rfc$1", href = "https://datatracker.ietf.org/doc/html/rfc$1"},
-]
\ No newline at end of file
+]
+
+[remote.gitlab]
+owner = "perxis"
+repo = "perxis-go"
+api_url = "https://git.perx.ru/api/v4/"
\ No newline at end of file
diff --git a/id/mocks/Descriptor.go b/id/mocks/Descriptor.go
new file mode 100644
index 0000000000000000000000000000000000000000..10a6b090f5bf4ccaae00e215f17fa76d9b5f4cab
--- /dev/null
+++ b/id/mocks/Descriptor.go
@@ -0,0 +1,157 @@
+// Code generated by mockery v2.50.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	id "git.perx.ru/perxis/perxis-go/id"
+	mock "github.com/stretchr/testify/mock"
+)
+
+// Descriptor is an autogenerated mock type for the Descriptor type
+type Descriptor struct {
+	mock.Mock
+}
+
+// FromMap provides a mock function with given fields: _a0
+func (_m *Descriptor) FromMap(_a0 map[string]interface{}) error {
+	ret := _m.Called(_a0)
+
+	if len(ret) == 0 {
+		panic("no return value specified for FromMap")
+	}
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(map[string]interface{}) error); ok {
+		r0 = rf(_a0)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// FromParts provides a mock function with given fields: _a0
+func (_m *Descriptor) FromParts(_a0 []string) error {
+	ret := _m.Called(_a0)
+
+	if len(ret) == 0 {
+		panic("no return value specified for FromParts")
+	}
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func([]string) error); ok {
+		r0 = rf(_a0)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// Map provides a mock function with no fields
+func (_m *Descriptor) Map() map[string]interface{} {
+	ret := _m.Called()
+
+	if len(ret) == 0 {
+		panic("no return value specified for Map")
+	}
+
+	var r0 map[string]interface{}
+	if rf, ok := ret.Get(0).(func() map[string]interface{}); ok {
+		r0 = rf()
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(map[string]interface{})
+		}
+	}
+
+	return r0
+}
+
+// New provides a mock function with no fields
+func (_m *Descriptor) New() id.Descriptor {
+	ret := _m.Called()
+
+	if len(ret) == 0 {
+		panic("no return value specified for New")
+	}
+
+	var r0 id.Descriptor
+	if rf, ok := ret.Get(0).(func() id.Descriptor); ok {
+		r0 = rf()
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(id.Descriptor)
+		}
+	}
+
+	return r0
+}
+
+// String provides a mock function with no fields
+func (_m *Descriptor) String() string {
+	ret := _m.Called()
+
+	if len(ret) == 0 {
+		panic("no return value specified for String")
+	}
+
+	var r0 string
+	if rf, ok := ret.Get(0).(func() string); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Get(0).(string)
+	}
+
+	return r0
+}
+
+// Type provides a mock function with no fields
+func (_m *Descriptor) Type() string {
+	ret := _m.Called()
+
+	if len(ret) == 0 {
+		panic("no return value specified for Type")
+	}
+
+	var r0 string
+	if rf, ok := ret.Get(0).(func() string); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Get(0).(string)
+	}
+
+	return r0
+}
+
+// Validate provides a mock function with no fields
+func (_m *Descriptor) Validate() error {
+	ret := _m.Called()
+
+	if len(ret) == 0 {
+		panic("no return value specified for Validate")
+	}
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func() error); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// NewDescriptor creates a new instance of Descriptor. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewDescriptor(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *Descriptor {
+	mock := &Descriptor{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/id/mocks/ObjectHandler.go b/id/mocks/ObjectHandler.go
new file mode 100644
index 0000000000000000000000000000000000000000..8e587abffdeae6aac2434ee69c117728d03991c1
--- /dev/null
+++ b/id/mocks/ObjectHandler.go
@@ -0,0 +1,47 @@
+// Code generated by mockery v2.50.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	id "git.perx.ru/perxis/perxis-go/id"
+	mock "github.com/stretchr/testify/mock"
+)
+
+// ObjectHandler is an autogenerated mock type for the ObjectHandler type
+type ObjectHandler struct {
+	mock.Mock
+}
+
+// Execute provides a mock function with given fields: _a0
+func (_m *ObjectHandler) Execute(_a0 interface{}) *id.ObjectId {
+	ret := _m.Called(_a0)
+
+	if len(ret) == 0 {
+		panic("no return value specified for Execute")
+	}
+
+	var r0 *id.ObjectId
+	if rf, ok := ret.Get(0).(func(interface{}) *id.ObjectId); ok {
+		r0 = rf(_a0)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*id.ObjectId)
+		}
+	}
+
+	return r0
+}
+
+// NewObjectHandler creates a new instance of ObjectHandler. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewObjectHandler(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *ObjectHandler {
+	mock := &ObjectHandler{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/id/mocks/ObjectIdentifier.go b/id/mocks/ObjectIdentifier.go
new file mode 100644
index 0000000000000000000000000000000000000000..9a7ba02c4158713dcd13960c45fcc3786d6aa84a
--- /dev/null
+++ b/id/mocks/ObjectIdentifier.go
@@ -0,0 +1,47 @@
+// Code generated by mockery v2.50.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	id "git.perx.ru/perxis/perxis-go/id"
+	mock "github.com/stretchr/testify/mock"
+)
+
+// ObjectIdentifier is an autogenerated mock type for the ObjectIdentifier type
+type ObjectIdentifier struct {
+	mock.Mock
+}
+
+// ObjectId provides a mock function with no fields
+func (_m *ObjectIdentifier) ObjectId() *id.ObjectId {
+	ret := _m.Called()
+
+	if len(ret) == 0 {
+		panic("no return value specified for ObjectId")
+	}
+
+	var r0 *id.ObjectId
+	if rf, ok := ret.Get(0).(func() *id.ObjectId); ok {
+		r0 = rf()
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*id.ObjectId)
+		}
+	}
+
+	return r0
+}
+
+// NewObjectIdentifier creates a new instance of ObjectIdentifier. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewObjectIdentifier(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *ObjectIdentifier {
+	mock := &ObjectIdentifier{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/images/mocks/EncodeFunc.go b/images/mocks/EncodeFunc.go
new file mode 100644
index 0000000000000000000000000000000000000000..2a31b5ffac1e7c983b1913b2218a05621f5ba8ad
--- /dev/null
+++ b/images/mocks/EncodeFunc.go
@@ -0,0 +1,47 @@
+// Code generated by mockery v2.50.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	image "image"
+	io "io"
+
+	mock "github.com/stretchr/testify/mock"
+)
+
+// EncodeFunc is an autogenerated mock type for the EncodeFunc type
+type EncodeFunc struct {
+	mock.Mock
+}
+
+// Execute provides a mock function with given fields: w, img
+func (_m *EncodeFunc) Execute(w io.Writer, img image.Image) error {
+	ret := _m.Called(w, img)
+
+	if len(ret) == 0 {
+		panic("no return value specified for Execute")
+	}
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(io.Writer, image.Image) error); ok {
+		r0 = rf(w, img)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// NewEncodeFunc creates a new instance of EncodeFunc. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewEncodeFunc(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *EncodeFunc {
+	mock := &EncodeFunc{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/items/mocks/spaceGetter.go b/images/mocks/spaceGetter.go
similarity index 60%
rename from pkg/items/mocks/spaceGetter.go
rename to images/mocks/spaceGetter.go
index 0dfa462e8b1af6c8feeee2bed7cd7e4c1317d0b1..b56dbea69d47c51f6a6755dc6a1a1d0bf0dd649a 100644
--- a/pkg/items/mocks/spaceGetter.go
+++ b/images/mocks/spaceGetter.go
@@ -1,16 +1,16 @@
-// Code generated by mockery v2.46.3. DO NOT EDIT.
+// Code generated by mockery v2.50.0. DO NOT EDIT.
 
 package mocks
 
 import mock "github.com/stretchr/testify/mock"
 
-// spaceGetter is an autogenerated mock type for the spaceGetter type
-type spaceGetter struct {
+// SpaceGetter is an autogenerated mock type for the spaceGetter type
+type SpaceGetter struct {
 	mock.Mock
 }
 
-// GetSpaceID provides a mock function with given fields:
-func (_m *spaceGetter) GetSpaceID() string {
+// GetSpaceID provides a mock function with no fields
+func (_m *SpaceGetter) GetSpaceID() string {
 	ret := _m.Called()
 
 	if len(ret) == 0 {
@@ -27,13 +27,13 @@ func (_m *spaceGetter) GetSpaceID() string {
 	return r0
 }
 
-// newSpaceGetter creates a new instance of spaceGetter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// NewSpaceGetter creates a new instance of SpaceGetter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
 // The first argument is typically a *testing.T value.
-func newSpaceGetter(t interface {
+func NewSpaceGetter(t interface {
 	mock.TestingT
 	Cleanup(func())
-}) *spaceGetter {
-	mock := &spaceGetter{}
+}) *SpaceGetter {
+	mock := &SpaceGetter{}
 	mock.Mock.Test(t)
 
 	t.Cleanup(func() { mock.AssertExpectations(t) })
diff --git a/logs/log.go b/logs/log.go
index 60f88d3a21869fef323c489af6e45858b3960124..df27ea0a0d6072a60a5229c039ff1d0c0d8bd554 100644
--- a/logs/log.go
+++ b/logs/log.go
@@ -27,18 +27,17 @@ func (l Level) String() string {
 }
 
 type Entry struct {
-	ID          string       `json:"id" bson:"_id" mapstructure:"id"`
-	Timestamp   time.Time    `json:"timestamp,omitempty" bson:"timestamp,omitempty" mapstructure:"timestamp,omitempty"`
-	Level       Level        `json:"level,omitempty" bson:"level,omitempty" mapstructure:"level,omitempty"`
-	Message     string       `json:"message,omitempty" bson:"message,omitempty" mapstructure:"message,omitempty"`
-	Category    string       `json:"category,omitempty" bson:"category,omitempty" mapstructure:"category,omitempty"`
-	Component   string       `json:"component,omitempty" bson:"component,omitempty" mapstructure:"component,omitempty"`
-	Event       string       `json:"event,omitempty" bson:"event,omitempty" mapstructure:"event,omitempty"`
-	ObjectID    *id.ObjectId `json:"object_id,omitempty" bson:"object_id,omitempty" mapstructure:"object_id,omitempty"`
-	CallerID    *id.ObjectId `json:"caller_id,omitempty" bson:"caller_id,omitempty" mapstructure:"caller_id,omitempty"`
-	Attr        interface{}  `json:"attr,omitempty" bson:"attr,omitempty" mapstructure:"attr,omitempty"`
-	Tags        []string     `json:"tags,omitempty" bson:"tags,omitempty" mapstructure:"tags,omitempty"`
-	SearchScore float64      `json:"searchScore,omitempty" bson:"search_score,omitempty"`
+	ID        string       `json:"id" bson:"_id" mapstructure:"id"`
+	Timestamp time.Time    `json:"timestamp,omitempty" bson:"timestamp,omitempty" mapstructure:"timestamp,omitempty"`
+	Level     Level        `json:"level,omitempty" bson:"level,omitempty" mapstructure:"level,omitempty"`
+	Message   string       `json:"message,omitempty" bson:"message,omitempty" mapstructure:"message,omitempty"`
+	Category  string       `json:"category,omitempty" bson:"category,omitempty" mapstructure:"category,omitempty"`
+	Component string       `json:"component,omitempty" bson:"component,omitempty" mapstructure:"component,omitempty"`
+	Event     string       `json:"event,omitempty" bson:"event,omitempty" mapstructure:"event,omitempty"`
+	ObjectID  *id.ObjectId `json:"object_id,omitempty" bson:"object_id,omitempty" mapstructure:"object_id,omitempty"`
+	CallerID  *id.ObjectId `json:"caller_id,omitempty" bson:"caller_id,omitempty" mapstructure:"caller_id,omitempty"`
+	Attr      interface{}  `json:"attr,omitempty" bson:"attr,omitempty" mapstructure:"attr,omitempty"`
+	Tags      []string     `json:"tags,omitempty" bson:"tags,omitempty" mapstructure:"tags,omitempty"`
 }
 
 //func convertInterfaceToAny(v interface{}) (*any.Any, error) {
@@ -53,16 +52,15 @@ type Entry struct {
 
 func EntryToPB(entry *Entry) *pb.LogEntry {
 	logEntry := &pb.LogEntry{
-		Id:          entry.ID,
-		Timestamp:   timestamppb.New(entry.Timestamp),
-		Level:       pb.LogLevel(entry.Level),
-		Message:     entry.Message,
-		Category:    entry.Category,
-		Component:   entry.Component,
-		Event:       entry.Event,
-		Attr:        nil, //implement
-		Tags:        entry.Tags,
-		SearchScore: entry.SearchScore,
+		Id:        entry.ID,
+		Timestamp: timestamppb.New(entry.Timestamp),
+		Level:     pb.LogLevel(entry.Level), //nolint:gosec //overflow doesn't expected
+		Message:   entry.Message,
+		Category:  entry.Category,
+		Component: entry.Component,
+		Event:     entry.Event,
+		Attr:      nil, // implement
+		Tags:      entry.Tags,
 	}
 	if entry.ObjectID != nil {
 		logEntry.ObjectId = entry.ObjectID.String()
@@ -76,14 +74,13 @@ func EntryToPB(entry *Entry) *pb.LogEntry {
 
 func EntryFromPB(request *pb.LogEntry) *Entry {
 	logEntry := &Entry{
-		ID:          request.Id,
-		Timestamp:   request.Timestamp.AsTime(),
-		Level:       Level(request.Level),
-		Message:     request.Message,
-		Category:    request.Category,
-		Component:   request.Component,
-		Event:       request.Event,
-		SearchScore: request.SearchScore,
+		ID:        request.GetId(),
+		Timestamp: request.GetTimestamp().AsTime(),
+		Level:     Level(request.GetLevel()),
+		Message:   request.GetMessage(),
+		Category:  request.GetCategory(),
+		Component: request.GetComponent(),
+		Event:     request.GetEvent(),
 	}
 
 	if request.ObjectId != "" {
diff --git a/logs/log_test.go b/logs/log_test.go
index 12aa362a1a2ec1b545d458f273ad9b662a579cf2..d95ddd9822a9ae9af70e49a4e441507dc63f08a9 100644
--- a/logs/log_test.go
+++ b/logs/log_test.go
@@ -88,23 +88,21 @@ func TestFindRequest(t *testing.T) {
 func TestFindResult(t *testing.T) {
 	t.Run("From PB", func(t *testing.T) {
 		res := FindResultFromPB(&pb.FindResult{
-			Options: &pb.FindOptions{Limit: 2, Sort: []string{"timestamp"}, Fields: []string{"level"}},
+			Options: &pb.FindOptions{Limit: 2, Sort: []string{"timestamp"}},
 		})
 		assert.True(t, res.Options.After.IsZero())
 		assert.True(t, res.Options.Before.IsZero())
 		assert.Equal(t, 2, res.Options.Limit)
 		assert.Equal(t, []string{"timestamp"}, res.Options.Sort)
-		assert.Equal(t, []string{"level"}, res.Options.Fields)
 	})
 	t.Run("To PB", func(t *testing.T) {
 		res := FindResultToPB(&FindResult{
-			Options: &FindOptions{Limit: 2, Sort: []string{"timestamp"}, Fields: []string{"level"}},
+			Options: &FindOptions{Limit: 2, Sort: []string{"timestamp"}},
 		})
 		assert.False(t, res.Options.After.IsValid())
 		assert.False(t, res.Options.Before.IsValid())
 		assert.Equal(t, int32(2), res.Options.Limit)
 		assert.Equal(t, []string{"timestamp"}, res.Options.Sort)
-		assert.Equal(t, []string{"level"}, res.Options.Fields)
 	})
 	t.Run("From PB: with nil filter and options", func(t *testing.T) {
 		res := FindResultFromPB(&pb.FindResult{Filter: nil, Options: nil})
diff --git a/pkg/items/mocks/Middleware.go b/logs/mocks/Middleware.go
similarity index 74%
rename from pkg/items/mocks/Middleware.go
rename to logs/mocks/Middleware.go
index 92a5017f5d8ad95d6c191a14aa9f824eada51337..1cf8d39f4f9e43642146d5288121a54a8298dd88 100644
--- a/pkg/items/mocks/Middleware.go
+++ b/logs/mocks/Middleware.go
@@ -1,9 +1,9 @@
-// Code generated by mockery v2.46.3. DO NOT EDIT.
+// Code generated by mockery v2.50.0. DO NOT EDIT.
 
 package mocks
 
 import (
-	items "git.perx.ru/perxis/perxis-go/pkg/items"
+	logs "git.perx.ru/perxis/perxis-go/logs"
 
 	mock "github.com/stretchr/testify/mock"
 )
@@ -14,19 +14,19 @@ type Middleware struct {
 }
 
 // Execute provides a mock function with given fields: _a0
-func (_m *Middleware) Execute(_a0 items.Items) items.Items {
+func (_m *Middleware) Execute(_a0 logs.Service) logs.Service {
 	ret := _m.Called(_a0)
 
 	if len(ret) == 0 {
 		panic("no return value specified for Execute")
 	}
 
-	var r0 items.Items
-	if rf, ok := ret.Get(0).(func(items.Items) items.Items); ok {
+	var r0 logs.Service
+	if rf, ok := ret.Get(0).(func(logs.Service) logs.Service); ok {
 		r0 = rf(_a0)
 	} else {
 		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(items.Items)
+			r0 = ret.Get(0).(logs.Service)
 		}
 	}
 
diff --git a/logs/mocks/WriteSyncer.go b/logs/mocks/WriteSyncer.go
new file mode 100644
index 0000000000000000000000000000000000000000..70b9414df0a5b4146f8ddd3081821b5f50415b86
--- /dev/null
+++ b/logs/mocks/WriteSyncer.go
@@ -0,0 +1,63 @@
+// Code generated by mockery v2.50.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	logs "git.perx.ru/perxis/perxis-go/logs"
+	mock "github.com/stretchr/testify/mock"
+)
+
+// WriteSyncer is an autogenerated mock type for the WriteSyncer type
+type WriteSyncer struct {
+	mock.Mock
+}
+
+// Sync provides a mock function with no fields
+func (_m *WriteSyncer) Sync() error {
+	ret := _m.Called()
+
+	if len(ret) == 0 {
+		panic("no return value specified for Sync")
+	}
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func() error); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// Write provides a mock function with given fields: entry
+func (_m *WriteSyncer) Write(entry *logs.Entry) error {
+	ret := _m.Called(entry)
+
+	if len(ret) == 0 {
+		panic("no return value specified for Write")
+	}
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(*logs.Entry) error); ok {
+		r0 = rf(entry)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// NewWriteSyncer creates a new instance of WriteSyncer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewWriteSyncer(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *WriteSyncer {
+	mock := &WriteSyncer{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/logs/mocks/spaceGetter.go b/logs/mocks/spaceGetter.go
new file mode 100644
index 0000000000000000000000000000000000000000..b56dbea69d47c51f6a6755dc6a1a1d0bf0dd649a
--- /dev/null
+++ b/logs/mocks/spaceGetter.go
@@ -0,0 +1,42 @@
+// Code generated by mockery v2.50.0. DO NOT EDIT.
+
+package mocks
+
+import mock "github.com/stretchr/testify/mock"
+
+// SpaceGetter is an autogenerated mock type for the spaceGetter type
+type SpaceGetter struct {
+	mock.Mock
+}
+
+// GetSpaceID provides a mock function with no fields
+func (_m *SpaceGetter) GetSpaceID() string {
+	ret := _m.Called()
+
+	if len(ret) == 0 {
+		panic("no return value specified for GetSpaceID")
+	}
+
+	var r0 string
+	if rf, ok := ret.Get(0).(func() string); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Get(0).(string)
+	}
+
+	return r0
+}
+
+// NewSpaceGetter creates a new instance of SpaceGetter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewSpaceGetter(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *SpaceGetter {
+	mock := &SpaceGetter{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/logs/service.go b/logs/service.go
index f91fbcc1d8e673ccd7a533778273fa8da7ab3039..2775bfce4d873bac71c990fbffe7e35aaf0fd93e 100644
--- a/logs/service.go
+++ b/logs/service.go
@@ -167,10 +167,8 @@ func FindOptionsToPB(opts *FindOptions) *pb.FindOptions {
 	}
 
 	res := &pb.FindOptions{
-		Sort:          opts.Sort,
-		Fields:        opts.Fields,
-		ExcludeFields: opts.ExcludeFields,
-		Limit:         int32(opts.Limit),
+		Sort:  opts.Sort,
+		Limit: int32(opts.Limit), //nolint:gosec //overflow doesn't expected
 	}
 
 	if !opts.After.IsZero() {
@@ -190,10 +188,8 @@ func FindOptionsFromPB(opts *pb.FindOptions) *FindOptions {
 		return nil
 	}
 	res := &FindOptions{
-		Sort:          opts.Sort,
-		Fields:        opts.Fields,
-		ExcludeFields: opts.ExcludeFields,
-		Limit:         int(opts.Limit),
+		Sort:  opts.GetSort(),
+		Limit: int(opts.GetLimit()),
 	}
 
 	if opts.After.IsValid() {
diff --git a/perxis-proto b/perxis-proto
index 28531974cc43f8ce31e7456241f3cb2535f8c179..0627c9f829178bc6de2623a0b6d42964c44de496 160000
--- a/perxis-proto
+++ b/perxis-proto
@@ -1 +1 @@
-Subproject commit 28531974cc43f8ce31e7456241f3cb2535f8c179
+Subproject commit 0627c9f829178bc6de2623a0b6d42964c44de496
diff --git a/pkg/clients/mocks/spaceGetter.go b/pkg/clients/mocks/spaceGetter.go
new file mode 100644
index 0000000000000000000000000000000000000000..b56dbea69d47c51f6a6755dc6a1a1d0bf0dd649a
--- /dev/null
+++ b/pkg/clients/mocks/spaceGetter.go
@@ -0,0 +1,42 @@
+// Code generated by mockery v2.50.0. DO NOT EDIT.
+
+package mocks
+
+import mock "github.com/stretchr/testify/mock"
+
+// SpaceGetter is an autogenerated mock type for the spaceGetter type
+type SpaceGetter struct {
+	mock.Mock
+}
+
+// GetSpaceID provides a mock function with no fields
+func (_m *SpaceGetter) GetSpaceID() string {
+	ret := _m.Called()
+
+	if len(ret) == 0 {
+		panic("no return value specified for GetSpaceID")
+	}
+
+	var r0 string
+	if rf, ok := ret.Get(0).(func() string); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Get(0).(string)
+	}
+
+	return r0
+}
+
+// NewSpaceGetter creates a new instance of SpaceGetter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewSpaceGetter(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *SpaceGetter {
+	mock := &SpaceGetter{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/collaborators/mocks/spaceGetter.go b/pkg/collaborators/mocks/spaceGetter.go
new file mode 100644
index 0000000000000000000000000000000000000000..b56dbea69d47c51f6a6755dc6a1a1d0bf0dd649a
--- /dev/null
+++ b/pkg/collaborators/mocks/spaceGetter.go
@@ -0,0 +1,42 @@
+// Code generated by mockery v2.50.0. DO NOT EDIT.
+
+package mocks
+
+import mock "github.com/stretchr/testify/mock"
+
+// SpaceGetter is an autogenerated mock type for the spaceGetter type
+type SpaceGetter struct {
+	mock.Mock
+}
+
+// GetSpaceID provides a mock function with no fields
+func (_m *SpaceGetter) GetSpaceID() string {
+	ret := _m.Called()
+
+	if len(ret) == 0 {
+		panic("no return value specified for GetSpaceID")
+	}
+
+	var r0 string
+	if rf, ok := ret.Get(0).(func() string); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Get(0).(string)
+	}
+
+	return r0
+}
+
+// NewSpaceGetter creates a new instance of SpaceGetter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewSpaceGetter(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *SpaceGetter {
+	mock := &SpaceGetter{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/delivery/mocks/spaceGetter.go b/pkg/delivery/mocks/spaceGetter.go
new file mode 100644
index 0000000000000000000000000000000000000000..b56dbea69d47c51f6a6755dc6a1a1d0bf0dd649a
--- /dev/null
+++ b/pkg/delivery/mocks/spaceGetter.go
@@ -0,0 +1,42 @@
+// Code generated by mockery v2.50.0. DO NOT EDIT.
+
+package mocks
+
+import mock "github.com/stretchr/testify/mock"
+
+// SpaceGetter is an autogenerated mock type for the spaceGetter type
+type SpaceGetter struct {
+	mock.Mock
+}
+
+// GetSpaceID provides a mock function with no fields
+func (_m *SpaceGetter) GetSpaceID() string {
+	ret := _m.Called()
+
+	if len(ret) == 0 {
+		panic("no return value specified for GetSpaceID")
+	}
+
+	var r0 string
+	if rf, ok := ret.Get(0).(func() string); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Get(0).(string)
+	}
+
+	return r0
+}
+
+// NewSpaceGetter creates a new instance of SpaceGetter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewSpaceGetter(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *SpaceGetter {
+	mock := &SpaceGetter{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/files/field.go b/pkg/files/field.go
index 7386831322a0c67852cd18e570bc3a0c5781da9f..bd237bd622f657861cef5bf608fcf5bf2aba1898 100644
--- a/pkg/files/field.go
+++ b/pkg/files/field.go
@@ -2,7 +2,6 @@ package files
 
 import (
 	"context"
-	"errors"
 	"fmt"
 	"io"
 	"net/url"
@@ -132,17 +131,16 @@ func (t FileType) PreSave(ctx context.Context, fld *field.Field, v interface{},
 		return nil, false, nil
 	}
 	f := v.(*File)
-	if f.ID == "" {
-		return nil, false, errors.New("FileType: file id required")
-	}
-	if !f.Temporary {
-		return f, false, nil
-	}
 
+	// Выполняет проверка и сохранение файла в постоянное хранилище
+	// Если файл уже находится в постоянном хранилище, то ничего не делаем
+	// TODO при реализации SaveFile нужно передавать флаг или ошибку
+	//  - чтобы корректно отдавать флаr changed если файл не перемещался
 	f, err := t.fs.MoveUpload(ctx, &MultipartUpload{File: *f})
 	if err != nil {
 		return nil, false, err
 	}
+
 	return f, true, nil
 }
 
diff --git a/pkg/files/mocks/spaceGetter.go b/pkg/files/mocks/spaceGetter.go
new file mode 100644
index 0000000000000000000000000000000000000000..b56dbea69d47c51f6a6755dc6a1a1d0bf0dd649a
--- /dev/null
+++ b/pkg/files/mocks/spaceGetter.go
@@ -0,0 +1,42 @@
+// Code generated by mockery v2.50.0. DO NOT EDIT.
+
+package mocks
+
+import mock "github.com/stretchr/testify/mock"
+
+// SpaceGetter is an autogenerated mock type for the spaceGetter type
+type SpaceGetter struct {
+	mock.Mock
+}
+
+// GetSpaceID provides a mock function with no fields
+func (_m *SpaceGetter) GetSpaceID() string {
+	ret := _m.Called()
+
+	if len(ret) == 0 {
+		panic("no return value specified for GetSpaceID")
+	}
+
+	var r0 string
+	if rf, ok := ret.Get(0).(func() string); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Get(0).(string)
+	}
+
+	return r0
+}
+
+// NewSpaceGetter creates a new instance of SpaceGetter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewSpaceGetter(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *SpaceGetter {
+	mock := &SpaceGetter{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/invitations/invitation.go b/pkg/invitations/invitation.go
index 86d0db29a4d77b0eb7e7533b706d4a299fbed388..649bc86498764c1b050bef1d8e4ead0d555017d9 100644
--- a/pkg/invitations/invitation.go
+++ b/pkg/invitations/invitation.go
@@ -6,13 +6,15 @@ const InvitationTTL = 7 * 24 * time.Hour
 
 type Invitation struct {
 	ID         string     `bson:"_id"`
-	Email      string     `bson:"email"`
+	Email      string     `bson:"email,omitempty"`
 	OrgID      string     `bson:"orgId"`
 	SpaceID    string     `bson:"spaceId"`
 	OwnerID    string     `bson:"ownerId"` // Invitation owner
 	Role       string     `bson:"role"`
 	CreatedAt  *time.Time `bson:"createdAt"`
 	ValidUntil *time.Time `bson:"validUntil"`
+	Uses       int        `bson:"uses"`
+	MaxUses    int        `bson:"max_uses"`
 }
 
 func (i Invitation) Clone() *Invitation {
@@ -25,6 +27,8 @@ func (i Invitation) Clone() *Invitation {
 		Role:       i.Role,
 		CreatedAt:  i.CreatedAt,
 		ValidUntil: i.ValidUntil,
+		Uses:       i.Uses,
+		MaxUses:    i.MaxUses,
 	}
 }
 
diff --git a/pkg/invitations/mocks/spaceGetter.go b/pkg/invitations/mocks/spaceGetter.go
new file mode 100644
index 0000000000000000000000000000000000000000..b56dbea69d47c51f6a6755dc6a1a1d0bf0dd649a
--- /dev/null
+++ b/pkg/invitations/mocks/spaceGetter.go
@@ -0,0 +1,42 @@
+// Code generated by mockery v2.50.0. DO NOT EDIT.
+
+package mocks
+
+import mock "github.com/stretchr/testify/mock"
+
+// SpaceGetter is an autogenerated mock type for the spaceGetter type
+type SpaceGetter struct {
+	mock.Mock
+}
+
+// GetSpaceID provides a mock function with no fields
+func (_m *SpaceGetter) GetSpaceID() string {
+	ret := _m.Called()
+
+	if len(ret) == 0 {
+		panic("no return value specified for GetSpaceID")
+	}
+
+	var r0 string
+	if rf, ok := ret.Get(0).(func() string); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Get(0).(string)
+	}
+
+	return r0
+}
+
+// NewSpaceGetter creates a new instance of SpaceGetter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewSpaceGetter(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *SpaceGetter {
+	mock := &SpaceGetter{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/invitations/transport/grpc/protobuf_type_converters.microgen.go b/pkg/invitations/transport/grpc/protobuf_type_converters.microgen.go
index 3b8a032fc55b50903d2d321ce62fa071b2a8d9a2..88690f4fb1d0d8940e7619c0a2db7a4cc3860691 100644
--- a/pkg/invitations/transport/grpc/protobuf_type_converters.microgen.go
+++ b/pkg/invitations/transport/grpc/protobuf_type_converters.microgen.go
@@ -38,6 +38,8 @@ func PtrInvitationToProto(invitation *service.Invitation) (*pb.Invitation, error
 		SpaceId: invitation.SpaceID,
 		OwnerId: invitation.OwnerID,
 		Role:    invitation.Role,
+		Uses:    uint32(invitation.Uses),
+		MaxUses: uint32(invitation.MaxUses),
 	}
 	if invitation.CreatedAt != nil && !invitation.CreatedAt.IsZero() {
 		pi.CreatedAt = timestamp.New(*invitation.CreatedAt)
@@ -59,6 +61,8 @@ func ProtoToPtrInvitation(protoInvitation *pb.Invitation) (*service.Invitation,
 		SpaceID: protoInvitation.SpaceId,
 		OwnerID: protoInvitation.OwnerId,
 		Role:    protoInvitation.Role,
+		Uses:    int(protoInvitation.Uses),
+		MaxUses: int(protoInvitation.MaxUses),
 	}
 	if protoInvitation.CreatedAt != nil {
 		t := protoInvitation.CreatedAt.AsTime()
diff --git a/pkg/items/middleware/access_logging_middleware.go b/pkg/items/middleware/access_logging_middleware.go
index a139dfe951ac200d3290903c861b95393008a945..a2659ff0f31280363a5a7a7943816c92d6d5916d 100644
--- a/pkg/items/middleware/access_logging_middleware.go
+++ b/pkg/items/middleware/access_logging_middleware.go
@@ -97,27 +97,28 @@ func (m *accessLoggingMiddleware) Archive(ctx context.Context, item *items.Item,
 	return err
 }
 
-func (m *accessLoggingMiddleware) CheckoutRevision(ctx context.Context, spaceId string, envId string, collId string, id string, revId string) (storedRevId string, err error) {
+func (m *accessLoggingMiddleware) CheckoutRevision(ctx context.Context, spaceID string, envID string, collectionID string, id string, revID string, options ...*items.CheckoutRevisionsOptions) (storedRevID string, err error) {
 	begin := time.Now()
 
 	m.logger.Debug("CheckoutRevision.Request",
 		zap.Reflect("principal", auth.GetPrincipal(ctx)),
-		zap.Reflect("spaceId", spaceId),
-		zap.Reflect("envId", envId),
-		zap.Reflect("collId", collId),
+		zap.Reflect("spaceID", spaceID),
+		zap.Reflect("envID", envID),
+		zap.Reflect("collectionID", collectionID),
 		zap.Reflect("id", id),
-		zap.Reflect("revId", revId),
+		zap.Reflect("revID", revID),
+		zap.Reflect("options", options),
 	)
 
-	storedRevId, err = m.next.CheckoutRevision(ctx, spaceId, envId, collId, id, revId)
+	storedRevID, err = m.next.CheckoutRevision(ctx, spaceID, envID, collectionID, id, revID, options...)
 
 	m.logger.Debug("CheckoutRevision.Response",
 		zap.Duration("time", time.Since(begin)),
-		zap.Reflect("storedRevId", storedRevId),
+		zap.Reflect("storedRevID", storedRevID),
 		zap.Error(err),
 	)
 
-	return storedRevId, err
+	return storedRevID, err
 }
 
 func (m *accessLoggingMiddleware) Create(ctx context.Context, item *items.Item, opts ...*items.CreateOptions) (created *items.Item, err error) {
@@ -254,6 +255,29 @@ func (m *accessLoggingMiddleware) Get(ctx context.Context, spaceId string, envId
 	return item, err
 }
 
+func (m *accessLoggingMiddleware) GetArchived(ctx context.Context, spaceID string, envID string, collectionID string, id string, options ...*items.GetArchivedOptions) (item *items.Item, err error) {
+	begin := time.Now()
+
+	m.logger.Debug("GetArchived.Request",
+		zap.Reflect("principal", auth.GetPrincipal(ctx)),
+		zap.Reflect("spaceID", spaceID),
+		zap.Reflect("envID", envID),
+		zap.Reflect("collectionID", collectionID),
+		zap.Reflect("id", id),
+		zap.Reflect("options", options),
+	)
+
+	item, err = m.next.GetArchived(ctx, spaceID, envID, collectionID, id, options...)
+
+	m.logger.Debug("GetArchived.Response",
+		zap.Duration("time", time.Since(begin)),
+		zap.Reflect("item", item),
+		zap.Error(err),
+	)
+
+	return item, err
+}
+
 func (m *accessLoggingMiddleware) GetPublished(ctx context.Context, spaceId string, envId string, collectionId string, id string, options ...*items.GetPublishedOptions) (item *items.Item, err error) {
 	begin := time.Now()
 
diff --git a/pkg/items/middleware/caching_middleware.go b/pkg/items/middleware/caching_middleware.go
index be9690a8d68292990189758cc8c41f3d69381794..f2d9bce6de7153c99bc9d116a538f59547b915b3 100644
--- a/pkg/items/middleware/caching_middleware.go
+++ b/pkg/items/middleware/caching_middleware.go
@@ -165,8 +165,16 @@ func (m cachingMiddleware) GetPublished(ctx context.Context, spaceId, envId, col
 	return nil, err
 }
 
-func (m cachingMiddleware) CheckoutRevision(ctx context.Context, spaceId string, envId string, collId string, id string, revId string) (storedRevId string, err error) {
-	storedRevId, err = m.Items.CheckoutRevision(ctx, spaceId, envId, collId, id, revId)
+func (m cachingMiddleware) CheckoutRevision(
+	ctx context.Context,
+	spaceId string,
+	envId string,
+	collId string,
+	id string,
+	revId string,
+	options ...*service.CheckoutRevisionsOptions,
+) (storedRevId string, err error) {
+	storedRevId, err = m.Items.CheckoutRevision(ctx, spaceId, envId, collId, id, revId, options...)
 	if err != nil {
 		return "", err
 	}
diff --git a/pkg/items/middleware/client_encode_middleware.go b/pkg/items/middleware/client_encode_middleware.go
index 358df0eef665200bac4b9f75c6272c71a6597e21..324c648ea398efab8295077fd6e49f897cf86f93 100644
--- a/pkg/items/middleware/client_encode_middleware.go
+++ b/pkg/items/middleware/client_encode_middleware.go
@@ -227,6 +227,20 @@ func (m *encodeDecodeMiddleware) ListRevisions(ctx context.Context, spaceId, env
 	return
 }
 
+func (m *encodeDecodeMiddleware) GetArchived(ctx context.Context, spaceID, envID, collectionID,
+	id string, options ...*items.GetArchivedOptions) (*items.Item, error) {
+	item, err := m.next.GetArchived(ctx, spaceID, envID, collectionID, id, options...)
+	if err != nil {
+		return nil, err
+	}
+
+	col, err := m.colls.Get(ctx, spaceID, envID, collectionID)
+	if err != nil {
+		return nil, err
+	}
+	return item.Decode(ctx, col.Schema)
+}
+
 func (m *encodeDecodeMiddleware) FindArchived(ctx context.Context, spaceId, envId, collectionId string, filter *items.Filter, options ...*items.FindArchivedOptions) (items []*items.Item, total int, err error) {
 	items, total, err = m.next.FindArchived(ctx, spaceId, envId, collectionId, filter, options...)
 	if err == nil && total > 0 {
@@ -284,8 +298,16 @@ func (m *encodeDecodeMiddleware) Undelete(ctx context.Context, item *items.Item,
 	return m.next.Undelete(ctx, item, options...)
 }
 
-func (m *encodeDecodeMiddleware) CheckoutRevision(ctx context.Context, spaceId string, envId string, collId string, id string, revId string) (storedRevId string, err error) {
-	return m.next.CheckoutRevision(ctx, spaceId, envId, collId, id, revId)
+func (m *encodeDecodeMiddleware) CheckoutRevision(
+	ctx context.Context,
+	spaceId string,
+	envId string,
+	collId string,
+	id string,
+	revId string,
+	options ...*items.CheckoutRevisionsOptions,
+) (storedRevId string, err error) {
+	return m.next.CheckoutRevision(ctx, spaceId, envId, collId, id, revId, options...)
 }
 
 func (m *encodeDecodeMiddleware) Aggregate(ctx context.Context, spaceId, envId, collectionId string, filter *items.Filter, options ...*items.AggregateOptions) (result map[string]interface{}, err error) {
diff --git a/pkg/items/middleware/logging_middleware.go b/pkg/items/middleware/logging_middleware.go
index 6443d727805addfd9192e2010c3f6c9586a5409e..037eeba3dfb75055992d315c87ed4b11b033ef2c 100644
--- a/pkg/items/middleware/logging_middleware.go
+++ b/pkg/items/middleware/logging_middleware.go
@@ -24,14 +24,22 @@ func LoggingMiddleware(logger *zap.Logger) Middleware {
 	}
 }
 
-func (m *loggingMiddleware) CheckoutRevision(ctx context.Context, spaceId string, envId string, collId string, id string, revId string) (storedRevId string, err error) {
+func (m *loggingMiddleware) CheckoutRevision(
+	ctx context.Context,
+	spaceId string,
+	envId string,
+	collId string,
+	id string,
+	revId string,
+	options ...*items.CheckoutRevisionsOptions,
+) (storedRevId string, err error) {
 	logger := m.logger.With(
 		logzap.Caller(ctx, logzap.WithSpace(spaceId)),
 		logzap.Event(items.EventCheckoutRevision),
 		logzap.Object(pkgId.NewItemId(spaceId, envId, collId, id)),
 	)
 
-	storedRevId, err = m.next.CheckoutRevision(ctx, spaceId, envId, collId, id, revId)
+	storedRevId, err = m.next.CheckoutRevision(ctx, spaceId, envId, collId, id, revId, options...)
 	if err != nil {
 		logger.Error("Failed to checkout revision", zap.Error(err))
 		return
@@ -219,6 +227,22 @@ func (m *loggingMiddleware) GetRevision(ctx context.Context, spaceId string, env
 	return item, err
 }
 
+func (m *loggingMiddleware) GetArchived(ctx context.Context, spaceID string, envID string, collectionID string,
+	id string, options ...*items.GetArchivedOptions) (*items.Item, error) {
+	logger := m.logger.With(
+		logzap.Caller(ctx, logzap.WithSpace(spaceID)),
+		logzap.Object(pkgId.NewItemId(spaceID, envID, collectionID, id)),
+	)
+
+	item, err := m.next.GetArchived(ctx, spaceID, envID, collectionID, id, options...)
+	if err != nil {
+		logger.Error("Failed to get revision", zap.Error(err))
+		return nil, err
+	}
+
+	return item, nil
+}
+
 func (m *loggingMiddleware) Introspect(ctx context.Context, item *items.Item, opts ...*items.IntrospectOptions) (itm *items.Item, sch *schema.Schema, err error) {
 	var spaceID string
 	if item != nil {
diff --git a/pkg/items/middleware/middleware.go b/pkg/items/middleware/middleware.go
index 3de56ead553a815f7ad874ab6065940819daf711..4ef6a1fd2a0e2aec25d759d75d2e40d699ad7e06 100644
--- a/pkg/items/middleware/middleware.go
+++ b/pkg/items/middleware/middleware.go
@@ -7,7 +7,7 @@ package middleware
 //go:generate gowrap gen -p git.perx.ru/perxis/perxis-go/pkg/items -i Items -t ../../../assets/templates/middleware/middleware.tmpl -o middleware.go -l ""
 
 import (
-	items "git.perx.ru/perxis/perxis-go/pkg/items"
+	"git.perx.ru/perxis/perxis-go/pkg/items"
 	"go.uber.org/zap"
 )
 
diff --git a/pkg/items/middleware/recovering_middleware.go b/pkg/items/middleware/recovering_middleware.go
index 787ccf1b5ac4fbd5171f7ecbabd282217df170e3..1583944a0639012adff4d4b8ec479539c6daae89 100644
--- a/pkg/items/middleware/recovering_middleware.go
+++ b/pkg/items/middleware/recovering_middleware.go
@@ -67,7 +67,7 @@ func (m *recoveringMiddleware) Archive(ctx context.Context, item *items.Item, op
 	return m.next.Archive(ctx, item, options...)
 }
 
-func (m *recoveringMiddleware) CheckoutRevision(ctx context.Context, spaceId string, envId string, collId string, id string, revId string) (storedRevId string, err error) {
+func (m *recoveringMiddleware) CheckoutRevision(ctx context.Context, spaceID string, envID string, collectionID string, id string, revID string, options ...*items.CheckoutRevisionsOptions) (storedRevID string, err error) {
 	logger := m.logger
 	defer func() {
 		if r := recover(); r != nil {
@@ -76,7 +76,7 @@ func (m *recoveringMiddleware) CheckoutRevision(ctx context.Context, spaceId str
 		}
 	}()
 
-	return m.next.CheckoutRevision(ctx, spaceId, envId, collId, id, revId)
+	return m.next.CheckoutRevision(ctx, spaceID, envID, collectionID, id, revID, options...)
 }
 
 func (m *recoveringMiddleware) Create(ctx context.Context, item *items.Item, opts ...*items.CreateOptions) (created *items.Item, err error) {
@@ -151,6 +151,18 @@ func (m *recoveringMiddleware) Get(ctx context.Context, spaceId string, envId st
 	return m.next.Get(ctx, spaceId, envId, collectionId, id, options...)
 }
 
+func (m *recoveringMiddleware) GetArchived(ctx context.Context, spaceID string, envID string, collectionID string, id string, options ...*items.GetArchivedOptions) (item *items.Item, 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.GetArchived(ctx, spaceID, envID, collectionID, id, options...)
+}
+
 func (m *recoveringMiddleware) GetPublished(ctx context.Context, spaceId string, envId string, collectionId string, id string, options ...*items.GetPublishedOptions) (item *items.Item, err error) {
 	logger := m.logger
 	defer func() {
diff --git a/pkg/items/middleware/telemetry_middleware.go b/pkg/items/middleware/telemetry_middleware.go
index a932f289d7ae05d0e1337415b2d07d4953e8935f..e9f8e6a99d85e05ec3a219299a5c04f63706d4ca 100644
--- a/pkg/items/middleware/telemetry_middleware.go
+++ b/pkg/items/middleware/telemetry_middleware.go
@@ -208,7 +208,7 @@ func (_d telemetryMiddleware) Archive(ctx context.Context, item *items.Item, opt
 }
 
 // CheckoutRevision implements items.Items
-func (_d telemetryMiddleware) CheckoutRevision(ctx context.Context, spaceId string, envId string, collId string, id string, revId string) (storedRevId string, err error) {
+func (_d telemetryMiddleware) CheckoutRevision(ctx context.Context, spaceID string, envID string, collectionID string, id string, revID string, options ...*items.CheckoutRevisionsOptions) (storedRevID string, err error) {
 	var att = []attribute.KeyValue{
 		attribute.String("service", "Items"),
 		attribute.String("method", "CheckoutRevision"),
@@ -219,12 +219,23 @@ func (_d telemetryMiddleware) CheckoutRevision(ctx context.Context, spaceId stri
 	ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Items.CheckoutRevision")
 	defer _span.End()
 
-	storedRevId, err = _d.Items.CheckoutRevision(ctx, spaceId, envId, collId, id, revId)
+	storedRevID, err = _d.Items.CheckoutRevision(ctx, spaceID, envID, collectionID, id, revID, options...)
 
 	_d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes)
 
 	var spID string
-	spID = spaceId
+	params := []interface{}{ctx, spaceID, envID, collectionID, id, revID, options, storedRevID, err}
+	for _, p := range params {
+		if p == nil {
+			continue
+		}
+		if sg, ok := p.(spaceGetter); ok {
+			spID = sg.GetSpaceID()
+			if spID != "" {
+				break
+			}
+		}
+	}
 	if spID != "" {
 		att = append(att, attribute.String("spaceID", spID))
 	}
@@ -237,13 +248,14 @@ func (_d telemetryMiddleware) CheckoutRevision(ctx context.Context, spaceId stri
 
 	if _d._spanDecorator != nil {
 		_d._spanDecorator(_span, map[string]interface{}{
-			"ctx":     ctx,
-			"spaceId": spaceId,
-			"envId":   envId,
-			"collId":  collId,
-			"id":      id,
-			"revId":   revId}, map[string]interface{}{
-			"storedRevId": storedRevId,
+			"ctx":          ctx,
+			"spaceID":      spaceID,
+			"envID":        envID,
+			"collectionID": collectionID,
+			"id":           id,
+			"revID":        revID,
+			"options":      options}, map[string]interface{}{
+			"storedRevID": storedRevID,
 			"err":         err})
 	} else if err != nil {
 		_d.requestMetrics.FailedTotal.Add(ctx, 1, attributes)
@@ -253,7 +265,7 @@ func (_d telemetryMiddleware) CheckoutRevision(ctx context.Context, spaceId stri
 		_span.SetAttributes(attribute.String("message", err.Error()))
 	}
 
-	return storedRevId, err
+	return storedRevID, err
 }
 
 // Create implements items.Items
@@ -568,6 +580,66 @@ func (_d telemetryMiddleware) Get(ctx context.Context, spaceId string, envId str
 	return item, err
 }
 
+// GetArchived implements items.Items
+func (_d telemetryMiddleware) GetArchived(ctx context.Context, spaceID string, envID string, collectionID string, id string, options ...*items.GetArchivedOptions) (item *items.Item, err error) {
+	var att = []attribute.KeyValue{
+		attribute.String("service", "Items"),
+		attribute.String("method", "GetArchived"),
+	}
+	attributes := otelmetric.WithAttributeSet(attribute.NewSet(att...))
+
+	start := time.Now()
+	ctx, _span := otel.Tracer(_d._instance).Start(ctx, "Items.GetArchived")
+	defer _span.End()
+
+	item, err = _d.Items.GetArchived(ctx, spaceID, envID, collectionID, id, options...)
+
+	_d.requestMetrics.DurationMilliseconds.Record(ctx, time.Since(start).Milliseconds(), attributes)
+
+	var spID string
+	params := []interface{}{ctx, spaceID, envID, collectionID, id, options, item, err}
+	for _, p := range params {
+		if p == nil {
+			continue
+		}
+		if sg, ok := p.(spaceGetter); ok {
+			spID = sg.GetSpaceID()
+			if spID != "" {
+				break
+			}
+		}
+	}
+	if spID != "" {
+		att = append(att, attribute.String("spaceID", spID))
+	}
+	caller, _ := pkgId.NewObjectId(auth.GetPrincipal(ctx))
+	if caller != nil {
+		att = append(att, attribute.String("caller", caller.String()))
+	}
+
+	_d.requestMetrics.Total.Add(ctx, 1, otelmetric.WithAttributeSet(attribute.NewSet(att...)))
+
+	if _d._spanDecorator != nil {
+		_d._spanDecorator(_span, map[string]interface{}{
+			"ctx":          ctx,
+			"spaceID":      spaceID,
+			"envID":        envID,
+			"collectionID": collectionID,
+			"id":           id,
+			"options":      options}, map[string]interface{}{
+			"item": item,
+			"err":  err})
+	} else if err != nil {
+		_d.requestMetrics.FailedTotal.Add(ctx, 1, attributes)
+
+		_span.RecordError(err)
+		_span.SetAttributes(attribute.String("event", "error"))
+		_span.SetAttributes(attribute.String("message", err.Error()))
+	}
+
+	return item, err
+}
+
 // GetPublished implements items.Items
 func (_d telemetryMiddleware) GetPublished(ctx context.Context, spaceId string, envId string, collectionId string, id string, options ...*items.GetPublishedOptions) (item *items.Item, err error) {
 	var att = []attribute.KeyValue{
diff --git a/pkg/items/mocks/Decoder.go b/pkg/items/mocks/Decoder.go
index 1d3208d2b53d64a886e296c9e79fe9f83430db9c..b9ec1b9492e6dac33fa67815a26906af2b6c9e63 100644
--- a/pkg/items/mocks/Decoder.go
+++ b/pkg/items/mocks/Decoder.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.46.3. DO NOT EDIT.
+// Code generated by mockery v2.49.0. DO NOT EDIT.
 
 package mocks
 
@@ -13,7 +13,7 @@ type Decoder struct {
 }
 
 // Decode provides a mock function with given fields: value, item
-func (_m *Decoder) Decode(value any, item *items.Item) error {
+func (_m *Decoder) Decode(value interface{}, item *items.Item) error {
 	ret := _m.Called(value, item)
 
 	if len(ret) == 0 {
@@ -21,7 +21,7 @@ func (_m *Decoder) Decode(value any, item *items.Item) error {
 	}
 
 	var r0 error
-	if rf, ok := ret.Get(0).(func(any, *items.Item) error); ok {
+	if rf, ok := ret.Get(0).(func(interface{}, *items.Item) error); ok {
 		r0 = rf(value, item)
 	} else {
 		r0 = ret.Error(0)
diff --git a/pkg/items/mocks/Encoder.go b/pkg/items/mocks/Encoder.go
index 6af2b841b04bf61b41103821740d954d4d5feb06..1cab133e993a99441dc1c492444d79d65296dd8e 100644
--- a/pkg/items/mocks/Encoder.go
+++ b/pkg/items/mocks/Encoder.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.46.3. DO NOT EDIT.
+// Code generated by mockery v2.49.0. DO NOT EDIT.
 
 package mocks
 
@@ -13,23 +13,23 @@ type Encoder struct {
 }
 
 // Encode provides a mock function with given fields: item
-func (_m *Encoder) Encode(item *items.Item) (any, error) {
+func (_m *Encoder) Encode(item *items.Item) (interface{}, error) {
 	ret := _m.Called(item)
 
 	if len(ret) == 0 {
 		panic("no return value specified for Encode")
 	}
 
-	var r0 any
+	var r0 interface{}
 	var r1 error
-	if rf, ok := ret.Get(0).(func(*items.Item) (any, error)); ok {
+	if rf, ok := ret.Get(0).(func(*items.Item) (interface{}, error)); ok {
 		return rf(item)
 	}
-	if rf, ok := ret.Get(0).(func(*items.Item) any); ok {
+	if rf, ok := ret.Get(0).(func(*items.Item) interface{}); ok {
 		r0 = rf(item)
 	} else {
 		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(any)
+			r0 = ret.Get(0).(interface{})
 		}
 	}
 
diff --git a/pkg/items/mocks/ItemObserver.go b/pkg/items/mocks/ItemObserver.go
index d4af95a2046dbed608ec580c2b3845b12dfc49fe..535ed00dd45ae6ab58b9087fdc05cf6203bc4deb 100644
--- a/pkg/items/mocks/ItemObserver.go
+++ b/pkg/items/mocks/ItemObserver.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.46.3. DO NOT EDIT.
+// Code generated by mockery v2.49.0. DO NOT EDIT.
 
 package mocks
 
diff --git a/pkg/items/mocks/ItemReadObserver.go b/pkg/items/mocks/ItemReadObserver.go
index d999d488300b6489ad893706867324f0c3100c07..8e1fc25aa9433086d4b914d2dcaa9878c6de707d 100644
--- a/pkg/items/mocks/ItemReadObserver.go
+++ b/pkg/items/mocks/ItemReadObserver.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.46.3. DO NOT EDIT.
+// Code generated by mockery v2.49.0. DO NOT EDIT.
 
 package mocks
 
diff --git a/pkg/items/mocks/Items.go b/pkg/items/mocks/Items.go
index aeefe3fd34993a302dfc0b3534fd2e2582eb9b47..4bb7c278b9843db26dbe7b5cf4662dc75f39ffc0 100644
--- a/pkg/items/mocks/Items.go
+++ b/pkg/items/mocks/Items.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.46.3. DO NOT EDIT.
+// Code generated by mockery v2.50.4. DO NOT EDIT.
 
 package mocks
 
@@ -115,9 +115,16 @@ func (_m *Items) Archive(ctx context.Context, item *items.Item, options ...*item
 	return r0
 }
 
-// CheckoutRevision provides a mock function with given fields: ctx, spaceId, envId, collId, id, revId
-func (_m *Items) CheckoutRevision(ctx context.Context, spaceId string, envId string, collId string, id string, revId string) (string, error) {
-	ret := _m.Called(ctx, spaceId, envId, collId, id, revId)
+// CheckoutRevision provides a mock function with given fields: ctx, spaceID, envID, collectionID, id, revID, options
+func (_m *Items) CheckoutRevision(ctx context.Context, spaceID string, envID string, collectionID string, id string, revID string, options ...*items.CheckoutRevisionsOptions) (string, error) {
+	_va := make([]interface{}, len(options))
+	for _i := range options {
+		_va[_i] = options[_i]
+	}
+	var _ca []interface{}
+	_ca = append(_ca, ctx, spaceID, envID, collectionID, id, revID)
+	_ca = append(_ca, _va...)
+	ret := _m.Called(_ca...)
 
 	if len(ret) == 0 {
 		panic("no return value specified for CheckoutRevision")
@@ -125,17 +132,17 @@ func (_m *Items) CheckoutRevision(ctx context.Context, spaceId string, envId str
 
 	var r0 string
 	var r1 error
-	if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string, string) (string, error)); ok {
-		return rf(ctx, spaceId, envId, collId, id, revId)
+	if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string, string, ...*items.CheckoutRevisionsOptions) (string, error)); ok {
+		return rf(ctx, spaceID, envID, collectionID, id, revID, options...)
 	}
-	if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string, string) string); ok {
-		r0 = rf(ctx, spaceId, envId, collId, id, revId)
+	if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string, string, ...*items.CheckoutRevisionsOptions) string); ok {
+		r0 = rf(ctx, spaceID, envID, collectionID, id, revID, options...)
 	} else {
 		r0 = ret.Get(0).(string)
 	}
 
-	if rf, ok := ret.Get(1).(func(context.Context, string, string, string, string, string) error); ok {
-		r1 = rf(ctx, spaceId, envId, collId, id, revId)
+	if rf, ok := ret.Get(1).(func(context.Context, string, string, string, string, string, ...*items.CheckoutRevisionsOptions) error); ok {
+		r1 = rf(ctx, spaceID, envID, collectionID, id, revID, options...)
 	} else {
 		r1 = ret.Error(1)
 	}
@@ -374,6 +381,43 @@ func (_m *Items) Get(ctx context.Context, spaceId string, envId string, collecti
 	return r0, r1
 }
 
+// GetArchived provides a mock function with given fields: ctx, spaceID, envID, collectionID, id, options
+func (_m *Items) GetArchived(ctx context.Context, spaceID string, envID string, collectionID string, id string, options ...*items.GetArchivedOptions) (*items.Item, error) {
+	_va := make([]interface{}, len(options))
+	for _i := range options {
+		_va[_i] = options[_i]
+	}
+	var _ca []interface{}
+	_ca = append(_ca, ctx, spaceID, envID, collectionID, id)
+	_ca = append(_ca, _va...)
+	ret := _m.Called(_ca...)
+
+	if len(ret) == 0 {
+		panic("no return value specified for GetArchived")
+	}
+
+	var r0 *items.Item
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string, ...*items.GetArchivedOptions) (*items.Item, error)); ok {
+		return rf(ctx, spaceID, envID, collectionID, id, options...)
+	}
+	if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string, ...*items.GetArchivedOptions) *items.Item); ok {
+		r0 = rf(ctx, spaceID, envID, collectionID, id, options...)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*items.Item)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(context.Context, string, string, string, string, ...*items.GetArchivedOptions) error); ok {
+		r1 = rf(ctx, spaceID, envID, collectionID, id, options...)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
 // GetPublished provides a mock function with given fields: ctx, spaceId, envId, collectionId, id, options
 func (_m *Items) GetPublished(ctx context.Context, spaceId string, envId string, collectionId string, id string, options ...*items.GetPublishedOptions) (*items.Item, error) {
 	_va := make([]interface{}, len(options))
diff --git a/pkg/items/mocks/PreSaver.go b/pkg/items/mocks/PreSaver.go
index 1f7d00102b25810a6ee79695422198749af85e53..8e5042bceb2f37f13009a227c26ae03f23be8810 100644
--- a/pkg/items/mocks/PreSaver.go
+++ b/pkg/items/mocks/PreSaver.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.46.3. DO NOT EDIT.
+// Code generated by mockery v2.49.0. DO NOT EDIT.
 
 package mocks
 
diff --git a/pkg/items/mocks/ProcessDataFunc.go b/pkg/items/mocks/ProcessDataFunc.go
index 9ed80e9e51fec6b18f175b698e47248639aff138..bdf9d7a1a1a213d76c8138f431717c746f58c6c8 100644
--- a/pkg/items/mocks/ProcessDataFunc.go
+++ b/pkg/items/mocks/ProcessDataFunc.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.46.3. DO NOT EDIT.
+// Code generated by mockery v2.49.0. DO NOT EDIT.
 
 package mocks
 
diff --git a/pkg/items/mocks/Storage.go b/pkg/items/mocks/Storage.go
index b1dd2c54a75c0afb8f81f8004d1ed8a1189aaa5c..0dab6afff04b92c35bf5e6752cf2b33300e0106a 100644
--- a/pkg/items/mocks/Storage.go
+++ b/pkg/items/mocks/Storage.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.46.3. DO NOT EDIT.
+// Code generated by mockery v2.49.0. DO NOT EDIT.
 
 package mocks
 
diff --git a/pkg/items/options.go b/pkg/items/options.go
index 9aa77887112a2e221c115bdc6c7800840f290719..b46d5e370255070ca0475c69b5ba01d8488d8eac 100644
--- a/pkg/items/options.go
+++ b/pkg/items/options.go
@@ -717,6 +717,54 @@ func FindArchivedOptionsFromProto(opts *pb.FindArchivedOptions) *FindArchivedOpt
 	return o
 }
 
+type GetArchivedOptions struct {
+	Options
+
+	// Язык перевода, который будет использоваться. Если не указан, то возвращаются данные для языка по умолчанию
+	LocaleID string
+
+	// Список идентификаторов переводов/локалей, которых должны быть включены в результат
+	TranslationsIDs []string
+}
+
+func MergeGetArchivedOptions(opts ...*GetArchivedOptions) *GetArchivedOptions {
+	o := &GetArchivedOptions{}
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		o.Options = MergeOptions(o.Options, opt.Options)
+
+		if opt.LocaleID != "" {
+			o.LocaleID = opt.LocaleID
+		}
+		o.TranslationsIDs = append(o.TranslationsIDs, opt.TranslationsIDs...)
+	}
+	return o
+}
+
+func GetArchivedOptionsToProto(opts ...*GetArchivedOptions) *pb.GetArchivedOptions {
+	if opts == nil {
+		return nil
+	}
+	o := MergeGetArchivedOptions(opts...)
+	return &pb.GetArchivedOptions{
+		LocaleId:        o.LocaleID,
+		TranslationsIds: o.TranslationsIDs,
+	}
+}
+
+func GetArchivedOptionsFromProto(opts *pb.GetArchivedOptions) *GetArchivedOptions {
+	if opts == nil {
+		return nil
+	}
+	o := &GetArchivedOptions{
+		LocaleID:        opts.GetLocaleId(),
+		TranslationsIDs: opts.GetTranslationsIds(),
+	}
+	return o
+}
+
 type UnarchiveOptions struct {
 	Options
 }
@@ -786,3 +834,18 @@ func MergeAggregatePublishedOptions(opts ...*AggregatePublishedOptions) *Aggrega
 	merged := MergeAggregateOptions(ao...)
 	return (*AggregatePublishedOptions)(merged)
 }
+
+type CheckoutRevisionsOptions struct {
+	Options
+}
+
+func MergeCheckoutRevisionsOptions(opts ...*CheckoutRevisionsOptions) *CheckoutRevisionsOptions {
+	o := &CheckoutRevisionsOptions{}
+	for _, opt := range opts {
+		if opt == nil {
+			continue
+		}
+		o.Options = MergeOptions(o.Options, opt.Options)
+	}
+	return o
+}
diff --git a/pkg/items/service.go b/pkg/items/service.go
index b193076bf804b133ce0d0f422278c41adb47e039..8ec77a1a3c50839e6f6318002f0231978dbeb5c7 100644
--- a/pkg/items/service.go
+++ b/pkg/items/service.go
@@ -35,12 +35,14 @@ type Items interface {
 
 	GetRevision(ctx context.Context, spaceId, envId, collectionId, id, revisionId string, options ...*GetRevisionOptions) (item *Item, err error)
 	ListRevisions(ctx context.Context, spaceId, envId, collectionId, id string, options ...*ListRevisionsOptions) (items []*Item, total int, err error)
+	CheckoutRevision(ctx context.Context, spaceID string, envID string, collectionID string, id string, revID string,
+		options ...*CheckoutRevisionsOptions) (storedRevID string, err error)
 
 	Archive(ctx context.Context, item *Item, options ...*ArchiveOptions) (err error)
 	FindArchived(ctx context.Context, spaceId, envId, collectionId string, filter *Filter, options ...*FindArchivedOptions) (items []*Item, total int, err error)
 	Unarchive(ctx context.Context, item *Item, options ...*UnarchiveOptions) (err error)
-
-	CheckoutRevision(ctx context.Context, spaceId string, envId string, collId string, id string, revId string) (storedRevId string, err error)
+	GetArchived(ctx context.Context, spaceID, envID, collectionID, id string, options ...*GetArchivedOptions,
+	) (item *Item, err error)
 
 	// Aggregate выполняет агрегацию данных
 	Aggregate(ctx context.Context, spaceId, envId, collectionId string, filter *Filter, options ...*AggregateOptions) (result map[string]interface{}, err error)
@@ -74,6 +76,22 @@ func NewFilter(params ...interface{}) *Filter {
 	return f
 }
 
+func (f *Filter) Clone() *Filter {
+	if f == nil {
+		return nil
+	}
+	clone := &Filter{
+		ID:     make([]string, len(f.ID)),
+		Data:   make([]*filter.Filter, len(f.Data)),
+		Q:      make([]string, len(f.Q)),
+		Search: f.Search,
+	}
+	copy(clone.ID, f.ID)
+	copy(clone.Data, f.Data)
+	copy(clone.Q, f.Q)
+	return clone
+}
+
 // AggregateExpRe - формат, которому должна соответствовать формула расчета данных
 var AggregateExpRe = regexp.MustCompile(`([a-zA-Z]+)\((.*)\)`)
 
diff --git a/pkg/items/transport/client.go b/pkg/items/transport/client.go
index ebe824081fe34dd5dfd288300e3a884de2d0c1fb..0fbf6de05ca82835764b2099a1e0cd07c69c2350 100644
--- a/pkg/items/transport/client.go
+++ b/pkg/items/transport/client.go
@@ -211,6 +211,21 @@ func (set EndpointsSet) FindArchived(arg0 context.Context, arg1, arg2, arg3 stri
 	return response.(*FindArchivedResponse).Items, response.(*FindArchivedResponse).Total, res2
 }
 
+func (set EndpointsSet) GetArchived(arg0 context.Context, arg1 string, arg2 string, arg3 string, arg4 string, arg5 ...*items.GetArchivedOptions) (res0 *items.Item, res1 error) {
+	request := GetArchivedRequest{
+		CollectionId: arg3,
+		EnvId:        arg2,
+		ItemId:       arg4,
+		SpaceId:      arg1,
+		Options:      arg5,
+	}
+	response, res1 := set.GetArchivedEndpoint(arg0, &request)
+	if res1 != nil {
+		return
+	}
+	return response.(*GetArchivedResponse).Item, res1
+}
+
 func (set EndpointsSet) Unarchive(arg0 context.Context, arg1 *items.Item, arg2 ...*items.UnarchiveOptions) (res0 error) {
 	request := UnarchiveRequest{Item: arg1, Options: arg2}
 	_, res0 = set.UnarchiveEndpoint(arg0, &request)
@@ -220,7 +235,7 @@ func (set EndpointsSet) Unarchive(arg0 context.Context, arg1 *items.Item, arg2 .
 	return res0
 }
 
-func (set EndpointsSet) CheckoutRevision(arg0 context.Context, arg1 string, arg2 string, arg3 string, arg4 string, arg5 string) (res0 string, res1 error) {
+func (set EndpointsSet) CheckoutRevision(arg0 context.Context, arg1 string, arg2 string, arg3 string, arg4 string, arg5 string, arg6 ...*items.CheckoutRevisionsOptions) (res0 string, res1 error) {
 	request := CheckoutRevisionRequest{
 		CollId:  arg3,
 		EnvId:   arg2,
diff --git a/pkg/items/transport/endpoints.microgen.go b/pkg/items/transport/endpoints.microgen.go
index bd34b2c4a9280aefb05ef1c027dfe0bd3300195c..325ca2fb4d12fce856a7489e180265ea042b772a 100644
--- a/pkg/items/transport/endpoints.microgen.go
+++ b/pkg/items/transport/endpoints.microgen.go
@@ -21,6 +21,7 @@ type EndpointsSet struct {
 	ListRevisionsEndpoint      endpoint.Endpoint
 	ArchiveEndpoint            endpoint.Endpoint
 	FindArchivedEndpoint       endpoint.Endpoint
+	GetArchivedEndpoint        endpoint.Endpoint
 	UnarchiveEndpoint          endpoint.Endpoint
 	CheckoutRevisionEndpoint   endpoint.Endpoint
 	AggregateEndpoint          endpoint.Endpoint
diff --git a/pkg/items/transport/exchanges.microgen.go b/pkg/items/transport/exchanges.microgen.go
index 0a9c8c7660f0d3226e6be11374c9aa93504bbfe1..1f487b71fdba61e8a41df91b84c0cb20ff2a7ba9 100644
--- a/pkg/items/transport/exchanges.microgen.go
+++ b/pkg/items/transport/exchanges.microgen.go
@@ -150,6 +150,17 @@ type (
 		Total int           `json:"total"`
 	}
 
+	GetArchivedRequest struct {
+		SpaceId      string                      `json:"space_id"`
+		EnvId        string                      `json:"env_id"`
+		CollectionId string                      `json:"collection_id"`
+		ItemId       string                      `json:"item_id"`
+		Options      []*items.GetArchivedOptions `json:"options"` // This field was defined with ellipsis (...).
+	}
+	GetArchivedResponse struct {
+		Item *items.Item `json:"item"`
+	}
+
 	UnarchiveRequest struct {
 		Item    *items.Item               `json:"item"`
 		Options []*items.UnarchiveOptions `json:"options"` // This field was defined with ellipsis (...).
diff --git a/pkg/items/transport/grpc/client.go b/pkg/items/transport/grpc/client.go
index fdaf060c46f1c73d43811bf4597b8c14bafad30e..ae171639514f03a4b41312863f473a5fb25ea2b5 100644
--- a/pkg/items/transport/grpc/client.go
+++ b/pkg/items/transport/grpc/client.go
@@ -26,6 +26,7 @@ func NewClient(conn *grpc.ClientConn, opts ...grpckit.ClientOption) transport.En
 		GetRevisionEndpoint:        grpcerr.ClientMiddleware(c.GetRevisionEndpoint),
 		ListRevisionsEndpoint:      grpcerr.ClientMiddleware(c.ListRevisionsEndpoint),
 		ArchiveEndpoint:            grpcerr.ClientMiddleware(c.ArchiveEndpoint),
+		GetArchivedEndpoint:        grpcerr.ClientMiddleware(c.GetArchivedEndpoint),
 		FindArchivedEndpoint:       grpcerr.ClientMiddleware(c.FindArchivedEndpoint),
 		UnarchiveEndpoint:          grpcerr.ClientMiddleware(c.UnarchiveEndpoint),
 		CheckoutRevisionEndpoint:   grpcerr.ClientMiddleware(c.CheckoutRevisionEndpoint),
diff --git a/pkg/items/transport/grpc/client.microgen.go b/pkg/items/transport/grpc/client.microgen.go
index 2d6e06b90f0d801758f4de521fb70e1ea80cabd5..073eaed273041753950ba03f4a6639d0e27e5b21 100644
--- a/pkg/items/transport/grpc/client.microgen.go
+++ b/pkg/items/transport/grpc/client.microgen.go
@@ -64,6 +64,13 @@ func NewGRPCClient(conn *grpc.ClientConn, addr string, opts ...grpckit.ClientOpt
 			pb.FindArchivedResponse{},
 			opts...,
 		).Endpoint(),
+		GetArchivedEndpoint: grpckit.NewClient(
+			conn, addr, "GetArchived",
+			_Encode_GetArchived_Request,
+			_Decode_GetArchived_Response,
+			pb.GetArchivedResponse{},
+			opts...,
+		).Endpoint(),
 		FindEndpoint: grpckit.NewClient(
 			conn, addr, "Find",
 			_Encode_Find_Request,
diff --git a/pkg/items/transport/grpc/protobuf_endpoint_converters.microgen.go b/pkg/items/transport/grpc/protobuf_endpoint_converters.microgen.go
index 6afbf9b14811727057f3fbfa965618b95f8f3b0a..2f4ed3b0dd90fcfbb5211f68edeef67fe1989446 100644
--- a/pkg/items/transport/grpc/protobuf_endpoint_converters.microgen.go
+++ b/pkg/items/transport/grpc/protobuf_endpoint_converters.microgen.go
@@ -258,6 +258,24 @@ func _Encode_Archive_Request(ctx context.Context, request interface{}) (interfac
 	return &pb.ArchiveRequest{Item: reqItem}, nil
 }
 
+func _Encode_GetArchived_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil GetArchivedRequest")
+	}
+	req := request.(*transport.GetArchivedRequest)
+	opts, err := GetArchiedOptionsToProto(req.Options)
+	if err != nil {
+		return nil, err
+	}
+	return &pb.GetArchivedRequest{
+		CollectionId: req.CollectionId,
+		EnvId:        req.EnvId,
+		ItemId:       req.ItemId,
+		SpaceId:      req.SpaceId,
+		Options:      opts,
+	}, nil
+}
+
 func _Encode_FindArchived_Request(ctx context.Context, request interface{}) (interface{}, error) {
 	if request == nil {
 		return nil, errors.New("nil FindArchivedRequest")
@@ -434,6 +452,18 @@ func _Encode_GetRevision_Response(ctx context.Context, response interface{}) (in
 	return &pb.GetRevisionResponse{Item: respItem}, nil
 }
 
+func _Encode_GetArchived_Response(ctx context.Context, response interface{}) (interface{}, error) {
+	if response == nil {
+		return nil, errors.New("nil GetArchivedResponse")
+	}
+	resp := response.(*transport.GetArchivedResponse)
+	respItem, err := PtrItemToProto(resp.Item)
+	if err != nil {
+		return nil, err
+	}
+	return &pb.GetArchivedResponse{Item: respItem}, nil
+}
+
 func _Encode_ListRevisions_Response(ctx context.Context, response interface{}) (interface{}, error) {
 	if response == nil {
 		return nil, errors.New("nil ListRevisionsResponse")
@@ -790,6 +820,24 @@ func _Decode_Archive_Request(ctx context.Context, request interface{}) (interfac
 	return &transport.ArchiveRequest{Item: reqItem}, nil
 }
 
+func _Decode_GetArchived_Request(ctx context.Context, request interface{}) (interface{}, error) {
+	if request == nil {
+		return nil, errors.New("nil GetArchivedRequest")
+	}
+	req := request.(*pb.GetArchivedRequest)
+	opts, err := ProtoToGetArchivedOptions(req.Options)
+	if err != nil {
+		return nil, err
+	}
+	return &transport.GetArchivedRequest{
+		CollectionId: string(req.CollectionId),
+		EnvId:        string(req.EnvId),
+		ItemId:       string(req.ItemId),
+		SpaceId:      string(req.SpaceId),
+		Options:      opts,
+	}, nil
+}
+
 func _Decode_FindArchived_Request(ctx context.Context, request interface{}) (interface{}, error) {
 	if request == nil {
 		return nil, errors.New("nil FindArchivedRequest")
@@ -938,6 +986,18 @@ func _Decode_Archive_Response(ctx context.Context, response interface{}) (interf
 	return &empty.Empty{}, nil
 }
 
+func _Decode_GetArchived_Response(ctx context.Context, response interface{}) (interface{}, error) {
+	if response == nil {
+		return nil, errors.New("nil GetArchivedResponse")
+	}
+	resp := response.(*pb.GetArchivedResponse)
+	respItem, err := ProtoToPtrItem(resp.Item)
+	if err != nil {
+		return nil, err
+	}
+	return &transport.GetArchivedResponse{Item: respItem}, nil
+}
+
 func _Decode_FindArchived_Response(ctx context.Context, response interface{}) (interface{}, error) {
 	if response == nil {
 		return nil, errors.New("nil FindArchivedResponse")
diff --git a/pkg/items/transport/grpc/protobuf_type_converters.microgen.go b/pkg/items/transport/grpc/protobuf_type_converters.microgen.go
index 1aba486580e9f94882b29d254b1fffab39c8270c..b3bb5768b737cb61cfeac5604a6c1e233f951491 100644
--- a/pkg/items/transport/grpc/protobuf_type_converters.microgen.go
+++ b/pkg/items/transport/grpc/protobuf_type_converters.microgen.go
@@ -191,6 +191,18 @@ func ProtoToGetRevisionOptions(protoOptions *pb.GetRevisionOptions) ([]*service.
 	return []*service.GetRevisionOptions{service.GetRevisionOptionsFromProto(protoOptions)}, nil
 }
 
+func ProtoToGetArchivedOptions(protoOptions *pb.GetArchivedOptions) ([]*service.GetArchivedOptions, error) {
+	return []*service.GetArchivedOptions{service.GetArchivedOptionsFromProto(protoOptions)}, nil
+}
+
+func GetArchiedOptionsToProto(options []*service.GetArchivedOptions) (*pb.GetArchivedOptions, error) {
+	return service.GetArchivedOptionsToProto(options...), nil
+}
+
+func ProtoToGetArchiedOptions(protoOptions *pb.GetArchivedOptions) ([]*service.GetArchivedOptions, error) {
+	return []*service.GetArchivedOptions{service.GetArchivedOptionsFromProto(protoOptions)}, nil
+}
+
 func ListRevisionsOptionsToProto(options []*service.ListRevisionsOptions) (*pb.ListRevisionsOptions, error) {
 	return service.ListRevisionsOptionsToProto(options...), nil
 }
@@ -343,6 +355,14 @@ func ProtoToFindArchivedOptions(protoOptions *pb.FindArchivedOptions) ([]*servic
 	return []*service.FindArchivedOptions{service.FindArchivedOptionsFromProto(protoOptions)}, nil
 }
 
+func ElPtrGetArchivedOptionsToProto() {
+	panic("function not provided") // TODO: provide converter
+}
+
+func ProtoToElPtrGetArchivedOptions() {
+	panic("function not provided") // TODO: provide converter
+}
+
 func ElPtrUnarchiveOptionsToProto() {
 	panic("function not provided") // TODO: provide converter
 }
diff --git a/pkg/items/transport/grpc/server.go b/pkg/items/transport/grpc/server.go
index 676027f91411c21c30aeb233572e6df9b4c26aa3..8760972788f0776a5426b4a1632e8daf2a381100 100644
--- a/pkg/items/transport/grpc/server.go
+++ b/pkg/items/transport/grpc/server.go
@@ -25,6 +25,7 @@ func NewServer(svc items.Items, opts ...grpckit.ServerOption) pb.ItemsServer {
 		GetRevisionEndpoint:        grpcerr.ServerMiddleware(eps.GetRevisionEndpoint),
 		ListRevisionsEndpoint:      grpcerr.ServerMiddleware(eps.ListRevisionsEndpoint),
 		ArchiveEndpoint:            grpcerr.ServerMiddleware(eps.ArchiveEndpoint),
+		GetArchivedEndpoint:        grpcerr.ServerMiddleware(eps.GetArchivedEndpoint),
 		FindArchivedEndpoint:       grpcerr.ServerMiddleware(eps.FindArchivedEndpoint),
 		UnarchiveEndpoint:          grpcerr.ServerMiddleware(eps.UnarchiveEndpoint),
 		CheckoutRevisionEndpoint:   grpcerr.ServerMiddleware(eps.CheckoutRevisionEndpoint),
diff --git a/pkg/items/transport/grpc/server.microgen.go b/pkg/items/transport/grpc/server.microgen.go
index 618bfd00f5712f5b9f75936fd32f2cce767a26e6..7e50e367ac394fe8decef4bada2cd5eb7cb70175 100644
--- a/pkg/items/transport/grpc/server.microgen.go
+++ b/pkg/items/transport/grpc/server.microgen.go
@@ -26,6 +26,7 @@ type itemsServer struct {
 	getRevision        grpc.Handler
 	listRevisions      grpc.Handler
 	archive            grpc.Handler
+	getArchived        grpc.Handler
 	findArchived       grpc.Handler
 	unarchive          grpc.Handler
 	checkoutRevision   grpc.Handler
@@ -109,6 +110,12 @@ func NewGRPCServer(endpoints *transport.EndpointsSet, opts ...grpc.ServerOption)
 			_Encode_GetRevision_Response,
 			opts...,
 		),
+		getArchived: grpc.NewServer(
+			endpoints.GetArchivedEndpoint,
+			_Decode_GetArchived_Request,
+			_Encode_GetArchived_Response,
+			opts...,
+		),
 		introspect: grpc.NewServer(
 			endpoints.IntrospectEndpoint,
 			_Decode_Introspect_Request,
@@ -266,6 +273,14 @@ func (S *itemsServer) Archive(ctx context.Context, req *pb.ArchiveRequest) (*emp
 	return resp.(*empty.Empty), nil
 }
 
+func (S *itemsServer) GetArchived(ctx context.Context, req *pb.GetArchivedRequest) (*pb.GetArchivedResponse, error) {
+	_, resp, err := S.getArchived.ServeGRPC(ctx, req)
+	if err != nil {
+		return nil, err
+	}
+	return resp.(*pb.GetArchivedResponse), nil
+}
+
 func (S *itemsServer) FindArchived(ctx context.Context, req *pb.FindArchivedRequest) (*pb.FindArchivedResponse, error) {
 	_, resp, err := S.findArchived.ServeGRPC(ctx, req)
 	if err != nil {
diff --git a/pkg/items/transport/server.microgen.go b/pkg/items/transport/server.microgen.go
index 36dd1b2dab85fb18b45c2bcb4c66d3a90910bed4..7df6cf99c66121406d47c36cf95362e6175e8fa3 100644
--- a/pkg/items/transport/server.microgen.go
+++ b/pkg/items/transport/server.microgen.go
@@ -21,6 +21,7 @@ func Endpoints(svc items.Items) EndpointsSet {
 		CreateEndpoint:             CreateEndpoint(svc),
 		DeleteEndpoint:             DeleteEndpoint(svc),
 		FindArchivedEndpoint:       FindArchivedEndpoint(svc),
+		GetArchivedEndpoint:        GetArchivedEndpoint(svc),
 		FindEndpoint:               FindEndpoint(svc),
 		FindPublishedEndpoint:      FindPublishedEndpoint(svc),
 		GetEndpoint:                GetEndpoint(svc),
@@ -182,6 +183,14 @@ func ArchiveEndpoint(svc items.Items) endpoint.Endpoint {
 	}
 }
 
+func GetArchivedEndpoint(svc items.Items) endpoint.Endpoint {
+	return func(arg0 context.Context, request interface{}) (interface{}, error) {
+		req := request.(*GetArchivedRequest)
+		res0, res1 := svc.GetArchived(arg0, req.SpaceId, req.EnvId, req.CollectionId, req.ItemId, req.Options...)
+		return &GetArchivedResponse{Item: res0}, res1
+	}
+}
+
 func FindArchivedEndpoint(svc items.Items) endpoint.Endpoint {
 	return func(arg0 context.Context, request interface{}) (interface{}, error) {
 		req := request.(*FindArchivedRequest)
diff --git a/pkg/members/mocks/spaceGetter.go b/pkg/members/mocks/spaceGetter.go
new file mode 100644
index 0000000000000000000000000000000000000000..b56dbea69d47c51f6a6755dc6a1a1d0bf0dd649a
--- /dev/null
+++ b/pkg/members/mocks/spaceGetter.go
@@ -0,0 +1,42 @@
+// Code generated by mockery v2.50.0. DO NOT EDIT.
+
+package mocks
+
+import mock "github.com/stretchr/testify/mock"
+
+// SpaceGetter is an autogenerated mock type for the spaceGetter type
+type SpaceGetter struct {
+	mock.Mock
+}
+
+// GetSpaceID provides a mock function with no fields
+func (_m *SpaceGetter) GetSpaceID() string {
+	ret := _m.Called()
+
+	if len(ret) == 0 {
+		panic("no return value specified for GetSpaceID")
+	}
+
+	var r0 string
+	if rf, ok := ret.Get(0).(func() string); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Get(0).(string)
+	}
+
+	return r0
+}
+
+// NewSpaceGetter creates a new instance of SpaceGetter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewSpaceGetter(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *SpaceGetter {
+	mock := &SpaceGetter{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/operation/mocks/Service.go b/pkg/operation/mocks/Service.go
new file mode 100644
index 0000000000000000000000000000000000000000..578f6d056c0358fed26daf0dc67433646df1fde1
--- /dev/null
+++ b/pkg/operation/mocks/Service.go
@@ -0,0 +1,144 @@
+// Code generated by mockery v2.50.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	context "context"
+
+	operation "git.perx.ru/perxis/perxis-go/pkg/operation"
+	mock "github.com/stretchr/testify/mock"
+
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+)
+
+// Service is an autogenerated mock type for the Service type
+type Service struct {
+	mock.Mock
+}
+
+// Cancel provides a mock function with given fields: ctx, id
+func (_m *Service) Cancel(ctx context.Context, id string) (*operation.Operation, error) {
+	ret := _m.Called(ctx, id)
+
+	if len(ret) == 0 {
+		panic("no return value specified for Cancel")
+	}
+
+	var r0 *operation.Operation
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, string) (*operation.Operation, error)); ok {
+		return rf(ctx, id)
+	}
+	if rf, ok := ret.Get(0).(func(context.Context, string) *operation.Operation); ok {
+		r0 = rf(ctx, id)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*operation.Operation)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
+		r1 = rf(ctx, id)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// Cleanup provides a mock function with no fields
+func (_m *Service) Cleanup() {
+	_m.Called()
+}
+
+// Create provides a mock function with given fields: ctx, desc, fn
+func (_m *Service) Create(ctx context.Context, desc string, fn func(context.Context) (protoreflect.ProtoMessage, error)) (*operation.Operation, error) {
+	ret := _m.Called(ctx, desc, fn)
+
+	if len(ret) == 0 {
+		panic("no return value specified for Create")
+	}
+
+	var r0 *operation.Operation
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, string, func(context.Context) (protoreflect.ProtoMessage, error)) (*operation.Operation, error)); ok {
+		return rf(ctx, desc, fn)
+	}
+	if rf, ok := ret.Get(0).(func(context.Context, string, func(context.Context) (protoreflect.ProtoMessage, error)) *operation.Operation); ok {
+		r0 = rf(ctx, desc, fn)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*operation.Operation)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(context.Context, string, func(context.Context) (protoreflect.ProtoMessage, error)) error); ok {
+		r1 = rf(ctx, desc, fn)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// Get provides a mock function with given fields: ctx, id
+func (_m *Service) Get(ctx context.Context, id string) (*operation.Operation, error) {
+	ret := _m.Called(ctx, id)
+
+	if len(ret) == 0 {
+		panic("no return value specified for Get")
+	}
+
+	var r0 *operation.Operation
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, string) (*operation.Operation, error)); ok {
+		return rf(ctx, id)
+	}
+	if rf, ok := ret.Get(0).(func(context.Context, string) *operation.Operation); ok {
+		r0 = rf(ctx, id)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*operation.Operation)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
+		r1 = rf(ctx, id)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// Set provides a mock function with given fields: ctx, op
+func (_m *Service) Set(ctx context.Context, op *operation.Operation) error {
+	ret := _m.Called(ctx, op)
+
+	if len(ret) == 0 {
+		panic("no return value specified for Set")
+	}
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(context.Context, *operation.Operation) error); ok {
+		r0 = rf(ctx, op)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// NewService creates a new instance of Service. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewService(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *Service {
+	mock := &Service{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/references/mocks/spaceGetter.go b/pkg/references/mocks/spaceGetter.go
new file mode 100644
index 0000000000000000000000000000000000000000..b56dbea69d47c51f6a6755dc6a1a1d0bf0dd649a
--- /dev/null
+++ b/pkg/references/mocks/spaceGetter.go
@@ -0,0 +1,42 @@
+// Code generated by mockery v2.50.0. DO NOT EDIT.
+
+package mocks
+
+import mock "github.com/stretchr/testify/mock"
+
+// SpaceGetter is an autogenerated mock type for the spaceGetter type
+type SpaceGetter struct {
+	mock.Mock
+}
+
+// GetSpaceID provides a mock function with no fields
+func (_m *SpaceGetter) GetSpaceID() string {
+	ret := _m.Called()
+
+	if len(ret) == 0 {
+		panic("no return value specified for GetSpaceID")
+	}
+
+	var r0 string
+	if rf, ok := ret.Get(0).(func() string); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Get(0).(string)
+	}
+
+	return r0
+}
+
+// NewSpaceGetter creates a new instance of SpaceGetter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewSpaceGetter(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *SpaceGetter {
+	mock := &SpaceGetter{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/pkg/roles/middleware/middleware.go b/pkg/roles/middleware/middleware.go
index aaeb2da895d5aa71768e577315e549daa6a247c4..299199a40432f486d1020bb803f5bff18a95428e 100644
--- a/pkg/roles/middleware/middleware.go
+++ b/pkg/roles/middleware/middleware.go
@@ -21,7 +21,7 @@ func WithLog(s roles.Roles, logger *zap.Logger, log_access bool) roles.Roles {
 	if log_access {
 		s = AccessLoggingMiddleware(logger)(s)
 	}
-	s = ErrorLoggingMiddleware(logger)(s)
+	s = LoggingMiddleware(logger)(s)
 
 	s = RecoveringMiddleware(logger)(s)
 	return s
diff --git a/pkg/schema/field/array.go b/pkg/schema/field/array.go
index bf1a4819dd075fc5e3f46fc4d1e289c8bd75cf90..682b6e5e7774cbf98e93fc31261e114b574049e7 100644
--- a/pkg/schema/field/array.go
+++ b/pkg/schema/field/array.go
@@ -132,24 +132,29 @@ func (ArrayType) Walk(ctx context.Context, field *Field, v interface{}, fn WalkF
 		return nil, false, nil
 	}
 
-	arr, ok := v.([]interface{})
-	if !ok && v != nil {
-		return nil, false, fmt.Errorf("incorrect type: \"%s\", expected \"[]interface{}\"", reflect.ValueOf(v).Kind())
+	arr := reflect.ValueOf(v)
+	if v != nil && arr.Kind() != reflect.Slice && arr.Kind() != reflect.Array {
+		return nil, false, fmt.Errorf("incorrect type: %s, expected array or slice", arr.Kind())
+	}
+
+	var length int
+	if v != nil {
+		length = arr.Len()
 	}
 
 	// Выполняется обход по схеме
-	if opts.WalkSchema && len(arr) == 0 {
+	if opts.WalkSchema && length == 0 {
 		_, _, _ = params.Item.Walk(ctx, nil, fn, WalkOpts(opts))
 		return nil, false, nil
 	}
 
-	m := make([]interface{}, 0, len(arr))
+	m := make([]interface{}, 0, length)
 
 	var merr *multierror.Error
-	for i, value := range arr {
+	for i := range length {
+		value := arr.Index(i).Interface()
 
 		valueNew, valueChanged, err := params.Item.Walk(ctx, value, fn, WalkOpts(opts))
-
 		if err != nil {
 			merr = multierror.Append(merr, errors.WithField(err, strconv.Itoa(i)))
 		}
diff --git a/pkg/schema/field/array_test.go b/pkg/schema/field/array_test.go
index b2948e1b12161da604ed22da96e4b8a092c0a99f..ab8eae74376154ba89ce5a41ebc885da7bc15a1a 100644
--- a/pkg/schema/field/array_test.go
+++ b/pkg/schema/field/array_test.go
@@ -48,7 +48,7 @@ func TestArrayField_Decode(t *testing.T) {
 			"Incorrect type",
 			Array(Number("int")),
 			"1 2 3",
-			"decode error: incorrect type: \"string\", expected \"[]interface{}\"",
+			"decode error: incorrect type: string, expected array or slice",
 			true,
 		},
 	}
@@ -86,7 +86,7 @@ func TestArrayField_Encode(t *testing.T) {
 			"Incorrect type",
 			Array(Number("int")),
 			"1 2 3",
-			"encode error: incorrect type: \"string\", expected \"[]interface{}\"",
+			"encode error: incorrect type: string, expected array or slice",
 			true,
 		},
 	}
@@ -125,6 +125,18 @@ func TestArrayType_Walk(t *testing.T) {
 			want1:   false,
 			wantErr: assert.NoError,
 		},
+		{
+			name:  "With nil data and WalkSchema = true",
+			field: Array(Object("a", String(), "b", String())),
+			v:     nil,
+			opts:  &WalkOptions{WalkSchema: true},
+			want:  nil,
+			want1: false,
+			fn: func(_ context.Context, _ *Field, _ interface{}) (WalkFuncResult, error) {
+				return WalkFuncResult{}, nil
+			},
+			wantErr: assert.NoError,
+		},
 		{
 			name:  "With empty data and WalkSchema = false",
 			field: Array(Object("a", String(), "b", String())),
@@ -162,3 +174,96 @@ func TestArrayType_Walk(t *testing.T) {
 		})
 	}
 }
+
+type customFloat float64
+type customInt int
+type customStr string
+type customMap map[string]interface{}
+
+func TestArrayField_WithType(t *testing.T) {
+	t.Run("Nil", func(t *testing.T) {
+		got, err := Decode(context.Background(), Array(Number("float")), nil)
+		require.NoError(t, err)
+		assert.ElementsMatch(t, got, nil)
+
+		got, err = Encode(context.Background(), Array(Number("float")), nil)
+		require.NoError(t, err)
+		assert.ElementsMatch(t, got, nil)
+	})
+	t.Run("With []float64", func(t *testing.T) {
+		got, err := Decode(context.Background(), Array(Number("float")), []float64{1.0, 2.0})
+		require.NoError(t, err)
+		assert.ElementsMatch(t, got, []interface{}{1.0, 2.0})
+
+		got, err = Encode(context.Background(), Array(Number("float")), []float64{1.0, 2.0})
+		require.NoError(t, err)
+		assert.ElementsMatch(t, got, []interface{}{1.0, 2.0})
+	})
+	t.Run("With []int", func(t *testing.T) {
+		got, err := Decode(context.Background(), Array(Number("int")), []int{1, 2})
+		require.NoError(t, err)
+		assert.ElementsMatch(t, got, []interface{}{int64(1), int64(2)})
+
+		got, err = Encode(context.Background(), Array(Number("int")), []int{1, 2})
+		require.NoError(t, err)
+		assert.ElementsMatch(t, got, []interface{}{int64(1), int64(2)})
+	})
+	t.Run("With []string", func(t *testing.T) {
+		got, err := Decode(context.Background(), Array(String()), []string{"1", "2"})
+		require.NoError(t, err)
+		assert.ElementsMatch(t, got, []interface{}{"1", "2"})
+
+		got, err = Encode(context.Background(), Array(String()), []string{"1", "2"})
+		require.NoError(t, err)
+		assert.ElementsMatch(t, got, []interface{}{"1", "2"})
+	})
+	t.Run("With []map", func(t *testing.T) {
+		got, err := Decode(context.Background(), Array(Object("a", String(), "b", String())),
+			[]map[string]interface{}{{"a": "1", "b": "2"}})
+		require.NoError(t, err)
+		assert.ElementsMatch(t, got, []interface{}{map[string]interface{}{"a": "1", "b": "2"}})
+
+		got, err = Encode(context.Background(), Array(Object("a", String(), "b", String())),
+			[]map[string]interface{}{{"a": "1", "b": "2"}})
+		require.NoError(t, err)
+		assert.ElementsMatch(t, got, []interface{}{map[string]interface{}{"a": "1", "b": "2"}})
+	})
+	t.Run("With []customFloat", func(t *testing.T) {
+		got, err := Decode(context.Background(), Array(Number("float")), []customFloat{1.0, 2.0})
+		require.NoError(t, err)
+		assert.ElementsMatch(t, got, []interface{}{1.0, 2.0})
+
+		got, err = Encode(context.Background(), Array(Number("float")), []customFloat{1.0, 2.0})
+		require.NoError(t, err)
+		assert.ElementsMatch(t, got, []interface{}{1.0, 2.0})
+	})
+	t.Run("With []customInt", func(t *testing.T) {
+		got, err := Decode(context.Background(), Array(Number("int")), []customInt{1, 2})
+		require.NoError(t, err)
+		assert.ElementsMatch(t, got, []interface{}{int64(1), int64(2)})
+
+		got, err = Encode(context.Background(), Array(Number("int")), []customInt{1, 2})
+		require.NoError(t, err)
+		assert.ElementsMatch(t, got, []interface{}{int64(1), int64(2)})
+	})
+	t.Run("With []customStr", func(t *testing.T) {
+		got, err := Decode(context.Background(), Array(String()), []customStr{"1", "2"})
+		require.NoError(t, err)
+		assert.ElementsMatch(t, got, []interface{}{"1", "2"})
+
+		got, err = Encode(context.Background(), Array(String()), []customStr{"1", "2"})
+		require.NoError(t, err)
+		assert.ElementsMatch(t, got, []interface{}{"1", "2"})
+	})
+	t.Run("With []customMap", func(t *testing.T) {
+		got, err := Decode(context.Background(), Array(Object("a", String(), "b", String())),
+			[]customMap{{"a": "1", "b": "2"}})
+		require.NoError(t, err)
+		assert.ElementsMatch(t, got, []interface{}{map[string]interface{}{"a": "1", "b": "2"}})
+
+		got, err = Encode(context.Background(), Array(Object("a", String(), "b", String())),
+			[]customMap{{"a": "1", "b": "2"}})
+		require.NoError(t, err)
+		assert.ElementsMatch(t, got, []interface{}{map[string]interface{}{"a": "1", "b": "2"}})
+	})
+}
diff --git a/pkg/schema/field/number.go b/pkg/schema/field/number.go
index dfc8a6635cc0e719bd55e9f680ba23688674edd0..16673917895c4967c5b9ca65c5b6d1a5b397b045 100644
--- a/pkg/schema/field/number.go
+++ b/pkg/schema/field/number.go
@@ -3,6 +3,7 @@ package field
 import (
 	"context"
 	"math"
+	"reflect"
 
 	"github.com/pkg/errors"
 )
@@ -41,6 +42,20 @@ func (NumberType) IsEmpty(v interface{}) bool {
 	return v == nil
 }
 
+func toNumberReflect(i interface{}) (interface{}, error) {
+	v := reflect.ValueOf(i)
+	switch v.Kind() { //nolint:exhaustive //not necessary to add all types
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return v.Int(), nil
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		return v.Uint(), nil
+	case reflect.Float32, reflect.Float64:
+		return v.Float(), nil
+	default:
+		return 0, errors.Errorf("error convert \"%s\" to number", i)
+	}
+}
+
 func ToNumber(i interface{}) (interface{}, error) {
 	switch v := i.(type) {
 	case int64:
@@ -63,8 +78,9 @@ func ToNumber(i interface{}) (interface{}, error) {
 		return float64(v), nil
 	case float64:
 		return v, nil
+	default:
+		return toNumberReflect(v)
 	}
-	return 0, errors.Errorf("error convert \"%s\" to number", i)
 }
 
 func (n NumberType) Decode(ctx context.Context, field *Field, v interface{}) (interface{}, error) {
diff --git a/pkg/schema/field/number_test.go b/pkg/schema/field/number_test.go
index 367ffe4249f36f2dff17aa1e61ef6a753ccabee8..26d76f9527e2a74c3232ff2831660fee02528be2 100644
--- a/pkg/schema/field/number_test.go
+++ b/pkg/schema/field/number_test.go
@@ -5,8 +5,12 @@ import (
 	"math"
 	"reflect"
 	"testing"
+
+	"git.perx.ru/perxis/perxis-go/pkg/errors"
 )
 
+type CustomInt int
+
 func TestNumberField_Decode(t *testing.T) {
 	tests := []struct {
 		name    string
@@ -21,6 +25,7 @@ func TestNumberField_Decode(t *testing.T) {
 		{"Correct", Number("int"), float32(2.2), int64(2), false},                           // #3
 		{"Correct", Number("int"), float64(2.6), int64(3), false},                           // #4
 		{"Correct", Number("int"), 2.6, int64(3), false},                                    // #5
+		{"Correct", Number("int"), CustomInt(2), int64(2), false},                           // #5
 		{"MaxInt64", Number(NumberFormatInt), int64(math.MaxInt64), nil, true},              // #6
 		{"MinInt64", Number(NumberFormatInt), int64(math.MinInt64), nil, true},              // #7
 		{"maxInt in float", Number(NumberFormatInt), float64(maxInt), int64(maxInt), false}, // #8
@@ -94,3 +99,152 @@ func TestNumberField_Encode(t *testing.T) {
 		})
 	}
 }
+
+// Добавлен полные функции, чтобы результаты теста не поменялись, в случае изменения Decode
+// Реализация cast type.
+func toNumber(i interface{}) (interface{}, error) {
+	switch v := i.(type) {
+	case int64:
+		return v, nil
+	case int:
+		return int64(v), nil
+	case int8:
+		return int64(v), nil
+	case int32:
+		return int64(v), nil
+	case uint64:
+		return v, nil
+	case uint:
+		return uint64(v), nil
+	case uint8:
+		return uint64(v), nil
+	case uint32:
+		return uint64(v), nil
+	case float32:
+		return float64(v), nil
+	case float64:
+		return v, nil
+	}
+	return 0, errors.Errorf("error convert \"%s\" to number", i)
+}
+func decodeNumber(field *Field, v interface{}) (interface{}, error) {
+	params, ok := field.Params.(*NumberParameters)
+	if !ok {
+		return nil, errors.New("field parameters required")
+	}
+
+	if v == nil {
+		return v, nil
+	}
+
+	n, err := toNumber(v)
+	if err != nil {
+		return nil, err
+	}
+
+	switch params.Format {
+	case NumberFormatInt:
+		switch i := n.(type) {
+		case int64:
+			if i > maxInt || i < minInt {
+				return nil, errors.New("integer out of range")
+			}
+			return i, nil
+		case uint64:
+			if i > maxInt {
+				return nil, errors.New("integer out of range")
+			}
+			return i, nil
+		case float64:
+			if i > maxInt || i < minInt {
+				return nil, errors.New("integer out of range")
+			}
+			return int64(math.Round(i)), nil
+		}
+	case NumberFormatFloat:
+		switch i := n.(type) {
+		case float64:
+			return i, nil
+		case int64:
+			return float64(i), nil
+		case uint64:
+			return float64(i), nil
+		}
+	}
+	return n, nil
+}
+
+// Реализация reflect.
+func decodeNumberReflect(field *Field, v interface{}) (interface{}, error) { //nolint:unparam // test case
+	params, ok := field.Params.(*NumberParameters)
+	if !ok {
+		return nil, errors.New("field parameters required")
+	}
+
+	if v == nil {
+		return v, nil
+	}
+
+	n, err := toNumberReflect(v) // вызов метода reflect
+	if err != nil {
+		return nil, err
+	}
+
+	switch params.Format {
+	case NumberFormatInt:
+		switch i := n.(type) {
+		case int64:
+			if i > maxInt || i < minInt {
+				return nil, errors.New("integer out of range")
+			}
+			return i, nil
+		case uint64:
+			if i > maxInt {
+				return nil, errors.New("integer out of range")
+			}
+			return i, nil
+		case float64:
+			if i > maxInt || i < minInt {
+				return nil, errors.New("integer out of range")
+			}
+			return int64(math.Round(i)), nil
+		}
+	case NumberFormatFloat:
+		switch i := n.(type) {
+		case float64:
+			return i, nil
+		case int64:
+			return float64(i), nil
+		case uint64:
+			return float64(i), nil
+		}
+	}
+	return n, nil
+}
+
+// команда запуска go test -bench=.
+func BenchmarkDecodeReflectNumber(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		_, _ = decodeNumberReflect(Number(NumberFormatInt), i)
+	}
+}
+func BenchmarkDecodeReflectCustomNumber(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		_, _ = decodeNumberReflect(Number(NumberFormatInt), customInt(i))
+	}
+}
+func BenchmarkDecodeNumber(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		_, _ = decodeNumber(Number(NumberFormatInt), i)
+	}
+}
+func BenchmarkDecodeNumberCurrentSolution(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		_, _ = NumberType{}.decode(context.Background(), Number(NumberFormatInt), i)
+	}
+}
+func BenchmarkDecodeCustomNumberCurrentSolution(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		_, _ = NumberType{}.decode(context.Background(), Number(NumberFormatInt), customInt(i))
+	}
+}
diff --git a/pkg/schema/field/string.go b/pkg/schema/field/string.go
index 17b5e7ae086d3fac1b25d8c332c33d83fecedfb8..96b4e8dd4d4d0d193a91718698906dda15c0cc85 100644
--- a/pkg/schema/field/string.go
+++ b/pkg/schema/field/string.go
@@ -37,6 +37,10 @@ func (StringType) Decode(_ context.Context, _ *Field, v interface{}) (interface{
 	if _, ok := v.(string); ok {
 		return v, nil
 	}
+	t := reflect.ValueOf(v)
+	if t.Kind() == reflect.String {
+		return t.String(), nil
+	}
 	return nil, fmt.Errorf("StringField decode error: unsupported value type : \"%s\"", reflect.ValueOf(v).Kind())
 }
 
@@ -47,6 +51,10 @@ func (StringType) Encode(_ context.Context, _ *Field, v interface{}) (interface{
 	if _, ok := v.(string); ok {
 		return v, nil
 	}
+	t := reflect.ValueOf(v)
+	if t.Kind() == reflect.String {
+		return t.String(), nil
+	}
 	return nil, fmt.Errorf("StringField encode error: unsupported value type : \"%s\"", reflect.ValueOf(v).Kind())
 }
 
diff --git a/pkg/schema/field/string_test.go b/pkg/schema/field/string_test.go
index 16b7538fb86797946a4a3c3ba709e6e30cf4d5d8..c858f607a7e13719152b3308773024e4d1919e5a 100644
--- a/pkg/schema/field/string_test.go
+++ b/pkg/schema/field/string_test.go
@@ -2,10 +2,14 @@ package field
 
 import (
 	"context"
+	"fmt"
 	"reflect"
+	"strconv"
 	"testing"
 )
 
+type customString string
+
 func TestStringField_Decode(t *testing.T) {
 	tests := []struct {
 		name    string
@@ -15,6 +19,7 @@ func TestStringField_Decode(t *testing.T) {
 		wantErr bool
 	}{
 		{"Correct", String(), "string", "string", false},
+		{"Correct", String(), customString("string"), "string", false},
 		{"Wrong data", String(), 2, nil, true},
 	}
 	for _, tt := range tests {
@@ -55,3 +60,54 @@ func TestStringField_Encode(t *testing.T) {
 		})
 	}
 }
+
+// Добавлен полные функции, чтобы результаты теста не поменялись, в случае изменения Decode
+// Старая реализация.
+func decodeStringReflect(v interface{}) (interface{}, error) { //nolint:unparam // test case
+	if v == nil {
+		return nil, nil //nolint:nilnil // test case
+	}
+	t := reflect.ValueOf(v)
+	if t.Kind() == reflect.String {
+		return t.String(), nil
+	}
+	return nil, fmt.Errorf("StringField decode error: unsupported value type : \"%s\"", reflect.ValueOf(v).Kind())
+}
+
+// Новая реализация.
+func decodeString(v interface{}) (interface{}, error) {
+	if v == nil {
+		return nil, nil //nolint:nilnil // test case
+	}
+	if _, ok := v.(string); ok {
+		return v, nil
+	}
+	return nil, fmt.Errorf("StringField decode error: unsupported value type : \"%s\"", reflect.ValueOf(v).Kind())
+}
+
+// команда запуска go test -bench=.
+func BenchmarkDecodeStringReflect(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		_, _ = decodeStringReflect(strconv.Itoa(i))
+	}
+}
+func BenchmarkDecodeCustomStringReflect(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		_, _ = decodeStringReflect(customString(strconv.Itoa(i)))
+	}
+}
+func BenchmarkDecodeString(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		_, _ = decodeString(strconv.Itoa(i))
+	}
+}
+func BenchmarkDecodeStringCurrentSolution(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		_, _ = StringType{}.Decode(context.Background(), nil, strconv.Itoa(i))
+	}
+}
+func BenchmarkDecodeCustomStringCurrentSolution(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		_, _ = StringType{}.Decode(context.Background(), nil, customString(strconv.Itoa(i)))
+	}
+}
diff --git a/pkg/schema/validate/array_test.go b/pkg/schema/validate/array_test.go
index ec9e9d818d5b86d7fe9e8647d862e73f44232c65..465401779153449ad04d342d41d4e7990e0fa302 100644
--- a/pkg/schema/validate/array_test.go
+++ b/pkg/schema/validate/array_test.go
@@ -50,8 +50,8 @@ func TestArrayValidate(t *testing.T) {
 	}{
 		{"Nil Max Items", field.Array(field.String()).AddOptions(MaxItems(1)), nil, false, ""},
 		{"Nil Min Items", field.Array(field.String()).AddOptions(MinItems(1)), nil, false, ""},
-		{"Array Max Items", field.Array(field.String()).AddOptions(MaxItems(1)), [1]interface{}{1}, true, "validation error: incorrect type: \"array\", expected \"[]interface{}\""},
-		{"Array Min Items", field.Array(field.String()).AddOptions(MinItems(1)), [1]interface{}{1}, true, "validation error: incorrect type: \"array\", expected \"[]interface{}\""},
+		{"Array Max Items", field.Array(field.String()).AddOptions(MaxItems(1)), [1]interface{}{1}, false, ""},
+		{"Array Min Items", field.Array(field.String()).AddOptions(MinItems(1)), [1]interface{}{1}, false, ""},
 		{"Slice Max Items", field.Array(field.String()).AddOptions(MaxItems(0)), []interface{}{}, false, ""},
 		{"Slice Min Items", field.Array(field.String()).AddOptions(MinItems(0)), []interface{}{}, false, ""},
 		{"Bool Max Items", field.Array(field.String()).AddOptions(MaxItems(1)), true, true, "validation error: incorrect type: \"bool\", expected \"array\""},
diff --git a/proto/invitations/invitations.pb.go b/proto/invitations/invitations.pb.go
index f9dbc0b32b001a2e5b738164d32e1291a4e7c4c3..79a0e8876b7ea35784c34714b8ab499330254763 100644
--- a/proto/invitations/invitations.pb.go
+++ b/proto/invitations/invitations.pb.go
@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.35.1
-// 	protoc        v5.28.3
+// 	protoc-gen-go v1.36.0
+// 	protoc        v5.29.2
 // source: invitations/invitations.proto
 
 package invitations
@@ -25,18 +25,19 @@ const (
 )
 
 type Invitation struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
+	state         protoimpl.MessageState `protogen:"open.v1"`
+	Id            string                 `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
+	Email         string                 `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"`
+	OrgId         string                 `protobuf:"bytes,3,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"`
+	SpaceId       string                 `protobuf:"bytes,4,opt,name=space_id,json=spaceId,proto3" json:"space_id,omitempty"`
+	OwnerId       string                 `protobuf:"bytes,5,opt,name=owner_id,json=ownerId,proto3" json:"owner_id,omitempty"`
+	Role          string                 `protobuf:"bytes,6,opt,name=role,proto3" json:"role,omitempty"`
+	CreatedAt     *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
+	ValidUntil    *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=valid_until,json=validUntil,proto3" json:"valid_until,omitempty"`
+	Uses          uint32                 `protobuf:"varint,9,opt,name=uses,proto3" json:"uses,omitempty"`                       // Количество пользователей, принявших приглашение.
+	MaxUses       uint32                 `protobuf:"varint,10,opt,name=max_uses,json=maxUses,proto3" json:"max_uses,omitempty"` // Максимальное количество пользователей, которые могут принять приглашение.
 	unknownFields protoimpl.UnknownFields
-
-	Id         string                 `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
-	Email      string                 `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"`
-	OrgId      string                 `protobuf:"bytes,3,opt,name=org_id,json=orgId,proto3" json:"org_id,omitempty"`
-	SpaceId    string                 `protobuf:"bytes,4,opt,name=space_id,json=spaceId,proto3" json:"space_id,omitempty"`
-	OwnerId    string                 `protobuf:"bytes,5,opt,name=owner_id,json=ownerId,proto3" json:"owner_id,omitempty"`
-	Role       string                 `protobuf:"bytes,6,opt,name=role,proto3" json:"role,omitempty"`
-	CreatedAt  *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
-	ValidUntil *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=valid_until,json=validUntil,proto3" json:"valid_until,omitempty"`
+	sizeCache     protoimpl.SizeCache
 }
 
 func (x *Invitation) Reset() {
@@ -125,17 +126,30 @@ func (x *Invitation) GetValidUntil() *timestamppb.Timestamp {
 	return nil
 }
 
+func (x *Invitation) GetUses() uint32 {
+	if x != nil {
+		return x.Uses
+	}
+	return 0
+}
+
+func (x *Invitation) GetMaxUses() uint32 {
+	if x != nil {
+		return x.MaxUses
+	}
+	return 0
+}
+
 type Filter struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
+	state         protoimpl.MessageState `protogen:"open.v1"`
+	Id            []string               `protobuf:"bytes,1,rep,name=id,proto3" json:"id,omitempty"`
+	Email         []string               `protobuf:"bytes,2,rep,name=email,proto3" json:"email,omitempty"`
+	OrgId         []string               `protobuf:"bytes,3,rep,name=org_id,json=orgId,proto3" json:"org_id,omitempty"`
+	SpaceId       []string               `protobuf:"bytes,4,rep,name=space_id,json=spaceId,proto3" json:"space_id,omitempty"`
+	OwnerId       []string               `protobuf:"bytes,5,rep,name=owner_id,json=ownerId,proto3" json:"owner_id,omitempty"`
+	Role          []string               `protobuf:"bytes,6,rep,name=role,proto3" json:"role,omitempty"`
 	unknownFields protoimpl.UnknownFields
-
-	Id      []string `protobuf:"bytes,1,rep,name=id,proto3" json:"id,omitempty"`
-	Email   []string `protobuf:"bytes,2,rep,name=email,proto3" json:"email,omitempty"`
-	OrgId   []string `protobuf:"bytes,3,rep,name=org_id,json=orgId,proto3" json:"org_id,omitempty"`
-	SpaceId []string `protobuf:"bytes,4,rep,name=space_id,json=spaceId,proto3" json:"space_id,omitempty"`
-	OwnerId []string `protobuf:"bytes,5,rep,name=owner_id,json=ownerId,proto3" json:"owner_id,omitempty"`
-	Role    []string `protobuf:"bytes,6,rep,name=role,proto3" json:"role,omitempty"`
+	sizeCache     protoimpl.SizeCache
 }
 
 func (x *Filter) Reset() {
@@ -211,11 +225,10 @@ func (x *Filter) GetRole() []string {
 }
 
 type CreateRequest struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
+	state         protoimpl.MessageState `protogen:"open.v1"`
+	Invitation    *Invitation            `protobuf:"bytes,1,opt,name=invitation,proto3" json:"invitation,omitempty"`
 	unknownFields protoimpl.UnknownFields
-
-	Invitation *Invitation `protobuf:"bytes,1,opt,name=invitation,proto3" json:"invitation,omitempty"`
+	sizeCache     protoimpl.SizeCache
 }
 
 func (x *CreateRequest) Reset() {
@@ -256,11 +269,10 @@ func (x *CreateRequest) GetInvitation() *Invitation {
 }
 
 type CreateResponse struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
+	state         protoimpl.MessageState `protogen:"open.v1"`
+	Invitation    *Invitation            `protobuf:"bytes,1,opt,name=invitation,proto3" json:"invitation,omitempty"`
 	unknownFields protoimpl.UnknownFields
-
-	Invitation *Invitation `protobuf:"bytes,1,opt,name=invitation,proto3" json:"invitation,omitempty"`
+	sizeCache     protoimpl.SizeCache
 }
 
 func (x *CreateResponse) Reset() {
@@ -301,11 +313,10 @@ func (x *CreateResponse) GetInvitation() *Invitation {
 }
 
 type GetRequest struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
+	state         protoimpl.MessageState `protogen:"open.v1"`
+	InvitationId  string                 `protobuf:"bytes,1,opt,name=invitation_id,json=invitationId,proto3" json:"invitation_id,omitempty"`
 	unknownFields protoimpl.UnknownFields
-
-	InvitationId string `protobuf:"bytes,1,opt,name=invitation_id,json=invitationId,proto3" json:"invitation_id,omitempty"`
+	sizeCache     protoimpl.SizeCache
 }
 
 func (x *GetRequest) Reset() {
@@ -346,11 +357,10 @@ func (x *GetRequest) GetInvitationId() string {
 }
 
 type GetResponse struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
+	state         protoimpl.MessageState `protogen:"open.v1"`
+	Invitation    *Invitation            `protobuf:"bytes,1,opt,name=invitation,proto3" json:"invitation,omitempty"`
 	unknownFields protoimpl.UnknownFields
-
-	Invitation *Invitation `protobuf:"bytes,1,opt,name=invitation,proto3" json:"invitation,omitempty"`
+	sizeCache     protoimpl.SizeCache
 }
 
 func (x *GetResponse) Reset() {
@@ -391,15 +401,14 @@ func (x *GetResponse) GetInvitation() *Invitation {
 }
 
 type UpdateRequest struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
+	state         protoimpl.MessageState `protogen:"open.v1"`
+	InvitationId  string                 `protobuf:"bytes,1,opt,name=invitation_id,json=invitationId,proto3" json:"invitation_id,omitempty"`
+	Sent          *wrapperspb.BoolValue  `protobuf:"bytes,2,opt,name=sent,proto3" json:"sent,omitempty"`                               // Флаг отправки приглашения
+	Pending       *wrapperspb.BoolValue  `protobuf:"bytes,3,opt,name=pending,proto3" json:"pending,omitempty"`                         // Флаг принятия приглашения
+	SentAt        *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=sent_at,json=sentAt,proto3" json:"sent_at,omitempty"`             // Время отправки приглашения
+	ValidUntil    *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=valid_until,json=validUntil,proto3" json:"valid_until,omitempty"` // Время до которого приглашение действует
 	unknownFields protoimpl.UnknownFields
-
-	InvitationId string                 `protobuf:"bytes,1,opt,name=invitation_id,json=invitationId,proto3" json:"invitation_id,omitempty"`
-	Sent         *wrapperspb.BoolValue  `protobuf:"bytes,2,opt,name=sent,proto3" json:"sent,omitempty"`                               // Флаг отправки приглашения
-	Pending      *wrapperspb.BoolValue  `protobuf:"bytes,3,opt,name=pending,proto3" json:"pending,omitempty"`                         // Флаг принятия приглашения
-	SentAt       *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=sent_at,json=sentAt,proto3" json:"sent_at,omitempty"`             // Время отправки приглашения
-	ValidUntil   *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=valid_until,json=validUntil,proto3" json:"valid_until,omitempty"` // Время до которого приглашение действует
+	sizeCache     protoimpl.SizeCache
 }
 
 func (x *UpdateRequest) Reset() {
@@ -468,9 +477,9 @@ func (x *UpdateRequest) GetValidUntil() *timestamppb.Timestamp {
 }
 
 type UpdateInvitationResponse struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
+	state         protoimpl.MessageState `protogen:"open.v1"`
 	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
 }
 
 func (x *UpdateInvitationResponse) Reset() {
@@ -504,12 +513,11 @@ func (*UpdateInvitationResponse) Descriptor() ([]byte, []int) {
 }
 
 type AcceptRequest struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
+	state         protoimpl.MessageState `protogen:"open.v1"`
+	InvitationId  string                 `protobuf:"bytes,1,opt,name=invitation_id,json=invitationId,proto3" json:"invitation_id,omitempty"`
+	UserId        string                 `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
 	unknownFields protoimpl.UnknownFields
-
-	InvitationId string `protobuf:"bytes,1,opt,name=invitation_id,json=invitationId,proto3" json:"invitation_id,omitempty"`
-	UserId       string `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
+	sizeCache     protoimpl.SizeCache
 }
 
 func (x *AcceptRequest) Reset() {
@@ -557,9 +565,9 @@ func (x *AcceptRequest) GetUserId() string {
 }
 
 type AcceptInvitationResponse struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
+	state         protoimpl.MessageState `protogen:"open.v1"`
 	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
 }
 
 func (x *AcceptInvitationResponse) Reset() {
@@ -593,12 +601,11 @@ func (*AcceptInvitationResponse) Descriptor() ([]byte, []int) {
 }
 
 type FindRequest struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
+	state         protoimpl.MessageState `protogen:"open.v1"`
+	Filter        *Filter                `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"`
+	Options       *common.FindOptions    `protobuf:"bytes,3,opt,name=options,proto3" json:"options,omitempty"`
 	unknownFields protoimpl.UnknownFields
-
-	Filter  *Filter             `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"`
-	Options *common.FindOptions `protobuf:"bytes,3,opt,name=options,proto3" json:"options,omitempty"`
+	sizeCache     protoimpl.SizeCache
 }
 
 func (x *FindRequest) Reset() {
@@ -646,12 +653,11 @@ func (x *FindRequest) GetOptions() *common.FindOptions {
 }
 
 type FindResponse struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
+	state         protoimpl.MessageState `protogen:"open.v1"`
+	Invitations   []*Invitation          `protobuf:"bytes,1,rep,name=invitations,proto3" json:"invitations,omitempty"`
+	Total         int64                  `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"`
 	unknownFields protoimpl.UnknownFields
-
-	Invitations []*Invitation `protobuf:"bytes,1,rep,name=invitations,proto3" json:"invitations,omitempty"`
-	Total       int64         `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"`
+	sizeCache     protoimpl.SizeCache
 }
 
 func (x *FindResponse) Reset() {
@@ -699,11 +705,10 @@ func (x *FindResponse) GetTotal() int64 {
 }
 
 type DeleteRequest struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
+	state         protoimpl.MessageState `protogen:"open.v1"`
+	InvitationId  string                 `protobuf:"bytes,1,opt,name=invitation_id,json=invitationId,proto3" json:"invitation_id,omitempty"`
 	unknownFields protoimpl.UnknownFields
-
-	InvitationId string `protobuf:"bytes,1,opt,name=invitation_id,json=invitationId,proto3" json:"invitation_id,omitempty"`
+	sizeCache     protoimpl.SizeCache
 }
 
 func (x *DeleteRequest) Reset() {
@@ -744,9 +749,9 @@ func (x *DeleteRequest) GetInvitationId() string {
 }
 
 type DeleteSpaceInvitationResponse struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
+	state         protoimpl.MessageState `protogen:"open.v1"`
 	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
 }
 
 func (x *DeleteSpaceInvitationResponse) Reset() {
@@ -792,7 +797,7 @@ var file_invitations_invitations_proto_rawDesc = []byte{
 	0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
 	0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f,
 	0x74, 0x6f, 0x1a, 0x13, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
-	0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8b, 0x02, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x69,
+	0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xba, 0x02, 0x0a, 0x0a, 0x49, 0x6e, 0x76, 0x69,
 	0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
 	0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18,
 	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x15, 0x0a, 0x06,
@@ -809,108 +814,111 @@ var file_invitations_invitations_proto_rawDesc = []byte{
 	0x64, 0x5f, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
 	0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
 	0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x69, 0x64,
-	0x55, 0x6e, 0x74, 0x69, 0x6c, 0x22, 0x8f, 0x01, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72,
-	0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64,
-	0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52,
-	0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64,
-	0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x12, 0x19, 0x0a,
-	0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52,
-	0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x77, 0x6e, 0x65,
-	0x72, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x77, 0x6e, 0x65,
-	0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x03, 0x28,
-	0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x50, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74,
-	0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x0a, 0x69, 0x6e, 0x76, 0x69,
-	0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63,
-	0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f,
-	0x6e, 0x73, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x69,
-	0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x51, 0x0a, 0x0e, 0x43, 0x72, 0x65,
-	0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0a, 0x69,
-	0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-	0x52, 0x0a, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x31, 0x0a, 0x0a,
-	0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e,
+	0x55, 0x6e, 0x74, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x73, 0x18, 0x09, 0x20,
+	0x01, 0x28, 0x0d, 0x52, 0x04, 0x75, 0x73, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78,
+	0x5f, 0x75, 0x73, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x6d, 0x61, 0x78,
+	0x55, 0x73, 0x65, 0x73, 0x22, 0x8f, 0x01, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12,
+	0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12,
+	0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05,
+	0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x15, 0x0a, 0x06, 0x6f, 0x72, 0x67, 0x5f, 0x69, 0x64, 0x18,
+	0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08,
+	0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07,
+	0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x77, 0x6e, 0x65, 0x72,
+	0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x77, 0x6e, 0x65, 0x72,
+	0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09,
+	0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x22, 0x50, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x0a, 0x69, 0x6e, 0x76, 0x69, 0x74,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6f,
+	0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+	0x73, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x69, 0x6e,
+	0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x51, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61,
+	0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0a, 0x69, 0x6e,
+	0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f,
+	0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+	0x0a, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x31, 0x0a, 0x0a, 0x47,
+	0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x76,
+	0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x0c, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x4e,
+	0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a,
+	0x0a, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6e, 0x76, 0x69,
+	0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x52, 0x0a, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x8c,
+	0x02, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69,
+	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52,
+	0x04, 0x73, 0x65, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x07, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c,
+	0x75, 0x65, 0x52, 0x07, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x33, 0x0a, 0x07, 0x73,
+	0x65, 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67,
+	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54,
+	0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x74, 0x41, 0x74,
+	0x12, 0x3b, 0x0a, 0x0b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x18,
+	0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
+	0x70, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x55, 0x6e, 0x74, 0x69, 0x6c, 0x22, 0x1a, 0x0a,
+	0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4d, 0x0a, 0x0d, 0x41, 0x63, 0x63,
+	0x65, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e,
 	0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x0c, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22,
-	0x4e, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f,
-	0x0a, 0x0a, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6e, 0x76,
-	0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74,
-	0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22,
-	0x8c, 0x02, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x09, 0x52, 0x0c, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12,
+	0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x1a, 0x0a, 0x18, 0x41, 0x63, 0x63, 0x65,
+	0x70, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x71, 0x0a, 0x0b, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x12, 0x33, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6e,
+	0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72,
+	0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x2d, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69,
+	0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
+	0x6f, 0x6e, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07,
+	0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x67, 0x0a, 0x0c, 0x46, 0x69, 0x6e, 0x64, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0b, 0x69, 0x6e, 0x76, 0x69, 0x74,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63,
+	0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x73, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x69,
+	0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f,
+	0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c,
+	0x22, 0x34, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
 	0x74, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f,
 	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65,
-	0x52, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x07, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e,
-	0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61,
-	0x6c, 0x75, 0x65, 0x52, 0x07, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x33, 0x0a, 0x07,
-	0x73, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
-	0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
-	0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x74, 0x41,
-	0x74, 0x12, 0x3b, 0x0a, 0x0b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x75, 0x6e, 0x74, 0x69, 0x6c,
-	0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
-	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
-	0x6d, 0x70, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x55, 0x6e, 0x74, 0x69, 0x6c, 0x22, 0x1a,
-	0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69,
-	0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4d, 0x0a, 0x0d, 0x41, 0x63,
-	0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x69,
-	0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x0c, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64,
-	0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x1a, 0x0a, 0x18, 0x41, 0x63, 0x63,
-	0x65, 0x70, 0x74, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x71, 0x0a, 0x0b, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x12, 0x33, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69,
-	0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65,
-	0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x2d, 0x0a, 0x07, 0x6f, 0x70, 0x74,
-	0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d,
-	0x6d, 0x6f, 0x6e, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52,
-	0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x67, 0x0a, 0x0c, 0x46, 0x69, 0x6e, 0x64,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0b, 0x69, 0x6e, 0x76, 0x69,
-	0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e,
-	0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69,
-	0x6f, 0x6e, 0x73, 0x2e, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b,
-	0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74,
-	0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61,
-	0x6c, 0x22, 0x34, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-	0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x6e, 0x76, 0x69, 0x74,
-	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x1f, 0x0a, 0x1d, 0x44, 0x65, 0x6c, 0x65, 0x74,
-	0x65, 0x53, 0x70, 0x61, 0x63, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x8d, 0x03, 0x0a, 0x0b, 0x49, 0x6e, 0x76,
-	0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x53, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61,
-	0x74, 0x65, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6e, 0x76,
-	0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
-	0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x43, 0x72, 0x65,
-	0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4a, 0x0a,
-	0x03, 0x47, 0x65, 0x74, 0x12, 0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69,
+	0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x1f, 0x0a, 0x1d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
+	0x53, 0x70, 0x61, 0x63, 0x65, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x8d, 0x03, 0x0a, 0x0b, 0x49, 0x6e, 0x76, 0x69,
+	0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x53, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74,
+	0x65, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6e, 0x76, 0x69,
+	0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e,
+	0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61,
+	0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4a, 0x0a, 0x03,
+	0x47, 0x65, 0x74, 0x12, 0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6e,
+	0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69,
 	0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e,
-	0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x06, 0x41, 0x63, 0x63,
-	0x65, 0x70, 0x74, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6e,
-	0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22,
-	0x00, 0x12, 0x4d, 0x0a, 0x04, 0x46, 0x69, 0x6e, 0x64, 0x12, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
-	0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e,
-	0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x63, 0x6f,
-	0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-	0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
-	0x12, 0x46, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x6e,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x06, 0x41, 0x63, 0x63, 0x65,
+	0x70, 0x74, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6e, 0x76,
+	0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00,
+	0x12, 0x4d, 0x0a, 0x04, 0x46, 0x69, 0x6e, 0x64, 0x12, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65,
+	0x6e, 0x74, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x46,
+	0x69, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x63, 0x6f, 0x6e,
 	0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
-	0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16,
-	0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
-	0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x3c, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x2e,
-	0x70, 0x65, 0x72, 0x78, 0x2e, 0x72, 0x75, 0x2f, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2f, 0x70,
-	0x65, 0x72, 0x78, 0x69, 0x73, 0x2d, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x69,
-	0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3b, 0x69, 0x6e, 0x76, 0x69, 0x74,
-	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x2e, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
+	0x46, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
+	0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e,
+	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e,
+	0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
+	0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x3c, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x2e, 0x70,
+	0x65, 0x72, 0x78, 0x2e, 0x72, 0x75, 0x2f, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2f, 0x70, 0x65,
+	0x72, 0x78, 0x69, 0x73, 0x2d, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x69, 0x6e,
+	0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3b, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
diff --git a/proto/invitations/invitations_grpc.pb.go b/proto/invitations/invitations_grpc.pb.go
index a2d39c524cc4b0e35889de2415f9cd8e1f067967..1f5c5ca5f1b5e2b3658b9ab9b098dec80d8a6024 100644
--- a/proto/invitations/invitations_grpc.pb.go
+++ b/proto/invitations/invitations_grpc.pb.go
@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
 // versions:
 // - protoc-gen-go-grpc v1.5.1
-// - protoc             v5.28.3
+// - protoc             v5.29.2
 // source: invitations/invitations.proto
 
 package invitations
diff --git a/proto/items/items.pb.go b/proto/items/items.pb.go
index 92f2455279996d314d9906ce3c9d181204e230ac..f62b1979fbc49ba99221176559c8df15d16365e7 100644
--- a/proto/items/items.pb.go
+++ b/proto/items/items.pb.go
@@ -1692,6 +1692,59 @@ func (x *GetRevisionOptions) GetTranslationsIds() []string {
 	return nil
 }
 
+type GetArchivedOptions struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	LocaleId        string   `protobuf:"bytes,7,opt,name=locale_id,json=localeId,proto3" json:"locale_id,omitempty"`                      // Язык перевода который будет использоваться. Если не указан, то возвращаются данные для языка по умолчанию
+	TranslationsIds []string `protobuf:"bytes,8,rep,name=translations_ids,json=translationsIds,proto3" json:"translations_ids,omitempty"` // Список идентификаторов переводов/локалей, которых должны быть включены в результат
+}
+
+func (x *GetArchivedOptions) Reset() {
+	*x = GetArchivedOptions{}
+	mi := &file_items_items_proto_msgTypes[24]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *GetArchivedOptions) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetArchivedOptions) ProtoMessage() {}
+
+func (x *GetArchivedOptions) ProtoReflect() protoreflect.Message {
+	mi := &file_items_items_proto_msgTypes[24]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetArchivedOptions.ProtoReflect.Descriptor instead.
+func (*GetArchivedOptions) Descriptor() ([]byte, []int) {
+	return file_items_items_proto_rawDescGZIP(), []int{24}
+}
+
+func (x *GetArchivedOptions) GetLocaleId() string {
+	if x != nil {
+		return x.LocaleId
+	}
+	return ""
+}
+
+func (x *GetArchivedOptions) GetTranslationsIds() []string {
+	if x != nil {
+		return x.TranslationsIds
+	}
+	return nil
+}
+
 // Fields - поля которые должны быть возвращены или вычислены в результате.
 // Ключ (string) - имя поля под которым будет добавляться результат.
 // Значение (string) - является выражением, вычисление которого сформирует результат
@@ -1713,7 +1766,7 @@ type AggregateOptions struct {
 
 func (x *AggregateOptions) Reset() {
 	*x = AggregateOptions{}
-	mi := &file_items_items_proto_msgTypes[24]
+	mi := &file_items_items_proto_msgTypes[25]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1725,7 +1778,7 @@ func (x *AggregateOptions) String() string {
 func (*AggregateOptions) ProtoMessage() {}
 
 func (x *AggregateOptions) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[24]
+	mi := &file_items_items_proto_msgTypes[25]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1738,7 +1791,7 @@ func (x *AggregateOptions) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use AggregateOptions.ProtoReflect.Descriptor instead.
 func (*AggregateOptions) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{24}
+	return file_items_items_proto_rawDescGZIP(), []int{25}
 }
 
 func (x *AggregateOptions) GetFields() map[string]string {
@@ -1758,7 +1811,7 @@ type AggregatePublishedOptions struct {
 
 func (x *AggregatePublishedOptions) Reset() {
 	*x = AggregatePublishedOptions{}
-	mi := &file_items_items_proto_msgTypes[25]
+	mi := &file_items_items_proto_msgTypes[26]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1770,7 +1823,7 @@ func (x *AggregatePublishedOptions) String() string {
 func (*AggregatePublishedOptions) ProtoMessage() {}
 
 func (x *AggregatePublishedOptions) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[25]
+	mi := &file_items_items_proto_msgTypes[26]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1783,7 +1836,7 @@ func (x *AggregatePublishedOptions) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use AggregatePublishedOptions.ProtoReflect.Descriptor instead.
 func (*AggregatePublishedOptions) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{25}
+	return file_items_items_proto_rawDescGZIP(), []int{26}
 }
 
 func (x *AggregatePublishedOptions) GetFields() map[string]string {
@@ -1804,7 +1857,7 @@ type CreateRequest struct {
 
 func (x *CreateRequest) Reset() {
 	*x = CreateRequest{}
-	mi := &file_items_items_proto_msgTypes[26]
+	mi := &file_items_items_proto_msgTypes[27]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1816,7 +1869,7 @@ func (x *CreateRequest) String() string {
 func (*CreateRequest) ProtoMessage() {}
 
 func (x *CreateRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[26]
+	mi := &file_items_items_proto_msgTypes[27]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1829,7 +1882,7 @@ func (x *CreateRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateRequest.ProtoReflect.Descriptor instead.
 func (*CreateRequest) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{26}
+	return file_items_items_proto_rawDescGZIP(), []int{27}
 }
 
 func (x *CreateRequest) GetItem() *Item {
@@ -1856,7 +1909,7 @@ type CreateResponse struct {
 
 func (x *CreateResponse) Reset() {
 	*x = CreateResponse{}
-	mi := &file_items_items_proto_msgTypes[27]
+	mi := &file_items_items_proto_msgTypes[28]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1868,7 +1921,7 @@ func (x *CreateResponse) String() string {
 func (*CreateResponse) ProtoMessage() {}
 
 func (x *CreateResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[27]
+	mi := &file_items_items_proto_msgTypes[28]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1881,7 +1934,7 @@ func (x *CreateResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CreateResponse.ProtoReflect.Descriptor instead.
 func (*CreateResponse) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{27}
+	return file_items_items_proto_rawDescGZIP(), []int{28}
 }
 
 func (x *CreateResponse) GetCreated() *Item {
@@ -1901,7 +1954,7 @@ type IntrospectRequest struct {
 
 func (x *IntrospectRequest) Reset() {
 	*x = IntrospectRequest{}
-	mi := &file_items_items_proto_msgTypes[28]
+	mi := &file_items_items_proto_msgTypes[29]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1913,7 +1966,7 @@ func (x *IntrospectRequest) String() string {
 func (*IntrospectRequest) ProtoMessage() {}
 
 func (x *IntrospectRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[28]
+	mi := &file_items_items_proto_msgTypes[29]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1926,7 +1979,7 @@ func (x *IntrospectRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use IntrospectRequest.ProtoReflect.Descriptor instead.
 func (*IntrospectRequest) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{28}
+	return file_items_items_proto_rawDescGZIP(), []int{29}
 }
 
 func (x *IntrospectRequest) GetItem() *Item {
@@ -1948,7 +2001,7 @@ type IntrospectResponse struct {
 
 func (x *IntrospectResponse) Reset() {
 	*x = IntrospectResponse{}
-	mi := &file_items_items_proto_msgTypes[29]
+	mi := &file_items_items_proto_msgTypes[30]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -1960,7 +2013,7 @@ func (x *IntrospectResponse) String() string {
 func (*IntrospectResponse) ProtoMessage() {}
 
 func (x *IntrospectResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[29]
+	mi := &file_items_items_proto_msgTypes[30]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1973,7 +2026,7 @@ func (x *IntrospectResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use IntrospectResponse.ProtoReflect.Descriptor instead.
 func (*IntrospectResponse) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{29}
+	return file_items_items_proto_rawDescGZIP(), []int{30}
 }
 
 func (x *IntrospectResponse) GetItem() *Item {
@@ -2008,7 +2061,7 @@ type GetOptions struct {
 
 func (x *GetOptions) Reset() {
 	*x = GetOptions{}
-	mi := &file_items_items_proto_msgTypes[30]
+	mi := &file_items_items_proto_msgTypes[31]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -2020,7 +2073,7 @@ func (x *GetOptions) String() string {
 func (*GetOptions) ProtoMessage() {}
 
 func (x *GetOptions) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[30]
+	mi := &file_items_items_proto_msgTypes[31]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2033,7 +2086,7 @@ func (x *GetOptions) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetOptions.ProtoReflect.Descriptor instead.
 func (*GetOptions) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{30}
+	return file_items_items_proto_rawDescGZIP(), []int{31}
 }
 
 func (x *GetOptions) GetLocaleId() string {
@@ -2064,7 +2117,7 @@ type GetRequest struct {
 
 func (x *GetRequest) Reset() {
 	*x = GetRequest{}
-	mi := &file_items_items_proto_msgTypes[31]
+	mi := &file_items_items_proto_msgTypes[32]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -2076,7 +2129,7 @@ func (x *GetRequest) String() string {
 func (*GetRequest) ProtoMessage() {}
 
 func (x *GetRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[31]
+	mi := &file_items_items_proto_msgTypes[32]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2089,7 +2142,7 @@ func (x *GetRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetRequest.ProtoReflect.Descriptor instead.
 func (*GetRequest) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{31}
+	return file_items_items_proto_rawDescGZIP(), []int{32}
 }
 
 func (x *GetRequest) GetSpaceId() string {
@@ -2137,7 +2190,7 @@ type GetResponse struct {
 
 func (x *GetResponse) Reset() {
 	*x = GetResponse{}
-	mi := &file_items_items_proto_msgTypes[32]
+	mi := &file_items_items_proto_msgTypes[33]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -2149,7 +2202,7 @@ func (x *GetResponse) String() string {
 func (*GetResponse) ProtoMessage() {}
 
 func (x *GetResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[32]
+	mi := &file_items_items_proto_msgTypes[33]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2162,7 +2215,7 @@ func (x *GetResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetResponse.ProtoReflect.Descriptor instead.
 func (*GetResponse) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{32}
+	return file_items_items_proto_rawDescGZIP(), []int{33}
 }
 
 func (x *GetResponse) GetItem() *Item {
@@ -2186,7 +2239,7 @@ type FindRequest struct {
 
 func (x *FindRequest) Reset() {
 	*x = FindRequest{}
-	mi := &file_items_items_proto_msgTypes[33]
+	mi := &file_items_items_proto_msgTypes[34]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -2198,7 +2251,7 @@ func (x *FindRequest) String() string {
 func (*FindRequest) ProtoMessage() {}
 
 func (x *FindRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[33]
+	mi := &file_items_items_proto_msgTypes[34]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2211,7 +2264,7 @@ func (x *FindRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use FindRequest.ProtoReflect.Descriptor instead.
 func (*FindRequest) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{33}
+	return file_items_items_proto_rawDescGZIP(), []int{34}
 }
 
 func (x *FindRequest) GetSpaceId() string {
@@ -2260,7 +2313,7 @@ type FindResponse struct {
 
 func (x *FindResponse) Reset() {
 	*x = FindResponse{}
-	mi := &file_items_items_proto_msgTypes[34]
+	mi := &file_items_items_proto_msgTypes[35]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -2272,7 +2325,7 @@ func (x *FindResponse) String() string {
 func (*FindResponse) ProtoMessage() {}
 
 func (x *FindResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[34]
+	mi := &file_items_items_proto_msgTypes[35]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2285,7 +2338,7 @@ func (x *FindResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use FindResponse.ProtoReflect.Descriptor instead.
 func (*FindResponse) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{34}
+	return file_items_items_proto_rawDescGZIP(), []int{35}
 }
 
 func (x *FindResponse) GetItems() []*Item {
@@ -2313,7 +2366,7 @@ type UpdateRequest struct {
 
 func (x *UpdateRequest) Reset() {
 	*x = UpdateRequest{}
-	mi := &file_items_items_proto_msgTypes[35]
+	mi := &file_items_items_proto_msgTypes[36]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -2325,7 +2378,7 @@ func (x *UpdateRequest) String() string {
 func (*UpdateRequest) ProtoMessage() {}
 
 func (x *UpdateRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[35]
+	mi := &file_items_items_proto_msgTypes[36]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2338,7 +2391,7 @@ func (x *UpdateRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UpdateRequest.ProtoReflect.Descriptor instead.
 func (*UpdateRequest) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{35}
+	return file_items_items_proto_rawDescGZIP(), []int{36}
 }
 
 func (x *UpdateRequest) GetItem() *Item {
@@ -2366,7 +2419,7 @@ type DeleteRequest struct {
 
 func (x *DeleteRequest) Reset() {
 	*x = DeleteRequest{}
-	mi := &file_items_items_proto_msgTypes[36]
+	mi := &file_items_items_proto_msgTypes[37]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -2378,7 +2431,7 @@ func (x *DeleteRequest) String() string {
 func (*DeleteRequest) ProtoMessage() {}
 
 func (x *DeleteRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[36]
+	mi := &file_items_items_proto_msgTypes[37]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2391,7 +2444,7 @@ func (x *DeleteRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DeleteRequest.ProtoReflect.Descriptor instead.
 func (*DeleteRequest) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{36}
+	return file_items_items_proto_rawDescGZIP(), []int{37}
 }
 
 func (x *DeleteRequest) GetItem() *Item {
@@ -2419,7 +2472,7 @@ type UndeleteRequest struct {
 
 func (x *UndeleteRequest) Reset() {
 	*x = UndeleteRequest{}
-	mi := &file_items_items_proto_msgTypes[37]
+	mi := &file_items_items_proto_msgTypes[38]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -2431,7 +2484,7 @@ func (x *UndeleteRequest) String() string {
 func (*UndeleteRequest) ProtoMessage() {}
 
 func (x *UndeleteRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[37]
+	mi := &file_items_items_proto_msgTypes[38]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2444,7 +2497,7 @@ func (x *UndeleteRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UndeleteRequest.ProtoReflect.Descriptor instead.
 func (*UndeleteRequest) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{37}
+	return file_items_items_proto_rawDescGZIP(), []int{38}
 }
 
 func (x *UndeleteRequest) GetItem() *Item {
@@ -2475,7 +2528,7 @@ type CheckoutRevisionRequest struct {
 
 func (x *CheckoutRevisionRequest) Reset() {
 	*x = CheckoutRevisionRequest{}
-	mi := &file_items_items_proto_msgTypes[38]
+	mi := &file_items_items_proto_msgTypes[39]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -2487,7 +2540,7 @@ func (x *CheckoutRevisionRequest) String() string {
 func (*CheckoutRevisionRequest) ProtoMessage() {}
 
 func (x *CheckoutRevisionRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[38]
+	mi := &file_items_items_proto_msgTypes[39]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2500,7 +2553,7 @@ func (x *CheckoutRevisionRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CheckoutRevisionRequest.ProtoReflect.Descriptor instead.
 func (*CheckoutRevisionRequest) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{38}
+	return file_items_items_proto_rawDescGZIP(), []int{39}
 }
 
 func (x *CheckoutRevisionRequest) GetSpaceId() string {
@@ -2548,7 +2601,7 @@ type CheckoutRevisionResponse struct {
 
 func (x *CheckoutRevisionResponse) Reset() {
 	*x = CheckoutRevisionResponse{}
-	mi := &file_items_items_proto_msgTypes[39]
+	mi := &file_items_items_proto_msgTypes[40]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -2560,7 +2613,7 @@ func (x *CheckoutRevisionResponse) String() string {
 func (*CheckoutRevisionResponse) ProtoMessage() {}
 
 func (x *CheckoutRevisionResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[39]
+	mi := &file_items_items_proto_msgTypes[40]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2573,7 +2626,7 @@ func (x *CheckoutRevisionResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use CheckoutRevisionResponse.ProtoReflect.Descriptor instead.
 func (*CheckoutRevisionResponse) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{39}
+	return file_items_items_proto_rawDescGZIP(), []int{40}
 }
 
 func (x *CheckoutRevisionResponse) GetStoredRevisionId() string {
@@ -2594,7 +2647,7 @@ type PublishRequest struct {
 
 func (x *PublishRequest) Reset() {
 	*x = PublishRequest{}
-	mi := &file_items_items_proto_msgTypes[40]
+	mi := &file_items_items_proto_msgTypes[41]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -2606,7 +2659,7 @@ func (x *PublishRequest) String() string {
 func (*PublishRequest) ProtoMessage() {}
 
 func (x *PublishRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[40]
+	mi := &file_items_items_proto_msgTypes[41]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2619,7 +2672,7 @@ func (x *PublishRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use PublishRequest.ProtoReflect.Descriptor instead.
 func (*PublishRequest) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{40}
+	return file_items_items_proto_rawDescGZIP(), []int{41}
 }
 
 func (x *PublishRequest) GetItem() *Item {
@@ -2647,7 +2700,7 @@ type UnpublishRequest struct {
 
 func (x *UnpublishRequest) Reset() {
 	*x = UnpublishRequest{}
-	mi := &file_items_items_proto_msgTypes[41]
+	mi := &file_items_items_proto_msgTypes[42]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -2659,7 +2712,7 @@ func (x *UnpublishRequest) String() string {
 func (*UnpublishRequest) ProtoMessage() {}
 
 func (x *UnpublishRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[41]
+	mi := &file_items_items_proto_msgTypes[42]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2672,7 +2725,7 @@ func (x *UnpublishRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UnpublishRequest.ProtoReflect.Descriptor instead.
 func (*UnpublishRequest) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{41}
+	return file_items_items_proto_rawDescGZIP(), []int{42}
 }
 
 func (x *UnpublishRequest) GetItem() *Item {
@@ -2703,7 +2756,7 @@ type GetPublishedRequest struct {
 
 func (x *GetPublishedRequest) Reset() {
 	*x = GetPublishedRequest{}
-	mi := &file_items_items_proto_msgTypes[42]
+	mi := &file_items_items_proto_msgTypes[43]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -2715,7 +2768,7 @@ func (x *GetPublishedRequest) String() string {
 func (*GetPublishedRequest) ProtoMessage() {}
 
 func (x *GetPublishedRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[42]
+	mi := &file_items_items_proto_msgTypes[43]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2728,7 +2781,7 @@ func (x *GetPublishedRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetPublishedRequest.ProtoReflect.Descriptor instead.
 func (*GetPublishedRequest) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{42}
+	return file_items_items_proto_rawDescGZIP(), []int{43}
 }
 
 func (x *GetPublishedRequest) GetSpaceId() string {
@@ -2776,7 +2829,7 @@ type GetPublishedResponse struct {
 
 func (x *GetPublishedResponse) Reset() {
 	*x = GetPublishedResponse{}
-	mi := &file_items_items_proto_msgTypes[43]
+	mi := &file_items_items_proto_msgTypes[44]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -2788,7 +2841,7 @@ func (x *GetPublishedResponse) String() string {
 func (*GetPublishedResponse) ProtoMessage() {}
 
 func (x *GetPublishedResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[43]
+	mi := &file_items_items_proto_msgTypes[44]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2801,7 +2854,7 @@ func (x *GetPublishedResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetPublishedResponse.ProtoReflect.Descriptor instead.
 func (*GetPublishedResponse) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{43}
+	return file_items_items_proto_rawDescGZIP(), []int{44}
 }
 
 func (x *GetPublishedResponse) GetItem() *Item {
@@ -2825,7 +2878,7 @@ type FindPublishedRequest struct {
 
 func (x *FindPublishedRequest) Reset() {
 	*x = FindPublishedRequest{}
-	mi := &file_items_items_proto_msgTypes[44]
+	mi := &file_items_items_proto_msgTypes[45]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -2837,7 +2890,7 @@ func (x *FindPublishedRequest) String() string {
 func (*FindPublishedRequest) ProtoMessage() {}
 
 func (x *FindPublishedRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[44]
+	mi := &file_items_items_proto_msgTypes[45]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2850,7 +2903,7 @@ func (x *FindPublishedRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use FindPublishedRequest.ProtoReflect.Descriptor instead.
 func (*FindPublishedRequest) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{44}
+	return file_items_items_proto_rawDescGZIP(), []int{45}
 }
 
 func (x *FindPublishedRequest) GetSpaceId() string {
@@ -2899,7 +2952,7 @@ type FindPublishedResponse struct {
 
 func (x *FindPublishedResponse) Reset() {
 	*x = FindPublishedResponse{}
-	mi := &file_items_items_proto_msgTypes[45]
+	mi := &file_items_items_proto_msgTypes[46]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -2911,7 +2964,7 @@ func (x *FindPublishedResponse) String() string {
 func (*FindPublishedResponse) ProtoMessage() {}
 
 func (x *FindPublishedResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[45]
+	mi := &file_items_items_proto_msgTypes[46]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2924,7 +2977,7 @@ func (x *FindPublishedResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use FindPublishedResponse.ProtoReflect.Descriptor instead.
 func (*FindPublishedResponse) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{45}
+	return file_items_items_proto_rawDescGZIP(), []int{46}
 }
 
 func (x *FindPublishedResponse) GetItems() []*Item {
@@ -2955,7 +3008,7 @@ type AggregateRequest struct {
 
 func (x *AggregateRequest) Reset() {
 	*x = AggregateRequest{}
-	mi := &file_items_items_proto_msgTypes[46]
+	mi := &file_items_items_proto_msgTypes[47]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -2967,7 +3020,7 @@ func (x *AggregateRequest) String() string {
 func (*AggregateRequest) ProtoMessage() {}
 
 func (x *AggregateRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[46]
+	mi := &file_items_items_proto_msgTypes[47]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2980,7 +3033,7 @@ func (x *AggregateRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use AggregateRequest.ProtoReflect.Descriptor instead.
 func (*AggregateRequest) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{46}
+	return file_items_items_proto_rawDescGZIP(), []int{47}
 }
 
 func (x *AggregateRequest) GetSpaceId() string {
@@ -3030,7 +3083,7 @@ type AggregateResponse struct {
 
 func (x *AggregateResponse) Reset() {
 	*x = AggregateResponse{}
-	mi := &file_items_items_proto_msgTypes[47]
+	mi := &file_items_items_proto_msgTypes[48]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -3042,7 +3095,7 @@ func (x *AggregateResponse) String() string {
 func (*AggregateResponse) ProtoMessage() {}
 
 func (x *AggregateResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[47]
+	mi := &file_items_items_proto_msgTypes[48]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3055,7 +3108,7 @@ func (x *AggregateResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use AggregateResponse.ProtoReflect.Descriptor instead.
 func (*AggregateResponse) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{47}
+	return file_items_items_proto_rawDescGZIP(), []int{48}
 }
 
 func (x *AggregateResponse) GetResult() *structpb.Struct {
@@ -3079,7 +3132,7 @@ type AggregatePublishedRequest struct {
 
 func (x *AggregatePublishedRequest) Reset() {
 	*x = AggregatePublishedRequest{}
-	mi := &file_items_items_proto_msgTypes[48]
+	mi := &file_items_items_proto_msgTypes[49]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -3091,7 +3144,7 @@ func (x *AggregatePublishedRequest) String() string {
 func (*AggregatePublishedRequest) ProtoMessage() {}
 
 func (x *AggregatePublishedRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[48]
+	mi := &file_items_items_proto_msgTypes[49]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3104,7 +3157,7 @@ func (x *AggregatePublishedRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use AggregatePublishedRequest.ProtoReflect.Descriptor instead.
 func (*AggregatePublishedRequest) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{48}
+	return file_items_items_proto_rawDescGZIP(), []int{49}
 }
 
 func (x *AggregatePublishedRequest) GetSpaceId() string {
@@ -3152,7 +3205,7 @@ type AggregatePublishedResponse struct {
 
 func (x *AggregatePublishedResponse) Reset() {
 	*x = AggregatePublishedResponse{}
-	mi := &file_items_items_proto_msgTypes[49]
+	mi := &file_items_items_proto_msgTypes[50]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -3164,7 +3217,7 @@ func (x *AggregatePublishedResponse) String() string {
 func (*AggregatePublishedResponse) ProtoMessage() {}
 
 func (x *AggregatePublishedResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[49]
+	mi := &file_items_items_proto_msgTypes[50]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3177,7 +3230,7 @@ func (x *AggregatePublishedResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use AggregatePublishedResponse.ProtoReflect.Descriptor instead.
 func (*AggregatePublishedResponse) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{49}
+	return file_items_items_proto_rawDescGZIP(), []int{50}
 }
 
 func (x *AggregatePublishedResponse) GetResult() *structpb.Struct {
@@ -3202,7 +3255,7 @@ type GetRevisionRequest struct {
 
 func (x *GetRevisionRequest) Reset() {
 	*x = GetRevisionRequest{}
-	mi := &file_items_items_proto_msgTypes[50]
+	mi := &file_items_items_proto_msgTypes[51]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -3214,7 +3267,7 @@ func (x *GetRevisionRequest) String() string {
 func (*GetRevisionRequest) ProtoMessage() {}
 
 func (x *GetRevisionRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[50]
+	mi := &file_items_items_proto_msgTypes[51]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3227,7 +3280,7 @@ func (x *GetRevisionRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetRevisionRequest.ProtoReflect.Descriptor instead.
 func (*GetRevisionRequest) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{50}
+	return file_items_items_proto_rawDescGZIP(), []int{51}
 }
 
 func (x *GetRevisionRequest) GetSpaceId() string {
@@ -3282,7 +3335,7 @@ type GetRevisionResponse struct {
 
 func (x *GetRevisionResponse) Reset() {
 	*x = GetRevisionResponse{}
-	mi := &file_items_items_proto_msgTypes[51]
+	mi := &file_items_items_proto_msgTypes[52]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -3294,7 +3347,7 @@ func (x *GetRevisionResponse) String() string {
 func (*GetRevisionResponse) ProtoMessage() {}
 
 func (x *GetRevisionResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[51]
+	mi := &file_items_items_proto_msgTypes[52]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3307,7 +3360,7 @@ func (x *GetRevisionResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use GetRevisionResponse.ProtoReflect.Descriptor instead.
 func (*GetRevisionResponse) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{51}
+	return file_items_items_proto_rawDescGZIP(), []int{52}
 }
 
 func (x *GetRevisionResponse) GetItem() *Item {
@@ -3331,7 +3384,7 @@ type ListRevisionsRequest struct {
 
 func (x *ListRevisionsRequest) Reset() {
 	*x = ListRevisionsRequest{}
-	mi := &file_items_items_proto_msgTypes[52]
+	mi := &file_items_items_proto_msgTypes[53]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -3343,7 +3396,7 @@ func (x *ListRevisionsRequest) String() string {
 func (*ListRevisionsRequest) ProtoMessage() {}
 
 func (x *ListRevisionsRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[52]
+	mi := &file_items_items_proto_msgTypes[53]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3356,7 +3409,7 @@ func (x *ListRevisionsRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListRevisionsRequest.ProtoReflect.Descriptor instead.
 func (*ListRevisionsRequest) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{52}
+	return file_items_items_proto_rawDescGZIP(), []int{53}
 }
 
 func (x *ListRevisionsRequest) GetSpaceId() string {
@@ -3405,7 +3458,7 @@ type ListRevisionsResponse struct {
 
 func (x *ListRevisionsResponse) Reset() {
 	*x = ListRevisionsResponse{}
-	mi := &file_items_items_proto_msgTypes[53]
+	mi := &file_items_items_proto_msgTypes[54]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -3417,7 +3470,7 @@ func (x *ListRevisionsResponse) String() string {
 func (*ListRevisionsResponse) ProtoMessage() {}
 
 func (x *ListRevisionsResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[53]
+	mi := &file_items_items_proto_msgTypes[54]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3430,7 +3483,7 @@ func (x *ListRevisionsResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ListRevisionsResponse.ProtoReflect.Descriptor instead.
 func (*ListRevisionsResponse) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{53}
+	return file_items_items_proto_rawDescGZIP(), []int{54}
 }
 
 func (x *ListRevisionsResponse) GetItems() []*Item {
@@ -3459,7 +3512,7 @@ type ArchiveRequest struct {
 
 func (x *ArchiveRequest) Reset() {
 	*x = ArchiveRequest{}
-	mi := &file_items_items_proto_msgTypes[54]
+	mi := &file_items_items_proto_msgTypes[55]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -3471,7 +3524,7 @@ func (x *ArchiveRequest) String() string {
 func (*ArchiveRequest) ProtoMessage() {}
 
 func (x *ArchiveRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[54]
+	mi := &file_items_items_proto_msgTypes[55]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3484,7 +3537,7 @@ func (x *ArchiveRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ArchiveRequest.ProtoReflect.Descriptor instead.
 func (*ArchiveRequest) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{54}
+	return file_items_items_proto_rawDescGZIP(), []int{55}
 }
 
 func (x *ArchiveRequest) GetItem() *Item {
@@ -3504,7 +3557,7 @@ type UnarchiveRequest struct {
 
 func (x *UnarchiveRequest) Reset() {
 	*x = UnarchiveRequest{}
-	mi := &file_items_items_proto_msgTypes[55]
+	mi := &file_items_items_proto_msgTypes[56]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -3516,7 +3569,7 @@ func (x *UnarchiveRequest) String() string {
 func (*UnarchiveRequest) ProtoMessage() {}
 
 func (x *UnarchiveRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[55]
+	mi := &file_items_items_proto_msgTypes[56]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3529,7 +3582,7 @@ func (x *UnarchiveRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UnarchiveRequest.ProtoReflect.Descriptor instead.
 func (*UnarchiveRequest) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{55}
+	return file_items_items_proto_rawDescGZIP(), []int{56}
 }
 
 func (x *UnarchiveRequest) GetItem() *Item {
@@ -3553,7 +3606,7 @@ type FindArchivedRequest struct {
 
 func (x *FindArchivedRequest) Reset() {
 	*x = FindArchivedRequest{}
-	mi := &file_items_items_proto_msgTypes[56]
+	mi := &file_items_items_proto_msgTypes[57]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -3565,7 +3618,7 @@ func (x *FindArchivedRequest) String() string {
 func (*FindArchivedRequest) ProtoMessage() {}
 
 func (x *FindArchivedRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[56]
+	mi := &file_items_items_proto_msgTypes[57]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3578,7 +3631,7 @@ func (x *FindArchivedRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use FindArchivedRequest.ProtoReflect.Descriptor instead.
 func (*FindArchivedRequest) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{56}
+	return file_items_items_proto_rawDescGZIP(), []int{57}
 }
 
 func (x *FindArchivedRequest) GetSpaceId() string {
@@ -3627,7 +3680,7 @@ type FindArchivedResponse struct {
 
 func (x *FindArchivedResponse) Reset() {
 	*x = FindArchivedResponse{}
-	mi := &file_items_items_proto_msgTypes[57]
+	mi := &file_items_items_proto_msgTypes[58]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -3639,7 +3692,7 @@ func (x *FindArchivedResponse) String() string {
 func (*FindArchivedResponse) ProtoMessage() {}
 
 func (x *FindArchivedResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_items_items_proto_msgTypes[57]
+	mi := &file_items_items_proto_msgTypes[58]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -3652,7 +3705,7 @@ func (x *FindArchivedResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use FindArchivedResponse.ProtoReflect.Descriptor instead.
 func (*FindArchivedResponse) Descriptor() ([]byte, []int) {
-	return file_items_items_proto_rawDescGZIP(), []int{57}
+	return file_items_items_proto_rawDescGZIP(), []int{58}
 }
 
 func (x *FindArchivedResponse) GetItems() []*Item {
@@ -3669,6 +3722,128 @@ func (x *FindArchivedResponse) GetTotal() int32 {
 	return 0
 }
 
+type GetArchivedRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	SpaceId      string              `protobuf:"bytes,1,opt,name=space_id,json=spaceId,proto3" json:"space_id,omitempty"`
+	EnvId        string              `protobuf:"bytes,2,opt,name=env_id,json=envId,proto3" json:"env_id,omitempty"`
+	CollectionId string              `protobuf:"bytes,3,opt,name=collection_id,json=collectionId,proto3" json:"collection_id,omitempty"`
+	ItemId       string              `protobuf:"bytes,4,opt,name=item_id,json=itemId,proto3" json:"item_id,omitempty"`
+	Options      *GetArchivedOptions `protobuf:"bytes,10,opt,name=options,proto3" json:"options,omitempty"`
+}
+
+func (x *GetArchivedRequest) Reset() {
+	*x = GetArchivedRequest{}
+	mi := &file_items_items_proto_msgTypes[59]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *GetArchivedRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetArchivedRequest) ProtoMessage() {}
+
+func (x *GetArchivedRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_items_items_proto_msgTypes[59]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetArchivedRequest.ProtoReflect.Descriptor instead.
+func (*GetArchivedRequest) Descriptor() ([]byte, []int) {
+	return file_items_items_proto_rawDescGZIP(), []int{59}
+}
+
+func (x *GetArchivedRequest) GetSpaceId() string {
+	if x != nil {
+		return x.SpaceId
+	}
+	return ""
+}
+
+func (x *GetArchivedRequest) GetEnvId() string {
+	if x != nil {
+		return x.EnvId
+	}
+	return ""
+}
+
+func (x *GetArchivedRequest) GetCollectionId() string {
+	if x != nil {
+		return x.CollectionId
+	}
+	return ""
+}
+
+func (x *GetArchivedRequest) GetItemId() string {
+	if x != nil {
+		return x.ItemId
+	}
+	return ""
+}
+
+func (x *GetArchivedRequest) GetOptions() *GetArchivedOptions {
+	if x != nil {
+		return x.Options
+	}
+	return nil
+}
+
+type GetArchivedResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Item *Item `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"`
+}
+
+func (x *GetArchivedResponse) Reset() {
+	*x = GetArchivedResponse{}
+	mi := &file_items_items_proto_msgTypes[60]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *GetArchivedResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetArchivedResponse) ProtoMessage() {}
+
+func (x *GetArchivedResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_items_items_proto_msgTypes[60]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetArchivedResponse.ProtoReflect.Descriptor instead.
+func (*GetArchivedResponse) Descriptor() ([]byte, []int) {
+	return file_items_items_proto_rawDescGZIP(), []int{60}
+}
+
+func (x *GetArchivedResponse) GetItem() *Item {
+	if x != nil {
+		return x.Item
+	}
+	return nil
+}
+
 var File_items_items_proto protoreflect.FileDescriptor
 
 var file_items_items_proto_rawDesc = []byte{
@@ -3899,179 +4074,79 @@ var file_items_items_proto_rawDesc = []byte{
 	0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x29, 0x0a,
 	0x10, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x69, 0x64,
 	0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x49, 0x64, 0x73, 0x22, 0x92, 0x01, 0x0a, 0x10, 0x41, 0x67, 0x67,
-	0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x43, 0x0a,
-	0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e,
-	0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x41, 0x67,
-	0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x46,
-	0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c,
-	0x64, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72,
-	0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
-	0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa4, 0x01,
-	0x0a, 0x19, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69,
-	0x73, 0x68, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4c, 0x0a, 0x06, 0x66,
-	0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x63, 0x6f,
+	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x49, 0x64, 0x73, 0x22, 0x5c, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x41,
+	0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1b,
+	0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x74,
+	0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x69, 0x64, 0x73, 0x18,
+	0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x73, 0x49, 0x64, 0x73, 0x22, 0x92, 0x01, 0x0a, 0x10, 0x41, 0x67, 0x67, 0x72, 0x65,
+	0x67, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x43, 0x0a, 0x06, 0x66,
+	0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x6f,
 	0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x41, 0x67, 0x67, 0x72,
-	0x65, 0x67, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x4f, 0x70,
-	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72,
-	0x79, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x46, 0x69, 0x65,
-	0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,
-	0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
-	0x3a, 0x02, 0x38, 0x01, 0x22, 0x70, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74,
-	0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x12, 0x36,
-	0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e,
-	0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f,
-	0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x3f, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61,
-	0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
-	0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x07,
-	0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x3c, 0x0a, 0x11, 0x49, 0x6e, 0x74, 0x72, 0x6f,
-	0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04,
-	0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e,
-	0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52,
-	0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0xab, 0x01, 0x0a, 0x12, 0x49, 0x6e, 0x74, 0x72, 0x6f, 0x73,
-	0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x04,
-	0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e,
-	0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52,
-	0x04, 0x69, 0x74, 0x65, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x54, 0x0a,
-	0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f,
-	0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
-	0x6e, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x42, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x56, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f,
-	0x6e, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72,
-	0x6f, 0x72, 0x73, 0x22, 0x54, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
-	0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x07,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x29,
-	0x0a, 0x10, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x69,
-	0x64, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c,
-	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x49, 0x64, 0x73, 0x22, 0xb1, 0x01, 0x0a, 0x0a, 0x47, 0x65,
-	0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63,
-	0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63,
-	0x65, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x65, 0x6e, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x76, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f,
-	0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12,
-	0x17, 0x0a, 0x07, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x06, 0x69, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x33, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69,
-	0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
-	0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x70, 0x74,
-	0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x36, 0x0a,
-	0x0b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x04,
-	0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e,
-	0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52,
-	0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0xc9, 0x01, 0x0a, 0x0b, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69,
-	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64,
-	0x12, 0x15, 0x0a, 0x06, 0x65, 0x6e, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x05, 0x65, 0x6e, 0x76, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65,
-	0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
-	0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x06,
-	0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63,
-	0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x46, 0x69, 0x6c,
-	0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x34, 0x0a, 0x07, 0x6f,
-	0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63,
-	0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x46, 0x69, 0x6e,
-	0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
-	0x73, 0x22, 0x4f, 0x0a, 0x0c, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x12, 0x29, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
-	0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73,
-	0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x14, 0x0a, 0x05,
-	0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, 0x74,
-	0x61, 0x6c, 0x22, 0x70, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x67, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x46, 0x69, 0x65,
+	0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73,
+	0x1a, 0x39, 0x0a, 0x0b, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
+	0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
+	0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa4, 0x01, 0x0a, 0x19,
+	0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68,
+	0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4c, 0x0a, 0x06, 0x66, 0x69, 0x65,
+	0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
+	0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67,
+	0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69,
+	0x6f, 0x6e, 0x73, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
+	0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x46, 0x69, 0x65, 0x6c, 0x64,
+	0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02,
+	0x38, 0x01, 0x22, 0x70, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75,
 	0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28,
 	0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d,
 	0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x12, 0x36, 0x0a, 0x07,
 	0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e,
-	0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x55, 0x70,
-	0x64, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74,
-	0x69, 0x6f, 0x6e, 0x73, 0x22, 0x70, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74,
-	0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x12, 0x36,
-	0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e,
-	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f,
-	0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x74, 0x0a, 0x0f, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65,
-	0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x69, 0x74, 0x65,
-	0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
-	0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69, 0x74,
-	0x65, 0x6d, 0x12, 0x38, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74,
-	0x65, 0x6d, 0x73, 0x2e, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69,
-	0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xaa, 0x01, 0x0a,
-	0x17, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f,
-	0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63,
-	0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63,
-	0x65, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x65, 0x6e, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x76, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f,
-	0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12,
-	0x17, 0x0a, 0x07, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x06, 0x69, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x76, 0x69,
-	0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72,
-	0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x48, 0x0a, 0x18, 0x43, 0x68, 0x65,
-	0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x5f,
-	0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x10, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f,
-	0x6e, 0x49, 0x64, 0x22, 0x72, 0x0a, 0x0e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74,
-	0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x12, 0x37,
-	0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x1d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e,
-	0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07,
-	0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x76, 0x0a, 0x10, 0x55, 0x6e, 0x70, 0x75, 0x62,
-	0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x69,
-	0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
-	0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04,
-	0x69, 0x74, 0x65, 0x6d, 0x12, 0x39, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e,
-	0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x55, 0x6e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x4f,
-	0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22,
-	0xc3, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65,
-	0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65,
-	0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x65, 0x6e, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x76, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c,
-	0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x17,
-	0x0a, 0x07, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x06, 0x69, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x3c, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f,
-	0x6e, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65,
-	0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c,
-	0x69, 0x73, 0x68, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70,
-	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x3f, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c,
-	0x69, 0x73, 0x68, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a,
-	0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f,
-	0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d,
-	0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0xdb, 0x01, 0x0a, 0x14, 0x46, 0x69, 0x6e, 0x64, 0x50,
-	0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
-	0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x65, 0x6e,
-	0x76, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x76, 0x49,
-	0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f,
-	0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63,
-	0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72,
-	0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
-	0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66,
-	0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3d, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
-	0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
-	0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x50, 0x75, 0x62, 0x6c, 0x69,
-	0x73, 0x68, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74,
-	0x69, 0x6f, 0x6e, 0x73, 0x22, 0x58, 0x0a, 0x15, 0x46, 0x69, 0x6e, 0x64, 0x50, 0x75, 0x62, 0x6c,
-	0x69, 0x73, 0x68, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a,
-	0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63,
-	0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65,
-	0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61,
-	0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x22, 0xd3,
-	0x01, 0x0a, 0x10, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75,
+	0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x43, 0x72,
+	0x65, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74,
+	0x69, 0x6f, 0x6e, 0x73, 0x22, 0x3f, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65,
+	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
+	0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x07, 0x63, 0x72,
+	0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x3c, 0x0a, 0x11, 0x49, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70,
+	0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x69, 0x74,
+	0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65,
+	0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69,
+	0x74, 0x65, 0x6d, 0x22, 0xab, 0x01, 0x0a, 0x12, 0x49, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65,
+	0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x04, 0x69, 0x74,
+	0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65,
+	0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69,
+	0x74, 0x65, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x54, 0x0a, 0x11, 0x76,
+	0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73,
+	0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
+	0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x42, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x56, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+	0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72,
+	0x73, 0x22, 0x54, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12,
+	0x1b, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x10,
+	0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x69, 0x64, 0x73,
+	0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x73, 0x49, 0x64, 0x73, 0x22, 0xb1, 0x01, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f,
+	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49,
+	0x64, 0x12, 0x15, 0x0a, 0x06, 0x65, 0x6e, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x05, 0x65, 0x6e, 0x76, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c,
+	0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x17, 0x0a,
+	0x07, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
+	0x69, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x33, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+	0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
+	0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f,
+	0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x36, 0x0a, 0x0b, 0x47,
+	0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x04, 0x69, 0x74,
+	0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65,
+	0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69,
+	0x74, 0x65, 0x6d, 0x22, 0xc9, 0x01, 0x0a, 0x0b, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75,
 	0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18,
 	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x15,
 	0x0a, 0x06, 0x65, 0x6e, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
@@ -4080,197 +4155,325 @@ var file_items_items_proto_rawDesc = []byte{
 	0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x06, 0x66, 0x69,
 	0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6e,
 	0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65,
-	0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x07, 0x6f, 0x70, 0x74,
-	0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6f, 0x6e,
-	0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65,
-	0x67, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74,
-	0x69, 0x6f, 0x6e, 0x73, 0x22, 0x44, 0x0a, 0x11, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74,
-	0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x72, 0x65, 0x73,
-	0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
-	0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75,
-	0x63, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xe5, 0x01, 0x0a, 0x19, 0x41,
-	0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65,
-	0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63,
-	0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63,
-	0x65, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x65, 0x6e, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x76, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f,
-	0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12,
-	0x2d, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e,
-	0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x42,
-	0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e,
-	0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68,
-	0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f,
-	0x6e, 0x73, 0x22, 0x4d, 0x0a, 0x1a, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x50,
-	0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x12, 0x2f, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
-	0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c,
-	0x74, 0x22, 0xe2, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f,
-	0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63,
-	0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63,
-	0x65, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x65, 0x6e, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x76, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f,
-	0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12,
-	0x17, 0x0a, 0x07, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x06, 0x69, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x76, 0x69,
-	0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72,
-	0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x07, 0x6f, 0x70, 0x74,
-	0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x6e,
-	0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65,
-	0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f,
-	0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x3e, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x52, 0x65, 0x76,
-	0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a,
-	0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f,
-	0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d,
-	0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0xc5, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x52,
-	0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
-	0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x65, 0x6e,
-	0x76, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x76, 0x49,
-	0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f,
-	0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63,
-	0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x69,
-	0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12,
-	0x3d, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x23, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73,
-	0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x4f, 0x70,
-	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x58,
-	0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73,
-	0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
-	0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65,
-	0x6d, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x05, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x22, 0x39, 0x0a, 0x0e, 0x41, 0x72, 0x63, 0x68,
-	0x69, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x69, 0x74,
-	0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65,
-	0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69,
-	0x74, 0x65, 0x6d, 0x22, 0x3b, 0x0a, 0x10, 0x55, 0x6e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65,
+	0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x34, 0x0a, 0x07, 0x6f, 0x70, 0x74,
+	0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6e,
+	0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x4f,
+	0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22,
+	0x4f, 0x0a, 0x0c, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+	0x29, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13,
+	0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49,
+	0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f,
+	0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c,
+	0x22, 0x70, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x27, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e,
+	0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x12, 0x36, 0x0a, 0x07, 0x6f, 0x70,
+	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6f,
+	0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61,
+	0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f,
+	0x6e, 0x73, 0x22, 0x70, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d,
+	0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x12, 0x36, 0x0a, 0x07,
+	0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e,
+	0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x44, 0x65,
+	0x6c, 0x65, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74,
+	0x69, 0x6f, 0x6e, 0x73, 0x22, 0x74, 0x0a, 0x0f, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65,
 	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18,
 	0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e,
 	0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d,
-	0x22, 0xd9, 0x01, 0x0a, 0x13, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65,
-	0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63,
-	0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63,
-	0x65, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x65, 0x6e, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x76, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f,
-	0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12,
-	0x2d, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e,
-	0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3c,
-	0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e,
-	0x46, 0x69, 0x6e, 0x64, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69,
-	0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x57, 0x0a, 0x14,
-	0x46, 0x69, 0x6e, 0x64, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20,
-	0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74,
-	0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12,
-	0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05,
-	0x74, 0x6f, 0x74, 0x61, 0x6c, 0x32, 0xfa, 0x0b, 0x0a, 0x05, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12,
-	0x47, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
+	0x12, 0x38, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d,
+	0x73, 0x2e, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+	0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xaa, 0x01, 0x0a, 0x17, 0x43,
+	0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f,
+	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49,
+	0x64, 0x12, 0x15, 0x0a, 0x06, 0x65, 0x6e, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x05, 0x65, 0x6e, 0x76, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c,
+	0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x17, 0x0a,
+	0x07, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
+	0x69, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69,
+	0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x76,
+	0x69, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x48, 0x0a, 0x18, 0x43, 0x68, 0x65, 0x63, 0x6b,
+	0x6f, 0x75, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65,
+	0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x10, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x49,
+	0x64, 0x22, 0x72, 0x0a, 0x0e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d,
+	0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x12, 0x37, 0x0a, 0x07,
+	0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e,
+	0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x50, 0x75,
+	0x62, 0x6c, 0x69, 0x73, 0x68, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70,
+	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x76, 0x0a, 0x10, 0x55, 0x6e, 0x70, 0x75, 0x62, 0x6c, 0x69,
+	0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x69, 0x74, 0x65,
+	0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
+	0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69, 0x74,
+	0x65, 0x6d, 0x12, 0x39, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74,
+	0x65, 0x6d, 0x73, 0x2e, 0x55, 0x6e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x4f, 0x70, 0x74,
+	0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xc3, 0x01,
+	0x0a, 0x13, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69,
+	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64,
+	0x12, 0x15, 0x0a, 0x06, 0x65, 0x6e, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x05, 0x65, 0x6e, 0x76, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65,
+	0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
+	0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07,
+	0x69, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69,
+	0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x3c, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+	0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
+	0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73,
+	0x68, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69,
+	0x6f, 0x6e, 0x73, 0x22, 0x3f, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73,
+	0x68, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x04, 0x69,
+	0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
+	0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04,
+	0x69, 0x74, 0x65, 0x6d, 0x22, 0xdb, 0x01, 0x0a, 0x14, 0x46, 0x69, 0x6e, 0x64, 0x50, 0x75, 0x62,
+	0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a,
+	0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x65, 0x6e, 0x76, 0x5f,
+	0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x76, 0x49, 0x64, 0x12,
+	0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69,
+	0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69,
+	0x74, 0x65, 0x6d, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c,
+	0x74, 0x65, 0x72, 0x12, 0x3d, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0a,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69,
+	0x74, 0x65, 0x6d, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68,
+	0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f,
+	0x6e, 0x73, 0x22, 0x58, 0x0a, 0x15, 0x46, 0x69, 0x6e, 0x64, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73,
+	0x68, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x05, 0x69,
+	0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e,
+	0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52,
+	0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x22, 0xd3, 0x01, 0x0a,
+	0x10, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06,
+	0x65, 0x6e, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e,
+	0x76, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f,
+	0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c,
+	0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74,
+	0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65,
+	0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52,
+	0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x39, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f,
+	0x6e, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65,
+	0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61,
+	0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f,
+	0x6e, 0x73, 0x22, 0x44, 0x0a, 0x11, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c,
+	0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74,
+	0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xe5, 0x01, 0x0a, 0x19, 0x41, 0x67, 0x67,
+	0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f,
+	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49,
+	0x64, 0x12, 0x15, 0x0a, 0x06, 0x65, 0x6e, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x05, 0x65, 0x6e, 0x76, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c,
+	0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2d, 0x0a,
+	0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e,
+	0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x46, 0x69,
+	0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x42, 0x0a, 0x07,
+	0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e,
+	0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x41, 0x67,
+	0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64,
+	0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+	0x22, 0x4d, 0x0a, 0x1a, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62,
+	0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f,
+	0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17,
+	0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+	0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22,
+	0xe2, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f,
+	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49,
+	0x64, 0x12, 0x15, 0x0a, 0x06, 0x65, 0x6e, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x05, 0x65, 0x6e, 0x76, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c,
+	0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x17, 0x0a,
+	0x07, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
+	0x69, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69,
+	0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x76,
+	0x69, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f,
+	0x6e, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65,
+	0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x76, 0x69,
+	0x73, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74,
+	0x69, 0x6f, 0x6e, 0x73, 0x22, 0x3e, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73,
+	0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x04, 0x69,
+	0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
+	0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04,
+	0x69, 0x74, 0x65, 0x6d, 0x22, 0xc5, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76,
+	0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a,
+	0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x65, 0x6e, 0x76, 0x5f,
+	0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x76, 0x49, 0x64, 0x12,
+	0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69,
+	0x6f, 0x6e, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18,
+	0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x3d, 0x0a,
+	0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23,
+	0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x4c,
+	0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x4f, 0x70, 0x74, 0x69,
+	0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x58, 0x0a, 0x15,
+	0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01,
+	0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69,
+	0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73,
+	0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52,
+	0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x22, 0x39, 0x0a, 0x0e, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76,
+	0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
+	0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69, 0x74, 0x65,
+	0x6d, 0x22, 0x3b, 0x0a, 0x10, 0x55, 0x6e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74,
+	0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0xd9,
+	0x01, 0x0a, 0x13, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f,
+	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49,
+	0x64, 0x12, 0x15, 0x0a, 0x06, 0x65, 0x6e, 0x76, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x05, 0x65, 0x6e, 0x76, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c,
+	0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2d, 0x0a,
+	0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e,
+	0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x46, 0x69,
+	0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3c, 0x0a, 0x07,
+	0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e,
+	0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x46, 0x69,
+	0x6e, 0x64, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+	0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x57, 0x0a, 0x14, 0x46, 0x69,
+	0x6e, 0x64, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x29, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
+	0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d,
+	0x73, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x14, 0x0a,
+	0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f,
+	0x74, 0x61, 0x6c, 0x22, 0xc1, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x41, 0x72, 0x63, 0x68, 0x69,
+	0x76, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70,
+	0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70,
+	0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x65, 0x6e, 0x76, 0x5f, 0x69, 0x64, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6e, 0x76, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d,
+	0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49,
+	0x64, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x06, 0x69, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x07, 0x6f, 0x70,
+	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6f,
+	0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41,
+	0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07,
+	0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x3e, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x72,
+	0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27,
+	0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63,
+	0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x74, 0x65,
+	0x6d, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x32, 0xd2, 0x0c, 0x0a, 0x05, 0x49, 0x74, 0x65, 0x6d,
+	0x73, 0x12, 0x47, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x63, 0x6f,
+	0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61,
+	0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
 	0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
-	0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0a, 0x49, 0x6e, 0x74, 0x72,
-	0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x12, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
-	0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63,
-	0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0a, 0x49, 0x6e,
+	0x74, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x12, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65,
 	0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x72, 0x6f, 0x73, 0x70,
-	0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3e, 0x0a,
-	0x03, 0x47, 0x65, 0x74, 0x12, 0x19, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69,
-	0x74, 0x65, 0x6d, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
-	0x1a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e,
-	0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a,
-	0x04, 0x46, 0x69, 0x6e, 0x64, 0x12, 0x1a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e,
-	0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x1a, 0x1b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d,
-	0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
-	0x12, 0x40, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x63, 0x6f, 0x6e,
-	0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74,
-	0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
-	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
-	0x22, 0x00, 0x12, 0x40, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x63,
-	0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x44, 0x65, 0x6c,
-	0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
+	0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x63, 0x6f, 0x6e,
+	0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x72, 0x6f,
+	0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
+	0x3e, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x19, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
+	0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x1a, 0x1a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d,
+	0x73, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
+	0x41, 0x0a, 0x04, 0x46, 0x69, 0x6e, 0x64, 0x12, 0x1a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
+	0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74,
+	0x65, 0x6d, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x22, 0x00, 0x12, 0x40, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x63,
+	0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x55, 0x70, 0x64,
+	0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
 	0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70,
-	0x74, 0x79, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x08, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65,
-	0x12, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73,
-	0x2e, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
-	0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x07, 0x50, 0x75,
-	0x62, 0x6c, 0x69, 0x73, 0x68, 0x12, 0x1d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e,
-	0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x46,
-	0x0a, 0x09, 0x55, 0x6e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x12, 0x1f, 0x2e, 0x63, 0x6f,
-	0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x55, 0x6e, 0x70, 0x75,
-	0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67,
+	0x74, 0x79, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1c,
+	0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x44,
+	0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67,
 	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45,
-	0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62,
-	0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
-	0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73,
-	0x68, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x63, 0x6f, 0x6e,
-	0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x75,
+	0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x08, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65,
+	0x74, 0x65, 0x12, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65,
+	0x6d, 0x73, 0x2e, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x07,
+	0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x12, 0x1d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
+	0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00,
+	0x12, 0x46, 0x0a, 0x09, 0x55, 0x6e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x12, 0x1f, 0x2e,
+	0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x55, 0x6e,
+	0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16,
+	0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+	0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x59, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x50,
+	0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65,
+	0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c,
+	0x69, 0x73, 0x68, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x63,
+	0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x47, 0x65, 0x74,
+	0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x22, 0x00, 0x12, 0x5c, 0x0a, 0x0d, 0x46, 0x69, 0x6e, 0x64, 0x50, 0x75, 0x62, 0x6c, 0x69,
+	0x73, 0x68, 0x65, 0x64, 0x12, 0x23, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69,
+	0x74, 0x65, 0x6d, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68,
+	0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
+	0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x50, 0x75,
 	0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
-	0x00, 0x12, 0x5c, 0x0a, 0x0d, 0x46, 0x69, 0x6e, 0x64, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68,
-	0x65, 0x64, 0x12, 0x23, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65,
-	0x6d, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
-	0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x50, 0x75, 0x62, 0x6c,
-	0x69, 0x73, 0x68, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
-	0x65, 0x0a, 0x10, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73,
-	0x69, 0x6f, 0x6e, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74,
-	0x65, 0x6d, 0x73, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x76, 0x69,
-	0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x63, 0x6f,
-	0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x43, 0x68, 0x65, 0x63,
-	0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x09, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67,
-	0x61, 0x74, 0x65, 0x12, 0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74,
-	0x65, 0x6d, 0x73, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69,
-	0x74, 0x65, 0x6d, 0x73, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6b, 0x0a, 0x12, 0x41, 0x67, 0x67, 0x72,
-	0x65, 0x67, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x28,
-	0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x41,
-	0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65,
-	0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65,
-	0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61,
-	0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x76, 0x69,
-	0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69,
-	0x74, 0x65, 0x6d, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
-	0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73,
-	0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5c, 0x0a,
-	0x0d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x23,
-	0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x4c,
-	0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74,
-	0x65, 0x6d, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
-	0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x07, 0x41,
-	0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x12, 0x1d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
-	0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12,
-	0x59, 0x0a, 0x0c, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x12,
-	0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e,
-	0x46, 0x69, 0x6e, 0x64, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74,
-	0x65, 0x6d, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x09, 0x55, 0x6e,
-	0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x12, 0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
-	0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x55, 0x6e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76,
-	0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
-	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
-	0x22, 0x00, 0x42, 0x30, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x2e, 0x70, 0x65, 0x72, 0x78, 0x2e, 0x72,
-	0x75, 0x2f, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2d,
-	0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x3b, 0x69,
-	0x74, 0x65, 0x6d, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x00, 0x12, 0x65, 0x0a, 0x10, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x76,
+	0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e,
+	0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65,
+	0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e,
+	0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x43, 0x68,
+	0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x09, 0x41, 0x67, 0x67, 0x72,
+	0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e,
+	0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
+	0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6b, 0x0a, 0x12, 0x41, 0x67,
+	0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64,
+	0x12, 0x28, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73,
+	0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73,
+	0x68, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x63, 0x6f, 0x6e,
+	0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65,
+	0x67, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x64, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x65,
+	0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
+	0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69,
+	0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
+	0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x76,
+	0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
+	0x5c, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73,
+	0x12, 0x23, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73,
+	0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e,
+	0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69,
+	0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x42, 0x0a,
+	0x07, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x12, 0x1d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65,
+	0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22,
+	0x00, 0x12, 0x59, 0x0a, 0x0c, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65,
+	0x64, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d,
+	0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e,
+	0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76,
+	0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x09,
+	0x55, 0x6e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x12, 0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
+	0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x55, 0x6e, 0x61, 0x72, 0x63, 0x68,
+	0x69, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
+	0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70,
+	0x74, 0x79, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x41, 0x72, 0x63, 0x68, 0x69,
+	0x76, 0x65, 0x64, 0x12, 0x21, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x74,
+	0x65, 0x6d, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
+	0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76,
+	0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x30, 0x5a, 0x2e,
+	0x67, 0x69, 0x74, 0x2e, 0x70, 0x65, 0x72, 0x78, 0x2e, 0x72, 0x75, 0x2f, 0x70, 0x65, 0x72, 0x78,
+	0x69, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2d, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x2f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x3b, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x62, 0x06,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -4286,7 +4489,7 @@ func file_items_items_proto_rawDescGZIP() []byte {
 }
 
 var file_items_items_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_items_items_proto_msgTypes = make([]protoimpl.MessageInfo, 61)
+var file_items_items_proto_msgTypes = make([]protoimpl.MessageInfo, 64)
 var file_items_items_proto_goTypes = []any{
 	(Item_State)(0),                                // 0: content.items.Item.State
 	(*Error)(nil),                                  // 1: content.items.Error
@@ -4313,74 +4516,77 @@ var file_items_items_proto_goTypes = []any{
 	(*FindArchivedOptions)(nil),                    // 22: content.items.FindArchivedOptions
 	(*ListRevisionsOptions)(nil),                   // 23: content.items.ListRevisionsOptions
 	(*GetRevisionOptions)(nil),                     // 24: content.items.GetRevisionOptions
-	(*AggregateOptions)(nil),                       // 25: content.items.AggregateOptions
-	(*AggregatePublishedOptions)(nil),              // 26: content.items.AggregatePublishedOptions
-	(*CreateRequest)(nil),                          // 27: content.items.CreateRequest
-	(*CreateResponse)(nil),                         // 28: content.items.CreateResponse
-	(*IntrospectRequest)(nil),                      // 29: content.items.IntrospectRequest
-	(*IntrospectResponse)(nil),                     // 30: content.items.IntrospectResponse
-	(*GetOptions)(nil),                             // 31: content.items.GetOptions
-	(*GetRequest)(nil),                             // 32: content.items.GetRequest
-	(*GetResponse)(nil),                            // 33: content.items.GetResponse
-	(*FindRequest)(nil),                            // 34: content.items.FindRequest
-	(*FindResponse)(nil),                           // 35: content.items.FindResponse
-	(*UpdateRequest)(nil),                          // 36: content.items.UpdateRequest
-	(*DeleteRequest)(nil),                          // 37: content.items.DeleteRequest
-	(*UndeleteRequest)(nil),                        // 38: content.items.UndeleteRequest
-	(*CheckoutRevisionRequest)(nil),                // 39: content.items.CheckoutRevisionRequest
-	(*CheckoutRevisionResponse)(nil),               // 40: content.items.CheckoutRevisionResponse
-	(*PublishRequest)(nil),                         // 41: content.items.PublishRequest
-	(*UnpublishRequest)(nil),                       // 42: content.items.UnpublishRequest
-	(*GetPublishedRequest)(nil),                    // 43: content.items.GetPublishedRequest
-	(*GetPublishedResponse)(nil),                   // 44: content.items.GetPublishedResponse
-	(*FindPublishedRequest)(nil),                   // 45: content.items.FindPublishedRequest
-	(*FindPublishedResponse)(nil),                  // 46: content.items.FindPublishedResponse
-	(*AggregateRequest)(nil),                       // 47: content.items.AggregateRequest
-	(*AggregateResponse)(nil),                      // 48: content.items.AggregateResponse
-	(*AggregatePublishedRequest)(nil),              // 49: content.items.AggregatePublishedRequest
-	(*AggregatePublishedResponse)(nil),             // 50: content.items.AggregatePublishedResponse
-	(*GetRevisionRequest)(nil),                     // 51: content.items.GetRevisionRequest
-	(*GetRevisionResponse)(nil),                    // 52: content.items.GetRevisionResponse
-	(*ListRevisionsRequest)(nil),                   // 53: content.items.ListRevisionsRequest
-	(*ListRevisionsResponse)(nil),                  // 54: content.items.ListRevisionsResponse
-	(*ArchiveRequest)(nil),                         // 55: content.items.ArchiveRequest
-	(*UnarchiveRequest)(nil),                       // 56: content.items.UnarchiveRequest
-	(*FindArchivedRequest)(nil),                    // 57: content.items.FindArchivedRequest
-	(*FindArchivedResponse)(nil),                   // 58: content.items.FindArchivedResponse
-	nil,                                            // 59: content.items.Item.TranslationsEntry
-	nil,                                            // 60: content.items.AggregateOptions.FieldsEntry
-	nil,                                            // 61: content.items.AggregatePublishedOptions.FieldsEntry
-	(*timestamppb.Timestamp)(nil),                  // 62: google.protobuf.Timestamp
-	(*structpb.Struct)(nil),                        // 63: google.protobuf.Struct
-	(*common.Filter)(nil),                          // 64: common.Filter
-	(*common.FindOptions)(nil),                     // 65: common.FindOptions
-	(*common.Error_BadRequest_FieldViolation)(nil), // 66: common.Error.BadRequest.FieldViolation
-	(*emptypb.Empty)(nil),                          // 67: google.protobuf.Empty
+	(*GetArchivedOptions)(nil),                     // 25: content.items.GetArchivedOptions
+	(*AggregateOptions)(nil),                       // 26: content.items.AggregateOptions
+	(*AggregatePublishedOptions)(nil),              // 27: content.items.AggregatePublishedOptions
+	(*CreateRequest)(nil),                          // 28: content.items.CreateRequest
+	(*CreateResponse)(nil),                         // 29: content.items.CreateResponse
+	(*IntrospectRequest)(nil),                      // 30: content.items.IntrospectRequest
+	(*IntrospectResponse)(nil),                     // 31: content.items.IntrospectResponse
+	(*GetOptions)(nil),                             // 32: content.items.GetOptions
+	(*GetRequest)(nil),                             // 33: content.items.GetRequest
+	(*GetResponse)(nil),                            // 34: content.items.GetResponse
+	(*FindRequest)(nil),                            // 35: content.items.FindRequest
+	(*FindResponse)(nil),                           // 36: content.items.FindResponse
+	(*UpdateRequest)(nil),                          // 37: content.items.UpdateRequest
+	(*DeleteRequest)(nil),                          // 38: content.items.DeleteRequest
+	(*UndeleteRequest)(nil),                        // 39: content.items.UndeleteRequest
+	(*CheckoutRevisionRequest)(nil),                // 40: content.items.CheckoutRevisionRequest
+	(*CheckoutRevisionResponse)(nil),               // 41: content.items.CheckoutRevisionResponse
+	(*PublishRequest)(nil),                         // 42: content.items.PublishRequest
+	(*UnpublishRequest)(nil),                       // 43: content.items.UnpublishRequest
+	(*GetPublishedRequest)(nil),                    // 44: content.items.GetPublishedRequest
+	(*GetPublishedResponse)(nil),                   // 45: content.items.GetPublishedResponse
+	(*FindPublishedRequest)(nil),                   // 46: content.items.FindPublishedRequest
+	(*FindPublishedResponse)(nil),                  // 47: content.items.FindPublishedResponse
+	(*AggregateRequest)(nil),                       // 48: content.items.AggregateRequest
+	(*AggregateResponse)(nil),                      // 49: content.items.AggregateResponse
+	(*AggregatePublishedRequest)(nil),              // 50: content.items.AggregatePublishedRequest
+	(*AggregatePublishedResponse)(nil),             // 51: content.items.AggregatePublishedResponse
+	(*GetRevisionRequest)(nil),                     // 52: content.items.GetRevisionRequest
+	(*GetRevisionResponse)(nil),                    // 53: content.items.GetRevisionResponse
+	(*ListRevisionsRequest)(nil),                   // 54: content.items.ListRevisionsRequest
+	(*ListRevisionsResponse)(nil),                  // 55: content.items.ListRevisionsResponse
+	(*ArchiveRequest)(nil),                         // 56: content.items.ArchiveRequest
+	(*UnarchiveRequest)(nil),                       // 57: content.items.UnarchiveRequest
+	(*FindArchivedRequest)(nil),                    // 58: content.items.FindArchivedRequest
+	(*FindArchivedResponse)(nil),                   // 59: content.items.FindArchivedResponse
+	(*GetArchivedRequest)(nil),                     // 60: content.items.GetArchivedRequest
+	(*GetArchivedResponse)(nil),                    // 61: content.items.GetArchivedResponse
+	nil,                                            // 62: content.items.Item.TranslationsEntry
+	nil,                                            // 63: content.items.AggregateOptions.FieldsEntry
+	nil,                                            // 64: content.items.AggregatePublishedOptions.FieldsEntry
+	(*timestamppb.Timestamp)(nil),                  // 65: google.protobuf.Timestamp
+	(*structpb.Struct)(nil),                        // 66: google.protobuf.Struct
+	(*common.Filter)(nil),                          // 67: common.Filter
+	(*common.FindOptions)(nil),                     // 68: common.FindOptions
+	(*common.Error_BadRequest_FieldViolation)(nil), // 69: common.Error.BadRequest.FieldViolation
+	(*emptypb.Empty)(nil),                          // 70: google.protobuf.Empty
 }
 var file_items_items_proto_depIdxs = []int32{
 	1,  // 0: content.items.DecodeError.errors:type_name -> content.items.Error
 	1,  // 1: content.items.ValidationError.errors:type_name -> content.items.Error
 	1,  // 2: content.items.ModificationError.errors:type_name -> content.items.Error
 	0,  // 3: content.items.Item.state:type_name -> content.items.Item.State
-	62, // 4: content.items.Item.created_rev_at:type_name -> google.protobuf.Timestamp
-	62, // 5: content.items.Item.created_at:type_name -> google.protobuf.Timestamp
-	62, // 6: content.items.Item.updated_at:type_name -> google.protobuf.Timestamp
-	63, // 7: content.items.Item.data:type_name -> google.protobuf.Struct
+	65, // 4: content.items.Item.created_rev_at:type_name -> google.protobuf.Timestamp
+	65, // 5: content.items.Item.created_at:type_name -> google.protobuf.Timestamp
+	65, // 6: content.items.Item.updated_at:type_name -> google.protobuf.Timestamp
+	66, // 7: content.items.Item.data:type_name -> google.protobuf.Struct
 	5,  // 8: content.items.Item.permissions:type_name -> content.items.Permissions
-	59, // 9: content.items.Item.translations:type_name -> content.items.Item.TranslationsEntry
-	64, // 10: content.items.Filter.data:type_name -> common.Filter
-	65, // 11: content.items.FindOptions.options:type_name -> common.FindOptions
-	65, // 12: content.items.FindPublishedOptions.options:type_name -> common.FindOptions
-	65, // 13: content.items.FindArchivedOptions.options:type_name -> common.FindOptions
-	60, // 14: content.items.AggregateOptions.fields:type_name -> content.items.AggregateOptions.FieldsEntry
-	61, // 15: content.items.AggregatePublishedOptions.fields:type_name -> content.items.AggregatePublishedOptions.FieldsEntry
+	62, // 9: content.items.Item.translations:type_name -> content.items.Item.TranslationsEntry
+	67, // 10: content.items.Filter.data:type_name -> common.Filter
+	68, // 11: content.items.FindOptions.options:type_name -> common.FindOptions
+	68, // 12: content.items.FindPublishedOptions.options:type_name -> common.FindOptions
+	68, // 13: content.items.FindArchivedOptions.options:type_name -> common.FindOptions
+	63, // 14: content.items.AggregateOptions.fields:type_name -> content.items.AggregateOptions.FieldsEntry
+	64, // 15: content.items.AggregatePublishedOptions.fields:type_name -> content.items.AggregatePublishedOptions.FieldsEntry
 	6,  // 16: content.items.CreateRequest.item:type_name -> content.items.Item
 	13, // 17: content.items.CreateRequest.options:type_name -> content.items.CreateOptions
 	6,  // 18: content.items.CreateResponse.created:type_name -> content.items.Item
 	6,  // 19: content.items.IntrospectRequest.item:type_name -> content.items.Item
 	6,  // 20: content.items.IntrospectResponse.item:type_name -> content.items.Item
-	66, // 21: content.items.IntrospectResponse.validation_errors:type_name -> common.Error.BadRequest.FieldViolation
-	31, // 22: content.items.GetRequest.options:type_name -> content.items.GetOptions
+	69, // 21: content.items.IntrospectResponse.validation_errors:type_name -> common.Error.BadRequest.FieldViolation
+	32, // 22: content.items.GetRequest.options:type_name -> content.items.GetOptions
 	6,  // 23: content.items.GetResponse.item:type_name -> content.items.Item
 	12, // 24: content.items.FindRequest.filter:type_name -> content.items.Filter
 	14, // 25: content.items.FindRequest.options:type_name -> content.items.FindOptions
@@ -4401,11 +4607,11 @@ var file_items_items_proto_depIdxs = []int32{
 	21, // 40: content.items.FindPublishedRequest.options:type_name -> content.items.FindPublishedOptions
 	6,  // 41: content.items.FindPublishedResponse.items:type_name -> content.items.Item
 	12, // 42: content.items.AggregateRequest.filter:type_name -> content.items.Filter
-	25, // 43: content.items.AggregateRequest.options:type_name -> content.items.AggregateOptions
-	63, // 44: content.items.AggregateResponse.result:type_name -> google.protobuf.Struct
+	26, // 43: content.items.AggregateRequest.options:type_name -> content.items.AggregateOptions
+	66, // 44: content.items.AggregateResponse.result:type_name -> google.protobuf.Struct
 	12, // 45: content.items.AggregatePublishedRequest.filter:type_name -> content.items.Filter
-	26, // 46: content.items.AggregatePublishedRequest.options:type_name -> content.items.AggregatePublishedOptions
-	63, // 47: content.items.AggregatePublishedResponse.result:type_name -> google.protobuf.Struct
+	27, // 46: content.items.AggregatePublishedRequest.options:type_name -> content.items.AggregatePublishedOptions
+	66, // 47: content.items.AggregatePublishedResponse.result:type_name -> google.protobuf.Struct
 	24, // 48: content.items.GetRevisionRequest.options:type_name -> content.items.GetRevisionOptions
 	6,  // 49: content.items.GetRevisionResponse.item:type_name -> content.items.Item
 	23, // 50: content.items.ListRevisionsRequest.options:type_name -> content.items.ListRevisionsOptions
@@ -4415,50 +4621,54 @@ var file_items_items_proto_depIdxs = []int32{
 	12, // 54: content.items.FindArchivedRequest.filter:type_name -> content.items.Filter
 	22, // 55: content.items.FindArchivedRequest.options:type_name -> content.items.FindArchivedOptions
 	6,  // 56: content.items.FindArchivedResponse.items:type_name -> content.items.Item
-	63, // 57: content.items.Item.TranslationsEntry.value:type_name -> google.protobuf.Struct
-	27, // 58: content.items.Items.Create:input_type -> content.items.CreateRequest
-	29, // 59: content.items.Items.Introspect:input_type -> content.items.IntrospectRequest
-	32, // 60: content.items.Items.Get:input_type -> content.items.GetRequest
-	34, // 61: content.items.Items.Find:input_type -> content.items.FindRequest
-	36, // 62: content.items.Items.Update:input_type -> content.items.UpdateRequest
-	37, // 63: content.items.Items.Delete:input_type -> content.items.DeleteRequest
-	38, // 64: content.items.Items.Undelete:input_type -> content.items.UndeleteRequest
-	41, // 65: content.items.Items.Publish:input_type -> content.items.PublishRequest
-	42, // 66: content.items.Items.Unpublish:input_type -> content.items.UnpublishRequest
-	43, // 67: content.items.Items.GetPublished:input_type -> content.items.GetPublishedRequest
-	45, // 68: content.items.Items.FindPublished:input_type -> content.items.FindPublishedRequest
-	39, // 69: content.items.Items.CheckoutRevision:input_type -> content.items.CheckoutRevisionRequest
-	47, // 70: content.items.Items.Aggregate:input_type -> content.items.AggregateRequest
-	49, // 71: content.items.Items.AggregatePublished:input_type -> content.items.AggregatePublishedRequest
-	51, // 72: content.items.Items.GetRevision:input_type -> content.items.GetRevisionRequest
-	53, // 73: content.items.Items.ListRevisions:input_type -> content.items.ListRevisionsRequest
-	55, // 74: content.items.Items.Archive:input_type -> content.items.ArchiveRequest
-	57, // 75: content.items.Items.FindArchived:input_type -> content.items.FindArchivedRequest
-	56, // 76: content.items.Items.Unarchive:input_type -> content.items.UnarchiveRequest
-	28, // 77: content.items.Items.Create:output_type -> content.items.CreateResponse
-	30, // 78: content.items.Items.Introspect:output_type -> content.items.IntrospectResponse
-	33, // 79: content.items.Items.Get:output_type -> content.items.GetResponse
-	35, // 80: content.items.Items.Find:output_type -> content.items.FindResponse
-	67, // 81: content.items.Items.Update:output_type -> google.protobuf.Empty
-	67, // 82: content.items.Items.Delete:output_type -> google.protobuf.Empty
-	67, // 83: content.items.Items.Undelete:output_type -> google.protobuf.Empty
-	67, // 84: content.items.Items.Publish:output_type -> google.protobuf.Empty
-	67, // 85: content.items.Items.Unpublish:output_type -> google.protobuf.Empty
-	44, // 86: content.items.Items.GetPublished:output_type -> content.items.GetPublishedResponse
-	46, // 87: content.items.Items.FindPublished:output_type -> content.items.FindPublishedResponse
-	40, // 88: content.items.Items.CheckoutRevision:output_type -> content.items.CheckoutRevisionResponse
-	48, // 89: content.items.Items.Aggregate:output_type -> content.items.AggregateResponse
-	50, // 90: content.items.Items.AggregatePublished:output_type -> content.items.AggregatePublishedResponse
-	52, // 91: content.items.Items.GetRevision:output_type -> content.items.GetRevisionResponse
-	54, // 92: content.items.Items.ListRevisions:output_type -> content.items.ListRevisionsResponse
-	67, // 93: content.items.Items.Archive:output_type -> google.protobuf.Empty
-	58, // 94: content.items.Items.FindArchived:output_type -> content.items.FindArchivedResponse
-	67, // 95: content.items.Items.Unarchive:output_type -> google.protobuf.Empty
-	77, // [77:96] is the sub-list for method output_type
-	58, // [58:77] is the sub-list for method input_type
-	58, // [58:58] is the sub-list for extension type_name
-	58, // [58:58] is the sub-list for extension extendee
-	0,  // [0:58] is the sub-list for field type_name
+	25, // 57: content.items.GetArchivedRequest.options:type_name -> content.items.GetArchivedOptions
+	6,  // 58: content.items.GetArchivedResponse.item:type_name -> content.items.Item
+	66, // 59: content.items.Item.TranslationsEntry.value:type_name -> google.protobuf.Struct
+	28, // 60: content.items.Items.Create:input_type -> content.items.CreateRequest
+	30, // 61: content.items.Items.Introspect:input_type -> content.items.IntrospectRequest
+	33, // 62: content.items.Items.Get:input_type -> content.items.GetRequest
+	35, // 63: content.items.Items.Find:input_type -> content.items.FindRequest
+	37, // 64: content.items.Items.Update:input_type -> content.items.UpdateRequest
+	38, // 65: content.items.Items.Delete:input_type -> content.items.DeleteRequest
+	39, // 66: content.items.Items.Undelete:input_type -> content.items.UndeleteRequest
+	42, // 67: content.items.Items.Publish:input_type -> content.items.PublishRequest
+	43, // 68: content.items.Items.Unpublish:input_type -> content.items.UnpublishRequest
+	44, // 69: content.items.Items.GetPublished:input_type -> content.items.GetPublishedRequest
+	46, // 70: content.items.Items.FindPublished:input_type -> content.items.FindPublishedRequest
+	40, // 71: content.items.Items.CheckoutRevision:input_type -> content.items.CheckoutRevisionRequest
+	48, // 72: content.items.Items.Aggregate:input_type -> content.items.AggregateRequest
+	50, // 73: content.items.Items.AggregatePublished:input_type -> content.items.AggregatePublishedRequest
+	52, // 74: content.items.Items.GetRevision:input_type -> content.items.GetRevisionRequest
+	54, // 75: content.items.Items.ListRevisions:input_type -> content.items.ListRevisionsRequest
+	56, // 76: content.items.Items.Archive:input_type -> content.items.ArchiveRequest
+	58, // 77: content.items.Items.FindArchived:input_type -> content.items.FindArchivedRequest
+	57, // 78: content.items.Items.Unarchive:input_type -> content.items.UnarchiveRequest
+	60, // 79: content.items.Items.GetArchived:input_type -> content.items.GetArchivedRequest
+	29, // 80: content.items.Items.Create:output_type -> content.items.CreateResponse
+	31, // 81: content.items.Items.Introspect:output_type -> content.items.IntrospectResponse
+	34, // 82: content.items.Items.Get:output_type -> content.items.GetResponse
+	36, // 83: content.items.Items.Find:output_type -> content.items.FindResponse
+	70, // 84: content.items.Items.Update:output_type -> google.protobuf.Empty
+	70, // 85: content.items.Items.Delete:output_type -> google.protobuf.Empty
+	70, // 86: content.items.Items.Undelete:output_type -> google.protobuf.Empty
+	70, // 87: content.items.Items.Publish:output_type -> google.protobuf.Empty
+	70, // 88: content.items.Items.Unpublish:output_type -> google.protobuf.Empty
+	45, // 89: content.items.Items.GetPublished:output_type -> content.items.GetPublishedResponse
+	47, // 90: content.items.Items.FindPublished:output_type -> content.items.FindPublishedResponse
+	41, // 91: content.items.Items.CheckoutRevision:output_type -> content.items.CheckoutRevisionResponse
+	49, // 92: content.items.Items.Aggregate:output_type -> content.items.AggregateResponse
+	51, // 93: content.items.Items.AggregatePublished:output_type -> content.items.AggregatePublishedResponse
+	53, // 94: content.items.Items.GetRevision:output_type -> content.items.GetRevisionResponse
+	55, // 95: content.items.Items.ListRevisions:output_type -> content.items.ListRevisionsResponse
+	70, // 96: content.items.Items.Archive:output_type -> google.protobuf.Empty
+	59, // 97: content.items.Items.FindArchived:output_type -> content.items.FindArchivedResponse
+	70, // 98: content.items.Items.Unarchive:output_type -> google.protobuf.Empty
+	61, // 99: content.items.Items.GetArchived:output_type -> content.items.GetArchivedResponse
+	80, // [80:100] is the sub-list for method output_type
+	60, // [60:80] is the sub-list for method input_type
+	60, // [60:60] is the sub-list for extension type_name
+	60, // [60:60] is the sub-list for extension extendee
+	0,  // [0:60] is the sub-list for field type_name
 }
 
 func init() { file_items_items_proto_init() }
@@ -4472,7 +4682,7 @@ func file_items_items_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_items_items_proto_rawDesc,
 			NumEnums:      1,
-			NumMessages:   61,
+			NumMessages:   64,
 			NumExtensions: 0,
 			NumServices:   1,
 		},
diff --git a/proto/items/items_grpc.pb.go b/proto/items/items_grpc.pb.go
index bf2ffcab59361cbe86dd8b7fb2102d97b5abb215..56c94a2c0e7c0e3e4b01cb0155b878c1c8bebd2a 100644
--- a/proto/items/items_grpc.pb.go
+++ b/proto/items/items_grpc.pb.go
@@ -47,6 +47,7 @@ const (
 	Items_Archive_FullMethodName            = "/content.items.Items/Archive"
 	Items_FindArchived_FullMethodName       = "/content.items.Items/FindArchived"
 	Items_Unarchive_FullMethodName          = "/content.items.Items/Unarchive"
+	Items_GetArchived_FullMethodName        = "/content.items.Items/GetArchived"
 )
 
 // ItemsClient is the client API for Items service.
@@ -87,6 +88,7 @@ type ItemsClient interface {
 	Archive(ctx context.Context, in *ArchiveRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
 	FindArchived(ctx context.Context, in *FindArchivedRequest, opts ...grpc.CallOption) (*FindArchivedResponse, error)
 	Unarchive(ctx context.Context, in *UnarchiveRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
+	GetArchived(ctx context.Context, in *GetArchivedRequest, opts ...grpc.CallOption) (*GetArchivedResponse, error)
 }
 
 type itemsClient struct {
@@ -287,6 +289,16 @@ func (c *itemsClient) Unarchive(ctx context.Context, in *UnarchiveRequest, opts
 	return out, nil
 }
 
+func (c *itemsClient) GetArchived(ctx context.Context, in *GetArchivedRequest, opts ...grpc.CallOption) (*GetArchivedResponse, error) {
+	cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+	out := new(GetArchivedResponse)
+	err := c.cc.Invoke(ctx, Items_GetArchived_FullMethodName, in, out, cOpts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
 // ItemsServer is the server API for Items service.
 // All implementations must embed UnimplementedItemsServer
 // for forward compatibility.
@@ -325,6 +337,7 @@ type ItemsServer interface {
 	Archive(context.Context, *ArchiveRequest) (*emptypb.Empty, error)
 	FindArchived(context.Context, *FindArchivedRequest) (*FindArchivedResponse, error)
 	Unarchive(context.Context, *UnarchiveRequest) (*emptypb.Empty, error)
+	GetArchived(context.Context, *GetArchivedRequest) (*GetArchivedResponse, error)
 	mustEmbedUnimplementedItemsServer()
 }
 
@@ -392,6 +405,9 @@ func (UnimplementedItemsServer) FindArchived(context.Context, *FindArchivedReque
 func (UnimplementedItemsServer) Unarchive(context.Context, *UnarchiveRequest) (*emptypb.Empty, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method Unarchive not implemented")
 }
+func (UnimplementedItemsServer) GetArchived(context.Context, *GetArchivedRequest) (*GetArchivedResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetArchived not implemented")
+}
 func (UnimplementedItemsServer) mustEmbedUnimplementedItemsServer() {}
 func (UnimplementedItemsServer) testEmbeddedByValue()               {}
 
@@ -755,6 +771,24 @@ func _Items_Unarchive_Handler(srv interface{}, ctx context.Context, dec func(int
 	return interceptor(ctx, in, info, handler)
 }
 
+func _Items_GetArchived_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetArchivedRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(ItemsServer).GetArchived(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: Items_GetArchived_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(ItemsServer).GetArchived(ctx, req.(*GetArchivedRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
 // Items_ServiceDesc is the grpc.ServiceDesc for Items service.
 // It's only intended for direct use with grpc.RegisterService,
 // and not to be introspected or modified (even as a copy)
@@ -838,6 +872,10 @@ var Items_ServiceDesc = grpc.ServiceDesc{
 			MethodName: "Unarchive",
 			Handler:    _Items_Unarchive_Handler,
 		},
+		{
+			MethodName: "GetArchived",
+			Handler:    _Items_GetArchived_Handler,
+		},
 	},
 	Streams:  []grpc.StreamDesc{},
 	Metadata: "items/items.proto",
diff --git a/proto/logs/log.pb.go b/proto/logs/log.pb.go
index 83525669d009233dda33e8df88b1b07a6ed0daac..e4cca2f92447094ba154974c6ba045b34d1e9c0c 100644
--- a/proto/logs/log.pb.go
+++ b/proto/logs/log.pb.go
@@ -146,8 +146,6 @@ type LogEntry struct {
 	Attr *anypb.Any `protobuf:"bytes,10,opt,name=attr,proto3" json:"attr,omitempty"`
 	// tags содержит теги связанные с событием, на усмотрение сервиса
 	Tags []string `protobuf:"bytes,11,rep,name=tags,proto3" json:"tags,omitempty"`
-	// релевантность элемента при полнотекстовом поиске
-	SearchScore float64 `protobuf:"fixed64,12,opt,name=search_score,json=searchScore,proto3" json:"search_score,omitempty"`
 }
 
 func (x *LogEntry) Reset() {
@@ -257,13 +255,6 @@ func (x *LogEntry) GetTags() []string {
 	return nil
 }
 
-func (x *LogEntry) GetSearchScore() float64 {
-	if x != nil {
-		return x.SearchScore
-	}
-	return 0
-}
-
 var File_logs_log_proto protoreflect.FileDescriptor
 
 var file_logs_log_proto_rawDesc = []byte{
@@ -273,7 +264,7 @@ var file_logs_log_proto_rawDesc = []byte{
 	0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f,
 	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f,
 	0x74, 0x6f, 0x1a, 0x12, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x65, 0x72, 0x72, 0x6f, 0x72,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xff, 0x02, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x45, 0x6e,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe2, 0x02, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x45, 0x6e,
 	0x74, 0x72, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
 	0x02, 0x69, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
 	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
@@ -295,17 +286,15 @@ var file_logs_log_proto_rawDesc = []byte{
 	0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
 	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x04, 0x61, 0x74, 0x74,
 	0x72, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x52,
-	0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f,
-	0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0b, 0x73, 0x65, 0x61,
-	0x72, 0x63, 0x68, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x2a, 0x45, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x4c,
-	0x65, 0x76, 0x65, 0x6c, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x00, 0x12, 0x0b,
-	0x0a, 0x07, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x45,
-	0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x52, 0x49, 0x54, 0x49, 0x43,
-	0x41, 0x4c, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x46, 0x41, 0x54, 0x41, 0x4c, 0x10, 0x04, 0x42,
-	0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x2e, 0x70, 0x65, 0x72, 0x78, 0x2e, 0x72, 0x75, 0x2f, 0x70,
-	0x65, 0x72, 0x78, 0x69, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2d, 0x67, 0x6f, 0x2f,
-	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6c, 0x6f, 0x67, 0x73, 0x3b, 0x6c, 0x6f, 0x67, 0x73, 0x62,
-	0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x04, 0x74, 0x61, 0x67, 0x73, 0x4a, 0x04, 0x08, 0x0c, 0x10, 0x0d, 0x2a, 0x45, 0x0a, 0x08, 0x4c,
+	0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x10,
+	0x00, 0x12, 0x0b, 0x0a, 0x07, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x09,
+	0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x52, 0x49,
+	0x54, 0x49, 0x43, 0x41, 0x4c, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x46, 0x41, 0x54, 0x41, 0x4c,
+	0x10, 0x04, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x2e, 0x70, 0x65, 0x72, 0x78, 0x2e, 0x72,
+	0x75, 0x2f, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2d,
+	0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6c, 0x6f, 0x67, 0x73, 0x3b, 0x6c, 0x6f,
+	0x67, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
diff --git a/proto/logs/log_service.pb.go b/proto/logs/log_service.pb.go
index ab218080b2e48e8115fe6dd1602d5b7bda083587..78cf84e2799ba72331e79adf80ccc303bb831ab4 100644
--- a/proto/logs/log_service.pb.go
+++ b/proto/logs/log_service.pb.go
@@ -175,10 +175,6 @@ type FindOptions struct {
 
 	// Сортировка результатов
 	Sort []string `protobuf:"bytes,1,rep,name=sort,proto3" json:"sort,omitempty"`
-	// Включить поля в результаты
-	Fields []string `protobuf:"bytes,2,rep,name=fields,proto3" json:"fields,omitempty"`
-	// Исключить поля из результатов
-	ExcludeFields bool `protobuf:"varint,3,opt,name=exclude_fields,json=excludeFields,proto3" json:"exclude_fields,omitempty"`
 	// Ограничение количества результатов
 	Limit int32 `protobuf:"varint,4,opt,name=limit,proto3" json:"limit,omitempty"`
 	// Ограничение результатов по времени начиная с этим временем (pagination)
@@ -224,20 +220,6 @@ func (x *FindOptions) GetSort() []string {
 	return nil
 }
 
-func (x *FindOptions) GetFields() []string {
-	if x != nil {
-		return x.Fields
-	}
-	return nil
-}
-
-func (x *FindOptions) GetExcludeFields() bool {
-	if x != nil {
-		return x.ExcludeFields
-	}
-	return false
-}
-
 func (x *FindOptions) GetLimit() int32 {
 	if x != nil {
 		return x.Limit
@@ -602,70 +584,67 @@ var file_logs_log_service_proto_rawDesc = []byte{
 	0x23, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d,
 	0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65,
 	0x72, 0x72, 0x6f, 0x72, 0x22, 0x16, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x0c,
-	0x0a, 0x01, 0x71, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x01, 0x71, 0x22, 0xdc, 0x01, 0x0a,
+	0x0a, 0x01, 0x71, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x01, 0x71, 0x22, 0xa9, 0x01, 0x0a,
 	0x0b, 0x46, 0x69, 0x6e, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04,
 	0x73, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x73, 0x6f, 0x72, 0x74,
-	0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09,
-	0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c,
-	0x75, 0x64, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08,
-	0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12,
-	0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05,
-	0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x30, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x05,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
-	0x52, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72,
-	0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
-	0x61, 0x6d, 0x70, 0x52, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x22, 0x60, 0x0a, 0x0b, 0x46,
-	0x69, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69,
+	0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52,
+	0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x30, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18,
+	0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
+	0x70, 0x52, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f,
+	0x72, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73,
+	0x74, 0x61, 0x6d, 0x70, 0x52, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x4a, 0x04, 0x08, 0x02,
+	0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x60, 0x0a, 0x0b, 0x46, 0x69, 0x6e, 0x64,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65,
+	0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x46,
+	0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x2b, 0x0a,
+	0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11,
+	0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+	0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xed, 0x01, 0x0a, 0x0a, 0x46,
+	0x69, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x28, 0x0a, 0x07, 0x65, 0x6e, 0x74,
+	0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67,
+	0x73, 0x2e, 0x4c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72,
+	0x69, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65,
+	0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x07, 0x6f, 0x70, 0x74,
+	0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6c, 0x6f, 0x67,
+	0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f,
+	0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18,
+	0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x25, 0x0a, 0x04,
+	0x6e, 0x65, 0x78, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6c, 0x6f, 0x67,
+	0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x04, 0x6e,
+	0x65, 0x78, 0x74, 0x12, 0x25, 0x0a, 0x04, 0x70, 0x72, 0x65, 0x76, 0x18, 0x06, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x11, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x52, 0x04, 0x70, 0x72, 0x65, 0x76, 0x22, 0x6d, 0x0a, 0x0c, 0x46, 0x69,
+	0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65,
+	0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6c, 0x6f, 0x67,
+	0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x48, 0x00, 0x52, 0x06,
+	0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45,
+	0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x0a, 0x0a,
+	0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x0a, 0x0d, 0x44, 0x65, 0x6c,
+	0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69,
 	0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x6c, 0x6f, 0x67,
 	0x73, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72,
-	0x12, 0x2b, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x11, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x4f, 0x70, 0x74,
-	0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xed, 0x01,
-	0x0a, 0x0a, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x28, 0x0a, 0x07,
-	0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e,
-	0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x4c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65,
-	0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x46, 0x69,
-	0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x07,
-	0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e,
-	0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
-	0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74,
-	0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12,
-	0x25, 0x0a, 0x04, 0x6e, 0x65, 0x78, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e,
+	0x22, 0x35, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72,
+	0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x32, 0xa3, 0x01, 0x0a, 0x0b, 0x4c, 0x6f, 0x67, 0x73,
+	0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2c, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x10,
+	0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x1a, 0x11, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x04, 0x46, 0x69, 0x6e, 0x64, 0x12, 0x11, 0x2e,
 	0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x52, 0x04, 0x6e, 0x65, 0x78, 0x74, 0x12, 0x25, 0x0a, 0x04, 0x70, 0x72, 0x65, 0x76, 0x18, 0x06,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x04, 0x70, 0x72, 0x65, 0x76, 0x22, 0x6d, 0x0a,
-	0x0c, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a,
-	0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e,
-	0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x48,
-	0x00, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, 0x72,
-	0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
-	0x6e, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72,
-	0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x0a, 0x0d,
-	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a,
-	0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e,
-	0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c,
-	0x74, 0x65, 0x72, 0x22, 0x35, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73,
-	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x72,
-	0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x32, 0xa3, 0x01, 0x0a, 0x0b, 0x4c,
-	0x6f, 0x67, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2c, 0x0a, 0x03, 0x4c, 0x6f,
-	0x67, 0x12, 0x10, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x04, 0x46, 0x69, 0x6e, 0x64,
-	0x12, 0x11, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x06, 0x44, 0x65, 0x6c,
-	0x65, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74,
-	0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e,
-	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
-	0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x2e, 0x70, 0x65, 0x72, 0x78, 0x2e, 0x72, 0x75, 0x2f,
-	0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2d, 0x67, 0x6f,
-	0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6c, 0x6f, 0x67, 0x73, 0x3b, 0x6c, 0x6f, 0x67, 0x73,
-	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x1a, 0x12, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
+	0x12, 0x13, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x44, 0x65, 0x6c,
+	0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x2e, 0x5a,
+	0x2c, 0x67, 0x69, 0x74, 0x2e, 0x70, 0x65, 0x72, 0x78, 0x2e, 0x72, 0x75, 0x2f, 0x70, 0x65, 0x72,
+	0x78, 0x69, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2d, 0x67, 0x6f, 0x2f, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x2f, 0x6c, 0x6f, 0x67, 0x73, 0x3b, 0x6c, 0x6f, 0x67, 0x73, 0x62, 0x06, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
diff --git a/proto/mailbox/mailbox.pb.go b/proto/mailbox/mailbox.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..6083aeb26db4fa2470f4d26fd48895be3702397d
--- /dev/null
+++ b/proto/mailbox/mailbox.pb.go
@@ -0,0 +1,567 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.35.2
+// 	protoc        v5.29.0
+// source: mailbox/mailbox.proto
+
+package mailbox
+
+import (
+	common "git.perx.ru/perxis/perxis-go/proto/common"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	emptypb "google.golang.org/protobuf/types/known/emptypb"
+	timestamppb "google.golang.org/protobuf/types/known/timestamppb"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// Сообщение для уведомления
+type Message struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Id        string                 `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`                                // Уникальный идентификатор уведомления
+	ObjectId  string                 `protobuf:"bytes,2,opt,name=object_id,json=objectId,proto3" json:"object_id,omitempty"`    // Идентификатор объекта события
+	From      string                 `protobuf:"bytes,3,opt,name=from,proto3" json:"from,omitempty"`                            // Идентификатор отправителя пользователя/сервиса/подсистемы
+	To        string                 `protobuf:"bytes,4,opt,name=to,proto3" json:"to,omitempty"`                                // Идентификатор получателя пользователя/сервиса/подсистемы
+	Title     string                 `protobuf:"bytes,5,opt,name=title,proto3" json:"title,omitempty"`                          // Заголовок уведомления
+	Message   string                 `protobuf:"bytes,6,opt,name=message,proto3" json:"message,omitempty"`                      // Текст уведомления
+	CreatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` // Время создания
+	IsRead    bool                   `protobuf:"varint,8,opt,name=is_read,json=isRead,proto3" json:"is_read,omitempty"`         // Статус прочтения
+}
+
+func (x *Message) Reset() {
+	*x = Message{}
+	mi := &file_mailbox_mailbox_proto_msgTypes[0]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *Message) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Message) ProtoMessage() {}
+
+func (x *Message) ProtoReflect() protoreflect.Message {
+	mi := &file_mailbox_mailbox_proto_msgTypes[0]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Message.ProtoReflect.Descriptor instead.
+func (*Message) Descriptor() ([]byte, []int) {
+	return file_mailbox_mailbox_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Message) GetId() string {
+	if x != nil {
+		return x.Id
+	}
+	return ""
+}
+
+func (x *Message) GetObjectId() string {
+	if x != nil {
+		return x.ObjectId
+	}
+	return ""
+}
+
+func (x *Message) GetFrom() string {
+	if x != nil {
+		return x.From
+	}
+	return ""
+}
+
+func (x *Message) GetTo() string {
+	if x != nil {
+		return x.To
+	}
+	return ""
+}
+
+func (x *Message) GetTitle() string {
+	if x != nil {
+		return x.Title
+	}
+	return ""
+}
+
+func (x *Message) GetMessage() string {
+	if x != nil {
+		return x.Message
+	}
+	return ""
+}
+
+func (x *Message) GetCreatedAt() *timestamppb.Timestamp {
+	if x != nil {
+		return x.CreatedAt
+	}
+	return nil
+}
+
+func (x *Message) GetIsRead() bool {
+	if x != nil {
+		return x.IsRead
+	}
+	return false
+}
+
+// Отправить уведомление
+type SendMessageRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	To      []string `protobuf:"bytes,1,rep,name=to,proto3" json:"to,omitempty"` // список получателей пользователей/сервисов/подсистем
+	Message *Message `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
+}
+
+func (x *SendMessageRequest) Reset() {
+	*x = SendMessageRequest{}
+	mi := &file_mailbox_mailbox_proto_msgTypes[1]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *SendMessageRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SendMessageRequest) ProtoMessage() {}
+
+func (x *SendMessageRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_mailbox_mailbox_proto_msgTypes[1]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SendMessageRequest.ProtoReflect.Descriptor instead.
+func (*SendMessageRequest) Descriptor() ([]byte, []int) {
+	return file_mailbox_mailbox_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *SendMessageRequest) GetTo() []string {
+	if x != nil {
+		return x.To
+	}
+	return nil
+}
+
+func (x *SendMessageRequest) GetMessage() *Message {
+	if x != nil {
+		return x.Message
+	}
+	return nil
+}
+
+// Запрос на получение уведомлений
+type ListMessageRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Options *FindOptions `protobuf:"bytes,10,opt,name=options,proto3" json:"options,omitempty"`
+}
+
+func (x *ListMessageRequest) Reset() {
+	*x = ListMessageRequest{}
+	mi := &file_mailbox_mailbox_proto_msgTypes[2]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *ListMessageRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListMessageRequest) ProtoMessage() {}
+
+func (x *ListMessageRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_mailbox_mailbox_proto_msgTypes[2]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListMessageRequest.ProtoReflect.Descriptor instead.
+func (*ListMessageRequest) Descriptor() ([]byte, []int) {
+	return file_mailbox_mailbox_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *ListMessageRequest) GetOptions() *FindOptions {
+	if x != nil {
+		return x.Options
+	}
+	return nil
+}
+
+// Ответ на получение уведомлений
+type ListMessageResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Message []*Message `protobuf:"bytes,1,rep,name=message,proto3" json:"message,omitempty"`
+}
+
+func (x *ListMessageResponse) Reset() {
+	*x = ListMessageResponse{}
+	mi := &file_mailbox_mailbox_proto_msgTypes[3]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *ListMessageResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListMessageResponse) ProtoMessage() {}
+
+func (x *ListMessageResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_mailbox_mailbox_proto_msgTypes[3]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListMessageResponse.ProtoReflect.Descriptor instead.
+func (*ListMessageResponse) Descriptor() ([]byte, []int) {
+	return file_mailbox_mailbox_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *ListMessageResponse) GetMessage() []*Message {
+	if x != nil {
+		return x.Message
+	}
+	return nil
+}
+
+// Пометка уведомлений как прочитанных
+type MarkMessagesRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Unread  bool         `protobuf:"varint,1,opt,name=unread,proto3" json:"unread,omitempty"` // Установить статус сообщения не/прочитано
+	Options *FindOptions `protobuf:"bytes,10,opt,name=options,proto3" json:"options,omitempty"`
+}
+
+func (x *MarkMessagesRequest) Reset() {
+	*x = MarkMessagesRequest{}
+	mi := &file_mailbox_mailbox_proto_msgTypes[4]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *MarkMessagesRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MarkMessagesRequest) ProtoMessage() {}
+
+func (x *MarkMessagesRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_mailbox_mailbox_proto_msgTypes[4]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use MarkMessagesRequest.ProtoReflect.Descriptor instead.
+func (*MarkMessagesRequest) Descriptor() ([]byte, []int) {
+	return file_mailbox_mailbox_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *MarkMessagesRequest) GetUnread() bool {
+	if x != nil {
+		return x.Unread
+	}
+	return false
+}
+
+func (x *MarkMessagesRequest) GetOptions() *FindOptions {
+	if x != nil {
+		return x.Options
+	}
+	return nil
+}
+
+type FindOptions struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Recipient  string                 `protobuf:"bytes,1,opt,name=recipient,proto3" json:"recipient,omitempty"`
+	MessageIds []string               `protobuf:"bytes,3,rep,name=message_ids,json=messageIds,proto3" json:"message_ids,omitempty"`
+	After      *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=after,proto3" json:"after,omitempty"`
+	Before     *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=before,proto3" json:"before,omitempty"`
+	Unread     *bool                  `protobuf:"varint,6,opt,name=unread,proto3,oneof" json:"unread,omitempty"`
+	Options    *common.FindOptions    `protobuf:"bytes,10,opt,name=options,proto3" json:"options,omitempty"`
+}
+
+func (x *FindOptions) Reset() {
+	*x = FindOptions{}
+	mi := &file_mailbox_mailbox_proto_msgTypes[5]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *FindOptions) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FindOptions) ProtoMessage() {}
+
+func (x *FindOptions) ProtoReflect() protoreflect.Message {
+	mi := &file_mailbox_mailbox_proto_msgTypes[5]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use FindOptions.ProtoReflect.Descriptor instead.
+func (*FindOptions) Descriptor() ([]byte, []int) {
+	return file_mailbox_mailbox_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *FindOptions) GetRecipient() string {
+	if x != nil {
+		return x.Recipient
+	}
+	return ""
+}
+
+func (x *FindOptions) GetMessageIds() []string {
+	if x != nil {
+		return x.MessageIds
+	}
+	return nil
+}
+
+func (x *FindOptions) GetAfter() *timestamppb.Timestamp {
+	if x != nil {
+		return x.After
+	}
+	return nil
+}
+
+func (x *FindOptions) GetBefore() *timestamppb.Timestamp {
+	if x != nil {
+		return x.Before
+	}
+	return nil
+}
+
+func (x *FindOptions) GetUnread() bool {
+	if x != nil && x.Unread != nil {
+		return *x.Unread
+	}
+	return false
+}
+
+func (x *FindOptions) GetOptions() *common.FindOptions {
+	if x != nil {
+		return x.Options
+	}
+	return nil
+}
+
+var File_mailbox_mailbox_proto protoreflect.FileDescriptor
+
+var file_mailbox_mailbox_proto_rawDesc = []byte{
+	0x0a, 0x15, 0x6d, 0x61, 0x69, 0x6c, 0x62, 0x6f, 0x78, 0x2f, 0x6d, 0x61, 0x69, 0x6c, 0x62, 0x6f,
+	0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2e,
+	0x6d, 0x61, 0x69, 0x6c, 0x62, 0x6f, 0x78, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x13, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d,
+	0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+	0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73,
+	0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xde, 0x01, 0x0a, 0x07, 0x4d,
+	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74,
+	0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x62, 0x6a, 0x65, 0x63,
+	0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x04, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65,
+	0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a,
+	0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
+	0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74,
+	0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
+	0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69,
+	0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64,
+	0x41, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x18, 0x08, 0x20,
+	0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x52, 0x65, 0x61, 0x64, 0x22, 0x57, 0x0a, 0x12, 0x53,
+	0x65, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x02, 0x74,
+	0x6f, 0x12, 0x31, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x69, 0x6c,
+	0x62, 0x6f, 0x78, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73,
+	0x73, 0x61, 0x67, 0x65, 0x22, 0x4b, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73,
+	0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x07, 0x6f, 0x70,
+	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x65,
+	0x72, 0x78, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x62, 0x6f, 0x78, 0x2e, 0x46, 0x69, 0x6e,
+	0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+	0x73, 0x22, 0x48, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73,
+	0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x65, 0x72, 0x78,
+	0x69, 0x73, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x62, 0x6f, 0x78, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61,
+	0x67, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x64, 0x0a, 0x13, 0x4d,
+	0x61, 0x72, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x08, 0x52, 0x06, 0x75, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x12, 0x35, 0x0a, 0x07, 0x6f, 0x70,
+	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x65,
+	0x72, 0x78, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x62, 0x6f, 0x78, 0x2e, 0x46, 0x69, 0x6e,
+	0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+	0x73, 0x22, 0x89, 0x02, 0x0a, 0x0b, 0x46, 0x69, 0x6e, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+	0x73, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12,
+	0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03,
+	0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x73,
+	0x12, 0x30, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+	0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x61, 0x66, 0x74,
+	0x65, 0x72, 0x12, 0x32, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x06,
+	0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x1b, 0x0a, 0x06, 0x75, 0x6e, 0x72, 0x65, 0x61, 0x64,
+	0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x06, 0x75, 0x6e, 0x72, 0x65, 0x61, 0x64,
+	0x88, 0x01, 0x01, 0x12, 0x2d, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0a,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x46, 0x69,
+	0x6e, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f,
+	0x6e, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x75, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x32, 0xed, 0x01,
+	0x0a, 0x07, 0x4d, 0x61, 0x69, 0x6c, 0x62, 0x6f, 0x78, 0x12, 0x44, 0x0a, 0x04, 0x53, 0x65, 0x6e,
+	0x64, 0x12, 0x22, 0x2e, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x62,
+	0x6f, 0x78, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12,
+	0x4f, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x22, 0x2e, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73,
+	0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x62, 0x6f, 0x78, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73,
+	0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x70, 0x65,
+	0x72, 0x78, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x62, 0x6f, 0x78, 0x2e, 0x4c, 0x69, 0x73,
+	0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x12, 0x4b, 0x0a, 0x0a, 0x4d, 0x61, 0x72, 0x6b, 0x41, 0x73, 0x52, 0x65, 0x61, 0x64, 0x12, 0x23,
+	0x2e, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x69, 0x6c, 0x62, 0x6f, 0x78, 0x2e,
+	0x4d, 0x61, 0x72, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x32, 0x5a,
+	0x30, 0x67, 0x69, 0x74, 0x2e, 0x70, 0x65, 0x72, 0x78, 0x2e, 0x72, 0x75, 0x2f, 0x70, 0x65, 0x72,
+	0x78, 0x69, 0x73, 0x2f, 0x70, 0x65, 0x72, 0x78, 0x69, 0x73, 0x2d, 0x67, 0x6f, 0x2f, 0x61, 0x70,
+	0x69, 0x2f, 0x6d, 0x61, 0x69, 0x6c, 0x62, 0x6f, 0x78, 0x3b, 0x6d, 0x61, 0x69, 0x6c, 0x62, 0x6f,
+	0x78, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_mailbox_mailbox_proto_rawDescOnce sync.Once
+	file_mailbox_mailbox_proto_rawDescData = file_mailbox_mailbox_proto_rawDesc
+)
+
+func file_mailbox_mailbox_proto_rawDescGZIP() []byte {
+	file_mailbox_mailbox_proto_rawDescOnce.Do(func() {
+		file_mailbox_mailbox_proto_rawDescData = protoimpl.X.CompressGZIP(file_mailbox_mailbox_proto_rawDescData)
+	})
+	return file_mailbox_mailbox_proto_rawDescData
+}
+
+var file_mailbox_mailbox_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
+var file_mailbox_mailbox_proto_goTypes = []any{
+	(*Message)(nil),               // 0: perxis.mailbox.Message
+	(*SendMessageRequest)(nil),    // 1: perxis.mailbox.SendMessageRequest
+	(*ListMessageRequest)(nil),    // 2: perxis.mailbox.ListMessageRequest
+	(*ListMessageResponse)(nil),   // 3: perxis.mailbox.ListMessageResponse
+	(*MarkMessagesRequest)(nil),   // 4: perxis.mailbox.MarkMessagesRequest
+	(*FindOptions)(nil),           // 5: perxis.mailbox.FindOptions
+	(*timestamppb.Timestamp)(nil), // 6: google.protobuf.Timestamp
+	(*common.FindOptions)(nil),    // 7: common.FindOptions
+	(*emptypb.Empty)(nil),         // 8: google.protobuf.Empty
+}
+var file_mailbox_mailbox_proto_depIdxs = []int32{
+	6,  // 0: perxis.mailbox.Message.created_at:type_name -> google.protobuf.Timestamp
+	0,  // 1: perxis.mailbox.SendMessageRequest.message:type_name -> perxis.mailbox.Message
+	5,  // 2: perxis.mailbox.ListMessageRequest.options:type_name -> perxis.mailbox.FindOptions
+	0,  // 3: perxis.mailbox.ListMessageResponse.message:type_name -> perxis.mailbox.Message
+	5,  // 4: perxis.mailbox.MarkMessagesRequest.options:type_name -> perxis.mailbox.FindOptions
+	6,  // 5: perxis.mailbox.FindOptions.after:type_name -> google.protobuf.Timestamp
+	6,  // 6: perxis.mailbox.FindOptions.before:type_name -> google.protobuf.Timestamp
+	7,  // 7: perxis.mailbox.FindOptions.options:type_name -> common.FindOptions
+	1,  // 8: perxis.mailbox.Mailbox.Send:input_type -> perxis.mailbox.SendMessageRequest
+	2,  // 9: perxis.mailbox.Mailbox.List:input_type -> perxis.mailbox.ListMessageRequest
+	4,  // 10: perxis.mailbox.Mailbox.MarkAsRead:input_type -> perxis.mailbox.MarkMessagesRequest
+	8,  // 11: perxis.mailbox.Mailbox.Send:output_type -> google.protobuf.Empty
+	3,  // 12: perxis.mailbox.Mailbox.List:output_type -> perxis.mailbox.ListMessageResponse
+	8,  // 13: perxis.mailbox.Mailbox.MarkAsRead:output_type -> google.protobuf.Empty
+	11, // [11:14] is the sub-list for method output_type
+	8,  // [8:11] is the sub-list for method input_type
+	8,  // [8:8] is the sub-list for extension type_name
+	8,  // [8:8] is the sub-list for extension extendee
+	0,  // [0:8] is the sub-list for field type_name
+}
+
+func init() { file_mailbox_mailbox_proto_init() }
+func file_mailbox_mailbox_proto_init() {
+	if File_mailbox_mailbox_proto != nil {
+		return
+	}
+	file_mailbox_mailbox_proto_msgTypes[5].OneofWrappers = []any{}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_mailbox_mailbox_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   6,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_mailbox_mailbox_proto_goTypes,
+		DependencyIndexes: file_mailbox_mailbox_proto_depIdxs,
+		MessageInfos:      file_mailbox_mailbox_proto_msgTypes,
+	}.Build()
+	File_mailbox_mailbox_proto = out.File
+	file_mailbox_mailbox_proto_rawDesc = nil
+	file_mailbox_mailbox_proto_goTypes = nil
+	file_mailbox_mailbox_proto_depIdxs = nil
+}
diff --git a/proto/mailbox/mailbox_grpc.pb.go b/proto/mailbox/mailbox_grpc.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..19e54c066f7b37a7aeb1acfa78617ca3a06381fd
--- /dev/null
+++ b/proto/mailbox/mailbox_grpc.pb.go
@@ -0,0 +1,208 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.5.1
+// - protoc             v5.29.0
+// source: mailbox/mailbox.proto
+
+package mailbox
+
+import (
+	context "context"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+	emptypb "google.golang.org/protobuf/types/known/emptypb"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+// Requires gRPC-Go v1.64.0 or later.
+const _ = grpc.SupportPackageIsVersion9
+
+const (
+	Mailbox_Send_FullMethodName       = "/perxis.mailbox.Mailbox/Send"
+	Mailbox_List_FullMethodName       = "/perxis.mailbox.Mailbox/List"
+	Mailbox_MarkAsRead_FullMethodName = "/perxis.mailbox.Mailbox/MarkAsRead"
+)
+
+// MailboxClient is the client API for Mailbox service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+//
+// Сервис уведомлений
+type MailboxClient interface {
+	// Отправка уведомления
+	Send(ctx context.Context, in *SendMessageRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
+	// Получение уведомлений, поле to в Message всегда содержит только получателя из запроса
+	List(ctx context.Context, in *ListMessageRequest, opts ...grpc.CallOption) (*ListMessageResponse, error)
+	// Пометка уведомлений как прочитанных
+	MarkAsRead(ctx context.Context, in *MarkMessagesRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
+}
+
+type mailboxClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewMailboxClient(cc grpc.ClientConnInterface) MailboxClient {
+	return &mailboxClient{cc}
+}
+
+func (c *mailboxClient) Send(ctx context.Context, in *SendMessageRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
+	cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+	out := new(emptypb.Empty)
+	err := c.cc.Invoke(ctx, Mailbox_Send_FullMethodName, in, out, cOpts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *mailboxClient) List(ctx context.Context, in *ListMessageRequest, opts ...grpc.CallOption) (*ListMessageResponse, error) {
+	cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+	out := new(ListMessageResponse)
+	err := c.cc.Invoke(ctx, Mailbox_List_FullMethodName, in, out, cOpts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *mailboxClient) MarkAsRead(ctx context.Context, in *MarkMessagesRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
+	cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+	out := new(emptypb.Empty)
+	err := c.cc.Invoke(ctx, Mailbox_MarkAsRead_FullMethodName, in, out, cOpts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// MailboxServer is the server API for Mailbox service.
+// All implementations must embed UnimplementedMailboxServer
+// for forward compatibility.
+//
+// Сервис уведомлений
+type MailboxServer interface {
+	// Отправка уведомления
+	Send(context.Context, *SendMessageRequest) (*emptypb.Empty, error)
+	// Получение уведомлений, поле to в Message всегда содержит только получателя из запроса
+	List(context.Context, *ListMessageRequest) (*ListMessageResponse, error)
+	// Пометка уведомлений как прочитанных
+	MarkAsRead(context.Context, *MarkMessagesRequest) (*emptypb.Empty, error)
+	mustEmbedUnimplementedMailboxServer()
+}
+
+// UnimplementedMailboxServer must be embedded to have
+// forward compatible implementations.
+//
+// NOTE: this should be embedded by value instead of pointer to avoid a nil
+// pointer dereference when methods are called.
+type UnimplementedMailboxServer struct{}
+
+func (UnimplementedMailboxServer) Send(context.Context, *SendMessageRequest) (*emptypb.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method Send not implemented")
+}
+func (UnimplementedMailboxServer) List(context.Context, *ListMessageRequest) (*ListMessageResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method List not implemented")
+}
+func (UnimplementedMailboxServer) MarkAsRead(context.Context, *MarkMessagesRequest) (*emptypb.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method MarkAsRead not implemented")
+}
+func (UnimplementedMailboxServer) mustEmbedUnimplementedMailboxServer() {}
+func (UnimplementedMailboxServer) testEmbeddedByValue()                 {}
+
+// UnsafeMailboxServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to MailboxServer will
+// result in compilation errors.
+type UnsafeMailboxServer interface {
+	mustEmbedUnimplementedMailboxServer()
+}
+
+func RegisterMailboxServer(s grpc.ServiceRegistrar, srv MailboxServer) {
+	// If the following call pancis, it indicates UnimplementedMailboxServer was
+	// embedded by pointer and is nil.  This will cause panics if an
+	// unimplemented method is ever invoked, so we test this at initialization
+	// time to prevent it from happening at runtime later due to I/O.
+	if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
+		t.testEmbeddedByValue()
+	}
+	s.RegisterService(&Mailbox_ServiceDesc, srv)
+}
+
+func _Mailbox_Send_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(SendMessageRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(MailboxServer).Send(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: Mailbox_Send_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(MailboxServer).Send(ctx, req.(*SendMessageRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Mailbox_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ListMessageRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(MailboxServer).List(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: Mailbox_List_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(MailboxServer).List(ctx, req.(*ListMessageRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Mailbox_MarkAsRead_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(MarkMessagesRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(MailboxServer).MarkAsRead(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: Mailbox_MarkAsRead_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(MailboxServer).MarkAsRead(ctx, req.(*MarkMessagesRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+// Mailbox_ServiceDesc is the grpc.ServiceDesc for Mailbox service.
+// It's only intended for direct use with grpc.RegisterService,
+// and not to be introspected or modified (even as a copy)
+var Mailbox_ServiceDesc = grpc.ServiceDesc{
+	ServiceName: "perxis.mailbox.Mailbox",
+	HandlerType: (*MailboxServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "Send",
+			Handler:    _Mailbox_Send_Handler,
+		},
+		{
+			MethodName: "List",
+			Handler:    _Mailbox_List_Handler,
+		},
+		{
+			MethodName: "MarkAsRead",
+			Handler:    _Mailbox_MarkAsRead_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "mailbox/mailbox.proto",
+}
diff --git a/proto/mocks/ItemsClient.go b/proto/mocks/ItemsClient.go
index 0bbd76f109c2b000988840f2b1c53271794f176d..7e8a6ca464d7cab82938a05d1d6b77b23a8de9a8 100644
--- a/proto/mocks/ItemsClient.go
+++ b/proto/mocks/ItemsClient.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.46.3. DO NOT EDIT.
+// Code generated by mockery v2.49.0. DO NOT EDIT.
 
 package mocks
 
@@ -129,6 +129,43 @@ func (_m *ItemsClient) Archive(ctx context.Context, in *items.ArchiveRequest, op
 	return r0, r1
 }
 
+// CheckoutRevision provides a mock function with given fields: ctx, in, opts
+func (_m *ItemsClient) CheckoutRevision(ctx context.Context, in *items.CheckoutRevisionRequest, opts ...grpc.CallOption) (*items.CheckoutRevisionResponse, error) {
+	_va := make([]interface{}, len(opts))
+	for _i := range opts {
+		_va[_i] = opts[_i]
+	}
+	var _ca []interface{}
+	_ca = append(_ca, ctx, in)
+	_ca = append(_ca, _va...)
+	ret := _m.Called(_ca...)
+
+	if len(ret) == 0 {
+		panic("no return value specified for CheckoutRevision")
+	}
+
+	var r0 *items.CheckoutRevisionResponse
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, *items.CheckoutRevisionRequest, ...grpc.CallOption) (*items.CheckoutRevisionResponse, error)); ok {
+		return rf(ctx, in, opts...)
+	}
+	if rf, ok := ret.Get(0).(func(context.Context, *items.CheckoutRevisionRequest, ...grpc.CallOption) *items.CheckoutRevisionResponse); ok {
+		r0 = rf(ctx, in, opts...)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*items.CheckoutRevisionResponse)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(context.Context, *items.CheckoutRevisionRequest, ...grpc.CallOption) error); ok {
+		r1 = rf(ctx, in, opts...)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
 // Create provides a mock function with given fields: ctx, in, opts
 func (_m *ItemsClient) Create(ctx context.Context, in *items.CreateRequest, opts ...grpc.CallOption) (*items.CreateResponse, error) {
 	_va := make([]interface{}, len(opts))
@@ -351,6 +388,43 @@ func (_m *ItemsClient) Get(ctx context.Context, in *items.GetRequest, opts ...gr
 	return r0, r1
 }
 
+// GetArchived provides a mock function with given fields: ctx, in, opts
+func (_m *ItemsClient) GetArchived(ctx context.Context, in *items.GetArchivedRequest, opts ...grpc.CallOption) (*items.GetArchivedResponse, error) {
+	_va := make([]interface{}, len(opts))
+	for _i := range opts {
+		_va[_i] = opts[_i]
+	}
+	var _ca []interface{}
+	_ca = append(_ca, ctx, in)
+	_ca = append(_ca, _va...)
+	ret := _m.Called(_ca...)
+
+	if len(ret) == 0 {
+		panic("no return value specified for GetArchived")
+	}
+
+	var r0 *items.GetArchivedResponse
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, *items.GetArchivedRequest, ...grpc.CallOption) (*items.GetArchivedResponse, error)); ok {
+		return rf(ctx, in, opts...)
+	}
+	if rf, ok := ret.Get(0).(func(context.Context, *items.GetArchivedRequest, ...grpc.CallOption) *items.GetArchivedResponse); ok {
+		r0 = rf(ctx, in, opts...)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*items.GetArchivedResponse)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(context.Context, *items.GetArchivedRequest, ...grpc.CallOption) error); ok {
+		r1 = rf(ctx, in, opts...)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
 // GetPublished provides a mock function with given fields: ctx, in, opts
 func (_m *ItemsClient) GetPublished(ctx context.Context, in *items.GetPublishedRequest, opts ...grpc.CallOption) (*items.GetPublishedResponse, error) {
 	_va := make([]interface{}, len(opts))
diff --git a/proto/mocks/ItemsServer.go b/proto/mocks/ItemsServer.go
index 84e55b69c67766e25de19414db1dc4c30b862bb2..c695997f3f8e556cf09bd7f3e74a706b5ca0c4ea 100644
--- a/proto/mocks/ItemsServer.go
+++ b/proto/mocks/ItemsServer.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.46.3. DO NOT EDIT.
+// Code generated by mockery v2.49.0. DO NOT EDIT.
 
 package mocks
 
@@ -106,6 +106,36 @@ func (_m *ItemsServer) Archive(_a0 context.Context, _a1 *items.ArchiveRequest) (
 	return r0, r1
 }
 
+// CheckoutRevision provides a mock function with given fields: _a0, _a1
+func (_m *ItemsServer) CheckoutRevision(_a0 context.Context, _a1 *items.CheckoutRevisionRequest) (*items.CheckoutRevisionResponse, error) {
+	ret := _m.Called(_a0, _a1)
+
+	if len(ret) == 0 {
+		panic("no return value specified for CheckoutRevision")
+	}
+
+	var r0 *items.CheckoutRevisionResponse
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, *items.CheckoutRevisionRequest) (*items.CheckoutRevisionResponse, error)); ok {
+		return rf(_a0, _a1)
+	}
+	if rf, ok := ret.Get(0).(func(context.Context, *items.CheckoutRevisionRequest) *items.CheckoutRevisionResponse); ok {
+		r0 = rf(_a0, _a1)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*items.CheckoutRevisionResponse)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(context.Context, *items.CheckoutRevisionRequest) error); ok {
+		r1 = rf(_a0, _a1)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
 // Create provides a mock function with given fields: _a0, _a1
 func (_m *ItemsServer) Create(_a0 context.Context, _a1 *items.CreateRequest) (*items.CreateResponse, error) {
 	ret := _m.Called(_a0, _a1)
@@ -286,6 +316,36 @@ func (_m *ItemsServer) Get(_a0 context.Context, _a1 *items.GetRequest) (*items.G
 	return r0, r1
 }
 
+// GetArchived provides a mock function with given fields: _a0, _a1
+func (_m *ItemsServer) GetArchived(_a0 context.Context, _a1 *items.GetArchivedRequest) (*items.GetArchivedResponse, error) {
+	ret := _m.Called(_a0, _a1)
+
+	if len(ret) == 0 {
+		panic("no return value specified for GetArchived")
+	}
+
+	var r0 *items.GetArchivedResponse
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, *items.GetArchivedRequest) (*items.GetArchivedResponse, error)); ok {
+		return rf(_a0, _a1)
+	}
+	if rf, ok := ret.Get(0).(func(context.Context, *items.GetArchivedRequest) *items.GetArchivedResponse); ok {
+		r0 = rf(_a0, _a1)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*items.GetArchivedResponse)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(context.Context, *items.GetArchivedRequest) error); ok {
+		r1 = rf(_a0, _a1)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
 // GetPublished provides a mock function with given fields: _a0, _a1
 func (_m *ItemsServer) GetPublished(_a0 context.Context, _a1 *items.GetPublishedRequest) (*items.GetPublishedResponse, error) {
 	ret := _m.Called(_a0, _a1)
diff --git a/proto/mocks/MailboxClient.go b/proto/mocks/MailboxClient.go
new file mode 100644
index 0000000000000000000000000000000000000000..bc15d49e1394cc5f30e928685be649ee86a3de5f
--- /dev/null
+++ b/proto/mocks/MailboxClient.go
@@ -0,0 +1,144 @@
+// Code generated by mockery v2.50.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	context "context"
+
+	grpc "google.golang.org/grpc"
+	emptypb "google.golang.org/protobuf/types/known/emptypb"
+
+	mailbox "git.perx.ru/perxis/perxis-go/proto/mailbox"
+
+	mock "github.com/stretchr/testify/mock"
+)
+
+// MailboxClient is an autogenerated mock type for the MailboxClient type
+type MailboxClient struct {
+	mock.Mock
+}
+
+// List provides a mock function with given fields: ctx, in, opts
+func (_m *MailboxClient) List(ctx context.Context, in *mailbox.ListMessageRequest, opts ...grpc.CallOption) (*mailbox.ListMessageResponse, error) {
+	_va := make([]interface{}, len(opts))
+	for _i := range opts {
+		_va[_i] = opts[_i]
+	}
+	var _ca []interface{}
+	_ca = append(_ca, ctx, in)
+	_ca = append(_ca, _va...)
+	ret := _m.Called(_ca...)
+
+	if len(ret) == 0 {
+		panic("no return value specified for List")
+	}
+
+	var r0 *mailbox.ListMessageResponse
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, *mailbox.ListMessageRequest, ...grpc.CallOption) (*mailbox.ListMessageResponse, error)); ok {
+		return rf(ctx, in, opts...)
+	}
+	if rf, ok := ret.Get(0).(func(context.Context, *mailbox.ListMessageRequest, ...grpc.CallOption) *mailbox.ListMessageResponse); ok {
+		r0 = rf(ctx, in, opts...)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*mailbox.ListMessageResponse)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(context.Context, *mailbox.ListMessageRequest, ...grpc.CallOption) error); ok {
+		r1 = rf(ctx, in, opts...)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// MarkAsRead provides a mock function with given fields: ctx, in, opts
+func (_m *MailboxClient) MarkAsRead(ctx context.Context, in *mailbox.MarkMessagesRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
+	_va := make([]interface{}, len(opts))
+	for _i := range opts {
+		_va[_i] = opts[_i]
+	}
+	var _ca []interface{}
+	_ca = append(_ca, ctx, in)
+	_ca = append(_ca, _va...)
+	ret := _m.Called(_ca...)
+
+	if len(ret) == 0 {
+		panic("no return value specified for MarkAsRead")
+	}
+
+	var r0 *emptypb.Empty
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, *mailbox.MarkMessagesRequest, ...grpc.CallOption) (*emptypb.Empty, error)); ok {
+		return rf(ctx, in, opts...)
+	}
+	if rf, ok := ret.Get(0).(func(context.Context, *mailbox.MarkMessagesRequest, ...grpc.CallOption) *emptypb.Empty); ok {
+		r0 = rf(ctx, in, opts...)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*emptypb.Empty)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(context.Context, *mailbox.MarkMessagesRequest, ...grpc.CallOption) error); ok {
+		r1 = rf(ctx, in, opts...)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// Send provides a mock function with given fields: ctx, in, opts
+func (_m *MailboxClient) Send(ctx context.Context, in *mailbox.SendMessageRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
+	_va := make([]interface{}, len(opts))
+	for _i := range opts {
+		_va[_i] = opts[_i]
+	}
+	var _ca []interface{}
+	_ca = append(_ca, ctx, in)
+	_ca = append(_ca, _va...)
+	ret := _m.Called(_ca...)
+
+	if len(ret) == 0 {
+		panic("no return value specified for Send")
+	}
+
+	var r0 *emptypb.Empty
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, *mailbox.SendMessageRequest, ...grpc.CallOption) (*emptypb.Empty, error)); ok {
+		return rf(ctx, in, opts...)
+	}
+	if rf, ok := ret.Get(0).(func(context.Context, *mailbox.SendMessageRequest, ...grpc.CallOption) *emptypb.Empty); ok {
+		r0 = rf(ctx, in, opts...)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*emptypb.Empty)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(context.Context, *mailbox.SendMessageRequest, ...grpc.CallOption) error); ok {
+		r1 = rf(ctx, in, opts...)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// NewMailboxClient creates a new instance of MailboxClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewMailboxClient(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *MailboxClient {
+	mock := &MailboxClient{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/proto/mocks/MailboxServer.go b/proto/mocks/MailboxServer.go
new file mode 100644
index 0000000000000000000000000000000000000000..8dcf00553cbda1ed91176a1a8d00716e233b761d
--- /dev/null
+++ b/proto/mocks/MailboxServer.go
@@ -0,0 +1,126 @@
+// Code generated by mockery v2.50.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	context "context"
+
+	mailbox "git.perx.ru/perxis/perxis-go/proto/mailbox"
+	emptypb "google.golang.org/protobuf/types/known/emptypb"
+
+	mock "github.com/stretchr/testify/mock"
+)
+
+// MailboxServer is an autogenerated mock type for the MailboxServer type
+type MailboxServer struct {
+	mock.Mock
+}
+
+// List provides a mock function with given fields: _a0, _a1
+func (_m *MailboxServer) List(_a0 context.Context, _a1 *mailbox.ListMessageRequest) (*mailbox.ListMessageResponse, error) {
+	ret := _m.Called(_a0, _a1)
+
+	if len(ret) == 0 {
+		panic("no return value specified for List")
+	}
+
+	var r0 *mailbox.ListMessageResponse
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, *mailbox.ListMessageRequest) (*mailbox.ListMessageResponse, error)); ok {
+		return rf(_a0, _a1)
+	}
+	if rf, ok := ret.Get(0).(func(context.Context, *mailbox.ListMessageRequest) *mailbox.ListMessageResponse); ok {
+		r0 = rf(_a0, _a1)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*mailbox.ListMessageResponse)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(context.Context, *mailbox.ListMessageRequest) error); ok {
+		r1 = rf(_a0, _a1)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// MarkAsRead provides a mock function with given fields: _a0, _a1
+func (_m *MailboxServer) MarkAsRead(_a0 context.Context, _a1 *mailbox.MarkMessagesRequest) (*emptypb.Empty, error) {
+	ret := _m.Called(_a0, _a1)
+
+	if len(ret) == 0 {
+		panic("no return value specified for MarkAsRead")
+	}
+
+	var r0 *emptypb.Empty
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, *mailbox.MarkMessagesRequest) (*emptypb.Empty, error)); ok {
+		return rf(_a0, _a1)
+	}
+	if rf, ok := ret.Get(0).(func(context.Context, *mailbox.MarkMessagesRequest) *emptypb.Empty); ok {
+		r0 = rf(_a0, _a1)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*emptypb.Empty)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(context.Context, *mailbox.MarkMessagesRequest) error); ok {
+		r1 = rf(_a0, _a1)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// Send provides a mock function with given fields: _a0, _a1
+func (_m *MailboxServer) Send(_a0 context.Context, _a1 *mailbox.SendMessageRequest) (*emptypb.Empty, error) {
+	ret := _m.Called(_a0, _a1)
+
+	if len(ret) == 0 {
+		panic("no return value specified for Send")
+	}
+
+	var r0 *emptypb.Empty
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, *mailbox.SendMessageRequest) (*emptypb.Empty, error)); ok {
+		return rf(_a0, _a1)
+	}
+	if rf, ok := ret.Get(0).(func(context.Context, *mailbox.SendMessageRequest) *emptypb.Empty); ok {
+		r0 = rf(_a0, _a1)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*emptypb.Empty)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(context.Context, *mailbox.SendMessageRequest) error); ok {
+		r1 = rf(_a0, _a1)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// mustEmbedUnimplementedMailboxServer provides a mock function with no fields
+func (_m *MailboxServer) mustEmbedUnimplementedMailboxServer() {
+	_m.Called()
+}
+
+// NewMailboxServer creates a new instance of MailboxServer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewMailboxServer(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *MailboxServer {
+	mock := &MailboxServer{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/proto/mocks/UnsafeItemsServer.go b/proto/mocks/UnsafeItemsServer.go
index 5db884b3261906fcc5393f7dfc4db611d06bd827..79bfa1521605d3c42d4fcf502373f31c11f5ede3 100644
--- a/proto/mocks/UnsafeItemsServer.go
+++ b/proto/mocks/UnsafeItemsServer.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.46.3. DO NOT EDIT.
+// Code generated by mockery v2.49.0. DO NOT EDIT.
 
 package mocks
 
diff --git a/proto/mocks/UnsafeMailboxServer.go b/proto/mocks/UnsafeMailboxServer.go
new file mode 100644
index 0000000000000000000000000000000000000000..3b55320322036f8860571c4489034c6a16774486
--- /dev/null
+++ b/proto/mocks/UnsafeMailboxServer.go
@@ -0,0 +1,29 @@
+// Code generated by mockery v2.50.0. DO NOT EDIT.
+
+package mocks
+
+import mock "github.com/stretchr/testify/mock"
+
+// UnsafeMailboxServer is an autogenerated mock type for the UnsafeMailboxServer type
+type UnsafeMailboxServer struct {
+	mock.Mock
+}
+
+// mustEmbedUnimplementedMailboxServer provides a mock function with no fields
+func (_m *UnsafeMailboxServer) mustEmbedUnimplementedMailboxServer() {
+	_m.Called()
+}
+
+// NewUnsafeMailboxServer creates a new instance of UnsafeMailboxServer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewUnsafeMailboxServer(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *UnsafeMailboxServer {
+	mock := &UnsafeMailboxServer{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}