## 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!
382 lines
9 KiB
Markdown
382 lines
9 KiB
Markdown
# Sojorn - Setup Guide
|
|
|
|
Quick guide to get Sojorn running locally and deployed.
|
|
|
|
---
|
|
|
|
## Prerequisites
|
|
|
|
- [Supabase CLI](https://supabase.com/docs/guides/cli/getting-started) installed
|
|
- [Deno](https://deno.land) installed (for Edge Functions)
|
|
- [Git](https://git-scm.com) installed
|
|
- A [Supabase account](https://supabase.com) (free tier works)
|
|
|
|
---
|
|
|
|
## Step 1: Environment Setup
|
|
|
|
### 1.1 Create Supabase Project
|
|
|
|
1. Go to [app.supabase.com](https://app.supabase.com)
|
|
2. Click "New Project"
|
|
3. Choose a name (e.g., "sojorn-dev")
|
|
4. Set a strong database password
|
|
5. Select a region close to you
|
|
6. Wait for project to initialize (~2 minutes)
|
|
|
|
### 1.2 Get Your Credentials
|
|
|
|
Once your project is ready:
|
|
|
|
1. Go to **Settings → API**
|
|
2. Copy these values:
|
|
- **Project URL** (e.g., `https://abcdefgh.supabase.co`)
|
|
- **anon/public key** (starts with `eyJ...`)
|
|
- **service_role key** (starts with `eyJ...`)
|
|
|
|
3. Go to **Settings → General**
|
|
- Copy your **Project Reference ID** (e.g., `abcdefgh`)
|
|
|
|
4. Go to **Settings → Database**
|
|
- Copy your **Database Password** (or reset it if you forgot)
|
|
|
|
### 1.3 Configure .env File
|
|
|
|
Open `.env` in this project and fill in your values:
|
|
|
|
```bash
|
|
SUPABASE_URL=https://YOUR_PROJECT_REF.supabase.co
|
|
SUPABASE_ANON_KEY=eyJ...your_anon_key...
|
|
SUPABASE_SERVICE_ROLE_KEY=eyJ...your_service_role_key...
|
|
SUPABASE_PROJECT_REF=YOUR_PROJECT_REF
|
|
SUPABASE_DB_PASSWORD=your_database_password
|
|
CRON_SECRET=generate_with_openssl_rand
|
|
NODE_ENV=development
|
|
API_BASE_URL=https://YOUR_PROJECT_REF.supabase.co/functions/v1
|
|
```
|
|
|
|
### 1.4 Generate CRON_SECRET
|
|
|
|
In your terminal:
|
|
|
|
```bash
|
|
# macOS/Linux
|
|
openssl rand -base64 32
|
|
|
|
# Windows (PowerShell)
|
|
-join ((48..57) + (65..90) + (97..122) | Get-Random -Count 32 | % {[char]$_})
|
|
```
|
|
|
|
Copy the output and paste it as your `CRON_SECRET` in `.env`.
|
|
|
|
---
|
|
|
|
## Step 2: Link to Supabase
|
|
|
|
```bash
|
|
# Login to Supabase
|
|
supabase login
|
|
|
|
# Link your local project to your Supabase project
|
|
supabase link --project-ref YOUR_PROJECT_REF
|
|
|
|
# Enter your database password when prompted
|
|
```
|
|
|
|
---
|
|
|
|
## Step 3: Deploy Database
|
|
|
|
### 3.1 Push Migrations
|
|
|
|
```bash
|
|
# Apply all migrations to your Supabase project
|
|
supabase db push
|
|
```
|
|
|
|
This will create all tables, functions, and RLS policies.
|
|
|
|
### 3.2 Seed Categories
|
|
|
|
Connect to your database and run the seed script:
|
|
|
|
```bash
|
|
# Using psql
|
|
psql "postgresql://postgres:YOUR_DB_PASSWORD@db.YOUR_PROJECT_REF.supabase.co:5432/postgres" \
|
|
-f supabase/seed/seed_categories.sql
|
|
|
|
# Or using Supabase SQL Editor:
|
|
# 1. Go to https://app.supabase.com/project/YOUR_PROJECT/editor
|
|
# 2. Copy contents of supabase/seed/seed_categories.sql
|
|
# 3. Paste and run
|
|
```
|
|
|
|
### 3.3 Verify Database Setup
|
|
|
|
```bash
|
|
# Check that tables were created
|
|
supabase db remote commit
|
|
```
|
|
|
|
Or in the Supabase Dashboard:
|
|
- Go to **Table Editor** → You should see all 14 tables
|
|
|
|
---
|
|
|
|
## Step 4: Deploy Edge Functions
|
|
|
|
### 4.1 Set Secrets
|
|
|
|
```bash
|
|
# Set the CRON_SECRET for the harmony calculation function
|
|
supabase secrets set CRON_SECRET="your_cron_secret_from_env"
|
|
```
|
|
|
|
### 4.2 Deploy All Functions
|
|
|
|
```bash
|
|
# Deploy each function
|
|
supabase functions deploy publish-post
|
|
supabase functions deploy publish-comment
|
|
supabase functions deploy block
|
|
supabase functions deploy report
|
|
supabase functions deploy feed-personal
|
|
supabase functions deploy feed-sojorn
|
|
supabase functions deploy trending
|
|
supabase functions deploy calculate-harmony
|
|
```
|
|
|
|
Or deploy all at once (if you have a deployment script).
|
|
|
|
### 4.3 Verify Functions
|
|
|
|
Go to **Edge Functions** in your Supabase dashboard:
|
|
- You should see 8 functions listed
|
|
- Check logs to ensure no deployment errors
|
|
|
|
---
|
|
|
|
## Step 5: Test the API
|
|
|
|
### 5.1 Create a Test User
|
|
|
|
1. Go to **Authentication → Users** in Supabase Dashboard
|
|
2. Click "Add User"
|
|
3. Enter email and password
|
|
4. Copy the User ID (UUID)
|
|
|
|
### 5.2 Manually Create Profile
|
|
|
|
In **SQL Editor**, run:
|
|
|
|
```sql
|
|
-- Replace USER_ID with the UUID from step 5.1
|
|
INSERT INTO profiles (id, handle, display_name, bio)
|
|
VALUES ('USER_ID', 'testuser', 'Test User', 'Testing Sojorn');
|
|
```
|
|
|
|
### 5.3 Get a JWT Token
|
|
|
|
1. Use the [Supabase Auth API](https://supabase.com/docs/reference/javascript/auth-signinwithpassword):
|
|
|
|
```bash
|
|
curl -X POST "https://YOUR_PROJECT_REF.supabase.co/auth/v1/token?grant_type=password" \
|
|
-H "apikey: YOUR_ANON_KEY" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"email": "test@example.com",
|
|
"password": "your_password"
|
|
}'
|
|
```
|
|
|
|
2. Copy the `access_token` from the response
|
|
|
|
### 5.4 Test Edge Functions
|
|
|
|
```bash
|
|
# Set your token
|
|
export TOKEN="your_access_token_here"
|
|
|
|
# Get a category ID (from seed data)
|
|
# Go to Table Editor → categories → Copy the 'general' category UUID
|
|
|
|
# Test publishing a post
|
|
curl -X POST "https://YOUR_PROJECT_REF.supabase.co/functions/v1/publish-post" \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"category_id": "CATEGORY_UUID",
|
|
"body": "This is my first calm post on Sojorn."
|
|
}'
|
|
|
|
# Test getting personal feed
|
|
curl "https://YOUR_PROJECT_REF.supabase.co/functions/v1/feed-personal" \
|
|
-H "Authorization: Bearer $TOKEN"
|
|
|
|
# Test Sojorn feed
|
|
curl "https://YOUR_PROJECT_REF.supabase.co/functions/v1/feed-sojorn?limit=10" \
|
|
-H "Authorization: Bearer $TOKEN"
|
|
```
|
|
|
|
---
|
|
|
|
## Step 6: Schedule Harmony Calculation
|
|
|
|
### Option 1: GitHub Actions (Recommended for small projects)
|
|
|
|
Create `.github/workflows/harmony-cron.yml`:
|
|
|
|
```yaml
|
|
name: Calculate Harmony Daily
|
|
|
|
on:
|
|
schedule:
|
|
- cron: '0 2 * * *' # 2 AM UTC daily
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
calculate:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Trigger harmony calculation
|
|
run: |
|
|
curl -X POST \
|
|
https://${{ secrets.SUPABASE_PROJECT_REF }}.supabase.co/functions/v1/calculate-harmony \
|
|
-H "Authorization: Bearer ${{ secrets.CRON_SECRET }}"
|
|
```
|
|
|
|
Add secrets in GitHub:
|
|
- `SUPABASE_PROJECT_REF`
|
|
- `CRON_SECRET`
|
|
|
|
### Option 2: Cron-Job.org (External service)
|
|
|
|
1. Go to [cron-job.org](https://cron-job.org) and create account
|
|
2. Create new cron job:
|
|
- URL: `https://YOUR_PROJECT_REF.supabase.co/functions/v1/calculate-harmony`
|
|
- Schedule: Daily at 2 AM
|
|
- Method: POST
|
|
- Header: `Authorization: Bearer YOUR_CRON_SECRET`
|
|
|
|
---
|
|
|
|
## Step 7: Verify Everything Works
|
|
|
|
### 7.1 Check Tables
|
|
|
|
In **Table Editor**, verify:
|
|
- [ ] `profiles` has your test user
|
|
- [ ] `categories` has 12 categories
|
|
- [ ] `trust_state` has your user (with harmony_score = 50)
|
|
- [ ] `posts` has any posts you created
|
|
|
|
### 7.2 Check RLS Policies
|
|
|
|
In **SQL Editor**, test block enforcement:
|
|
|
|
```sql
|
|
-- Create a second test user
|
|
INSERT INTO auth.users (id, email) VALUES (gen_random_uuid(), 'test2@example.com');
|
|
INSERT INTO profiles (id, handle, display_name)
|
|
VALUES ((SELECT id FROM auth.users WHERE email = 'test2@example.com'), 'testuser2', 'Test User 2');
|
|
|
|
-- Block user 2 from user 1
|
|
INSERT INTO blocks (blocker_id, blocked_id)
|
|
VALUES (
|
|
(SELECT id FROM profiles WHERE handle = 'testuser'),
|
|
(SELECT id FROM profiles WHERE handle = 'testuser2')
|
|
);
|
|
|
|
-- Verify user 1 cannot see user 2's profile
|
|
SET request.jwt.claims TO '{"sub": "USER_1_ID"}';
|
|
SELECT * FROM profiles WHERE handle = 'testuser2'; -- Should return 0 rows
|
|
|
|
-- Reset
|
|
RESET request.jwt.claims;
|
|
```
|
|
|
|
### 7.3 Test Tone Detection
|
|
|
|
Try publishing a hostile post:
|
|
|
|
```bash
|
|
curl -X POST "https://YOUR_PROJECT_REF.supabase.co/functions/v1/publish-post" \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"category_id": "CATEGORY_UUID",
|
|
"body": "This is fucking bullshit."
|
|
}'
|
|
```
|
|
|
|
Expected response:
|
|
```json
|
|
{
|
|
"error": "Content rejected",
|
|
"message": "This post contains language that does not fit here.",
|
|
"suggestion": "This space works without profanity. Try rephrasing."
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### "Relation does not exist" error
|
|
- Run `supabase db push` again
|
|
- Check that migrations completed successfully
|
|
|
|
### "JWT expired" error
|
|
- Your auth token expired (tokens last 1 hour)
|
|
- Sign in again to get a new token
|
|
|
|
### "Failed to fetch" error
|
|
- Check your `SUPABASE_URL` is correct
|
|
- Verify Edge Functions are deployed
|
|
- Check function logs: `supabase functions logs FUNCTION_NAME`
|
|
|
|
### RLS policies blocking everything
|
|
- Ensure you're using the correct user ID in JWT
|
|
- Check that user exists in `profiles` table
|
|
- Verify RLS policies with `\d+ TABLE_NAME` in psql
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
Now that your backend is running:
|
|
|
|
1. **Build missing Edge Functions** (signup, follow, like, etc.)
|
|
2. **Start Flutter client** (see Flutter setup guide when created)
|
|
3. **Write transparency pages** (How Reach Works, Rules)
|
|
4. **Add admin tooling** (report review, trending overrides)
|
|
|
|
---
|
|
|
|
## Useful Commands
|
|
|
|
```bash
|
|
# View Edge Function logs
|
|
supabase functions logs publish-post --tail
|
|
|
|
# Reset database (WARNING: deletes all data)
|
|
supabase db reset
|
|
|
|
# Check Supabase status
|
|
supabase status
|
|
|
|
# View remote database changes
|
|
supabase db remote commit
|
|
|
|
# Generate TypeScript types from database
|
|
supabase gen types typescript --local > types/database.ts
|
|
```
|
|
|
|
---
|
|
|
|
## Support
|
|
|
|
- [Supabase Docs](https://supabase.com/docs)
|
|
- [Supabase Discord](https://discord.supabase.com)
|
|
- [Sojorn Documentation](README.md)
|