diff --git a/android/app/src/main/java/com/shonar/provider/CustomShonarProvider.kt b/android/app/src/main/java/com/shonar/provider/CustomShonarProvider.kt index c26f935..ec38a05 100644 --- a/android/app/src/main/java/com/shonar/provider/CustomShonarProvider.kt +++ b/android/app/src/main/java/com/shonar/provider/CustomShonarProvider.kt @@ -306,6 +306,35 @@ class CustomShonarProvider( "/api/v1/recordings/$recordingId/jobs", recordingId ) + /** Force one pipeline stage to re-run on the server (no re-upload). + * [model] only applies to job="transcribe" (switches the saved + * per-recording override). 409 = stage already running or nothing to + * summarize; surfaced as ProviderError.Transient with the server's + * detail message. */ + suspend fun reprocess(recordingId: String, job: String, model: String? = null): String = + withContext(Dispatchers.IO) { + ensureConnected() + val base = currentOrigin() + val q = if (model != null) "&model=$model" else "" + executeAuthed(base) { token -> + post(base, "/api/v1/recordings/$recordingId/reprocess?job=$job$q", token, "{}") + }.use { resp -> + when (resp.code) { + 200, 201 -> resp.body?.string().orEmpty() + 404 -> throw ProviderError.NotFound(recordingId) + else -> { + val body = runCatching { + org.json.JSONObject(resp.body?.string().orEmpty()) + .optString("detail") + }.getOrNull() + throw ProviderError.Transient( + body?.takeIf { it.isNotBlank() } + ?: "Reprocess failed (HTTP ${resp.code})") + } + } + } + } + /** User edit → new server version with edited_by_user=true (pipeline won't clobber). */ suspend fun updateTranscript( recordingId: String,