use crate::database::schema::{ entities, entity_facts, entity_photo_links, favorites, image_exif, libraries, photo_insights, users, video_preview_clips, }; use serde::Serialize; #[derive(Insertable)] #[diesel(table_name = users)] pub struct InsertUser<'a> { pub username: &'a str, pub password: &'a str, } #[derive(Serialize, Queryable, Clone, Debug)] pub struct User { pub id: i32, pub username: String, #[serde(skip_serializing)] pub password: String, } #[derive(Insertable)] #[diesel(table_name = favorites)] pub struct InsertFavorite<'a> { pub userid: &'a i32, #[diesel(column_name = rel_path)] pub path: &'a str, } #[derive(Serialize, Queryable, Clone, Debug)] pub struct Favorite { pub id: i32, pub userid: i32, #[diesel(column_name = rel_path)] pub path: String, } #[derive(Insertable)] #[diesel(table_name = image_exif)] pub struct InsertImageExif { pub library_id: i32, #[diesel(column_name = rel_path)] pub file_path: String, pub camera_make: Option, pub camera_model: Option, pub lens_model: Option, pub width: Option, pub height: Option, pub orientation: Option, pub gps_latitude: Option, pub gps_longitude: Option, pub gps_altitude: Option, pub focal_length: Option, pub aperture: Option, pub shutter_speed: Option, pub iso: Option, pub date_taken: Option, pub created_time: i64, pub last_modified: i64, pub content_hash: Option, pub size_bytes: Option, } // Field order matches the post-migration column order in `image_exif`. #[derive(Serialize, Queryable, Clone, Debug)] pub struct ImageExif { pub id: i32, pub library_id: i32, #[diesel(column_name = rel_path)] pub file_path: String, pub camera_make: Option, pub camera_model: Option, pub lens_model: Option, pub width: Option, pub height: Option, pub orientation: Option, pub gps_latitude: Option, pub gps_longitude: Option, pub gps_altitude: Option, pub focal_length: Option, pub aperture: Option, pub shutter_speed: Option, pub iso: Option, pub date_taken: Option, pub created_time: i64, pub last_modified: i64, pub content_hash: Option, pub size_bytes: Option, } #[derive(Insertable)] #[diesel(table_name = photo_insights)] pub struct InsertPhotoInsight { pub library_id: i32, #[diesel(column_name = rel_path)] pub file_path: String, pub title: String, pub summary: String, pub generated_at: i64, pub model_version: String, pub is_current: bool, pub training_messages: Option, /// `"local"` (Ollama with images) | `"hybrid"` (local vision + OpenRouter chat). pub backend: String, } #[derive(Serialize, Queryable, Clone, Debug)] pub struct PhotoInsight { pub id: i32, pub library_id: i32, #[diesel(column_name = rel_path)] pub file_path: String, pub title: String, pub summary: String, pub generated_at: i64, pub model_version: String, pub is_current: bool, pub training_messages: Option, pub approved: Option, /// `"local"` (Ollama with images) | `"hybrid"` (local vision + OpenRouter chat). pub backend: String, } // --- Libraries --- #[derive(Serialize, Queryable, Clone, Debug)] pub struct LibraryRow { pub id: i32, pub name: String, pub root_path: String, pub created_at: i64, } #[derive(Insertable)] #[diesel(table_name = libraries)] pub struct InsertLibrary<'a> { pub name: &'a str, pub root_path: &'a str, pub created_at: i64, } // --- Knowledge memory models --- #[derive(Insertable)] #[diesel(table_name = entities)] pub struct InsertEntity { pub name: String, pub entity_type: String, pub description: String, pub embedding: Option>, pub confidence: f32, pub status: String, pub created_at: i64, pub updated_at: i64, } #[derive(Serialize, Queryable, Clone, Debug)] pub struct Entity { pub id: i32, pub name: String, pub entity_type: String, pub description: String, pub embedding: Option>, pub confidence: f32, pub status: String, pub created_at: i64, pub updated_at: i64, } #[derive(Insertable)] #[diesel(table_name = entity_facts)] pub struct InsertEntityFact { pub subject_entity_id: i32, pub predicate: String, pub object_entity_id: Option, pub object_value: Option, pub source_photo: Option, pub source_insight_id: Option, pub confidence: f32, pub status: String, pub created_at: i64, } #[derive(Serialize, Queryable, Clone, Debug)] pub struct EntityFact { pub id: i32, pub subject_entity_id: i32, pub predicate: String, pub object_entity_id: Option, pub object_value: Option, pub source_photo: Option, pub source_insight_id: Option, pub confidence: f32, pub status: String, pub created_at: i64, } #[derive(Insertable)] #[diesel(table_name = entity_photo_links)] pub struct InsertEntityPhotoLink { pub entity_id: i32, pub library_id: i32, #[diesel(column_name = rel_path)] pub file_path: String, pub role: String, } #[derive(Serialize, Queryable, Clone, Debug)] pub struct EntityPhotoLink { pub id: i32, pub entity_id: i32, pub library_id: i32, #[diesel(column_name = rel_path)] pub file_path: String, pub role: String, } #[derive(Insertable)] #[diesel(table_name = video_preview_clips)] pub struct InsertVideoPreviewClip { pub library_id: i32, #[diesel(column_name = rel_path)] pub file_path: String, pub status: String, pub created_at: String, pub updated_at: String, } #[derive(Serialize, Queryable, Clone, Debug)] pub struct VideoPreviewClip { pub id: i32, pub library_id: i32, #[diesel(column_name = rel_path)] pub file_path: String, pub status: String, pub duration_seconds: Option, pub file_size_bytes: Option, pub error_message: Option, pub created_at: String, pub updated_at: String, }