feat: add database schema and SQLx migrations

- 5 reversible migrations: extensions/enums, tables, indexes, views, config seed
- Tables: event, user, session, upload, hashtag, upload_hashtag, comment,
  comment_hashtag, like, export_job, config
- Views: v_feed (uploads with like/comment counts), v_hashtag_counts
- Indexes optimised for feed queries, session lookup, hashtag filtering
- Config table seeded with default rate limits and quotas
- db.rs module: PgPool creation with auto-migration on startup
- docker-compose.override.yml: expose db port 5432 for local dev
- Fix crate names: async_zip, tower_governor (underscore, not hyphen)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
fabi
2026-03-31 21:15:25 +02:00
parent b89b1d6ffa
commit e976f0f670
15 changed files with 4492 additions and 3 deletions

19
backend/src/db.rs Normal file
View File

@@ -0,0 +1,19 @@
use anyhow::{Context, Result};
use sqlx::postgres::PgPoolOptions;
use sqlx::PgPool;
pub async fn create_pool(database_url: &str) -> Result<PgPool> {
let pool = PgPoolOptions::new()
.max_connections(10)
.connect(database_url)
.await
.context("failed to connect to database")?;
sqlx::migrate!()
.run(&pool)
.await
.context("failed to run database migrations")?;
tracing::info!("database connected and migrations applied");
Ok(pool)
}

View File

@@ -1,6 +1,8 @@
use anyhow::Result;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
mod db;
#[tokio::main]
async fn main() -> Result<()> {
dotenvy::dotenv().ok();
@@ -12,10 +14,14 @@ async fn main() -> Result<()> {
.with(tracing_subscriber::fmt::layer())
.init();
let database_url =
std::env::var("DATABASE_URL").expect("DATABASE_URL must be set");
let port: u16 = std::env::var("APP_PORT")
.unwrap_or_else(|_| "3000".to_string())
.parse()?;
let _pool = db::create_pool(&database_url).await?;
let router = axum::Router::new()
.route("/health", axum::routing::get(|| async { "ok" }));