DEV Community

himanshu
himanshu

Posted on

Quizy - Technical Design & API Contract

โœ… Functional Requirements (FRD) โ€“ Quizy


๐Ÿ” User Authentication & Accounts

  • User can register with name, email, and password.
  • User can login and receive a JWT token + refresh token.
  • User can logout (token invalidation if stored server-side).
  • User can reset password via:

    • Forgot Password (email trigger)
    • Reset Password (token-based form)
  • User authentication must be secure and token-based (JWT).

  • Authenticated user session should be persisted client-side.


๐Ÿ“š Question Bank Management

  • User can create multiple question banks.
  • Each question bank:

    • Has a title and description.
    • Belongs to one user.
    • Contains multiple question sets (from PDF uploads).

๐Ÿ“„ Question Set Upload & Processing

  • User can upload a PDF to a specific question bank.
  • Each PDF is stored as a question set.
  • After upload:

    • The system starts a background job to parse questions from the PDF.
    • Questions are stored with:
    • Text
    • 4 options (a, b, c, d)
    • Correct answer
    • Explanation
    • Tags
  • User can poll /status endpoint to check processing state: PENDING, PROCESSING, DONE, FAILED.

  • Extracted questions can be fetched and browsed.


๐Ÿงช Test Creation & Series

  • Users can group multiple tests under a Test Series.
  • A test can be created by selecting questions from:

    • One or more question sets
  • Each test has:

    • Title, description
    • List of question IDs
    • Belongs to a test series and a user

๐Ÿ“ Test Taking (Attempt Lifecycle)

  • User can start a test attempt (one active per test).
  • During the test:

    • A scrollable, paginated view shows the questions
    • User can:
    • Select one option (a, b, c, d)
    • Mark question for review
    • Navigate across questions
  • User can submit the test:

    • Score is calculated
    • All question attempts are recorded
  • System returns:

    • Final score
    • Detailed breakdown with:
    • Selected answer
    • Correct answer
    • Explanation

๐Ÿ“ˆ Tracking & Analytics

  • Each test attempt is stored in an Attempt history table.
  • Users can:

    • View past test scores
    • Track progress (score vs. time)
    • See leaderboard (based on avg scores across users)

๐Ÿท๏ธ Tag-based Features

  • Questions can be tagged (string[]).
  • User can filter or select questions by tag during:

    • Test creation
    • Reviewing questions
    • Creating topic-specific tests (future scope)

๐Ÿงฐ Admin/Moderation (Future Scope)

  • System admin may get dashboard to:

    • Manage flagged questions
    • Approve/reject user-uploaded questions (if public bank)
    • Monitor processing failures

๐Ÿ” System Functional Notes

  • All uploaded PDFs are stored via ActiveStorage + AWS S3.
  • PDF parsing job runs asynchronously via Sidekiq.
  • Test submissions are atomic (submitted only once per attempt).
  • Long-poll or polling status for PDF jobs will hit: /api/question-sets/:id/status

Quizy - Quiz Application (API-First Design)

Stack Overview

  • Frontend: React (with Redux or Zustand for state management) [backend might change]
  • Backend: Node.js (Express.js) or ROR
  • Database: PostgreSQL (via Prisma ORM)
  • Authentication: JWT + Refresh Token
  • File Handling: AWS S3
  • PDF Extraction: Python microservice (FastAPI)
  • Communication: REST + Long Polling

Data Models (PostgreSQL via Prisma)

User

id: string (UUID)
email: string
passwordHash: string
name: string
createdAt: Date
updatedAt: Date
Enter fullscreen mode Exit fullscreen mode

QuestionBank

id: string
userId: string (FK -> User)
title: string
description: string
createdAt: Date
Enter fullscreen mode Exit fullscreen mode

QuestionSet

id: string
questionBankId: string (FK -> QuestionBank)
title: string
sourcePdfUrl: string
status: enum('PENDING', 'PROCESSING', 'DONE', 'FAILED')
createdAt: Date
Enter fullscreen mode Exit fullscreen mode

Question

id: string
questionSetId: string (FK -> QuestionSet)
text: string
options: { a: string, b: string, c: string, d: string }
correctAnswer: 'a' | 'b' | 'c' | 'd'
explanation: string
tags: string[]
Enter fullscreen mode Exit fullscreen mode

TestSeries

id: string
userId: string
title: string
Enter fullscreen mode Exit fullscreen mode

Test

id: string
testSeriesId: string
userId: string
title: string
description: string
questionIds: string[]
createdAt: Date
Enter fullscreen mode Exit fullscreen mode

Attempt

id: string
testId: string
userId: string
questionResponses: {
  questionId: string,
  selectedOption: 'a' | 'b' | 'c' | 'd' | null,
  markedForReview: boolean
}[]
score: number
startedAt: Date
submittedAt: Date
Enter fullscreen mode Exit fullscreen mode

API Contracts

Authentication

POST /api/auth/register

Registers a user.

{ "email": "...", "password": "...", "name": "..." }
Enter fullscreen mode Exit fullscreen mode

Response:

{ "token": "...", "refreshToken": "..." }
Enter fullscreen mode Exit fullscreen mode

POST /api/auth/login

Logs in a user.

{ "email": "...", "password": "..." }
Enter fullscreen mode Exit fullscreen mode

Response: Same as above

POST /api/auth/refresh

Refreshes the JWT.

{ "refreshToken": "..." }
Enter fullscreen mode Exit fullscreen mode

POST /api/auth/forgot

Starts password reset process.

{ "email": "..." }
Enter fullscreen mode Exit fullscreen mode

POST /api/auth/reset

Resets password.

{ "token": "...", "newPassword": "..." }
Enter fullscreen mode Exit fullscreen mode

Question Bank

POST /api/question-banks

Creates a question bank.

{ "title": "...", "description": "..." }
Enter fullscreen mode Exit fullscreen mode

GET /api/question-banks

Returns all user's question banks.


Question Set & PDF Upload

POST /api/question-banks/:id/question-sets

Upload PDF to a question bank.
Form-Data:

  • title: string
  • pdf: File

Response:

{ "id": "...", "status": "PENDING" }
Enter fullscreen mode Exit fullscreen mode

GET /api/question-sets/:id/status

Get PDF processing status (long-poll).

{ "status": "PROCESSING" | "DONE" | "FAILED" }
Enter fullscreen mode Exit fullscreen mode

GET /api/question-sets/:id/questions

Get parsed questions from a question set.

[{
  "id": "...",
  "text": "...",
  "options": { "a": "...", "b": "...", "c": "...", "d": "..." },
  "correctAnswer": "a",
  "explanation": "...",
  "tags": ["...", "..."]
}]
Enter fullscreen mode Exit fullscreen mode

Test Series & Test Creation

POST /api/test-series

{ "title": "..." }
Enter fullscreen mode Exit fullscreen mode

POST /api/tests

{ "testSeriesId": "...", "title": "...", "description": "...", "questionIds": ["..."] }
Enter fullscreen mode Exit fullscreen mode

GET /api/tests/:id

{
  "id": "...",
  "title": "...",
  "description": "...",
  "questions": [
    {
      "id": "...",
      "text": "...",
      "options": { "a": "...", "b": "...", "c": "...", "d": "..." }
    }, ...
  ]
}
Enter fullscreen mode Exit fullscreen mode

Test Attempt Workflow

POST /api/attempts/start

Starts a test attempt.

{ "testId": "..." }
Enter fullscreen mode Exit fullscreen mode

Response:

{ "attemptId": "...", "startedAt": "..." }
Enter fullscreen mode Exit fullscreen mode

GET /api/attempts/:attemptId/questions?offset=0&limit=10

Paginated scroll view of questions.

POST /api/attempts/:attemptId/response

Submit or update a response for a question.

{
  "questionId": "...",
  "selectedOption": "a",
  "markedForReview": true
}
Enter fullscreen mode Exit fullscreen mode

POST /api/attempts/:attemptId/submit

Submits entire test.
Response:

{
  "score": 18,
  "total": 20,
  "detailedBreakdown": [
    { "questionId": "...", "correct": true, "yourAnswer": "a", "explanation": "..." }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Attempt History & Leaderboard

GET /api/attempts/history

[
  { "testTitle": "...", "score": 18, "total": 20, "submittedAt": "..." },
  ...
]
Enter fullscreen mode Exit fullscreen mode

GET /api/leaderboard

Returns top average scores.

[
  { "user": "User1", "avgScore": 92 },
  { "user": "You", "avgScore": 85 }
]
Enter fullscreen mode Exit fullscreen mode

GET /api/user/progress

Get performance trend.

{
  "history": [
    { "date": "2025-07-10", "score": 12 },
    { "date": "2025-07-12", "score": 18 }
  ]
}
Enter fullscreen mode Exit fullscreen mode

React UI Capabilities

  • Auth context (register/login/logout/forgot/reset)
  • Dashboard for question bank management
  • Drag-drop or file-picker for PDF upload
  • Polling spinner for background extraction
  • Question browser per set
  • Create test from questions picker UI
  • Scrollable view with react-window for test attempt
  • Mark for review toggle
  • Submission confirmation and result view
  • History + leaderboard UI with charts

All user-provided requirements are now covered:
โœ… Question creation
โœ… Tag-based filtering
โœ… PDF upload + background extraction
โœ… Long polling
โœ… Test & TestSeries
โœ… Attempt lifecycle + scroll
โœ… Mark-for-review
โœ… Final score + response tracking
โœ… History + Leaderboard + Progress

Top comments (0)