Skip to content

Added dotnet - #4

Open
mpchenette wants to merge 2 commits into
mainfrom
added_dotnet
Open

Added dotnet#4
mpchenette wants to merge 2 commits into
mainfrom
added_dotnet

Conversation

@mpchenette

Copy link
Copy Markdown
Owner

This pull request introduces a new .NET 8.0 web API for managing tasks, with a flexible, testable architecture and CSV-based persistence. It includes a robust TaskItem model with a custom scoring algorithm, two interchangeable task service implementations (CSV and in-memory), a full suite of xUnit tests, and an OpenAPI-enabled minimal API with endpoints for CRUD operations. The project is structured for maintainability and extensibility.

@mpchenette
mpchenette requested a review from CopilotAugust 6, 2025 18:59
@sonarqubecloud

Copy link
Copy Markdown

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This pull request introduces a complete .NET 8.0 web API for task management, featuring a flexible architecture with multiple persistence options and a comprehensive scoring algorithm for task prioritization.

  • Implements a full-stack task management system with both API endpoints and a web interface
  • Provides two interchangeable storage implementations (in-memory and CSV-based) through dependency injection
  • Includes a custom task scoring algorithm that considers priority, status, creation date, and other factors

Reviewed Changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 6 comments.

Show a summary per file
FileDescription
DotnetApp/wwwroot/index.htmlFrontend web interface for task management with CRUD operations
DotnetApp/Services/ITaskService.csService interface defining task management contract
DotnetApp/Services/InMemoryTaskService.csIn-memory implementation of task service using concurrent collections
DotnetApp/Services/CsvTaskService.csCSV-based persistence implementation with file locking
DotnetApp/Program.csMain application entry point configuring API endpoints and services
DotnetApp/Models/TaskItem.csTask model with complex scoring algorithm implementation
DotnetApp/DotnetApp.csprojProject configuration for .NET 8.0 web application
DotnetApp.Tests/Services/InMemoryTaskServiceTests.csUnit tests for in-memory task service implementation
DotnetApp.Tests/Models/TestItemTest.csUnit tests for task scoring algorithm
DotnetApp.Tests/DotnetApp.Tests.csprojTest project configuration with xUnit dependencies

<option value="in-progress" ${task.status === 'in-progress' ? 'selected' : ''}>In Progress</option>
<option value="completed" ${task.status === 'completed' ? 'selected' : ''}>Completed</option>
</select>
<button class="btn-edit btn-delete" onclick="deleteTask(${task.id})">Delete</button>

CopilotAIAug 6, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The delete button has both btn-edit and btn-delete CSS classes applied. The btn-edit class should be removed as it's semantically incorrect for a delete action and may cause styling conflicts.

Suggested change
<buttonclass="btn-edit btn-delete" onclick="deleteTask(${task.id})">Delete</button>
<buttonclass="btn-delete" onclick="deleteTask(${task.id})">Delete</button>

Copilot uses AI. Check for mistakes.
.Where(line => !string.IsNullOrWhiteSpace(line))
.Select(line =>
{
var parts = line.Split(',');

CopilotAIAug 6, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CSV parsing using Split(',') is vulnerable to breaking when task titles or descriptions contain commas. This will cause incorrect field parsing and potential data corruption. Consider using a proper CSV parser library or implementing proper CSV escaping/unescaping that handles quoted fields.

Copilot uses AI. Check for mistakes.
/// </summary>
/// <param name="value">The string value to escape.</param>
/// <returns>The escaped string.</returns>
private string Escape(string? value) => value?.Replace("\"", "\"\"") ?? string.Empty;

CopilotAIAug 6, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CSV escaping is incomplete. This method only escapes quotes but doesn't wrap fields containing commas, quotes, or newlines in quotes. Fields containing commas will break the CSV parsing. A complete implementation should wrap such fields in quotes: \"field,with,commas\".

Suggested change
privatestringEscape(string?value)=>value?.Replace("\"","\"\"")??string.Empty;
privatestringEscape(string?value)
{
if(string.IsNullOrEmpty(value))
returnstring.Empty;
varneedsQuotes=value.Contains(',')||value.Contains('"')||value.Contains('\n')||value.Contains('\r');
varescaped=value.Replace("\"","\"\"");
returnneedsQuotes?$"\"{escaped}\"":escaped;
}

Copilot uses AI. Check for mistakes.
private List<TaskItem> ReadAll()
{
var lines = File.ReadAllLines(_filePath);
return lines

CopilotAIAug 6, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GetTaskById method reads the entire CSV file for each lookup, which is inefficient for large datasets. Consider caching the task list in memory or implementing an index for better performance, especially since this method may be called frequently.

Suggested change
returnlines
RefreshCache();
_nextId=_taskCache.Any()?_taskCache.Max(t =>t.Id):0;
}
/// <summary>
/// Refreshes the in-memory task cache from the CSV file.
/// </summary>
privatevoidRefreshCache()
{
varlines=File.ReadAllLines(_filePath);
_taskCache= lines

Copilot uses AI. Check for mistakes.
/// </summary>
/// <param name="id">The unique identifier of the task.</param>
/// <returns>The task item if found; otherwise, null.</returns>
public TaskItem? GetTaskById(int id) => ReadAll().FirstOrDefault(t => t.Id == id);

CopilotAIAug 6, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GetTaskById method reads the entire CSV file for each lookup, which is inefficient for large datasets. Consider caching the task list in memory or implementing an index for better performance, especially since this method may be called frequently.

Copilot uses AI. Check for mistakes.
{
foreach (var word in Title.Split(' '))
{
if (word.Length > 10)

CopilotAIAug 6, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The magic number 10 for word length threshold should be extracted to a named constant to improve code readability and maintainability. Consider defining private const int LongWordThreshold = 10;.

Suggested change
if(word.Length>10)
if(word.Length>LongWordThreshold)

Copilot uses AI. Check for mistakes.
@mpchenette

Copy link
Copy Markdown
OwnerAuthor

Hello from VS Code!

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mpchenette