< Summary - Heimdall API

Information
Class: ArturRios.Heimdall.Data.EntityMaps.ScopeOwnerInvitationDbMap
Assembly: ArturRios.Heimdall.Data
File(s): /home/ci/agent/workspace/heimdall-api-docs_main/app/src/Infrastructure/ArturRios.Heimdall.Data/EntityMaps/ScopeOwnerInvitationDbMap.cs
Line coverage
100%
Covered lines: 30
Uncovered lines: 0
Coverable lines: 30
Total lines: 55
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage
100%
Covered methods: 1
Fully covered methods: 1
Total methods: 1
Method coverage: 100%
Full method coverage: 100%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Configure(...)100%11100%

File(s)

/home/ci/agent/workspace/heimdall-api-docs_main/app/src/Infrastructure/ArturRios.Heimdall.Data/EntityMaps/ScopeOwnerInvitationDbMap.cs

#LineLine coverage
 1using ArturRios.Heimdall.Domain.Entities;
 2using Microsoft.EntityFrameworkCore;
 3using Microsoft.EntityFrameworkCore.Metadata.Builders;
 4
 5namespace ArturRios.Heimdall.Data.EntityMaps;
 6
 7internal static class ScopeOwnerInvitationDbMap
 8{
 9    public static void Configure(this EntityTypeBuilder<ScopeOwnerInvitation> invitation)
 10    {
 11        // An outcome is one of the four, and only an ended row has one; an ended row without one ended by
 12        // expiry (ScopeOwnerInvitationOutcomes).
 413        invitation.ToTable("scope_owner_invitation", table =>
 414        {
 415            table.HasCheckConstraint("ck_scope_owner_invitation_outcome_known", "outcome IS NULL OR outcome BETWEEN 1 AN
 416            table.HasCheckConstraint("ck_scope_owner_invitation_outcome_ends_it", "outcome IS NULL OR ended_at IS NOT NU
 817        });
 18
 19        // Internal bigint Id as the key; PublicId is the reference the API uses (§4.0).
 420        invitation.HasKey(x => x.Id);
 21
 422        invitation.Property(x => x.PublicId).IsRequired();
 423        invitation.HasIndex(x => x.PublicId).IsUnique();
 24
 425        invitation.Property(x => x.CreatedAt).HasDefaultValueSql("now()");
 426        invitation.Property(x => x.ExpiresAt).IsRequired();
 427        invitation.Property(x => x.Outcome).HasColumnType("smallint");
 28
 29        // One unended invitation per scope and invitee (FR-SC-18). An expired row still holds the slot until
 30        // ScopeOwnerInvitations.OpenAsync closes it.
 431        invitation.HasIndex(x => new { x.ScopeId, x.InviteePersonId })
 432            .IsUnique()
 433            .HasFilter("ended_at IS NULL");
 34
 35        // An invitation means nothing once its scope or its invitee is gone (UC-05, UC-10).
 436        invitation.HasOne(x => x.Scope)
 437            .WithMany()
 438            .HasForeignKey(x => x.ScopeId)
 439            .IsRequired()
 440            .OnDelete(DeleteBehavior.Cascade);
 41
 442        invitation.HasOne(x => x.Invitee)
 443            .WithMany()
 444            .HasForeignKey(x => x.InviteePersonId)
 445            .IsRequired()
 446            .OnDelete(DeleteBehavior.Cascade);
 47
 48        // The inviter's removal does not end it: the invitation stands for the scope, not for them.
 449        invitation.HasOne(x => x.InvitedBy)
 450            .WithMany()
 451            .HasForeignKey(x => x.InvitedByPersonId)
 452            .IsRequired(false)
 453            .OnDelete(DeleteBehavior.SetNull);
 454    }
 55}