feat: async insight generation with SQLite job tracking

- Add insight_generation_jobs table migration and DAO
- Implement job lifecycle: create_or_get_active, complete, fail, cancel
- Refactor POST /insights/generate and /agentic to async spawn with timeout
- Add GET /insights/generation/status endpoint with job_id and file_path lookup
- Use String for enum fields in Diesel models to avoid private Bound type
- Add from_str() helpers on InsightJobStatus and InsightGenerationType
- Fix update_training_messages to return Result<usize, DbError>
- 7/7 DAO unit tests passing
This commit is contained in:
Cameron Cordes
2026-05-27 10:01:17 -04:00
parent 5a75d1a28c
commit b87eb4e690
13 changed files with 1046 additions and 174 deletions
+16
View File
@@ -271,12 +271,27 @@ diesel::table! {
}
}
diesel::table! {
insight_generation_jobs (id) {
id -> Integer,
library_id -> Integer,
file_path -> Text,
generation_type -> Text,
status -> Text,
started_at -> BigInt,
completed_at -> Nullable<BigInt>,
result_insight_id -> Nullable<Integer>,
error_message -> Nullable<Text>,
}
}
diesel::joinable!(entity_facts -> photo_insights (source_insight_id));
diesel::joinable!(entity_photo_links -> entities (entity_id));
diesel::joinable!(entity_photo_links -> libraries (library_id));
diesel::joinable!(face_detections -> libraries (library_id));
diesel::joinable!(face_detections -> persons (person_id));
diesel::joinable!(image_exif -> libraries (library_id));
diesel::joinable!(insight_generation_jobs -> libraries (library_id));
diesel::joinable!(personas -> users (user_id));
diesel::joinable!(persons -> entities (entity_id));
diesel::joinable!(photo_insights -> libraries (library_id));
@@ -292,6 +307,7 @@ diesel::allow_tables_to_appear_in_same_query!(
face_detections,
favorites,
image_exif,
insight_generation_jobs,
libraries,
location_history,
personas,