SkyFlow is a modern, console-based airport and airline management system. It was built as a 3rd year semester 1 project to demonstrate OOP principles, database integration, and structured software architecture using C# and .NET 8.
The system models the real operational flow of an airport: administrators manage flights and staff, while gate agents handle passenger check-in and boarding. Every action is logged, every state transition is controlled, and every piece of data persists across application restarts.
Why I Built SkyFlow
Airport operations are a natural fit for exploring object-oriented design. The domain has clear roles (admin, gate agent), well-defined entities (flights, passengers, bookings), and real state transitions (scheduled, boarding, departed). It is a problem space where clean architecture genuinely matters.
I wanted to build something that goes beyond a basic CRUD application. SkyFlow demonstrates:
- Role-based access control with distinct workflows per role.
- State machines for flight and booking status transitions.
- Database persistence using SQL Server with Dapper ORM.
- Audit logging for every mutating action in the system.
System Architecture
SkyFlow follows a layered architecture with clean project separation. Each project has a single responsibility, and dependencies flow in one direction: Console → Core ← Data.
Core - The Domain Layer
The domain layer has zero database dependencies. It defines the entities, enums, and contracts that the rest of the system depends on:
Useris an abstract base class withUserId,Username, andRole. It defines the contract for dashboard display.AdminextendsUserwith flight management, staff creation, and audit log access.GateAgentextendsUserwith passenger check-in, flight manifest viewing, and boarding operations.Flightholds flight data with encapsulated status transitions. Status changes go through controlled methods likeDepartFlight()- you cannot set the status directly.Passenger,Booking,Baggage,Aircraft,Airport, andFlightAssignmentmodel the full airport domain.AuditLog,FlightLog, andNotificationhandle system tracking and user communication.FlightStatus(Scheduled,Boarding,Departed,Cancelled) andBookingStatus(Booked,CheckedIn,Boarded) are enums that enforce valid state transitions.- Repository interfaces (
IUserRepository,IFlightRepository,IPassengerRepository, etc.) define data contracts without specifying implementation.
Data - The Persistence Layer
The data layer implements every repository interface using Dapper against SQL Server:
DapperContextprovides a connection factory for SQL Server.- Each repository (
UserRepository,FlightRepository,BookingRepository, etc.) maps SQL queries to domain objects using Dapper's lightweight ORM. - All queries use parameterised SQL to prevent injection.
Console - The Presentation Layer
The console layer handles authentication, menu flow, and user interaction:
AuthControllermanages the login screen with masked password input and BCrypt verification.AdminDashboarddrives the admin menu loop and dispatches actions.GateAgentDashboarddrives the gate agent menu loop and dispatches actions.ConsoleTableEnginerenders structured data as formatted ASCII tables with borders and alignment.ConsoleHelperprovides input prompts, colour formatting, and display utilities.
Key Features
Role-Based Authentication
Users authenticate with BCrypt-hashed credentials. The system recognises two roles:
- Admin - Full system access: manage flights, view the master flight table, create staff accounts, and review audit logs.
- Gate Agent - Operational access: view flight manifests, check in passengers, and manage the boarding gate.
Each role has a completely separate dashboard with distinct menu options.
Flight Management
Administrators create flight schedules, assign aircraft, and track real-time status. Flights move through a controlled lifecycle:
Scheduled → Boarding → Departed
→ Cancelled
Status transitions are encapsulated within the Flight model itself. You cannot jump from Scheduled to Departed - the system enforces the correct order.
Passenger Check-In and Boarding
Gate agents search passengers by national ID or passport number, then update booking status through the check-in flow. Bookings move through a controlled lifecycle:
Booked → CheckedIn → Boarded
The boarding gate finalises flights and transitions passengers from CheckedIn to Boarded, then marks the flight as Departed. Status transitions are enforced - you cannot board a passenger who has not checked in.
Staff Management
Administrators can create new gate agent accounts directly from the admin dashboard. New accounts are created with BCrypt-hashed passwords and assigned the GateAgent role. This keeps account provisioning within the system rather than requiring direct database access.
System Oversight
The master flight table gives administrators a bird's-eye view of all flights with live occupancy percentages and capacity tracking. This is rendered using the custom ConsoleTableEngine for clean, readable ASCII output.
Audit Logging
Every mutating action is recorded with the user who performed it, a timestamp, and the affected entity. This means you can trace exactly who did what and when - a critical requirement in systems that manage operational data. Flight status changes are tracked separately in the FlightLog for granular lifecycle visibility.
Notifications
Gate agents receive notifications for events that affect their workflow - flight assignments, status changes, and system alerts. Notifications track read/unread state so agents can focus on what is new.
OOP Principles in Practice
SkyFlow was designed to demonstrate core OOP concepts in a meaningful context:
| Principle | Implementation |
|---|---|
| Abstraction | IDataRepository interfaces separate database logic from business logic |
| Inheritance | Admin and GateAgent extend the abstract User base class |
| Polymorphism | DisplayDashboard() dispatches role-specific menus at runtime |
| Encapsulation | Private _status field with controlled transition methods like DepartFlight() |
Technical Stack
- Language: C# with .NET 8
- Database: SQL Server (via Docker or local instance)
- ORM: Dapper - lightweight SQL mapping for all CRUD operations
- Security: BCrypt password hashing and verification
- Architecture: Multi-project solution with Domain, Data, and UI layers
- Cross-Platform: Docker Compose setup ensures compatibility across Windows and macOS (including Apple Silicon)
Database Design
The SQL scripts are versioned and ordered:
001-create-database.sql- Creates SkyFlowDB002-create-tables.sql- Creates all relational tables003-seed-data.sql- Inserts sample data for testing
The Docker Compose setup automatically runs all seed scripts on startup, so getting started requires just docker compose up -d followed by dotnet run.
What I Learned
Building SkyFlow reinforced several engineering disciplines:
- Interface-driven design makes testing and refactoring significantly easier. Swapping from SQL Server to any other database would only require new repository implementations.
- State machines are underrated. Encoding valid transitions in the domain model prevents an entire category of bugs.
- Audit trails should be first-class concerns, not afterthoughts. Building them into the architecture from day one is far simpler than retrofitting.
- Console applications can be elegant. The
ConsoleTableEngineproved that a well-designed text UI can be just as readable as a graphical one for operational tools.
Where Can I Learn More?
- Repository: GitHub Repo
- Documentation: Full developer docs available in the docs/ folder