Server locations: no user threshold

The public projection of a server's place showed only the country for
servers reporting fewer than 10 users. The owner never decided that
threshold: every located server now shows its city, coordinates (0.1°)
and network, and a CDN-fronted one still shows only its CDN, since the
address reached is the CDN's edge. Statistics:PublicCityMinUsers is
gone; the ROADMAP decision on server locations, CLAUDE.md and the
/stargazing explainer are corrected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
thepraandClaude Opus 5.5 committed 2026-10-04 11:12:02 +02:00
1 parent 31d1d21d1e
commit eb7552e8f3
9 files changed
+56 -57

No files matched your search

@@ -10,7 +10,6 @@ using PrivaPub.Domain.Statistics;
using PrivaPub.Federation.Actors;
using PrivaPub.Federation.Objects;
using PrivaPub.Infrastructure;
using PrivaPub.Infrastructure.Statistics;
using PrivaPub.Models.Federation;
using PrivaPub.Models.Jobs;
using PrivaPub.Models.Post;
@@ -29,16 +28,14 @@ namespace PrivaPub.Api.Mastodon.Controllers
readonly DbEntities _dbEntities;
readonly ISelfLocation _self;
readonly ILocalActorService _localActors;
readonly IOptionsMonitor<StatisticsOptions> _statistics;
readonly IOptionsMonitor<RegistrationOptions> _registrations;
public ProvenanceController(DbEntities dbEntities, ISelfLocation self, ILocalActorService localActors,
IOptionsMonitor<StatisticsOptions> statistics, IOptionsMonitor<RegistrationOptions> registrations)
IOptionsMonitor<RegistrationOptions> registrations)
{
_dbEntities = dbEntities;
_self = self;
_localActors = localActors;
_statistics = statistics;
_registrations = registrations;
}
@@ -83,15 +80,14 @@ namespace PrivaPub.Api.Mastodon.Controllers
if (host == selfHost)
described.Add(await DescribeSelf(host, token));
else if (remote.FirstOrDefault(i => i.Host == host) is { } instance)
described.Add(Describe(instance, _statistics.CurrentValue.PublicCityMinUsers));
described.Add(Describe(instance));
}
return described;
}
async Task<InstanceDescription> DescribeSelf(string host, CancellationToken token)
{
var (geo, configured) = await _self.Get(token);
var users = await Counted.Users(token);
var geo = await _self.Get(token);
return new InstanceDescription
{
Host = host,
@@ -101,13 +97,11 @@ namespace PrivaPub.Api.Mastodon.Controllers
Protocols = new() { "activitypub" },
OpenRegistrations = _registrations.CurrentValue.IsOpen,
DescribedAt = MastodonJson.Time(DateTime.UtcNow),
Geo = configured
? Located(new PublicLocation(geo.Country, geo.City, geo.Latitude, geo.Longitude, default, default), geo)
: Located(PublicGeo.Project(new RemoteInstance { Geo = geo, UsersTotal = users }, _statistics.CurrentValue.PublicCityMinUsers), geo)
Geo = Located(PublicGeo.Project(geo), geo)
};
}
//the public projection of a server's place (owner decision on server locations, ROADMAP 2026-10-03)
//the public projection of a server's place (PublicGeo)
static InstanceLocation Located(PublicLocation location, InstanceGeo geo) => location == default ? default : new InstanceLocation
{
Precision = location.Cdn != default ? "cdn" : location.Latitude != default ? "city" : "country",
@@ -158,11 +152,11 @@ namespace PrivaPub.Api.Mastodon.Controllers
RawHash = r.RawHash,
Raw = r.Raw == default ? default : JsonNode.Parse(r.Raw)
}).ToList() ?? new(),
Instance = instance == default ? default : Describe(instance, _statistics.CurrentValue.PublicCityMinUsers)
Instance = instance == default ? default : Describe(instance)
};
}
static InstanceDescription Describe(RemoteInstance instance, int minUsers) => new()
static InstanceDescription Describe(RemoteInstance instance) => new()
{
Host = instance.Host,
Software = instance.Software,
@@ -180,7 +174,7 @@ namespace PrivaPub.Api.Mastodon.Controllers
LastSuccessAt = instance.LastSuccessAt is { } success ? MastodonJson.Time(success) : default,
LastFailureAt = instance.LastFailureAt is { } failure ? MastodonJson.Time(failure) : default
},
Geo = Located(PublicGeo.Project(instance, minUsers), instance.Geo)
Geo = Located(PublicGeo.Project(instance.Geo), instance.Geo)
};
public class Provenance
@@ -246,7 +240,8 @@ namespace PrivaPub.Api.Mastodon.Controllers
public InstanceLocation Geo { get; set; }
}
//precision: "city" (coordinates to 0.1°, city and network), "country" (the country only) or "cdn" (the CDN's name only)
//precision: "city" (coordinates to 0.1°, city and network), "country" (located only to a country) or "cdn" (the
//CDN's name only)
public class InstanceLocation
{
public string Precision { get; set; }