sojorn/sojorn_docs/SOJORN_ARCHITECTURE.md

396 lines
9.9 KiB
Markdown

# 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.*