Skip to content

Commit 18b2b68

Browse files
feat: migrate opening drill logging endpoints to new api schema
1 parent ab7be30 commit 18b2b68

4 files changed

Lines changed: 53 additions & 140 deletions

File tree

src/api/openings.ts

Lines changed: 5 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,17 @@
11
import { buildUrl } from './utils'
22

3-
// API Types for opening drill logging
4-
export interface OpeningDrillSelection {
3+
export interface LogOpeningDrillRequest {
54
opening_fen: string
65
side_played: string
7-
}
8-
9-
export interface SelectOpeningDrillsRequest {
10-
openings: OpeningDrillSelection[]
116
opponent: string
127
num_moves: number
13-
num_drills: number
14-
}
15-
16-
export interface SelectOpeningDrillsResponse {
17-
session_id: string
18-
}
19-
20-
export interface SubmitOpeningDrillRequest {
21-
session_id: string
22-
opening_fen: string
23-
side_played: string
248
moves_played_uci: string[]
259
}
2610

27-
// API function to log opening drill selections and start a session
28-
export const selectOpeningDrills = async (
29-
request: SelectOpeningDrillsRequest,
30-
): Promise<SelectOpeningDrillsResponse> => {
31-
const res = await fetch(buildUrl('opening/select_opening_drills'), {
32-
method: 'POST',
33-
headers: {
34-
Accept: 'application/json',
35-
'Content-Type': 'application/json',
36-
},
37-
body: JSON.stringify(request),
38-
})
39-
40-
if (res.status === 401) {
41-
throw new Error('Unauthorized')
42-
}
43-
44-
if (!res.ok) {
45-
throw new Error(`Failed to select opening drills: ${res.statusText}`)
46-
}
47-
48-
const data = await res.json()
49-
return data as SelectOpeningDrillsResponse
50-
}
51-
52-
// API function to submit a completed opening drill
53-
export const submitOpeningDrill = async (
54-
request: SubmitOpeningDrillRequest,
11+
export const logOpeningDrill = async (
12+
request: LogOpeningDrillRequest,
5513
): Promise<void> => {
56-
const res = await fetch(buildUrl('opening/record_opening_drill'), {
14+
const res = await fetch(buildUrl('opening/log_opening_drill'), {
5715
method: 'POST',
5816
headers: {
5917
Accept: 'application/json',
@@ -67,6 +25,6 @@ export const submitOpeningDrill = async (
6725
}
6826

6927
if (!res.ok) {
70-
throw new Error(`Failed to submit opening drill: ${res.statusText}`)
28+
throw new Error(`Failed to log opening drill: ${res.statusText}`)
7129
}
7230
}

src/components/Openings/OpeningSelectionModal.tsx

Lines changed: 32 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import {
2222
trackDrillConfigurationCompleted,
2323
} from 'src/lib/analytics'
2424
import { MAIA_MODELS_WITH_NAMES } from 'src/constants/common'
25-
import { selectOpeningDrills } from 'src/api/openings'
2625

2726
type MobileTab = 'browse' | 'selected'
2827

@@ -991,65 +990,41 @@ export const OpeningSelectionModal: React.FC<Props> = ({
991990
}
992991
}
993992

994-
const handleStartDrilling = async () => {
995-
if (selections.length > 0) {
996-
try {
997-
// Prepare API request data
998-
const openings = selections.map((selection) => ({
999-
opening_fen: selection.variation
1000-
? selection.variation.fen
1001-
: selection.opening.fen,
1002-
side_played: selection.playerColor,
1003-
}))
1004-
1005-
// Call the backend API to log opening selections and get session ID
1006-
const response = await selectOpeningDrills({
1007-
openings,
1008-
opponent: selectedMaiaVersion.id,
1009-
num_moves: targetMoveNumber,
1010-
num_drills: selections.length, // Use selections length instead of separate drill count
1011-
})
1012-
1013-
const configuration: DrillConfiguration = {
1014-
selections,
1015-
sessionId: response.session_id,
1016-
}
993+
const handleStartDrilling = () => {
994+
if (selections.length === 0) {
995+
return
996+
}
1017997

1018-
// Track drill configuration completion
1019-
const uniqueOpenings = new Set(selections.map((s) => s.opening.id)).size
1020-
const averageTargetMoves =
1021-
selections.reduce((sum, s) => sum + s.targetMoveNumber, 0) /
1022-
selections.length
1023-
const maiaVersionsUsed = [
1024-
...new Set(selections.map((s) => s.maiaVersion)),
1025-
]
1026-
const colorDistribution = selections.reduce(
1027-
(acc, s) => {
1028-
acc[s.playerColor]++
1029-
return acc
1030-
},
1031-
{ white: 0, black: 0 },
1032-
)
998+
const configuration: DrillConfiguration = {
999+
selections,
1000+
}
10331001

1034-
trackDrillConfigurationCompleted(
1035-
selections.length,
1036-
selections.length, // Use selections length for drill count
1037-
uniqueOpenings,
1038-
averageTargetMoves,
1039-
maiaVersionsUsed,
1040-
colorDistribution,
1041-
)
1002+
// Track drill configuration completion
1003+
const uniqueOpenings = new Set(selections.map((s) => s.opening.id)).size
1004+
const averageTargetMoves =
1005+
selections.reduce((sum, s) => sum + s.targetMoveNumber, 0) /
1006+
selections.length
1007+
const maiaVersionsUsed = [
1008+
...new Set(selections.map((s) => s.maiaVersion)),
1009+
]
1010+
const colorDistribution = selections.reduce(
1011+
(acc, s) => {
1012+
acc[s.playerColor]++
1013+
return acc
1014+
},
1015+
{ white: 0, black: 0 },
1016+
)
10421017

1043-
onComplete(configuration)
1044-
} catch (error) {
1045-
console.error('Failed to start drilling session:', error)
1046-
// Still allow the drill to start even if API call fails
1047-
const configuration: DrillConfiguration = {
1048-
selections,
1049-
}
1050-
onComplete(configuration)
1051-
}
1052-
}
1018+
trackDrillConfigurationCompleted(
1019+
selections.length,
1020+
selections.length, // Use selections length for drill count
1021+
uniqueOpenings,
1022+
averageTargetMoves,
1023+
maiaVersionsUsed,
1024+
colorDistribution,
1025+
)
1026+
1027+
onComplete(configuration)
10531028
}
10541029

10551030
return (

src/hooks/useOpeningDrillController/useOpeningDrillController.ts

Lines changed: 16 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Chess } from 'chess.ts'
22
import { fetchGameMove } from 'src/api/play'
3-
import { submitOpeningDrill } from 'src/api/openings'
3+
import { logOpeningDrill } from 'src/api/openings'
44
import { useLocalStorage } from '../useLocalStorage'
55
import { GameTree, GameNode, Color } from 'src/types'
66
import { useState, useMemo, useCallback, useEffect, useRef } from 'react'
@@ -449,21 +449,20 @@ export const useOpeningDrillController = (
449449
try {
450450
setIsAnalyzingDrill(true)
451451

452-
// Submit drill data to backend if session ID is available
453-
if (configuration.sessionId) {
454-
try {
455-
await submitOpeningDrill({
456-
session_id: configuration.sessionId,
457-
opening_fen: drillGame.selection.variation
458-
? drillGame.selection.variation.fen
459-
: drillGame.selection.opening.fen,
460-
side_played: drillGame.selection.playerColor,
461-
moves_played_uci: drillGame.moves,
462-
})
463-
} catch (error) {
464-
console.error('Failed to submit drill to backend:', error)
465-
// Continue even if backend submission fails
466-
}
452+
// Submit drill data to backend once the drill is complete
453+
try {
454+
await logOpeningDrill({
455+
opening_fen: drillGame.selection.variation
456+
? drillGame.selection.variation.fen
457+
: drillGame.selection.opening.fen,
458+
side_played: drillGame.selection.playerColor,
459+
opponent: drillGame.selection.maiaVersion,
460+
num_moves: drillGame.moves.length,
461+
moves_played_uci: drillGame.moves,
462+
})
463+
} catch (error) {
464+
console.error('Failed to log opening drill:', error)
465+
// Continue even if backend submission fails
467466
}
468467

469468
// Simple performance evaluation without complex analysis tracking
@@ -481,26 +480,10 @@ export const useOpeningDrillController = (
481480
setIsAnalyzingDrill(false)
482481
}
483482
},
484-
[currentDrillGame, evaluateDrillPerformance, configuration.sessionId],
483+
[currentDrillGame, evaluateDrillPerformance],
485484
)
486485

487486
const moveToNextDrill = useCallback(async () => {
488-
// Submit drill data to backend if session ID is available
489-
if (configuration.sessionId && currentDrillGame) {
490-
try {
491-
await submitOpeningDrill({
492-
session_id: configuration.sessionId,
493-
opening_fen: currentDrillGame.selection.variation
494-
? currentDrillGame.selection.variation.fen
495-
: currentDrillGame.selection.opening.fen,
496-
side_played: currentDrillGame.selection.playerColor,
497-
moves_played_uci: currentDrillGame.moves,
498-
})
499-
} catch (error) {
500-
console.error('Failed to submit drill to backend:', error)
501-
}
502-
}
503-
504487
setShowPerformanceModal(false)
505488
setCurrentPerformanceData(null)
506489
setContinueAnalyzingMode(false)
@@ -512,8 +495,6 @@ export const useOpeningDrillController = (
512495
}, [
513496
currentDrillIndex,
514497
configuration.selections,
515-
configuration.sessionId,
516-
currentDrillGame,
517498
])
518499

519500
// Navigate to a specific drill by index

src/types/openings.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ export interface OpeningSelection {
2727

2828
export interface DrillConfiguration {
2929
selections: OpeningSelection[]
30-
sessionId?: string
3130
}
3231

3332
export interface OpeningDrillState {

0 commit comments

Comments
 (0)