• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

curt / Viae / 19527137380

20 Nov 2025 05:53AM UTC coverage: 51.56%. First build
19527137380

push

github

web-flow
feat: provide minimal locus and vestigium views (#1)

62 of 109 branches covered (56.88%)

Branch coverage included in aggregate %.

500 of 981 new or added lines in 61 files covered. (50.97%)

500 of 981 relevant lines covered (50.97%)

19.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/endpoint/src/Viae.Persistence/UriGenerationInterceptor.cs
1
// Copyright © 2025 Curt Gilman
2
// SPDX-License-Identifier: AGPL-3.0-only
3
// Viae: A geo-centric, journey-focused, federated blog platform
4

5
using Microsoft.EntityFrameworkCore;
6
using Microsoft.EntityFrameworkCore.Diagnostics;
7
using Viae.Domain.Models;
8
using Viae.Persistence.Generators;
9

10
namespace Viae.Persistence;
11

12
/// <summary>
13
/// EF Core interceptor that automatically generates URIs for IUriIdentifiable entities
14
/// during SaveChanges, after IDs have been generated but before saving to the database.
15
/// </summary>
16
/// <remarks>
17
/// Initializes a new instance of the <see cref="UriGenerationInterceptor"/> class.
18
/// </remarks>
19
/// <param name="uriGenerator">The URI generator service.</param>
NEW
20
public class UriGenerationInterceptor(IUriGeneratorService uriGenerator) : SaveChangesInterceptor
×
21
{
22
    /// <inheritdoc />
23
    public override InterceptionResult<int> SavingChanges(
24
        DbContextEventData eventData,
25
        InterceptionResult<int> result
26
    )
27
    {
NEW
28
        GenerateUris(eventData.Context);
×
NEW
29
        return base.SavingChanges(eventData, result);
×
30
    }
31

32
    /// <inheritdoc />
33
    public override ValueTask<InterceptionResult<int>> SavingChangesAsync(
34
        DbContextEventData eventData,
35
        InterceptionResult<int> result,
36
        CancellationToken cancellationToken = default
37
    )
38
    {
NEW
39
        GenerateUris(eventData.Context);
×
NEW
40
        return base.SavingChangesAsync(eventData, result, cancellationToken);
×
41
    }
42

43
    private void GenerateUris(DbContext? context)
44
    {
NEW
45
        if (context == null)
×
46
        {
NEW
47
            return;
×
48
        }
49

50
        // Ensure all pending changes are detected
NEW
51
        context.ChangeTracker.DetectChanges();
×
52

53
        // Get all Added IUriIdentifiable entities that don't have URIs yet
NEW
54
        var entries = context
×
NEW
55
            .ChangeTracker.Entries<IUriIdentifiable>()
×
NEW
56
            .Where(e => e.State == EntityState.Added && e.Entity.Uri == null)
×
NEW
57
            .ToList(); // Materialize to avoid collection modified during iteration
×
58

NEW
59
        foreach (var entry in entries)
×
60
        {
61
            // The ID should have been generated when the entity was added
62
            // Check if it's been set
NEW
63
            var id = entry.Entity.Id;
×
64

65
            // If still empty, generate ID manually
66
            // EF Core InMemory doesn't always trigger value generators at the right time
NEW
67
            if (string.IsNullOrEmpty(id))
×
68
            {
69
                // Generate ID using the same generator
NEW
70
                id = Base58IdGenerator.Generate();
×
NEW
71
                entry.Entity.Id = id;
×
72

73
                // Mark the ID property as modified so EF Core knows to save it
NEW
74
                entry.Property(nameof(IIdentifiable.Id)).IsModified = true;
×
75
            }
76

77
            // Generate URI based on entity type
NEW
78
            var uri = entry.Entity switch
×
NEW
79
            {
×
NEW
80
                Admissio admissio => uriGenerator.GenerateUri(admissio),
×
NEW
81
                Adreflexio adreflexio => uriGenerator.GenerateUri(adreflexio),
×
NEW
82
                _ => throw new NotSupportedException(
×
NEW
83
                    $"URI generation not supported for type {entry.Entity.GetType().Name}"
×
NEW
84
                ),
×
NEW
85
            };
×
86

NEW
87
            entry.Entity.Uri = uri;
×
88
            // Mark the URI property as modified
NEW
89
            entry.Property(nameof(IUriIdentifiable.Uri)).IsModified = true;
×
90
        }
NEW
91
    }
×
92
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc