generated from VLADIMIR/template_frontend
2383 lines
70 KiB
Protocol Buffer
2383 lines
70 KiB
Protocol Buffer
syntax = "proto3";
|
||
|
||
// Contract rules:
|
||
// - fields inside each message are declared in ascending number order;
|
||
// - published field numbers are never renumbered or reused;
|
||
// - use ID, <name>ID and URL for abbreviation fields so generated clients
|
||
// keep the same naming convention across Go and TypeScript.
|
||
|
||
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 <token>";
|
||
}
|
||
}
|
||
}
|
||
security: {
|
||
security_requirement: {
|
||
key : "BearerAuth";
|
||
value: {};
|
||
}
|
||
}
|
||
};
|
||
|
||
service EveningDetectiveServer {
|
||
rpc GetTasks(GetTasksReq) returns (GetTasksRsp) {
|
||
option (google.api.http) = { get: "/api/tasks" };
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Задачи";
|
||
summary : "Получить общую доску задач";
|
||
description: "Доступно разработчикам и администратору.";
|
||
};
|
||
}
|
||
rpc GetTaskAssignees(GetTaskAssigneesReq) returns (GetTaskAssigneesRsp) {
|
||
option (google.api.http) = { get: "/api/tasks/assignees" };
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Задачи";
|
||
summary : "Получить разработчиков для назначения";
|
||
description: "Доступно разработчикам и администратору.";
|
||
};
|
||
}
|
||
rpc CreateTask(CreateTaskReq) returns (TaskRsp) {
|
||
option (google.api.http) = { post: "/api/tasks" body: "*" };
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Задачи";
|
||
summary : "Создать задачу";
|
||
description: "Доступно разработчикам и администратору.";
|
||
};
|
||
}
|
||
rpc UpdateTask(UpdateTaskReq) returns (TaskRsp) {
|
||
option (google.api.http) = { put: "/api/tasks/{ID}" body: "*" };
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Задачи";
|
||
summary : "Редактировать задачу";
|
||
description: "Доступно разработчикам и администратору.";
|
||
};
|
||
}
|
||
rpc SetTaskStatus(SetTaskStatusReq) returns (TaskRsp) {
|
||
option (google.api.http) = { post: "/api/tasks/{ID}/status" body: "*" };
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Задачи";
|
||
summary : "Изменить статус задачи";
|
||
description: "Доступно разработчикам и администратору.";
|
||
};
|
||
}
|
||
rpc DeleteTask(DeleteTaskReq) returns (DeleteTaskRsp) {
|
||
option (google.api.http) = { post: "/api/tasks/{ID}/delete" body: "*" };
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Задачи";
|
||
summary : "Удалить задачу";
|
||
description: "Доступно разработчикам и администратору.";
|
||
};
|
||
}
|
||
rpc GetParticipation(GetParticipationReq) returns (ParticipationRsp) {
|
||
option (google.api.http) = { post: "/api/participation/get" body: "*" };
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
security : {};
|
||
tags : "Подтверждение участия";
|
||
summary : "Получить состояние участия";
|
||
description: "Возвращает команду, игру и текущее решение по персональному токену из письма. Авторизация JWT не требуется. Чтение не меняет статус участия. Токен передаётся в теле запроса. Недействительная ссылка и ошибки обработки возвращаются стандартным gRPC status error.";
|
||
};
|
||
}
|
||
rpc AnswerParticipation(AnswerParticipationReq) returns (ParticipationRsp) {
|
||
option (google.api.http) = { post: "/api/participation/answer" body: "*" };
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
security : {};
|
||
tags : "Подтверждение участия";
|
||
summary : "Подтвердить или отменить участие";
|
||
description: "Принимает окончательный ответ капитана: confirmed или cancelled. Авторизация JWT не требуется; доступ определяется персональным токеном. Первый ответ сохраняется, повтор того же ответа успешен, противоположный ответ отклоняется. Новый ответ принимается только до планового начала игры и пока игра имеет статус draft. Ошибки ссылки, значения answer, закрытого приёма или изменения решения возвращаются стандартным gRPC status error; при уже принятом решении возвращается его текущее состояние.";
|
||
};
|
||
}
|
||
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: "Получить информацию о себе";
|
||
};
|
||
}
|
||
|
||
// Только администратор; сеансы пользователя сохраняются.
|
||
// Ошибки: 401, 403, 400, 404, 500.
|
||
rpc ChangeUserPassword(ChangeUserPasswordReq) returns (ChangeUserPasswordRsp) {
|
||
option (google.api.http) = {
|
||
post: "/api/users/{ID}/password"
|
||
body: "*"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Пользователи";
|
||
summary : "Изменить чужой пароль (только администратор)";
|
||
description: "Пароль вводится вручную: минимум 12 символов, максимум 72 байта. Сеансы сохраняются. Ошибки: 401 — нет авторизации, 403 — нет прав, 400 — неверные данные или собственный ID, 404 — пользователь не найден, 500 — ошибка сохранения.";
|
||
};
|
||
}
|
||
|
||
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 GetPlaylists(GetPlaylistsReq) returns (GetPlaylistsRsp) {
|
||
option (google.api.http) = { get: "/api/playlists" };
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Музыка";
|
||
summary: "Получить плейлисты";
|
||
};
|
||
}
|
||
|
||
rpc CreatePlaylist(CreatePlaylistReq) returns (CreatePlaylistRsp) {
|
||
option (google.api.http) = { post: "/api/playlists" body: "*" };
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Музыка";
|
||
summary: "Создать плейлист";
|
||
};
|
||
}
|
||
|
||
rpc UpdatePlaylist(UpdatePlaylistReq) returns (UpdatePlaylistRsp) {
|
||
option (google.api.http) = { put: "/api/playlists/{ID}" body: "*" };
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Музыка";
|
||
summary: "Изменить плейлист";
|
||
};
|
||
}
|
||
|
||
rpc DeletePlaylist(DeletePlaylistReq) returns (DeletePlaylistRsp) {
|
||
option (google.api.http) = { delete: "/api/playlists/{ID}" };
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Музыка";
|
||
summary: "Удалить плейлист";
|
||
};
|
||
}
|
||
|
||
rpc UploadPlaylistTrack(UploadPlaylistTrackReq) returns (UploadPlaylistTrackRsp) {
|
||
option (google.api.http) = { post: "/api/playlists/{playlistID}/tracks" body: "*" };
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Музыка";
|
||
summary: "Загрузить MP3 в плейлист";
|
||
};
|
||
}
|
||
|
||
rpc DeletePlaylistTrack(DeletePlaylistTrackReq) returns (DeletePlaylistTrackRsp) {
|
||
option (google.api.http) = { delete: "/api/playlists/{playlistID}/tracks/{trackID}" };
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Музыка";
|
||
summary: "Удалить MP3 из плейлиста";
|
||
};
|
||
}
|
||
|
||
rpc SetScenarioPlaylist(SetScenarioPlaylistReq) returns (SetScenarioPlaylistRsp) {
|
||
option (google.api.http) = { put: "/api/scenarios/{ID}/playlist" body: "*" };
|
||
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 AddScenarioQuestion(AddScenarioQuestionReq) returns (AddScenarioQuestionRsp) {
|
||
option (google.api.http) = {
|
||
post: "/api/scenarios/{ID}/questions"
|
||
body: "*"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Вопросы сценария";
|
||
summary: "Создать вопрос дела";
|
||
};
|
||
}
|
||
|
||
rpc UpdateScenarioQuestion(UpdateScenarioQuestionReq) returns (UpdateScenarioQuestionRsp) {
|
||
option (google.api.http) = {
|
||
put : "/api/scenarios/{ID}/questions/{code}"
|
||
body: "*"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Вопросы сценария";
|
||
summary: "Обновить вопрос дела";
|
||
};
|
||
}
|
||
|
||
rpc DeleteScenarioQuestion(DeleteScenarioQuestionReq) returns (DeleteScenarioQuestionRsp) {
|
||
option (google.api.http) = {
|
||
delete: "/api/scenarios/{ID}/questions/{code}"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Вопросы сценария";
|
||
summary: "Удалить вопрос дела";
|
||
};
|
||
}
|
||
|
||
// Загрузить файл через UploadFile, затем передать его имя; пустое имя удаляет фон дела.
|
||
rpc UpdateScenarioBackground(UpdateScenarioBackgroundReq) returns (UpdateScenarioBackgroundRsp) {
|
||
option (google.api.http) = {
|
||
put : "/api/scenarios/{ID}/background"
|
||
body: "*"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Сценарии";
|
||
summary: "Установить или удалить фон дела";
|
||
};
|
||
}
|
||
|
||
rpc UpdateScenarioIntro(UpdateScenarioIntroReq) returns (UpdateScenarioIntroRsp) {
|
||
option (google.api.http) = {
|
||
put : "/api/scenarios/{ID}/introduction"
|
||
body: "*"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Сценарии";
|
||
summary: "Обновить введение сценария";
|
||
};
|
||
}
|
||
|
||
// Видео загружается через UploadFile (MP4/WebM). Пустая conclusion удаляет закрывашку.
|
||
rpc UpdateScenarioConclusion(UpdateScenarioConclusionReq) returns (UpdateScenarioConclusionRsp) {
|
||
option (google.api.http) = {
|
||
put : "/api/scenarios/{ID}/conclusion"
|
||
body: "*"
|
||
};
|
||
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: "Получить игру";
|
||
};
|
||
}
|
||
|
||
// HTTP uploads are streamed by a dedicated handler, bypassing gRPC message limits.
|
||
rpc ImportGame(google.api.HttpBody) returns (GameImportRsp) {
|
||
option (google.api.http) = {
|
||
post: "/api/games/import"
|
||
body: "*"
|
||
};
|
||
}
|
||
|
||
// Dedicated HTTP handlers stream ZIPs; gRPC retains its message size limit.
|
||
rpc DownloadGameResultsPackage(GameResultsPackageReq) returns (google.api.HttpBody) {
|
||
option (google.api.http) = {get: "/api/games/{ID}/results-package/download"};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags: "Игры";
|
||
summary: "Скачать свежий ZIP результатов завершённой venue-игры";
|
||
produces: "application/zip";
|
||
};
|
||
}
|
||
|
||
rpc ApplyGameResultsPackage(ApplyGameResultsPackageReq) returns (GameResultsPackageRsp) {
|
||
option (google.api.http) = {
|
||
post: "/api/games/{ID}/results-package/apply"
|
||
body: "package"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags: "Игры";
|
||
summary: "Применить ZIP результатов на исходной prod-игре";
|
||
description: "HTTP принимает сырой ZIP до 1 ГиБ, включая поток без Content-Length. Ошибки: 400 неверный пакет/игра, 413 размер, 409 конфликт, 503 временный отказ.";
|
||
consumes: "application/zip";
|
||
produces: "application/json";
|
||
};
|
||
}
|
||
|
||
rpc StartGameExport(StartGameExportReq) returns (GameExportRsp) {
|
||
option (google.api.http) = {
|
||
post: "/api/games/{ID}/export"
|
||
body: "*"
|
||
};
|
||
}
|
||
|
||
rpc GetGameExport(GetGameExportReq) returns (GameExportRsp) {
|
||
option (google.api.http) = {get: "/api/games/{ID}/export"};
|
||
}
|
||
|
||
rpc IssueGameTickets(IssueGameTicketsReq) returns (IssueGameTicketsRsp) {
|
||
option (google.api.http) = {
|
||
post: "/api/games/{gameID}/tickets"
|
||
body: "*"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
security: { security_requirement: {} }
|
||
tags : "Билеты";
|
||
summary : "Выпустить билеты на игру";
|
||
};
|
||
}
|
||
|
||
rpc GetTicket(GetTicketReq) returns (GetTicketRsp) {
|
||
option (google.api.http) = {
|
||
get: "/api/tickets/{token}"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
security: { security_requirement: {} }
|
||
tags : "Билеты";
|
||
summary : "Получить данные билета";
|
||
};
|
||
}
|
||
|
||
rpc AcceptTicket(AcceptTicketReq) returns (AcceptTicketRsp) {
|
||
option (google.api.http) = {
|
||
post: "/api/tickets/{token}/accept"
|
||
body: "*"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Билеты";
|
||
summary: "Принять билет";
|
||
};
|
||
}
|
||
|
||
// Создать сессию экрана. Экран получает токен и показывает QR для привязки.
|
||
rpc CreateScreenSession(CreateScreenSessionReq) returns (CreateScreenSessionRsp) {
|
||
option (google.api.http) = {
|
||
post: "/api/screens"
|
||
body: "*"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
security: {
|
||
security_requirement: {}
|
||
}
|
||
tags : "Экраны";
|
||
summary: "Создать сессию экрана";
|
||
};
|
||
}
|
||
|
||
// Получить состояние экрана по его токену. Вызывается самим экраном.
|
||
rpc GetScreenState(GetScreenStateReq) returns (GetScreenStateRsp) {
|
||
option (google.api.http) = {
|
||
post: "/api/screens/state"
|
||
body: "*"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
security: {
|
||
security_requirement: {}
|
||
}
|
||
tags : "Экраны";
|
||
summary: "Получить состояние экрана";
|
||
};
|
||
}
|
||
|
||
rpc GetGameScreens(GetGameScreensReq) returns (GetGameScreensRsp) {
|
||
option (google.api.http) = {
|
||
get: "/api/games/{gameID}/screens"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Экраны";
|
||
summary: "Получить экраны игры";
|
||
};
|
||
}
|
||
|
||
rpc GetGameMusic(GetGameMusicReq) returns (GetGameMusicRsp) {
|
||
option (google.api.http) = { get: "/api/games/{gameID}/music" };
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Музыка";
|
||
summary: "Получить музыку игры";
|
||
};
|
||
}
|
||
|
||
rpc SetGameMusic(SetGameMusicReq) returns (SetGameMusicRsp) {
|
||
option (google.api.http) = { post: "/api/games/{gameID}/music" body: "*" };
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Музыка";
|
||
summary: "Изменить музыку игры";
|
||
};
|
||
}
|
||
|
||
rpc AdvanceScreenMusic(AdvanceScreenMusicReq) returns (AdvanceScreenMusicRsp) {
|
||
option (google.api.http) = { post: "/api/screens/music/advance" body: "*" };
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
security: { security_requirement: {} }
|
||
tags : "Музыка";
|
||
summary : "Перейти к следующему треку экрана";
|
||
};
|
||
}
|
||
|
||
// Привязать экран к игре. Требует авторизацию организатора, автора или администратора.
|
||
rpc BindScreen(BindScreenReq) returns (BindScreenRsp) {
|
||
option (google.api.http) = {
|
||
post: "/api/screens/{screenID}/bind"
|
||
body: "*"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Экраны";
|
||
summary: "Привязать экран к игре";
|
||
};
|
||
}
|
||
|
||
// Отвязать экран от игры. Требует авторизацию организатора, автора или администратора.
|
||
rpc UnbindScreen(UnbindScreenReq) returns (UnbindScreenRsp) {
|
||
option (google.api.http) = {
|
||
post: "/api/screens/{screenID}/unbind"
|
||
body: "*"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Экраны";
|
||
summary: "Отвязать экран от игры";
|
||
};
|
||
}
|
||
|
||
rpc SetScreenSound(SetScreenSoundReq) returns (SetScreenSoundRsp) {
|
||
option (google.api.http) = {
|
||
post: "/api/screens/{screenID}/sound"
|
||
body: "*"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Экраны";
|
||
summary: "Назначить экран со звуком";
|
||
};
|
||
}
|
||
|
||
rpc GetGameMap(GetGameMapReq) returns (GetGameMapRsp) {
|
||
option (google.api.http) = { get: "/api/games/{gameID}/map" };
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Экраны";
|
||
summary: "Получить карту игры";
|
||
};
|
||
}
|
||
|
||
rpc UpdateGameMapItem(UpdateGameMapItemReq) returns (UpdateGameMapItemRsp) {
|
||
option (google.api.http) = {
|
||
post: "/api/games/{gameID}/map/items/{kind}/{itemID}"
|
||
body: "*"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Экраны";
|
||
summary: "Изменить объект карты игры";
|
||
};
|
||
}
|
||
|
||
// Изменить общий режим показа всех экранов игры.
|
||
rpc SetScreenMode(SetScreenModeReq) returns (SetScreenModeRsp) {
|
||
option (google.api.http) = {
|
||
post: "/api/games/{gameID}/screens/mode"
|
||
body: "*"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Экраны";
|
||
summary: "Изменить режим показа экранов";
|
||
};
|
||
}
|
||
|
||
rpc SetScreenTimer(SetScreenTimerReq) returns (SetScreenTimerRsp) {
|
||
option (google.api.http) = {
|
||
post: "/api/games/{gameID}/screens/timer"
|
||
body: "*"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Экраны";
|
||
summary: "Настроить таймер экранов";
|
||
};
|
||
}
|
||
|
||
// Отправить общую команду экранам игры.
|
||
rpc SendScreenCommand(SendScreenCommandReq) returns (SendScreenCommandRsp) {
|
||
option (google.api.http) = {
|
||
post: "/api/games/{gameID}/screens/command"
|
||
body: "*"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Экраны";
|
||
summary: "Отправить команду экранам";
|
||
};
|
||
}
|
||
|
||
rpc GetScreenPlan(GetScreenPlanReq) returns (GetScreenPlanRsp) {
|
||
option (google.api.http) = { get: "/api/games/{gameID}/screen-plan" };
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Экраны";
|
||
summary: "Получить план экранов";
|
||
};
|
||
}
|
||
|
||
rpc SaveScreenPlan(SaveScreenPlanReq) returns (SaveScreenPlanRsp) {
|
||
option (google.api.http) = {
|
||
put : "/api/games/{gameID}/screen-plan"
|
||
body: "*"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Экраны";
|
||
summary: "Сохранить план экранов";
|
||
};
|
||
}
|
||
|
||
rpc SetScreenPlanStep(SetScreenPlanStepReq) returns (SetScreenPlanStepRsp) {
|
||
option (google.api.http) = {
|
||
post: "/api/games/{gameID}/screen-plan/step"
|
||
body: "*"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Экраны";
|
||
summary: "Перейти на шаг плана экранов";
|
||
};
|
||
}
|
||
|
||
rpc GetScreenResults(GetScreenResultsReq) returns (GetScreenResultsRsp) {
|
||
option (google.api.http) = { post: "/api/screens/results" body: "*" };
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Экраны";
|
||
summary: "Получить результаты для экрана";
|
||
};
|
||
}
|
||
|
||
rpc DownloadTeamQR(GetGameReq) returns (google.api.HttpBody) {
|
||
option (google.api.http) = {
|
||
get: "/api/games/{ID}/teams/qr.pdf"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Игры";
|
||
summary: "Скачать PDF с QR-кодами всех команд игры";
|
||
};
|
||
}
|
||
|
||
rpc GetGameAnswers(GetGameAnswersReq) returns (GetGameAnswersRsp) {
|
||
option (google.api.http) = {
|
||
get: "/api/games/{gameID}/answers"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Игры";
|
||
summary: "Получить ответы команд на вопросы дела (для оценки организатором)";
|
||
};
|
||
}
|
||
|
||
rpc GetGameResults(GetGameResultsReq) returns (GetGameResultsRsp) {
|
||
option (google.api.http) = {
|
||
get: "/api/games/{gameID}/results"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Игры";
|
||
summary: "Получить итоговую таблицу игры (после завершения)";
|
||
};
|
||
}
|
||
|
||
rpc CreateGameReview(CreateGameReviewReq) returns (CreateGameReviewRsp) {
|
||
option (google.api.http) = {
|
||
post: "/api/games/{gameID}/reviews"
|
||
body: "*"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
security: { security_requirement: {} }
|
||
tags : "Отзывы"
|
||
summary : "Оставить отзыв об игре"
|
||
};
|
||
}
|
||
|
||
rpc GetGameReviews(GetGameReviewsReq) returns (GetGameReviewsRsp) {
|
||
option (google.api.http) = {
|
||
get: "/api/games/{gameID}/reviews"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
security: { security_requirement: {} }
|
||
tags : "Отзывы"
|
||
summary : "Получить отзывы об игре"
|
||
};
|
||
}
|
||
|
||
rpc GetScenarioReviews(GetScenarioReviewsReq) returns (GetGameReviewsRsp) {
|
||
option (google.api.http) = {
|
||
get: "/api/scenarios/{scenarioID}/reviews"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
security: { security_requirement: {} }
|
||
tags : "Отзывы"
|
||
summary : "Получить отзывы сценария"
|
||
};
|
||
}
|
||
|
||
rpc GetGameReviewsForModeration(GetGameReviewsReq) returns (GetGameReviewsRsp) {
|
||
option (google.api.http) = {
|
||
get: "/api/admin/games/{gameID}/reviews"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Отзывы"
|
||
summary: "Получить отзывы игры для модерации"
|
||
};
|
||
}
|
||
|
||
rpc GetReviewsForModeration(GetReviewsForModerationReq) returns (GetGameReviewsRsp) {
|
||
option (google.api.http) = {
|
||
get: "/api/admin/game-reviews"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
tags : "Отзывы"
|
||
summary: "Получить общую очередь отзывов"
|
||
};
|
||
}
|
||
|
||
rpc ModerateGameReview(ModerateGameReviewReq) returns (ModerateGameReviewRsp) {
|
||
option (google.api.http) = {
|
||
put : "/api/admin/game-reviews/{ID}"
|
||
body: "*"
|
||
};
|
||
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: "Удалить последний ход";
|
||
};
|
||
}
|
||
|
||
rpc GetTeamAnswers(GetTeamAnswersReq) returns (GetTeamAnswersRsp) {
|
||
option (google.api.http) = {
|
||
get: "/api/teams/{ID}/answers"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
security: {
|
||
security_requirement: {}
|
||
}
|
||
tags : "Ходы";
|
||
summary: "Получить ответы команды на вопросы дела";
|
||
};
|
||
}
|
||
|
||
rpc SubmitTeamAnswers(SubmitTeamAnswersReq) returns (SubmitTeamAnswersRsp) {
|
||
option (google.api.http) = {
|
||
post: "/api/teams/{ID}/answers"
|
||
body: "*"
|
||
};
|
||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||
security: {
|
||
security_requirement: {}
|
||
}
|
||
tags : "Ходы";
|
||
summary: "Отправить ответы команды на вопросы дела";
|
||
};
|
||
}
|
||
|
||
rpc SetTeamAnswerScore(SetTeamAnswerScoreReq) returns (SetTeamAnswerScoreRsp) {
|
||
option (google.api.http) = {
|
||
put : "/api/teams/{ID}/answers/{questionCode}/score"
|
||
body: "*"
|
||
};
|
||
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 {
|
||
}
|
||
|
||
message RefreshPasswordReq {
|
||
string email = 1;
|
||
}
|
||
|
||
message RefreshPasswordRsp {
|
||
}
|
||
|
||
message LoginReq {
|
||
string email = 1;
|
||
string password = 2;
|
||
}
|
||
|
||
message LoginRsp {
|
||
string accessToken = 1;
|
||
string refreshToken = 2;
|
||
}
|
||
|
||
message RefreshReq {
|
||
string refreshToken = 1;
|
||
}
|
||
|
||
message RefreshRsp {
|
||
string accessToken = 1;
|
||
string refreshToken = 2;
|
||
}
|
||
|
||
// Пароль подтверждает, что удаляет аккаунт его владелец, а не обладатель
|
||
// украденного access-токена (ст. 21 152-ФЗ). Передаётся HTTP-заголовком
|
||
// X-Password (пробрасывается матчером в cmd/evening_detective_server/main.go),
|
||
// чтобы креденшел не попадал в URL/query-параметры и логи.
|
||
message DeleteAccountReq {}
|
||
|
||
message DeleteAccountRsp {
|
||
}
|
||
|
||
// Документы раздаются по постоянным URL, на которые ссылается сервис при
|
||
// фиксации акцептов соглашений (user_agreements) и форма регистрации.
|
||
message GetTermsReq {}
|
||
|
||
message GetTermsRsp {
|
||
string text = 1;
|
||
}
|
||
|
||
message GetPrivacyReq {}
|
||
|
||
message GetPrivacyRsp {
|
||
string text = 1;
|
||
}
|
||
|
||
message GetConsentReq {}
|
||
|
||
message GetConsentRsp {
|
||
string text = 1;
|
||
}
|
||
|
||
message GetUsersReq {}
|
||
|
||
message GetUsersRsp {
|
||
repeated User users = 1;
|
||
}
|
||
|
||
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 {
|
||
User user = 1;
|
||
}
|
||
|
||
message GetMeReq {}
|
||
|
||
message GetMeRsp {
|
||
User user = 1;
|
||
}
|
||
|
||
message ChangeUserPasswordReq {
|
||
int32 ID = 1;
|
||
string new_password = 2;
|
||
}
|
||
|
||
message ChangeUserPasswordRsp {}
|
||
|
||
message AddUserRoleReq {
|
||
int32 ID = 1;
|
||
string role = 2;
|
||
}
|
||
|
||
message AddUserRoleRsp {
|
||
}
|
||
|
||
message DeleteUserRoleReq {
|
||
int32 ID = 1;
|
||
string role = 2;
|
||
}
|
||
|
||
message DeleteUserRoleRsp {
|
||
}
|
||
|
||
message GetPermissionsReq {}
|
||
|
||
message GetPermissionsRsp {
|
||
repeated string permissions = 1;
|
||
// Actual server environment: prod or venue.
|
||
string environment = 2;
|
||
}
|
||
|
||
message UploadFileReq {
|
||
string filename = 1;
|
||
bytes data = 2;
|
||
}
|
||
|
||
message UploadFileRsp {
|
||
string filename = 1;
|
||
// Тип загруженного файла: image | pdf | audio | video (определяется сервером по
|
||
// содержимому). Удобен редактору для предзаполнения file_type улики.
|
||
string file_type = 2 [json_name = "file_type"];
|
||
}
|
||
|
||
message DownloadFileReq {
|
||
string filename = 1;
|
||
}
|
||
|
||
message PlaylistTrack {
|
||
int32 ID = 1;
|
||
string name = 2;
|
||
string filename = 3;
|
||
int32 position = 4;
|
||
}
|
||
|
||
message Playlist {
|
||
int32 ID = 1;
|
||
string name = 2;
|
||
repeated PlaylistTrack tracks = 3;
|
||
}
|
||
|
||
message GetPlaylistsReq {}
|
||
|
||
message GetPlaylistsRsp {
|
||
repeated Playlist playlists = 1;
|
||
}
|
||
|
||
message CreatePlaylistReq {
|
||
string name = 1;
|
||
}
|
||
|
||
message CreatePlaylistRsp {
|
||
Playlist playlist = 1;
|
||
}
|
||
|
||
message UpdatePlaylistReq {
|
||
int32 ID = 1;
|
||
string name = 2;
|
||
}
|
||
|
||
message UpdatePlaylistRsp {
|
||
Playlist playlist = 1;
|
||
}
|
||
|
||
message DeletePlaylistReq {
|
||
int32 ID = 1;
|
||
}
|
||
|
||
message DeletePlaylistRsp {}
|
||
|
||
message UploadPlaylistTrackReq {
|
||
int32 playlistID = 1;
|
||
string name = 2;
|
||
string filename = 3;
|
||
bytes data = 4;
|
||
}
|
||
|
||
message UploadPlaylistTrackRsp {
|
||
Playlist playlist = 1;
|
||
}
|
||
|
||
message DeletePlaylistTrackReq {
|
||
int32 playlistID = 1;
|
||
int32 trackID = 2;
|
||
}
|
||
|
||
message DeletePlaylistTrackRsp {}
|
||
|
||
message SetScenarioPlaylistReq {
|
||
int32 ID = 1;
|
||
int32 playlistID = 2;
|
||
}
|
||
|
||
message SetScenarioPlaylistRsp {}
|
||
|
||
message AddScenarioReq {
|
||
string name = 1;
|
||
}
|
||
|
||
message AddScenarioRsp {
|
||
int32 ID = 1;
|
||
}
|
||
|
||
message GetMyScenariosReq {}
|
||
|
||
message GetMyScenariosRsp {
|
||
repeated Scenario scenarios = 1;
|
||
}
|
||
|
||
message GetScenariosCatalogReq {}
|
||
|
||
message GetScenariosCatalogRsp {
|
||
repeated Scenario scenarios = 1;
|
||
}
|
||
|
||
message GetScenarioReq {
|
||
int32 ID = 1;
|
||
}
|
||
|
||
message GetScenarioRsp {
|
||
Scenario scenario = 1;
|
||
}
|
||
|
||
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;
|
||
double average_rating = 11;
|
||
int32 reviews_count = 12;
|
||
string difficulty = 13;
|
||
optional int32 music_playlist_id = 14 [json_name = "music_playlist_id"];
|
||
}
|
||
|
||
message Story {
|
||
repeated Place places = 1;
|
||
Introduction introduction = 2;
|
||
repeated Question questions = 3;
|
||
string background = 4;
|
||
Conclusion conclusion = 5; // Только в полном сценарии, игрокам не передаётся.
|
||
}
|
||
|
||
message Conclusion {
|
||
string text = 1;
|
||
string video = 2;
|
||
}
|
||
|
||
message Introduction {
|
||
string text = 1;
|
||
string audio = 2;
|
||
}
|
||
|
||
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;
|
||
// Тип файла улики: image | pdf | audio. Значение выводится сервером из
|
||
// расширения файла (см. file_storage.FileType); пустое значение возможно
|
||
// только для legacy-строк без расширения.
|
||
string file_type = 3 [json_name = "file_type"];
|
||
}
|
||
|
||
message Door {
|
||
string code = 1;
|
||
string name = 2;
|
||
repeated Key keys = 3;
|
||
}
|
||
|
||
message Key {
|
||
string name = 1;
|
||
}
|
||
|
||
// Вопрос дела - вопрос, на который команда должна ответить в конце игры.
|
||
// Правильный ответ (answer) виден только автору сценария и организаторам
|
||
// (при оценке ответов команд), команде не передаётся.
|
||
message Question {
|
||
// Код вопроса - используется при отправке ответов командой
|
||
string code = 1;
|
||
|
||
// Текст вопроса
|
||
string text = 2;
|
||
|
||
// Правильный ответ (справка для организатора при оценке)
|
||
string answer = 3;
|
||
}
|
||
|
||
// Ответ команды на вопрос дела
|
||
message Answer {
|
||
// Код вопроса
|
||
string questionCode = 1;
|
||
|
||
// Текст ответа команды
|
||
string answer = 2;
|
||
}
|
||
|
||
// Ответ команды с баллом (для панели организатора)
|
||
message AnswerScore {
|
||
string questionCode = 1;
|
||
string answer = 2;
|
||
// Балл, выставленный организатором; отсутствует, если ещё не оценено
|
||
optional int32 score = 3;
|
||
}
|
||
|
||
// Ответы одной команды на вопросы дела
|
||
message TeamAnswers {
|
||
Team team = 1;
|
||
repeated AnswerScore answers = 2;
|
||
}
|
||
|
||
message UpdateScenarioReq {
|
||
int32 ID = 1;
|
||
string name = 2;
|
||
string description = 3;
|
||
string image = 4;
|
||
}
|
||
|
||
message UpdateScenarioRsp {
|
||
}
|
||
|
||
message PublicScenarioReq {
|
||
int32 ID = 1;
|
||
}
|
||
|
||
message PublicScenarioRsp {
|
||
}
|
||
|
||
message DraftScenarioReq {
|
||
int32 ID = 1;
|
||
}
|
||
|
||
message DraftScenarioRsp {
|
||
}
|
||
|
||
message DeleteScenarioReq {
|
||
int32 ID = 1;
|
||
}
|
||
|
||
message DeleteScenarioRsp {
|
||
}
|
||
|
||
message AddScenarioPlaceReq {
|
||
int32 ID = 1;
|
||
Place place = 2;
|
||
}
|
||
|
||
message AddScenarioPlaceRsp {
|
||
}
|
||
|
||
message UpdateScenarioPlaceReq {
|
||
int32 ID = 1;
|
||
string code = 2;
|
||
Place place = 3;
|
||
}
|
||
|
||
message UpdateScenarioPlaceRsp {
|
||
}
|
||
|
||
message DeleteScenarioPlaceReq {
|
||
int32 ID = 1;
|
||
string code = 2;
|
||
}
|
||
|
||
message DeleteScenarioPlaceRsp {
|
||
}
|
||
|
||
message UpdateScenarioConclusionReq {
|
||
int32 ID = 1;
|
||
Conclusion conclusion = 2;
|
||
}
|
||
|
||
message UpdateScenarioConclusionRsp {
|
||
}
|
||
|
||
message UpdateScenarioIntroReq {
|
||
int32 ID = 1;
|
||
Introduction introduction = 2;
|
||
}
|
||
|
||
message UpdateScenarioIntroRsp {
|
||
}
|
||
|
||
message AddScenarioQuestionReq {
|
||
int32 ID = 1;
|
||
Question question = 2;
|
||
}
|
||
|
||
message AddScenarioQuestionRsp {
|
||
}
|
||
|
||
message UpdateScenarioQuestionReq {
|
||
int32 ID = 1;
|
||
string code = 2;
|
||
Question question = 3;
|
||
}
|
||
|
||
message UpdateScenarioQuestionRsp {
|
||
}
|
||
|
||
message DeleteScenarioQuestionReq {
|
||
int32 ID = 1;
|
||
string code = 2;
|
||
}
|
||
|
||
message DeleteScenarioQuestionRsp {
|
||
}
|
||
|
||
message DownloadScenarioArchiveReq {
|
||
int32 ID = 1;
|
||
}
|
||
|
||
message UploadScenarioArchiveRsp {
|
||
int32 ID = 1;
|
||
}
|
||
|
||
message AddGameReq {
|
||
string name = 1;
|
||
string description = 2;
|
||
google.protobuf.Timestamp start_at = 3;
|
||
int32 scenarioID = 4;
|
||
string format = 5;
|
||
string location = 6;
|
||
}
|
||
|
||
message AddGameRsp {
|
||
int32 ID = 1;
|
||
}
|
||
|
||
message GetGamesReq {}
|
||
|
||
message GetGamesRsp {
|
||
repeated Game games = 1;
|
||
}
|
||
|
||
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;
|
||
string format = 10;
|
||
string location = 11;
|
||
GameExport export = 12;
|
||
}
|
||
|
||
// Download ready ZIP through the authenticated streaming HTTP route:
|
||
// GET /api/games/{ID}/export/download (not an HttpBody RPC).
|
||
message GameExport {
|
||
string ID = 1;
|
||
string state = 2; // preparing, ready or failed; preparing/ready lock game writes.
|
||
string packageID = 3;
|
||
int64 size = 4;
|
||
string sha256 = 5;
|
||
string failure = 6;
|
||
}
|
||
|
||
message GameImportRsp {
|
||
int32 gameID = 1;
|
||
string packageID = 2;
|
||
bool repeated = 3;
|
||
}
|
||
|
||
message StartGameExportReq { int32 ID = 1; }
|
||
|
||
message GetGameExportReq { int32 ID = 1; }
|
||
|
||
message GameExportRsp { GameExport export = 1; }
|
||
|
||
enum ScreenMode {
|
||
SCREEN_MODE_UNSPECIFIED = 0;
|
||
SCREEN_MODE_COVER = 1;
|
||
SCREEN_MODE_INTRO = 2;
|
||
SCREEN_MODE_INTRO_DONE = 3;
|
||
SCREEN_MODE_CONCLUSION = 4;
|
||
SCREEN_MODE_CONCLUSION_DONE = 5;
|
||
SCREEN_MODE_RESULTS = 6;
|
||
SCREEN_MODE_TIMER = 7;
|
||
SCREEN_MODE_TEXT = 8;
|
||
}
|
||
|
||
enum ScreenTimerState {
|
||
SCREEN_TIMER_STATE_UNSPECIFIED = 0;
|
||
SCREEN_TIMER_STATE_STOPPED = 1;
|
||
SCREEN_TIMER_STATE_RUNNING = 2;
|
||
SCREEN_TIMER_STATE_PAUSED = 3;
|
||
SCREEN_TIMER_STATE_FINISHED = 4;
|
||
}
|
||
|
||
enum ScreenCommand {
|
||
SCREEN_COMMAND_UNSPECIFIED = 0;
|
||
SCREEN_COMMAND_PLAY = 1;
|
||
SCREEN_COMMAND_PAUSE = 2;
|
||
SCREEN_COMMAND_RESUME = 3;
|
||
SCREEN_COMMAND_STOP = 4;
|
||
SCREEN_COMMAND_REPLAY = 5;
|
||
SCREEN_COMMAND_SEEK = 6;
|
||
SCREEN_COMMAND_VOLUME = 7;
|
||
SCREEN_COMMAND_TIMER_START = 8;
|
||
SCREEN_COMMAND_TIMER_PAUSE = 9;
|
||
SCREEN_COMMAND_TIMER_RESUME = 10;
|
||
SCREEN_COMMAND_TIMER_RESET = 11;
|
||
}
|
||
|
||
message ScreenState {
|
||
string ID = 1;
|
||
string status = 2;
|
||
optional int32 gameID = 3;
|
||
ScreenMode mode = 4;
|
||
bool sound_enabled = 5;
|
||
string error = 6;
|
||
int64 state_version = 7;
|
||
int64 position_ms = 8;
|
||
string game_name = 9;
|
||
string cover_image = 10;
|
||
string intro_audio = 11;
|
||
string conclusion_video = 12;
|
||
ScreenCommand command = 13;
|
||
int32 volume = 14;
|
||
string background_image = 15;
|
||
string timer_label = 16;
|
||
int64 timer_duration_seconds = 17;
|
||
int64 timer_remaining_seconds = 18;
|
||
ScreenTimerState timer_state = 19;
|
||
string text = 20;
|
||
MusicState music = 21;
|
||
}
|
||
|
||
message CreateScreenSessionReq {}
|
||
|
||
message CreateScreenSessionRsp {
|
||
string screenID = 1;
|
||
string access_token = 2;
|
||
}
|
||
|
||
message GetScreenStateReq {
|
||
string screenID = 1;
|
||
string accessToken = 2;
|
||
}
|
||
|
||
message GetScreenStateRsp {
|
||
ScreenState state = 1;
|
||
}
|
||
|
||
message GetGameScreensReq {
|
||
int32 gameID = 1;
|
||
}
|
||
|
||
message GetGameScreensRsp {
|
||
repeated ScreenState screens = 1;
|
||
}
|
||
|
||
enum MusicPlaybackState {
|
||
MUSIC_PLAYBACK_UNSPECIFIED = 0;
|
||
MUSIC_PLAYBACK_STOPPED = 1;
|
||
MUSIC_PLAYBACK_PLAYING = 2;
|
||
MUSIC_PLAYBACK_PAUSED = 3;
|
||
}
|
||
|
||
message MusicState {
|
||
Playlist playlist = 1;
|
||
int32 track_index = 2;
|
||
int64 position_ms = 3;
|
||
int32 volume = 4;
|
||
bool loop = 5;
|
||
MusicPlaybackState playback = 6;
|
||
int64 state_version = 7;
|
||
}
|
||
|
||
message GetGameMusicReq {
|
||
int32 gameID = 1;
|
||
}
|
||
|
||
message GetGameMusicRsp {
|
||
repeated Playlist playlists = 1;
|
||
MusicState state = 2;
|
||
int32 scenario_playlist_id = 3;
|
||
int32 game_playlist_id = 4;
|
||
}
|
||
|
||
message SetGameMusicReq {
|
||
int32 gameID = 1;
|
||
int32 playlistID = 2;
|
||
int32 track_index = 3;
|
||
int64 position_ms = 4;
|
||
int32 volume = 5;
|
||
bool loop = 6;
|
||
MusicPlaybackState playback = 7;
|
||
}
|
||
|
||
message SetGameMusicRsp {
|
||
MusicState state = 1;
|
||
}
|
||
|
||
message AdvanceScreenMusicReq {
|
||
string screenID = 1;
|
||
string accessToken = 2;
|
||
}
|
||
|
||
message AdvanceScreenMusicRsp {
|
||
MusicState state = 1;
|
||
}
|
||
|
||
message BindScreenReq {
|
||
string screenID = 1;
|
||
string accessToken = 2;
|
||
int32 gameID = 3;
|
||
}
|
||
|
||
message BindScreenRsp {
|
||
ScreenState state = 1;
|
||
}
|
||
|
||
message UnbindScreenReq {
|
||
string screenID = 1;
|
||
}
|
||
|
||
message UnbindScreenRsp {
|
||
}
|
||
|
||
message SetScreenSoundReq {
|
||
string screenID = 1;
|
||
bool soundEnabled = 2;
|
||
}
|
||
|
||
message SetScreenSoundRsp {
|
||
}
|
||
|
||
message MapItem {
|
||
string kind = 1;
|
||
int32 itemID = 2;
|
||
string label = 3;
|
||
int32 x = 4;
|
||
int32 y = 5;
|
||
bool hidden = 6;
|
||
string status = 7;
|
||
bool sound_enabled = 8;
|
||
}
|
||
|
||
message GetGameMapReq {
|
||
int32 gameID = 1;
|
||
}
|
||
|
||
message GetGameMapRsp {
|
||
repeated MapItem items = 1;
|
||
}
|
||
|
||
message UpdateGameMapItemReq {
|
||
int32 gameID = 1;
|
||
string kind = 2;
|
||
int32 itemID = 3;
|
||
int32 x = 4;
|
||
int32 y = 5;
|
||
bool hidden = 6;
|
||
}
|
||
|
||
message UpdateGameMapItemRsp {}
|
||
|
||
message SetScreenModeReq {
|
||
int32 gameID = 1;
|
||
ScreenMode mode = 2;
|
||
}
|
||
|
||
message SetScreenModeRsp {
|
||
}
|
||
|
||
message SetScreenTimerReq {
|
||
int32 gameID = 1;
|
||
int64 duration_seconds = 2;
|
||
string label = 3;
|
||
}
|
||
|
||
message SetScreenTimerRsp {
|
||
}
|
||
|
||
message SendScreenCommandReq {
|
||
int32 gameID = 1;
|
||
ScreenCommand command = 2;
|
||
int64 position_ms = 3;
|
||
int32 volume = 4;
|
||
}
|
||
|
||
message SendScreenCommandRsp {
|
||
}
|
||
|
||
message ScreenPlanStep {
|
||
ScreenMode mode = 1;
|
||
string text = 2;
|
||
string timer_label = 3;
|
||
int64 timer_duration_seconds = 4;
|
||
}
|
||
|
||
message ScreenPlan {
|
||
repeated ScreenPlanStep steps = 1;
|
||
int32 current_step = 2;
|
||
}
|
||
|
||
message GetScreenPlanReq {
|
||
int32 gameID = 1;
|
||
}
|
||
|
||
message GetScreenPlanRsp {
|
||
ScreenPlan plan = 1;
|
||
}
|
||
|
||
message SaveScreenPlanReq {
|
||
int32 gameID = 1;
|
||
repeated ScreenPlanStep steps = 2;
|
||
int32 current_step = 3;
|
||
}
|
||
|
||
message SaveScreenPlanRsp {
|
||
ScreenPlan plan = 1;
|
||
}
|
||
|
||
message SetScreenPlanStepReq {
|
||
int32 gameID = 1;
|
||
int32 current_step = 2;
|
||
}
|
||
|
||
message SetScreenPlanStepRsp {
|
||
ScreenPlan plan = 1;
|
||
}
|
||
|
||
message GetScreenResultsReq {
|
||
string screenID = 1;
|
||
string accessToken = 2;
|
||
}
|
||
|
||
message GetScreenResultsRsp {
|
||
repeated ResultsQuestion questions = 1;
|
||
repeated TeamResult teams = 2;
|
||
}
|
||
|
||
message GetParticipationReq {
|
||
// Персональный токен из письма: 64 шестнадцатеричных символа. Не является JWT.
|
||
string token = 1;
|
||
}
|
||
|
||
message AnswerParticipationReq {
|
||
// Персональный токен из письма: 64 шестнадцатеричных символа. Не является JWT.
|
||
string token = 1;
|
||
// Окончательное решение: confirmed — участвуем, cancelled — отменяем запись.
|
||
string answer = 2;
|
||
}
|
||
|
||
message ParticipationRsp {
|
||
// Название команды. Данные доступны только по действительному токену.
|
||
string team_name = 1;
|
||
// Название игры.
|
||
string game_name = 2;
|
||
// Плановое начало игры, UTC (RFC 3339 в JSON).
|
||
google.protobuf.Timestamp start_at = 3;
|
||
// Заявленное число участников команды.
|
||
int32 participants_count = 4;
|
||
// pending — ожидает ответа, confirmed — подтверждено, cancelled — отменено.
|
||
string status = 5;
|
||
// Новые ответы закрыты: наступило плановое начало или игра вышла из draft.
|
||
// Изменение уже принятого решения запрещено независимо от этого поля.
|
||
bool closed = 6;
|
||
}
|
||
|
||
message Team {
|
||
int32 ID = 1;
|
||
string name = 2;
|
||
string status = 3;
|
||
string password = 4;
|
||
int32 actions_count = 5;
|
||
repeated Application applications = 6;
|
||
string captain_email = 7;
|
||
int32 participants_count = 8;
|
||
// Статус участия: pending, confirmed или cancelled. Поле панели организатора.
|
||
string participation_status = 9;
|
||
// Источник решения: captain, automatic либо пустая строка до ответа.
|
||
string participation_source = 10;
|
||
// Последняя ошибка отправки; пустая строка, если ошибки нет.
|
||
string participation_email_error = 11;
|
||
// Письмо принято SMTP-сервером; не означает прочтение или доставку во входящие.
|
||
bool participation_email_sent = 12;
|
||
}
|
||
|
||
message GetGameReq {
|
||
int32 ID = 1;
|
||
}
|
||
|
||
message GetGameRsp {
|
||
Game game = 1;
|
||
}
|
||
|
||
message GetGameAnswersReq {
|
||
int32 gameID = 1;
|
||
}
|
||
|
||
message GetGameAnswersRsp {
|
||
repeated Question questions = 1;
|
||
repeated TeamAnswers teams = 2;
|
||
}
|
||
|
||
message GetGameResultsReq {
|
||
int32 gameID = 1;
|
||
}
|
||
|
||
// Вопрос в шапке итоговой таблицы: правильный ответ (поле answer сообщения
|
||
// Question) командам/таблице не передаётся — он виден только в панели оценки.
|
||
message ResultsQuestion {
|
||
string code = 1;
|
||
string text = 2;
|
||
}
|
||
|
||
// Строка итоговой таблицы: команда, баллы по вопросам, сумма и место.
|
||
message TeamResult {
|
||
Team team = 1;
|
||
repeated AnswerScore answers = 2;
|
||
// Сумма баллов по всем вопросам сценария (неоценённые считаются как 0)
|
||
int32 total_score = 3;
|
||
// Место в итоговой таблице: команды с одинаковой суммой баллов и
|
||
// одинаковым числом ходов занимают одно место (следующее пропускается)
|
||
int32 place = 4;
|
||
// Количество ходов команды (дублирует team.actions_count для удобства
|
||
// таблицы; участвует в тай-брейке при равенстве суммы баллов)
|
||
int32 actions_count = 5;
|
||
}
|
||
|
||
message GetGameResultsRsp {
|
||
repeated ResultsQuestion questions = 1;
|
||
repeated TeamResult teams = 2;
|
||
}
|
||
|
||
message GameReview {
|
||
int32 ID = 1;
|
||
int32 gameID = 2;
|
||
int32 teamID = 3;
|
||
string team_name = 4;
|
||
int32 rating = 5;
|
||
string text = 6;
|
||
string status = 7;
|
||
google.protobuf.Timestamp created_at = 8;
|
||
string game_name = 9;
|
||
int32 difficulty = 10;
|
||
}
|
||
|
||
message CreateGameReviewReq {
|
||
int32 gameID = 1;
|
||
int32 teamID = 2;
|
||
string password = 3;
|
||
int32 rating = 4;
|
||
string text = 5;
|
||
int32 difficulty = 6;
|
||
}
|
||
|
||
message CreateGameReviewRsp {
|
||
GameReview review = 1;
|
||
}
|
||
|
||
message GetGameReviewsReq {
|
||
int32 gameID = 1;
|
||
}
|
||
|
||
message GetScenarioReviewsReq {
|
||
int32 scenarioID = 1;
|
||
}
|
||
|
||
message GetReviewsForModerationReq {}
|
||
|
||
message GetGameReviewsRsp {
|
||
double average_rating = 1;
|
||
int32 reviews_count = 2;
|
||
repeated GameReview reviews = 3;
|
||
}
|
||
|
||
message ModerateGameReviewReq {
|
||
int32 ID = 1;
|
||
string status = 2;
|
||
}
|
||
|
||
message ModerateGameReviewRsp {
|
||
GameReview review = 1;
|
||
}
|
||
|
||
message UpdateGameReq {
|
||
int32 ID = 1;
|
||
string name = 2;
|
||
string description = 3;
|
||
google.protobuf.Timestamp start_at = 4;
|
||
int32 scenarioID = 5;
|
||
string format = 6;
|
||
string location = 7;
|
||
}
|
||
|
||
message UpdateGameRsp {
|
||
}
|
||
|
||
message StartGameReq {
|
||
int32 ID = 1;
|
||
}
|
||
|
||
message StartGameRsp {
|
||
}
|
||
|
||
message PauseGameReq {
|
||
int32 ID = 1;
|
||
}
|
||
|
||
message PauseGameRsp {
|
||
}
|
||
|
||
message PlayGameReq {
|
||
int32 ID = 1;
|
||
}
|
||
|
||
message PlayGameRsp {
|
||
}
|
||
|
||
message FinishGameReq {
|
||
int32 ID = 1;
|
||
}
|
||
|
||
message FinishGameRsp {
|
||
}
|
||
|
||
message ResetGameReq {
|
||
int32 ID = 1;
|
||
}
|
||
|
||
message ResetGameRsp {
|
||
}
|
||
|
||
message DeleteGameReq {
|
||
int32 ID = 1;
|
||
}
|
||
|
||
message DeleteGameRsp {
|
||
}
|
||
|
||
message AddTeamReq {
|
||
int32 gameID = 1;
|
||
string name = 2;
|
||
string captain_email = 3;
|
||
int32 participants_count = 4;
|
||
}
|
||
|
||
message AddTeamRsp {
|
||
int32 ID = 1;
|
||
string password = 2;
|
||
}
|
||
|
||
message UpdateTeamReq {
|
||
int32 ID = 1;
|
||
string name = 2;
|
||
}
|
||
|
||
message UpdateTeamRsp {
|
||
}
|
||
|
||
message DeleteTeamReq {
|
||
int64 ID = 1;
|
||
}
|
||
|
||
message DeleteTeamRsp {
|
||
}
|
||
|
||
message GiveTeamApplicationsReq {
|
||
int64 ID = 1;
|
||
string name = 2;
|
||
}
|
||
|
||
message GiveTeamApplicationsRsp {
|
||
}
|
||
|
||
message GetTeamStoryReq {
|
||
int64 ID = 1;
|
||
string password = 2;
|
||
}
|
||
|
||
message GetTeamStoryRsp {
|
||
Story story = 1;
|
||
Game game = 2;
|
||
repeated TeamAction actions = 3;
|
||
}
|
||
|
||
message TeamAction {
|
||
string code = 1;
|
||
bool mcp = 2;
|
||
}
|
||
|
||
message AddTeamActionReq {
|
||
int64 ID = 1;
|
||
string password = 2;
|
||
string code = 3;
|
||
}
|
||
|
||
message AddTeamActionRsp {
|
||
}
|
||
|
||
message DeleteLastTeamActionReq {
|
||
int64 ID = 1;
|
||
}
|
||
|
||
message DeleteLastTeamActionRsp {
|
||
}
|
||
|
||
message GetTeamAnswersReq {
|
||
int64 ID = 1;
|
||
string password = 2;
|
||
}
|
||
|
||
message GetTeamAnswersRsp {
|
||
repeated Answer answers = 1;
|
||
}
|
||
|
||
message SubmitTeamAnswersReq {
|
||
int64 ID = 1;
|
||
string password = 2;
|
||
repeated Answer answers = 3;
|
||
}
|
||
|
||
message SubmitTeamAnswersRsp {
|
||
}
|
||
|
||
message SetTeamAnswerScoreReq {
|
||
int64 ID = 1;
|
||
string questionCode = 2;
|
||
// Балл; отсутствует — сбросить выставленный балл
|
||
optional int32 score = 3;
|
||
}
|
||
|
||
message SetTeamAnswerScoreRsp {
|
||
}
|
||
|
||
message UpdateScenarioBackgroundReq {
|
||
int32 ID = 1;
|
||
string background = 2;
|
||
}
|
||
|
||
message UpdateScenarioBackgroundRsp {
|
||
}
|
||
|
||
message IssueGameTicketsReq {
|
||
int32 gameID = 1;
|
||
int32 count = 2;
|
||
}
|
||
|
||
message IssueGameTicketsRsp {
|
||
repeated Ticket tickets = 1;
|
||
}
|
||
|
||
message Ticket {
|
||
int32 ID = 1;
|
||
string URL = 2;
|
||
}
|
||
|
||
message GetTicketReq {
|
||
string token = 1;
|
||
}
|
||
|
||
message GetTicketRsp {
|
||
TicketPage ticket = 1;
|
||
}
|
||
|
||
message AcceptTicketReq {
|
||
string token = 1;
|
||
}
|
||
|
||
message AcceptTicketRsp {
|
||
TicketPage ticket = 1;
|
||
}
|
||
|
||
message TicketPage {
|
||
int32 ID = 1;
|
||
string game_name = 2;
|
||
google.protobuf.Timestamp start_at = 3;
|
||
string location = 4;
|
||
string status = 5;
|
||
string game_status = 6;
|
||
optional google.protobuf.Timestamp used_at = 7;
|
||
string used_by = 8;
|
||
}
|
||
|
||
// Developer tasks use new, in_progress, review and done statuses.
|
||
message DeveloperTask {
|
||
int32 ID = 1;
|
||
string title = 2;
|
||
string description = 3;
|
||
string status = 4;
|
||
// Omitted assignee means the task is unassigned.
|
||
optional int32 assigneeID = 5;
|
||
string assigneeName = 6;
|
||
optional int32 authorID = 7;
|
||
// Calendar deadline in YYYY-MM-DD format; empty means no deadline.
|
||
string dueDate = 8;
|
||
google.protobuf.Timestamp createdAt = 9;
|
||
google.protobuf.Timestamp updatedAt = 10;
|
||
// Required for updates and deletion to detect concurrent edits.
|
||
int32 version = 11;
|
||
}
|
||
|
||
message TaskAssignee {
|
||
int32 ID = 1;
|
||
string name = 2;
|
||
}
|
||
|
||
message GetTasksReq {}
|
||
|
||
message GetTasksRsp { repeated DeveloperTask tasks = 1; }
|
||
|
||
message GetTaskAssigneesReq {}
|
||
|
||
message GetTaskAssigneesRsp { repeated TaskAssignee assignees = 1; }
|
||
|
||
message CreateTaskReq {
|
||
string title = 1;
|
||
string description = 2;
|
||
string status = 3;
|
||
optional int32 assigneeID = 4;
|
||
string dueDate = 5;
|
||
}
|
||
|
||
message UpdateTaskReq {
|
||
int32 ID = 1;
|
||
string title = 2;
|
||
string description = 3;
|
||
string status = 4;
|
||
optional int32 assigneeID = 5;
|
||
string dueDate = 6;
|
||
int32 version = 7;
|
||
}
|
||
|
||
message SetTaskStatusReq {
|
||
int32 ID = 1;
|
||
string status = 2;
|
||
int32 version = 3;
|
||
}
|
||
|
||
message DeleteTaskReq {
|
||
int32 ID = 1;
|
||
int32 version = 2;
|
||
}
|
||
|
||
message TaskRsp { DeveloperTask task = 1; }
|
||
|
||
message DeleteTaskRsp {}
|
||
|
||
message GameResultsPackageReq { int32 ID = 1; }
|
||
message ApplyGameResultsPackageReq {
|
||
int32 ID = 1;
|
||
google.api.HttpBody package = 2;
|
||
}
|
||
message GameResultsPackageRsp {
|
||
int32 gameID = 1;
|
||
string packageID = 2;
|
||
string appliedAt = 3;
|
||
}
|