Add per-app ActivityPub actors via shared AP blueprint

Each AP-enabled app (blog, market, events, federation) now serves its
own webfinger, actor profile, inbox, outbox, and followers endpoints.
Per-app actors are virtual projections of the same ActorProfile/keypair,
scoped by APFollower.app_domain and APActivity.origin_app.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
giles
2026-02-23 19:02:30 +00:00
parent 001cbffd74
commit f2262f702b
10 changed files with 1087 additions and 35 deletions

View File

@@ -176,6 +176,7 @@ class APFollowerDTO:
follower_inbox: str
follower_actor_url: str
created_at: datetime | None = None
app_domain: str | None = None
@dataclass(frozen=True, slots=True)

View File

@@ -222,6 +222,7 @@ class FederationService(Protocol):
async def get_outbox(
self, session: AsyncSession, username: str,
page: int = 1, per_page: int = 20,
origin_app: str | None = None,
) -> tuple[list[APActivityDTO], int]: ...
async def get_activity_for_source(
@@ -236,6 +237,7 @@ class FederationService(Protocol):
# -- Followers ------------------------------------------------------------
async def get_followers(
self, session: AsyncSession, username: str,
app_domain: str | None = None,
) -> list[APFollowerDTO]: ...
async def get_followers_paginated(
@@ -247,10 +249,12 @@ class FederationService(Protocol):
self, session: AsyncSession, username: str,
follower_acct: str, follower_inbox: str, follower_actor_url: str,
follower_public_key: str | None = None,
app_domain: str | None = None,
) -> APFollowerDTO: ...
async def remove_follower(
self, session: AsyncSession, username: str, follower_acct: str,
app_domain: str | None = None,
) -> bool: ...
# -- Remote actors --------------------------------------------------------