BACHELOR PROJECT
Overtidsmat - Full-Stack Ordering Platform
A full-stack ordering and administration platform developed for an external enterprise client to replace a manual paper-based overtime-meal ordering workflow.
Replacing a paper workflow with a web application.
The client originally handled overtime-meal orders using a physical paper list in the office kitchen. Employees had to visit the kitchen in person to register an order, which was inconvenient for employees working remotely or away from the office.
As a three-person bachelor team, we developed a full-stack web application that digitized the process for both employees and kitchen staff.
Employees received a simple interface for ordering and managing meals, while kitchen staff received an administrative interface for menu planning, order management and operational overview.
Two very different user experiences.
The application was designed around two primary roles. Employees needed the ordering process to be as quick as possible, while the kitchen needed tools for planning and administration.
Order and manage meals
- View today's meal
- Place an overtime-meal order
- Add comments or meal modifications
- Edit or cancel an existing order
- View the weekly menu
- Manage personal allergens
- View previous orders
Plan and administer service
- Create and edit the weekly menu
- View today's orders
- See employee comments and allergens
- View the total order count
- Review historical meal statistics
- Change the daily ordering cutoff time
A conventional full-stack architecture.
The frontend was built with React and TypeScript. It communicated with an ASP.NET Core backend through asynchronous HTTP requests, while the backend used controllers and repository/DAL layers to separate application logic from data access.
Reusing existing enterprise identities.
An early requirement was to provide authenticated access. Instead of creating and maintaining a separate username and password system, the project was later expanded to integrate Microsoft Entra ID.
MSAL handled the frontend authentication flow and access tokens, while the backend validated bearer tokens through Microsoft's identity integration.
Roles supplied through the identity system were then used to decide which parts of the application each user could access.
No local password database
Authentication could rely on the organization's existing identity platform rather than introducing another password store into the application.
Role-based interfaces
Employee and kitchen users were presented with different routes and functionality based on their assigned application role.
Separating responsibilities in the backend.
The backend was divided into controllers and dedicated data-access modules rather than allowing API endpoints to interact directly with the database.
Separate repositories were used for orders, users and kitchen data. This helped isolate database operations from controller logic and made the application easier to reason about and extend.
Features that grew from client feedback.
Requirements evolved throughout development as working versions of the application were demonstrated to the client. Several useful features came from those feedback cycles.
Allergen profiles
Employees could save their allergens once in their profile rather than manually entering them with every order.
Automatic allergy warning
When ordering, the application compared the employee's stored allergens with the allergens associated with the day's meal and displayed a warning when they matched.
Dynamic cutoff time
Kitchen staff could choose when ordering should close instead of relying on one fixed time every day.
Weekly menu
The original concept of setting only today's meal evolved into a full weekly menu visible to both employees and kitchen staff.
Order history
Employees could review previous orders, including meal names, comments and order dates.
Kitchen statistics
Historical order counts provided a basic overview of popular meals and demand over time.
Choosing technologies for maintainability and learning.
The team already had Angular experience, but chose React to learn another widely used frontend technology and provide a technology the client could reasonably maintain in the future.
MongoDB provided a flexible document-based structure that was straightforward to integrate and could accommodate future changes to the application's data model.
Using an established identity provider reduced the amount of sensitive authentication information the application needed to manage itself.
The backend separated API handling, application logic and data access to improve maintainability and reduce coupling.
Developing with an external client.
The project started with relatively open requirements. As the team produced working prototypes and demonstrated them, the client was able to refine what they wanted from the system.
This turned development into an iterative process in which requirements, implementation and feedback influenced one another.
Azure DevOps
Boards were used to break the project into tasks, track remaining work and coordinate responsibility within the team.
GitHub
Git and GitHub provided source control and a shared codebase throughout development.
Swagger
Swagger UI was used to exercise and inspect backend API endpoints without requiring every test to go through the frontend.
Automated tests
Controller-level unit tests formed part of the final cleanup and testing phase of the project.
From student project to a system intended for real use.
The finished application implemented the majority of the project's functional requirements and expanded beyond several of the initial requirements as development progressed.
At the end of the project, the client expressed that they were very satisfied with the system and were interested in moving it toward production use. The project documentation therefore also included a handover section covering identity configuration, hosting and the changes required to move from local development URLs to a deployed environment.
The project that established my full-stack foundation.
The project provided practical experience across frontend development, backend APIs, database integration, authentication and application architecture while working as part of a small development team.
Just as importantly, it demonstrated the value of requirements, planning and regular communication with the people who will actually use a system.