Files
duempelkas/.github/prompts/04-application-services.prompt.md
troogs e589cc170a Add GitHub Copilot prompt files
- Step-by-step prompts for solution skeleton, domain model,
  DbContext mappings, application services, UI shell/pages,
  PDF export, and tests/validation
2026-03-31 17:12:35 +02:00

58 lines
3.1 KiB
Markdown

---
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<List<AccountSummaryDto>> GetAllAccountsAsync()` — returns each account with its current total balance across all years.
- `Task<AccountSummaryDto> CreateAccountAsync(string name)`
- `Task RenameAccountAsync(int accountId, string newName)`
- `Task DeleteAccountAsync(int accountId)`
### IAccountYearService
- `Task<List<AccountYearDto>> GetYearsForAccountAsync(int accountId)`
- `Task<AccountYearDto> CreateYearAsync(int accountId, int year, decimal openingBalance)`
- `Task<decimal> SuggestCarryoverAsync(int accountId, int year)` — calculates prior year's closing balance as suggestion.
- `Task UpdateOpeningBalanceAsync(int accountYearId, decimal openingBalance)`
### IEntryService
- `Task<List<EntryDto>> GetEntriesAsync(int accountYearId)`
- `Task<EntryDto> 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<decimal> GetAccountTotalBalanceAsync(int accountId)` — OpeningBalance + sum(Income) - sum(Expense) across all years.
- `Task<YearlySummaryDto> GetYearlySummaryAsync(int accountYearId)` — returns opening balance, total income, total expense, yearly movement, closing balance.
### IPdfStatementService
- `Task<byte[]> GenerateYearlyStatementAsync(int accountYearId)`
### IFileSaveService
- `Task<string?> 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.