Skip to main content

Storing an exported training upload

For support. A training the server keeps refusing stays in the tracking app's upload queue; the app never deletes it. From 3.0.8 the user can hand it over as a file: tap "Pending uploads", then "Export" in the message. This page says what the file is and how to get the training into the account.

When a user sends a file​

  1. Ask them to update first. Most refusals are healed by the app or the server on the next attempt (see offline & sync, "An upload the server refuses"). After the update: open the app with a connection and wait a minute. If "Pending uploads" is gone, nothing is left to do.
  2. If it stays, ask for the export. The user must not sign out, reinstall or clear the app before the training is stored — the queue on the device is the original.

What the file contains​

A JSON document, enode-uploads-<date>.json:

FieldMeaning
format, version"enode.stuck-uploads", 1
exportedAtwhen the file was made (ISO time)
uploaderUserIDthe signed-in user whose queue it is
batches[]one entry per refused upload
batches[].payloadthe sessions exactly as the app sends them to POST /workout_sessions
batches[].sessionIdsthe ids of those sessions
batches[].lastFailurethe server's last answer: HTTP status, time at, and reason when it gave one
batches[].exerciseRefsper session: the exercise definition and the athlete it was recorded for
batches[].unboundSessions, packageTypeKeysrepair data the app applies before sending; empty for most uploads

The file holds training data of the account's athletes. Treat it like any other personal data: keep it in the ticket, delete local copies afterwards.

Reading the reason​

lastFailure.reasonWhat it meansWhat to do
exercise_not_foundthe session names an exercise the server no longer hasstore it with the exercise from exerciseRefs (below)
no_access_to_athletethe uploader may no longer see that athleterestore the access in the portal, then the app uploads by itself
unknown_metrica metric id the server does not knowreport to development with the file
none, status 400the server could not read the requestreport to development with the file
none, status 0no answer from the servernot a refusal; the app keeps retrying

Storing the training​

The backend has an import route for the file (POST /api/workout_sessions/import, admin token). For now a backend developer runs it; support cannot yet:

scripts/import-stuck-uploads.sh <base-url> <file> # in enode_backend_v1
  1. Hand the file to a backend developer unchanged, with the ticket. The route takes it as exported.

  2. The import acts as uploaderUserID, with the same checks as a normal upload. A session whose exercise the server does not know is stored on the exercise of the athlete named in exerciseRefs, created if missing.

  3. The answer lists every session:

    outcomeMeaning
    createdstored now
    alreadyPresentwas stored before; running a file twice is safe
    rejected + no_access_to_athletethe uploader may no longer see that athlete — restore the access, run again
    rejected + exercise_not_foundthe file has no exerciseRefs for that session (queued by an app before 3.0.8) — a developer has to name the exercise
    rejected + invalid_payloadthat batch could not be read; the other batches are stored
  4. 1RMs and personal bests are recalculated. No push notification and no session-rating request go out for imported sessions.

  5. Tell the user. Their app drops the queue entry on its next attempt, because the server now answers alreadyPresent.

What cannot be recovered from the file​

Set videos are not in it; they stay on the device and can be saved to the photo library from the set's Technique view.