AccountingNext/CLAUDE.md
Claudio Schaad 9f11f6490b PR A: correctness fixes and improvement plan
- Add IMPROVEMENT_PLAN.md with phased plan for follow-up work
- Consolidate DI registrations into a single AddAccounting() extension;
  drop the duplicate service registrations and the PdfParsingService
  self-registration
- TrySetYear: capture this.year before overwriting so rollback actually
  restores the previous value
- DummyFxService: check toCurrency (was checking fromCurrency twice)
- TransactionRepository.GetTransaction: return a copy instead of mutating
  the loaded entity, and guard against unknown ids
- ViewService.GetTransactionViewList(accountId): flip the sign on a copy
  rather than mutating the entity returned by the repository
- FileService.GetTransactionListCsv: same treatment; use a local
  signedValue instead of mutating trx.Value
- ProfitLossReport: use ClassIds.Income/Expenses instead of magic 3/4
- CLAUDE.md: correct the ClassIds documentation (1/2/3/4, not
  1000/2000/3000/4000)

SettingsService lifetime is intentionally left as Singleton for now;
making it Scoped requires persisting year/mandator selection across
page reloads first (tracked in the plan).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-02 20:37:03 +02:00

64 lines
2.6 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Commands
```bash
# Build
dotnet build
# Run (dev server at http://localhost:5225)
cd Schaad.Accounting.UI && dotnet run
# Publish
dotnet publish -c Release
```
There are no automated tests or lint commands.
## Architecture
**AccountingNext** is a Swiss personal accounting app built with ASP.NET Core 9 + Blazor (interactive server-side rendering) and Microsoft Fluent UI. Data is stored as XML files on disk — no database.
### Projects
| Project | Role |
|---|---|
| `Schaad.Accounting.UI` | Blazor web app — pages, dialogs, layout |
| `Schaad.Accounting.Services` | Business logic — balances, FX conversion, file import, charts |
| `Schaad.Accounting.Db` | Repository layer — XML serialization/deserialization |
| `Schaad.Accounting.Common` | Shared models, DTOs, interfaces |
### Data flow
```
Blazor Pages/Dialogs (UI)
→ Services (ViewService, FileService, ChartService)
→ Repositories (AccountRepository, TransactionRepository, …)
→ XML files: {DataPath}/{year}/{mandator}/Data/*.xml
```
Data is multi-year and multi-mandator. Each combination has its own directory under `DataPath` (configured in `appsettings.Development.json`). When a new year is opened, the previous year's data is copied as the starting point.
### Key services
- **ViewService** — aggregates account balances, applies FX rates, builds datasets for the UI
- **FileService** — imports bank statements (MT940, CAMT053 via external `Schaad.Finance.dll`), parses PDFs, manages backups
- **ChartService** — produces data for Plotly charts (assets, spendings over time)
- **SettingsService** — manages the active year, mandator, and file paths
### UI structure
Pages live in `Schaad.Accounting.UI/Components/Pages/`. Each page typically has a companion `Dialogs/` subfolder with Fluent UI dialog components for CRUD operations. The app is hardcoded to the `de-CH` culture.
### Key external dependencies
- `Microsoft.FluentUI.AspNetCore.Components` — UI components (FluentDataGrid, FluentDialog, etc.)
- `Plotly.Blazor` — charts
- `FreeSpire.PDF` — PDF parsing for bank statement imports
- `Schaad.Finance.dll` / `Schaad.Finance.Api.dll` — proprietary DLLs for MT940/CAMT053 parsing and FX rate lookups (FixerIo API key in `appsettings.Development.json`)
### Domain constants
`ClassIds` in `Schaad.Accounting.Common` defines the Swiss accounting chart-of-accounts classes: Activa=1, Passiva=2, Income=3, Expenses=4. These are the leading digit of an account number (accounts are 4-digit; `Account.Class = Number / 1000`).