modifications
All checks were successful
Mindforge API Build and Deploy / Build Mindforge API Image (push) Successful in 2m10s
Mindforge API Build and Deploy / Deploy Mindforge API (internal) (push) Successful in 8s
Mindforge Web Build and Deploy (internal) / Build Mindforge Web Image (push) Successful in 3m38s
Mindforge Web Build and Deploy (internal) / Deploy Mindforge Web (internal) (push) Successful in 8s

This commit is contained in:
2026-06-01 19:29:01 -03:00
parent f03bcc40e3
commit 097ba577cf
6 changed files with 375 additions and 159 deletions

View File

@@ -54,7 +54,7 @@ namespace Mindforge.API.Models.Flashcards
{
public string SubSubject { get; set; } = string.Empty;
public FlashcardRagSummary Summary { get; set; } = new();
public List<FlashcardRagCard> Cards { get; set; } = [];
public List<FlashcardRagLibrary> Libraries { get; set; } = [];
}
public class FlashcardRagSummary
@@ -68,17 +68,16 @@ namespace Mindforge.API.Models.Flashcards
public double AttentionPercentage { get; set; }
}
public class FlashcardRagCard
public class FlashcardRagLibrary
{
public long CardId { get; set; }
public long LibraryId { get; set; }
public string FilePath { get; set; } = string.Empty;
public string FileName { get; set; } = string.Empty;
public string Subject { get; set; } = string.Empty;
public string SubSubject { get; set; } = string.Empty;
public string Front { get; set; } = string.Empty;
public string Back { get; set; } = string.Empty;
public int CorrectCount { get; set; }
public int IncorrectCount { get; set; }
public int CardCount { get; set; }
public int TotalAnswers { get; set; }
public double PerformanceRate { get; set; }
public DateTime? LastReviewedAt { get; set; }

View File

@@ -103,26 +103,31 @@ namespace Mindforge.API.Services
var now = DateTime.UtcNow;
var cards = await _flashcardRepository.GetAllCardsWithLibraryAsync();
var ragCards = cards
.Select(card => BuildRagCard(card, now))
var ragLibraries = cards
.GroupBy(card => card.LibraryId)
.Select(group => BuildRagLibrary(group.ToList(), now))
.ToList();
var subjectGroups = ragCards
.GroupBy(card => card.Subject, StringComparer.OrdinalIgnoreCase)
var subjectGroups = ragLibraries
.GroupBy(library => library.Subject, StringComparer.OrdinalIgnoreCase)
.OrderBy(group => group.Key, StringComparer.OrdinalIgnoreCase)
.Select(subjectGroup =>
{
var subSubjectGroups = subjectGroup
.GroupBy(card => card.SubSubject, StringComparer.OrdinalIgnoreCase)
.GroupBy(library => library.SubSubject, StringComparer.OrdinalIgnoreCase)
.OrderBy(group => group.Key, StringComparer.OrdinalIgnoreCase)
.Select(subSubjectGroup =>
{
var subSubjectCards = subSubjectGroup.ToList();
var subSubjectLibraries = subSubjectGroup
.OrderBy(library => StatusSortOrder(library.RagStatus))
.ThenBy(library => library.FileName, StringComparer.OrdinalIgnoreCase)
.ToList();
return new FlashcardRagSubSubjectGroup
{
SubSubject = subSubjectGroup.Key,
Summary = BuildSummary(subSubjectCards),
Cards = subSubjectCards
Summary = BuildSummary(subSubjectLibraries),
Libraries = subSubjectLibraries
};
})
.ToList();
@@ -312,32 +317,37 @@ namespace Mindforge.API.Services
return string.Join(" / ", segments[subSubjectStart..subSubjectEnd]);
}
private static FlashcardRagCard BuildRagCard(FlashcardCardWithLibrary card, DateTime referenceTime)
private static FlashcardRagLibrary BuildRagLibrary(
IReadOnlyList<FlashcardCardWithLibrary> cards,
DateTime referenceTime)
{
var subject = string.IsNullOrWhiteSpace(card.Subject)
? ExtractSubject(card.FilePath)
: card.Subject;
var subSubject = ExtractSubSubject(card.FilePath);
var totalAnswers = card.CorrectCount + card.IncorrectCount;
var firstCard = cards[0];
var subject = string.IsNullOrWhiteSpace(firstCard.Subject)
? ExtractSubject(firstCard.FilePath)
: firstCard.Subject;
var subSubject = ExtractSubSubject(firstCard.FilePath);
var correctCount = cards.Sum(card => card.CorrectCount);
var incorrectCount = cards.Sum(card => card.IncorrectCount);
var totalAnswers = correctCount + incorrectCount;
var lastReviewedAt = cards.Max(card => card.LastReviewedAt);
var performanceRate = totalAnswers == 0
? 0
: (double)card.CorrectCount / totalAnswers;
: (double)correctCount / totalAnswers;
return new FlashcardRagCard
return new FlashcardRagLibrary
{
CardId = card.Id,
LibraryId = card.LibraryId,
FileName = card.FileName,
LibraryId = firstCard.LibraryId,
FilePath = firstCard.FilePath,
FileName = firstCard.FileName,
Subject = subject,
SubSubject = subSubject,
Front = card.Front,
Back = card.Back,
CorrectCount = card.CorrectCount,
IncorrectCount = card.IncorrectCount,
CorrectCount = correctCount,
IncorrectCount = incorrectCount,
CardCount = cards.Count,
TotalAnswers = totalAnswers,
PerformanceRate = performanceRate,
LastReviewedAt = card.LastReviewedAt,
RagStatus = DetermineRagStatus(card.LastReviewedAt, performanceRate, referenceTime)
LastReviewedAt = lastReviewedAt,
RagStatus = DetermineRagStatus(lastReviewedAt, performanceRate, referenceTime)
};
}
@@ -369,13 +379,13 @@ namespace Mindforge.API.Services
return "Amber";
}
private static FlashcardRagSummary BuildSummary(IEnumerable<FlashcardRagCard> cards)
private static FlashcardRagSummary BuildSummary(IEnumerable<FlashcardRagLibrary> libraries)
{
var cardList = cards.ToList();
var greenCount = cardList.Count(card => card.RagStatus == "Green");
var amberCount = cardList.Count(card => card.RagStatus == "Amber");
var redCount = cardList.Count(card => card.RagStatus == "Red");
var greyCount = cardList.Count(card => card.RagStatus == "Grey");
var libraryList = libraries.ToList();
var greenCount = libraryList.Count(library => library.RagStatus == "Green");
var amberCount = libraryList.Count(library => library.RagStatus == "Amber");
var redCount = libraryList.Count(library => library.RagStatus == "Red");
var greyCount = libraryList.Count(library => library.RagStatus == "Grey");
var activeCount = greenCount + amberCount + redCount;
var greenPercentage = activeCount == 0
@@ -397,6 +407,17 @@ namespace Mindforge.API.Services
};
}
private static int StatusSortOrder(string status)
{
return status switch
{
"Red" => 0,
"Amber" => 1,
"Green" => 2,
_ => 3
};
}
private class FlashcardJsonPayload
{
public List<FlashcardJsonCard> Flashcards { get; set; } = [];