sojorn/sojorn_docs/SOJORN_ARCHITECTURE.md

9.9 KiB

Sojorn Architecture & Deployment Guide

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


Table of Contents

  1. Overview
  2. Project Structure
  3. Flutter App
  4. Go Backend
  5. Server Deployment
  6. Database
  7. Common Commands
  8. 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

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

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:

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

[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

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

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

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

# Run on Chrome
flutter run -d chrome

# Build web
flutter build web

# Run tests
flutter test

# Analyze code
flutter analyze

Go Backend

# 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

# 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

# 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:

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.