sojorn/sojorn_docs/TODO.md

11 KiB

Sojorn Development TODO

Last Updated: February 7, 2026


🎯 High Priority — Feature Work

1. Finalize AI Moderation — Image & Video

Status: In Progress
Text moderation is live (OpenAI Moderation API). Image and video moderation not yet implemented.

  • Add image moderation to post creation flow (send image to OpenAI or Vision API)
  • Add video moderation via thumbnail extraction (grab first frame or key frame)
  • Run extracted thumbnail through same image moderation pipeline
  • Flag content that exceeds thresholds into moderation_flags table
  • Wire into existing Three Poisons scoring (Hate, Greed, Delusion)
  • Add admin queue visibility for image/video flags

Backend: go-backend/internal/handlers/post_handler.go (CreatePost flow)
Key decision: Use OpenAI Vision API for images, ffmpeg thumbnail extraction for video on the server side


2. Quips — Complete Video Recorder & Editor Overhaul

Status: Needs major work
Current recorder is basic. Goal: TikTok/Instagram-level recording and editing experience.

  • Multi-segment recording with pause/resume
  • Speed control (0.5x, 1x, 2x, 3x)
  • Filters and effects (color grading, beauty mode)
  • Text overlays with timing and positioning
  • Music/audio overlay from library or device
  • Trim and reorder clips
  • Transitions between segments
  • Preview before posting
  • Progress indicator during upload
  • Thumbnail selection for posted quip

Frontend: sojorn_app/lib/screens/quips/create/
Packages to evaluate: camera, ffmpeg_kit_flutter, video_editor


3. Beacon Page Overhaul — Local Safety & Social Awareness

Status: Basic beacon system exists (post, vouch, report). Needs full redesign.
Vision: Citizen + Nextdoor but focused on social awareness over fear-mongering.

  • Redesign beacon feed as a local safety dashboard
  • Map view with clustered pins (incidents, community alerts, mutual aid)
  • Beacon categories: Safety Alert, Community Need, Lost & Found, Event, Mutual Aid
  • Verified/official source badges for local orgs
  • "How to help" action items on each beacon (donate, volunteer, share)
  • Tone guidelines — auto-moderate fear-bait and rage-bait language
  • Neighborhood/radius filtering
  • Push notifications for nearby beacons (opt-in)
  • Confidence scoring visible to users (vouch/report ratio)
  • Resolution status (active → resolved → archived)

Backend: go-backend/internal/handlers/post_handler.go (beacon endpoints)
Frontend: sojorn_app/lib/screens/beacons/


⚠️ Medium Priority — Core Features

4. User Profile Customization — Modular Widget System

Status: Basic profiles exist. Needs a modular, personalized approach.
Vision: New-age MySpace — users pick and arrange profile widgets to make it their own, without chaos.

Core Architecture:

  • Profile is a grid/stack of draggable widgets the user can add, remove, and reorder
  • Each widget is a self-contained component with a fixed max size and style boundary
  • Widgets render inside a consistent design system (can't break the layout or go full HTML)
  • Profile data stored as a JSON profile_layout column: ordered list of widget types + config

Standard Fields (always present):

  • Avatar + display name + handle (non-removable header)
  • Bio (rich text, links, emoji)
  • Pronouns field
  • Location (optional, city-level)

Widget Catalog (user picks and arranges):

  • Pinned Posts — Pin up to 3 posts to the top of your profile
  • Music Widget — Currently listening / favorite track (Spotify/Apple Music embed or manual)
  • Photo Grid — Mini gallery (3-6 featured photos from uploads)
  • Social Links — Icons row for external links (site, GitHub, IG, etc.)
  • Causes I Care About — Tag-style badges (environment, mutual aid, arts, etc.)
  • Featured Friends — Highlight 3-6 people (like MySpace Top 8 but chill)
  • Stats Widget — Post count, follower count, member since (opt-in)
  • Quote Widget — A single styled quote / motto
  • Beacon Activity — Recent community contributions
  • Custom Text Block — Markdown-rendered freeform section

Theming (constrained but expressive):

  • Accent color picker (applies to profile header, widget borders, link color)
  • Light/dark/auto profile theme (independent of app theme)
  • Banner image (behind header area)
  • Profile badges (verified, early adopter, community helper — system-assigned)

Implementation:

  • Backend: profile_layout JSONB column on profiles table
  • Backend: PUT /profile/layout endpoint to save widget arrangement
  • Frontend: ProfileWidgetRenderer that reads layout JSON and renders widget stack
  • Frontend: ProfileEditor with drag-to-reorder and add/remove widget catalog
  • Widget sandboxing — each widget has max height, no custom CSS/HTML injection
  • Default layout for new users (bio + social links + pinned posts)

5. Blocking System

Status: Basic block exists. Import/export not implemented.

  • Verify block prevents: seeing posts, DMs, mentions, search results, follow
  • Block list management screen (view, unblock)
  • Export block list as JSON/CSV
  • Import block list from JSON/CSV
  • Import block list from other platforms (Twitter/X format, Mastodon format)
  • Blocked users cannot see your profile or posts
  • Silent block (user doesn't know they're blocked)

Frontend: sojorn_app/lib/screens/profile/blocked_users_screen.dart
Backend: go-backend/internal/handlers/user_handler.go


6. E2EE Chat Stability & Sync

Status: X3DH implementation works but key sync across devices is fragile.

  • Audit key recovery flow — ensure it reliably recovers from MAC errors
  • Device-to-device key sync without storing plaintext on server
  • QR code key verification between users
  • "Encrypted with old keys" messages should offer re-request option
  • Clean up forceResetBrokenKeys() dead code in simple_e2ee_service.dart
  • Ensure cloud backup/restore cycle works end-to-end
  • Add key fingerprint display in chat settings
  • Rate limit key recovery to prevent loops

7. Repost / Boost Feature

Status: Not started.
A "repost" action that amplifies content to your followers without quote-posting.

  • Repost button on posts (share to your followers' feeds)
  • Repost count displayed on posts
  • Reposted-by attribution in feed ("@user reposted")
  • Undo repost
  • Backend: reposts table (user_id, post_id, created_at)
  • Feed algorithm weights reposts into feed ranking

8. Algorithm Refactor — Promote Good, Discourage Anger

Status: Basic algorithm exists in algorithm_config table. Needs philosophical overhaul.
Core principle: Show users what they love, not what they hate.

  • Engagement scoring that weights positive interactions (save, repost, thoughtful reply) over rage-clicks
  • De-rank content with high negative-reaction ratios
  • "Cooling period" — delay viral anger content by 30min before amplifying
  • Boost content tagged as good news, community, mutual aid, creativity
  • User-controllable feed preferences ("show me more of X, less of Y")
  • Diversity injection — prevent echo chambers by mixing in adjacent-interest content
  • Transparency: show users why a post appeared in their feed
  • Admin algorithm tuning panel (already built in admin dashboard)
  • A/B testing framework for algorithm changes

🔧 Low Priority — Polish & Cleanup

9. Remaining Code TODOs

Small scattered items across the codebase:

  • sojorn_rich_text.dart — Implement profile navigation from @mentions
  • post_with_video_widget.dart — Implement post options menu (edit, delete, report)
  • video_player_with_comments.dart — Implement "more options" button
  • sojorn_swipeable_post.dart — Wire up allowChain setting when API supports it
  • reading_post_card.dart — Implement share functionality

10. Legacy Cleanup

  • Delete go-backend/cmd/supabase-migrate/ directory (dead migration tool)
  • Update 2 stale Supabase comments in go-backend/internal/middleware/auth.go
  • Remove forceResetBrokenKeys() from simple_e2ee_service.dart

Completed

Core Platform (shipped)

  • Go backend — 100% migrated from Supabase
  • User auth (JWT, refresh tokens, email verification)
  • Posts (create, edit, delete, visibility, chains)
  • Comments (threaded, with replies)
  • Feed algorithm (basic version)
  • Image/video uploads to Cloudflare R2
  • Follow/unfollow system
  • Search (users, posts, hashtags)
  • Categories and user settings
  • Chain posts
  • Beacon voting (vouch, report, remove vote)
  • E2EE chat (X3DH, key backup/restore)
  • Push notifications (FCM)
  • Quips (basic video recording and feed)

Admin & Moderation (shipped)

  • Admin panel (Next.js dashboard, users, posts, moderation queue, appeals)
  • OpenAI text moderation (auto-flag on post/comment creation)
  • Three Poisons scoring (Hate, Greed, Delusion)
  • Ban/suspend system with content jailing
  • Email notifications (ban, suspend, restore, content removal)
  • Moderation queue with dismiss/action/ban workflows
  • User violation tracking and history
  • IP-based ban evasion detection

Infrastructure (shipped)

  • PostgreSQL with full schema
  • Cloudflare R2 media storage
  • Nginx reverse proxy + SSL/TLS
  • Systemd service management
  • GeoIP for location features
  • Automated deploy scripts

NSFW Moderation System (Feb 7, 2026)

  • AI moderation prompt: Cinemax nudity rule, violence 1-10 scale (≤5 allowed)
  • Three-outcome moderation: clean / nsfw (auto-label + warn) / flag (remove + appeal email)
  • DB: nsfw_blur_enabled column on user_settings
  • Backend: is_nsfw/nsfw_reason returned from ALL post queries (feed, profile, detail, saved, liked, chain, focus context)
  • Backend: NSFW posts excluded from search, discover, trending, hashtag pages
  • Backend: NSFW in feed limited to own posts + followed users only
  • Backend: nsfw_warning and content_removed notification types + appeal email
  • Backend: user self-labeling (is_nsfw in CreatePost)
  • Flutter: NSFW opt-in toggle + blur toggle in settings (hidden behind expandable at bottom)
  • Flutter: 18+ confirmation dialog for enabling NSFW (moderation rules, not a free-for-all)
  • Flutter: 18+ confirmation dialog for disabling blur (disturbing content warning)
  • Flutter: 6-click path to enable (profile → settings → expand → toggle → confirm → enable)
  • Flutter: blur enforced everywhere — post card, threaded conversation, parent preview, replies
  • Flutter: NSFW self-label toggle in compose toolbar
  • Flutter: publishPost API sends is_nsfw/nsfw_reason

Recent Fixes (Feb 2026)

  • Notification badge count clears on archive
  • Notification UI → full page (was slide-up dialog)
  • Moderation queue constraint fix (dismissed/actioned statuses)
  • Debug print cleanup (190+ statements removed)
  • Run scripts cleanup (run_dev, run_web, run_web_chrome)