···4545{
4646 private const int DefaultRecursionLimit = 100;
47474848+ // https://misskey-hub.net/en/tools/aid-converter/
4949+ // this seems to be the timestamp for 'zzzzzzzzzzzzzzzz'. anything newer i would expect something to break
5050+ private static DateTime _scheduleIdTimeLimit = new DateTime(2089, 05, 24);
5151+4852 private static readonly AsyncKeyedLocker<string> KeyedLocker = new(o =>
4953 {
5054 o.PoolSize = 100;
···276280 throw GracefulException.UnprocessableEntity("Refusing to create a pure renote reply");
277281 }
278282279279- var noteId = data.Preview ? "preview" : IdHelpers.GenerateSnowflakeId(data.CreatedAt);
283283+ // we need the note ids to sort correctly, but we also don't want to limit clients to a specific time
284284+ // as some clients have "drafts" that are posts scheduled for absurd years. let's assume that if you're scheduling
285285+ // something like that you don't care where it'll be sorted (not that we'll *actually* schedule it anyways, see ScheduleNoteAsync)
286286+ var idTimestamp = data.ScheduledAt != null && data.ScheduledAt < _scheduleIdTimeLimit
287287+ ? data.ScheduledAt
288288+ : data.CreatedAt;
289289+290290+ var noteId = data.Preview ? "preview" : IdHelpers.GenerateSnowflakeId(idTimestamp);
280291 var threadId = data.Reply?.ThreadId ?? noteId;
281292282293 var context = data.ASNote?.Context;