feat(migrations): try to fix the migrations service

This commit is contained in:
perf3ct 2025-06-13 14:27:31 +00:00
parent e61db1036e
commit e1e949cf65
3 changed files with 101 additions and 9 deletions

View File

@ -10,7 +10,7 @@ tower = { version = "0.4", features = ["util"] }
tower-http = { version = "0.5", features = ["cors", "fs"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "postgres", "sqlite", "chrono", "uuid"] }
sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "postgres", "sqlite", "chrono", "uuid", "migrate"] }
regex = "1.0"
uuid = { version = "1", features = ["v4", "serde"] }
chrono = { version = "0.4", features = ["serde"] }

View File

@ -0,0 +1,62 @@
-- Create extensions
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pg_trgm";
-- Create users table
CREATE TABLE IF NOT EXISTS users (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
username VARCHAR(255) UNIQUE NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Create documents table
CREATE TABLE IF NOT EXISTS documents (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
filename VARCHAR(255) NOT NULL,
original_filename VARCHAR(255) NOT NULL,
file_path VARCHAR(500) NOT NULL,
file_size BIGINT NOT NULL,
mime_type VARCHAR(100) NOT NULL,
content TEXT,
ocr_text TEXT,
tags TEXT[] DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
user_id UUID REFERENCES users(id) ON DELETE CASCADE
);
-- Create indexes
CREATE INDEX IF NOT EXISTS idx_documents_user_id ON documents(user_id);
CREATE INDEX IF NOT EXISTS idx_documents_filename ON documents(filename);
CREATE INDEX IF NOT EXISTS idx_documents_mime_type ON documents(mime_type);
CREATE INDEX IF NOT EXISTS idx_documents_tags ON documents USING GIN(tags);
CREATE INDEX IF NOT EXISTS idx_documents_content_search ON documents USING GIN(to_tsvector('english', COALESCE(content, '') || ' ' || COALESCE(ocr_text, '')));
CREATE INDEX IF NOT EXISTS idx_documents_filename_trgm ON documents USING GIN(filename gin_trgm_ops);
CREATE INDEX IF NOT EXISTS idx_documents_content_trgm ON documents USING GIN((COALESCE(content, '') || ' ' || COALESCE(ocr_text, '')) gin_trgm_ops);
-- Create settings table
CREATE TABLE IF NOT EXISTS settings (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID REFERENCES users(id) ON DELETE CASCADE UNIQUE,
ocr_language VARCHAR(10) DEFAULT 'eng',
concurrent_ocr_jobs INT DEFAULT 4,
ocr_timeout_seconds INT DEFAULT 300,
max_file_size_mb INT DEFAULT 50,
allowed_file_types TEXT[] DEFAULT ARRAY['pdf', 'png', 'jpg', 'jpeg', 'tiff', 'bmp', 'txt'],
auto_rotate_images BOOLEAN DEFAULT TRUE,
enable_image_preprocessing BOOLEAN DEFAULT TRUE,
search_results_per_page INT DEFAULT 25,
search_snippet_length INT DEFAULT 200,
fuzzy_search_threshold REAL DEFAULT 0.8,
retention_days INT,
enable_auto_cleanup BOOLEAN DEFAULT FALSE,
enable_compression BOOLEAN DEFAULT FALSE,
memory_limit_mb INT DEFAULT 512,
cpu_priority VARCHAR(10) DEFAULT 'normal',
enable_background_ocr BOOLEAN DEFAULT TRUE,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);

View File

@ -4,6 +4,7 @@ use axum::{
routing::get,
Router,
};
use sqlx::Row;
use std::sync::Arc;
use tower_http::{cors::CorsLayer, services::ServeDir};
use tracing::{info, error};
@ -41,16 +42,45 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = Config::from_env()?;
let db = Database::new(&config.database_url).await?;
db.migrate().await?;
// Don't run the old migration system - let SQLx handle everything
// db.migrate().await?;
// Run SQLx migrations
sqlx::migrate!("./migrations")
.run(&db.pool)
.await
.map_err(|e| {
error!("Failed to run migrations: {}", e);
e
})?;
info!("Running SQLx migrations...");
let migrations = sqlx::migrate!("./migrations");
info!("Found {} migrations", migrations.migrations.len());
for migration in migrations.migrations.iter() {
info!("Migration available: {} - {}", migration.version, migration.description);
}
// Check current migration status
let applied_result = sqlx::query("SELECT version, description FROM _sqlx_migrations ORDER BY version")
.fetch_all(&db.pool)
.await;
match applied_result {
Ok(rows) => {
info!("Currently applied migrations:");
for row in rows {
let version: i64 = row.get("version");
let description: String = row.get("description");
info!(" - {} {}", version, description);
}
}
Err(e) => {
info!("No existing migrations found (this is normal for first run): {}", e);
}
}
let result = migrations.run(&db.pool).await;
match result {
Ok(_) => info!("SQLx migrations completed successfully"),
Err(e) => {
error!("Failed to run SQLx migrations: {}", e);
return Err(e.into());
}
}
// Seed admin user
seed::seed_admin_user(&db).await?;