Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
209 commits
Select commit Hold shift + click to select a range
bc7b7b3
added interfaces
filzasaleem Feb 27, 2026
61c273b
Merge pull request #40 from salt-community/feat/interfaces
filzasaleem Feb 27, 2026
55a12e0
Merge branch 'main' of github.com:salt-community/Note2QuizAI into cho…
shakana0 Feb 27, 2026
b95ddd3
test: add unit tests for OpenAIService.GenerateQuizAsync method
johanjaners Mar 1, 2026
14d0735
feat: add IChatClient interface with GetCompletionAsync method
johanjaners Mar 1, 2026
52e5f0d
feat: update IOpenAIService to include GenerateQuizAsync method
johanjaners Mar 1, 2026
faf4bd7
feat: add GeneratedQuestion record to represent quiz questions
johanjaners Mar 1, 2026
46c45d4
feat: implement GenerateQuizAsync method with validation and JSON res…
johanjaners Mar 1, 2026
6736588
Merge pull request #45 from salt-community/chore/sync-dev
shakana0 Mar 2, 2026
190281f
feat: implement db context
shakana0 Mar 2, 2026
67a6ee4
feat: add seed data
shakana0 Mar 2, 2026
4f49720
feat: add seed data on start up
shakana0 Mar 2, 2026
1a5c91d
Merge branch 'dev' into feat/dbcontext
shakana0 Mar 2, 2026
cf67297
Merge pull request #46 from salt-community/feat/dbcontext
shakana0 Mar 2, 2026
3641c22
Merge branch 'dev' of https://github.com/salt-community/Note2QuizAI i…
johanjaners Mar 2, 2026
e9d1179
feat: add Moq package reference for unit testing
johanjaners Mar 2, 2026
479c1d1
fix: add four options
shakana0 Mar 2, 2026
8c90c2f
feat: implement OpenAIService for quiz generation
johanjaners Mar 2, 2026
f5a1bc5
feat: add OpenAIPrompts class for generating quiz questions
johanjaners Mar 2, 2026
d3dd1ce
feat: add QuizGenQuestion model for quiz generation
johanjaners Mar 2, 2026
ef9b735
feat: add QuizGenResponse model for handling quiz generation responses
johanjaners Mar 2, 2026
08ad1f8
refactor: remove QuizGenResponse and QuizGenQuestion classes from Ope…
johanjaners Mar 2, 2026
07938f6
feat: implement OpenAIResponseParser for deserializing AI responses
johanjaners Mar 2, 2026
52b89dd
vision service added
filzasaleem Mar 2, 2026
23a1483
feat: implement OpenAIValidator for validating AI responses
johanjaners Mar 2, 2026
4704719
feat: refactor text truncation logic into TextTruncator class
johanjaners Mar 2, 2026
a304ca9
feat: add missing OpenAI namespace import in OpenAIServiceTests
johanjaners Mar 2, 2026
a4bb991
Merge pull request #49 from salt-community/fix/seeddata
shakana0 Mar 2, 2026
41a59ae
fix: interface using with correct enitity name
shakana0 Mar 2, 2026
ea60397
Merge pull request #51 from salt-community/fix/interface
shakana0 Mar 2, 2026
729f46d
Merge branch 'dev' of https://github.com/salt-community/Note2QuizAI i…
johanjaners Mar 2, 2026
e4aefc3
Merge pull request #48 from salt-community/feature/open-ai-service
johanjaners Mar 2, 2026
fb103a5
fix: fixed the class name
filzasaleem Mar 2, 2026
c12ea6f
fixed the errors
filzasaleem Mar 2, 2026
6b8f553
Merge pull request #50 from salt-community/feat/vision-services
shakana0 Mar 2, 2026
36fb44c
fix: update QuestionDto to use List<OptionDto> for Options
johanjaners Mar 2, 2026
38c5506
feat: implement QuizRepository with CreateQuizSessionAsync method
johanjaners Mar 2, 2026
9b70396
feat: add CreateQuizAsync method for generated questions
johanjaners Mar 2, 2026
d9f2593
feat: update CreateQuizAsync method to accept userId parameter
johanjaners Mar 2, 2026
f9536a0
feat: update CreateQuizAsync method to include file and difficulty pa…
johanjaners Mar 2, 2026
d13a603
feat: update SubmitQuizRequest to use List<AnswerDto> for answers
johanjaners Mar 2, 2026
625ddf3
feat: update CreateQuizSessionAsync method to return void
johanjaners Mar 2, 2026
c04f538
feat: update CreateQuizSessionAsync method to return void
johanjaners Mar 2, 2026
a94233c
feat: register OpenAIService in the service container
johanjaners Mar 2, 2026
8c10eaa
feat: add unit tests for CreateQuizAsync method in QuizService
johanjaners Mar 2, 2026
3a087d7
feat: update ExtractTextFromImageAsync method to include Cancellation…
johanjaners Mar 2, 2026
89ed4ab
feat: update CreateQuizAsync method to include CancellationToken in E…
johanjaners Mar 2, 2026
90f868a
feat: update CreateQuizRequest to use Stream instead of string for Im…
johanjaners Mar 3, 2026
893c931
feat: update CreateQuizAsync method to accept CreateQuizRequest inste…
johanjaners Mar 3, 2026
9250c5c
feat: update CreateQuizAsync method to accept CreateQuizRequest and u…
johanjaners Mar 3, 2026
3678229
feat: update QuizServiceTests to use CreateQuizRequest instead of IFo…
johanjaners Mar 3, 2026
4050c21
added tanstack query to the front end for uploading the image
filzasaleem Mar 3, 2026
5a8c473
feat: implement IQuizService interface in QuizService class
johanjaners Mar 3, 2026
4e42187
feat: remove GetUserQuizzesAsync method from IQuizService interface
johanjaners Mar 3, 2026
212632d
feat: reorder service registrations in Program.cs for clarity
johanjaners Mar 3, 2026
b48c3e8
added config file for api end points
filzasaleem Mar 3, 2026
1b3707c
chore: stop tracking .env file
filzasaleem Mar 3, 2026
a457c36
Merge pull request #53 from salt-community/feat/quiz-image-upload
filzasaleem Mar 3, 2026
8b1cdab
Merge pull request #52 from salt-community/feature/quiz-service
johanjaners Mar 3, 2026
3591678
added header and auth token in the post request
filzasaleem Mar 3, 2026
42bb8d8
feat: add Clerk configuration to appsettings.json
johanjaners Mar 3, 2026
b2d562c
feat: implement JWT authentication and authorization in Program.cs
johanjaners Mar 3, 2026
f8a3dfe
chore: add package for openAI
shakana0 Mar 3, 2026
a32f165
feat: update IQuizRepository to include CancellationToken in CreateQu…
johanjaners Mar 3, 2026
21c1dce
feat: update CreateQuizAsync method to include CancellationToken in C…
johanjaners Mar 3, 2026
2e37154
feat: implement QuizController with Create method for quiz generation
johanjaners Mar 3, 2026
cd0be81
feat: implement IQuizRepository interface in QuizRepository class
johanjaners Mar 3, 2026
1ffe13d
feat: a centralized configuration model to easily toggle JSON mode an…
shakana0 Mar 3, 2026
51da134
feat: update API endpoint for quiz generation to use create route
johanjaners Mar 3, 2026
a37fcf0
feat: add ChatSettings property
shakana0 Mar 3, 2026
eea5e0a
feat: implement GetCompletionAsync
shakana0 Mar 3, 2026
ca6cf79
refactor: uppdate to salvage partially correct results by filtering i…
shakana0 Mar 3, 2026
c8f8a08
refactor: optimize OpenAI service for cost and stability
shakana0 Mar 3, 2026
5d21ae6
refactor: reduced MaxSourceChars to 4000 to slash input costs and upd…
shakana0 Mar 3, 2026
150d174
feat: register AzureChatClient
shakana0 Mar 3, 2026
9d2fc5e
chore: add placeholder variables
shakana0 Mar 3, 2026
32957d6
chore: remove comment
shakana0 Mar 3, 2026
b81f5bb
feat: add userAnswer entity
shakana0 Mar 3, 2026
f2ba1f7
feat add UserAnswers property
shakana0 Mar 3, 2026
e0e4232
feat: add UserAnswers DbSet to DbContext
shakana0 Mar 3, 2026
76014d6
refactor: specify 4 opt each
shakana0 Mar 3, 2026
3ff6ab1
fix: update tests to check if it's filtered correctly instead of thro…
shakana0 Mar 3, 2026
415b128
Merge pull request #55 from salt-community/fix/openai
shakana0 Mar 4, 2026
97fa9b6
Merge branch 'dev' of https://github.com/salt-community/Note2QuizAI i…
johanjaners Mar 4, 2026
b3599e5
feat: add authorization service to the application
johanjaners Mar 4, 2026
f602705
refactor: Implement content-length validation to prevent expensive Op…
shakana0 Mar 4, 2026
6f9b77c
refactor: resolve the IDE0001 warning and null-warnings
shakana0 Mar 4, 2026
5766f31
fix: correct route attribute syntax in QuizController
johanjaners Mar 4, 2026
6273f32
feat: add missing AddControllers service registration in Program.cs
johanjaners Mar 4, 2026
d614bad
refactor: remove unused QuizRepository dependency from QuizService
johanjaners Mar 4, 2026
689d834
refactor: comment out unused repository import and seed data initiali…
johanjaners Mar 4, 2026
f7ccdb4
refactor: comment out unused interface and repository code
johanjaners Mar 4, 2026
ae0194b
refactor: Implement content-length validation to prevent expensive Op…
shakana0 Mar 4, 2026
85ed72c
refactor: update tests to reflect changes in quizService
shakana0 Mar 4, 2026
e7a9db5
docs: add missing endpoint documentation for POST /api/quiz/submit
johanjaners Mar 4, 2026
39fd757
Merge pull request #54 from salt-community/feat/header-token
filzasaleem Mar 4, 2026
bbf0793
Merge pull request #56 from salt-community/feat/add-useranswer-entity
shakana0 Mar 4, 2026
183fdb1
Merge pull request #58 from salt-community/fix/aivision
shakana0 Mar 4, 2026
7b39623
Merge pull request #59 from salt-community/refactor/quiz-service
shakana0 Mar 4, 2026
a4e800a
fix: update CreateQuizRequest to use IFormFile for image handling
johanjaners Mar 4, 2026
de3ad4f
refactor: simplify CreateQuizRequest instantiation by using IFormFile…
johanjaners Mar 4, 2026
3b80aa8
fix: update CreateQuizAsync to use OpenReadStream for image processing
johanjaners Mar 4, 2026
7950eeb
Merge branch 'dev' of https://github.com/salt-community/Note2QuizAI i…
johanjaners Mar 4, 2026
bdf28c5
fix: resolve image stream handling in CreateQuizAsync method
johanjaners Mar 4, 2026
fb66c99
feat: register db context and and try catch when seeding data at startup
shakana0 Mar 4, 2026
0fa1c05
Merge pull request #60 from salt-community/feat/register-dbcontext
shakana0 Mar 4, 2026
a5ceb12
fix: restore QuizRepository usage in QuizService constructor and sess…
johanjaners Mar 4, 2026
5361d9b
fix: uncomment IQuizRepository interface and its method definition
johanjaners Mar 4, 2026
6b88a87
fix: uncomment IQuizRepository registration and seed data initializat…
johanjaners Mar 4, 2026
71b5037
Merge branch 'dev' of https://github.com/salt-community/Note2QuizAI i…
johanjaners Mar 4, 2026
b3469c6
refactor: remove unused GET method from QuizController
johanjaners Mar 4, 2026
386b49f
fix: add file size validation to CreateQuiz method in QuizController
johanjaners Mar 4, 2026
c7c662a
fix: increase file size limit to 20MB in CreateQuiz method
johanjaners Mar 4, 2026
c70a6f1
Merge pull request #61 from salt-community/feature/controller-create-…
johanjaners Mar 4, 2026
0760e7e
created quiz history in quiz servics and repo
filzasaleem Mar 4, 2026
5eb453b
feat: add DefaultConnection
shakana0 Mar 4, 2026
5abf667
chore: add UserSecretsId
shakana0 Mar 4, 2026
7dc6412
Merge branch 'dev' into feat/connectionstr
shakana0 Mar 4, 2026
0e435d6
merged dev branch to this branch and resolved conflicts
filzasaleem Mar 4, 2026
46facf9
fix: update CreateQuizRequest to use IFormFile for file handling in Q…
johanjaners Mar 4, 2026
abf74ee
Merge pull request #62 from salt-community/fix/service-test-stream
johanjaners Mar 4, 2026
f87070d
add end point in the controller for the quiz history.
filzasaleem Mar 4, 2026
7d3b2bc
feat: add Prettier configuration for code formatting
johanjaners Mar 4, 2026
5decd73
feat: add UserAnswers property
shakana0 Mar 4, 2026
216972d
feat: add UserAnswer model builder
shakana0 Mar 4, 2026
9bc9c19
chore: add ef core migrations
shakana0 Mar 4, 2026
f1a6706
Merge pull request #65 from salt-community/feat/connectionstr
shakana0 Mar 4, 2026
a790e23
Merge pull request #64 from salt-community/feature/prettier-rc
johanjaners Mar 4, 2026
2180009
Merge branch 'dev' of github.com:salt-community/Note2QuizAI into feat…
filzasaleem Mar 5, 2026
08e3e19
fixed the comment
filzasaleem Mar 5, 2026
5080e6f
fixed the cors and api connection
filzasaleem Mar 5, 2026
078276c
connected the backend and front end for histrory
filzasaleem Mar 5, 2026
688e30b
commented out the difficulty
filzasaleem Mar 5, 2026
a22aebc
Merge pull request #63 from salt-community/feat/quiz-histroy
filzasaleem Mar 5, 2026
27ef884
fix: update BASE_URL and API endpoint for quiz generation
johanjaners Mar 5, 2026
df84128
fix: correct formData key from "image" to "file" in quiz generation API
johanjaners Mar 5, 2026
c7c5e8c
Merge branch 'dev' of https://github.com/salt-community/Note2QuizAI i…
johanjaners Mar 5, 2026
8cbbef6
fix: update user ID claim type to use ClaimTypes.NameIdentifier in Cr…
johanjaners Mar 5, 2026
314f2fc
fix: refactor uploadImageAndGenerateQuiz function and restore QuizHis…
johanjaners Mar 5, 2026
774d0b6
fix: update base url
johanjaners Mar 5, 2026
e8c16d1
fix: update branding in header to include 'AI'
johanjaners Mar 6, 2026
31839ab
fix: update title in header to include 'AI'
johanjaners Mar 6, 2026
fb85568
Merge pull request #67 from salt-community/fix/debug-api-create-quiz
johanjaners Mar 6, 2026
072bf2a
Merge pull request #68 from salt-community/fix/header-branding
johanjaners Mar 6, 2026
48ca3e7
feat: add Difficulty and Title property
shakana0 Mar 6, 2026
24cedc5
feat: update seed
shakana0 Mar 6, 2026
56c51b3
feat: update migration
shakana0 Mar 6, 2026
61855ed
Merge branch 'dev' into feat/update-quizsession
shakana0 Mar 6, 2026
70ba234
Merge branch 'dev' into feat/update-quizsession
shakana0 Mar 6, 2026
d7cbc10
Merge pull request #69 from salt-community/feat/update-quizsession
shakana0 Mar 6, 2026
180b15e
implementing the single quiz end point
filzasaleem Mar 6, 2026
6ecbce4
Merge branch 'dev' of github.com:salt-community/Note2QuizAI into feat…
filzasaleem Mar 6, 2026
89b4b76
fixed the quizPage in front end
filzasaleem Mar 6, 2026
bc76cfd
feat: add GetQuizSessionForSubmitAsync method to IQuizRepository inte…
johanjaners Mar 6, 2026
7969f85
feat: implement GetQuizSessionForSubmitAsync method in QuizRepository
johanjaners Mar 6, 2026
8762fd6
Merge branch 'dev' of https://github.com/salt-community/Note2QuizAI i…
johanjaners Mar 6, 2026
9b6cbaf
feat: implement SaveUserAnswerAsync method in QuizRepository
johanjaners Mar 6, 2026
d66b932
feat: rename SaveUserAnswerAsync to ReplaceUserAnswersAsync and updat…
johanjaners Mar 6, 2026
bd92f53
feat: implement SubmitQuizAsync method for handling quiz submissions
johanjaners Mar 6, 2026
03b1c52
feat: add SubmitQuizAsync method to IQuizService interface for quiz s…
johanjaners Mar 6, 2026
13b53da
feat: implement Submit method in QuizController for quiz submission h…
johanjaners Mar 6, 2026
afb4955
Merge pull request #70 from salt-community/feat/quizSesson
filzasaleem Mar 6, 2026
10816ba
Merge branch 'dev' of https://github.com/salt-community/Note2QuizAI i…
johanjaners Mar 6, 2026
bf92778
fixed the dash board
filzasaleem Mar 6, 2026
628e669
feat: add Title prop
shakana0 Mar 6, 2026
5fa24c8
feat: add validation check for model and title
shakana0 Mar 6, 2026
5baf9bc
refactor: update prompt to include title
shakana0 Mar 6, 2026
581bbf9
Merge pull request #71 from salt-community/feat/fix-dashboard
shakana0 Mar 6, 2026
3e71d1f
feat: refactor quizApi.ts to define interfaces for quiz submission an…
johanjaners Mar 6, 2026
13bc68d
feat: add uploadImageAndGenerateQuiz function for quiz generation
johanjaners Mar 6, 2026
248f74c
Merge branch 'dev' into feat/title
shakana0 Mar 6, 2026
5c089a7
feat: enhance quiz session retrieval and implement quiz submission fu…
johanjaners Mar 6, 2026
efbcf72
feat: make quiz difficulty optional and improve error handling in qui…
johanjaners Mar 6, 2026
1b105bc
feat: add submit endpoint to API configuration for quiz submission
johanjaners Mar 6, 2026
a7c2286
feat: import submitQuiz function for quiz submission handling in Quiz…
johanjaners Mar 6, 2026
12186ab
feat: refactor state management for quiz submission handling in QuizPage
johanjaners Mar 6, 2026
2878627
feat: improve quiz submission handling and error management in QuizPage
johanjaners Mar 6, 2026
e54b6e5
feat: import useMutation for quiz submission handling in QuizPage
johanjaners Mar 6, 2026
b7c4387
feat: enhance quiz result display and submission handling in QuizPage
johanjaners Mar 6, 2026
a9f340b
fix: rename GetQuizzAsync to GetQuizAsync
johanjaners Mar 6, 2026
0385649
fix: remove IsCorrect from OptionDto and clean quiz dto mappings
johanjaners Mar 6, 2026
5d8d651
Merge branch 'dev' of https://github.com/salt-community/Note2QuizAI i…
johanjaners Mar 6, 2026
02981ae
refactor: extract validation and evaluation from SubmitQuizAsync
johanjaners Mar 6, 2026
4a93fdc
fix: remove isCorrect property from OptionDto interface
johanjaners Mar 6, 2026
3054958
fix: calculate quiz history and average score as percentage
johanjaners Mar 6, 2026
6452d5c
fix: ensure Dashboard link is hidden on small screens
johanjaners Mar 6, 2026
dd484d6
fix: adjust layout for quiz navigation buttons to support wrapping
johanjaners Mar 6, 2026
8ee5cb5
feat: add Difficulty and Title to dto
shakana0 Mar 9, 2026
124c6c3
refactor: update return type to QuizGenResponse
shakana0 Mar 9, 2026
eba3d8b
refactor: update session mapping
shakana0 Mar 9, 2026
2649b04
refactor: update return type to QuizGenResponse
shakana0 Mar 9, 2026
ae82221
Merge pull request #74 from salt-community/feat/title
shakana0 Mar 9, 2026
cdf686d
refactor: move quiz submission validation logic to a new QuizSubmissi…
johanjaners Mar 9, 2026
13333ef
Merge pull request #72 from salt-community/feature/submit-quiz
johanjaners Mar 9, 2026
1394433
chore: remove unused UnitTest1.cs file
johanjaners Mar 9, 2026
b818baa
chore: remove console.log statements from Index component
johanjaners Mar 9, 2026
971d647
refactor: update QuizServiceTests to use QuizGenResponse for AI quest…
johanjaners Mar 9, 2026
b7967cf
refactor: update assertions in OpenAIServiceTests to match new result…
johanjaners Mar 9, 2026
4e4f5f7
chore: remove console.log statement from ProtectedRoute component
johanjaners Mar 9, 2026
35c091a
Merge pull request #75 from salt-community/fix/test-fix-remove-consol…
johanjaners Mar 9, 2026
c3bd58e
added few tests
filzasaleem Mar 9, 2026
ff80c5c
added toast
filzasaleem Mar 9, 2026
ab7a8d3
fixed the title at the front end
filzasaleem Mar 9, 2026
57dfce9
resolved conflicts
filzasaleem Mar 9, 2026
1d6659c
Merge pull request #76 from salt-community/feat/teats
filzasaleem Mar 9, 2026
9d70670
Merge pull request #79 from salt-community/fix/title-FE
filzasaleem Mar 9, 2026
81dcfec
Merge pull request #78 from salt-community/feat/toastify
filzasaleem Mar 9, 2026
80a9027
fixed the loader on the quizPage
filzasaleem Mar 10, 2026
f2ba025
Merge pull request #81 from salt-community/fix/loader
filzasaleem Mar 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"useTabs": true,
"tabWidth": 4,
"semi": true,
"singleQuote": false,
"printWidth": 140,
"trailingComma": "none",
"quoteProps": "consistent",
"arrowParens": "avoid",
"bracketSpacing": true,

"overrides": [
{
"files": ["*.yml", "*.yaml"],
"options": {
"useTabs": false,
"tabWidth": 2
}
},
{
"files": ["Dockerfile", "Dockerfile.*"],
"options": {
"useTabs": false,
"tabWidth": 2
}
}
]
}
99 changes: 97 additions & 2 deletions note2quiz-backend/Note2Quiz.API/Controllers/QuizController.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,99 @@
// POST /api/quiz/generate
// GET /api/quiz/history
// POST /api/quiz/submit
using System.Security.Claims;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Note2Quiz.API.DTOs;
using Note2Quiz.API.Interfaces;

namespace Note2Quiz.API.Controllers;

[ApiController]
[Route("api/[controller]")]
[Authorize]
public class QuizController : ControllerBase
{
private readonly IQuizService _quizService;

public QuizController(IQuizService quizService)
{
_quizService = quizService;
}

[HttpPost]
[RequestSizeLimit(20 * 1024 * 1024)]
public async Task<ActionResult<QuizResponse>> Create(
[FromForm] IFormFile file,
[FromForm] Difficulty difficulty,
CancellationToken ct
)
{
if (file == null || file.Length == 0)
return BadRequest("File is required.");

if (file.Length > 20 * 1024 * 1024)
return BadRequest("File too large. Max size is 20MB.");

if (file.ContentType is not ("image/jpeg" or "image/png"))
return BadRequest("Only jpeg or png allowed.");

var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
if (userId == null)
return Unauthorized();

var request = new CreateQuizRequest(file, difficulty);

var result = await _quizService.CreateQuizAsync(userId, request, ct);

return Ok(result);
}

[HttpGet("history")]
public async Task<ActionResult<List<QuizHistoryItemDto>>> GetQuizHistory(CancellationToken ct)
{
var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;

if (userId == null)
return Unauthorized();

var result = await _quizService.GetQuizzesAsync(userId, ct);

return Ok(result);
}


[HttpGet("{quizSessionId}")]
public async Task<ActionResult<QuizResponse>> GetQuiz(int quizSessionId, CancellationToken ct)
{
var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;

if (userId == null)
return Unauthorized();

var result = await _quizService.GetQuizAsync(userId, quizSessionId, ct);

return Ok(result);
}

[HttpPost("submit")]
public async Task<ActionResult<SubmitQuizResponse>> Submit(
[FromBody] SubmitQuizRequest request,
CancellationToken ct)
{
var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
if (userId == null)
return Unauthorized();

if (request == null)
return BadRequest("Request is required.");

if (request.QuizSessionId <= 0)
return BadRequest("QuizSessionId is invalid.");

if (request.Answers == null || request.Answers.Count == 0)
return BadRequest("Answers are required.");

var result = await _quizService.SubmitQuizAsync(userId, request, ct);

return Ok(result);
}
}
33 changes: 13 additions & 20 deletions note2quiz-backend/Note2Quiz.API/DTOs/QuizDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,20 @@ public enum Difficulty
{
Easy,
Medium,
Hard
Hard,
}

public record CreateQuizRequest(
string ImageBase64,
Difficulty Difficulty
);
public record CreateQuizRequest(IFormFile Image, Difficulty Difficulty);

public record QuizResponse(
int QuizSessionId,
List<QuestionDto> Questions
);
public record QuizResponse(int QuizSessionId, List<QuestionDto> Questions);

public record QuestionDto(
int Id,
string Text,
List<string> Options
);
public record QuestionDto(int Id, string Text, List<OptionDto> Options);

public record SubmitQuizRequest(
int QuizSessionId,
List<int> SelectedOptionsIds
);
public record OptionDto(int OptionId, string OptionText);

public record SubmitQuizRequest(int QuizSessionId, List<AnswerDto> Answers);

public record AnswerDto(int QuestionId, int SelectedOptionId);

public record SubmitQuizResponse(
int QuizSessionId,
Expand All @@ -46,5 +37,7 @@ public record QuizHistoryItemDto(
int QuizSessionId,
DateTime CreatedAt,
int QuestionCount,
int? Score
);
int? Score,
Difficulty Difficulty,
string Title
);
70 changes: 70 additions & 0 deletions note2quiz-backend/Note2Quiz.API/Data/Note2QuizDbContext.cs
Original file line number Diff line number Diff line change
@@ -1 +1,71 @@
using Microsoft.EntityFrameworkCore;
using Note2Quiz.API.Models;

namespace Note2Quiz.API.Data;

public class Note2QuizDbContext : DbContext
{
public Note2QuizDbContext(DbContextOptions<Note2QuizDbContext> options)
: base(options)
{
}

public DbSet<QuizSession> QuizSessions { get; set; }
public DbSet<Question> Questions { get; set; }
public DbSet<Option> Options { get; set; }
public DbSet<UserAnswer> UserAnswers { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);

// QuizSession → Questions
modelBuilder.Entity<QuizSession>()
.HasMany(qs => qs.Questions)
.WithOne(q => q.QuizSession)
.HasForeignKey(q => q.QuizSessionId)
.OnDelete(DeleteBehavior.Cascade);

// Question → Options
modelBuilder.Entity<Question>()
.HasMany(q => q.Options)
.WithOne(o => o.Question)
.HasForeignKey(o => o.QuestionId)
.OnDelete(DeleteBehavior.Cascade);

// UserAnswer → Question
modelBuilder.Entity<UserAnswer>()
.HasOne(ua => ua.Question)
.WithMany(q => q.UserAnswers)
.HasForeignKey(ua => ua.QuestionId)
.OnDelete(DeleteBehavior.Restrict);

// UserAnswer → Option
modelBuilder.Entity<UserAnswer>()
.HasOne(ua => ua.Option)
.WithMany()
.HasForeignKey(ua => ua.OptionId)
.OnDelete(DeleteBehavior.Restrict);

// UserAnswer → QuizSession
modelBuilder.Entity<UserAnswer>()
.HasOne(ua => ua.QuizSession)
.WithMany(qs => qs.UserAnswers)
.HasForeignKey(ua => ua.QuizSessionId)
.OnDelete(DeleteBehavior.Restrict);

// Required fields
modelBuilder.Entity<QuizSession>()
.Property(x => x.UserId)
.IsRequired();

modelBuilder.Entity<Question>()
.Property(x => x.Text)
.IsRequired();

modelBuilder.Entity<Option>()
.Property(x => x.Text)
.IsRequired();

}
}
54 changes: 53 additions & 1 deletion note2quiz-backend/Note2Quiz.API/Data/Note2QuizSeed.cs
Original file line number Diff line number Diff line change
@@ -1 +1,53 @@
namespace Note2Quiz.API.Data;
using Note2Quiz.API.Models;
using Microsoft.EntityFrameworkCore;
using Note2Quiz.API.DTOs;

namespace Note2Quiz.API.Data;

public static class SeedData
{
public static async Task InitializeAsync(Note2QuizDbContext db)
{
if (await db.QuizSessions.AnyAsync())
return;

var session = new QuizSession
{
UserId = "seed-user",
CreatedAt = DateTime.UtcNow,
Difficulty = Difficulty.Easy,
Title = "General Knowledge Quiz",

Questions = new List<Question>
{
new Question
{
Text = "What is the capital of Sweden?",
CreatedAt = DateTime.UtcNow,
Options = new List<Option>
{
new Option { Text = "Stockholm", IsCorrect = true },
new Option { Text = "Gothenburg", IsCorrect = false },
new Option { Text = "Malmö", IsCorrect = false },
new Option { Text = "Västerås", IsCorrect = false }
}
},
new Question
{
Text = "Which planet is known as the Red Planet?",
CreatedAt = DateTime.UtcNow,
Options = new List<Option>
{
new Option { Text = "Mars", IsCorrect = true },
new Option { Text = "Venus", IsCorrect = false },
new Option { Text = "Jupiter", IsCorrect = false },
new Option { Text = "Tellus", IsCorrect = false }
}
}
}
};

db.QuizSessions.Add(session);
await db.SaveChangesAsync();
}
}
11 changes: 11 additions & 0 deletions note2quiz-backend/Note2Quiz.API/Interfaces/IChatClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Note2Quiz.API.Services.OpenAI.Models;

public interface IChatClient
{
Task<string> GetCompletionAsync(
string systemPrompt,
string userPrompt,
ChatSettings settings,
CancellationToken ct
);
}
14 changes: 13 additions & 1 deletion note2quiz-backend/Note2Quiz.API/Interfaces/IOpenAIService.cs
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
namespace Note2Quiz.API.Interfaces;
using Note2Quiz.API.DTOs;
using Note2Quiz.API.Services.OpenAI;

namespace Note2Quiz.API.Services;

public interface IOpenAIService
{
Task<QuizGenResponse> GenerateQuizAsync(
string sourceText,
Difficulty difficulty,
CancellationToken ct
);
}
13 changes: 12 additions & 1 deletion note2quiz-backend/Note2Quiz.API/Interfaces/IQuizRepository.cs
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
namespace Note2Quiz.API.Interfaces;
using Note2Quiz.API.Models;

namespace Note2Quiz.API.Interfaces;

public interface IQuizRepository
{
Task<QuizSession> CreateQuizSessionAsync(QuizSession session, CancellationToken ct);
Task<QuizSession?> GetQuizSessionById(string userId, int quizSessionId, CancellationToken ct);
Task<List<QuizSession>> GetQuizSessionsByUserIdAsync(string userId, CancellationToken ct);
Task<QuizSession?> GetQuizSessionForSubmitAsync(int quizSessionId, CancellationToken ct);
Task ReplaceUserAnswersAsync(int quizSessionId, List<UserAnswer> userAnswers, CancellationToken ct);
}
23 changes: 22 additions & 1 deletion note2quiz-backend/Note2Quiz.API/Interfaces/IQuizService.cs
Original file line number Diff line number Diff line change
@@ -1 +1,22 @@
namespace Note2Quiz.API.Interfaces;
using Note2Quiz.API.DTOs;
using Note2Quiz.API.Models;

namespace Note2Quiz.API.Interfaces;

public interface IQuizService
{
Task<QuizResponse> CreateQuizAsync(
string userId,
CreateQuizRequest request,
CancellationToken ct
);

Task<List<QuizHistoryItemDto>> GetQuizzesAsync(string userId, CancellationToken ct);

Task<SubmitQuizResponse> SubmitQuizAsync(
string userId,
SubmitQuizRequest request,
CancellationToken ct
);
Task<QuizResponse> GetQuizAsync(string userId, int quizSessionId, CancellationToken ct);
}
7 changes: 6 additions & 1 deletion note2quiz-backend/Note2Quiz.API/Interfaces/IVisionService.cs
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
namespace Note2Quiz.API.Interfaces;
namespace Note2Quiz.API.Interfaces;

public interface IVisionService
{
Task<string> ExtractTextFromImageAsync(Stream imageStream, CancellationToken ct);
}
Loading