This commit is contained in:
2026-09-01 01:04:38 +07:00
parent 1bf463de02
commit cfda264b02
2 changed files with 459 additions and 9 deletions
+187
View File
@@ -365,6 +365,38 @@ service EveningDetectiveServer {
}; };
} }
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: "Удалить вопрос дела";
};
}
rpc UpdateScenarioIntro(UpdateScenarioIntroReq) returns (UpdateScenarioIntroRsp) { rpc UpdateScenarioIntro(UpdateScenarioIntroReq) returns (UpdateScenarioIntroRsp) {
option (google.api.http) = { option (google.api.http) = {
put : "/api/scenarios/{id}/introduction" put : "/api/scenarios/{id}/introduction"
@@ -428,6 +460,16 @@ service EveningDetectiveServer {
}; };
} }
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 UpdateGame(UpdateGameReq) returns (UpdateGameRsp) { rpc UpdateGame(UpdateGameReq) returns (UpdateGameRsp) {
option (google.api.http) = { option (google.api.http) = {
put : "/api/games/{id}" put : "/api/games/{id}"
@@ -583,6 +625,44 @@ service EveningDetectiveServer {
summary: "Удалить последний ход"; 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 PingReq {}
@@ -792,6 +872,7 @@ message Scenario {
message Story { message Story {
Introduction introduction = 2; Introduction introduction = 2;
repeated Place places = 1; repeated Place places = 1;
repeated Question questions = 3;
} }
message Introduction { message Introduction {
@@ -829,6 +910,43 @@ message Key {
string name = 1; 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 { message UpdateScenarioReq {
int32 id = 1; int32 id = 1;
string name = 2; string name = 2;
@@ -901,6 +1019,34 @@ message UpdateScenarioIntroRsp {
string error = 1; string error = 1;
} }
message AddScenarioQuestionReq {
int32 id = 1;
Question question = 2;
}
message AddScenarioQuestionRsp {
string error = 1;
}
message UpdateScenarioQuestionReq {
int32 id = 1;
string code = 2;
Question question = 3;
}
message UpdateScenarioQuestionRsp {
string error = 1;
}
message DeleteScenarioQuestionReq {
int32 id = 1;
string code = 2;
}
message DeleteScenarioQuestionRsp {
string error = 1;
}
message DownloadScenarioArchiveReq { message DownloadScenarioArchiveReq {
int32 id = 1; int32 id = 1;
} }
@@ -959,6 +1105,16 @@ message GetGameRsp {
Game game = 2; Game game = 2;
} }
message GetGameAnswersReq {
int32 gameId = 1;
}
message GetGameAnswersRsp {
string error = 1;
repeated Question questions = 2;
repeated TeamAnswers teams = 3;
}
message UpdateGameReq { message UpdateGameReq {
int32 id = 1; int32 id = 1;
string name = 2; string name = 2;
@@ -1084,3 +1240,34 @@ message DeleteLastTeamActionReq {
message DeleteLastTeamActionRsp { message DeleteLastTeamActionRsp {
string error = 1; string error = 1;
} }
message GetTeamAnswersReq {
int64 id = 1;
string password = 2;
}
message GetTeamAnswersRsp {
string error = 1;
repeated Answer answers = 2;
}
message SubmitTeamAnswersReq {
int64 id = 1;
string password = 2;
repeated Answer answers = 3;
}
message SubmitTeamAnswersRsp {
string error = 1;
}
message SetTeamAnswerScoreReq {
int64 id = 1;
string questionCode = 2;
// Балл; отсутствует — сбросить выставленный балл
optional int32 score = 3;
}
message SetTeamAnswerScoreRsp {
string error = 1;
}
@@ -208,6 +208,7 @@ export type Scenario = {
export type Story = { export type Story = {
introduction: Introduction | undefined; introduction: Introduction | undefined;
places: Place[] | undefined; places: Place[] | undefined;
questions: Question[] | undefined;
}; };
export type Introduction = { export type Introduction = {
@@ -245,6 +246,18 @@ export type Key = {
name: string | undefined; name: string | undefined;
}; };
// Вопрос дела - вопрос, на который команда должна ответить в конце игры.
// Правильный ответ (answer) виден только автору сценария и организаторам
// (при оценке ответов команд), команде не передаётся.
export type Question = {
// Код вопроса - используется при отправке ответов командой
code: string | undefined;
// Текст вопроса
text: string | undefined;
// Правильный ответ (справка для организатора при оценке)
answer: string | undefined;
};
export type GetScenariosCatalogReq = { export type GetScenariosCatalogReq = {
}; };
@@ -262,6 +275,37 @@ export type GetScenarioRsp = {
scenario: Scenario | undefined; scenario: Scenario | undefined;
}; };
// Ответ команды на вопрос дела
export type Answer = {
// Код вопроса
questionCode: string | undefined;
// Текст ответа команды
answer: string | undefined;
};
// Ответ команды с баллом (для панели организатора)
export type AnswerScore = {
questionCode: string | undefined;
answer: string | undefined;
// Балл, выставленный организатором; отсутствует, если ещё не оценено
score?: number;
};
// Ответы одной команды на вопросы дела
export type TeamAnswers = {
team: Team | undefined;
answers: AnswerScore[] | undefined;
};
export type Team = {
id: number | undefined;
name: string | undefined;
status: string | undefined;
password: string | undefined;
actionsCount: number | undefined;
applications: Application[] | undefined;
};
export type UpdateScenarioReq = { export type UpdateScenarioReq = {
id: number | undefined; id: number | undefined;
name: string | undefined; name: string | undefined;
@@ -334,6 +378,34 @@ export type UpdateScenarioIntroRsp = {
error: string | undefined; error: string | undefined;
}; };
export type AddScenarioQuestionReq = {
id: number | undefined;
question: Question | undefined;
};
export type AddScenarioQuestionRsp = {
error: string | undefined;
};
export type UpdateScenarioQuestionReq = {
id: number | undefined;
code: string | undefined;
question: Question | undefined;
};
export type UpdateScenarioQuestionRsp = {
error: string | undefined;
};
export type DeleteScenarioQuestionReq = {
id: number | undefined;
code: string | undefined;
};
export type DeleteScenarioQuestionRsp = {
error: string | undefined;
};
export type DownloadScenarioArchiveReq = { export type DownloadScenarioArchiveReq = {
id: number | undefined; id: number | undefined;
}; };
@@ -375,15 +447,6 @@ export type Game = {
endedAt?: wellKnownTimestamp; endedAt?: wellKnownTimestamp;
}; };
export type Team = {
id: number | undefined;
name: string | undefined;
status: string | undefined;
password: string | undefined;
actionsCount: number | undefined;
applications: Application[] | undefined;
};
export type GetGameReq = { export type GetGameReq = {
id: number | undefined; id: number | undefined;
}; };
@@ -393,6 +456,16 @@ export type GetGameRsp = {
game: Game | undefined; game: Game | undefined;
}; };
export type GetGameAnswersReq = {
gameId: number | undefined;
};
export type GetGameAnswersRsp = {
error: string | undefined;
questions: Question[] | undefined;
teams: TeamAnswers[] | undefined;
};
export type UpdateGameReq = { export type UpdateGameReq = {
id: number | undefined; id: number | undefined;
name: string | undefined; name: string | undefined;
@@ -519,6 +592,37 @@ export type DeleteLastTeamActionRsp = {
error: string | undefined; error: string | undefined;
}; };
export type GetTeamAnswersReq = {
id: number | undefined;
password: string | undefined;
};
export type GetTeamAnswersRsp = {
error: string | undefined;
answers: Answer[] | undefined;
};
export type SubmitTeamAnswersReq = {
id: number | undefined;
password: string | undefined;
answers: Answer[] | undefined;
};
export type SubmitTeamAnswersRsp = {
error: string | undefined;
};
export type SetTeamAnswerScoreReq = {
id: number | undefined;
questionCode: string | undefined;
// Балл; отсутствует — сбросить выставленный балл
score?: number;
};
export type SetTeamAnswerScoreRsp = {
error: string | undefined;
};
export interface EveningDetectiveServer { export interface EveningDetectiveServer {
Ping(request: PingReq): Promise<PingRsp>; Ping(request: PingReq): Promise<PingRsp>;
Echo(request: EchoReq): Promise<EchoRsp>; Echo(request: EchoReq): Promise<EchoRsp>;
@@ -550,12 +654,16 @@ export interface EveningDetectiveServer {
AddScenarioPlace(request: AddScenarioPlaceReq): Promise<AddScenarioPlaceRsp>; AddScenarioPlace(request: AddScenarioPlaceReq): Promise<AddScenarioPlaceRsp>;
UpdateScenarioPlace(request: UpdateScenarioPlaceReq): Promise<UpdateScenarioPlaceRsp>; UpdateScenarioPlace(request: UpdateScenarioPlaceReq): Promise<UpdateScenarioPlaceRsp>;
DeleteScenarioPlace(request: DeleteScenarioPlaceReq): Promise<DeleteScenarioPlaceRsp>; DeleteScenarioPlace(request: DeleteScenarioPlaceReq): Promise<DeleteScenarioPlaceRsp>;
AddScenarioQuestion(request: AddScenarioQuestionReq): Promise<AddScenarioQuestionRsp>;
UpdateScenarioQuestion(request: UpdateScenarioQuestionReq): Promise<UpdateScenarioQuestionRsp>;
DeleteScenarioQuestion(request: DeleteScenarioQuestionReq): Promise<DeleteScenarioQuestionRsp>;
UpdateScenarioIntro(request: UpdateScenarioIntroReq): Promise<UpdateScenarioIntroRsp>; UpdateScenarioIntro(request: UpdateScenarioIntroReq): Promise<UpdateScenarioIntroRsp>;
DownloadScenarioArchive(request: DownloadScenarioArchiveReq): Promise<googleapi_HttpBody>; DownloadScenarioArchive(request: DownloadScenarioArchiveReq): Promise<googleapi_HttpBody>;
UploadScenarioArchive(request: googleapi_HttpBody): Promise<UploadScenarioArchiveRsp>; UploadScenarioArchive(request: googleapi_HttpBody): Promise<UploadScenarioArchiveRsp>;
AddGame(request: AddGameReq): Promise<AddGameRsp>; AddGame(request: AddGameReq): Promise<AddGameRsp>;
GetGames(request: GetGamesReq): Promise<GetGamesRsp>; GetGames(request: GetGamesReq): Promise<GetGamesRsp>;
GetGame(request: GetGameReq): Promise<GetGameRsp>; GetGame(request: GetGameReq): Promise<GetGameRsp>;
GetGameAnswers(request: GetGameAnswersReq): Promise<GetGameAnswersRsp>;
UpdateGame(request: UpdateGameReq): Promise<UpdateGameRsp>; UpdateGame(request: UpdateGameReq): Promise<UpdateGameRsp>;
StartGame(request: StartGameReq): Promise<StartGameRsp>; StartGame(request: StartGameReq): Promise<StartGameRsp>;
PauseGame(request: PauseGameReq): Promise<PauseGameRsp>; PauseGame(request: PauseGameReq): Promise<PauseGameRsp>;
@@ -570,6 +678,9 @@ export interface EveningDetectiveServer {
GetTeamStory(request: GetTeamStoryReq): Promise<GetTeamStoryRsp>; GetTeamStory(request: GetTeamStoryReq): Promise<GetTeamStoryRsp>;
AddTeamAction(request: AddTeamActionReq): Promise<AddTeamActionRsp>; AddTeamAction(request: AddTeamActionReq): Promise<AddTeamActionRsp>;
DeleteLastTeamAction(request: DeleteLastTeamActionReq): Promise<DeleteLastTeamActionRsp>; DeleteLastTeamAction(request: DeleteLastTeamActionReq): Promise<DeleteLastTeamActionRsp>;
GetTeamAnswers(request: GetTeamAnswersReq): Promise<GetTeamAnswersRsp>;
SubmitTeamAnswers(request: SubmitTeamAnswersReq): Promise<SubmitTeamAnswersRsp>;
SetTeamAnswerScore(request: SetTeamAnswerScoreReq): Promise<SetTeamAnswerScoreRsp>;
} }
type RequestType = { type RequestType = {
@@ -1142,6 +1253,72 @@ export function createEveningDetectiveServerClient(
method: "DeleteScenarioPlace", method: "DeleteScenarioPlace",
}) as Promise<DeleteScenarioPlaceRsp>; }) as Promise<DeleteScenarioPlaceRsp>;
}, },
AddScenarioQuestion(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
if (!request.id) {
throw new Error("missing required field request.id");
}
const path = `api/scenarios/${request.id}/questions`; // eslint-disable-line quotes
const body = JSON.stringify(request);
const queryParams: string[] = [];
let uri = path;
if (queryParams.length > 0) {
uri += `?${queryParams.join("&")}`
}
return handler({
path: uri,
method: "POST",
body,
}, {
service: "EveningDetectiveServer",
method: "AddScenarioQuestion",
}) as Promise<AddScenarioQuestionRsp>;
},
UpdateScenarioQuestion(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
if (!request.id) {
throw new Error("missing required field request.id");
}
if (!request.code) {
throw new Error("missing required field request.code");
}
const path = `api/scenarios/${request.id}/questions/${request.code}`; // eslint-disable-line quotes
const body = JSON.stringify(request);
const queryParams: string[] = [];
let uri = path;
if (queryParams.length > 0) {
uri += `?${queryParams.join("&")}`
}
return handler({
path: uri,
method: "PUT",
body,
}, {
service: "EveningDetectiveServer",
method: "UpdateScenarioQuestion",
}) as Promise<UpdateScenarioQuestionRsp>;
},
DeleteScenarioQuestion(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
if (!request.id) {
throw new Error("missing required field request.id");
}
if (!request.code) {
throw new Error("missing required field request.code");
}
const path = `api/scenarios/${request.id}/questions/${request.code}`; // eslint-disable-line quotes
const body = null;
const queryParams: string[] = [];
let uri = path;
if (queryParams.length > 0) {
uri += `?${queryParams.join("&")}`
}
return handler({
path: uri,
method: "DELETE",
body,
}, {
service: "EveningDetectiveServer",
method: "DeleteScenarioQuestion",
}) as Promise<DeleteScenarioQuestionRsp>;
},
UpdateScenarioIntro(request) { // eslint-disable-line @typescript-eslint/no-unused-vars UpdateScenarioIntro(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
if (!request.id) { if (!request.id) {
throw new Error("missing required field request.id"); throw new Error("missing required field request.id");
@@ -1253,6 +1430,26 @@ export function createEveningDetectiveServerClient(
method: "GetGame", method: "GetGame",
}) as Promise<GetGameRsp>; }) as Promise<GetGameRsp>;
}, },
GetGameAnswers(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
if (!request.gameId) {
throw new Error("missing required field request.gameId");
}
const path = `api/games/${request.gameId}/answers`; // eslint-disable-line quotes
const body = null;
const queryParams: string[] = [];
let uri = path;
if (queryParams.length > 0) {
uri += `?${queryParams.join("&")}`
}
return handler({
path: uri,
method: "GET",
body,
}, {
service: "EveningDetectiveServer",
method: "GetGameAnswers",
}) as Promise<GetGameAnswersRsp>;
},
UpdateGame(request) { // eslint-disable-line @typescript-eslint/no-unused-vars UpdateGame(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
if (!request.id) { if (!request.id) {
throw new Error("missing required field request.id"); throw new Error("missing required field request.id");
@@ -1533,6 +1730,72 @@ export function createEveningDetectiveServerClient(
method: "DeleteLastTeamAction", method: "DeleteLastTeamAction",
}) as Promise<DeleteLastTeamActionRsp>; }) as Promise<DeleteLastTeamActionRsp>;
}, },
GetTeamAnswers(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
if (!request.id) {
throw new Error("missing required field request.id");
}
const path = `api/teams/${request.id}/answers`; // eslint-disable-line quotes
const body = null;
const queryParams: string[] = [];
if (request.password) {
queryParams.push(`password=${encodeURIComponent(request.password.toString())}`)
}
let uri = path;
if (queryParams.length > 0) {
uri += `?${queryParams.join("&")}`
}
return handler({
path: uri,
method: "GET",
body,
}, {
service: "EveningDetectiveServer",
method: "GetTeamAnswers",
}) as Promise<GetTeamAnswersRsp>;
},
SubmitTeamAnswers(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
if (!request.id) {
throw new Error("missing required field request.id");
}
const path = `api/teams/${request.id}/answers`; // eslint-disable-line quotes
const body = JSON.stringify(request);
const queryParams: string[] = [];
let uri = path;
if (queryParams.length > 0) {
uri += `?${queryParams.join("&")}`
}
return handler({
path: uri,
method: "POST",
body,
}, {
service: "EveningDetectiveServer",
method: "SubmitTeamAnswers",
}) as Promise<SubmitTeamAnswersRsp>;
},
SetTeamAnswerScore(request) { // eslint-disable-line @typescript-eslint/no-unused-vars
if (!request.id) {
throw new Error("missing required field request.id");
}
if (!request.questionCode) {
throw new Error("missing required field request.questionCode");
}
const path = `api/teams/${request.id}/answers/${request.questionCode}/score`; // eslint-disable-line quotes
const body = JSON.stringify(request);
const queryParams: string[] = [];
let uri = path;
if (queryParams.length > 0) {
uri += `?${queryParams.join("&")}`
}
return handler({
path: uri,
method: "PUT",
body,
}, {
service: "EveningDetectiveServer",
method: "SetTeamAnswerScore",
}) as Promise<SetTeamAnswerScoreRsp>;
},
}; };
} }
// Message that represents an arbitrary HTTP body. It should only be used for // Message that represents an arbitrary HTTP body. It should only be used for