A .NET Web API for tracking warehouse colleague activity, task assignments, breaks, and work sessions in real time.
WarehouseTracker solves the problem of tracking colleague movements and activity in a warehouse environment. It records when colleagues sign in, which departments they work in, when they take breaks, and builds a full activity timeline for each workday.
The solution follows a clean layered architecture:
WarehouseTracker.Api → Controllers, DTOs, entry point
WarehouseTracker.Application → Services, interfaces, business logic
WarehouseTracker.Domain → Domain models
WarehouseTracker.Infrastructure → Repositories, DbContext, EF Core
WarehouseTracker.Tests → Unit tests
Represents a colleague being present at work for a given day. Everything hangs off the WorkDay — task assignments, events, and activity sessions. A WorkDay is created when a colleague signs in and closed when they sign out.
Represents what a colleague is currently doing (e.g. Pick, Pack, Dispatch). A colleague can only have one active task at a time. When they check into a new department, the current task is closed and a new one is opened.
Things that happen during a workday — checking into a department, break started, break ended, shift ended. Events are the source of truth from which activity sessions are rebuilt.
Built from events by the ActivitySessionBuilder. Represents continuous periods of activity — either Active (working in a department) or Break. Sessions are rebuilt every time a new event is recorded.
A background service that runs every 30 seconds and automatically fires BreakStarted and BreakEnded events based on configured break rules.
Colleague signs in
→ WorkDay created (Status: Active)
Colleague checks into department
→ TaskAssignment created (e.g. Pick)
→ CheckedIntoDepartment event saved
→ ActivitySessions rebuilt
Break time reached
→ BreakSchedulerService fires BreakStarted event
→ WorkDay Status → OnBreak
→ ActivitySessions rebuilt (Break session added)
Break ends
→ BreakSchedulerService fires BreakEnded event
→ WorkDay Status → Active
→ ActivitySessions rebuilt (Active session resumed with previous department)
Colleague signs out
→ Open TaskAssignment closed
→ WorkDay closed (Status: Completed)
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/workday/signin |
Sign a colleague in, creates a WorkDay |
| POST | /api/workday/signout |
Sign a colleague out, closes WorkDay and active task |
| GET | /api/workday/active/{colleagueId} |
Get the active WorkDay for a colleague |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/taskassignment |
Check a colleague into a department/task |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/event |
Record a manual event for a colleague |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/activitysession |
Get activity sessions by workDayId or colleagueId |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/colleague |
Register a new colleague |
| GET | /api/colleague |
Get all colleagues |
| GET | /api/colleague/{id} |
Get colleague by ID |
public class WorkDay
{
public int Id { get; set; }
public string ColleagueId { get; set; }
public DateTimeOffset WorkDayStart { get; set; }
public DateTimeOffset? WorkDayEnd { get; set; }
public string Status { get; set; } // Active, OnBreak, Completed
public ICollection<TaskAssignment> TaskAssignments { get; set; }
}public class TaskAssignment
{
public int Id { get; set; }
public int WorkDayId { get; set; }
public string ColleagueId { get; set; }
public string DepartmentCode { get; set; }
public DateTimeOffset TaskStart { get; set; }
public DateTimeOffset? TaskEnd { get; set; }
public string Status { get; set; } // Active, Completed
}public class ActivitySession
{
public int Id { get; set; }
public string ColleagueId { get; set; }
public int WorkDayId { get; set; }
public string? DepartmentCode { get; set; }
public string SessionType { get; set; } // Active, Break
public DateTimeOffset SessionStart { get; set; }
public DateTimeOffset SessionEnd { get; set; }
}- .NET 8
- SQL Server
- Entity Framework Core
- Clone the repository:
git clone https://github.com/Zemulax/WarehouseTracker.git- Update the connection string in
appsettings.json:
{
"ConnectionStrings": {
"DefaultConnection": "Server=YOUR_SERVER;Database=WarehouseTracker;Trusted_Connection=True;"
}
}- Apply migrations:
dotnet ef database update- Run the API:
dotnet run --project WarehouseTracker.ApiServices vs Repositories — Repositories handle data access only. Services contain business logic, validation, and orchestration. For example, WorkDayService.StartWorkDayAsync checks for an existing open workday before creating a new one — logic that belongs in the service, not the repository.
Server-side resolution — Callers provide minimal data (e.g. ColleagueId, DepartmentCode). The server resolves internal concerns like WorkDayId automatically, keeping the API surface clean.
Event-sourced sessions — ActivitySessions are not manually managed. They are fully rebuilt from the event log every time a new event is recorded, ensuring the session timeline always accurately reflects what happened.
Background break scheduling — Breaks are automatically triggered by BreakSchedulerService based on configurable BreakRule records, removing the need for manual break events.