Full implementation for flashcards - #220
Conversation
Dejmenek
left a comment
There was a problem hiding this comment.
Hey @DeanoAbr 👋
I've reviewed your project and it looks great😁
🟢 You've fulfilled all of the project requirements
🟢 I like that you added indexes where they make sense
🟢 Good idea using a check constraint to enforce valid score values at the database level
⭐ Well done on completing the challenge of implementing the report system
Suggestions
🟡 Right now, FlashcardRepository is responsible for both flashcards and stacks, so it's handling more than one responsibility. It might be worth introducing a separate StackRepository to keep those concerns separated.
🟡 The same idea applies to Program.cs. At the moment it contains quite a lot of logic, so splitting methods like ManageStacksAsync into a StacksManager class and ManageCardsAsync into a CardsManager class could make the code easier to read, maintain, and eventually test.
🟡 I was wondering why you decided not to use Spectre.Console for this project. I think it could simplify quite a bit of the code, and it comes with a lot of useful features that make building console applications much easier.
🟡 Instead of recalculating the display ID every time you update or delete a card, you could return the card IDs from GetCardsAsync and pass them through to the update and delete operations.
🟡 I noticed the reports are displayed twice because of how the PIVOT query is built. The subquery feeding the PIVOT selects both ss.Id AS SessionId and a score percentage, even though each report only aggregates one of them. Since PIVOT groups by every column that isn't the pivot column or the aggregated value, the remaining column ends up splitting the results into separate groups.
- In the Sessions per Month report, you're counting SessionId, so Percentage becomes part of the grouping. SQL Server groups by (StackName, Percentage) instead of just StackName.
- In the Average Score report, you're averaging Percentage, so SessionId becomes part of the grouping. That results in grouping by (StackName, SessionId).
Because every study session has a unique SessionId and percentage, while the rows generated for months without sessions contain NULL values, a stack with a single study session ends up being split into two rows: one containing the actual data and another containing zeros for the remaining months.

I'll mark your project as approved✔. Keep up the good work😁
No description provided.