CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl-labs/aspnet-project-structure

ASP.NET Core project structure — minimal APIs vs controllers, layer

95

2.50x
Quality

93%

Does it follow best practices?

Impact

100%

2.50x

Average score across 5 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

criteria.jsonevals/scenario-5/

{
  "context": "Tests whether the agent properly refactors a monolithic controller into the recommended ASP.NET Core project structure. The task asks to 'properly organize' but does NOT mention DTOs as records, From() factories, IServiceCollection extensions, or typed exceptions with middleware. The agent should apply all of these proactively.",
  "type": "weighted_checklist",
  "checklist": [
    {
      "name": "Services folder with business logic extracted",
      "description": "A Services/ directory exists containing a service class (e.g., TicketService). The database queries, pagination logic, and business rules from the controller have been moved into the service.",
      "max_score": 10
    },
    {
      "name": "No business logic in controller",
      "description": "The refactored TicketsController does NOT contain inline EF Core queries, pagination logic, or business validation. All action methods delegate to service methods.",
      "max_score": 12
    },
    {
      "name": "DTOs folder with records",
      "description": "A DTOs/ directory exists containing response types declared as C# records (not anonymous objects). The inline anonymous object constructions from the original controller are replaced with named DTO records.",
      "max_score": 12
    },
    {
      "name": "DTO From() factory method",
      "description": "At least one response DTO record includes a static From() method mapping from the Ticket entity. The agent was NOT asked to use factory methods.",
      "max_score": 10
    },
    {
      "name": "Typed exception classes",
      "description": "An Exceptions/ directory contains at least two typed exception classes (e.g., NotFoundException, BadRequestException). The scattered NotFound/BadRequest returns from the original controller are replaced with thrown exceptions.",
      "max_score": 10
    },
    {
      "name": "Centralized exception middleware",
      "description": "A Middleware/ directory contains exception-handling middleware that catches typed exceptions and returns consistent HTTP error responses. The controller no longer returns error responses directly.",
      "max_score": 10
    },
    {
      "name": "Models in separate folder",
      "description": "A Models/ directory exists containing entity class definitions (Ticket, Comment, Agent) separate from DTOs.",
      "max_score": 8
    },
    {
      "name": "Data folder with DbContext",
      "description": "A Data/ directory exists containing the DbContext class, moved out of the project root.",
      "max_score": 8
    },
    {
      "name": "IServiceCollection extension methods",
      "description": "DI registration is organized into IServiceCollection extension methods rather than all being inline in Program.cs. The agent was NOT asked about DI organization.",
      "max_score": 8
    },
    {
      "name": "Service interface defined",
      "description": "The service class has a corresponding interface (e.g., ITicketService) and the controller depends on the interface, not the concrete class.",
      "max_score": 6
    },
    {
      "name": "appsettings.json with config",
      "description": "An appsettings.json file exists with a ConnectionStrings section. Configuration is not hardcoded.",
      "max_score": 6
    }
  ]
}

evals

tile.json