FEAT-1b: Inzuchtkoeffizient endpoints via Wright path method

- PedigreeCalculator: pure, EF-free Wright path-method engine (recursive F_A,
  per-common-ancestor contributions, generationsAvailable, cycle guards)
- InbreedingService: loads pedigree from ApplicationContext shadow FKs
  (Gerbils.LitterId, Litters.FatherId/MotherId) into in-memory maps
- InbreedingController: GET /gerbils/{id}/inbreeding-coefficient,
  POST /genetics/test-inbreeding (hypothetical pairing for Probeverpaarung)
- Injects ApplicationContext directly; no Program.cs change (Dwight owns it)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-06 00:10:19 +02:00
parent bca97ed10a
commit 0c94a6ecd3
5 changed files with 366 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
namespace GerbilManagerWebAPI.Genetics
{
/// <summary>
/// Result of an inbreeding-coefficient (Inzuchtkoeffizient) calculation for an
/// individual or a hypothetical pairing.
/// </summary>
/// <param name="Coefficient">Wright's inbreeding coefficient F, in the range 0..1.</param>
/// <param name="Percent">The coefficient expressed as a percentage (F * 100).</param>
/// <param name="GenerationsAvailable">
/// The deepest generation of known ancestry above the individual (parents = 1,
/// grandparents = 2, …). 0 when no parents are recorded.
/// </param>
/// <param name="CommonAncestors">
/// The ancestors common to both parents, each with its additive contribution to F,
/// ordered by contribution descending. Empty when there is no inbreeding.
/// </param>
public record InbreedingResult(
double Coefficient,
double Percent,
int GenerationsAvailable,
IReadOnlyList<CommonAncestorContribution> CommonAncestors);
/// <summary>A single common ancestor and how much it contributes to F.</summary>
public record CommonAncestorContribution(Guid Id, string Name, double Contribution);
}