syntax = "proto3"; package crabs.evening_detective_server; import "google/api/annotations.proto"; import "google/protobuf/timestamp.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; import "google/api/httpbody.proto"; option go_package = "pkg/proto"; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { info: { title : "Документация сервиса \"Вечерний детектив\""; version: "v0.1.0"; }; security_definitions: { security: { key : "BearerAuth"; value: { type : TYPE_API_KEY; in : IN_HEADER; name : "Authorization"; description: "Authentication token, prefixed by Bearer: Bearer "; } } } security: { security_requirement: { key : "BearerAuth"; value: {}; } } }; service EveningDetectiveServer { rpc Ping(PingReq) returns (PingRsp) { option (google.api.http) = { get: "/api/test/ping" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { security: { security_requirement: {} } summary: "Проверить доступность"; }; } rpc Echo(EchoReq) returns (EchoRsp) { option (google.api.http) = { post: "/api/test/echo" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { security: { security_requirement: {} } summary: "Проверить обработку данных"; }; } rpc Signup(SignupReq) returns (SignupRsp) { option (google.api.http) = { post: "/api/auth/signup" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { security: { security_requirement: {} } tags : "Регистрация и вход"; summary: "Зарегистрироваться"; }; } rpc RefreshPassword(RefreshPasswordReq) returns (RefreshPasswordRsp) { option (google.api.http) = { post: "/api/auth/refresh-password" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { security: { security_requirement: {} } tags : "Регистрация и вход"; summary: "Обновить пароль"; }; } rpc Login(LoginReq) returns (LoginRsp) { option (google.api.http) = { post: "/api/auth/login" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { security: { security_requirement: {} } tags : "Регистрация и вход"; summary: "Войти и получить токена доступа"; }; } rpc Refresh(RefreshReq) returns (RefreshRsp) { option (google.api.http) = { post: "/api/auth/refresh" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { security: { security_requirement: {} } tags : "Регистрация и вход"; summary: "Обновить токена доступа"; }; } rpc DeleteAccount(DeleteAccountReq) returns (DeleteAccountRsp) { option (google.api.http) = { delete: "/api/auth/delete-account" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Регистрация и вход"; summary : "Удалить учётную запись и персональные данные"; description: "Удаляет учётную запись и персональные данные текущего пользователя (ст. 21 152-ФЗ). Требует заголовок X-Password с паролем учётной записи (подтверждение владельца; пароль не передаётся в URL)."; }; } rpc GetTerms(GetTermsReq) returns (GetTermsRsp) { option (google.api.http) = { get: "/api/terms" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Документы"; summary: "Получить текст Пользовательского соглашения (оферты)"; }; } rpc GetPrivacy(GetPrivacyReq) returns (GetPrivacyRsp) { option (google.api.http) = { get: "/api/privacy" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Документы"; summary: "Получить текст Политики конфиденциальности"; }; } rpc GetConsent(GetConsentReq) returns (GetConsentRsp) { option (google.api.http) = { get: "/api/consent" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Документы"; summary: "Получить текст Согласия на обработку персональных данных"; }; } rpc GetUsers(GetUsersReq) returns (GetUsersRsp) { option (google.api.http) = { get: "/api/users" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Пользователи"; summary: "Получить всех пользователей"; }; } rpc GetUserById(GetUserByIdReq) returns (GetUserByIdRsp) { option (google.api.http) = { get: "/api/users/{id}" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Пользователи"; summary: "Получить пользователя по id"; }; } rpc GetMe(GetMeReq) returns (GetMeRsp) { option (google.api.http) = { get: "/api/users/me" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Пользователи"; summary: "Получить информацию о себе"; }; } rpc AddUserRole(AddUserRoleReq) returns (AddUserRoleRsp) { option (google.api.http) = { post: "/api/users/{id}/role/add" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Пользователи"; summary: "Добавить пользователю роль"; }; } rpc DeleteUserRole(DeleteUserRoleReq) returns (DeleteUserRoleRsp) { option (google.api.http) = { post: "/api/users/{id}/role/delete" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Пользователи"; summary: "Забрать у пользователя роль"; }; } rpc GetPermissions(GetPermissionsReq) returns (GetPermissionsRsp) { option (google.api.http) = { get: "/api/ui/permissions" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Доступы"; summary: "Получить список доступных элементов интерфейса"; }; } rpc UploadFile(UploadFileReq) returns (UploadFileRsp) { option (google.api.http) = { post: "/api/files/upload" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Файлы"; summary: "Загрузить файл"; }; } rpc DownloadFile(DownloadFileReq) returns (google.api.HttpBody) { option (google.api.http) = { get: "/api/files/{filename}" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Файлы"; summary: "Получить файл"; }; } rpc AddScenario(AddScenarioReq) returns (AddScenarioRsp) { option (google.api.http) = { post: "/api/scenario" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Сценарии"; summary: "Создать сценарий"; }; } rpc GetMyScenarios(GetMyScenariosReq) returns (GetMyScenariosRsp) { option (google.api.http) = { get: "/api/my-scenarios" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Сценарии"; summary: "Получить свои сценарии"; }; } rpc GetScenariosCatalog(GetScenariosCatalogReq) returns (GetScenariosCatalogRsp) { option (google.api.http) = { get: "/api/catalog" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Сценарии"; summary: "Получить каталог сценариев"; }; } rpc GetFullScenario(GetScenarioReq) returns (GetScenarioRsp) { option (google.api.http) = { get: "/api/scenarios/{id}/full" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Сценарии"; summary: "Получить сценарий со всеми деталями по id"; }; } rpc GetScenario(GetScenarioReq) returns (GetScenarioRsp) { option (google.api.http) = { get: "/api/scenarios/{id}" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Сценарии"; summary: "Получить сценарий по id"; }; } rpc UpdateScenario(UpdateScenarioReq) returns (UpdateScenarioRsp) { option (google.api.http) = { put : "/api/scenarios/{id}" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Сценарии"; summary: "Редактировать сценарий"; }; } rpc PublicScenario(PublicScenarioReq) returns (PublicScenarioRsp) { option (google.api.http) = { put : "/api/scenarios/{id}/public" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Сценарии"; summary: "Опубликовать сценарий"; }; } rpc DraftScenario(DraftScenarioReq) returns (DraftScenarioRsp) { option (google.api.http) = { put : "/api/scenarios/{id}/draft" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Сценарии"; summary: "Снять с публикации сценарий"; }; } rpc DeleteScenario(DeleteScenarioReq) returns (DeleteScenarioRsp) { option (google.api.http) = { delete: "/api/scenarios/{id}" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Сценарии"; summary: "Удалить сценарий"; }; } rpc AddScenarioPlace(AddScenarioPlaceReq) returns (AddScenarioPlaceRsp) { option (google.api.http) = { post: "/api/scenarios/{id}/places" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Точки сценария"; summary: "Создать точку сценария"; }; } rpc UpdateScenarioPlace(UpdateScenarioPlaceReq) returns (UpdateScenarioPlaceRsp) { option (google.api.http) = { put : "/api/scenarios/{id}/places/{code}" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Точки сценария"; summary: "Обновить точку сценария"; }; } rpc DeleteScenarioPlace(DeleteScenarioPlaceReq) returns (DeleteScenarioPlaceRsp) { option (google.api.http) = { delete: "/api/scenarios/{id}/places/{code}" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Точки сценария"; summary: "Удалить точку сценария"; }; } rpc DownloadScenarioArchive(DownloadScenarioArchiveReq) returns (google.api.HttpBody) { option (google.api.http) = { get: "/api/scenarios/{id}/archive" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Сценарии"; summary: "Скачать сценарий архивом (со всеми материалами и картинками)"; }; } rpc UploadScenarioArchive(google.api.HttpBody) returns (UploadScenarioArchiveRsp) { option (google.api.http) = { post: "/api/scenarios/archive" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Сценарии"; summary: "Создать сценарий из архива"; }; } rpc AddGame(AddGameReq) returns (AddGameRsp) { option (google.api.http) = { post: "/api/games" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Игры"; summary: "Создать игру"; }; } rpc GetGames(GetGamesReq) returns (GetGamesRsp) { option (google.api.http) = { get: "/api/games" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Игры"; summary: "Получить игры"; }; } rpc GetGame(GetGameReq) returns (GetGameRsp) { option (google.api.http) = { get: "/api/games/{id}" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Игры"; summary: "Получить игру"; }; } rpc UpdateGame(UpdateGameReq) returns (UpdateGameRsp) { option (google.api.http) = { put : "/api/games/{id}" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Игры"; summary: "Обновить игру"; }; } rpc StartGame(StartGameReq) returns (StartGameRsp) { option (google.api.http) = { put : "/api/games/{id}/start" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Игры"; summary: "Начать игру"; }; } rpc PauseGame(PauseGameReq) returns (PauseGameRsp) { option (google.api.http) = { put : "/api/games/{id}/pause" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Игры"; summary: "Остановить игру"; }; } rpc PlayGame(PlayGameReq) returns (PlayGameRsp) { option (google.api.http) = { put : "/api/games/{id}/play" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Игры"; summary: "Продолжить игру"; }; } rpc FinishGame(FinishGameReq) returns (FinishGameRsp) { option (google.api.http) = { put : "/api/games/{id}/finish" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Игры"; summary: "Закончить игру"; }; } rpc ResetGame(ResetGameReq) returns (ResetGameRsp) { option (google.api.http) = { put : "/api/games/{id}/reset" body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Игры"; summary: "Сбросить игру"; }; } rpc DeleteGame(DeleteGameReq) returns (DeleteGameRsp) { option (google.api.http) = { delete: "/api/games/{id}" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Игры"; summary: "Удалить игру"; }; } rpc AddTeam(AddTeamReq) returns (AddTeamRsp) { option (google.api.http) = { post: "/api/teams", body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Команда"; summary: "Создать команду"; }; } rpc UpdateTeam(UpdateTeamReq) returns (UpdateTeamRsp) { option (google.api.http) = { put : "/api/teams/{id}", body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Команда"; summary: "Обновить команду"; }; } rpc DeleteTeam(DeleteTeamReq) returns (DeleteTeamRsp) { option (google.api.http) = { delete: "/api/teams/{id}" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Команда"; summary: "Удалить команду"; }; } rpc GiveTeamApplications(GiveTeamApplicationsReq) returns (GiveTeamApplicationsRsp) { option (google.api.http) = { post: "/api/teams/{id}/applications", body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Команда"; summary: "Выдать улику"; }; } rpc GetTeamStory(GetTeamStoryReq) returns (GetTeamStoryRsp) { option (google.api.http) = { get: "/api/teams/{id}/story" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { security: { security_requirement: {} } tags : "Ходы"; summary: "Получить ходы"; }; } rpc AddTeamAction(AddTeamActionReq) returns (AddTeamActionRsp) { option (google.api.http) = { post: "/api/teams/{id}/actions", body: "*" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { security: { security_requirement: {} } tags : "Ходы"; summary: "Сделать ход"; }; } rpc DeleteLastTeamAction(DeleteLastTeamActionReq) returns (DeleteLastTeamActionRsp) { option (google.api.http) = { delete: "/api/teams/{id}/last-actions" }; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags : "Ходы"; summary: "Удалить последний ход"; }; } } message PingReq {} message PingRsp {} message EchoReq { string text = 1; } message EchoRsp { string text = 1; } message SignupReq { string username = 1; string email = 2; bool accept_terms = 3; bool accept_privacy = 4; } message SignupRsp { string error = 1; } message RefreshPasswordReq { string email = 1; } message RefreshPasswordRsp { string error = 1; } message LoginReq { string email = 1; string password = 2; } message LoginRsp { string error = 1; string accessToken = 2; string refreshToken = 3; } message RefreshReq { string refreshToken = 1; } message RefreshRsp { string error = 1; string accessToken = 2; string refreshToken = 3; } // Пароль подтверждает, что удаляет аккаунт его владелец, а не обладатель // украденного access-токена (ст. 21 152-ФЗ). Передаётся HTTP-заголовком // X-Password (пробрасывается матчером в cmd/evening_detective_server/main.go), // чтобы креденшел не попадал в URL/query-параметры и логи. message DeleteAccountReq {} message DeleteAccountRsp { string error = 1; } // Документы раздаются по постоянным URL, на которые ссылается сервис при // фиксации акцептов соглашений (user_agreements) и форма регистрации. message GetTermsReq {} message GetTermsRsp { string error = 1; string text = 2; } message GetPrivacyReq {} message GetPrivacyRsp { string error = 1; string text = 2; } message GetConsentReq {} message GetConsentRsp { string error = 1; string text = 2; } message GetUsersReq {} message GetUsersRsp { string error = 1; repeated User users = 2; } message User { int32 id = 1; string username = 2; string email = 3; repeated string roles = 4; bool is_active = 5; google.protobuf.Timestamp created_at = 6; } message GetUserByIdReq { int32 id = 1; } message GetUserByIdRsp { string error = 1; User user = 2; } message GetMeReq {} message GetMeRsp { string error = 1; User user = 2; } message AddUserRoleReq { int32 id = 1; string role = 2; } message AddUserRoleRsp { string error = 1; } message DeleteUserRoleReq { int32 id = 1; string role = 2; } message DeleteUserRoleRsp { string error = 1; } message GetPermissionsReq {} message GetPermissionsRsp { string error = 1; repeated string permissions = 2; } message UploadFileReq { string filename = 1; bytes data = 2; } message UploadFileRsp { string error = 1; string filename = 2; } message DownloadFileReq { string filename = 1; } message AddScenarioReq { string name = 1; } message AddScenarioRsp { string error = 1; int32 id = 2; } message GetMyScenariosReq {} message GetMyScenariosRsp { string error = 1; repeated Scenario scenarios = 2; } message GetScenariosCatalogReq {} message GetScenariosCatalogRsp { string error = 1; repeated Scenario scenarios = 2; } message GetScenarioReq { int32 id = 1; } message GetScenarioRsp { string error = 1; Scenario scenario = 2; } message Scenario { int32 id = 1; string name = 2; optional string description = 3; optional string image = 4; Story story = 5; string status = 6; User author = 7; google.protobuf.Timestamp updated_at = 8; google.protobuf.Timestamp created_at = 9; google.protobuf.Timestamp published_at = 10; } message Story { repeated Place places = 1; } message Place { string code = 1; string name = 2; string text = 3; string image = 4; bool hidden = 5; repeated Application applications = 6; repeated Door doors = 7; repeated Key keys = 8; } message Application { string name = 1; string image = 2; } message Door { string code = 1; string name = 2; repeated Key keys = 3; } message Key { string name = 1; } message UpdateScenarioReq { int32 id = 1; string name = 2; string description = 3; string image = 4; } message UpdateScenarioRsp { string error = 1; } message PublicScenarioReq { int32 id = 1; } message PublicScenarioRsp { string error = 1; } message DraftScenarioReq { int32 id = 1; } message DraftScenarioRsp { string error = 1; } message DeleteScenarioReq { int32 id = 1; } message DeleteScenarioRsp { string error = 1; } message AddScenarioPlaceReq { int32 id = 1; Place place = 2; } message AddScenarioPlaceRsp { string error = 1; } message UpdateScenarioPlaceReq { int32 id = 1; string code = 2; Place place = 3; } message UpdateScenarioPlaceRsp { string error = 1; } message DeleteScenarioPlaceReq { int32 id = 1; string code = 2; } message DeleteScenarioPlaceRsp { string error = 1; } message DownloadScenarioArchiveReq { int32 id = 1; } message UploadScenarioArchiveRsp { string error = 1; int32 id = 2; } message AddGameReq { string name = 1; string description = 2; google.protobuf.Timestamp start_at = 3; int32 scenario_id = 4; } message AddGameRsp { string error = 1; int32 id = 2; } message GetGamesReq {} message GetGamesRsp { string error = 1; repeated Game games = 2; } message Game { int32 id = 1; string name = 2; string description = 3; google.protobuf.Timestamp start_at = 4; string status = 5; Scenario scenario = 6; repeated Team teams = 7; optional google.protobuf.Timestamp started_at = 8; optional google.protobuf.Timestamp ended_at = 9; } message Team { int32 id = 1; string name = 2; string status = 3; string password = 4; int32 actions_count = 5; repeated Application applications = 6; } message GetGameReq { int32 id = 1; } message GetGameRsp { string error = 1; Game game = 2; } message UpdateGameReq { int32 id = 1; string name = 2; string description = 3; google.protobuf.Timestamp start_at = 4; int32 scenario_id = 5; } message UpdateGameRsp { string error = 1; } message StartGameReq { int32 id = 1; } message StartGameRsp { string error = 1; } message PauseGameReq { int32 id = 1; } message PauseGameRsp { string error = 1; } message PlayGameReq { int32 id = 1; } message PlayGameRsp { string error = 1; } message FinishGameReq { int32 id = 1; } message FinishGameRsp { string error = 1; } message ResetGameReq { int32 id = 1; } message ResetGameRsp { string error = 1; } message DeleteGameReq { int32 id = 1; } message DeleteGameRsp { string error = 1; } message AddTeamReq { int32 game_id = 1; string name = 2; } message AddTeamRsp { string error = 1; int32 id = 2; string password = 3; } message UpdateTeamReq { int32 id = 1; string name = 2; } message UpdateTeamRsp { string error = 1; } message DeleteTeamReq { int64 id = 1; } message DeleteTeamRsp { string error = 1; } message GiveTeamApplicationsReq { int64 id = 1; string name = 2; } message GiveTeamApplicationsRsp { string error = 1; } message GetTeamStoryReq { int64 id = 1; string password = 2; } message GetTeamStoryRsp { string error = 1; Story story = 2; Game game = 3; } message AddTeamActionReq { int64 id = 1; string password = 2; string code = 3; } message AddTeamActionRsp { string error = 1; } message DeleteLastTeamActionReq { int64 id = 1; } message DeleteLastTeamActionRsp { string error = 1; }