FEAT-13: SaleContract + BreederSettings entities (additive migration, join table justified in code docs), /contracts + /settings/breeder-profile Minimal-API endpoints w/ Abgabe-completion transaction + SQLite-backed endpoint round-trip tests (21/21)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-06 07:23:06 +02:00
parent adea82a0e7
commit daa6683405
13 changed files with 1933 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
using System.ComponentModel.DataAnnotations;
namespace GerbilManagerWebAPI.Models
{
/// <summary>
/// Zuchtprofil (Verkäufer-Block der Abgabeverträge) — Einzelzeilen-Entity
/// (Singleton, fixe Id, leer geseedet). Die Züchterin pflegt ihre Daten in
/// der App unter /einstellungen statt in einer JSON-Datei; FEAT-13 phase B
/// ersetzt damit die appsettings-Variante aus phase A.
/// </summary>
public class BreederSettings
{
/// <summary>Fixe Id der einzigen Zeile (per HasData geseedet).</summary>
public static readonly Guid SingletonId = new("11111111-1111-1111-1111-000000000001");
[Key]
public Guid Id { get; set; }
public string ZuchtName { get; set; } = "";
/// <summary>Vor- und Nachname inkl. Anrede, z. B. „Frau Erika Muster“.</summary>
public string Name { get; set; } = "";
/// <summary>Anschrift einzeilig: „Straße Nr, PLZ Ort“.</summary>
public string Address { get; set; } = "";
public string Phone { get; set; } = "";
public string Email { get; set; } = "";
public string Homepage { get; set; } = "";
/// <summary>Ort für die Unterschriftszeile („{Ort}, den {Datum}“).</summary>
public string City { get; set; } = "";
}
}

View File

@@ -0,0 +1,45 @@
using System.ComponentModel.DataAnnotations;
namespace GerbilManagerWebAPI.Models
{
/// <summary>
/// Ein erzeugter Abgabevertrag (FEAT-13). Die .docx liegt wie die Fotos im
/// Datei-Root (Contracts:RootPath bzw. contract-storage/), in der DB steht
/// nur der Dateiname. Tiere hängen über <see cref="SaleContractAnimal"/>
/// (Join-Entity statt uuid[]-Spalte: referenzielle Integrität, „Verträge
/// eines Tieres“ bleibt abfragbar, und pro Tier-Zeile ist später Platz für
/// Zusatzdaten wie den Einzelpreis).
/// </summary>
public class SaleContract
{
[Key]
public Guid Id { get; set; }
/// <summary>Abnehmer (Käufer-Block des Vertrags).</summary>
public Guid ContactId { get; set; }
public Contact? Contact { get; set; }
/// <summary>Kaufpreis in Euro (gesamt).</summary>
public decimal Price { get; set; }
public DateOnly HandoverDate { get; set; }
/// <summary>Datum der Unterschriftszeile (Standard: Übergabedatum).</summary>
public DateOnly ContractDate { get; set; }
/// <summary>Dateiname der erzeugten .docx im Vertrags-Dateiroot.</summary>
public required string FileName { get; set; }
public DateTimeOffset CreatedAt { get; set; }
public List<SaleContractAnimal> Animals { get; set; } = [];
}
/// <summary>Join-Zeile Vertrag ↔ Tier (zusammengesetzter Schlüssel).</summary>
public class SaleContractAnimal
{
public Guid SaleContractId { get; set; }
public Guid GerbilId { get; set; }
public Gerbil? Gerbil { get; set; }
}
}