# Sojorn Architecture & Deployment Guide

> **Last Updated:** 2026-02-03  
> **Maintainer:** MPLS LLC

---

## Table of Contents
1. [Overview](#overview)
2. [Project Structure](#project-structure)
3. [Flutter App](#flutter-app)
4. [Go Backend](#go-backend)
5. [Server Deployment](#server-deployment)
6. [Database](#database)
7. [Common Commands](#common-commands)
8. [Troubleshooting](#troubleshooting)

---

## Overview

**Sojorn** is a social media platform with the following core features:
- **Posts & Feeds:** Category-based content discovery
- **Chains (Threads):** Reddit-style threaded conversations
- **Beacons:** Location-based ephemeral posts
- **E2EE Chat:** End-to-end encrypted direct messaging
- **Profiles:** User profiles with follow/friend system
- **Reactions:** Custom emoji reactions on posts

### Tech Stack
| Component | Technology |
|-----------|------------|
| Mobile/Web App | Flutter (Dart) |
| Backend API | Go (Gin framework) |
| Database | PostgreSQL |
| Media Storage | Cloudflare R2 |
| Realtime | WebSockets |

---

## Project Structure

```
C:\Webs\Sojorn\
├── sojorn_app/           # Flutter application
│   ├── lib/              # Dart source code
│   │   ├── screens/      # UI screens
│   │   ├── widgets/      # Reusable widgets
│   │   ├── services/     # Business logic & API calls
│   │   ├── models/       # Data models
│   │   ├── providers/    # Riverpod state management
│   │   └── theme/        # App theming
│   ├── web/              # Web-specific assets
│   ├── android/          # Android configs
│   ├── ios/              # iOS configs
│   └── pubspec.yaml      # Dependencies
│
├── go-backend/           # Go API server
│   ├── cmd/api/          # Main entry point (main.go)
│   ├── internal/
│   │   ├── handlers/     # HTTP route handlers
│   │   ├── repository/   # Database queries
│   │   ├── services/     # Business logic
│   │   ├── models/       # Go structs
│   │   ├── middleware/   # Auth, CORS, rate limiting
│   │   └── config/       # Environment configuration
│   └── pkg/utils/        # Shared utilities
│
└── sojorn_docs/          # Documentation
```

---

## Flutter App

### Running Locally

```powershell
cd C:\Webs\Sojorn\sojorn_app

# Web (Chrome)
flutter run -d chrome

# Android
flutter run -d <device-id>

# iOS
flutter run -d <simulator-id>
```

### API Configuration
The app connects to the production API at:
```
https://api.sojorn.net  (or http://194.238.28.122:8080)
```

Configuration is in: `lib/config/api_config.dart`

### Key Files
| File | Purpose |
|------|---------|
| `lib/services/api_service.dart` | All backend API calls |
| `lib/services/auth_service.dart` | Authentication & token management |
| `lib/services/secure_chat_service.dart` | E2EE messaging |
| `lib/screens/profile/profile_screen.dart` | User's own profile |
| `lib/screens/profile/viewable_profile_screen.dart` | Viewing other profiles |

---

## Go Backend

### Local Development

```powershell
cd C:\Webs\Sojorn\go-backend

# Run locally
go run ./cmd/api

# Build binary
go build -o sojorn-api ./cmd/api
```

### Environment Variables
Create `.env` file or set environment variables:
```env
DATABASE_URL=postgres://user:pass@localhost:5432/sojorn?sslmode=disable
PORT=8080
JWT_SECRET=your-secret
CORS_ORIGINS=*
R2_ACCESS_KEY=...
R2_SECRET_KEY=...
```

### Key Files
| File | Purpose |
|------|---------|
| `cmd/api/main.go` | Server setup & route registration |
| `internal/handlers/post_handler.go` | Post CRUD & feed endpoints |
| `internal/handlers/user_handler.go` | Profile & social endpoints |
| `internal/repository/post_repository.go` | Post database queries |
| `internal/repository/user_repository.go` | User database queries |
aaa
---

## Server Deployment

### Server Details
| Property | Value |
|----------|-------|
| **IP Address** | `194.238.28.122` |
| **SSH User** | `patrick` |
| **SSH Key** | `C:\Users\Patrick\.ssh\mpls.pem` |
| **Sudo Password** | `P22k154ever!` |

### Directory Structure on Server
```
/opt/sojorn/
├── bin/
│   └── api              # ⚠️ THE RUNNING BINARY
├── go-backend/          # Git repo clone
│   └── ...
├── .env                 # Environment variables
└── sojorn-api           # Build output (copy to bin/api)
```

### Systemd Service
**Service Name:** `sojorn-api`  
**Config File:** `/etc/systemd/system/sojorn-api.service`

```ini
[Unit]
Description=Sojorn Golang API Server
After=network.target postgresql.service

[Service]
Type=simple
User=root
WorkingDirectory=/opt/sojorn
ExecStart=/opt/sojorn/bin/api    # ⚠️ IMPORTANT: Uses bin/api
Restart=always
RestartSec=5s
EnvironmentFile=/opt/sojorn/.env

[Install]
WantedBy=multi-user.target
```

### Deployment Workflow

```bash
# 1. SSH to server
ssh -i "C:\Users\Patrick\.ssh\mpls.pem" patrick@194.238.28.122

# 2. Pull latest code
cd /opt/sojorn/go-backend
git fetch origin
git reset --hard origin/ThreadRestoration  # or main branch

# 3. Build
go build -o sojorn-api ./cmd/api

# 4. Stop service, copy binary, start service
sudo systemctl stop sojorn-api
sudo cp sojorn-api /opt/sojorn/bin/api
sudo systemctl start sojorn-api

# 5. Verify
sudo systemctl status sojorn-api
```

### Quick Deploy Command (from Windows)
```powershell
ssh -i "C:\Users\Patrick\.ssh\mpls.pem" patrick@194.238.28.122 "cd /opt/sojorn/go-backend && git fetch origin && git reset --hard origin/ThreadRestoration && go build -o sojorn-api ./cmd/api && echo 'P22k154ever!' | sudo -S systemctl stop sojorn-api && echo 'P22k154ever!' | sudo -S cp sojorn-api /opt/sojorn/bin/api && echo 'P22k154ever!' | sudo -S systemctl start sojorn-api"
```

---

## Database

### Connection Details
| Property | Value |
|----------|-------|
| **Host** | `localhost` (from server) |
| **Port** | `5432` |
| **Database** | `sojorn` |
| **User** | `postgres` |
| **Password** | `A24Zr7AEoch4eO0N` |

### Connection String
```
postgres://postgres:A24Zr7AEoch4eO0N@localhost:5432/sojorn?sslmode=disable
```

### Key Tables
| Table | Purpose |
|-------|---------|
| `profiles` | User profiles |
| `posts` | All posts (regular, chains, beacons) |
| `post_metrics` | Like/comment counts |
| `post_likes` | Who liked which post |
| `post_saves` | Saved/bookmarked posts |
| `post_reactions` | Emoji reactions |
| `follows` | Follow relationships |
| `conversations` | E2EE chat conversations |
| `messages` | Chat messages |
| `categories` | Content categories |
| `category_settings` | User category preferences |

### Useful Queries
```sql
-- Check saved posts
SELECT COUNT(*) FROM post_saves;

-- Check user's saved posts
SELECT * FROM post_saves WHERE user_id = 'uuid-here';

-- Check posts table
SELECT id, author_id, body, created_at FROM posts LIMIT 10;
```

---

## Common Commands

### Flutter App
```powershell
# Run on Chrome
flutter run -d chrome

# Build web
flutter build web

# Run tests
flutter test

# Analyze code
flutter analyze
```

### Go Backend
```powershell
# Run locally
cd C:\Webs\Sojorn\go-backend
go run ./cmd/api

# Build
go build -o sojorn-api ./cmd/api

# Format code
go fmt ./...
```

### Server Management
```bash
# SSH to server
ssh -i "C:\Users\Patrick\.ssh\mpls.pem" patrick@194.238.28.122

# Service commands
sudo systemctl status sojorn-api
sudo systemctl restart sojorn-api
sudo systemctl stop sojorn-api
sudo systemctl start sojorn-api

# View logs
sudo journalctl -u sojorn-api -f

# Database access
PGPASSWORD=A24Zr7AEoch4eO0N psql -h localhost -U postgres -d sojorn
```

### Git Operations
```powershell
# Commit and push (from local)
cd C:\Webs\Sojorn\go-backend
git add .
git commit -m "Your message"
git push

# Pull on server
ssh ... "cd /opt/sojorn/go-backend && git pull"
```

---

## Troubleshooting

### Route Not Found (404) After Deployment
**Cause:** Old binary is still running.  
**Solution:** Stop service before copying new binary:
```bash
sudo systemctl stop sojorn-api
sudo cp sojorn-api /opt/sojorn/bin/api
sudo systemctl start sojorn-api
```

### "Text file busy" Error
**Cause:** Trying to overwrite running binary.  
**Solution:** Stop the service first.

### Server Not Responding
1. Check service status: `sudo systemctl status sojorn-api`
2. Check logs: `sudo journalctl -u sojorn-api -n 50`
3. Verify port: `sudo netstat -tlnp | grep 8080`

### Database Connection Errors
1. Check PostgreSQL: `sudo systemctl status postgresql`
2. Verify credentials in `/opt/sojorn/.env`
3. Test connection: `psql -h localhost -U postgres -d sojorn`

### Flutter Build Errors
1. Clean build: `flutter clean && flutter pub get`
2. Analyze: `flutter analyze`
3. Check Dart version: `flutter doctor`

---

## API Endpoints Reference

### Authentication
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/v1/auth/register` | Register new user |
| POST | `/api/v1/auth/login` | Login |
| POST | `/api/v1/auth/refresh` | Refresh token |

### Profile
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/v1/profile` | Get own profile |
| GET | `/api/v1/profiles/:id` | Get profile by ID |
| PATCH | `/api/v1/profile` | Update profile |

### Posts
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/v1/posts` | Create post |
| GET | `/api/v1/posts/:id` | Get single post |
| GET | `/api/v1/feed` | Get user's feed |
| GET | `/api/v1/users/:id/posts` | Get user's posts |
| GET | `/api/v1/users/:id/saved` | Get user's saved posts |
| POST | `/api/v1/posts/:id/save` | Save a post |
| DELETE | `/api/v1/posts/:id/save` | Unsave a post |

### Social
| Method | Endpoint | Description |
|--------|----------|-------------|
| POST | `/api/v1/users/:id/follow` | Follow user |
| DELETE | `/api/v1/users/:id/follow` | Unfollow user |
| POST | `/api/v1/posts/:id/like` | Like post |
| DELETE | `/api/v1/posts/:id/like` | Unlike post |

---

*This document should be updated whenever deployment procedures or architecture changes.*
