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
This commit is contained in:
1 parent
51f2c10c6f
commit
31542a181e
9 files changed
+56
-6
No files matched your search
@@ -0,0 +1,26 @@
|
||||
using MongoDB.Entities;
|
||||
|
||||
using PrivaPub.Models.Post;
|
||||
|
||||
namespace PrivaPub.Infrastructure.Data.Migrations
|
||||
{
|
||||
public class _006_unedited_remote_posts_lose_year_one : IMigration
|
||||
{
|
||||
public async Task UpgradeAsync()
|
||||
{
|
||||
var posts = await DB.Default.Find<Post>()
|
||||
.Match(p => p.EditedAt == DateTime.MinValue || p.UpdateDate == DateTime.MinValue || p.Revisions.Any(r => r.EditedAt == DateTime.MinValue))
|
||||
.ExecuteAsync();
|
||||
foreach (var post in posts)
|
||||
{
|
||||
foreach (var revision in post.Revisions.Where(r => r.EditedAt == DateTime.MinValue))
|
||||
revision.EditedAt = post.CreationDate;
|
||||
await DB.Default.Update<Post>().MatchID(post.ID)
|
||||
.Modify(p => p.EditedAt, post.EditedAt == DateTime.MinValue ? null : post.EditedAt)
|
||||
.Modify(p => p.UpdateDate, post.UpdateDate == DateTime.MinValue ? post.CreationDate : post.UpdateDate)
|
||||
.Modify(p => p.Revisions, post.Revisions)
|
||||
.ExecuteAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,19 @@
|
||||
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,
|
||||
|
||||
Reference in new issue
Block a user