Skip to main content
POST
/
api
/
history
Practice History
curl --request POST \
  --url https://api.example.com/api/history \
  --header 'Content-Type: application/json' \
  --data '
{
  "sessionId": "<string>",
  "timestamp": "<string>",
  "section": "<string>",
  "questionIds": [
    {}
  ],
  "responses": {},
  "score": 123,
  "totalQuestions": 123,
  "timeTaken": 123,
  "bookmarkedQuestionIds": [
    {}
  ]
}
'
{
  "practiceHistory": [
    {}
  ],
  "bookmarkedQuestions": [
    {}
  ],
  "progress": {},
  "PracticeQuestions": 123,
  "StudyStreak": 123,
  "lastStudyDate": "<string>",
  "updatedAt": "<string>",
  "error": "<string>"
}

Overview

This endpoint records practice session results and updates comprehensive user statistics in Firestore. It manages practice history (limited to 3 sessions, one per section), tracks study streaks, updates progress metrics, and manages bookmarked questions.

Authentication

Requires a valid user UUID passed as a query parameter.

Request

uuid
string
required
Unique identifier for the user

Body Parameters

sessionId
string
required
Unique identifier for this practice session
timestamp
string
required
ISO timestamp when the session was completed
section
string
required
Section practiced: “analytical-reasoning”, “logical-reasoning”, or “reading-comprehension”
questionIds
array
required
Array of question IDs attempted in this session
responses
object
required
Object mapping question IDs to user responses
score
number
required
Number of correct answers (can be 0)
totalQuestions
number
required
Total number of questions in the session
timeTaken
number
required
Time taken for the session in seconds (can be 0)
bookmarkedQuestionIds
array
required
Array of question IDs that were bookmarked during this session

Response

practiceHistory
array
Updated practice history array (max 3 sessions, one per section)
bookmarkedQuestions
array
Updated array of all bookmarked question IDs (unique values only)
progress
object
Updated progress tracking object with fields:
  • analyticalReasoning: Number of analytical reasoning sessions completed
  • logicalReasoning: Number of logical reasoning sessions completed
  • readingComprehension: Number of reading comprehension sessions completed
  • testAttempts: Total number of test attempts
  • totalTimeSpent: Total time spent practicing (in seconds)
PracticeQuestions
number
Total number of practice questions completed
StudyStreak
number
Current consecutive days of practice
lastStudyDate
string
Date of last study session (YYYY-MM-DD format)
updatedAt
string
Timestamp of the last update (ISO format)

Practice History Management

The endpoint maintains a maximum of 3 practice sessions in history:
  1. Section Replacement: Replaces existing session for the same section
  2. Limit Enforcement: If more than 3 sessions exist, removes the oldest
  3. One Per Section: Ensures only one session per section is stored
Source: /workspace/source/src/app/api/history/route.ts:94-104

Study Streak Calculation

Same-day logic as the study plan endpoint:
  • Same Day: Streak remains unchanged if practicing on the same day
  • Next Day: Streak increments by 1 for consecutive day practice
  • Gap: Streak resets to 1 if there’s a gap of more than one day
Source: /workspace/source/src/app/api/history/route.ts:134-156

Progress Tracking

The endpoint automatically increments section-specific counters:
  • analyticalReasoning: +1 when section === "analytical-reasoning"
  • logicalReasoning: +1 when section === "logical-reasoning"
  • readingComprehension: +1 when section === "reading-comprehension"
  • testAttempts: +1 for every session
  • totalTimeSpent: Accumulates time from all sessions
Source: /workspace/source/src/app/api/history/route.ts:116-123

Example Request

curl -X POST 'https://api.lsattraining.com/api/history?uuid=user123' \
  -H 'Content-Type: application/json' \
  -d '{
    "sessionId": "session_abc123",
    "timestamp": "2024-03-03T14:30:00.000Z",
    "section": "logical-reasoning",
    "questionIds": ["q1", "q2", "q3", "q4", "q5"],
    "responses": {
      "q1": "A",
      "q2": "C",
      "q3": "B",
      "q4": "D",
      "q5": "A"
    },
    "score": 4,
    "totalQuestions": 5,
    "timeTaken": 600,
    "bookmarkedQuestionIds": ["q2", "q5"]
  }'

Example Response

{
  "practiceHistory": [
    {
      "sessionId": "session_abc123",
      "timestamp": "2024-03-03T14:30:00.000Z",
      "section": "logical-reasoning",
      "questionIds": ["q1", "q2", "q3", "q4", "q5"],
      "responses": {
        "q1": "A",
        "q2": "C",
        "q3": "B",
        "q4": "D",
        "q5": "A"
      },
      "score": 4,
      "totalQuestions": 5,
      "timeTaken": 600
    },
    {
      "sessionId": "session_xyz789",
      "timestamp": "2024-03-02T10:00:00.000Z",
      "section": "analytical-reasoning",
      "score": 3,
      "totalQuestions": 5,
      "timeTaken": 720
    }
  ],
  "bookmarkedQuestions": ["q2", "q5", "q15", "q22"],
  "progress": {
    "analyticalReasoning": 2,
    "logicalReasoning": 5,
    "readingComprehension": 3,
    "testAttempts": 10,
    "totalTimeSpent": 7200
  },
  "PracticeQuestions": 50,
  "StudyStreak": 7,
  "lastStudyDate": "2024-03-03",
  "updatedAt": "2024-03-03T14:30:15.000Z"
}

Bookmark Management

Bookmarks are managed with deduplication:
const updatedBookmarkedQuestions = [
  ...new Set([...(userData.bookmarkedQuestions || []), ...bookmarkedQuestionIds])
];
Source: /workspace/source/src/app/api/history/route.ts:109-111 This ensures:
  • Existing bookmarks are preserved
  • New bookmarks are added
  • No duplicate question IDs exist in the array

Error Responses

error
string
Error message describing what went wrong

400 Bad Request

{
  "error": "UUID is required"
}
{
  "error": "Invalid JSON format"
}
{
  "error": "Missing required fields"
}

404 Not Found

{
  "error": "User not found"
}

500 Internal Server Error

{
  "error": "Failed to update Firestore document"
}
{
  "error": "Failed to update user data"
}

Data Validation

The endpoint validates all required fields before processing:
if (
  !sessionId ||
  !timestamp ||
  !section ||
  !questionIds ||
  !responses ||
  score === undefined || // Allows score = 0
  !totalQuestions ||
  timeTaken === undefined // Allows timeTaken = 0
) {
  return error;
}
Source: /workspace/source/src/app/api/history/route.ts:52-74

Implementation Details

  • Database: Firebase Firestore with merge strategy
  • UUID Processing: Trims whitespace from UUID parameter
  • Atomic Updates: All user data updates are atomic via Firestore merge
  • Preserves Existing Data: Uses spread operator to maintain other user fields
Source: /workspace/source/src/app/api/history/route.ts

Build docs developers (and LLMs) love