sojorn/sojorn_docs/deployment/SETUP.md

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 friendly 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)