Personal Manager app icon

Personal Manager

A self-hosted income & expense manager with an offline-capable device app, a credential vault and a personal organizer.

Built as one .NET solution where the web app, the device app and the API share the same domain, the same Razor UI and the same database schema. A screen is written once and appears in both hosts. The device app keeps a complete encrypted local replica, so it works with no network at all and reconciles with the server when one is available.

This page is a public overview of the project. The source repository is private — see Source and licence below.

Three hosts, one codebase

HostWhat it isRuns on
PersonalManager.Web Blazor Interactive Server site, installable as a PWA Any browser
PersonalManager.MauiHybrid .NET MAUI Blazor Hybrid app with its own encrypted local database Android, Windows
PersonalManager.Api JWT-authenticated HTTP API and background backup host IIS / Kestrel / shared hosting
Architecture overview: shared domain, application and UI layers feeding a Blazor Server host, a MAUI Blazor Hybrid host and an ASP.NET Core API over SQL Server.
How the hosts, the shared layers and the two databases fit together.

What it does

Finance

Organizer workspace

A diary, notes and task manager living beside the finance screens, sharing the same account. Every tab is its own bookmarkable URL.

SectionContains
TodayOverdue work, tasks due today, today's notes and diary
NotesActive / Pinned / Archive / Recycle bin
DiaryActive / Drafts / Favorites / Archive / Recycle bin
TasksUpcoming, Overdue, Recurring, Completed, Archived, All — list or calendar view

Credential vault

Cards, bank logins, website logins and secure notes, encrypted with a passphrase separate from the account password — the app cannot read any of it until that passphrase is entered. Supports custom fields, per-field secret masking, security question/answer pairs and recovery codes, and works offline on the device app.

Backup and restore

Engineering notes

Write once, render twice

The browser host and the native WebView host render the same Razor components from a shared UI project, against the same contracts.

Offline is the default

The device app owns a complete local database and treats the server as a peer it reconciles with — not an online client with a cache.

Strictly inward dependencies

Domain depends on nothing; Application on Domain; Infrastructure and API on Application; the hosts on the shared UI.

Schema changes are a procedure

Migration, then regenerated SQL deployment scripts behind a drift check, then review and targeted migration tests. Nothing is ever auto-applied to a hosted database.

Layer diagram showing dependencies pointing inward from hosts through UI and Application to Domain.
Layers and dependency direction.
Diagram of a single read path serving both the Blazor Server host and the MAUI Blazor Hybrid host.
One read path, two hosts — the same component served from a browser circuit and from a native WebView.

Offline replica and sync

Sync engine diagram: local writes, encrypted outbox, change feed pull and idempotent replay.
The sync engine: local write, encrypted outbox, change-feed pull, idempotent replay.

Security

Five separate encryption layers, frequently confused for one:

LayerProtects
In transitAPI ↔ SQL Server
At rest — databaseData and log files, and server backups, via Transparent Data Encryption where the host allows it
At rest — app backupsArchives written by the backup feature, including Drive uploads. AES-256-GCM, always on
At rest — device replicaThe offline copy on the phone or PC and the unsent queue. SQLCipher + AES-256-GCM, per-install key in the platform keystore
At rest — vaultVault records, under a passphrase separate from the account password

Alongside those:

Every configuration file in the repository carries placeholders only. Signing keys, mail passwords and OAuth secrets are supplied through user-secrets locally or environment variables in production, and are never committed.

Tech stack

AreaChoice
Runtime.NET 10
APIASP.NET Core, controllers, OpenAPI
Web UIBlazor Interactive Server + PWA
Device UI.NET MAUI Blazor Hybrid — net10.0-android (API 23+) and net10.0-windows10.0.19041.0
DataEF Core 10 — SQL Server in production, SQLite as a zero-setup dev fallback
Device dataSQLCipher (AES-256) local replica, key held in the platform keystore
SpreadsheetsClosedXML
PDFPDFsharp-MigraDoc
AuthJWT bearer + rotating refresh tokens; cookie auth on the Web host
TestsxUnit, Microsoft.AspNetCore.Mvc.Testing, coverlet
PackagesCentral Package Management with transitive pinning

iOS and Mac Catalyst targets are deliberately off: the Apple toolchain only builds on macOS, so adding the framework without a Mac breaks the build rather than getting closer to shipping.

Testing and delivery

Source and licence

The implementation lives in a private repository. This page exists to describe the work and the decisions behind it; it does not distribute the code.

No licence is granted for anything described here. The diagrams on this page are from the project's own design documentation.