PyFed (PieFed) Codebase Analysis — Comprehensive Feature Specification

Project: PyFed v1.8.0-dev (PieFed) — Python Flask-based ActivityPub link aggregation platform (Lemmy/Mbin alternative) Codebase Location: /home/user/code/python/pyfedi/ Target: Threadlight — Rust-based single-instance social platform with trust-based governance, credit economy, circles, and community forking


1. Architecture Overview

1.1 Stack

  • Framework: Flask + SQLAlchemy ORM
  • Database: PostgreSQL (primary), SQLite (dev)
  • Cache: Redis, FileSystemCache
  • Queue: Celery + Redis broker
  • Frontend: Jinja2 templates + HTMX + Bootstrap
  • Auth: Flask-Login + JWT + OAuth (Google, Mastodon, Discord)
  • Federation: ActivityPub (custom implementation)
  • Search: sqlalchemy-searchable (TSVector full-text search)

1.2 Directory Layout

pyfedi/
├── app/
│   ├── activitypub/    # Federation logic (actors, routes, signature, util)
│   ├── admin/          # Admin panel (routes, forms, util, constants)
│   ├── api/alpha/      # REST API (FastAPI-backed swagger-documented API)
│   ├── auth/           # Login, registration, OAuth, passkeys, onboarding
│   ├── chat/           # Private messaging
│   ├── community/      # Community management (CRUD, moderation, wiki)
│   ├── dev/            # Developer tools
│   ├── domain/         # Domain management
│   ├── feed/           # Curated feeds (user collections of communities)
│   ├── instance/       # Instance exploration
│   ├── main/           # Home page, global routes, RSS
│   ├── post/           # Post/reply CRUD, voting, bookmarks, embeds
│   ├── search/         # Full-text search
│   ├── tag/            # Tag browsing
│   ├── topic/          # Topic-based community grouping
│   ├── user/           # Profile, settings, filters, blocks
│   ├── shared/         # Shared service layer (tasks, upload, feed, auth, etc.)
│   ├── models.py       # All database models (~4273 lines)
│   ├── utils.py        # Utility functions (~4602 lines)
│   ├── constants.py    # App-wide constants
│   ├── inoculation.py  # Media literacy / anti-radicalization resources
│   └── plugins/        # Plugin system
├── migrations/         # Alembic DB migrations
├── tests/              # Test suite
└── docs/               # Documentation

2. Content Filtering System (Multi-Layered)

2.1 Keyword Filters (Filter Model)

DB Model (app/models.py:3509-3524):

class Filter(db.Model):
    id            = Integer, PK
    title         = String(50)           # User-given name
    filter_home   = Boolean, default=True # Apply to home feed
    filter_posts  = Boolean, default=True # Apply to community posts
    filter_replies = Boolean, default=False # Apply to replies
    hide_type     = Integer, default=0    # 0 = semi-transparent, 1 = hide completely
    user_id       = Integer, FK->User
    expire_after  = Date                  # Optional expiration
    keywords      = String(500)           # Newline-separated keywords

Implementation (app/utils.py:1997-2036):

  • Three cached functions: user_filters_home(), user_filters_posts(), user_filters_replies()
  • Each loads filters where filter_{scope}=True and expire_after > today OR expire_after IS NULL
  • Keywords split by newline, lowercased
  • hide_type == 0 → posts get semi-transparent treatment in templates
  • hide_type == 1 → posts excluded from SQL query (template-level filtering)
  • Result structure: {filter_title: {set_of_keywords}, '-1': {set_of_keywords}} where -1 means “hide completely”

2.2 Content Visibility Settings (User Model)

On User model (app/models.py:959-1078):

Field Type Default Description
hide_nsfw Integer 1 0=show, 1=hide, 2=blur, 3=semi-transparent
hide_nsfl Integer 1 Same scale
hide_gen_ai Integer 2 0=show, 1=hide, 2=label, 3=semi-transparent
ignore_bots Integer 0 0=show, 1=hide completely, 2=blur, 3=semi-transparent
hide_low_quality Boolean false Hide posts from low_quality communities
hide_read_posts Boolean false Hide posts user has already interacted with
read_language_ids ARRAY(Integer) [] Only show content in these languages
community_keyword_filter String(150) ‘’ Hide communities with these words in name

Template-level filtering (app/templates/user/edit_filters.html):

  • hide_type_choices: Show, Hide completely, Blur thumbnail, Make semi-transparent
  • ai_hide_type_choices: Show, Hide completely, Label as AI, Make semi-transparent

2.3 Blocking System (4 Levels)

Block Target DB Model Primary Key Implementation
User UserBlock blocker_id, blocked_id SQL exclusion in feed queries
Community CommunityBlock user_id, community_id SQL exclusion in feed queries
Domain DomainBlock user_id, domain_id Post.domain_id NOT IN blocked_domains()
Instance InstanceBlock user_id, instance_id Post.instance_id NOT IN blocked_instances()

Implementation (app/utils.py:3236-3301):

  • All blocking is applied at the SQL query level in get_deduped_post_ids()
  • Blocked users: p.user_id NOT IN :blocked_accounts
  • Blocked communities: p.community_id NOT IN :blocked_community_ids
  • Blocked domains: (p.domain_id NOT IN :domain_ids OR p.domain_id IS NULL)
  • Blocked instances: (p.instance_id NOT IN :instance_ids OR p.instance_id IS NULL)
  • Cached via @cache.memoize(timeout=300) helper functions

2.4 Flair Blocking (CommunityFlairBlock)

DB Model (app/models.py:4115-4119):

class CommunityFlairBlock(db.Model):
    community_id      = Integer, FK->Community
    community_flair_id = Integer, FK->CommunityFlair
    user_id           = Integer, FK->User

Users can block posts with specific flairs/tags within a community. Applied in get_deduped_post_ids():

p.id NOT IN (SELECT post_id FROM post_flair WHERE flair_id IN :blocked_flair_ids)

3. Vote / Score System

3.1 Vote Models

PostVote (app/models.py:3459-3475):

class PostVote(db.Model):
    id         = Integer, PK
    user_id    = Integer, FK->User     # Who voted
    author_id  = Integer, FK->User     # Post author (reputation target)
    post_id    = Integer, FK->Post
    effect     = Float                 # Vote weight (not just -1/+1)
    emoji      = String(50)            # Emoji reaction
    created_at = DateTime

PostReplyVote (app/models.py:3478-3494): Same structure for comment votes.

Vote effects are floats, enabling weighted voting systems (reputation-weighted, etc., though PyFed uses simple +/-1 in practice with float storage for future).

3.2 Vote Federating / Privacy

Setting Location Effect
federate_votes User setting When false, votes only count locally, not broadcast via ActivityPub
vote_privately User model When true, votes are hidden from other users
show_scores API schema Controls display of aggregate scores
Instance votes_are_public() Instance model Returns True for Lemmy/Mbin/kbin (for compatibility)

3.3 Downvote Controls (Granular)

Site-level (Site.enable_downvotes, Boolean, default=True):

  • Master toggle: if false, no downvoting anywhere on instance

Community-level (Community.downvote_accept_mode, Integer):

DOWNVOTE_ACCEPT_NONE    = -1  # No downvotes allowed
DOWNVOTE_ACCEPT_ALL     = 0   # Anyone can downvote
DOWNVOTE_ACCEPT_MEMBERS = 2   # Only community members
DOWNVOTE_ACCEPT_INSTANCE= 4   # Only users from same instance
DOWNVOTE_ACCEPT_TRUSTED = 6   # Only from trusted instances

User-level restrictions (app/utils.py:1766-1807):

  • Banned users can’t downvote
  • Bot accounts can’t downvote
  • Users with negative attitude (more downvotes than upvotes cast) can’t downvote
  • Users with reputation < -10 can’t downvote
  • Banned from community can’t downvote there

3.4 Vote Quota

  • VOTE_QUOTA config: max 240 votes per day (configurable)
  • votes_cast_today(user_id): Redis counter, resets daily
  • Displayed on user profiles as vote_quota_used

3.5 Reputation & Attitude

User fields:

  • reputation (Float): Accumulated reputation score
  • attitude (Float, -1 to 1): Ratio of (upvotes_cast - downvotes_cast) / total_votes_cast
    • Only calculated after 10+ votes
    • Used to determine if user can downvote

Reputation calculation:

  • Based on recent 50 post votes + 50 comment votes
  • Post authors’ reputation affected by votes on their content
  • Low-quality communities marked with low_quality flag don’t improve reputation

3.6 Reply Visibility Thresholds

Setting Description
reply_collapse_threshold (integer, default=-10) Replies scored at or below this are collapsed
reply_hide_threshold (integer, default=-20) Replies scored at or below this are hidden entirely

Comment sort options: hot, top, new, old


4. Hide Read / Hidden Posts

4.1 Read Posts Tracking

Many-to-many table (read_posts, app/models.py:928-933):

read_posts = db.Table('read_posts',
    db.Column('user_id', Integer, FK->User, PK),
    db.Column('read_post_id', Integer, FK->Post, PK),
    db.Column('interacted_at', DateTime, indexed),
    Index('ix_read_posts_user_post', 'user_id', 'read_post_id')
)

User model relationship:

  • User.read_post: posts the user has read/interacted with
  • Post.read_by: users who have read this post
  • User.hide_read_posts (Boolean): master toggle

Hide Read in Feed Query (app/utils.py:3264-3265):

p.id NOT IN (SELECT read_post_id FROM "read_posts" WHERE user_id = :user_id)

4.2 Hidden Posts

Table (hidden_posts, app/models.py:937-942): Same structure as read_posts.

Always applied (app/utils.py:3268):

p.id NOT IN (SELECT hidden_post_id FROM "hidden_posts" WHERE user_id = :user_id)

Users can manually hide individual posts. These are always excluded from feed.

4.3 Interaction Recording

Interaction is recorded when:

  • A user opens/clicks a post
  • A user upvotes or downvotes a post
  • This powers both hide_read_posts and the “read history” feature

4.4 View Templates

  • user/read_posts.html: shows user’s read post history
  • user/hidden_posts.html: shows hidden posts with unhide option
  • user/_read_posts_nav.html: navigation for read/hidden posts

5. Content Moderation & Governance

5.1 Community Moderation

Community membership levels:

SUBSCRIPTION_OWNER     = 3
SUBSCRIPTION_MODERATOR = 2
SUBSCRIPTION_MEMBER    = 1
SUBSCRIPTION_NONMEMBER = 0
SUBSCRIPTION_PENDING   = -1
SUBSCRIPTION_BANNED    = -2

Moderation tools:

  • Community bans (with reason, optional duration)
  • Post/reply removal
  • Report handling (new → escalated → resolved)
  • Moderation log (audit trail)
  • Content retention policies (auto-delete after N months)
  • Flair management (text/color/blur-images)
  • Wiki management with revision history
  • Mod-only communities

5.2 Report System

Report types (constants.py):

REPORT_TYPE_USER      = 0
REPORT_TYPE_POST      = 1
REPORT_TYPE_REPLY     = 2
REPORT_TYPE_COMMUNITY = 3
REPORT_TYPE_MESSAGE   = 4

Report states: new → escalated → appealed → resolved → discarded

Report reasons (from user/forms.py):

  1. Breaks community rules
  2. Harassment
  3. Threatening violence
  4. Promoting hate/genocide
  5. Minor abuse/sexualization
  6. Sharing personal info (doxing)
  7. Spam
  8. Non-consensual intimate media
  9. Prohibited transaction
  10. Impersonation
  11. Copyright violation
  12. Trademark violation
  13. Self-harm/suicide
  14. Other
  15. Misinformation/disinformation
  16. Racism/sexism/transphobia
  17. Malicious reporting

5.3 Instance-level Controls

Setting Type Description
enable_downvotes Boolean Master downvote toggle
registration_mode String Open / RequireApplication / Closed
application_question Text Question for registration applications
private_instance Boolean Require login to view anything
allow_or_block_list Integer 1=allowlist, 2=blocklist
allowlist_mode Integer 0=weak, 1=strong, 2=intense
blocked_phrases Text Discard incoming content with these phrases
auto_decline_referrers Text Auto-reject registrations from these referrers
honeypot Boolean Bot detection

5.4 Inoculation System

app/inoculation.py contains educational content displayed to users about:

  • Groupthink and cult dynamics
  • Alt-right radicalization pipelines
  • Media literacy
  • Confirmation bias
  • The dark side of upvotes

This is shown at registration and optionally in sidebars — a unique approach to platform responsibility.


6. Custom Feeds & Curated Collections

6.1 Feed System

Feeds are user-curated collections of communities, acting like topic-based aggregations.

Feed model (app/models.py):

  • User-owned (or instance-wide)
  • Can be public or private
  • Auto-follow/auto-leave behavior for subscribing
  • Remote feeds via ActivityPub federation
  • Feeds can have parent-child hierarchy (sub-feeds)

6.2 Topic System

Topics are admin-created groupings of communities with hierarchical structure (Topic model has parent_id).

6.3 Community Features

  • Private communities: Only members can view
  • Local-only communities: No federation
  • Encrypted communities: End-to-end encryption
  • Restricted-to-mods posting: Only moderators can post
  • Question/Answer mode: StackOverflow-style communities (question_answer flag)
  • Default layout: Per-community layout preference
  • Community themes: Visual customization per community
  • Post flairs: Categorization with visual styling (text color, background color, blur images)

7. User Experience & Accessibility

7.1 Themes & Visual

  • 18+ themes including accessibility-focused ones (high contrast, dyslexic font)
  • Font choices: Atkinson Hyperlegible, OpenDyslexic, Inter, Roboto
  • Compact UI modes (3 levels: normal/compact/ultra-compact)
  • Low bandwidth mode (reduces page size)
  • Code syntax highlighting (18 color schemes)
  • Additional CSS injection for users and admins

7.2 Productivity Features

  • Usage limits: max_hours_per_day with configurable change restrictions
  • Vote quota: Limits daily voting to prevent vote manipulation
  • Scheduled posts: Posts with scheduled_for, repeat (daily/weekly/monthly)
  • Post drafts: Posts with status -1 (draft)
  • Bookmarks: Separate for posts and replies
  • Cross-posting: Track cross-posted content across communities
  • User notes: Private notes about other users
  • Keyboard shortcuts: Documented in keyboard_shortcuts.html

7.3 Notification System

Granular notification subscriptions:

  • User follows (when followed user posts)
  • Community posts (new posts in community)
  • Topic posts (new posts in topic communities)
  • Post replies (new top-level comments)
  • Reply replies (replies to your comments)
  • Mentions
  • Private messages
  • Ban/unban notifications
  • New moderator notifications
  • Report updates

8. Key Technical Patterns

8.1 Feed Query Pipeline

The get_deduped_post_ids() function (app/utils.py:3197-3317) is the core query builder:

  1. View filter selection (subscribed/local/popular/all/moderating)
  2. Community source selection
  3. Following user content inclusion (optional)
  4. Content type filters (nsfw, nsfl, ai, bots)
  5. Hide read posts
  6. Hidden posts exclusion
  7. Language filter
  8. Blocked domains/instances/communities/users
  9. Community bans
  10. Flair blocks
  11. Community keyword filter
  12. Sort application (hot/scaled/top/new/active/old)

8.2 Vote Quota Circuit (Redis-based)

def votes_cast_today(user_id):
    num = redis_client.get(f'votes_cast_{date.today()}_{user_id}')
    if num is None: return 0
    return int(num)

8.3 Deduplication Strategy

Cross-posts are tracked via Post.cross_posts (ARRAY of post IDs) and deduplicated in the feed query:

  • Posts with the same URL are grouped
  • Non-bot posts preferred over bot posts
  • Post with most replies preferred
  • Seen posts tracked in seen_before set

9. Features Valuable for Threadlight → Detailed Recommendations

9.1 HIGH VALUE — Direct Port

9.1.1 Multi-Layered Content Filtering System

Why: Threadlight’s goal of encouraging quality engagement requires giving users granular control over their feed.

Recommended implementation:

  • Keyword Filter Set: Named filters with keywords, scope (feed/community/replies), hide_type (dim, hide, blur), and optional expiration. Users can create “spoiler” or “topic avoid” filters.
  • Content Toggles: NSFW, AI-generated, bot content — each with graduated visibility levels (show/dim/hide). This aligns with trust-based governance where communities self-identify content types.
  • Language Filter: Filter feed to languages the user understands.

Why for Threadlight: Single-instance doesn’t need instance blocking, but user-level blocking of communities, users, and content keywords is essential for a healthy social platform. The graduated visibility concept (show → semi-transparent → blur → hide) is more nuanced than binary show/hide.

9.1.2 Hide Read / Voted Posts

Why: Reduces feed fatigue. Users who browse frequently see fresh content.

Recommended implementation:

  • Track post reads, upvotes, and downvotes per user
  • Optional toggle to exclude read/voted posts from feed
  • Separate explicit “hide post” function
  • “Read post history” page for personal reference

Why for Threadlight: With Threadlight’s credit economy, tracking what users have engaged with is already needed. Extending this to feed filtering is a small addition with huge UX benefit.

9.1.3 Reply Collapse/Hide Thresholds

Why: Users collapse/expand replies based on score. This empowers the community to self-moderate without total censorship.

Recommended implementation:

  • User-configurable thresholds for collapsing and hiding replies
  • Default: collapse at -10, hide at -20 (configurable)
  • Works with Threadlight’s credit-based voting system

Why for Threadlight: Perfect fit for trust-based governance. Bad-faith replies don’t need deletion — they just get buried. The threshold approach gives users agency.

9.2 MEDIUM-HIGH VALUE — Adapt with Credit Economy

9.2.1 Downvote Controls (Community-Level)

Why: Communities should decide their own norms around feedback.

Recommended implementation:

  • Site-level master toggle for downvotes
  • Per-circle (community) downvote policy: None / Members only / Trusted only / Everyone
  • User reputation/credit check: only users with positive credit ratio can downvote

Why for Threadlight: The credit economy naturally maps to this. “Who can downvote” becomes a trust function — users with proven good judgment (high credit, positive attitude) earn the right to give negative feedback.

9.2.2 Vote Privacy & Score Visibility

Why: Reduces social pressure and groupthink.

Recommended implementation:

  • federate_votes → adapt to share_votes (share with circle/community or keep private)
  • vote_privatelyhide_my_votes (don’t show my voting activity on my profile)
  • show_scores → configurable per-community, per-post type
  • Vote weighting by user reputation (already using float effect values)

Why for Threadlight: Core to “not promoting outrage”. Hidden scores reduce pile-on voting. Reputation-weighted votes reduce brigading. Makes the credit economy meaningful.

9.2.3 Vote Quota / Daily Limits

Why: Prevents vote manipulation and encourages deliberate engagement.

Recommended implementation:

  • Configurable daily vote budget (e.g., 80 per day)
  • Redis-based counter, resets daily
  • Higher credit users could get larger budgets

Why for Threadlight: The credit economy needs scarcity. Daily vote budgets make each vote meaningful. Could tie quota to credit level (higher credit = more votes/day, aligning incentives).

9.3 MEDIUM VALUE — Community & Trust Features

9.3.1 Community Flairs with User Blocking

Why: Communities can tag posts with flairs; users can block specific flairs.

Recommended implementation:

  • Circle moderators define flairs (e.g., “Politics”, “Venting”, “Humor”, “NSFW”)
  • Flairs have visual styling (text color, background color, optional image blur)
  • Users can block posts with specific flairs (per-circle)
  • Posts auto-assigned flair based on content analysis

Why for Threadlight: Circles (Threadlight’s communities) have diverse content. Flair-blocking lets users curate their experience within a circle without leaving it.

9.3.2 Custom Feeds / Curated Collections

Why: Users can aggregate content across circles.

Recommended implementation:

  • User-created “feeds” that pool posts from selected circles
  • Public/private toggle
  • Auto-follow/auto-leave: subscribing to a feed auto-joins the constituent circles
  • Instance-wide curated feeds (staff-picked)

Why for Threadlight: Threadlight’s “circles” concept makes this natural — feeds become “meta-circles” or collections. Great for onboarding: “Here’s a starter feed of recommended circles.”

9.3.3 Question & Answer Mode

Why: Some circles benefit from StackOverflow-style structured Q&A.

Recommended implementation:

  • Circle-level toggle for Q&A mode
  • Accepted answer feature (NOTIF_ANSWER notification type)
  • Different sorting: unanswered first, accepted answers highlighted

Why for Threadlight: Technical circles, support circles, or knowledge-sharing circles benefit from this. It is a relatively contained feature (circle setting + accepted answer field).

9.3.4 Scheduled / Repeating Posts

Why: For regular content like daily discussions, weekly threads.

Recommended implementation:

  • scheduled_for datetime for future posting
  • repeat mode: daily, weekly, monthly
  • stop_repeating end date
  • Draft queue (status = -1) for pre-written content

Why for Threadlight: Circles with regular events (weekly book club, daily check-in) benefit from automatable posts. Keeps the community engaged with minimal moderation overhead.

9.4 NOTEWORTHY — Quality of Life

9.4.1 Inoculation / Media Literacy Resources

Why: Unique to PyFed — an educational content system shown at registration and in sidebars.

Recommended implementation:

  • Configurable set of links/resources shown during onboarding
  • Topics: critical thinking, media literacy, community guidelines
  • Rotation-based display (different resource each time)

Why for Threadlight: Fits the “bringing people together” mission. Could be integrated into the credit economy (read an inoculation article → earn small credit bonus). Makes Threadlight’s trust-based governance self-reinforcing.

9.4.2 User Notes (Private Labels)

Why: Users can attach private notes to other users visible only to themselves.

Recommended implementation:

  • Simple user_id → target_id → note_text mapping
  • “Apply to all with same username” option (for known trolls across instances — less relevant for single-instance)
  • Displayed on user hover/profile as a subtle note

Why for Threadlight: Lightweight trust tool. “I’ve had good interactions with this person” or “Reminder: this user posted bad-faith content before.” Supports the credit economy by letting users track their own trust signals.

9.4.3 Usage Time Limits

Why: Users can set daily time limit on the platform with configurable change restrictions.

Recommended implementation:

  • max_hours_per_day setting
  • Enforce via session timing or activity tracking
  • Change restriction options: anytime / 1 day / 1 month / 2 months
  • Helps with compulsive usage

Why for Threadlight: Aligns with ethical platform design. If Threadlight aims to be a “quality engagement” platform, helping users manage their time is a strong signal of pro-user values.

9.4.4 Activity Logging (User-Level)

Why: Users can see their voting history, posting patterns, and platform usage.

Recommended implementation:

  • ActivityLog model tracks user activity types
  • Profile charts showing posting/commenting patterns (hour of day, etc.)
  • Recently upvoted/downvoted posts visible on profile

Why for Threadlight: The credit economy needs transparency. Showing users their own activity patterns and vote history reinforces accountability. Could combine with credit statement (“Your votes this week earned/spent X credits”).

9.5 LOWER PRIORITY — Nice to Have

Feature Reason for Lower Priority
Cross-posting detection Useful but complex; not core to Threadlight’s value prop
Bot detection patterns Single-instance has fewer bot problems
PWAs/service workers Nice but separate from social architecture
Pluggable themes Valuable but not transformative
RSS feeds Good for power users but not core
Full-text search Assumed baseline for any social platform
Multiple code highlight themes Low impact on community health

10. Implementation Notes for Rust/Threadlight

10.1 Query Pattern: Layered Feed Filtering

PyFed’s get_deduped_post_ids() demonstrates a composable filter pattern:

1. Source selection   (which communities/circles)
2. Include following  (friends/trusted users)
3. Content filters    (nsfw, ai, bots)
4. Read/explicit hide (interacted posts)
5. Language filter
6. Block list         (users, communities, flairs)
7. Ban list           (community bans)
8. Sort               (hot, top, new, etc.)

Each layer is a SQL WHERE clause. In Rust, this maps cleanly to a builder pattern:

FeedQuery::new()
    .from_circles(user.subscribed_circles())
    .include_following(user.following())
    .filter_nsfw(user.hide_nsfw())
    .hide_read_posts(user.hide_read_posts())
    .exclude_blocked_users(user.blocked_users())
    .language_filter(user.languages())
    .sort(Sort::Hot)
    .build()

10.2 Vote as Float

PyFed stores effect as Float, not just +/-1. For Threadlight’s credit economy:

  • Upvote effect could scale with voter credit: effect = voter.credit_level * base_weight
  • Downvote effect could scale inversely: effect = -(1.0 / voter.credit_level) * base_weight
  • This naturally weights high-credit users’ opinions more heavily

10.3 Redis Counter Pattern for Quotas

// Simple Redis-based daily quota
async fn votes_remaining(user_id: &str, redis: &Client) -> i64 {
    let key = format!("vote_quota:{}:{}", user_id, today());
    let used: i64 = redis.get(&key).unwrap_or(0);
    let max = get_user_quota(user_id); // Higher credit = higher quota
    max - used
}

10.4 Single-Instance Adaptations

Threadlight is single-instance, so skip:

  • Instance federation
  • Remote content fetching
  • Allowlist/blocklist
  • Instance-level admin for other instances

Focus instead on:

  • Circle (community) level governance
  • User-level trust and credit
  • Platform-level defaults and policies

Appendix A: Complete DB Schema Summary (Threadlight-Relevant)

Table Purpose Key Fields
Filter User keyword filters title, filter_home, filter_posts, filter_replies, hide_type, keywords, expire_after
UserBlock Blocked users blocker_id, blocked_id
CommunityBlock Blocked communities user_id, community_id
DomainBlock Blocked domains user_id, domain_id
CommunityFlairBlock Blocked flairs community_id, flair_id, user_id
PostVote Post votes user_id, post_id, effect (Float), emoji
PostReplyVote Comment votes user_id, reply_id, effect (Float)
read_posts Read tracking user_id, post_id, interacted_at
hidden_posts Hidden posts user_id, post_id
CommunityFlair Post categorizations flair, text_color, background_color, blur_images
Community Circle/community downvote_accept_mode, question_answer, private, local_only
User User settings hide_nsfw, hide_nsfl, hide_gen_ai, hide_read_posts, vote_privately, reputation, attitude
UserNote Private user notes user_id, target_id, note
NotificationSubscription Notification prefs user_id, entity_id, type (NOTIF_*)
ModLog Moderation audit user_id, action, target, community_id

Analysis completed: July 25, 2026. PyFed version: 1.8.0-dev.