https://github.com/christitustech/titusbooks
I hate quickbooks, I'm making my own self-hosted all data never leaves local network.
https://github.com/christitustech/titusbooks
Last synced: about 1 month ago
JSON representation
I hate quickbooks, I'm making my own self-hosted all data never leaves local network.
- Host: GitHub
- URL: https://github.com/christitustech/titusbooks
- Owner: ChrisTitusTech
- Created: 2026-06-16T14:31:13.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-06-21T23:52:56.000Z (about 1 month ago)
- Last Synced: 2026-06-22T10:27:59.896Z (about 1 month ago)
- Language: C#
- Homepage:
- Size: 293 KB
- Stars: 14
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Roadmap: ROADMAP.md
- Agents: AGENTS.md
Awesome Lists containing this project
README
# TitusBooks
TitusBooks is a multi-platform bookkeeping desktop app on an Avalonia + ASP.NET Core + .NET 10 + PostgreSQL foundation.
Phases 0 through 5 of the roadmap are implemented locally. TitusBooks currently supports organization and account setup, manual expense/income/transfer posting, account registers, financial reports, CSV report export, and generic CSV transaction staging with column mapping and duplicate detection.
## Files
- `SPEC.md` - Product, accounting, database, import, security, and UX specification.
- `ROADMAP.md` - Phased implementation roadmap with milestones and acceptance criteria.
- `AGENTS.md` - Codex agent operating instructions and task decomposition rules.
- `SKILLS.md` - Domain and technical skills Codex should apply while working on the project.
- `src/FinancialApp.Desktop` - Avalonia desktop application.
- `src/FinancialApp.Api` - ASP.NET Core API service.
- `src/FinancialApp.Core` - Domain and application models.
- `src/FinancialApp.Data` - PostgreSQL data access and embedded migrations.
- `src/FinancialApp.Migrations` - CLI for applying PostgreSQL migrations.
- `src/FinancialApp.Importers` - Generic CSV parsing, normalization, fingerprinting, and staging services.
- `src/FinancialApp.Reports` - Financial report calculations and CSV export.
- `tests` - xUnit test projects.
## Local Development
Prerequisite:
- .NET SDK 10
Build:
```bash
dotnet build TitusBooks.slnx
```
Run tests:
```bash
dotnet test TitusBooks.slnx
```
Run the desktop app:
```bash
dotnet run --project src/FinancialApp.Desktop/FinancialApp.Desktop.csproj
```
Local, non-secret desktop overrides may be placed in `src/FinancialApp.Desktop/appsettings.Local.json`. Desktop clients should store the API endpoint, not PostgreSQL credentials.
Run the API locally:
```bash
dotnet run --project src/FinancialApp.Api/FinancialApp.Api.csproj --urls http://127.0.0.1:5000
```
Check API health:
```bash
curl http://127.0.0.1:5000/health
curl http://127.0.0.1:5000/health/database
```
Report endpoints use inclusive `startDate` and `endDate` query parameters:
```text
GET /organizations/{organizationId}/reports/profit-and-loss
GET /organizations/{organizationId}/reports/expenses-by-category
GET /organizations/{organizationId}/reports/income-by-source
GET /organizations/{organizationId}/reports/{reportName}/csv
```
Generic CSV import endpoints:
```text
POST /imports/csv/headers
POST /organizations/{organizationId}/imports/csv/preview
POST /organizations/{organizationId}/imports/csv
GET /organizations/{organizationId}/imports/transactions
```
CSV imports remain in staging and never post journal entries automatically.
## Database Migrations
The migration CLI runs on the API/database host and accepts a PostgreSQL connection string from an argument or environment variable. Keep secrets out of committed config files.
Preferred local setup:
```bash
cp .env.example .env
```
Then edit `.env` and fill in `TITUSBOOKS_CONNECTIONSTRING`. The `.env` file is ignored by git.
```bash
dotnet run --project src/FinancialApp.Migrations/FinancialApp.Migrations.csproj -- \
--connection-string "Host=localhost;Port=5432;Database=titusbooks;Username=postgres;Password=..."
```
Or:
```bash
TITUSBOOKS_CONNECTIONSTRING="Host=localhost;Port=5432;Database=titusbooks;Username=postgres;Password=..." \
dotnet run --project src/FinancialApp.Migrations/FinancialApp.Migrations.csproj
```
Or, after filling in `.env`:
```bash
dotnet run --project src/FinancialApp.Migrations/FinancialApp.Migrations.csproj
```
The baseline migration creates organizations, accounts, import batches, imported transactions, journal entries, journal lines, categorization rules, and reconciliations.
## Server Publish
Publish the API for Linux x64:
```bash
dotnet publish src/FinancialApp.Api/FinancialApp.Api.csproj \
-c Release \
-r linux-x64 \
--self-contained false \
-o artifacts/publish/FinancialApp.Api
```
Copy the published files to the server:
```bash
rsync -av artifacts/publish/FinancialApp.Api/ titus@10.0.0.80:/opt/titusbooks/api/
```
The server-side systemd service should set:
```text
ASPNETCORE_URLS=http://10.0.0.80:5000
TITUSBOOKS_CONNECTIONSTRING=Host=127.0.0.1;Port=5432;Database=titusbooks;Username=titus;Password=...;SSL Mode=Disable;Timeout=15;Command Timeout=120;Keepalive=30
TITUSBOOKS_RUN_MIGRATIONS=false
```
Install the systemd service template:
```bash
sudo cp deploy/systemd/titusbooks-api.service /etc/systemd/system/titusbooks-api.service
sudo systemctl daemon-reload
sudo systemctl enable titusbooks-api
sudo systemctl start titusbooks-api
```
Check service status and logs:
```bash
sudo systemctl status titusbooks-api
sudo journalctl -u titusbooks-api -n 100 --no-pager
```
If `TITUSBOOKS_RUN_MIGRATIONS=true`, the API applies embedded migrations during startup. Keep it `false` if you prefer running migrations manually with `FinancialApp.Migrations`.
## Foundation Stack (Locked)
- Desktop UI: Avalonia UI
- API: ASP.NET Core
- Language/runtime: .NET 10
- Database: PostgreSQL
- Data access: Npgsql + Dapper
- Migrations: FluentMigrator or DbUp
- Tests: xUnit
- Packaging: platform-specific desktop packages later in roadmap
The outline in this repository is intentionally constrained to this stack to keep implementation decisions specific and consistent.