/*
  Сервис реализует функционал управления объектами строительства телеметрии
*/
syntax = "proto3";

import "google/api/annotations.proto";
import "google/api/field_behavior.proto";
import "google/protobuf/wrappers.proto";
import "google/protobuf/timestamp.proto";

package keyapis.telemetry_control.v1;

option java_package = "ru.keyapis.telemetry_control.v1";
option java_outer_classname = "KeyapisTelemetryControlV1Proto";
option java_multiple_files = false;
option java_string_check_utf8 = true;
option go_package = "/keyapis_telemetry_control_v1";
option cc_enable_arenas = true;
option csharp_namespace = "Keyapis.TelemetryControl.V1";
option objc_class_prefix = "KEYAPISTELEMETRYCONTROLV1";
option php_namespace = "Keyapis\\TelemetryControl\\V1";
option ruby_package = "Keyapis::TelemetryControl::V1";
option optimize_for = LITE_RUNTIME;

// Сервис управления объектами строительства телеметрии.
// Авторизация:
//   - Authorization: Bearer token.
//   - X-Api-Key: apiKey
service BuildingService {
  // Метод получения объекта строительства.
  // Разрешения: telemetry_control:building:card, telemetry_control:building:card:own.
  // Метод доступен для: Token: admin, service, bti, seller, application, owner, employee. При наличии разрешений.
  // Метод доступен для: ApiKey: При наличии разрешений
  rpc GetBuilding (GetBuildingRequest) returns (GetBuildingResponse) {
    option (google.api.http) = {
      get: "/telemetry_control/api/v1/building/{id}"
    };
  }
  // Метод получения списка объектов строительства.
  // Разрешения: telemetry_control:building:list, telemetry_control:building:list:own.
  // Метод доступен для: Token: admin, service, bti, seller, application, owner, employee. При наличии разрешений.
  // Метод доступен для: ApiKey: При наличии разрешений
  rpc GetBuildingList (GetBuildingListRequest) returns (stream GetBuildingListResponse) {
    option (google.api.http) = {
      get: "/telemetry_control/api/v1/building/list"
    };
  }
  // Метод получения количества объектов строительства.
  // Разрешения: telemetry_control:building:list, telemetry_control:building:list:own.
  // Метод доступен для: Token: admin, service, bti, seller, application, owner, employee. При наличии разрешений.
  // Метод доступен для: ApiKey: При наличии разрешений
  rpc GetBuildingCount (GetBuildingCountRequest) returns (GetBuildingCountResponse) {
    option (google.api.http) = {
      get: "/telemetry_control/api/v1/building/count"
    };
  }
  // Метод сохранения объекта строительства.
  // Поддерживает создание и обновление.
  // Разрешения: telemetry_control:building:save, telemetry_control:building:save:own.
  // Метод доступен для: Token: admin, service, bti, seller, application, owner, employee. При наличии разрешений
  rpc PostBuilding (PostBuildingRequest) returns (PostBuildingResponse) {
    option (google.api.http) = {
      post: "/telemetry_control/api/v1/building"
      body: "*"
    };
  }
  // Полнодуплексный метод отправки статусов на сервер и получения изменения со стороны сервера.
  // Разрешения: telemetry_control:building:list, telemetry_control:building:list:own.
  // Метод доступен для: Token: admin, service, bti, seller, application, owner, employee. При наличии разрешений.
  // Метод доступен для: ApiKey: Без учета разрешений
  rpc PostBuildingFullDuplex (stream PostBuildingFullDuplexRequest) returns (stream PostBuildingFullDuplexResponse) {}
  // Метод удаления объекта строительства.
  // Разрешения: telemetry_control:building:remove, telemetry_control:building:remove:own.
  // Метод доступен для: admin, service, bti, seller, application, owner, employee. При наличии разрешений
  rpc DeleteBuilding (DeleteBuildingRequest) returns (DeleteBuildingResponse) {
    option (google.api.http) = {
      delete: "/telemetry_control/api/v1/building/{id}"
    };
  }
  // Метод получения списка связей объектов строительства и группы пользователя.
  // Метод доступен для: Token: admin, service, bti, seller. Без учета разрешений
  rpc GetBuildingGroupList (GetBuildingGroupListRequest) returns (stream GetBuildingGroupListResponse) {
    option (google.api.http) = {
      get: "/telemetry_control/api/v1/building/group/list"
    };
  }
  // Метод получения количества связей объектов строительства и группы пользователя.
  // Метод доступен для: Token: admin, service, bti, seller. Без учета разрешений
  rpc GetBuildingGroupCount (GetBuildingGroupCountRequest) returns (GetBuildingGroupCountResponse) {
    option (google.api.http) = {
      get: "/telemetry_control/api/v1/building/group/count"
    };
  }
  // Метод сохранения связей объектов строительства и группы пользователя.
  // Поддерживает только создание.
  // Метод доступен для: Token: admin, service, bti, seller. Без учета разрешений
  rpc PutBuildingGroupAttach (PutBuildingGroupAttachRequest) returns (PutBuildingGroupAttachResponse) {
    option (google.api.http) = {
      put: "/telemetry_control/api/v1/building/{building_group.building_id}/group/{building_group.group_id}/attach"
    };
  }
  // Метод удаления связей объектов строительства и группы пользователя.
  // Метод доступен для: Token: admin, service, bti, seller. Без учета разрешений
  rpc PutBuildingGroupDetach (PutBuildingGroupDetachRequest) returns (PutBuildingGroupDetachResponse) {
    option (google.api.http) = {
      put: "/telemetry_control/api/v1/building/{building_group.building_id}/group/{building_group.group_id}/detach"
    };
  }
}

// Запрос сохранения объекта строительства
message PostBuildingRequest {
  // Объект строительства
  Building data = 1 [(google.api.field_behavior) = REQUIRED];
}

// Запрос сохранения связей объектов строительства и группы пользователя
message PutBuildingGroupAttachRequest {
  // Связь объекта строительства и группы пользователя
  BuildingGroup building_group = 1 [(google.api.field_behavior) = REQUIRED];
}

// Ответ на запрос сохранения объекта строительства
message PostBuildingResponse {
  // Тип результата
  oneof type {
    // Объект строительства
    Building data = 1;
  }
}

// Ответ на запрос сохранения связи объекта строительства и группы пользователя
message PutBuildingGroupAttachResponse {}

// Запрос получения объекта строительства
message GetBuildingRequest {
  // Идентификатор объекта строительства
  int32 id = 1 [(google.api.field_behavior) = REQUIRED];
}

// Ответ на запрос получения объекта строительства
message GetBuildingResponse {
  // Тип результата
  oneof type {
    // Объект строительства
    Building data = 1;
  }
}

// Запрос получения списка
message GetBuildingListRequest {
  // Фильтр индикаторов
  BuildingFilter filter = 1;
  // Вариант разбиения на страницы
  oneof pagination {
    // Пагинация по индикаторам
    BuildingPaging paging = 2;
  }
}

// Запрос получения списка
message GetBuildingGroupListRequest {
  // Фильтр связей объектов строительства и группы пользователя
  BuildingGroupFilter filter = 1;
  // Вариант разбиения на страницы
  oneof pagination {
    // Пагинация
    BuildingGroupPaging paging = 2;
  }
}

// Пагинация связей объектов строительства и группы пользователя
message BuildingGroupPaging {
  // Справочник типов сортировки
  enum OrderByType {
    // Значение не указано
    ORDER_BY_TYPE_UNKNOWN = 0;
    // По Идентификатору группы пользователя
    GROUP_ID = 1;
    // По Объекту строительства
    BUILDING_ID = 2;
  }
  // Тип значения сортировки.
  // По умолчанию: ID
  OrderByType order_by_type = 1;
  // Справочник типов направлений сортировки
  enum DirectionType {
    // Значение не указано
    DIRECTION_TYPE_UNKNOWN = 0;
    // От большего к меньшему
    DESC = 1;
    // От меньшего к большему
    ASC = 2;
  }
  // Тип направления сортировки.
  // По умолчанию: DESC
  DirectionType direction_type = 2;
  // Количество записей на страницу.
  // Минимальное значение: 1.
  // Максимальное значение: 100.
  // По умолчанию: 20.
  // Если значение 0 (не передано), то выставляем значение по умолчанию
  int32 limit = 3;
  // Сдвиг.
  // По умолчанию: 0
  int32 offset = 4;
}

// Пагинация объектов строительства
message BuildingPaging {
  // Справочник типов сортировки
  enum OrderByType {
    // Значение не указано
    ORDER_BY_TYPE_UNKNOWN = 0;
    // По уникальному ключу
    ID = 1;
    // По наименованию
    TITLE = 2;
    // По дате создания
    CREATED_AT = 3;
    // По дате изменения
    CHANGED_AT = 4;
    // По ФИАС
    FIAS_ID = 5;
  }
  // Тип значения сортировки.
  // По умолчанию: ID
  OrderByType order_by_type = 1;
  // Справочник типов направлений сортировки
  enum DirectionType {
    // Значение не указано
    DIRECTION_TYPE_UNKNOWN = 0;
    // От большего к меньшему
    DESC = 1;
    // От меньшего к большему
    ASC = 2;
  }
  // Тип направления сортировки.
  // По умолчанию: DESC
  DirectionType direction_type = 2;
  // Количество записей на страницу.
  // Минимальное значение: 1.
  // Максимальное значение: 100.
  // По умолчанию: 20.
  // Если значение 0 (не передано), то выставляем значение по умолчанию
  int32 limit = 3;
  // Сдвиг.
  // По умолчанию: 0
  int32 offset = 4;
}

// Ответ на запрос получения списка объектов строительства
message GetBuildingListResponse {
  // Тип результата
  oneof type {
    // Индикатор
    Building data = 1;
  }
}

// Ответ на запрос получения списка связей объектов строительства и группы пользователя
message GetBuildingGroupListResponse {
  // Тип результата
  oneof type {
    // Связь объекта строительства и группы пользователя
    BuildingGroup data = 1;
  }
}

// Событие создания/изменения объекта строительства на сервера
message PostBuildingFullDuplexResponse {
  // Событие удаления объекта строительства
  message RemoveBuildingEvent {
    // Идентификатор объекта строительства
    int32 id = 1 [(google.api.field_behavior) = REQUIRED];
  }
  // Событие создания/обновления объекта строительства
  message UpsertBuildingEvent {
    // Объект строительства
    Building data = 1 [(google.api.field_behavior) = REQUIRED];
  }
  // Идентификатор запроса
  string request_id = 1 [(google.api.field_behavior) = REQUIRED];
  // Событие
  oneof event {
    // Событие создания/обновления объекта строительства
    UpsertBuildingEvent upsert_building_event = 2;
    // Событие удаления объекта строительства
    RemoveBuildingEvent remove_building_event = 3;
  }
}

// Запрос создания задачи с клиента на сервере
message PostBuildingFullDuplexRequest {
  // Результат обработки объекта строительства на клиенте
  message BuildingAsyncStatus {
    // Команда принята
    message Success {}
    // Ошибки обработки объекта строительства на клиенте
    message Error {
      // Неизвестная ошибка на стороне клиента
      message UnknownError {
        // Произвольный текст ошибки на стороне клиента.
        // Отправляется в случае если в спецификации нет подходящей ошибки.
        // После анализа таких ошибок в спецификацию добавляется специальный тип под эту ошибку
        string message = 1 [(google.api.field_behavior) = REQUIRED];
      }
      // Причина ошибки
      oneof reason {
        // Неизвестная ошибка
        UnknownError unknown = 1;
      }
    }
    // Идентификатор объекта строительства
    int32 building_id = 1 [(google.api.field_behavior) = REQUIRED];
    // Тип результата
    oneof type {
      // Успех
      Success data = 2;
      // Ошибка
      Error error = 3;
    }
  }

  // Идентификатор запроса
  string request_id = 1 [(google.api.field_behavior) = REQUIRED];
  // Задача с клиента
  oneof task {
    // Результат обработки объекта строительства на клиенте
    BuildingAsyncStatus building_async_status = 2;
  }
}


// Фильтр для запроса объектов строительства.
// При передаче массива в параметр фильтра элементы массива работают в выборке через ИЛИ.
// При передаче нескольких разных параметров фильтра они работают в выборке через И
message BuildingFilter {
  // По ФИАС
  repeated google.protobuf.StringValue fias_id = 1;
  // По заголовку
  google.protobuf.StringValue title = 2;
  // По нижней границе дате создания
  google.protobuf.Timestamp after_created_at = 3;
  // По верхней границе дате создания
  google.protobuf.Timestamp before_created_at = 4;
  // По МРФ (Макрорегион)
  repeated Building.MrfType mrf_types = 5;
  // По РФ (Регион)
  repeated Building.RfType rf_types = 6;
  // По статусам объекта строительства
  repeated Building.StatusType status_types = 7;
  // По ОРПОНам
  repeated int64 orpons = 8;
}

// Фильтр для запроса связей объектов строительства и группы пользователя.
// При передаче массива в параметр фильтра элементы массива работают в выборке через ИЛИ.
// При передаче нескольких разных параметров фильтра они работают в выборке через И
message BuildingGroupFilter {
  // По Идентификатору группы пользователя
  repeated string group_ids = 1;
  // По Объекту строительства
  repeated int32 building_ids = 2;
}

// Запрос получения количества объектов строительства
message GetBuildingCountRequest {
  // Фильтр по индикаторам
  BuildingFilter filter = 1;
}

// Запрос получения количества связей объектов строительства и группы пользователя
message GetBuildingGroupCountRequest {
  // Фильтр связей объектов строительства и группы пользователя
  BuildingGroupFilter filter = 1;
}

// Ответ на запрос получения количества объектов строительства
message GetBuildingCountResponse {
  // Тип результата
  oneof type {
    // Всего индикаторов
    int32 data = 1;
  }
}

// Ответ на запрос получения количества связей объектов строительства и группы пользователя
message GetBuildingGroupCountResponse {
  // Тип результата
  oneof type {
    // Всего связей объектов строительства и группы пользователя
    int32 data = 1;
  }
}

// Запрос удаления объекта строительства
message DeleteBuildingRequest {
  // Идентификатор
  int32 id = 1 [(google.api.field_behavior) = REQUIRED];
}


// Ответ на запрос удаления объекта строительства
message DeleteBuildingResponse {}

// Запрос удаления связей объектов строительства и группы пользователя
message PutBuildingGroupDetachRequest {
  // Связь объекта строительства и группы пользователя
  BuildingGroup building_group = 1 [(google.api.field_behavior) = REQUIRED];
}

// Ответ на запрос удаления связи объекта строительства и группы пользователя
message PutBuildingGroupDetachResponse {}

// Объект строительства
message Building {
  // Идентификатор
  int32 id = 1;
  // Наименование объекта строительства
  string title = 2;
  // Дата создания
  google.protobuf.Timestamp created_at = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
  // Дата последнего изменения.
  // Заполняется и обновляется сервером.
  // Заполняется при создании и изменении.
  // Является версией объекта
  google.protobuf.Timestamp changed_at = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
  // Смещение временной зоны объекта строительства от UTC в минутах
  int32 utc_offset = 5 [(google.api.field_behavior) = REQUIRED];
  // ФИАС
  google.protobuf.StringValue fias_id = 6;
  // Справочник МРФ (Макрорегионы)
  enum MrfType {
    // Значение не указано
    MRF_TYPE_UNKNOWN = 0;
    // Центр
    TSENTR = 1;
    // Юг
    YUG = 2;
    // Урал
    URAL = 3;
    // Сибирь
    SIBIR = 4;
    // Северо-Запад
    SEVERO_ZAPAD = 5;
    //Дальний Восток
    DALNIY_VOSTOK = 6;
    // Волга
    VOLGA = 7;
  }
  // Принадлежность объекта строительства к МРФ
  MrfType mrf_type = 7;
  // Справочник РФ (Регионы)
  enum RfType {
    // Значение не указано
    RF_TYPE_UNKNOWN = 0;
    // Республика Башкортостан
    UFA = 1;
    // Кировская область
    KIROV = 2;
    // Ивановский филиал
    IVANOVO = 3;
    // Калужский филиал
    KALUGA = 4;
    // Костромской филиал
    KOSTROMA = 5;
    // Курский филиал
    KURSK = 6;
    // Липецкий филиал
    LIPETSK = 7;
    // Московская область
    MOSOBLAST = 8;
    // Орловский филиал
    OREL = 9;
    // Рязанский филиал
    RYAZAN = 10;
    // Тамбовский филиал
    TAMBOV = 11;
    // Тверской филиал
    TVER = 12;
    // Ярославский филиал
    YAROSLAVL = 13;
    // Смоленский филиал
    SMOLENSK = 14;
    // Тульский филиал
    TULA = 15;
    // Москва
    MOSCOW = 16;
    // ЕАО
    EAO = 17;
    // Филиал в Тюменской и Курганской областях
    KURGAN = 18;
    // Филиал в Тюменской и Курганской областях
    TUMEN = 19;
    // Ханты-Мансийский филиал
    HANTY = 20;
    // Амурская область
    AMUR = 21;
    // Камчатский край
    KAMCHATKA = 22;
    // Магаданская область
    MAGADAN = 23;
    // Приморский край
    PRIMORYE = 24;
    // Сахалинская область
    SAKHALIN = 25;
    // Хабаровский край
    KHABAROVSK = 26;
    // Забайкальский край
    CHITA = 27;
    // ЧАО
    CHUKOTKA = 28;
    // Архангельск
    ARCHANGELSK = 29;
    // Вологда
    VOLOGDA = 30;
    // Калининград
    KALININGRAD = 31;
    // Карелия
    KARELIA = 32;
    // Коми
    KOMI = 33;
    // Лен область
    LENOBLAST = 34;
    // Мурманск
    MURMANSK = 35;
    // Новгород
    NOVGOROD = 36;
    // Псков
    PSKOV = 37;
    // СПб
    SPB = 38;
    // Алтайский филиал
    ALTAI = 39;
    // Бурятский филиал
    BURYATIYA = 40;
    // Иркутский филиал
    IRKUTSK = 41;
    // Кемеровский филиал
    KEMEROVO = 42;
    // Красноярский филиал
    KRASNOYARSK = 43;
    // Омский филиал
    OMSK = 44;
    // Республика Хакасия
    HAKASIYA = 45;
    // Республика Алтай
    RALTAY = 46;
    // Республика Тыва
    TUVA = 47;
    // Томский филиал
    TOMSK = 48;
    // Оренбургская область
    ORENBURG = 49;
    // Белгородский филиал
    BELGOROD = 50;
    // Саха
    SAKHA = 51;
    // Екатеринбургский филиал
    EKT = 52;
    // Волгоградский филиал
    VOLGOGRAD = 53;
    // Ямало-Ненецкий филиал
    YAMAL = 54;
    // Челябинский филиал
    CHELYABINSK = 55;
    // Пермский филиал ПАО "Ростелеком"
    PERM = 56;
    // Республика Марий Эл
    MARYEL = 57;
    // Пензенская область
    PENZA = 58;
    // Ингушский филиал
    INGUSHETIA = 59;
    // Кабардино-Балкарский филиал
    NALCHIK = 60;
    // Калмыцкий филиал
    ELISTA = 61;
    // Ростовский филиал
    ROSTOV = 62;
    // Дагестанский филиал
    MAHACHKALA = 63;
    // Республика Мордовия
    MORDOVIYA = 64;
    // Республика Татарстан (Татарстан)
    KAZAN = 65;
    // Самарская область
    SAMARA = 66;
    // Саратовская область
    SARATOV = 67;
    // Удмуртская Республика
    UDMURTIYA = 68;
    // Ульяновская область
    ULYANOVSK = 69;
    // Чувашская Республика - Чувашия
    CHUVASHIYA = 70;
    // Нижегородская область
    NNOVGOROD = 71;
    // Брянский филиал
    BRYANSK = 72;
    // Владимирский филиал
    VLADIMIR = 73;
    // Воронежский филиал
    VORONEZH = 74;
    // Северо-Осетинский филиал
    VLADIKAVKAZ = 75;
    // Ставропольский филиал
    STAVROPOL = 76;
    // Республика Карачаево-Черкесская
    CHERKESSK = 77;
    // Республика Адыгея
    MAYKOP = 78;
    // Астраханский филиал
    ASTRAKHAN = 79;
    // Краснодарский филиал
    KRASNODAR = 80;
    // Тестовый
    TEST = 81;
    // Новосибирский филиал
    NOVOSIBIRSK = 82;
  }
  // Принадлежность объекта строительства к РФ
  RfType rf_type = 8;
  // Статусы объектов строительства
  enum StatusType {
    // Значение не указано
    STATUS_TYPE_UNKNOWN = 0;
    // СМР
    BUILDING = 1;
    // Реализован
    ACCEPTANCE = 2;
    // Обслуживание
    ACTIVE = 3;
    // Снят с обслуживания
    ARCHIVE = 4;
    // Отказ от заключения договора
    CANCELLED = 5;
    // Тестовый
    TEST_STATUS_TYPE = 6;
  }
  // Статус объекта строительства
  StatusType status_type = 9;
  // Адрес объекта строительства
  string full_address = 10;
  // ОРПОН
  int64 orpon = 11;
}

// Связка объекта строительства и группы пользователя.
// Задает область ресурсов (resource scope), доступную пользователю.
// Используется для контроля доступа к объекту строительства
message BuildingGroup {
  // Идентификатор группы.
  // # Тип: Guid
  string group_id = 1 [(google.api.field_behavior) = REQUIRED];
  // Идентификатор объекта строительства.
  // # Диапазон: 0..2147483647
  int32 building_id = 2 [(google.api.field_behavior) = REQUIRED];
}
