angee.social.managers
Managers that own the social write path and its chainable read scopes.
Following the repo's Manager/QuerySet canon (storage.FileQuerySet/FileManager via from_queryset; the very split the messaging ORM review flagged as H3): read predicates are chainable scopes on a *QuerySet; the managers own the writes. The feed-ingest overlay reuses messaging.Message.objects.ingest for the message core, and per-actor reactions reuse the single messaging.Reaction table, so these managers own only the remaining social layer — engagement counts, following, and the per-account API quota ledger.
FeedFollowQuerySet
class FeedFollowQuerySet(AngeeQuerySet[Any])REBAC-scoped read scopes for the following/timeline edge.
active
def active() -> FeedFollowQuerySetReturn open follows (never ended).
for_handle
def for_handle(handle: Any) -> FeedFollowQuerySetReturn the follows a given handle subscribes through.
for_feed
def for_feed(feed: Any) -> FeedFollowQuerySetReturn the follows subscribed to a given feed.
FeedFollowManager
class FeedFollowManager(RebacManager.from_queryset(FeedFollowQuerySet))Owns the follow/unfollow writes over the (feed, handle) subscription.
follow
def follow(*, feed: Any, handle: Any, owner_id: Any = None) -> AnyOpen (or re-open) the follow of feed by handle; idempotent.
unfollow
def unfollow(*, feed: Any, handle: Any) -> intClose the open follow of feed by handle; returns rows closed.
PostMetricsManager
class PostMetricsManager(AngeeManager)Owns the one-to-one engagement-counter upsert for a message.
upsert
def upsert(*, message: Any, metrics: Any, owner_id: Any = None) -> AnyWrite the rolled-up engagement counters for message (idempotent).
metrics is a :class:~angee.social.backends.ParsedMetrics. Counters are a platform-reported snapshot, so the latest fetch overwrites the row — no F() delta (unlike thread counters, which the ingest owner increments).
QuotaQuerySet
class QuotaQuerySet(AngeeQuerySet[Any])REBAC-scoped read scopes for the per-handle, per-platform API budget.
for_handle
def for_handle(handle: Any) -> QuotaQuerySetReturn the quota ledgers of one handle.
current
def current(*, platform: str, now: datetime) -> QuotaQuerySetReturn the ledger rows whose period contains now for platform.
QuotaManager
class QuotaManager(RebacManager.from_queryset(QuotaQuerySet))Owns the API-unit ledger: opening a period and atomic consumption.
A backend calls :meth:consume before spending platform API units; enforcement is advisory (the caller must ask). Cost tables / safety margins live with the source backend that knows its API, not here.
open_period
def open_period(*,
handle: Any,
platform: str,
limit: int,
now: datetime | None = None,
window: timedelta | None = None) -> AnyReturn the current ledger row for (handle, platform), opening one if due.
consume
def consume(*,
handle: Any,
platform: str,
units: int,
limit: int,
now: datetime | None = None) -> boolAtomically consume units from the current period; False if it would exceed.
Bumps quota_used with an F() delta under a row lock so concurrent spenders never lose an increment, and refuses (leaving the ledger untouched) when the budget is insufficient.