timed revision
All checks were successful
Mindforge API Build and Deploy / Build Mindforge API Image (push) Successful in 3m58s
Mindforge API Build and Deploy / Deploy Mindforge API (internal) (push) Successful in 37s
Mindforge Web Build and Deploy (internal) / Build Mindforge Web Image (push) Successful in 5m19s
Mindforge Web Build and Deploy (internal) / Deploy Mindforge Web (internal) (push) Successful in 11s

This commit is contained in:
2026-06-01 19:08:48 -03:00
parent b80d28f671
commit f03bcc40e3
14 changed files with 1138 additions and 14 deletions

View File

@@ -1,4 +1,5 @@
using Dapper;
using Mindforge.API.Exceptions;
using Mindforge.API.Models.Flashcards;
using Mindforge.API.Services.Interfaces;
using Npgsql;
@@ -37,11 +38,24 @@ namespace Mindforge.API.Repositories
front TEXT NOT NULL,
back TEXT NOT NULL,
position INTEGER NOT NULL,
correct_count INTEGER NOT NULL DEFAULT 0,
incorrect_count INTEGER NOT NULL DEFAULT 0,
last_reviewed_at TIMESTAMPTZ NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
ALTER TABLE flashcards
ADD COLUMN IF NOT EXISTS correct_count INTEGER NOT NULL DEFAULT 0;
ALTER TABLE flashcards
ADD COLUMN IF NOT EXISTS incorrect_count INTEGER NOT NULL DEFAULT 0;
ALTER TABLE flashcards
ADD COLUMN IF NOT EXISTS last_reviewed_at TIMESTAMPTZ NULL;
CREATE INDEX IF NOT EXISTS ix_flashcard_libraries_subject ON flashcard_libraries(subject);
CREATE INDEX IF NOT EXISTS ix_flashcards_library_id_position ON flashcards(library_id, position);
CREATE INDEX IF NOT EXISTS ix_flashcards_last_reviewed_at ON flashcards(last_reviewed_at);
""";
await using var connection = CreateConnection();
@@ -193,6 +207,9 @@ namespace Mindforge.API.Repositories
front AS Front,
back AS Back,
position AS Position,
correct_count AS CorrectCount,
incorrect_count AS IncorrectCount,
last_reviewed_at AS LastReviewedAt,
created_at AS CreatedAt
FROM flashcards
WHERE library_id = @LibraryId
@@ -240,6 +257,9 @@ namespace Mindforge.API.Repositories
front AS Front,
back AS Back,
position AS Position,
correct_count AS CorrectCount,
incorrect_count AS IncorrectCount,
last_reviewed_at AS LastReviewedAt,
created_at AS CreatedAt
FROM flashcards
WHERE library_id = ANY(@LibraryIds)
@@ -252,6 +272,49 @@ namespace Mindforge.API.Repositories
return cards.ToList();
}
public async Task RecordReviewAnswerAsync(long cardId, bool correct)
{
var sql = correct
? "UPDATE flashcards SET correct_count = correct_count + 1, last_reviewed_at = NOW() WHERE id = @CardId;"
: "UPDATE flashcards SET incorrect_count = incorrect_count + 1, last_reviewed_at = NOW() WHERE id = @CardId;";
await using var connection = CreateConnection();
await connection.OpenAsync();
var affectedRows = await connection.ExecuteAsync(sql, new { CardId = cardId });
if (affectedRows == 0)
{
throw new UserException("Card de revisao nao encontrado para registrar resposta.");
}
}
public async Task<IReadOnlyList<FlashcardCardWithLibrary>> GetAllCardsWithLibraryAsync()
{
const string sql = """
SELECT
f.id AS Id,
f.library_id AS LibraryId,
f.front AS Front,
f.back AS Back,
f.position AS Position,
f.correct_count AS CorrectCount,
f.incorrect_count AS IncorrectCount,
f.last_reviewed_at AS LastReviewedAt,
f.created_at AS CreatedAt,
l.file_path AS FilePath,
l.file_name AS FileName,
l.subject AS Subject
FROM flashcards f
INNER JOIN flashcard_libraries l ON l.id = f.library_id
ORDER BY l.subject, l.file_name, f.position;
""";
await using var connection = CreateConnection();
await connection.OpenAsync();
var cards = await connection.QueryAsync<FlashcardCardWithLibrary>(sql);
return cards.ToList();
}
private NpgsqlConnection CreateConnection()
{
return new NpgsqlConnection(_connectionString);