Skip to content
Snippets Groups Projects
Commit 3efcdea5 authored by Paolo.Brasolin's avatar Paolo.Brasolin
Browse files

feat: #be implement precise word choice API

parent 899bf047
No related branches found
No related tags found
No related merge requests found
...@@ -20,21 +20,34 @@ type IdInParamsType = Static<typeof IdInParamsSchema>; ...@@ -20,21 +20,34 @@ type IdInParamsType = Static<typeof IdInParamsSchema>;
const apiPlugin: FastifyPluginCallback = (fastify, options, next) => { const apiPlugin: FastifyPluginCallback = (fastify, options, next) => {
fastify.route<{ fastify.route<{
Body: Types.WordChoice;
Reply: Types.Word; Reply: Types.Word;
}>({ }>({
method: "GET", method: "POST",
url: "/word", url: "/words/choice",
schema: { schema: {
body: Schemas.WordChoice,
response: { response: {
200: Schemas.Word, 200: Schemas.Word,
404: {}, // TODO: JSend error 404: {}, // TODO: JSend error
}, },
}, },
handler: async (request, reply) => { handler: async (request, reply) => {
const ocrConfidenceRange: readonly [number, number] = [
request.body.ocr_confidence_min,
request.body.ocr_confidence_max,
];
const ocrTranscriptLengthRange: readonly [number, number] = [
request.body.ocr_transcript_length_min,
request.body.ocr_transcript_length_max,
];
const ocrTranscriptRegex =
"^[[:alpha:]]{" + ocrTranscriptLengthRange.join(",") + "}$";
// TODO: scope this to game to avoid collisions // TODO: scope this to game to avoid collisions
const word = await connection<Types.Word>("words") const word = await connection<Types.Word>("words")
.whereBetween("ocr_confidence", [0.4, 0.8]) // i.e. needs improvement but it's not trash .whereBetween("ocr_confidence", ocrConfidenceRange)
.whereRaw(`"ocr_transcript" ~ '^[[:alpha:]]+$'`) // i.e. no numbers nor symbols .where("ocr_transcript", "~", ocrTranscriptRegex)
.orderByRaw("RANDOM()") .orderByRaw("RANDOM()")
.first(); .first();
if (word === undefined) { if (word === undefined) {
......
...@@ -60,3 +60,18 @@ export const ClueCreate = Type.Intersect([ ...@@ -60,3 +60,18 @@ export const ClueCreate = Type.Intersect([
]); ]);
export const ShotCreate = Type.Omit(Shot, ["id", "game_id"]); export const ShotCreate = Type.Omit(Shot, ["id", "game_id"]);
export const WordChoice = Type.Object({
ocr_confidence_min: Type.Number({
minimum: 0.0,
default: 0.4,
maximum: 1.0,
}),
ocr_confidence_max: Type.Number({
minimum: 0.0,
default: 0.8,
maximum: 1.0,
}),
ocr_transcript_length_min: Type.Number({ minimum: 1, default: 1 }),
ocr_transcript_length_max: Type.Number({ minimum: 1, default: 20 }),
});
...@@ -13,3 +13,5 @@ export type GameUpdate = Static<typeof Schemas.GameUpdate>; ...@@ -13,3 +13,5 @@ export type GameUpdate = Static<typeof Schemas.GameUpdate>;
export type ClueCreate = Static<typeof Schemas.ClueCreate>; export type ClueCreate = Static<typeof Schemas.ClueCreate>;
export type ClueUpdate = Static<typeof Schemas.ClueUpdate>; export type ClueUpdate = Static<typeof Schemas.ClueUpdate>;
export type ShotCreate = Static<typeof Schemas.ShotCreate>; export type ShotCreate = Static<typeof Schemas.ShotCreate>;
export type WordChoice = Static<typeof Schemas.WordChoice>;
...@@ -18,7 +18,8 @@ export default { ...@@ -18,7 +18,8 @@ export default {
createDevice: () => backend.post<Types.Device>("/api/devices"), createDevice: () => backend.post<Types.Device>("/api/devices"),
getDevice: (deviceId: string) => getDevice: (deviceId: string) =>
backend.get<Types.Device>(`/api/devices/${deviceId}`), backend.get<Types.Device>(`/api/devices/${deviceId}`),
getWord: () => backend.get<Types.Word>("/api/word"), createWordChoice: (data: Types.WordChoice) =>
backend.post<Types.Word>("/api/words/choice", data),
createGame: (deviceId: string, data: Types.GameCreate) => createGame: (deviceId: string, data: Types.GameCreate) =>
backend.post<Types.Game>(`/api/devices/${deviceId}/games`, data), backend.post<Types.Game>(`/api/devices/${deviceId}/games`, data),
updateGame: (gameId: string, data: Types.GameUpdate) => updateGame: (gameId: string, data: Types.GameUpdate) =>
......
...@@ -22,7 +22,7 @@ class Foe { ...@@ -22,7 +22,7 @@ class Foe {
} }
async initialize() { async initialize() {
this.beWord = (await backend.getWord()).data; this.beWord = (await backend.createWordChoice({})).data;
if (!this.scene.scene.isActive()) return; if (!this.scene.scene.isActive()) return;
this.beClue = ( this.beClue = (
await backend.createClue(this.scene.beGame.id, { await backend.createClue(this.scene.beGame.id, {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment