Work Order Desk
A full stack work order management application built to demonstrate strong domain modeling, clean architecture, and predictable state transitions.
Overview
Work Order Desk is a portfolio project designed to showcase how I approach full stack application design beyond basic CRUD. The goal was to build a system with meaningful business rules, clear ownership of responsibilities, and a backend structure that could scale without turning into a tightly coupled codebase.
Problem
Internal tools often become difficult to maintain when business rules are scattered across controllers, UI code, and persistence logic. I wanted to build a work order system where the rules were explicit and enforced in the right place. That meant treating work orders as domain objects with valid transitions and constraints, rather than as loose database records.
Core Business Rules
This project centers around a state-driven workflow:
- Backlog → Open → InProgress → Complete
- Archive can happen from any state
- Invalid transitions are rejected
- InProgress requires an assignee
- CreatedAt is set on creation
- UpdatedAt changes whenever the work order is modified
- CompletedAt and ArchivedAt are set when appropriate
These rules helped make the project feel closer to a real business application and gave me a strong reason to separate domain logic from transport and persistence concerns.
Architecture
I split the backend into four projects to keep responsibilities clear:
- Domain: entities, enums, and business rules
- Application: commands, handlers, and use-case orchestration
- Infrastructure: EF Core, repositories, and database concerns
- API: HTTP endpoints and application wiring
On the frontend, I used React and TypeScript to build a simple, focused interface for creating and managing work orders. The UI stays lightweight while the backend carries the responsibility for enforcing rules.
Why I Structured It This Way
I did not want the domain rules to live inside controllers or be implicitly enforced by UI behavior. Separating concerns made it easier to reason about change and easier to test the system in isolation.
I used a command and handler pattern in the application layer so each backend action had a clear entry point and a single place for orchestration. That made state-changing operations more explicit and easier to evolve over time.
I also intentionally kept the API thin. Its job is to receive the request, pass it into the application layer, and return the result. The API should not be the place where business rules are invented.
Key Technical Decisions
- Used .NET 8 and EF Core for a modern backend with clean data access patterns.
- Used SQLite to keep setup simple while developing the portfolio project.
- Kept repository abstractions between the application layer and persistence layer to reduce coupling.
- Used TypeScript on the frontend for stronger contracts and clearer data handling.
- Added centralized exception handling so API errors could be translated into consistent responses.
Challenges
One of the main challenges was making sure the project actually demonstrated engineering judgment instead of becoming a standard CRUD app. That meant choosing constraints that mattered and then designing the system around them.
Another challenge was keeping the frontend simple while still making the overall project feel polished. I wanted the interface to support the backend design rather than distract from it.
What I Would Add Next
- Authentication and role-based permissions
- Filtering, sorting, and search for larger datasets
- Audit history for status changes
- Automated tests around domain rules and application handlers
- Deployment to a cloud environment with a production database