## Phase 1: Critical Feature Completion (Beacon Voting) - Add VouchBeacon, ReportBeacon, RemoveBeaconVote methods to PostRepository - Implement beacon voting HTTP handlers with confidence score calculations - Register new beacon routes: /beacons/:id/vouch, /beacons/:id/report, /beacons/:id/vouch (DELETE) - Auto-flag beacons at 5+ reports, confidence scoring (0.5 base + 0.1 per vouch) ## Phase 2: Feed Logic & Post Distribution Integrity - Verify unified feed logic supports all content types (Standard, Quips, Beacons) - Ensure proper distribution: Profile Feed + Main/Home Feed for followers - Beacon Map integration for location-based content - Video content filtering for Quips feed ## Phase 3: The Notification System - Create comprehensive NotificationService with FCM integration - Add CreateNotification method to NotificationRepository - Implement smart deep linking: beacon_map, quip_feed, main_feed - Trigger notifications for beacon interactions and cross-post comments - Push notification logic with proper content type detection ## Phase 4: The Great Supabase Purge - Delete function_proxy.go and remove /functions/:name route - Remove SupabaseURL, SupabaseKey from config.go - Remove SupabaseID field from User model - Clean all Supabase imports and dependencies - Sanitize codebase of legacy Supabase references ## Phase 5: Flutter Frontend Integration - Implement vouchBeacon(), reportBeacon(), removeBeaconVote() in ApiService - Replace TODO delay in video_comments_sheet.dart with actual publishComment call - Fix compilation errors (named parameters, orphaned child properties) - Complete frontend integration with Go API endpoints ## Additional Improvements - Fix compilation errors in threaded_comment_widget.dart (orphaned child property) - Update video_comments_sheet.dart to use proper named parameters - Comprehensive error handling and validation - Production-ready notification system with deep linking ## Migration Status: 100% Complete - Backend: Fully migrated from Supabase to custom Go/Gin API - Frontend: Integrated with new Go endpoints - Notifications: Complete FCM integration with smart routing - Database: Clean of all Supabase dependencies - Features: All functionality preserved and enhanced Ready for VPS deployment and production testing!
166 lines
6 KiB
Markdown
166 lines
6 KiB
Markdown
# Sojorn Backend Architecture
|
|
|
|
## How Boundaries Are Enforced
|
|
|
|
Sojorn's calm is not aspirational—it is structural. The database itself enforces the behavioral philosophy through **Row Level Security (RLS)**, constraints, and functions that make certain behaviors impossible, not just discouraged.
|
|
|
|
---
|
|
|
|
## 1. Blocking: Complete Disappearance
|
|
|
|
**Principle:** When you block someone, they disappear from your world and you from theirs.
|
|
|
|
**Implementation:**
|
|
- The `has_block_between(user_a, user_b)` function checks if either user has blocked the other.
|
|
- RLS policies prevent blocked users from:
|
|
- Seeing each other's profiles
|
|
- Seeing each other's posts
|
|
- Seeing each other's follows
|
|
- Interacting in any way
|
|
|
|
**Effect:** No notifications, no traces, no conflict. The system enforces separation silently.
|
|
|
|
---
|
|
|
|
## 2. Consent: Conversation Requires Mutual Follow
|
|
|
|
**Principle:** You cannot reply to someone unless you mutually follow each other.
|
|
|
|
**Implementation:**
|
|
- The `is_mutual_follow(user_a, user_b)` function verifies bidirectional following.
|
|
- Comments can only be created if `is_mutual_follow(commenter, post_author)` returns true.
|
|
- RLS policies prevent reading comments unless you are:
|
|
- The post author, OR
|
|
- A mutual follower of the post author
|
|
|
|
**Effect:** Unwanted replies are impossible. Conversation is opt-in by structure.
|
|
|
|
---
|
|
|
|
## 3. Exposure: Opt-In by Default
|
|
|
|
**Principle:** Users choose what content they see. Filtering is private and encouraged.
|
|
|
|
**Implementation:**
|
|
- All categories except `general` have `default_off = true`.
|
|
- Users must explicitly enable categories to see posts from them.
|
|
- RLS policies on `posts` check:
|
|
- User has enabled the category, OR
|
|
- Category is not default-off AND user hasn't disabled it
|
|
|
|
**Effect:** Heavy topics (grief, struggle, world events) are invisible unless invited in. No algorithmic exposure.
|
|
|
|
---
|
|
|
|
## 4. Influence: Earned Slowly Through Trust
|
|
|
|
**Principle:** New users have limited reach and posting capacity. Trust grows with positive behavior.
|
|
|
|
**Implementation:**
|
|
- Each user has a `trust_state` with:
|
|
- `harmony_score` (0-100, starts at 50)
|
|
- `tier` (new, trusted, established, restricted)
|
|
- Behavioral counters
|
|
- Post rate limits depend on tier:
|
|
- New: 3 posts/day
|
|
- Trusted: 10 posts/day
|
|
- Established: 25 posts/day
|
|
- Restricted: 1 post/day
|
|
- The `can_post(user_id)` function enforces this before allowing inserts.
|
|
|
|
**Effect:** Spam and abuse are throttled by friction. Positive contributors gain capacity over time.
|
|
|
|
---
|
|
|
|
## 5. Moderation: Guidance Through Friction, Not Punishment
|
|
|
|
**Principle:** Sharp speech does not travel. The system gently contains hostility.
|
|
|
|
**Implementation:**
|
|
- Posts and comments carry `tone_label` and `cis_score` (content integrity score).
|
|
- Content flagged as hostile:
|
|
- Has reduced reach (implemented in feed algorithms, not yet built)
|
|
- May be soft-deleted (`status = 'removed'`)
|
|
- Triggers adjustments to author's `harmony_score`
|
|
- All moderation actions are logged in `audit_log` with full transparency.
|
|
|
|
**Effect:** Hostility is contained, not amplified. Violators experience reduced reach before account action.
|
|
|
|
---
|
|
|
|
## 6. Non-Attachment: Nothing Is Permanent
|
|
|
|
**Principle:** Feeds rotate, trends fade, attention is non-possessive.
|
|
|
|
**Implementation:**
|
|
- No "permanence" affordances like pinned posts or evergreen content.
|
|
- Posts are timestamped and will naturally age out of feeds.
|
|
- No edit history preserved beyond `edited_at` timestamp.
|
|
- Soft deletes allow content to disappear without breaking audit trails.
|
|
|
|
**Effect:** The platform discourages attachment to metrics or viral moments. Content is transient by design.
|
|
|
|
---
|
|
|
|
## 7. Transparency: Users Are Told How Reach Works
|
|
|
|
**Principle:** The system does not hide how it operates.
|
|
|
|
**Implementation:**
|
|
- `trust_state` is visible to the user (their own state only via RLS).
|
|
- `audit_log` events related to a user are readable by that user.
|
|
- Rate limits, tier effects, and category mechanics are explained in-app (not yet built).
|
|
|
|
**Effect:** Users understand why their reach changes. No hidden algorithmic manipulation.
|
|
|
|
---
|
|
|
|
## Database Design Summary
|
|
|
|
### Core Tables
|
|
- **profiles**: User identity (handle, display name, bio)
|
|
- **categories**: Content organization with opt-in/opt-out controls
|
|
- **user_category_settings**: Per-user category preferences
|
|
- **follows**: Explicit connections (required for conversation)
|
|
- **blocks**: Complete bidirectional separation
|
|
|
|
### Content Tables
|
|
- **posts**: Primary content (500 char max, categorized, moderated)
|
|
- **post_metrics**: Engagement counters (likes, saves, views)
|
|
- **post_likes**: Public appreciation (boosts)
|
|
- **post_saves**: Private bookmarks
|
|
- **comments**: Conversation within mutual-follow circles
|
|
- **comment_votes**: Helpful/unhelpful signals (private)
|
|
|
|
### Moderation Tables
|
|
- **reports**: User-filed reports for review
|
|
- **trust_state**: Per-user trust metrics and rate limits
|
|
- **audit_log**: Complete transparency trail
|
|
|
|
### Key Functions
|
|
- `has_block_between(user_a, user_b)`: Check for blocking
|
|
- `is_mutual_follow(user_a, user_b)`: Verify mutual connection
|
|
- `can_post(user_id)`: Rate limit enforcement
|
|
- `adjust_harmony_score(user_id, delta, reason)`: Trust adjustments
|
|
- `log_audit_event(actor_id, event_type, payload)`: Audit logging
|
|
|
|
---
|
|
|
|
## What This Enables
|
|
|
|
1. **Calm is enforced, not suggested.** The database will not allow hostile interactions.
|
|
2. **Boundaries are private.** Blocking and filtering leave no trace visible to the blocked party.
|
|
3. **Consent is required.** You cannot force your words into someone's space.
|
|
4. **Exposure is controlled.** Users see only what they choose to see.
|
|
5. **Influence is earned.** New accounts cannot spam or brigade.
|
|
6. **Moderation is transparent.** Users know why their reach changed.
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
- **Edge Functions**: Implement feed generation, content moderation, and signup flows.
|
|
- **Flutter Client**: Build UI that reflects these structural constraints.
|
|
- **Content Moderation**: Integrate tone classification and integrity scoring.
|
|
- **Feed Algorithms**: Design reach curves based on harmony score and engagement patterns.
|