{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://kakitori.page/schemas/result.json","title":"ResultRegistration","description":"POST /api/v1/notes/:key/results のリクエストボディ","type":"object","required":["questionId","gameKey","kind","result"],"additionalProperties":false,"properties":{"questionId":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$","description":"対象問題のid (UUID v7)"},"gameKey":{"type":"string","minLength":21,"maxLength":64,"description":"結果の出所となるゲームのkey (games.key)。ゲーム登録時に発行される"},"kind":{"enum":["practice","reading","writing"],"description":"出題形態 (練習 / 読みテスト / 書き取りテスト)。ゲームが申告"},"result":{"$ref":"#/$defs/blockResult"}},"$defs":{"blockResult":{"type":"object","required":["complete","matched","cells","annotations"],"properties":{"id":{"type":"string","maxLength":64},"complete":{"type":"boolean"},"matched":{"type":"boolean"},"cells":{"type":"array","maxItems":16,"items":{"$ref":"#/$defs/cellResult"}},"annotations":{"type":"array","maxItems":16,"items":{"$ref":"#/$defs/annotationResult"}}}},"cellResult":{"type":"object","required":["kind","chars"],"properties":{"kind":{"enum":["guided","free","blank"]},"chars":{"type":"array","maxItems":32,"items":{"$ref":"#/$defs/charResult"}},"span":{"type":"integer","minimum":1,"maximum":16}}},"annotationResult":{"type":"object","required":["chars"],"properties":{"chars":{"type":"array","maxItems":32,"items":{"$ref":"#/$defs/charResult"}},"cellRange":{"type":"array","prefixItems":[{"type":"integer","minimum":0},{"type":"integer","minimum":0}],"minItems":2,"maxItems":2},"placement":{"enum":["top","bottom","left","right"]},"sizeRatio":{"type":"number","exclusiveMinimum":0,"maximum":1}}},"charResult":{"type":"object","required":["character","complete","matched","perStroke","outlineShown"],"properties":{"character":{"type":"string","minLength":1,"maxLength":2},"complete":{"type":"boolean"},"matched":{"type":"boolean"},"perStroke":{"type":"array","maxItems":64,"items":{"$ref":"#/$defs/strokeResult"}},"outlineShown":{"type":"boolean","description":"書いている間にお手本 (アウトライン) が見えていたか。guidedの書き取りで途中一瞬でも表示されたらtrue。show / free / annotation由来は常にfalse"},"mistakes":{"type":"integer","minimum":0},"strokeEndingMistakes":{"type":"integer","minimum":0},"mistakeEvents":{"type":"array","maxItems":512,"items":{"$ref":"#/$defs/charMistakeEvent"}},"similarity":{"type":"number","minimum":0,"maximum":1},"candidate":{"type":"string","maxLength":32},"source":{"enum":["guided","free","annotation"]},"mode":{"enum":["write","show"]}}},"charMistakeEvent":{"type":"object","required":["strokeNum","kind","mistakesOnStroke","similarity","attempt"],"properties":{"strokeNum":{"type":"integer","minimum":0,"maximum":64},"kind":{"enum":["shape","backwards","ending"]},"mistakesOnStroke":{"type":"integer","minimum":0},"similarity":{"type":"number","minimum":0,"maximum":1},"strokeEnding":{"$ref":"#/$defs/strokeEnding"},"attempt":{"type":"integer","minimum":1}},"if":{"properties":{"kind":{"const":"ending"}},"required":["kind"]},"then":{"required":["strokeEnding"]},"else":{"not":{"required":["strokeEnding"]}}},"strokeResult":{"type":"object","required":["matched","similarity"],"properties":{"matched":{"type":"boolean"},"similarity":{"type":"number","minimum":0,"maximum":1},"strokeEnding":{"$ref":"#/$defs/strokeEnding"},"points":{"type":"array","maxItems":512,"items":{"$ref":"#/$defs/timedPoint"}},"mistakesOnStroke":{"type":"integer","minimum":0},"isBackwards":{"type":"boolean"}}},"strokeEnding":{"type":"object","required":["correct"],"properties":{"correct":{"type":"boolean"},"expected":{"type":"array","items":{"enum":["tome","hane","harai"]}},"observed":{"enum":["tome","hane","harai",null]},"confidence":{"type":"number","minimum":0,"maximum":1},"velocityProfile":{"enum":["decelerating","constant","accelerating"]},"actualEndDirection":{"type":["array","null"],"items":{"type":"number"},"minItems":2,"maxItems":2}}},"timedPoint":{"type":"object","required":["x","y","t"],"properties":{"x":{"type":"number","minimum":-128,"maximum":1152},"y":{"type":"number","minimum":-256,"maximum":1024},"t":{"type":"number","minimum":0}},"description":"hanzi-writer内部座標系 (x 0〜1024、y -124〜900) に許容マージンを加えた範囲。tはストローク開始からのms"}}}