Back to projects
Jeff G. Njoroge
Jeff G. Njoroge

Debt Manager

Year: 2025
C#.NET 8ASP.NET Core Web APIEntity Framework CoreSQLiteSwagger / OpenAPI.NET MAUIMVVM (CommunityToolkit.MVVM)REST / JSONxUnitDocker

Debt Manager is a cross-platform debt tracking system designed for small teams or individuals who need a lightweight way to track money owed, record payments, and understand outstanding balances at a glance.

The system consists of a backend REST API (data + business rules) and a cross-platform client app (UI). In practice these are maintained as separate codebases so the API can be deployed independently of the client.

On the backend, the API models a simple financial workflow: Customers → Debts → Payments. It supports creating/updating/deleting records and provides query capabilities (search, sorting, and filtering) to power list views and dashboards.

On the client side, the app follows an MVVM architecture with repositories that call the API over HTTP and bind results into responsive screens for customers, debts, and payments. A dashboard summarizes totals (outstanding balance and recent activity) to reduce time spent reconciling records manually.

Key features:

  • Cross-platform client app targeting desktop and mobile platforms from a single codebase
  • CRUD flows for customers, debts, and payments with basic input validation
  • Dashboard-style summary (e.g., outstanding total, recent debts, monthly payments)
  • Search + sort on customer/debt/payment lists (client-side), backed by rich server-side query parameters
  • Backend data integrity via relational constraints (cascade deletes from customer → debts → payments)
  • Optimistic concurrency + auditing fields on the backend to support safe edits and traceability
  • Developer ergonomics: Swagger docs for API exploration and automated tests for controllers

How it works (high-level):

  • A user creates a customer, then records one or more debts tied to that customer.
  • Payments are recorded against a specific debt; the remaining balance is derived from total amount minus payments.
  • The client app calls the REST API (JSON over HTTP) through repository abstractions and updates MVVM viewmodels bound to the UI.
  • The API persists data in SQLite via Entity Framework Core, exposing endpoints for list/detail views and advanced filtering (amount/date/status).
  • Backend responses use DTOs to shape payloads and avoid overly deep object graphs in list endpoints.

Detail

This project separates concerns between a backend API that owns data integrity and business rules, and a cross-platform MAUI client that focuses on user experience and presentation. This boundary keeps the domain consistent (one source of truth for validation and persistence) while allowing the UI to evolve independently across platforms.

On the API side, the core domain is modeled as Customers → Debts → Payments, with relational rules enforced in the database layer (including cascading deletes to prevent orphaned records). The API exposes both standard CRUD endpoints and richer list endpoints that accept query parameters for searching, sorting, and filtering—so the client can request exactly the slices of data needed for dashboards and list screens without shipping large datasets unnecessarily.

Several backend decisions are specifically aimed at robustness in real-world usage:

  • DTO-based responses: payloads are shaped for UI consumption and to avoid deep circular graphs (e.g., list endpoints can omit nested collections when they aren’t needed).
  • Derived financial fields: values like “total paid”, “remaining balance”, and paid status are computed from source-of-truth amounts and payment sums rather than stored redundantly, reducing inconsistency risk.
  • Auditing: entities carry created/updated metadata, and the data layer populates these fields during save operations using the current request identity when available.
  • Optimistic concurrency: entities include a row-version token that is updated on inserts/updates in SQLite, enabling the API to detect and reject conflicting edits safely instead of silently overwriting data.

On the client side, MVVM is used to keep UI code maintainable and testable:

  • ViewModels manage screen state (loading/error/search/sort) and orchestrate user workflows like “add customer”, “add debt”, and “record payment”.
  • Repository abstractions isolate HTTP concerns behind typed methods, keeping viewmodels focused on behavior rather than networking details.

Notes/assumptions:

  • The backend includes automated tests for controller behavior using common .NET testing tools and an in-memory EF Core provider.
  • The API is documented via Swagger/OpenAPI for local exploration and easier client integration.