Fix auth header lost on multipart task completion requests

The createCompletionWithImages method used client.post() with a manual
MultiPartFormDataContent body, which can override the Authorization header.
Switch to submitFormWithBinaryData() (matching DocumentApi's working pattern)
which properly separates form data from request headers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-03-02 19:56:13 -06:00
parent cee6be8db2
commit 469d371635

View File

@@ -4,6 +4,7 @@ import com.example.casera.models.*
import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.request.*
import io.ktor.client.request.forms.*
import io.ktor.http.*
class TaskCompletionApi(private val client: HttpClient = ApiClient.httpClient) {
@@ -100,34 +101,31 @@ class TaskCompletionApi(private val client: HttpClient = ApiClient.httpClient) {
imageFileNames: List<String> = emptyList()
): ApiResult<WithSummaryResponse<TaskCompletionResponse>> {
return try {
val response = client.post("$baseUrl/task-completions/") {
header("Authorization", "Token $token")
val response = client.submitFormWithBinaryData(
url = "$baseUrl/task-completions/",
formData = formData {
// Add text fields
append("task_id", request.taskId.toString())
request.completedAt?.let { append("completed_at", it) }
request.actualCost?.let { append("actual_cost", it.toString()) }
request.notes?.let { append("notes", it) }
request.rating?.let { append("rating", it.toString()) }
setBody(
io.ktor.client.request.forms.MultiPartFormDataContent(
io.ktor.client.request.forms.formData {
// Add text fields
append("task_id", request.taskId.toString())
request.completedAt?.let { append("completed_at", it) }
request.actualCost?.let { append("actual_cost", it.toString()) }
request.notes?.let { append("notes", it) }
request.rating?.let { append("rating", it.toString()) }
// Add image files
images.forEachIndexed { index, imageBytes ->
val fileName = imageFileNames.getOrNull(index) ?: "image_$index.jpg"
append(
"images",
imageBytes,
io.ktor.http.Headers.build {
append(HttpHeaders.ContentType, "image/jpeg")
append(HttpHeaders.ContentDisposition, "filename=\"$fileName\"")
}
)
// Add image files
images.forEachIndexed { index, imageBytes ->
val fileName = imageFileNames.getOrNull(index) ?: "image_$index.jpg"
append(
"images",
imageBytes,
Headers.build {
append(HttpHeaders.ContentType, "image/jpeg")
append(HttpHeaders.ContentDisposition, "filename=\"$fileName\"")
}
}
)
)
)
}
}
) {
header("Authorization", "Token $token")
}
if (response.status.isSuccess()) {