MyHotel Code

ASP.NET Core 9 · EF Core · SignalR

Hotel operations, in one calm console.

MyHotel runs the day-to-day of a hotel: a rooms board that updates live, work orders, shift logs, complaints, cash counts, inventory and team messaging, for five departments and five permission levels, across multiple properties.

  • 29 MVC controllers
  • 5 departments
  • 5 roles
  • 4 themes
MyHotel dashboard: greeting banner with occupancy, ready rooms and checks done, KPI cards, a floor map of room statuses and a recent activity timeline.

All screenshots are from the real app running locally with fictional sample data.

Real-time

Changes show up where the work happens.

One SignalR hub carries two kinds of events. Personal notifications go to user_{id}, and hotel-wide events like room status changes go to hotel_{id}. The hub only lets a connection join hotels the user has a role in.

The engineering manager's page showing a live toast: New Work Order 215, guest reports the shower drain is slow.

Work order → engineering, instantly

The front desk files a work order. NotificationService saves a notification for each engineer and pushes it; their bell badge ticks up and a toast slides in.

The housekeeping rooms board after room 103 was changed to Inspected from another browser: the tile, counts and status bar updated in place and a toast appeared.

Rooms board stays in sync

A manager marks room 103 inspected. Every open board for that hotel receives RoomStatusChanged and patches the tile, the counts and the status bar in place, with no reload.

  1. 1
    Browser posts the work order form (antiforgery token, cookie auth).
  2. 2
    WorkOrdersController saves it with EF Core and finds the Engineering department.
  3. 3
    NotificationService writes one Notification row per member, except the sender.
  4. 4
    IHubContext sends ReceiveNotification to each user_{id} group.
  5. 5
    Engineer's browser bumps the bell badge and shows a toast built with textContent.

Tour

A look around the app.

Rooms board grouped by floor: each tile shows the room number, type and a status pill with an icon and label; a sticky status bar shows counts per status.

Floor-by-floor board. Status is shown by colour, icon and label, so it still reads for colour-blind users. Changing a status happens in place and is broadcast to every open board.

Features

Every department gets its own hub.

Front desk

Shift pass logs, daily checks, complaints with escalation, lost & found, and cash reports with bill, coin and roll counts.

Housekeeping

Live rooms board with notices (VIP, DND, early check-in, late checkout), cleaning requests and supply inventory.

Engineering

Work orders (list or board), preventive maintenance schedule, meter readings and an asset register.

Sales

Group sales pipeline plus the shared meetings, schedule, messages and inventory tools.

Administrative

Budget and expenses, cross-module reports, staff evaluations, directory and a room-tax calculator.

Management

Multi-hotel switching, employee and department management, per-user permission overrides and admin impersonation.

Role hierarchy

  1. AdminAll hotels, creates GMs
  2. General ManagerTheir hotels, all modules
  3. Assistant GMOne hotel, all modules
  4. Dept. ManagerTheir department
  5. EmployeeRole permissions + overrides

Architecture

A classic, well-lit MVC monolith.

Server-rendered Razor views with a sprinkle of Alpine.js, thin controllers, scoped services, EF Core on SQLite, and one SignalR hub for push.

MyHotel architecture The browser sends requests to ASP.NET Core MVC controllers protected by Identity cookie auth and antiforgery. Controllers use scoped services (HotelContext, Permission, Impersonation, Notification) and EF Core, which stores data in SQLite. NotificationService pushes events through IHubContext to NotificationHub, which delivers them to browser groups user_id and hotel_id. Browser Razor views + Tailwind Alpine.js, SweetAlert2 SignalR JS client toast · badge · room tiles ASP.NET Core 9 MVC 29 controllers Identity cookie auth, lockout Global antiforgery filter Session: current hotel Scoped services HotelContextService PermissionService ImpersonationService NotificationService EF Core 9 → SQLite 26 entity files, 6 migrations auto-migrate on startup optional demo seed NotificationHub /hubs/notifications groups: user_{id} hotel_{id} (role-checked) HTTP IHubContext WebSocket push

Stack

Tools, chosen for a small team.

  • C# / .NET 9
  • ASP.NET Core MVC
  • ASP.NET Identity
  • EF Core 9
  • SQLite
  • SignalR
  • Razor
  • Tailwind CSS (prebuilt)
  • Alpine.js
  • SweetAlert2
  • xUnit
  • GitHub Actions
  • Ubuntu · nginx · systemd

Run it

Clone, run, sign in. No database server.

SQLite is created and migrated on first run. In Development the app seeds two fictional hotels, 22 staff accounts and 64 rooms, and the sign-in page offers one-click demo accounts.

Needs the .NET 9 SDK. Node is only needed if you change Tailwind classes.

Terminal
# clone and run
git clone https://github.com/GustavoLarcoDev/myhotel.git
cd myhotel
dotnet run
# open http://localhost:5122
# sign in as jaime@myhotel.com / jaime123 (demo GM)

# tests
dotnet test tests/MyHotel.Tests/MyHotel.Tests.csproj