Project · Water
Yachty
Maritime crew management — one source of truth across the fleet.
Essence
For the people who use it
Yacht operations run on a patchwork of spreadsheets, shared inboxes and cloud-drive folders. Certifications expire silently. Onboarding stalls because somebody never received a document. Payroll across multiple currencies and time zones turns into a monthly fire drill. Yachty replaces the patchwork with one place to keep crew data, run the operation and prove compliance.
Built for captains, crew managers, HR, fleet operators and the crew themselves, the platform covers the full lifecycle: recruitment, onboarding, compliance, leave, payroll, travel documents, budgets, reporting. Each role has the view it needs. Captains see crew availability and expiries; HR runs payroll; crew members upload their own documents and request their own leave.
The vessel is the unit. A fleet operator with twelve yachts gets twelve isolated tenants without twelve databases. A new crew member joining a new vessel is a workflow, not a project plan.
- Crew lifecycle management — profiles, certifications, emergency contacts, documents, across multiple vessels.
- Multi-step onboarding workflows that hold up sailing until compliance is finished.
- Leave & entitlements with request workflows, balance tracking, public-holiday calendars and rotation scheduling.
- Multi-currency monthly payroll — allowances, deductions, instant payslip generation.
- Travel-document handling — passport / visa MRZ parsing with expiry alerts and automatic compliance checks.
- Vessel-level budgets & expenses with variance reporting and category breakdowns.
- Vessel dashboards — crew availability, budget vs actual, expiry calendar.
- Role-based self-service portals — crew upload documents, request leave and view payslips; admins manage everything.
Construction
For the engineers
Stack
- API
- ASP.NET Core 10 Web API on .NET 10 · 60+ RESTful endpoints with OpenAPI
- Frontend
- Two Blazor WebAssembly 10 SPAs — Admin (operators) and Site (crew)
- Data access
- Dapper 2.1.66 — no EF Core, database-first
- Database
- SQL Server, idempotent schema scripts
- Auth
- JWT Bearer (24h + refresh) · BCrypt · Blazored.LocalStorage
- UI
- BootstrapBlazor 10.2.1 · Syncfusion Blazor 32.1.22 — grids, charts, rich text
- Document parsing
- TesseractOCR 5.5.1 · MRZ 1.2.0 for passport / visa parsing
- Testing
- Microsoft.Playwright 1.57 · NUnit · Bogus for test-data generation
Architecture
Layered monolith with clear seams. The API hosts controllers → services →
Dapper repositories → SQL Server. Yachty.Shared holds DTOs, domain models, lookup
entities and authentication contracts and is referenced by both Blazor SPAs as well as the API,
so any change to a shape ripples to both ends at compile time.
Central Package Management. Every dependency version lives in
Directory.Packages.Props. Five projects, one place to update — no drift between the
Admin SPA, Crew SPA, API, Shared and Tests projects.
Multi-vessel isolation by foreign key. Every core table — CrewMembers,
Employments, PayrollRuns, Expenses — carries a
VesselId. A twelve-yacht fleet operator gets twelve isolated tenants in one database
without per-tenant schema sprawl.
Strict soft delete and audit trail. Every entity carries IsDeleted
plus a four-column audit (CreatedAt, CreatedBy, UpdatedAt,
UpdatedBy). Nothing is destroyed; everything is attributed.
Database-first, idempotent SQL. Schema lives in a two-part DBSchema-Update.sql
— table definitions in part one, idempotent alters in part two. The same script can run against an
empty database or production without modification.
Notable details
- Repository pattern is mandatory — no Dapper calls outside the repository layer.
- Typed exception model (
ValidationException,NotFoundException) mapped to consistent HTTP responses. - Async/await throughout — no blocking calls in the request pipeline.
- CSharpier-enforced formatting after every build; warnings treated as errors.
- End-to-end tests with Playwright + NUnit; Bogus generates realistic crew data.
- Parameterised Dapper queries — SQL injection by construction not possible.
- CORS, HTTPS, BCrypt-hashed passwords, XSS protection inherited from Blazor.
- OCR + MRZ pipeline lifts passport data straight from a scan into the crew profile.
- Containerisable for Docker deployment; today runs on IIS / Kestrel.