Files
indiekit-endpoint-activitypub/views/activitypub-following.njk
Ricardo 84122cc470 feat: batch re-follow system for imported AP accounts
After Mastodon migration, imported accounts exist only locally — no
Follow activities were sent. This adds a gradual background processor
that sends Follow activities to all source:"import" accounts so remote
servers start delivering Create activities to our inbox.

- New batch engine (lib/batch-refollow.js) processes 10 accounts per
  batch with 3s between follows and 30s between batches
- Accept(Follow) inbox listener transitions source to "federation"
  and cleans up tracking fields
- Admin API: pause, resume, and status JSON endpoints
- Dashboard progress bar with Alpine.js polling (10s interval)
- Following list badges for refollow:sent and refollow:failed states
- Restart recovery resets stale refollow:pending back to import
- 3 retries with 1-hour cooldown before permanent failure
2026-02-20 08:10:45 +01:00

33 lines
1.3 KiB
Plaintext

{% extends "document.njk" %}
{% from "heading/macro.njk" import heading with context %}
{% from "card/macro.njk" import card with context %}
{% from "prose/macro.njk" import prose with context %}
{% from "badge/macro.njk" import badge with context %}
{% from "pagination/macro.njk" import pagination with context %}
{% block content %}
{{ heading({ text: followingCount + " " + __("activitypub.following"), level: 1, parent: { text: __("activitypub.title"), href: mountPath } }) }}
{% if following.length > 0 %}
{% for account in following %}
{{ card({
title: account.name or account.handle or account.actorUrl,
url: account.actorUrl,
description: { text: "@" + account.handle if account.handle },
published: account.followedAt,
badges: [{
text: __("activitypub.sourceImport") if account.source === "import"
else __("activitypub.sourceRefollowPending") if account.source === "refollow:sent"
else __("activitypub.sourceRefollowFailed") if account.source === "refollow:failed"
else __("activitypub.sourceFederation")
}]
}) }}
{% endfor %}
{{ pagination(cursor) if cursor }}
{% else %}
{{ prose({ text: __("activitypub.noFollowing") }) }}
{% endif %}
{% endblock %}