From 0280e0e05e34db32249e81ac41a22b0974840957 Mon Sep 17 00:00:00 2001 From: beo3000 Date: Sat, 3 Jan 2026 14:21:59 +0100 Subject: [PATCH] K2: add EF configurations for cashbook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - BookingCategoryConfiguration with unique index - CashBookEntryConfiguration with FK relationships - ClubConfiguration: InitialBalance, MonthlyMembershipFee - AppDbContext: BookingCategories, CashBookEntries DbSets 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- docs/IMPLEMENTATION_PLAN.md | 2 +- .../Data/AppDbContext.cs | 4 ++ .../BookingCategoryConfiguration.cs | 58 ++++++++++++++++ .../CashBookEntryConfiguration.cs | 69 +++++++++++++++++++ .../Data/Configurations/ClubConfiguration.cs | 6 ++ 5 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 src/Koogle.Infrastructure/Data/Configurations/BookingCategoryConfiguration.cs create mode 100644 src/Koogle.Infrastructure/Data/Configurations/CashBookEntryConfiguration.cs diff --git a/docs/IMPLEMENTATION_PLAN.md b/docs/IMPLEMENTATION_PLAN.md index a02fb41..6182955 100644 --- a/docs/IMPLEMENTATION_PLAN.md +++ b/docs/IMPLEMENTATION_PLAN.md @@ -1700,7 +1700,7 @@ public enum CashBookEntryType { Income = 0, Expense = 1 } | ☐ | Phase | Bereich | Beschreibung | Dateien | |---|-------|---------|--------------|---------| | ✓ | K1 | Domain | Entities + Enums | 5 | -| ☐ | K2 | Infrastructure | EF Configurations | 4 | +| ✓ | K2 | Infrastructure | EF Configurations | 4 | | ☐ | K3 | Infrastructure | Migration | - | | ☐ | K4 | Security | Kassenwart Role + Policy | 4 | | ☐ | K5 | Infrastructure | Repositories | 5 | diff --git a/src/Koogle.Infrastructure/Data/AppDbContext.cs b/src/Koogle.Infrastructure/Data/AppDbContext.cs index fe28ee7..a4a596c 100644 --- a/src/Koogle.Infrastructure/Data/AppDbContext.cs +++ b/src/Koogle.Infrastructure/Data/AppDbContext.cs @@ -37,6 +37,10 @@ public class AppDbContext : DbContext // Statistics public DbSet PlayerGameStatistics => Set(); + // Cash Book + public DbSet BookingCategories => Set(); + public DbSet CashBookEntries => Set(); + // GIF Celebrations public DbSet ClubGifs => Set(); public DbSet ClubGifRatings => Set(); diff --git a/src/Koogle.Infrastructure/Data/Configurations/BookingCategoryConfiguration.cs b/src/Koogle.Infrastructure/Data/Configurations/BookingCategoryConfiguration.cs new file mode 100644 index 0000000..0623606 --- /dev/null +++ b/src/Koogle.Infrastructure/Data/Configurations/BookingCategoryConfiguration.cs @@ -0,0 +1,58 @@ +using Koogle.Domain.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace Koogle.Infrastructure.Data.Configurations; + +/// +/// EF Core configuration for BookingCategory entity. +/// +public class BookingCategoryConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("BookingCategories"); + + builder.HasKey(x => x.Id); + + builder.Property(x => x.ClubId) + .IsRequired(); + + builder.Property(x => x.Name) + .HasMaxLength(100) + .IsRequired(); + + builder.Property(x => x.Description) + .HasMaxLength(500); + + builder.Property(x => x.CategoryType) + .HasConversion() + .IsRequired(); + + builder.Property(x => x.IsSystemCategory) + .IsRequired(); + + builder.Property(x => x.Color) + .HasMaxLength(7); // #RRGGBB + + builder.Property(x => x.Icon) + .HasMaxLength(50); + + builder.Property(x => x.IsActive) + .IsRequired(); + + builder.HasOne(x => x.Club) + .WithMany(c => c.BookingCategories) + .HasForeignKey(x => x.ClubId) + .OnDelete(DeleteBehavior.NoAction); + + builder.HasAlternateKey(x => new { x.Id, x.ClubId }); + + builder.HasIndex(x => x.ClubId); + builder.HasIndex(x => new { x.ClubId, x.Name }) + .HasFilter("[IsDeleted] = 0") + .IsUnique(); + + builder.HasQueryFilter(x => !x.IsDeleted); + } +} diff --git a/src/Koogle.Infrastructure/Data/Configurations/CashBookEntryConfiguration.cs b/src/Koogle.Infrastructure/Data/Configurations/CashBookEntryConfiguration.cs new file mode 100644 index 0000000..215a682 --- /dev/null +++ b/src/Koogle.Infrastructure/Data/Configurations/CashBookEntryConfiguration.cs @@ -0,0 +1,69 @@ +using Koogle.Domain.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace Koogle.Infrastructure.Data.Configurations; + +/// +/// EF Core configuration for CashBookEntry entity. +/// +public class CashBookEntryConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("CashBookEntries"); + + builder.HasKey(x => x.Id); + + builder.Property(x => x.ClubId) + .IsRequired(); + + builder.Property(x => x.CategoryId) + .IsRequired(); + + builder.Property(x => x.EntryType) + .HasConversion() + .IsRequired(); + + builder.Property(x => x.Amount) + .HasPrecision(10, 2) + .IsRequired(); + + builder.Property(x => x.BookingDate) + .IsRequired(); + + builder.Property(x => x.Comment) + .HasMaxLength(500); + + builder.Property(x => x.ReceiptReference) + .HasMaxLength(100); + + builder.HasOne(x => x.Club) + .WithMany(c => c.CashBookEntries) + .HasForeignKey(x => x.ClubId) + .OnDelete(DeleteBehavior.NoAction); + + builder.HasOne(x => x.Category) + .WithMany(c => c.CashBookEntries) + .HasForeignKey(x => x.CategoryId) + .OnDelete(DeleteBehavior.Restrict); + + builder.HasOne(x => x.Day) + .WithMany() + .HasForeignKey(x => x.DayId) + .OnDelete(DeleteBehavior.SetNull); + + builder.HasOne(x => x.Person) + .WithMany() + .HasForeignKey(x => x.PersonId) + .OnDelete(DeleteBehavior.SetNull); + + builder.HasIndex(x => x.ClubId); + builder.HasIndex(x => x.CategoryId); + builder.HasIndex(x => x.BookingDate); + builder.HasIndex(x => x.DayId); + builder.HasIndex(x => x.PersonId); + + builder.HasQueryFilter(x => !x.IsDeleted); + } +} diff --git a/src/Koogle.Infrastructure/Data/Configurations/ClubConfiguration.cs b/src/Koogle.Infrastructure/Data/Configurations/ClubConfiguration.cs index b2cfe0c..4cd0a38 100644 --- a/src/Koogle.Infrastructure/Data/Configurations/ClubConfiguration.cs +++ b/src/Koogle.Infrastructure/Data/Configurations/ClubConfiguration.cs @@ -29,6 +29,12 @@ public class ClubConfiguration : IEntityTypeConfiguration .HasMaxLength(256) .IsRequired(false); + builder.Property(x => x.InitialBalance) + .HasPrecision(10, 2); + + builder.Property(x => x.MonthlyMembershipFee) + .HasPrecision(10, 2); + builder.HasIndex(x => x.Name); builder.HasIndex(x => x.LoginName);