The MVC Application Design
With the domain modeled, the web application almost designs itself β if you follow the layered discipline from Module 6. This lesson maps actors to Areas, screens to ViewModels, and queues to Kendo grids.
One area per actor
ASP.NET Core MVC Areas give each actor their own controller/view namespace inside one deployable app:
Areas/Eppβ the submitter portal: submit a transcript package, watch its status, respond to document requests. Small, friendly, Bootstrap-forms territory.Areas/Analystβ the workbench: a work queue, the review screen (built out fully in Module 11 Lesson 4), and determination entry. This is where the app earns its keep.Areas/Adminβ SMR and methodology management, user/role administration, operational reports.
Authorization follows the same lines: role-based [Authorize(Roles = "Analyst")] at the area
level, plus row-level checks in services (an EPP sees only its candidates β enforce that in
the query, not the view).
Thin controllers over services
Every controller action should read like a table of contents: bind, call a service, map, return.
public IActionResult Queue(QueueFilter filter)
{
var items = _reviewService.GetQueue(User.Identity.Name, filter);
return View(_mapper.Map<List<QueueItemVm>>(items));
}
The rules engine, status transitions, and AI calls all live behind service interfaces in the business layer. The payoff is the usual one β testability β plus something specific to this domain: when an auditor asks "what exactly happens when an analyst approves a finding?", the answer is one service method, not logic smeared across three controllers and a view.
ViewModels and AutoMapper
Entities never reach a view. The review screen needs a composite ViewModel β candidate
header, coursework rows, SMR checklist with findings β assembled from several entities, while
the EPP status page needs five fields. Define per-screen ViewModels and let AutoMapper
profiles do the shuttling. Two domain-specific rules: map PII fields explicitly (no
convention-mapping a Ssn onto a ViewModel by accident), and flatten confidence scores and
status enums into display-ready strings in the profile, not in Razor.
Kendo grids for the work queues
The analyst queue is the canonical Kendo Grid use case from Module 4: server-side paging,
sorting, and filtering over a DataSourceRequest, showing status badges, days-in-queue, and an
assignment column. Resist loading the whole queue client-side β statewide volume will grow, and
ToDataSourceResult over an IQueryable keeps SQL Server doing the paging.
File upload for transcripts
Uploads deserve paranoia: accept only PDF/TIFF, check the magic bytes not just the
extension, cap the size, virus-scan if the agency mandates it, and stream to storage rather
than buffering in memory. Store a SHA-256 hash on TranscriptDocument β it deduplicates
resubmissions and proves later that the file reviewed is the file submitted. Return the user to
a status page immediately; extraction happens in the background (next lesson).