openapi: 3.0.0 info: title: Api version: 0.0.0 servers: - url: "http://localhost:8080" paths: /purchases/packs/: post: tags: - PurchasesApiV2 summary: createPackPurchase description: "POST /api/v2/purchases/packs/{packId}\nCreate purchase intent for a pack\nReturns purchase info including payment URL for YooKassa" operationId: createPackPurchase parameters: - name: packId in: path required: true schema: type: string responses: 200: description: "Operation completed!" /purchases/packs//status: get: tags: - PurchasesApiV2 summary: getPackPurchaseStatus description: "GET /api/v2/purchases/packs/{packId}/status\nCheck if pack is purchased by the authenticated user" operationId: getPackPurchaseStatus parameters: - name: packId in: path required: true schema: type: string responses: 200: description: "Operation completed!" /purchases/payments: post: tags: - PurchasesApiV2 summary: createPayment description: POST /api/v2/purchases/payments\nCreate a payment\nCurrently supports YooKassa for web payments operationId: createPayment responses: 200: description: "Operation completed!" /purchases/payments//verify: get: tags: - PurchasesApiV2 summary: verifyPayment description: "GET /api/v2/purchases/payments/{paymentId}/verify\nVerify payment status\nUpdates user purchases on success" operationId: verifyPayment parameters: - name: paymentId in: path required: true schema: type: string responses: 200: description: "Operation completed!" /users/me: get: tags: - UsersApiV2 summary: getCurrentUser description: GET /api/v2/users/me\nReturns current authenticated user. operationId: getCurrentUser responses: 200: description: "Operation completed!" patch: tags: - UsersApiV2 summary: updateCurrentUser description: PATCH /api/v2/users/me\nUpdates mutable user fields (currently name and email). operationId: updateCurrentUser responses: 200: description: "Operation completed!" /users/me/settings: post: tags: - UsersApiV2 summary: updateUserSettings description: POST /api/v2/users/me/settings\nUpdates user settings. operationId: updateUserSettings responses: 200: description: "Operation completed!" /users/me/statistics: post: tags: - UsersApiV2 summary: addUserTestStatistics description: POST /api/v2/users/me/statistics\nAdds user test statistics entry. operationId: addUserTestStatistics responses: 200: description: "Operation completed!" /users/me/purchases: get: tags: - UsersApiV2 summary: getUserPurchases description: GET /api/v2/users/me/purchases\nReturns current user's processed purchases. operationId: getUserPurchases responses: 200: description: "Operation completed!" /users/me/statistics/detailed: get: tags: - UsersApiV2 summary: getDetailedStatistics 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: 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." 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: 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." 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: 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 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: 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. 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: 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. Includes both unlocked and locked achievements with progress indicators." operationId: getAchievements security: - bearerAuth: [] responses: 200: 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: - AdminUsersApiV2 summary: getUsers description: GET /api/v2/admin/users\nReturns list of users by optional ids. operationId: getUsers responses: 200: description: "Operation completed!" post: tags: - AdminUsersApiV2 summary: upsertUser description: POST /api/v2/admin/users\nCreates or updates user data (admin editing). operationId: upsertUser responses: 200: description: "Operation completed!" /admin/users/ids: get: tags: - AdminUsersApiV2 summary: getUserIds description: GET /api/v2/admin/users/ids\nReturns comma separated user ids. operationId: getUserIds responses: 200: description: "Operation completed!" /admin/users//purchases: get: tags: - AdminUsersApiV2 summary: getUserPurchases description: "GET /api/v2/admin/users//purchases\nReturns user payments history." operationId: getUserPurchases parameters: - name: userId in: path required: true schema: type: string responses: 200: description: "Operation completed!" /admin/users/: delete: tags: - AdminUsersApiV2 summary: deleteUser description: "DELETE /api/v2/admin/users/\nDeletes user." operationId: deleteUser parameters: - name: userId in: path required: true schema: type: string responses: 200: description: "Operation completed!" /auth/oauth/google: post: tags: - AuthApiV2 summary: authenticateGoogle description: POST /api/v2/auth/oauth/google\nAuthenticate with Google ID token operationId: authenticateGoogle responses: 200: description: "Operation completed!" /auth/telegram/generate-code: post: tags: - AuthApiV2 summary: generateTelegramCode description: "POST /api/v2/auth/telegram/generate-code\nGenerate a new Telegram authentication code\nCalled by the Telegram bot when user requests a code\nBody: { telegramUserId: string, telegramUsername?: string, firstName?: string, lastName?: string }" operationId: generateTelegramCode responses: 200: description: "Operation completed!" /auth/telegram/web-code: post: tags: - AuthApiV2 summary: createWebTelegramCode description: "POST /api/v2/auth/telegram/web-code\nGenerates a new Telegram authentication code initiated from the web app" operationId: createWebTelegramCode responses: 200: description: "Operation completed!" /auth/telegram/claim-code: post: tags: - AuthApiV2 summary: claimTelegramCode description: "POST /api/v2/auth/telegram/claim-code\nCalled by Telegram bot when user sends a code generated via the web app\nBody: { code: string, telegramUserId: string, telegramUsername?: string, firstName?: string, lastName?: string }" operationId: claimTelegramCode responses: 200: description: "Operation completed!" /auth/telegram/code-status/: get: tags: - AuthApiV2 summary: getTelegramCodeStatus description: "GET /api/v2/auth/telegram/code-status/\nReturns current status for a Telegram authentication code" operationId: getTelegramCodeStatus parameters: - name: code in: path required: true schema: type: string responses: 200: description: "Operation completed!" /auth/oauth/telegram: post: tags: - AuthApiV2 summary: authenticateTelegram description: "POST /api/v2/auth/oauth/telegram\nAuthenticate with Telegram auth code from bot\nBody: { code: string }" operationId: authenticateTelegram responses: 200: description: "Operation completed!" /auth/refresh: post: tags: - AuthApiV2 summary: refreshToken description: POST /api/v2/auth/refresh\nRefresh access token using refresh token operationId: refreshToken responses: 200: description: "Operation completed!" /auth/me: get: tags: - AuthApiV2 summary: getCurrentUser description: GET /api/v2/auth/me\nGet current authenticated user (requires Bearer token) operationId: getCurrentUser responses: 200: description: "Operation completed!" /auth/logout: post: tags: - AuthApiV2 summary: logout description: "POST /api/v2/auth/logout\nLogout and invalidate tokens\nBody (optional): { refreshToken: string }" operationId: logout responses: 200: description: "Operation completed!" /tests/: get: tags: - TestsApiV2 summary: getTest description: "GET /api/v2/tests/{testId}\nGet test details by ID" operationId: getTest parameters: - name: testId in: path required: true schema: type: string responses: 200: description: "Operation completed!" /tests//results: post: tags: - TestsApiV2 summary: submitTestResults description: "POST /api/v2/tests/{testId}/results\nSubmit test results" operationId: submitTestResults parameters: - name: testId in: path required: true schema: type: string responses: 200: description: "Operation completed!" /tests//history: get: tags: - TestsApiV2 summary: getTestHistory description: "GET /api/v2/tests/{testId}/history\nGet test attempt history for the authenticated user\nSupports pagination via query params: ?page=1&limit=20" operationId: getTestHistory parameters: - name: testId in: path required: true schema: type: string responses: 200: description: "Operation completed!" /games: get: tags: - GamesApiV2 summary: getGames description: GET /api/v2/games\nGet all available games\nReturns list of games with metadata operationId: getGames responses: 200: description: "Operation completed!" /games//assets: get: tags: - GamesApiV2 summary: getGameAssets description: "GET /api/v2/games/{gameId}/assets\nGet game assets\nReturns game assets file (zip) or asset info" operationId: getGameAssets parameters: - name: gameId in: path required: true schema: type: string responses: 200: description: "Operation completed!" /admin/discounts: get: tags: - DiscountsApiV2 summary: GET /api/v2/admin/discounts operationId: listDiscountCampaigns responses: 200: description: "Operation completed!" post: tags: - DiscountsApiV2 summary: POST /api/v2/admin/discounts operationId: addDiscountCampaign responses: 200: description: "Operation completed!" /admin/discounts/: delete: tags: - DiscountsApiV2 summary: "DELETE /api/v2/admin/discounts/{id}" operationId: deleteDiscountCampaign parameters: - name: id in: path required: true schema: type: string responses: 200: description: "Operation completed!" /subscriptions/plans: get: tags: - SubscriptionsApiV2 summary: getPlans description: GET /api/v2/subscriptions/plans\nList available subscription plans\nReturns all available subscription plans. Authentication is optional. operationId: getPlans responses: 200: description: "Operation completed!" /subscriptions/purchase: post: tags: - SubscriptionsApiV2 summary: purchase description: POST /api/v2/subscriptions/purchase\nPurchase a subscription operationId: purchase responses: 200: description: "Operation completed!" /subscriptions/status: get: tags: - SubscriptionsApiV2 summary: getStatus description: GET /api/v2/subscriptions/status\nGet current user subscription status operationId: getStatus responses: 200: description: "Operation completed!" /subscriptions/cancel: post: tags: - SubscriptionsApiV2 summary: cancel description: POST /api/v2/subscriptions/cancel\nCancel user’s subscription operationId: cancel responses: 200: description: "Operation completed!" /packs: get: tags: - PacksApiV2 summary: getPacks description: "GET /api/v2/packs\nGet all pack previews with pagination\nQuery params: ?search=term&language=lang&page=1&limit=20" operationId: getPacks responses: 200: description: "Operation completed!" /packs/: get: tags: - PacksApiV2 summary: getPack description: "GET /api/v2/packs/{packId}\nGet pack details by ID\nReturns full pack details with purchase status if authenticated" operationId: getPack parameters: - name: packId in: path required: true schema: type: string responses: 200: description: "Operation completed!" /packs//buy: get: tags: - PacksApiV2 summary: getPackBuyPage description: "GET /api/v2/packs/{packId}/buy\nReturns pack purchase details (includes rewarded ads offer when available)" operationId: getPackBuyPage parameters: - name: packId in: path required: true schema: type: string responses: 200: description: "Operation completed!" /packs//cards: get: tags: - PacksApiV2 summary: getPackCards description: "GET /api/v2/packs/{packId}/cards\nGet all cards in a pack\nSupports pagination via query params: ?page=1&limit=20" operationId: getPackCards parameters: - name: packId in: path required: true schema: type: string responses: 200: description: "Operation completed!" /packs//cards//image: get: tags: - PacksApiV2 summary: getCardImage description: "GET /api/v2/packs/{packId}/cards/{cardId}/image\nGet card image\nReturns PNG image file\n\nImages are accessible for enabled packs even without authentication\nto allow image preview in public pack listings" operationId: getCardImage parameters: - name: packId in: path required: true schema: type: string - name: cardId in: path required: true schema: type: string responses: 200: description: "Operation completed!" /packs//tests: get: tags: - PacksApiV2 summary: getPackTests description: "GET /api/v2/packs/{packId}/tests\nGet tests for a pack" operationId: getPackTests parameters: - name: packId in: path required: true schema: type: string responses: 200: description: "Operation completed!" /tasks: get: tags: - TasksApiV2 summary: "GET /api/v2/tasks - Get tasks with optional filtering" operationId: getTasks responses: 200: description: "Operation completed!" /tasks/: get: tags: - TasksApiV2 summary: "GET /api/v2/tasks/{taskId} - Get specific task" operationId: getTask parameters: - name: taskId in: path required: true schema: type: string responses: 200: description: "Operation completed!" /tasks//start: post: tags: - TasksApiV2 summary: "POST /api/v2/tasks/{taskId}/start - Start a task" operationId: startTask parameters: - name: taskId in: path required: true schema: type: string responses: 200: description: "Operation completed!" /tasks//complete: post: tags: - TasksApiV2 summary: "POST /api/v2/tasks/{taskId}/complete - Complete a task" operationId: completeTask parameters: - name: taskId in: path required: true schema: type: string responses: 200: description: "Operation completed!" /users/me/tasks/progress: get: tags: - TasksApiV2 summary: "GET /api/v2/users/me/tasks/progress - Get user task progress" operationId: getUserProgress responses: 200: description: "Operation completed!" /tasks/categories: get: tags: - TasksApiV2 summary: "GET /api/v2/tasks/categories - Get available task categories and filters" operationId: getTaskCategories responses: 200: description: "Operation completed!" /promocodes: get: tags: - PromocodesApiV2 summary: listPromocodes description: GET /api/v2/promocodes\nLists available promocodes for current user.\nReturns active campaigns with promocodes that user can apply. operationId: listPromocodes responses: 200: description: "Operation completed!" /promocodes//validate: get: tags: - PromocodesApiV2 summary: validatePromocode description: "GET /api/v2/promocodes/{code}/validate\nValidates a promocode without applying it.\nReturns validation result with valid: true/false and message." operationId: validatePromocode parameters: - name: code in: path required: true schema: type: string responses: 200: description: "Operation completed!" /promocodes//apply: post: tags: - PromocodesApiV2 summary: applyPromocode description: "POST /api/v2/promocodes/{code}/apply\nApplies promocode for current user." operationId: applyPromocode parameters: - name: code in: path required: true schema: type: string responses: 200: description: "Operation completed!" /admin/promocodes: get: tags: - PromocodesApiV2 summary: listPromoCodeCampaigns description: GET /api/v2/admin/promocodes\nLists promocode campaigns (admin only). operationId: listPromoCodeCampaigns responses: 200: description: "Operation completed!" post: tags: - PromocodesApiV2 summary: upsertPromoCodeCampaign description: POST /api/v2/admin/promocodes\nCreates or updates promocode campaign (admin only). operationId: upsertPromoCodeCampaign responses: 200: description: "Operation completed!" /admin/promocodes/: get: tags: - PromocodesApiV2 summary: getPromoCodeCampaign description: "GET /api/v2/admin/promocodes/{id}\nReturns promocode campaign details (admin only)." operationId: getPromoCodeCampaign parameters: - name: id in: path required: true schema: type: string responses: 200: description: "Operation completed!" delete: tags: - PromocodesApiV2 summary: deletePromoCodeCampaign description: "DELETE /api/v2/admin/promocodes/{id}\nDeletes promocode campaign (admin only)." operationId: deletePromoCodeCampaign parameters: - name: id in: path required: true schema: type: string responses: 200: description: "Operation completed!" /ads/product/acquire/: post: tags: - AdsApiV2 summary: "POST /api/v2/ads/product/acquire/{key}" description: Confirms rewarded ad completion and grants product access to the user. operationId: acquireProductForAd parameters: - name: key in: path required: true schema: type: string responses: 200: description: "Operation completed!" /adsgram/reward: get: tags: - AdsApiV2 summary: "GET /api/v2/adsgram/reward?userId={userId}" description: Callback endpoint for Adsgram rewarded ad completion.\nThis endpoint is called by Adsgram when a user completes a rewarded ad. operationId: adsgramRewardCallback responses: 200: description: "Operation completed!" 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 - name: UsersApiV2 description: "API v2 endpoints for user profile and self-service operations." - name: AdminUsersApiV2 description: Admin endpoints for user management in API v2. - name: AuthApiV2 description: API v2 Authentication endpoints\n\nImplements OAuth2/JWT Bearer token authentication - name: TestsApiV2 description: Tests API v2\n\nRESTful endpoints for managing tests and test results - name: GamesApiV2 description: Games API v2\n\nRESTful endpoints for managing games and game assets - name: DiscountsApiV2 description: Admin endpoints for discount campaign management. - name: SubscriptionsApiV2 description: "Subscriptions API v2\nRESTful endpoints for managing subscriptions & plans" - name: PacksApiV2 description: API v2 Packs endpoints\n\nRESTful endpoints for card packs with pagination and filtering - name: TasksApiV2 description: API v2 endpoints for user tasks management - name: PromocodesApiV2 description: API v2 endpoints for promocode management and activation. - name: AdsApiV2 description: API v2 endpoints for rewarded ads flows.