feat(backend): Update OpenAPI Specification for Statistics Endpoints
Task ID: BACKEND-008 Priority: medium Changes: Completed by: AI Agent Duration: 83447ms
This commit is contained in:
parent
4a468bd0c3
commit
88a69bb605
3 changed files with 867 additions and 16 deletions
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"component": "backend",
|
||||
"current_task_id": "BACKEND-007",
|
||||
"iteration_count": 5,
|
||||
"current_task_id": "BACKEND-008",
|
||||
"iteration_count": 6,
|
||||
"max_iterations": 10,
|
||||
"started_at": "2025-11-21T01:06:15.789515+00:00",
|
||||
"last_commit": null,
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@
|
|||
"id": "BACKEND-008",
|
||||
"title": "Update OpenAPI Specification for Statistics Endpoints",
|
||||
"priority": "medium",
|
||||
"status": "pending",
|
||||
"status": "in_progress",
|
||||
"estimated_hours": 2.0,
|
||||
"description": "Update public/open_api.yaml to include all statistics endpoints (detailed, packs, words, timeline, sessions, achievements) with proper request/response schemas, query parameters, and examples.",
|
||||
"acceptance_criteria": [
|
||||
|
|
|
|||
|
|
@ -117,61 +117,472 @@ paths:
|
|||
tags:
|
||||
- UsersApiV2
|
||||
summary: getDetailedStatistics
|
||||
description: "GET /api/v2/users/me/statistics/detailed\nReturns detailed user statistics including streaks, study time, achievements."
|
||||
description: "GET /api/v2/users/me/statistics/detailed\nReturns detailed user statistics including streaks, study time, achievements, word statistics, and pack progress."
|
||||
operationId: getDetailedStatistics
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
200:
|
||||
description: "Operation completed!"
|
||||
description: Detailed user statistics
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UserDataDto'
|
||||
example:
|
||||
allWordsStatistics:
|
||||
words:
|
||||
- word: "hello"
|
||||
correct: 10.0
|
||||
incorrect: 2.0
|
||||
skipped: 0.0
|
||||
questionTypes: ["translation", "pronunciation"]
|
||||
correct: 150.0
|
||||
incorrect: 30.0
|
||||
skipped: 5.0
|
||||
allTestsStatistics:
|
||||
tests: []
|
||||
totalAttempts: 25
|
||||
averageScore: 0.85
|
||||
lastTimeOnline: "2024-01-15T10:30:00Z"
|
||||
totalStudyTimeMinutes: 1200
|
||||
currentStreak: 7
|
||||
longestStreak: 15
|
||||
packProgress:
|
||||
basic_pack:
|
||||
packId: "basic_pack"
|
||||
totalCards: 100
|
||||
learnedCards: 45
|
||||
studyTimeMinutes: 300
|
||||
lastStudyDate: "2024-01-15T09:00:00Z"
|
||||
firstStudyDate: "2024-01-01T08:00:00Z"
|
||||
cardAttempts: {}
|
||||
averageAccuracy: 0.82
|
||||
studyDates:
|
||||
- "2024-01-15T09:00:00Z"
|
||||
- "2024-01-14T10:00:00Z"
|
||||
categoryMinutes:
|
||||
basic: 300
|
||||
achievements:
|
||||
- id: "streak_7"
|
||||
title: "Week Warrior"
|
||||
description: "Study for 7 consecutive days"
|
||||
type: "streak7Days"
|
||||
unlockedAt: "2024-01-15T09:00:00Z"
|
||||
progress: 1.0
|
||||
401:
|
||||
description: Unauthorized - Authentication required
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "unauthorized"
|
||||
message: "Authentication required"
|
||||
404:
|
||||
description: User data not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "user_data_not_found"
|
||||
500:
|
||||
description: Internal server error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "internal_server_error"
|
||||
message: "An unexpected error occurred"
|
||||
/users/me/statistics/packs:
|
||||
get:
|
||||
tags:
|
||||
- UsersApiV2
|
||||
summary: getPacksStatistics
|
||||
description: "GET /api/v2/users/me/statistics/packs\nReturns statistics for all user packs or specific pack if packId provided.\nQuery parameters: ?packId=<packId>"
|
||||
description: "GET /api/v2/users/me/statistics/packs\nReturns statistics for all user packs or specific pack if packId provided."
|
||||
operationId: getPacksStatistics
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: packId
|
||||
in: query
|
||||
description: Filter by specific pack ID
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
example: "basic_pack"
|
||||
responses:
|
||||
200:
|
||||
description: "Operation completed!"
|
||||
description: List of pack progress statistics
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/PackProgressDto'
|
||||
example:
|
||||
- packId: "basic_pack"
|
||||
totalCards: 100
|
||||
learnedCards: 45
|
||||
studyTimeMinutes: 300
|
||||
lastStudyDate: "2024-01-15T09:00:00Z"
|
||||
firstStudyDate: "2024-01-01T08:00:00Z"
|
||||
cardAttempts: {}
|
||||
averageAccuracy: 0.82
|
||||
- packId: "advanced_pack"
|
||||
totalCards: 200
|
||||
learnedCards: 120
|
||||
studyTimeMinutes: 600
|
||||
lastStudyDate: "2024-01-14T15:00:00Z"
|
||||
firstStudyDate: "2023-12-01T10:00:00Z"
|
||||
cardAttempts: {}
|
||||
averageAccuracy: 0.75
|
||||
401:
|
||||
description: Unauthorized - Authentication required
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "unauthorized"
|
||||
message: "Authentication required"
|
||||
500:
|
||||
description: Internal server error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "internal_server_error"
|
||||
message: "An unexpected error occurred"
|
||||
/users/me/statistics/words:
|
||||
get:
|
||||
tags:
|
||||
- UsersApiV2
|
||||
summary: getWordsStatistics
|
||||
description: "GET /api/v2/users/me/statistics/words\nReturns paginated word statistics with optional filtering.\nQuery parameters:\n- packId: filter by specific pack\n- limit: number of results (default 50, max 100)\n- offset: pagination offset (default 0)\n- sortBy: 'difficulty', 'accuracy', 'recent' (default 'difficulty')\n- needsReview: 'true' to show only words needing review"
|
||||
description: "GET /api/v2/users/me/statistics/words\nReturns paginated word statistics with optional filtering."
|
||||
operationId: getWordsStatistics
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: packId
|
||||
in: query
|
||||
description: Filter by specific pack ID
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
example: "basic_pack"
|
||||
- name: limit
|
||||
in: query
|
||||
description: Number of results per page (default 50, max 100)
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 100
|
||||
default: 50
|
||||
example: 50
|
||||
- name: offset
|
||||
in: query
|
||||
description: Pagination offset (default 0)
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 0
|
||||
default: 0
|
||||
example: 0
|
||||
- name: sortBy
|
||||
in: query
|
||||
description: Sort order - 'difficulty', 'accuracy', 'recent', or 'alphabetical' (default 'difficulty')
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
enum: [difficulty, accuracy, recent, alphabetical]
|
||||
default: difficulty
|
||||
example: "difficulty"
|
||||
- name: needsReview
|
||||
in: query
|
||||
description: Filter to show only words needing review (set to 'true')
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
enum: ["true", "false"]
|
||||
example: "false"
|
||||
responses:
|
||||
200:
|
||||
description: "Operation completed!"
|
||||
description: Paginated word statistics
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/WordStatisticsPaginatedResponse'
|
||||
example:
|
||||
words:
|
||||
- word: "hello"
|
||||
correct: 10.0
|
||||
incorrect: 2.0
|
||||
skipped: 0.0
|
||||
questionTypes: ["translation"]
|
||||
lastReviewed: "2024-01-15T09:00:00Z"
|
||||
firstLearned: "2024-01-01T08:00:00Z"
|
||||
recentAttempts: []
|
||||
difficultyScore: 0.17
|
||||
needsReview: false
|
||||
packId: "basic_pack"
|
||||
- word: "world"
|
||||
correct: 5.0
|
||||
incorrect: 8.0
|
||||
skipped: 1.0
|
||||
questionTypes: ["translation", "pronunciation"]
|
||||
lastReviewed: "2024-01-14T10:00:00Z"
|
||||
firstLearned: "2024-01-01T08:00:00Z"
|
||||
recentAttempts: []
|
||||
difficultyScore: 0.57
|
||||
needsReview: true
|
||||
packId: "basic_pack"
|
||||
totalCount: 45
|
||||
page: 0
|
||||
pageSize: 50
|
||||
hasMore: false
|
||||
400:
|
||||
description: Bad request - Invalid query parameters
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "bad_request"
|
||||
message: "Invalid limit parameter. Must be between 1 and 100."
|
||||
401:
|
||||
description: Unauthorized - Authentication required
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "unauthorized"
|
||||
message: "Authentication required"
|
||||
500:
|
||||
description: Internal server error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "internal_server_error"
|
||||
message: "An unexpected error occurred"
|
||||
/users/me/statistics/timeline:
|
||||
get:
|
||||
tags:
|
||||
- UsersApiV2
|
||||
summary: getTimelineStatistics
|
||||
description: "GET /api/v2/users/me/statistics/timeline\nReturns timeline statistics for study activity.\nQuery parameters:\n- period: 'day', 'week', 'month', 'year' (default 'month')\n- from: ISO date string for start date\n- to: ISO date string for end date"
|
||||
description: "GET /api/v2/users/me/statistics/timeline\nReturns timeline statistics for study activity over a specified period."
|
||||
operationId: getTimelineStatistics
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: period
|
||||
in: query
|
||||
description: Time period - 'day', 'week', 'month', or 'year' (default 'month')
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
enum: [day, week, month, year]
|
||||
default: month
|
||||
example: "month"
|
||||
- name: from
|
||||
in: query
|
||||
description: Start date in ISO 8601 format (overrides period if provided)
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2024-01-01T00:00:00Z"
|
||||
- name: to
|
||||
in: query
|
||||
description: End date in ISO 8601 format (defaults to now if not provided)
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2024-01-31T23:59:59Z"
|
||||
responses:
|
||||
200:
|
||||
description: "Operation completed!"
|
||||
description: Timeline statistics for the specified period
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TimelineStatisticsResponse'
|
||||
example:
|
||||
period: "month"
|
||||
startDate: "2024-01-01T00:00:00Z"
|
||||
endDate: "2024-01-31T23:59:59Z"
|
||||
totalDays: 31
|
||||
activeDays: 20
|
||||
totalMinutes: 1200
|
||||
averageDailyMinutes: 60.0
|
||||
currentStreak: 7
|
||||
dailyActivity:
|
||||
"2024-01-15T00:00:00Z": 60
|
||||
"2024-01-14T00:00:00Z": 45
|
||||
"2024-01-13T00:00:00Z": 30
|
||||
studyDates:
|
||||
- "2024-01-15T09:00:00Z"
|
||||
- "2024-01-14T10:00:00Z"
|
||||
- "2024-01-13T08:00:00Z"
|
||||
400:
|
||||
description: Bad request - Invalid date format
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "bad_request"
|
||||
message: "Invalid date format. Use ISO 8601 format (YYYY-MM-DDTHH:mm:ssZ)."
|
||||
401:
|
||||
description: Unauthorized - Authentication required
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "unauthorized"
|
||||
message: "Authentication required"
|
||||
500:
|
||||
description: Internal server error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "internal_server_error"
|
||||
message: "An unexpected error occurred"
|
||||
/users/me/sessions:
|
||||
post:
|
||||
tags:
|
||||
- UsersApiV2
|
||||
summary: recordStudySession
|
||||
description: POST /api/v2/users/me/sessions\nRecords a study session for the user.
|
||||
description: "POST /api/v2/users/me/sessions\nRecords a study session for the user. Used to track study activity and update statistics."
|
||||
operationId: recordStudySession
|
||||
security:
|
||||
- bearerAuth: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/StudySessionDto'
|
||||
example:
|
||||
sessionId: "session_1234567890"
|
||||
startTime: "2024-01-15T09:00:00Z"
|
||||
endTime: "2024-01-15T09:30:00Z"
|
||||
wordsLearned: 10
|
||||
testsCompleted: 2
|
||||
accuracy: 0.85
|
||||
packId: "basic_pack"
|
||||
testId: null
|
||||
responses:
|
||||
200:
|
||||
description: "Operation completed!"
|
||||
description: Session recorded successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
result:
|
||||
type: boolean
|
||||
example: true
|
||||
sessionId:
|
||||
type: string
|
||||
example: "session_1234567890"
|
||||
example:
|
||||
result: true
|
||||
sessionId: "session_1234567890"
|
||||
400:
|
||||
description: Bad request - Invalid session data
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "bad_request"
|
||||
message: "Invalid session data: startTime is required"
|
||||
401:
|
||||
description: Unauthorized - Authentication required
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "unauthorized"
|
||||
message: "Authentication required"
|
||||
500:
|
||||
description: Internal server error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "internal_server_error"
|
||||
message: "An unexpected error occurred"
|
||||
/users/me/achievements:
|
||||
get:
|
||||
tags:
|
||||
- UsersApiV2
|
||||
summary: getAchievements
|
||||
description: GET /api/v2/users/me/achievements\nReturns user's achievements and progress.
|
||||
description: "GET /api/v2/users/me/achievements\nReturns user's achievements and progress. Includes both unlocked and locked achievements with progress indicators."
|
||||
operationId: getAchievements
|
||||
security:
|
||||
- bearerAuth: []
|
||||
responses:
|
||||
200:
|
||||
description: "Operation completed!"
|
||||
description: List of user achievements
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/AchievementDto'
|
||||
example:
|
||||
- id: "streak_7"
|
||||
title: "Week Warrior"
|
||||
description: "Study for 7 consecutive days"
|
||||
iconUrl: null
|
||||
unlockedAt: "2024-01-15T09:00:00Z"
|
||||
type: "streak7Days"
|
||||
progress: 1.0
|
||||
- id: "words_10"
|
||||
title: "Word Explorer"
|
||||
description: "Learn 10 words"
|
||||
iconUrl: null
|
||||
unlockedAt: "2024-01-10T08:00:00Z"
|
||||
type: "words10Learned"
|
||||
progress: 1.0
|
||||
- id: "streak_30"
|
||||
title: "Monthly Master"
|
||||
description: "Study for 30 consecutive days"
|
||||
iconUrl: null
|
||||
unlockedAt: null
|
||||
type: "streak30Days"
|
||||
progress: 0.23
|
||||
401:
|
||||
description: Unauthorized - Authentication required
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "unauthorized"
|
||||
message: "Authentication required"
|
||||
500:
|
||||
description: Internal server error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
error: "internal_server_error"
|
||||
message: "An unexpected error occurred"
|
||||
/admin/users:
|
||||
get:
|
||||
tags:
|
||||
|
|
@ -760,7 +1171,447 @@ paths:
|
|||
responses:
|
||||
200:
|
||||
description: "Operation completed!"
|
||||
components: { }
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: JWT Bearer token authentication
|
||||
schemas:
|
||||
ErrorResponse:
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
description: Error code identifier
|
||||
example: "bad_request"
|
||||
message:
|
||||
type: string
|
||||
description: Human-readable error message
|
||||
example: "Invalid request parameters"
|
||||
required:
|
||||
- error
|
||||
UserDataDto:
|
||||
type: object
|
||||
description: Comprehensive user statistics and data
|
||||
properties:
|
||||
allWordsStatistics:
|
||||
$ref: '#/components/schemas/AllWordsStatisticsDto'
|
||||
allTestsStatistics:
|
||||
$ref: '#/components/schemas/AllTestsStatisticsDto'
|
||||
lastTimeOnline:
|
||||
type: string
|
||||
format: date-time
|
||||
nullable: true
|
||||
description: When user was last online
|
||||
totalStudyTimeMinutes:
|
||||
type: integer
|
||||
description: Total study time in minutes
|
||||
example: 1200
|
||||
currentStreak:
|
||||
type: integer
|
||||
description: Current consecutive days streak
|
||||
example: 7
|
||||
longestStreak:
|
||||
type: integer
|
||||
description: Longest streak ever achieved
|
||||
example: 15
|
||||
packProgress:
|
||||
type: object
|
||||
additionalProperties:
|
||||
$ref: '#/components/schemas/PackProgressDto'
|
||||
description: Map of pack ID to pack progress statistics
|
||||
studyDates:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: date-time
|
||||
description: List of dates when user studied
|
||||
categoryMinutes:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: integer
|
||||
description: Study time by category/language in minutes
|
||||
achievements:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/AchievementDto'
|
||||
description: User's achievements
|
||||
AllWordsStatisticsDto:
|
||||
type: object
|
||||
description: Aggregated word statistics
|
||||
properties:
|
||||
words:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/WordStatisticsDto'
|
||||
correct:
|
||||
type: number
|
||||
format: double
|
||||
description: Total correct answers
|
||||
incorrect:
|
||||
type: number
|
||||
format: double
|
||||
description: Total incorrect answers
|
||||
skipped:
|
||||
type: number
|
||||
format: double
|
||||
description: Total skipped answers
|
||||
WordStatisticsDto:
|
||||
type: object
|
||||
description: Basic word statistics
|
||||
properties:
|
||||
word:
|
||||
type: string
|
||||
description: The word being tracked
|
||||
example: "hello"
|
||||
correct:
|
||||
type: number
|
||||
format: double
|
||||
description: Number of correct answers
|
||||
example: 10.0
|
||||
incorrect:
|
||||
type: number
|
||||
format: double
|
||||
description: Number of incorrect answers
|
||||
example: 2.0
|
||||
skipped:
|
||||
type: number
|
||||
format: double
|
||||
description: Number of skipped answers
|
||||
example: 0.0
|
||||
questionTypes:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: Types of questions attempted
|
||||
example: ["translation", "pronunciation"]
|
||||
AllTestsStatisticsDto:
|
||||
type: object
|
||||
description: Aggregated test statistics
|
||||
properties:
|
||||
tests:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
totalAttempts:
|
||||
type: integer
|
||||
description: Total number of test attempts
|
||||
averageScore:
|
||||
type: number
|
||||
format: double
|
||||
description: Average test score (0.0 to 1.0)
|
||||
PackProgressDto:
|
||||
type: object
|
||||
description: Statistics about user's progress on a specific pack
|
||||
properties:
|
||||
packId:
|
||||
type: string
|
||||
description: Pack identifier
|
||||
example: "basic_pack"
|
||||
totalCards:
|
||||
type: integer
|
||||
description: Total number of cards in the pack
|
||||
example: 100
|
||||
learnedCards:
|
||||
type: integer
|
||||
description: Number of cards learned by the user
|
||||
example: 45
|
||||
studyTimeMinutes:
|
||||
type: integer
|
||||
description: Total study time spent on this pack in minutes
|
||||
example: 300
|
||||
lastStudyDate:
|
||||
type: string
|
||||
format: date-time
|
||||
nullable: true
|
||||
description: Date when user last studied this pack
|
||||
example: "2024-01-15T09:00:00Z"
|
||||
firstStudyDate:
|
||||
type: string
|
||||
format: date-time
|
||||
nullable: true
|
||||
description: Date when user first started studying this pack
|
||||
example: "2024-01-01T08:00:00Z"
|
||||
cardAttempts:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: integer
|
||||
description: Map of card ID to number of attempts
|
||||
example: {}
|
||||
averageAccuracy:
|
||||
type: number
|
||||
format: double
|
||||
description: Average accuracy across all attempts (0.0 to 1.0)
|
||||
example: 0.82
|
||||
required:
|
||||
- packId
|
||||
- totalCards
|
||||
DetailedWordStatisticsDto:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/WordStatisticsDto'
|
||||
- type: object
|
||||
properties:
|
||||
lastReviewed:
|
||||
type: string
|
||||
format: date-time
|
||||
nullable: true
|
||||
description: When this word was last reviewed
|
||||
firstLearned:
|
||||
type: string
|
||||
format: date-time
|
||||
nullable: true
|
||||
description: When this word was first learned
|
||||
recentAttempts:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/WordAttemptDto'
|
||||
description: Recent attempts (last 10)
|
||||
difficultyScore:
|
||||
type: number
|
||||
format: double
|
||||
description: Difficulty score (0.0 = easy, 1.0 = hard)
|
||||
example: 0.57
|
||||
needsReview:
|
||||
type: boolean
|
||||
description: Whether this word needs review
|
||||
example: true
|
||||
packId:
|
||||
type: string
|
||||
nullable: true
|
||||
description: Which pack this word belongs to
|
||||
example: "basic_pack"
|
||||
WordAttemptDto:
|
||||
type: object
|
||||
description: Individual word attempt data
|
||||
properties:
|
||||
timestamp:
|
||||
type: string
|
||||
format: date-time
|
||||
description: When the attempt happened
|
||||
wasCorrect:
|
||||
type: boolean
|
||||
description: Whether the answer was correct
|
||||
questionType:
|
||||
type: string
|
||||
description: Type of question asked
|
||||
example: "translation"
|
||||
wasSkipped:
|
||||
type: boolean
|
||||
description: Whether the question was skipped
|
||||
default: false
|
||||
required:
|
||||
- timestamp
|
||||
- wasCorrect
|
||||
- questionType
|
||||
WordStatisticsPaginatedResponse:
|
||||
type: object
|
||||
description: Paginated response for word statistics
|
||||
properties:
|
||||
words:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/DetailedWordStatisticsDto'
|
||||
description: List of word statistics
|
||||
totalCount:
|
||||
type: integer
|
||||
description: Total number of words matching the filter
|
||||
example: 45
|
||||
page:
|
||||
type: integer
|
||||
description: Current page number (0-based)
|
||||
example: 0
|
||||
pageSize:
|
||||
type: integer
|
||||
description: Number of results per page
|
||||
example: 50
|
||||
hasMore:
|
||||
type: boolean
|
||||
description: Whether there are more results available
|
||||
example: false
|
||||
required:
|
||||
- words
|
||||
- totalCount
|
||||
- page
|
||||
- pageSize
|
||||
- hasMore
|
||||
TimelineStatisticsResponse:
|
||||
type: object
|
||||
description: Timeline statistics for study activity
|
||||
properties:
|
||||
period:
|
||||
type: string
|
||||
description: Time period used
|
||||
enum: [day, week, month, year]
|
||||
example: "month"
|
||||
startDate:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Start date of the period
|
||||
example: "2024-01-01T00:00:00Z"
|
||||
endDate:
|
||||
type: string
|
||||
format: date-time
|
||||
description: End date of the period
|
||||
example: "2024-01-31T23:59:59Z"
|
||||
totalDays:
|
||||
type: integer
|
||||
description: Total days in the period
|
||||
example: 31
|
||||
activeDays:
|
||||
type: integer
|
||||
description: Number of days with study activity
|
||||
example: 20
|
||||
totalMinutes:
|
||||
type: integer
|
||||
description: Total study time in minutes
|
||||
example: 1200
|
||||
averageDailyMinutes:
|
||||
type: number
|
||||
format: double
|
||||
description: Average study time per active day in minutes
|
||||
example: 60.0
|
||||
currentStreak:
|
||||
type: integer
|
||||
description: Current streak within the period
|
||||
example: 7
|
||||
dailyActivity:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: integer
|
||||
description: Map of date (ISO string) to study minutes for that day
|
||||
example:
|
||||
"2024-01-15T00:00:00Z": 60
|
||||
"2024-01-14T00:00:00Z": 45
|
||||
studyDates:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: date-time
|
||||
description: List of dates when user studied
|
||||
example:
|
||||
- "2024-01-15T09:00:00Z"
|
||||
- "2024-01-14T10:00:00Z"
|
||||
required:
|
||||
- period
|
||||
- startDate
|
||||
- endDate
|
||||
- totalDays
|
||||
- activeDays
|
||||
- totalMinutes
|
||||
- averageDailyMinutes
|
||||
- currentStreak
|
||||
- dailyActivity
|
||||
- studyDates
|
||||
StudySessionDto:
|
||||
type: object
|
||||
description: Study session data for tracking learning activity
|
||||
properties:
|
||||
sessionId:
|
||||
type: string
|
||||
nullable: true
|
||||
description: Unique session identifier
|
||||
example: "session_1234567890"
|
||||
startTime:
|
||||
type: string
|
||||
format: date-time
|
||||
description: When the session started
|
||||
example: "2024-01-15T09:00:00Z"
|
||||
endTime:
|
||||
type: string
|
||||
format: date-time
|
||||
nullable: true
|
||||
description: When the session ended (null if still active)
|
||||
example: "2024-01-15T09:30:00Z"
|
||||
wordsLearned:
|
||||
type: integer
|
||||
description: Number of words learned during this session
|
||||
default: 0
|
||||
example: 10
|
||||
testsCompleted:
|
||||
type: integer
|
||||
description: Number of tests completed during this session
|
||||
default: 0
|
||||
example: 2
|
||||
accuracy:
|
||||
type: number
|
||||
format: double
|
||||
description: Overall accuracy during this session (0.0 to 1.0)
|
||||
default: 0.0
|
||||
example: 0.85
|
||||
packId:
|
||||
type: string
|
||||
nullable: true
|
||||
description: Pack being studied (if focused on specific pack)
|
||||
example: "basic_pack"
|
||||
testId:
|
||||
type: string
|
||||
nullable: true
|
||||
description: Test being taken (if part of a test)
|
||||
required:
|
||||
- startTime
|
||||
AchievementDto:
|
||||
type: object
|
||||
description: Achievement data structure
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: Unique achievement identifier
|
||||
example: "streak_7"
|
||||
title:
|
||||
type: string
|
||||
description: Achievement title
|
||||
example: "Week Warrior"
|
||||
description:
|
||||
type: string
|
||||
description: Achievement description
|
||||
example: "Study for 7 consecutive days"
|
||||
iconUrl:
|
||||
type: string
|
||||
nullable: true
|
||||
description: URL to achievement icon/badge image
|
||||
unlockedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
nullable: true
|
||||
description: When this achievement was unlocked (null if locked)
|
||||
example: "2024-01-15T09:00:00Z"
|
||||
type:
|
||||
type: string
|
||||
description: Achievement type for categorization
|
||||
enum:
|
||||
- firstWordLearned
|
||||
- firstTestCompleted
|
||||
- firstPackCompleted
|
||||
- streak3Days
|
||||
- streak7Days
|
||||
- streak30Days
|
||||
- streak100Days
|
||||
- words10Learned
|
||||
- words50Learned
|
||||
- words100Learned
|
||||
- words500Learned
|
||||
- words1000Learned
|
||||
- perfectTestScore
|
||||
- speedLearner
|
||||
- dedicatedLearner
|
||||
- nightOwl
|
||||
- earlyBird
|
||||
- consistentLearner
|
||||
- languageMaster
|
||||
example: "streak7Days"
|
||||
progress:
|
||||
type: number
|
||||
format: double
|
||||
description: Progress towards unlocking (0.0 to 1.0 for locked achievements)
|
||||
default: 0.0
|
||||
example: 1.0
|
||||
required:
|
||||
- id
|
||||
- title
|
||||
- description
|
||||
- type
|
||||
tags:
|
||||
- name: PurchasesApiV2
|
||||
description: Purchases API v2\n\nRESTful endpoints for managing purchases and payments
|
||||
|
|
|
|||
Loading…
Reference in a new issue