Files
SocialPub/PrivaPub/Infrastructure/Ids/PrivacyIds.cs
T
thepraandClaude Opus 5.5 31542a181e Remote posts take their timeline place on arrival, and an unedited one has no edit date
Found by the first live run against GoToSocial:

- A remote post's id came from its published second plus random bytes, so a reply arriving in the same second as
  the post it answers could sort under it, and a late arrival landed behind a client's since_id. A post published
  within the last hour now gets an id for its arrival; backfill keeps its published time.
- NoteParser.Time returned default(DateTime) for a missing "updated", so every remote post was stored as edited in
  year one. Migration _006 clears the stored ones.
- published now carries milliseconds, so peers that derive ids from it (GoToSocial, Mastodon) keep our posts in
  order within a second.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012CzABvBkbcFqoHdmi8b9WB
2026-10-01 13:19:16 +02:00

28 lines
945 B
C#

using System.Buffers.Binary;
using System.Security.Cryptography;
using MongoDB.Bson;
namespace PrivaPub.Infrastructure.Ids
{
public static class PrivacyIds
{
public static string ForDay(DateTime when) => At(DateTime.SpecifyKind(when, DateTimeKind.Utc).Date);
public static string Arrived(DateTime published) =>
DateTime.SpecifyKind(published, DateTimeKind.Utc) > DateTime.UtcNow - LiveWindow ? ObjectId.GenerateNewId().ToString() : At(published);
static readonly TimeSpan LiveWindow = TimeSpan.FromHours(1);
public static string At(DateTime when)
{
var seconds = Math.Clamp(new DateTimeOffset(DateTime.SpecifyKind(when, DateTimeKind.Utc)).ToUnixTimeSeconds(), 0,
DateTimeOffset.UtcNow.AddDays(1).ToUnixTimeSeconds());
Span<byte> bytes = stackalloc byte[12];
BinaryPrimitives.WriteInt32BigEndian(bytes, (int)seconds);
RandomNumberGenerator.Fill(bytes[4..]);
return Convert.ToHexStringLower(bytes);
}
}
}