feature/insight-jobs #102
Reference in New Issue
Block a user
Delete Branch "feature/insight-jobs"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
- Fix query param mismatch: rename GenerationStatusQuery.file_path to path so the client's app-resume buildQuery({ path: ... }) resolves correctly instead of always getting 400 - Remove dead _lib_id bindings from both generate handlers - Return 202 Accepted instead of 200 from generate endpoints - Restore OpenTelemetry span instrumentation on generate handlers - Remove stale UNIQUE constraint from initial migration (incompatible with plain-INSERT DAO) - Add tests for status guard: complete_job/fail_job are no-ops when job is already cancelled, and cancel_job by id - Persist generation params (num_ctx, temperature, top_p, top_k, min_p, system_prompt, persona_id) on the photo_insights table for auditing Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>Every map_err(|_| DbError::new(...)) and map_err(|_| anyhow!("...")) in the database layer was discarding the actual Diesel/SQLite error, making failures impossible to diagnose from logs. - Add DbError::log() that logs the source error before converting - Replace all ~130 swallowed outer map_err closures with DbError::log - Replace all ~47 swallowed inner anyhow closures to include the source error in the message Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>The previous fix logged the underlying error in a separate log line, but the error that propagated up still showed just "DbError { kind: InsertError }" at the call site. Now the source message is captured on the struct itself, so Debug/Display output at any call site shows the actual Diesel error inline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>Replace the one-shot SSE chat stream with an async dispatch + reconnectable replay flow so the mobile client survives backgrounding, network blips, and OS-killed sockets without losing an in-flight agentic turn. - TurnRegistry/TurnEntry: in-memory per-turn event buffer (cap 500, front eviction) shared by the agentic loop (writer) and SSE replay readers. ReplayOutcome + replay_from/next_batch distinguish Events/CaughtUp/Gone; next_batch registers the Notify before reading state (no lost wakeup) and drains every buffered event before signaling terminal, so the final Done/Error is never dropped and the stream closes cleanly. - Endpoints: POST /insights/chat/turn (202 + turn_id), GET /insights/chat/turn/{id} (SSE replay, ?skip_before= resume, per-event seq, 410 on eviction), DELETE /insights/chat/turn/{id} (real task abort + cooperative is_running() check at each loop boundary). - Cancellation actually stops the task (AbortHandle stored on the entry) and emits a Done{cancelled:true}; callers skip persistence on cancel. - Background sweeper drops stale turns; interval clamped to <=300s. - OpenTelemetry spans: ai.chat.turn.execute/replay/cancel. - Legacy POST /insights/chat/stream path preserved unchanged. Tests: registry coverage for terminal delivery (race guard), waiting, Gone, abort, eviction; handler integration tests for 404/410, skip_before, seq stamping, completed replay, and cancel. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>generate_video built the rel_path for its image_exif lookup by stripping the library root from the absolute path, leaving backslashes on Windows (Melissa\clip.mp4). file_scan stores rel_paths forward-slash and get_exif_batch matches exactly with no normalization, so the lookup missed and the handler re-hashed the entire video file on every request. Extract rel_path_for_lookup and normalize separators with replace('\\', '/'). Adds tests for Windows/Unix separators, file-at-root, leading separator stripping, and the no-match fallback. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>