# Sojorn Database Architecture & Context **Last Updated:** January 27, 2026 ## Overview The Sojorn backend uses a PostgreSQL database hosted on a VPS. It is critical to note that there are multiple databases present in the Postgres instance, and the application serves from a specific one. ## Connection Details - **Host:** `localhost` (Internal to VPS) - **Port:** `5432` - **Primary Database Name:** `sojorn` - **User:** `postgres` - **SSL Mode:** `disable` - **Application Config Source:** `/opt/sojorn/.env` (on VPS) **Warning:** Do not assume the database is named `postgres`. Always target the `sojorn` database for application schema changes. ## Critical Key Tables & Schema Notes ### 1. Profiles (`public.profiles`) Stores user identity and global configuration. | Column | Type | Notes | | :--- | :--- | :--- | | `id` | UUID | Primary Key | | `handle` | Text | Unique user handle (username) | | `is_private` | Boolean | **Crucial:** Controls visibility in global feeds. Defaults to `FALSE`. | | `is_official` | Boolean | **Crucial:** Verification badge / official account status. | | `identity_key` | Text | For E2EE (Signal Protocol) | ### 2. Follows (`public.follows`) Manages the social graph. | Column | Type | Notes | | :--- | :--- | :--- | | `follower_id` | UUID | User DOING the following | | `following_id` | UUID | User BEING followed | | `status` | Text | **Crucial:** Must be `'accepted'` or `'pending'`. Logic joins on `status='accepted'`. | ### 3. Posts (`public.posts`) | Column | Type | Notes | | :--- | :--- | :--- | | `duration_ms` | Int | **Nullable**. Can be NULL for non-video posts. Queries MUST use `COALESCE(duration_ms, 0)`. | | `is_beacon` | Boolean | Determines if post is location-aware. | | `location` | Geography | Post coordinates (PostGIS). | ## Troubleshooting & Maintenance ### Accessing the Database (CLI) To manually inspect or patch the database, use the following command pattern on the VPS: ```bash # Connect specifically to the 'sojorn' database export PGPASSWORD='YOUR_PASSWORD' psql -U postgres -h localhost -d sojorn ``` ### Common Pitfalls 1. **Patching `postgres` instead of `sojorn`:** Running `psql` without `-d sojorn` defaults to the `postgres` system DB. Schema changes here WON'T affect the app. 2. **Null Scanning:** Go's `database/sql` driver will panic or error if you try to `Scan` a SQL `NULL` into a non-pointer primitive (e.g., `int` vs `*int` or `NullInt`). Always use `COALESCE` in SQL queries for nullable optional fields like `duration_ms`, `image_url`. 3. **Scan Mismatches:** If you add a column to a `SELECT` query, you MUST add a corresponding destination variable in `rows.Scan()`. ### Migration Strategy - The project currently relies on imperative SQL patches or `golang-migrate` scripts. - Ensure any migration scripts target the `DATABASE_URL` defined in `.env`.