--- description: "Define and implement application service interfaces and implementations for accounts, years, entries, transfers, balance queries, and file operations" agent: "agent" --- # Step 4: Application Services ## Interfaces (in `src/Duempelkas.App/Services/`) ### IAccountService - `Task> GetAllAccountsAsync()` — returns each account with its current total balance across all years. - `Task CreateAccountAsync(string name)` - `Task RenameAccountAsync(int accountId, string newName)` - `Task DeleteAccountAsync(int accountId)` ### IAccountYearService - `Task> GetYearsForAccountAsync(int accountId)` - `Task CreateYearAsync(int accountId, int year, decimal openingBalance)` - `Task SuggestCarryoverAsync(int accountId, int year)` — calculates prior year's closing balance as suggestion. - `Task UpdateOpeningBalanceAsync(int accountYearId, decimal openingBalance)` ### IEntryService - `Task> GetEntriesAsync(int accountYearId)` - `Task CreateEntryAsync(int accountYearId, EntryType type, DateTime date, string title, decimal amount)` - `Task CreateTransferAsync(int sourceAccountYearId, int targetAccountYearId, DateTime date, string title, decimal amount)` — atomically creates two entries + TransferLink. - `Task DeleteEntryAsync(int entryId)` — if linked transfer, deletes both sides atomically. - `Task UpdateEntryAsync(int entryId, DateTime date, string title, decimal amount)` ### IBalanceQueryService - `Task GetAccountTotalBalanceAsync(int accountId)` — OpeningBalance + sum(Income) - sum(Expense) across all years. - `Task GetYearlySummaryAsync(int accountYearId)` — returns opening balance, total income, total expense, yearly movement, closing balance. ### IPdfStatementService - `Task GenerateYearlyStatementAsync(int accountYearId)` ### IFileSaveService - `Task SaveFileAsync(byte[] content, string suggestedFileName)` — abstracts native file-save dialog. ## DTOs (in `src/Duempelkas.App/Services/Models/`) - `AccountSummaryDto` { Id, Name, TotalBalance, CreatedUtc } - `AccountYearDto` { Id, AccountId, Year, OpeningBalance } - `EntryDto` { Id, AccountYearId, Type, Date, Title, Amount, IsTransfer, TransferLinkId, LinkedAccountName } - `YearlySummaryDto` { OpeningBalance, TotalIncome, TotalExpense, YearlyMovement, ClosingBalance } ## Implementations (in `src/Duempelkas.Infrastructure/Services/`) - Implement each interface using `FinanceDbContext`. - All balance calculations use the single formula: `OpeningBalance + sum(Income) - sum(Expense)`. - Transfer creation must be wrapped in a transaction. - Entry deletion must check for TransferLink and delete both sides if linked. ## DI Registration - Create `src/Duempelkas.Infrastructure/DependencyInjection.cs` with `AddInfrastructure(this IServiceCollection, string connectionString)` extension method that registers DbContext and all services. ## Conventions - File-scoped namespaces. - Async/await throughout. - No business logic in entities; all in services.